// import a library for an LCD
#include <LiquidCrystal.h>
void diodePulseToggle();
void writeLCDMessage();
bool shouldResetSecondRow();
void lcd2ndRowReset();
void createSpecialCharacters();
// LCD setup
const int RS = 11,
E = 12,
D4 = 13,
D5 = 5,
D6 = 4,
D7 = 3;
LiquidCrystal lcd(RS,E,D4,D5,D6,D7);
const int LCD_COLS = 16;
const int LCD_ROWS = 2;
const int LCD_2_ROW_START_COL = 2;
// pins declarations
const int redLedPin = 8;
const int yellowLedPin = 7;
const int greenLedPin = 2;
const int redBtnPin = 10;
const int yellowBtnPin = 9;
const int greenBtnPin = 6;
// arrayx with pin numbers
const int ledPinNrsArray[] = {redLedPin, yellowLedPin, greenLedPin};
const int btnPinNrsArray[] = {redBtnPin};
const char *const pinColors[] = {"red", "yellow", "green"};
const char *const pinColorsPL[] = {"czerwony", "żółty", "zielony"};
int ledStates[] = {0, 0, 0};
// length counter for the above array
const int amountOfPinsUsed = (sizeof(ledPinNrsArray) / sizeof(ledPinNrsArray[0]));
// diodes counter
int x = -1;
// init diode status
bool isLightOn = false;
int lastLight = -1;
int lastButtonState = -1;
int btnState = -1;
// time counter initial values
unsigned long previousMillis = 0;
const long interval = 1000;
unsigned long currentMillis = 0;
// time counter for a button debouncing
unsigned long lastDebounceTime = 0;
const long debounceDelay = 50;
const byte a_[8] = { //ą
B00000,
B01110,
B00001,
B01111,
B10001,
B01111,
B00010,
B00001,
};
const byte c_[8] = { //ć
B00010,
B00100,
B01110,
B10000,
B10000,
B10001,
B01110,
B00000,
};
const byte e_[8] = { //ę
B00000,
B01110,
B10001,
B11111,
B10000,
B01110,
B00100,
B00010,
};
const byte l_[8] = { //ł
B01100,
B00100,
B00100,
B00110,
B01100,
B00100,
B01110,
B00000,
};
const byte n_[8] = { //ń
B00010,
B00100,
B10110,
B11001,
B10001,
B10001,
B10001,
B00000,
};
const byte o_[8] = { //ó
B00010,
B00100,
B01110,
B10001,
B10001,
B10001,
B01110,
B00000,
};
const byte s_[8] = { //ś
B00010,
B00100,
B01110,
B10000,
B01110,
B00001,
B11110,
B00000,
};
const byte z__[8] = { //ź
B00010,
B00100,
B11111,
B00010,
B00100,
B01000,
B11111,
B00000,
};
const byte z_[8] = { //ż
B00100,
B00000,
B11111,
B00010,
B00100,
B01000,
B11111,
B00000,
};
const byte heartSymbol[8] = {
B00000,
B01010,
B11111,
B11111,
B01110,
B00100,
B00000,
B00000
};
const byte resetCharacter[8] = {
B00000,B00000,B00000,B000000,B00000,B00000,B00000,B00000
};
void setup() {
// set up a terminal
Serial.begin(9600);
createSpecialCharacters();
// lcd printing init
lcd.begin(16,2);
// set cursor at the beginning (col, row)
lcd.setCursor(0,0);
lcd.print("Light status");
Serial.println("Light status");
lcd.setCursor(5,0);
lcd.write(byte(3));
// declare using pins
for (int i = 0; i < amountOfPinsUsed; i++) {
pinMode(ledPinNrsArray[i], OUTPUT);
}
pinMode(btnPinNrsArray[0], INPUT_PULLUP);
lastButtonState = digitalRead(btnPinNrsArray[0]);
}
// main loop for reading buttons' actions
void loop() {
currentMillis = millis();
// read current button state
int btnStateTemp = digitalRead(btnPinNrsArray[0]);
// check if it is the same as in the last time of a loop
// if not, assign current time to the lastDebounceTime
// because now we start debouncing:)
if (lastButtonState != btnStateTemp) lastDebounceTime = millis();
// at that point when the program wants to go on, check if
// there is an appropriate difference from lastDebounceTime
// or if the program should wait
if ((millis()-lastDebounceTime) >= debounceDelay) {
// check if the button state from that loop
// is the same as global button state
if (btnStateTemp != btnState) {
// are different, so assign new value to the global btnState
btnState = btnStateTemp;
// button pressed => 0
if (!btnState) {
// here we have small correction for a starting value of x (-1)
// and for the moment when
// we have already lit all the diodes and want to start over again
if (x >= amountOfPinsUsed || x < 0) x=0;
// if the current diode went out
// and it is time to turn on the next one
else if (!ledStates[x]) x++;
diodePulseToggle();
}
}
// try to clear LCD status
// if button is not pushed & if no diode lit
if (btnState && shouldResetSecondRow()) lcd2ndRowReset();
}
// update lastButtonState (updating with the each loop)
lastButtonState = btnStateTemp;
}
// switch the light of a diode
// write status on the LCD
void diodePulseToggle() {
int ledPinNr = ledPinNrsArray[x];
int ledState = !digitalRead(ledPinNr);
// eliminate blinking
if(ledState != ledStates[x]){
digitalWrite(ledPinNr, ledState);
lcd2ndRowReset();
ledStates[x] = ledState;
writeLCDMessage();
lastLight = x;
previousMillis = currentMillis;
}
//delay(2000);
}
// set cursor below the initially written "Light status "
// and write status of the specific diode
void writeLCDMessage() {
lcd.setCursor(LCD_2_ROW_START_COL, 1);
/*for(int i = 0; i < String(pinColorsPL[x]).length(); i++){
char currLetter = pinColorsPL[x][i];
lcd.setCursor(LCD_2_ROW_START_COL + i, 1);
if (currLetter == "ł") {
lcd.write(byte(0));
} else if (currLetter == "ó") {
lcd.write(byte(1));
} else if (currLetter == "ż") {
lcd.write(byte(2));
} else {
lcd.print(pinColorsPL[x][2]);
}
}*/
String stringToPrint = String(": ") + (ledStates[x] ? "ON" : "OFF");
if(pinColorsPL[x] == "żółty") {
lcd.write(byte(2));
lcd.write(byte(1));
lcd.write(byte(0));
lcd.print(pinColorsPL[x][6]);
lcd.print(pinColorsPL[x][7]);
lcd.print(stringToPrint);
Serial.println("\nżółty" + stringToPrint);
} else {
stringToPrint = pinColorsPL[x] + stringToPrint;
lcd.print(stringToPrint);
Serial.println("\n" + stringToPrint);
}
}
// return a boolean saying whether to reset the 2nd row
// if a second has passed and the text is still visible on the LCD
bool shouldResetSecondRow(){
// if last light went out
if (!ledStates[x] && lastLight == x) {
// wait a specific time
int millisDifference = currentMillis-previousMillis;
return millisDifference >= interval;
} else {
return false;
}
}
void lcd2ndRowReset() {
lcd.setCursor(0, 1);
lcd.print(" ");
}
void createSpecialCharacters() {
// maximum is 0 - 7
// reset character to avoid problem
// with displaying letters
// after e.g. chaning their index nr
//lcd.createChar(, resetCharacter);
//lcd.createChar(, a_);
//lcd.createChar(, resetCharacter);
//lcd.createChar(, c_);
//lcd.createChar(, resetCharacter);
//lcd.createChar(, e_);
lcd.createChar(0, resetCharacter);
lcd.createChar(0, l_);
//lcd.createChar(, resetCharacter);
//lcd.createChar(, n_);
lcd.createChar(1, resetCharacter);
lcd.createChar(1, o_);
//lcd.createChar(, resetCharacter);
//lcd.createChar(, s_);
//lcd.createChar(, resetCharacter);
//lcd.createChar(, z__);
lcd.createChar(2, resetCharacter);
lcd.createChar(2, z_);
lcd.createChar(3, resetCharacter);
lcd.createChar(3, heartSymbol);
//lcd.write(byte(0));
//lcd.write(byte(1));
//lcd.write(byte(2));
//lcd.write(byte(3));
//lcd.write(byte(4));
//lcd.write(byte(5));
//lcd.write(byte(6));
//lcd.write(byte(7));
}