AGirs
LedLcdManager.cpp
Go to the documentation of this file.
1 // Comment out if LCD is not wanted or needed. Except for needing some memory,
2 // it has otherwise no disadvantages.
3 // Remove for minimal memory footprint.
4 
5 // This should be taken from config.h, but the Arduino IDE does not seem
6 // to allow for this. User friendlyness taken to a new level...
7 // Adjust if needed
8 #if defined(ARDUINO) & ! defined(ARDUINO_AVR_MICRO) & ! defined(ARDUINO_AVR_NANO)
9 #define LCD
10 #endif
11 
12 #include "LedLcdManager.h"
13 #include "Tokenizer.h"
14 #include <string.h>
15 
16 #ifdef LCD
17 LiquidCrystal_I2C *LedLcdManager::lcd;
18 #endif
19 milliseconds_t LedLcdManager::blinkTime = defaultBlinkTime;
20 unsigned long LedLcdManager::turnOffTime;
21 unsigned int LedLcdManager::lcdRows = 0;
22 unsigned int LedLcdManager::lcdColumns = 0;
23 
24 pin_t LedLcdManager::physicalLeds[maxLeds];
25 led_t LedLcdManager::logicalLeds[maxLeds];
26 bool LedLcdManager::shouldTimeOut[maxLeds];
27 
28 void LedLcdManager::setup(int8_t i2cAddress, uint8_t columns, uint8_t rows,
29  const pin_t physicalLeds_[], const led_t logicalLeds_[], const bool shouldTimeOut_[]) {
30  setupLcdI2c(i2cAddress, columns, rows);
31  setupPhysicalLeds(physicalLeds_);
32  setupLogicLeds(logicalLeds_);
33  setupShouldTimeOut(shouldTimeOut_);
34  disableTurnOffTime();
35 }
36 
37 bool LedLcdManager::setPhysicalLed(led_t physicalLed, LedState state) {
38  pin_t pin = physicalLeds[physicalLed-1];
39  if (pin == invalidPin)
40  return false;
41 
42 #ifdef ARDUINO
43  digitalWrite(pin, state == off ? LOW : HIGH);
44 #else
45  std::cout << "setPhysicalLed: pin = " << (int) pin << ", " << (state == off ? "off" : "on") << std::endl;
46 #endif
47  if (state == blink)
49  return true;
50 }
51 
53  return value == NULL ? invalid
54  : strcmp(value, "on") == 0 ? on
55  : strcmp(value, "off") == 0 ? off
56  : strcmp(value, "blink") == 0 ? blink
57  : invalid;
58 }
59 
60 bool LedLcdManager::setLogicLed(led_t logicLed, LedState state) {
61  if (logicLed == invalidLed
62  || logicLed < 1
63  || logicLed > maxLeds
64  || state == invalid )
65  return false;
66 
67  led_t physicalLed = logicalLeds[logicLed - 1];
68  if (physicalLed == invalidLed)
69  return false;
70 
71  return setPhysicalLed(physicalLed, state);
72 }
73 
74 bool LedLcdManager::setupLogicLed(led_t logicLed, led_t physicalLed) {
75  if (physicalLed == invalidLed)
76  return false;
77 
78  logicalLeds[logicLed-1] = physicalLed;
79  return true;
80 }
81 
82 bool LedLcdManager::setupLogicLeds(const led_t logicalLeds_[maxLeds]) {
83  for (int i = 0; i < maxLeds; i++)
84  logicalLeds[i] = logicalLeds_ == NULL ? i+1 : logicalLeds_[i];
85  return true;
86 }
87 
88 void LedLcdManager::setupPhysicalLeds(const pin_t physicalLeds_[maxLeds]) {
89  for (int i = 0; i < maxLeds; i++) {
90  physicalLeds[i] = physicalLeds_ == NULL ? invalidPin : physicalLeds_[i];
91  if (physicalLeds[i] != invalidPin)
92  pinMode(physicalLeds[i], OUTPUT);
93  }
94 }
95 
96 void LedLcdManager::setupShouldTimeOut(const bool shouldTimeOut_[maxLeds]) {
97  for (int i = 0; i < maxLeds; i++)
98  shouldTimeOut[i] = shouldTimeOut_ == NULL ? true : shouldTimeOut_[i];
99 }
100 
101 void LedLcdManager::setupShouldTimeout(led_t logicLed, bool state) {
102  if (logicLed != invalidLed)
103  shouldTimeOut[logicLed-1] = state;
104 }
105 
106 void LedLcdManager::setupLcdI2c(int8_t i2cAddress, uint8_t columns, uint8_t rows) {
107 #ifdef LCD
108  lcd = i2cAddress >= 0 ? new LiquidCrystal_I2C((uint8_t)i2cAddress, columns, rows) : NULL;
109  if (lcd) {
110  lcdRows = rows;
111  lcdColumns = columns;
112  lcd->init();
113  }
114 #else
115  (void) i2cAddress;
116  (void) columns;
117  (void) rows;
118 #endif
119 }
120 
122  turnOffTime = millis() + blinkTime;
123 }
124 
125 void LedLcdManager::selfTest(const char *text) {
126  lcdPrint(text);
127  for (led_t i = 1; i <= maxLeds; i++)
128  setLogicLed(i, on);
129  delay(
130 #ifdef LCD
131  lcd ? selftestTimeWithLCD :
132 #endif
134  allOff(true);
135 }
136 
137 #ifdef ARDUINO
138 void LedLcdManager::selfTest(const __FlashStringHelper *text) {
139  lcdPrint(text);
140  for (led_t i = 1; i <= maxLeds; i++)
141  setLogicLed(i, on);
142  delay(
143 #ifdef LCD
144  lcd ? selftestTimeWithLCD :
145 #endif
147  allOff(true);
148 }
149 #endif
150 
152  if (millis() > turnOffTime)
153  allOff(false);
154 }
155 
156 void LedLcdManager::allOff(bool force) {
157 #ifdef LCD
158  if (lcd) {
159  lcd->noDisplay();
160  lcd->noBacklight();
161  }
162 #endif
163  for (led_t i = 1; i <= maxLeds; i++)
164  if (force || shouldTimeOut[i - 1])
165  setLogicLed(i, off);
166 
167  disableTurnOffTime();
168 }
169 
170 void LedLcdManager::disableTurnOffTime() {
171  turnOffTime = (unsigned long) -1;
172 }
173 
174 void LedLcdManager::lcdPrint(String& string, bool clear, int x, int y) {
175 #ifdef LCD
176  if (!lcd)
177  return;
178 
179  int row = (y < 0 && clear) ? 0 : y;
180  int column = x < 0 ? 0 : x;
181  if (row > (int) lcdRows - 1 || column > (int) lcdColumns - 1) // outside of display
182  return;
183 
184  if (clear)
185  lcd->clear();
186 
187  bool didPrint = false;
188  Tokenizer tokenizer(string);
189  while (true) {
190  String line = tokenizer.getLine();
191  if (line.length() == 0)
192  break;
193  if (line.length() > lcdColumns)
194  line = line.substring(0, lcdColumns);
195  if (clear || y >= 0) {
196  lcd->setCursor(column, row);
197  row++;
198  column = 0;
199  }
200  lcd->print(line.c_str());
201  didPrint = true;
202  }
203  if (didPrint) {
204  lcd->display();
205  lcd->backlight();
206  }
208 #else
209  (void) string;
210  (void) clear;
211  (void) x;
212  (void) y;
213 #endif
214 }
static LedState onOffBlinkParse(const char *value)
static const int maxLeds
Definition: LedLcdManager.h:14
static const int selftestTimeWithoutLCD
Definition: LedLcdManager.h:19
static bool setPhysicalLed(led_t physicalLed, LedState state)
static const int selftestTimeWithLCD
Definition: LedLcdManager.h:20
static void setup(int8_t i2cAddress=-1, uint8_t columns=defaultLcdColumns, uint8_t rows=defaultLcdRows, const pin_t physicalLeds[maxLeds]=NULL, const led_t logicalLeds[maxLeds]=NULL, const bool shouldTimeOut[maxLeds]=NULL)
Sets up the instance, to be called before using the instance.
#define LCD
static bool setLogicLed(led_t logicLed, LedState state)
static bool setupLogicLeds(const led_t array[maxLeds])
uint8_t led_t
Definition: LedLcdManager.h:10
static const led_t invalidLed
Definition: LedLcdManager.h:30
static void setupShouldTimeout(led_t logicLed, bool state)
static void lcdPrint(String &string, bool clear=true, int x=0, int y=-1)
static void updateTurnOffTime()
static void allOff(bool force)
static void selfTest(const char *text)
static bool setupLogicLed(led_t loginLed, led_t physicalLed)
static void checkTurnoff()
Turn off if it is due.
String getLine()
Definition: Tokenizer.cpp:54