// include the library code:
#include <Wire.h>
#include <Adafruit_RGBLCDShield.h>
#include <utility/Adafruit_MCP23017.h>
#include <NoiascaLiquidCrystal.h>
#include <NoiascaHW/lcd_mcp23017.h>
// Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();
// uint8_t i=0;
// uint8_t buttons = lcd.readButtons();
const byte cols = 16; // columns/characters per row
const byte rows = 2; // how many rows
const byte addr = 0x20; // set the LCD address to 0x20
const byte rs = 7 + 8; // GPIOB7
const byte rw = 255; // not used
const byte en = 5 + 8; // GPIOB5
const byte d4 = 4 + 8; // GPIOB4
const byte d5 = 3 + 8; // GPIOB3
const byte d6 = 2 + 8; // GPIOB2
const byte d7 = 1 + 8; // GPIOB1
const byte bl = 255; // not used
const byte rgbRed = 6; // GPIOA6
const byte rgbGreen = 0 + 8; // GPIOB0
const byte rgbBlue = 7; // GPIOA7
const byte btnSelect = 0; // GPIOA0 Buttons
const byte btnRight = 1; // A1
const byte btnDown = 2; //A2
const byte btnUp = 3; //A3
const byte btnLeft = 4; //A4
const byte button`[]` {btnLeft, btnUp, btnDown, btnRight, btnSelect}; // the 5 buttons on the LCD RGB KEYPAD connected to GPIO A
const byte OFF = HIGH; // The buttons are low active, therefore we need to inverse them
const byte ON = !OFF;
LiquidCrystal_MCP23017_custompin lcd(addr, rs, rw, en, d4, d5, d6, d7, bl, POSITIVE, cols, rows);
//LiquidCrystal_MCP23017_custompin_base lcd(addr, rs, rw, en, d4, d5, d6, d7, bl, POSITIVE, cols, rows); // this is just for internal tests
struct Data {
char line[rows][cols + 1 + 8]; // a buffer for each line[row], with the length of cols + null + some spare place if UTF-8 is needed
};
const Data data`[]` {
{"Text A 0", "Text A 1"},
{"123456789A123456", "123456789B123456"},
{"Latin", "Ä ä Ö ö Ü ü ß"},
{"Symbols", "αβμΣ°÷∞←→"},
{"Text E 0", "Text E 1"}
};
const size_t noOfData = sizeof (data) / sizeof(data[0]); // how many elements in data?
enum class State {FIXTEXT, RUNTIME, RANDOM, newstate} state; // what kind of data should be shown
size_t currentData = 0; // which data should be shown next time
const byte discretePin = A0; // just a pin on the Arduino to read from - not used
// loop through the array of data
void updateFixtext()
{
static uint32_t previousMillis = 0;
static size_t currentLine = 0;
if (millis() - previousMillis > 4000)
{
previousMillis = millis();
Serial.println(data[currentLine].line[0]);
lcd.clear();
lcd.print(data[currentLine].line[0]);
lcd.setCursor(0, 1);
lcd.print(data[currentLine].line[1]);
// increase line for next iteration
currentLine++;
currentLine = currentLine % noOfData;
}
}
//show runtime on LCD
void updateRuntime()
{
static uint32_t previousMillis = 0;
if (millis() - previousMillis > 1000)
{
previousMillis = millis();
Serial.println(F("runtime"));
Serial.println(millis() / 1000);
lcd.clear();
lcd.print(F("runtime"));
lcd.setCursor(0, 1);
lcd.print(millis() / 1000);
}
}
//show a random value on LCD
void updateRandom()
{
static uint32_t previousMillis = 0;
if (millis() - previousMillis > 2000)
{
previousMillis = millis();
Serial.println(F("Random:"));
Serial.println(random(42)); // just print a Random number
lcd.clear();
lcd.print(F("Random:"));
lcd.setCursor(0, 1);
lcd.print(random(42));
}
}
void newstates()
{
static uint32_t previousMillis = 0;
if (millis() - previousMillis > 8000)
{
previousMillis = millis();
lcd.clear();
lcd.print("poopy Button hit");
lcd.setCursor(0,1);
lcd.print("poopy time:");
delay(4000);
int randNumber = random(2);
// lcd.setBacklight(RED);
if (randNumber == 1)
{
lcd.clear();
lcd.print("big");
}
if (randNumber == 0)
{
lcd.clear();
lcd.print("poopy");
}
}
}
// Debounce and Change state detection for the keypad
bool wasPressedKeypad()
{
static uint32_t previousMillis = 0;
static bool previousState = OFF;
bool currentState = lcd.digitalRead(btnSelect);
bool result = false;
if (currentState != previousState && millis() - previousMillis > 40) // Debounce
{
previousMillis = millis();
previousState = currentState;
if (currentState == LOW) {
result = true;
Serial.println(F("pressed"));
}
}
return result;
}
// Debounce and Change state detection for the keypad
bool wasLeftPressed()
{
static uint32_t previousMillis = 0;
static bool previousState = OFF;
bool currentState = lcd.digitalRead(btnLeft);
bool result = false;
if (currentState != previousState && millis() - previousMillis > 40) // Debounce
{
previousMillis = millis();
previousState = currentState;
if (currentState == LOW) {
result = true;
Serial.println(F("pressed"));
}
}
return result;
}
// just an example how to debounce pins on the Arduino
//bool wasPressedDiscrete()
//{
// static uint32_t previousMillis = 0;
// static bool previousState = LOW;
// bool currentState = digitalRead(A0);
// bool result = false;
// if (currentState != previousState && millis() - previousMillis > 40)
// {
// previousMillis = millis();
// if (currentState == LOW) result = true;
// previousState = currentState;
// }
// return result;
//}
void runFSM()
{
switch (state)
{
case State::FIXTEXT :
updateFixtext();
if (wasPressedKeypad())
state = State::RUNTIME;
break;
case State::RUNTIME :
updateRuntime();
if (wasPressedKeypad())
state = State::RANDOM;
break;
case State::RANDOM :
updateRandom();
if (wasPressedKeypad())
state = State::FIXTEXT;
break;
case State::newstate :
newstates();
if (wasPressedKeypad())
state = State::newstate;
break;
}
}
void setup()
{
Serial.begin(115200);
Serial.println(F("\nStart"));
Wire.begin(); // start I2C library
lcd.begin(); // initialize the LCD
lcd.setCursor(1, 0); // set the cursor to a specific position
lcd.print("Hello, world!");
lcd.setCursor(0, 1);
lcd.print("αβμΣ°÷∞←→äöüßÄÖÜ"); // show some special character entered in UTF-8
for (auto & i : button)
lcd.setPinMode(i, INPUT_PULLUP); // activate the internal pullups for the defined buttons
lcd.setPinMode(rgbBlue, OUTPUT); // set the RGB pins to outputs
lcd.setPinMode(rgbRed, OUTPUT);
lcd.setPinMode(rgbGreen, OUTPUT);
lcd.digitalWrite(rgbBlue, OFF); // swith a RGB pin
lcd.digitalWrite(rgbRed, ON);
lcd.digitalWrite(rgbGreen, OFF);
}
void loop()
{
runFSM();
}