// test file to include writing to / reading from EEPROM, blink the builtin LED without using Delay()
// output to serial
// read pushbutton inputs and illuminate red / green LEDs
#include <LiquidCrystal_I2C.h>
#define I2C_ADDR 0x27
#define LCD_COLUMNS 20
#define LCD_LINES 2
LiquidCrystal_I2C lcd(I2C_ADDR, LCD_COLUMNS, LCD_LINES);
#include <EEPROM.h>
// the following was copied from example EEPROM Read file
// initialize the starting address, a value (for each byte) and the count (unsigned long)
int memAddress = 0;
unsigned long memValue;
unsigned long count0 = 0x05; // initial value to place in EEPROM
unsigned long count1 = count0 - 1; // initial value to place in EEPROM
unsigned long count2 = count0 - 2; // initial value to place in EEPROM
unsigned long count3 = count0 - 3; // initial value to place in EEPROM
// debounce values
unsigned long lastDebounceTime = 0; // the last time the output pin was toggled
unsigned long debounceDelay = 50; // the debounce time; increase if the output flickers
// constants won't change. Used here to set a pin number:
const int ledOnboard = LED_BUILTIN; // the board number of the LED pin
const int button1Pin = 8; // the number of the pushbutton pin
const int button2Pin = 9; // the number of the pushbutton pin
const int led1Pin = 2; // the number of the red LED pin
const int led2Pin = 3; // the number of the green LED pin
const int togglePin = 7; //... lucky pin
const long interval = 1000; // interval at which to blink (milliseconds)
// Variables will change:
int led0State = LOW; // led0State used to set the onboard LED
int led1State = LOW; // led1State used to set the red LED
int led2State = LOW; // led2State used to set the green LED
int button1State = LOW; // variable for reading the pushbutton 1 status
int button2State = LOW; // variable for reading the pushbutton 2 status
int lastButton1State = HIGH; // previous state of button 1
int lastButton2State = HIGH; // previous state of button 2
//...
int switchState = HIGH;
// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0; // will store last time LED was updated
void setup() {
// set digital pins as outputs for the LEDs:
pinMode(ledOnboard, OUTPUT);
pinMode(led1Pin, OUTPUT);
pinMode(led2Pin, OUTPUT);
pinMode(togglePin, OUTPUT);
// LCD Initialization
lcd.init();
lcd.backlight();
// Print something
lcd.setCursor(0, 0);
lcd.print("Line 1");
lcd.setCursor(0, 1);
lcd.print("Line 2");
Serial.begin(9600);
// initialize the external pushbutton pins as input, and choose the internal pullup resistor:
pinMode(button1Pin, INPUT_PULLUP);
pinMode(button2Pin, INPUT_PULLUP);
// populate first four (long integer i.e. 4 byte) EEPROM storage locations
// use EEPROM.put if you want to explicitly write
// use EEPROM.update if you want to write only if previous contents will be changed - prevents wear...?
EEPROM.put(memAddress + 0 , count0);
EEPROM.update(memAddress + 0 , count0);
EEPROM.put(memAddress + 4 , count1);
EEPROM.update(memAddress + 8 , count2);
EEPROM.update(memAddress + 12 , count3);
}
// define onboard LED toggle function - if onboard LED is off turn it on and vice-versa
// I think this could be written more concisely but the following code makes it obvious
void toggleLED() {
if (led0State == LOW) {
led0State = HIGH;
} else {
led0State = LOW;
}
}
void loop() {
// here is where you'd put code that needs to be running all the time.
// serial echo
if (Serial.available()) { // If anything comes in Serial (USB)
Serial.write(Serial.read()); // echo it back to Serial (USB)
}
button1State = digitalRead(button1Pin);
button2State = digitalRead(button2Pin);
if (button1State != lastButton1State) {
lastDebounceTime = millis();
}
lastButton1State = button1State ;
if ((millis() - lastDebounceTime) > debounceDelay) {
if (button1State != switchState) {
Serial.print("State change detected! ");
if (button1State == LOW) {
digitalWrite(led1Pin, HIGH);
//...
digitalWrite(togglePin, digitalRead(togglePin) == HIGH ? LOW : HIGH); // toggle that other LED
count1++ ;
}
else {
digitalWrite(led1Pin, LOW);
}
}
switchState = button1State;
}
// same for button 2.
// this code does not apply any debounce logic
if (button2State != lastButton2State) {
if (button2State == LOW) {
// turn LED on:
digitalWrite(led2Pin, HIGH);
count2++;
}
// turn LED on:
digitalWrite(led2Pin, HIGH);
count2++;
} else {
// turn LED off:
digitalWrite(led2Pin, LOW);
}
// check to see if it's time to toggle the onboard LED; that is, if the difference
// between the current time and last time you toggled the LED is larger than
// the interval at which you want to toggle the LED.
unsigned long currentMillis = millis();
unsigned long currentSecs = currentMillis / 1000;
if (currentMillis - previousMillis >= interval) {
// save the last time you toggled the LED
previousMillis = currentMillis;
toggleLED();
// seconds elapsed time serial output
Serial.print("Time ");
Serial.print(currentSecs);
Serial.print("\t");
// read a byte from the current address of the EEPROM
memValue = EEPROM.get(memAddress, memValue);
// print the EEPROM memValue at memAddress
Serial.print("Addr: ");
Serial.print(memAddress);
Serial.print(" ");
Serial.print(memValue, HEX);
Serial.print(" ");
Serial.print("Count1: ");
Serial.print(count1);
Serial.print(" ");
Serial.print("Count2: ");
Serial.print(count2);
Serial.println();
// set the onboard LED to the ledState of the variable:
digitalWrite(ledOnboard, led0State);
// Advance to the next address, when at the end restart at the beginning.
memAddress = memAddress + 4; // increment the memory address by 4 bytes
if (memAddress >= EEPROM.length()) {
memAddress = 0;
}
}
}