Accessories
Arduino for motors and lights library.
AccessoryBaseLight.cpp
1 /**********************************************************************
2 project: <Accessories>
3 author: <Thierry PARIS>
4 description: <Class for a light, flashing or not, with optional fading>
5 ***********************************************************************/
6 
7 #include "Accessories.h"
8 #include "AccessoryBaseLight.hpp"
9 #ifndef NO_EEPROM
10 #include "EEPROM.h"
11 #endif
12 
13 #ifndef NO_LIGHT
14 
15 const uint8_t PROGMEM gamma8[] = {
16  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
17  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
18  1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2,
19  2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5,
20  5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10,
21  10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16,
22  17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25,
23  25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36,
24  37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50,
25  51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68,
26  69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89,
27  90, 92, 93, 95, 96, 98, 99,101,102,104,105,107,109,110,112,114,
28  115,117,119,120,122,124,126,127,129,131,133,135,137,138,140,142,
29  144,146,148,150,152,154,156,158,160,162,164,167,169,171,173,175,
30  177,180,182,184,186,189,191,193,196,198,200,203,205,208,210,213,
31  215,218,220,223,225,228,231,233,236,239,241,244,247,249,252,255 };
32 
34 {
35  this->pPort = NULL;
36  this->state = LIGHTOFF;
37  this->currentState = LIGHT_OFF;
38  this->startingMillis = 0;
39  this->fadingStep = this->fadingDelay = 0;
40  this->blinkingDelay = 0;
41  this->pOwner = inpOwner;
42 }
43 
44 void AccessoryBaseLight::SetState(ACC_STATE inState)
45 {
46  if (inState == LIGHTBLINK && this->blinkingDelay == 0)
47  inState = LIGHTON;
48 
49 #ifdef ACCESSORIES_DEBUG_VERBOSE_MODE
50  Serial.print(F("AccessoryBaseLight SetState "));
51  Serial.println(inState == LIGHTON ? "ON" : inState == LIGHTOFF ? "OFF" : "BLINK");
52 #endif
53 
54  this->SetStateRaw(inState);
55 }
56 
57 void AccessoryBaseLight::SetStateRaw(ACC_STATE inNewState)
58 {
59  if (this->state != inNewState)
60  {
61  if (inNewState == LIGHTBLINK && this->startingMillis == 0)
62  this->StartAction();
63  this->state = inNewState;
64  this->pOwner->SetStateRaw(inNewState);
65  }
66 }
67 
68 void AccessoryBaseLight::SetFading(uint8_t inStep, uint8_t inDelay)
69 {
70  this->fadingStep = inStep;
71  this->fadingDelay = inDelay;
72  this->fadingCurrentValue = 0;
73 
74 #ifdef ACCESSORIES_DEBUG_MODE
75  if (this->pPort->GetPinType() == DIGITAL || this->pPort->GetPinType() == DIGITAL_INVERTED)
76  Serial.println(F("Fading on a light is not allowed on a DIGITAL pin !"));
77  if (this->blinkingDelay > 0 && FADING_FULL_DELAY > this->blinkingDelay)
78  Serial.println(F("Light fading duration greater than blinking duration !"));
79 #endif
80 }
81 
82 void AccessoryBaseLight::begin(Port *inpPort, int inIntensity, Accessory *inpOwner)
83 {
84  if (inpOwner != NULL)
85  this->pOwner = inpOwner;
86  this->pPort = inpPort;
87  this->pPort->SetSpeed(inIntensity);
88  this->LightOff();
89 }
90 
91 void AccessoryBaseLight::LightFadingRaw(uint8_t inValue)
92 {
93 #ifdef ACCESSORIES_DEBUG_MODE
94 #ifdef ACCESSORIES_DEBUG_VERBOSE_MODE
95  Serial.print(F("AccessoryBaseLight Fading at "));
96  Serial.println(inValue);
97 #endif
98 #endif
99  this->fadingCurrentValue = inValue;
100  this->pPort->MoveLeftDir(0, pgm_read_byte(&gamma8[inValue]));
101 }
102 
103 void AccessoryBaseLight::LightOnRaw()
104 {
105  this->LightFadingRaw(this->pPort->GetSpeed());
106 }
107 
108 void AccessoryBaseLight::LightOffRaw()
109 {
110  this->LightFadingRaw(0);
111  this->pPort->MoveStop();
112 }
113 
114 void AccessoryBaseLight::LightOn()
115 {
116  this->SetState(LIGHTON);
117 }
118 
119 void AccessoryBaseLight::LightOff()
120 {
121  this->SetState(LIGHTOFF);
122 }
123 
124 ACC_STATE AccessoryBaseLight::Toggle()
125 {
126  if (this->state == LIGHTON || this->state == LIGHTBLINK)
127  this->SetState(LIGHTOFF);
128  else
129  this->SetState(LIGHTBLINK); // will be converted in LIGHTON if Duration is 0 !
130 
131  return this->state;
132 }
133 
134 void AccessoryBaseLight::Event(ACCESSORIES_EVENT_TYPE inEvent, int inData)
135 {
136  switch (inEvent)
137  {
138  case ACCESSORIES_EVENT_MOVEPOSITIONID:
139  case ACCESSORIES_EVENT_TOGGLE:
140  this->Toggle();
141  break;
142 
143  case ACCESSORIES_EVENT_MOVE:
144  switch (inData)
145  {
146  case ACCESSORIES_MOVE_STRAIGHT:
147  case ACCESSORIES_MOVE_TOP:
148  case ACCESSORIES_MOVE_LEFT:
149  case ACCESSORIES_MOVE_DIVERGE:
150  case ACCESSORIES_MOVE_BOTTOM:
151  case ACCESSORIES_MOVE_RIGHT:
152  case ACCESSORIES_MOVE_ON:
153  this->LightOn();
154  break;
155  case ACCESSORIES_MOVE_OFF:
156  case ACCESSORIES_MOVE_STOP:
157  this->LightOff();
158  break;
159  case ACCESSORIES_MOVE_MORE:
160  case ACCESSORIES_MOVE_LESS:
161  {
162  int oldValue = this->pPort->GetSpeed();
163  this->pPort->SetSpeed(oldValue + inData);
164  this->LightOn();
165  this->pPort->SetSpeed(oldValue);
166  }
167  break;
168  }
169  break;
170 
171  case ACCESSORIES_EVENT_MOVEPOSITION:
172  {
173  int oldValue = this->pPort->GetSpeed();
174  this->pPort->SetSpeed(inData);
175  this->LightOn();
176  this->pPort->SetSpeed(oldValue);
177  }
178  break;
179 
180  case ACCESSORIES_EVENT_SETSPEED:
181  this->pPort->SetSpeed(inData);
182  break;
183 
184  default:
185  break;
186  }
187 }
188 
189 void AccessoryBaseLight::StartAction()
190 {
191  if (this->blinkingDelay > 0 || this->IsFading())
192  {
193  this->startingMillis = millis();
194  }
195 
196 #ifdef ACCESSORIES_DEBUG_VERBOSE_MODE
197  Serial.print(F("AccessoryBaseLight start action "));
198  Serial.println(this->startingMillis);
199 #endif
200 }
201 
202 bool AccessoryBaseLight::ActionEnded()
203 {
204 #ifdef ACCESSORIES_DEBUG_VERBOSE_MODE
205  if (this->pOwner->IsActionDelayPending())
206  Serial.println(F("End action of light."));
207 #endif
208  this->pOwner->ResetAction();
209 
210  if (this->state == LIGHTON && this->currentState == LIGHT_ON)
211  return true;
212 
213  if (this->state == LIGHTOFF && this->currentState == LIGHT_OFF)
214  return true;
215 
216 #ifdef ACCESSORIES_DEBUG_VERBOSE_MODE
217  Serial.print(F("Light current state : "));
218  switch (this->currentState)
219  {
220  case LIGHT_ON:
221  Serial.println(F("On"));
222  break;
223  case LIGHT_OFF:
224  Serial.println(F("Off"));
225  break;
226  case LIGHT_ASCENDING:
227  Serial.println(F("Ascending"));
228  break;
229  case LIGHT_DESCENDING:
230  Serial.println(F("Descending"));
231  break;
232  }
233 #endif
234  switch (this->currentState)
235  {
236  case LIGHT_ON:
237  // If the light is off, or if his blinking delay has expired
238  if (this->state == LIGHTOFF || (this->IsBlinking() && millis() - this->startingMillis > this->blinkingDelay - FADING_FULL_DELAY))
239  {
240  // Turn off the light
241  if (this->IsFading())
242  {
243  // When fading, start the turn off by passing in descending mode.
244  this->currentState = LIGHT_DESCENDING;
245  this->startingMillis = millis();
246  this->LightFadingRaw(this->pPort->GetSpeed());
247  return false;
248  }
249  else
250  {
251  // If not fading, simply turn off the pin and restart the blinking delay.
252  if (this->IsBlinking())
253  this->startingMillis = millis();
254  this->currentState = LIGHT_OFF;
255  this->pPort->MoveStop();
256  }
257  }
258  break;
259 
260  case LIGHT_OFF:
261  // If the light is on, or if his blinking delay has expired
262  if (this->state == LIGHTON || (this->IsBlinking() && millis() - this->startingMillis > this->blinkingDelay - FADING_FULL_DELAY))
263  {
264  // Turn on the light
265  if (this->IsFading())
266  {
267  // When fading, start the turn on by passing in ascending mode.
268  this->currentState = LIGHT_ASCENDING;
269  this->startingMillis = millis();
270  this->LightFadingRaw(0);
271  return false;
272  }
273  else
274  {
275  // If not fading, simply turn on the pin and restart the blinking delay.
276  if (this->IsBlinking())
277  this->startingMillis = millis();
278  this->currentState = LIGHT_ON;
279  this->pPort->MoveLeftDir();
280  }
281  }
282  break;
283 
284  case LIGHT_ASCENDING:
285  {
286  bool endStateAsc = false;
287  if (this->fadingStep == 0)
288  endStateAsc = true;
289  else
290  if (millis() - this->startingMillis > this->fadingDelay)
291  {
292  int curr = (int) this->fadingCurrentValue + this->fadingStep;
293  if (curr > this->pPort->GetSpeed() || curr <= 0)
294  endStateAsc = true;
295  else
296  {
297  this->LightFadingRaw((unsigned char)curr);
298  this->startingMillis = millis();
299  }
300  }
301  //else
302  //Serial.println("Fading delay not finished");
303  if (endStateAsc)
304  {
305  // End of fading
306  this->currentState = LIGHT_ON;
307  if (this->IsBlinking())
308  this->startingMillis = millis();
309  else
310  this->startingMillis = 0;
311  this->LightOnRaw();
312  return true;
313  }
314  }
315  break;
316 
317  case LIGHT_DESCENDING:
318  {
319  bool endStateDesc = false;
320  if (this->fadingStep == 0)
321  endStateDesc = true;
322  else
323  if (millis() - this->startingMillis > this->fadingDelay)
324  {
325  int curr = (int) this->fadingCurrentValue - this->fadingStep;
326  if (curr <= 0)
327  endStateDesc = true;
328  else
329  {
330  this->LightFadingRaw((unsigned char)curr);
331  this->startingMillis = millis();
332  }
333  }
334  //else
335  //Serial.println("Fading delay not finished");
336  if (endStateDesc)
337  {
338  // End of fading
339  this->currentState = LIGHT_OFF;
340  if (this->IsBlinking())
341  this->startingMillis = millis();
342  else
343  this->startingMillis = 0;
344  this->LightOffRaw();
345  return true;
346  }
347  }
348  break;
349 
350  }
351  return false;
352 }
353 
354 #ifndef NO_EEPROM
355 int AccessoryBaseLight::EEPROMSave(int inPos, bool inSimulate)
356 {
357  if (!inSimulate)
358  EEPROM.write(inPos, this->state);
359 
360  return inPos + 1;
361 }
362 
363 int AccessoryBaseLight::EEPROMLoad(int inPos)
364 {
365  this->state = (ACC_STATE)EEPROM.read(inPos++);
366 
367  return inPos;
368 }
369 #endif
370 #ifdef ACCESSORIES_PRINT_ACCESSORIES
371 void AccessoryBaseLight::printAccessory()
372 {
373  Serial.print(F("Fading Step: "));
374  Serial.print(this->fadingStep);
375  Serial.print(F(" / Fading Delay: "));
376  Serial.print(this->fadingDelay);
377  Serial.print(F(" / Blinking Delay: "));
378  Serial.print(this->blinkingDelay);
379  Serial.print(F(" / "));
380  if (this->GetPort() != NULL)
381  this->GetPort()->printPort();
382  Serial.println(F(" "));
383 }
384 #endif
385 
386 #endif
Port * GetPort() const
virtual void ResetAction()
Definition: Accessory.hpp:411
bool IsActionDelayPending() const
Definition: Accessory.hpp:424
void Event(ACCESSORIES_EVENT_TYPE inEvent = ACCESSORIES_EVENT_MOVEPOSITIONID, int inData = 0)
virtual void MoveStop()
Definition: Port.hpp:177
virtual void MoveLeftDir(unsigned long inDuration = 0)
Definition: Port.hpp:153
virtual int SetSpeed(int inSpeed)
Definition: Port.cpp:190
Definition: Port.hpp:60
void begin(Port *inpPort, int inIntensity = 255, Accessory *inpOwner = 0)
PIN_TYPE GetPinType() const
Definition: Port.hpp:77
int GetSpeed() const
Definition: Port.hpp:129
void SetFading(uint8_t inStep, uint8_t inDelay)
void SetStateRaw(ACC_STATE inNewState)
Definition: Accessory.cpp:224
AccessoryBaseLight(Accessory *inpOwner = 0)