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_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 #ifdef ACCESSORIES_DEBUG_MODE
117  Serial.println(F("AccessoryBaseLight ON"));
118 #endif
119  this->SetState(LIGHTON);
120 }
121 
122 void AccessoryBaseLight::LightOff()
123 {
124 #ifdef ACCESSORIES_DEBUG_MODE
125  Serial.println(F("AccessoryBaseLight OFF"));
126 #endif
127  this->SetState(LIGHTOFF);
128 }
129 
130 ACC_STATE AccessoryBaseLight::Toggle()
131 {
132  if (this->state == LIGHTON || this->state == LIGHTBLINK)
133  this->SetState(LIGHTOFF);
134  else
135  this->SetState(LIGHTBLINK); // will be converted in LIGHTON if Duration is 0 !
136 
137  return this->state;
138 }
139 
140 void AccessoryBaseLight::Event(ACCESSORIES_EVENT_TYPE inEvent, int inData)
141 {
142  switch (inEvent)
143  {
144  case ACCESSORIES_EVENT_MOVEPOSITIONID:
145  case ACCESSORIES_EVENT_TOGGLE:
146  this->Toggle();
147  break;
148 
149  case ACCESSORIES_EVENT_MOVE:
150  switch (inData)
151  {
152  case ACCESSORIES_MOVE_STRAIGHT:
153  case ACCESSORIES_MOVE_TOP:
154  case ACCESSORIES_MOVE_LEFT:
155  case ACCESSORIES_MOVE_DIVERGE:
156  case ACCESSORIES_MOVE_BOTTOM:
157  case ACCESSORIES_MOVE_RIGHT:
158  case ACCESSORIES_MOVE_ON:
159  this->LightOn();
160  break;
161  case ACCESSORIES_MOVE_OFF:
162  case ACCESSORIES_MOVE_STOP:
163  this->LightOff();
164  break;
165  case ACCESSORIES_MOVE_MORE:
166  case ACCESSORIES_MOVE_LESS:
167  {
168  int oldValue = this->pPort->GetSpeed();
169  this->pPort->SetSpeed(oldValue + inData);
170  this->LightOn();
171  this->pPort->SetSpeed(oldValue);
172  }
173  break;
174  }
175  break;
176 
177  case ACCESSORIES_EVENT_MOVEPOSITION:
178  {
179  int oldValue = this->pPort->GetSpeed();
180  this->pPort->SetSpeed(inData);
181  this->LightOn();
182  this->pPort->SetSpeed(oldValue);
183  }
184  break;
185 
186  case ACCESSORIES_EVENT_SETSPEED:
187  this->pPort->SetSpeed(inData);
188  break;
189 
190  default:
191  break;
192  }
193 }
194 
195 void AccessoryBaseLight::StartAction()
196 {
197  if (this->blinkingDelay > 0 || this->IsFading())
198  {
199  this->startingMillis = millis();
200  }
201 
202 #ifdef ACCESSORIES_DEBUG_MODE
203 #ifdef ACCESSORIES_DEBUG_VERBOSE_MODE
204  Serial.print(F("AccessoryBaseLight start action "));
205  Serial.println(this->startingMillis);
206 #endif
207 #endif
208 }
209 
210 bool AccessoryBaseLight::ActionEnded()
211 {
212 #ifdef ACCESSORIES_DEBUG_MODE
213 #ifdef ACCESSORIES_DEBUG_VERBOSE_MODE
214  if (this->pOwner->IsActionDelayPending())
215  Serial.println(F("End action of light."));
216 #endif
217 #endif
218  this->pOwner->ResetAction();
219 
220  if (this->state == LIGHTON && this->currentState == LIGHT_ON)
221  return true;
222 
223  if (this->state == LIGHTOFF && this->currentState == LIGHT_OFF)
224  return true;
225 
226 #ifdef ACCESSORIES_DEBUG_MODE
227 #ifdef ACCESSORIES_DEBUG_VERBOSE_MODE
228  Serial.print(F("Light current state : "));
229  switch (this->currentState)
230  {
231  case LIGHT_ON:
232  Serial.println(F("On"));
233  break;
234  case LIGHT_OFF:
235  Serial.println(F("Off"));
236  break;
237  case LIGHT_ASCENDING:
238  Serial.println(F("Ascending"));
239  break;
240  case LIGHT_DESCENDING:
241  Serial.println(F("Descending"));
242  break;
243  }
244 #endif
245 #endif
246  switch (this->currentState)
247  {
248  case LIGHT_ON:
249  // If the light is off, or if his blinking delay has expired
250  if (this->state == LIGHTOFF || (this->IsBlinking() && millis() - this->startingMillis > this->blinkingDelay - FADING_FULL_DELAY))
251  {
252  // Turn off the light
253  if (this->IsFading())
254  {
255  // When fading, start the turn off by passing in descending mode.
256  this->currentState = LIGHT_DESCENDING;
257  this->startingMillis = millis();
258  this->LightFadingRaw(this->pPort->GetSpeed());
259  return false;
260  }
261  else
262  {
263  // If not fading, simply turn off the pin and restart the blinking delay.
264  if (this->IsBlinking())
265  this->startingMillis = millis();
266  this->currentState = LIGHT_OFF;
267  this->pPort->MoveStop();
268  }
269  }
270  break;
271 
272  case LIGHT_OFF:
273  // If the light is on, or if his blinking delay has expired
274  if (this->state == LIGHTON || (this->IsBlinking() && millis() - this->startingMillis > this->blinkingDelay - FADING_FULL_DELAY))
275  {
276  // Turn on the light
277  if (this->IsFading())
278  {
279  // When fading, start the turn on by passing in ascending mode.
280  this->currentState = LIGHT_ASCENDING;
281  this->startingMillis = millis();
282  this->LightFadingRaw(0);
283  return false;
284  }
285  else
286  {
287  // If not fading, simply turn on the pin and restart the blinking delay.
288  if (this->IsBlinking())
289  this->startingMillis = millis();
290  this->currentState = LIGHT_ON;
291  this->pPort->MoveLeftDir();
292  }
293  }
294  break;
295 
296  case LIGHT_ASCENDING:
297  {
298  bool endStateAsc = false;
299  if (this->fadingStep == 0)
300  endStateAsc = true;
301  else
302  if (millis() - this->startingMillis > this->fadingDelay)
303  {
304  int curr = (int) this->fadingCurrentValue + this->fadingStep;
305  if (curr > this->pPort->GetSpeed() || curr <= 0)
306  endStateAsc = true;
307  else
308  {
309  this->LightFadingRaw((unsigned char)curr);
310  this->startingMillis = millis();
311  }
312  }
313  //else
314  //Serial.println("Fading delay not finished");
315  if (endStateAsc)
316  {
317  // End of fading
318  this->currentState = LIGHT_ON;
319  if (this->IsBlinking())
320  this->startingMillis = millis();
321  else
322  this->startingMillis = 0;
323  this->LightOnRaw();
324  return true;
325  }
326  }
327  break;
328 
329  case LIGHT_DESCENDING:
330  {
331  bool endStateDesc = false;
332  if (this->fadingStep == 0)
333  endStateDesc = true;
334  else
335  if (millis() - this->startingMillis > this->fadingDelay)
336  {
337  int curr = (int) this->fadingCurrentValue - this->fadingStep;
338  if (curr <= 0)
339  endStateDesc = true;
340  else
341  {
342  this->LightFadingRaw((unsigned char)curr);
343  this->startingMillis = millis();
344  }
345  }
346  //else
347  //Serial.println("Fading delay not finished");
348  if (endStateDesc)
349  {
350  // End of fading
351  this->currentState = LIGHT_OFF;
352  if (this->IsBlinking())
353  this->startingMillis = millis();
354  else
355  this->startingMillis = 0;
356  this->LightOffRaw();
357  return true;
358  }
359  }
360  break;
361 
362  }
363  return false;
364 }
365 
366 #ifndef NO_EEPROM
367 int AccessoryBaseLight::EEPROMSave(int inPos, bool inSimulate)
368 {
369  if (!inSimulate)
370  EEPROM.write(inPos, this->state);
371 
372  return inPos + 1;
373 }
374 
375 int AccessoryBaseLight::EEPROMLoad(int inPos)
376 {
377  this->state = (ACC_STATE)EEPROM.read(inPos++);
378 
379  return inPos;
380 }
381 #endif
382 #ifdef ACCESSORIES_PRINT_ACCESSORIES
383 void AccessoryBaseLight::printAccessory()
384 {
385  Serial.print(F("Fading Step: "));
386  Serial.print(this->fadingStep);
387  Serial.print(F(" / Fading Delay: "));
388  Serial.print(this->fadingDelay);
389  Serial.print(F(" / Blinking Delay: "));
390  Serial.print(this->blinkingDelay);
391  Serial.print(F(" / "));
392  if (this->GetPort() != NULL)
393  this->GetPort()->printPort();
394  Serial.println(F(" "));
395 }
396 #endif
397 
398 #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:174
int GetSpeed() const
Definition: Port.hpp:126
virtual void MoveLeftDir(unsigned long inDuration = 0)
Definition: Port.hpp:150
virtual int SetSpeed(int inSpeed)
Definition: Port.cpp:108
void begin(Port *inpPort, int inIntensity = 255, Accessory *inpOwner = 0)
Definition: Port.hpp:61
PIN_TYPE GetPinType() const
Definition: Port.hpp:74
void SetFading(uint8_t inStep, uint8_t inDelay)
void SetStateRaw(ACC_STATE inNewState)
Definition: Accessory.cpp:224
AccessoryBaseLight(Accessory *inpOwner = 0)