RSeries astromech firmware
DataPanel.h
Go to the documentation of this file.
1 #ifndef _DATAPANEL_H_
2 #define _DATAPANEL_H_
3 
4 #include "ReelTwo.h"
6 #include "core/SetupEvent.h"
7 #include "core/AnimatedEvent.h"
8 #include "core/CommandEvent.h"
9 
82 {
83 public:
87  DataPanel(LedControl& ledControl) :
88  fLC(ledControl),
89  fID(ledControl.addDevice()),
90  fDisplayEffectVal(kNormalVal),
91  fPreviousEffectVal(~kNormalVal)
92  {
93  }
94 
96  {
98  };
99  enum Sequence
100  {
101  kNormal = 0,
104  };
105 
113  void selectEffect(long inputNum)
114  {
115  fDisplayEffectVal = inputNum;
116  fPreviousEffectVal = ~fDisplayEffectVal;
117  }
118 
122  inline void setSequence(Sequence seq = kNormal, uint8_t speedScale = 0, uint8_t numSeconds = 0)
123  {
124  selectEffect((long int)seq * 10000L + (long int)speedScale * 100 + numSeconds);
125  }
126 
130  virtual void setup() override
131  {
132  fLC.clearDisplay(fID);
133  fLC.setIntensity(fID, 15);
134  fLC.setPower(fID, true);
135  }
136 
140  virtual void animate() override
141  {
142  unsigned long now = millis();
143  if (fDisplayEffectVal != fPreviousEffectVal)
144  {
145  fLC.setIntensity(fID, 15);
146  fLC.clearDisplay(fID);
147  fSeqStep = -1;
148  fDelayTime = 50;
149  fNextStepTimeMS = 0;
150  fEffectStartMillis = millis();
151  fPreviousEffectVal = fDisplayEffectVal;
152  fLastTimeBar = now;
153  fLastTimeBlue = now;
154  fLastTimeRed = now;
155  fLastTimeBottom = now;
156  fLastTimeTop = now;
157  fBarValue = 0;
158  fBarDirection = 1;
159  }
160  else if (now < fNextStepTimeMS)
161  {
162  return;
163  }
164 
165  int selectSequence = (fDisplayEffectVal % 1000000) / 10000;
166  int selectSpeed = (fDisplayEffectVal % 1000) / 100;
167  int selectLength = (fDisplayEffectVal % 100);
168  UNUSED(selectSpeed);
169 
170  switch (selectSequence)
171  {
172  case kDisabled:
173  break;
174  case kFlicker:
175  fLC.setIntensity(fID, random(15));
176  // Fall through
177  case kNormal:
178  if (fLastTimeBar + BARGRAPHSPEED < now)
179  {
180  byte chance = random(100);
181  byte displayValue = getBargraph();
182  /* 10% chance of changing direction */
183  if (displayValue == fBarValue && chance < 10)
184  {
185  fBarDirection = -fBarDirection;
186  }
187  /* 40% chance of moving */
188  if (displayValue == fBarValue && chance < 40)
189  {
190  fBarValue = min(max(0, fBarValue + fBarDirection), 6);
191  setBargraph(fBarValue);
192  }
193  /* 90% chance of blinking */
194  else if (chance < 90 && fBarValue > 0)
195  {
196  displayValue = (displayValue == fBarValue) ? displayValue - 1 : fBarValue;
197  setBargraph(displayValue);
198  }
199  fLastTimeBar = now;
200  }
201  if (fLastTimeBlue + BLUELEDSPEED < now)
202  {
203  setBlueLed(fLC.randomRow(4));
204  fLastTimeBlue = now;
205  }
206  if (fLastTimeRed + REDLEDSPEED < now)
207  {
208  setRed1Led(random(2));
209  setRed2Led(random(2));
210  fLastTimeRed = now;
211  }
212  if (fLastTimeBottom + BOTTOMLEDSPEED < now)
213  {
214  setBottomLed(fLC.randomRow(4), fLC.randomRow(4));
215  fLastTimeBottom = now;
216  }
217  if (fLastTimeTop + TOPBLOCKSPEED < now)
218  {
219  setYellowBlock(fLC.randomRow(4), fLC.randomRow(4));
220  setGreenBlock(fLC.randomRow(4), fLC.randomRow(4));
221  fLastTimeTop = TOPBLOCKSPEED;
222  }
223  fDelayTime = min(TOPBLOCKSPEED, min(BOTTOMLEDSPEED, min(REDLEDSPEED, min(BLUELEDSPEED, BARGRAPHSPEED))));
224  break;
225  default:
226  selectEffect(kNormalVal); //unknown effecct go back to normal
227  break;
228  }
229  fNextStepTimeMS = now + fDelayTime;
230  if (selectLength > 0 && millis() - fEffectStartMillis >= unsigned(selectLength) * 1000L)
231  {
232  selectEffect(kNormalVal); //go back to normal operation if its time
233  }
234  }
235 
239  virtual void handleCommand(const char* cmd) override
240  {
241  if (*cmd++ == 'D' && *cmd++ == 'P')
242  {
243  long int cmdvalue = 0;
244  const char* c = cmd;
245  while (*c >= '0' && *c <= '9')
246  {
247  cmdvalue = cmdvalue * 10 + (*c++ - '0');
248  }
249  selectEffect(cmdvalue);
250  }
251  }
252 
256  void setYellowBlock(byte top, byte bottom)
257  {
258  byte bits = fLC.getRow(fID, YELLOWBLOCK);
259  fLC.setRow(fID, YELLOWBLOCK, (((top&7)<<5)|(bottom&7)<<2)|(bits&3));
260  }
261 
265  void setGreenBlock(byte top, byte bottom)
266  {
267  byte bits = fLC.getRow(fID, GREENBLOCK);
268  fLC.setRow(fID, GREENBLOCK, ((top&7)<<5)|((bottom&7)<<2)|(bits&3));
269  }
270 
274  void setRed1Led(bool on)
275  {
276  byte bits = fLC.getRow(fID, BARGRAPH_LEFT) & ~B10;
277  if (on)
278  bits |= B10;
279  fLC.setRow(fID, BARGRAPH_LEFT, bits);
280  }
281 
285  void setRed2Led(bool on)
286  {
287  byte bits = fLC.getRow(fID, BARGRAPH_RIGHT) & ~B10;
288  if (on)
289  bits |= B10;
290  fLC.setRow(fID, BARGRAPH_RIGHT, bits);
291  }
292 
296  void setBottomLed(byte top, byte bottom)
297  {
298  byte bits = fLC.getRow(fID, BOTTOMLED);
299  fLC.setRow(fID, BOTTOMLED, (((top&7)<<5)|(bottom&7)<<2)|(bits&3));
300  }
301 
305  void setBlueLed(byte pattern)
306  {
307  fLC.setRow(fID, BLUELED, pattern<<2);
308  }
309 
321  void setBargraph(byte value)
322  {
323  byte i = 0;
324  byte bits = 0;
325  value = min((int)value, 6);
326  while (value > 0)
327  {
328  bits |= B100<<i;
329  value--;
330  i++;
331  }
332  fLC.setRow(fID, BARGRAPH_LEFT, bits | (fLC.getRow(fID, BARGRAPH_LEFT) & 3));
333  fLC.setRow(fID, BARGRAPH_RIGHT, bits | (fLC.getRow(fID, BARGRAPH_RIGHT) & 3));
334  }
335 
339  byte getBargraph()
340  {
341  byte i = 0;
342  byte bits = fLC.getRow(fID, BARGRAPH_LEFT);
343  if (bits == fLC.getRow(fID, BARGRAPH_RIGHT))
344  {
345  while (i < 6)
346  {
347  if (!(bits & (B100<<i)))
348  break;
349  i++;
350  }
351  }
352  return i;
353  }
354 
355 private:
356  LedControl& fLC;
357  byte fID;
358  int fSeqStep;
359  byte fBarPrevValue;
360  signed char fBarValue;
361  signed char fBarDirection;
362  unsigned long fLastTimeBar;
363  unsigned long fLastTimeBlue;
364  unsigned long fLastTimeRed;
365  unsigned long fLastTimeBottom;
366  unsigned long fLastTimeTop;
367  unsigned long fNextStepTimeMS;
368  unsigned long fEffectStartMillis;
369 
370  long fDisplayEffectVal;
371  long fPreviousEffectVal;
372 
373  /* we always wait a bit between updates of the display */
374  unsigned long fDelayTime = 300;
375 
376  static const int YELLOWBLOCK = 4;
377  static const int GREENBLOCK = 5;
378 
379  static const int BARGRAPH_LEFT = 2;
380  static const int BARGRAPH_RIGHT = 3;
381 
382  static const int REDLED_LEFT = 2;
383  static const int REDLED_RIGHT = 3;
384 
385  static const int BLUELED = 0;
386  static const int BOTTOMLED = 1;
387 
388  static const int TOPBLOCKSPEED = 70;
389  static const int BOTTOMLEDSPEED = 200;
390  static const int REDLEDSPEED = 500;
391  static const int BLUELEDSPEED = 500;
392  static const int BARGRAPHSPEED = 100;
393 };
394 
395 #endif
DataPanel::setRed1Led
void setRed1Led(bool on)
Set the Red #1 LED.
Definition: DataPanel.h:274
DataPanel::setup
virtual void setup() override
Perform any initialzation not possible in the constructor.
Definition: DataPanel.h:130
CommandEvent
Base class for all command enabled devices. CommandEvent::handleCommand() is called for each device e...
Definition: CommandEvent.h:17
DataPanel::kFlicker
@ kFlicker
Definition: DataPanel.h:103
ReelTwo.h
DataPanel::Sequence
Sequence
Definition: DataPanel.h:99
SetupEvent.h
AnimatedEvent
Base class for all animated devices. AnimatedEvent::animate() is called for each device once through ...
Definition: AnimatedEvent.h:18
SetupEvent
Base class for all devices that require setup that cannot happen in the constructor....
Definition: SetupEvent.h:15
DataPanel::setBottomLed
void setBottomLed(byte top, byte bottom)
Set the bottom LEDs.
Definition: DataPanel.h:296
LedControlMAX7221.h
UNUSED
#define UNUSED(x)
Definition: ReelTwo.h:172
DataPanel::setGreenBlock
void setGreenBlock(byte top, byte bottom)
Set the green block LEDs.
Definition: DataPanel.h:265
AnimatedEvent.h
DataPanel::selectEffect
void selectEffect(long inputNum)
Select the specified effect using a 32-bit integer.
Definition: DataPanel.h:113
DataPanel::kNormal
@ kNormal
Definition: DataPanel.h:101
DataPanel::animate
virtual void animate() override
Perform a single frame of LED animation based on the selected sequence.
Definition: DataPanel.h:140
DataPanel::kDisabled
@ kDisabled
Definition: DataPanel.h:102
DataPanel::DataPanel
DataPanel(LedControl &ledControl)
Constructor.
Definition: DataPanel.h:87
DataPanel::setYellowBlock
void setYellowBlock(byte top, byte bottom)
Set the yellow block LEDs.
Definition: DataPanel.h:256
DataPanel::setSequence
void setSequence(Sequence seq=kNormal, uint8_t speedScale=0, uint8_t numSeconds=0)
Select the specified effect sequence.
Definition: DataPanel.h:122
DataPanel::EffectValue
EffectValue
Definition: DataPanel.h:95
DataPanel::handleCommand
virtual void handleCommand(const char *cmd) override
ChargeBayIndicator Commands start with 'DP'.
Definition: DataPanel.h:239
DataPanel::setBlueLed
void setBlueLed(byte pattern)
Set the blue LEDs.
Definition: DataPanel.h:305
DataPanel::kNormalVal
@ kNormalVal
Definition: DataPanel.h:97
DataPanel::setRed2Led
void setRed2Led(bool on)
Set the Red #2 LED.
Definition: DataPanel.h:285
DataPanel::setBargraph
void setBargraph(byte value)
Set the bargraph height.
Definition: DataPanel.h:321
CommandEvent.h
DataPanel
DataPanel controller.
Definition: DataPanel.h:81
DataPanel::getBargraph
byte getBargraph()
Get the current bargraph height.
Definition: DataPanel.h:339