Greetings, I used this code by Dan Hostler and modified it to work with my Seeeduino XIAO and SSD1306 OLED display. Obviously, I am in dire need of some assistance as the code compiles but does not "run." As I am really just a hack/noob, I cannot trace the program sufficiently enough to find my error(s). I hope to get this core sketch functional so that I may populate it with a project of mine requiring a menu driven interface.
My deepest appreciation in advance to anyone who may be able to look over this code and point out to me what I am missing.
Respectfully - Baran
// Program written by Dan Hostler, October 2020.
// Feel free to use as you need to.
// PayPal donations appreciated at danhostler1985@yahoo.com
// I tried to Modify this sketch to "work" with a Seeeduino XIAO microprocessor and an SSD1306 display.
// by changing references from the LCD display to my OLED display and reducing strings to 10 characters.
// LIBRARIES
#include "I2Cdev.h" // Used in my main program to control the I2C communications
// My SSD1306 is an I2C display
#include <Wire.h> // deals with I2C connections as the sketch grows.
#include <Adafruit_GFX.h> // Calls up the OLED graphics folder.
#include <Adafruit_SSD1306.h> // Calls up the OLED display folder.
//DISPLAY SETUP
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 32
#define OLED_RESET -1
Adafruit_SSD1306 display(OLED_RESET);
#define LOGO16_GLCD_HEIGHT 32 // Sets the display to 032 bits high
#define LOGO16_GLCD_WIDTH 128 // Sets the display to 128 bits long
void i2cSetup() {
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
{ Wire.begin();}
#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
{ Fastwire::setup(400, true);}
#endif
}
// MENU ARRAYS
String menuOption[] = {{"Setting 1"}, {"Setting 2"}, {"Setting 3"}, {"Setting 4"}, {"Setting 5"}}; // Text on the top line
String measurementType[] = {{"[DEG. FAHR]"}, {"[DEG. CEL]"}, {"[POUNDS]"}, {"[INCHES]"}, {"[MPH]"}}; // Text on the bottom line
// I/O PINS ON THE XIAO SEEEDUINO.
// MAKE THESE "CONST INT" VARIABLES AS THESE DO NOT CHANGE IN THE PROGRAM.
const int leftButtonPin = 3; // Pin 3 for "Left" command
const int rightButtonPin = 6; // Pin 6 for "Right" command
const int upButtonPin = 10; // Pin 10 for "Up" command
const int downButtonPin = 8; // Pin 8 for "Down" command
const int enterButtonPin = 9; // Pin 9 for "Enter" command
// NUMBER COUNT OF BUTTON PRESSES AND COUNTER UNITS.
// MAKE THESE A "INT" VARIABLES TO ALLOW FOR NEGATIVE INTEGERS.
int setting1Counter = 0; // Counters for settings 1 - 5
int setting2Counter = 0;
int setting3Counter = 0;
int setting4Counter = 0;
int setting5Counter = 0;
int directionPush = 0; // This counter changes the menu option with each "left" or "right" button push.
int upPressCount = 0; // This counter measures the amount of times the user pushes the "up" button.
int downPressCount = 0; // This counter measures the amount of times the user pushes the "down" button.
// BUTTON PRESS STATES FOR EACH FUNCTION, ALL SET TO "LOW".
// MAKE THESE "BOOLEAN" VARIABLES AS THESE ONLY WILL BE "HIGH" OR "LOW".
boolean buttonStateLeft = LOW; // Button states for the "Left" command
boolean lastButtonStateLeft = LOW;
boolean currentButtonStateLeft = LOW;
boolean buttonStateRight = LOW; // Button states for the "Right" command
boolean lastButtonStateRight = LOW;
boolean currentButtonStateRight = LOW;
boolean buttonStateUp = LOW; // Button states for the "Up" command
boolean lastButtonStateUp = LOW;
boolean currentButtonStateUp = LOW;
boolean buttonStateDown = LOW; // Button states for the "Down" command
boolean lastButtonStateDown = LOW;
boolean currentButtonStateDown = LOW;
boolean buttonStateEnter = LOW; // Button states for the "Enter" command
boolean lastButtonStateEnter = LOW;
boolean currentButtonStateEnter = LOW;
// DEBOUNCE VARIABLES TO MEASURE THE DEBOUNCING TIME OF A BUTTON PUSH.
// MAKE THESE "UNSIGNED LONG" VARIABLES AS THE NUMERICAL VALUE WILL HAVE AN EXTENDED SIZE.
unsigned long lastDebounceTime = 0; // This variable takes a "snapshot" of time when any button is pushed.
unsigned long debounceDelay = 50; // Delay time in milliseconds; the amount of time the button is pressed must be higher than the delay to register a push
// SETUP
void setup() {
Serial.begin(115200); //SET THE BAUD RATE AT 115200
i2cSetup();
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
pinMode(leftButtonPin, INPUT); // SETS THE leftButtonPin AS AN INPUT
pinMode(rightButtonPin, INPUT); // SETS THE rightButtonPin AS AN INPUT
pinMode(upButtonPin, INPUT); // SETS THE upButtonPin AS AN INPUT
pinMode(downButtonPin, INPUT); // SETS THE downButtonPin AS AN INPUT
pinMode(enterButtonPin, INPUT); // SETS THE enterButtonPin AS AN INPUT
delay(1000); // I do not know why there is a delay here . . .
}
// MAIN LOOP
void loop() {
int unitSetting[] = {setting1Counter, setting2Counter, setting3Counter, setting4Counter, setting5Counter}; // This variable holds the individual counters in one array
display.setCursor(0,0); // Menu displayed on the LCD.
display.println(menuOption[directionPush]); // The menuOption that is displayed is determined by the left or right push.
display.setCursor(0,1);
display.println(unitSetting[directionPush]); // The setting counter that is displayed is determined by the left or right push.
display.setCursor(5,1); // This cursor setting fixes the measurementType in one place, preventing offset
display.println(measurementType[directionPush]); // by the unitSetting.
// The program at this point is waiting for a button press.
currentButtonStateLeft = digitalRead(leftButtonPin);
currentButtonStateRight = digitalRead(rightButtonPin);
currentButtonStateUp = digitalRead(upButtonPin);
currentButtonStateDown = digitalRead(downButtonPin);
currentButtonStateEnter = digitalRead(enterButtonPin);
if (currentButtonStateLeft != lastButtonStateLeft || currentButtonStateRight != lastButtonStateRight ||
currentButtonStateUp != lastButtonStateUp || currentButtonStateDown != lastButtonStateDown || currentButtonStateEnter != lastButtonStateEnter)
// If there is a button push on any of the buttons, the following routine runs to check if it was a valid press:
{
lastDebounceTime = millis(); // lastDebounceTime is set equal to the running millis() function.
}
if ((millis() - lastDebounceTime) > debounceDelay)
// If the lastDebounceTime (aka. the "snapshot" time) minus the running millis() function is higher than the set debounce delay, the following routine
// below runs and checks which button was pushed:
{
// The current state for each button is set not equal to the pressed state and when it changes, the pressed state becomes equal to the current state.
// LEFT BUTTON PRESS
if (currentButtonStateLeft != buttonStateLeft) // Left button scrolls the menu options to the left.
{
buttonStateLeft = currentButtonStateLeft;
if (buttonStateLeft == LOW) // Once the button is released, the push is registered and the code below runs.
{
directionPush--; // Both the up and down press counts will be reset to zero when the left button is pushed.
upPressCount = 0;
downPressCount = 0;
}
if (directionPush < 0) // If the user tries to scroll below the first menu option,
{ // the program will loop back to the last menu option.
directionPush = 4;
}
display.clearDisplay();
}
// RIGHT BUTTON PRESS
if (currentButtonStateRight != buttonStateRight) // Right button scrolls the menu options to the right.
{
buttonStateRight = currentButtonStateRight;
if (buttonStateRight == LOW)
{
directionPush++; // Both the up and down press counts will be reset to zero when the right button is pushed.
upPressCount = 0;
downPressCount = 0;
}
if (directionPush > 4) // If the user tries to scroll above the last menu option,
{ // the program will loop back to the first menu option.
directionPush = 0;
}
display.clearDisplay();
}
// UP BUTTON PRESS
if (currentButtonStateUp != buttonStateUp) // Up button scrolls the setting upward.
{
buttonStateUp = currentButtonStateUp;
if (buttonStateUp == LOW && directionPush == 0) // The first 5 times in which the "up" button is pushed, each push will add 1 increment to the setting.
{
upPressCount++;
downPressCount = 0; // The downPressCount is reset to zero.
setting1Counter++;
if (upPressCount > 5) // If the "up" button is pushed more than 5 times consecutively, the setting increment increases by 5
{ // with every "up" button push and resets back when the down, left or right button is pushed.
setting1Counter = setting1Counter + 4;
}
if (setting1Counter > 999) // Sets the setting counter limit to 999. The user cannot increase the counter beyond 999.
{
setting1Counter = 999;
}
}
if (buttonStateUp == LOW && directionPush == 1)
{
upPressCount++;
downPressCount = 0;
setting2Counter++;
if (upPressCount > 5)
{
setting2Counter = setting2Counter + 4;
}
if (setting2Counter > 999) // Sets the setting counter limit to 999. The user cannot increase the counter beyond 999.
{
setting2Counter = 999;
}
}
if (buttonStateUp == LOW && directionPush == 2)
{
upPressCount++;
downPressCount = 0;
setting3Counter++;
if (upPressCount > 5)
{
setting3Counter = setting3Counter + 4;
}
if (setting3Counter > 999) // Sets the setting counter limit to 999. The user cannot increase the counter beyond 999.
{
setting3Counter = 999;
}
}
if (buttonStateUp == LOW && directionPush == 3)
{
upPressCount++;
downPressCount = 0;
setting4Counter++;
if (upPressCount > 5)
{
setting4Counter = setting4Counter + 4;
}
if (setting4Counter > 999) // Sets the setting counter limit to 999. The user cannot increase the counter beyond 999.
{
setting4Counter = 999;
}
}
if (buttonStateUp == LOW && directionPush == 4)
{
upPressCount++;
downPressCount = 0;
setting5Counter++;
if (upPressCount > 5)
{
setting5Counter = setting5Counter + 4;
}
if (setting5Counter > 999) // Sets the setting counter limit to 999. The user cannot increase the counter beyond 999.
{
setting5Counter = 999;
}
}
display.clearDisplay();
}
// DOWN BUTTON PRESS
if (currentButtonStateDown != buttonStateDown) // Down button scrolls the setting downward.
{
buttonStateDown = currentButtonStateDown;
if (buttonStateDown == LOW && directionPush == 0) // The first 5 times in which the "down" button is pushed, each push will subtract 1 increment to the setting.
{
downPressCount++;
upPressCount = 0; // The upPressCount is reset to zero.
setting1Counter--;
if (downPressCount > 5) // If the "down" button is pushed more than 5 times consecutively, the setting increment decreases by 5
{ // with every "down" button push and resets back when the up, left or right button is pushed.
setting1Counter = setting1Counter - 4;
}
if (setting1Counter < -999) // Sets the setting counter limit to -999. The user cannot increase the counter beyond -999.
{
setting1Counter = -999;
}
}
if (buttonStateDown == LOW && directionPush == 1)
{
downPressCount++;
upPressCount = 0;
setting2Counter--;
if (downPressCount > 5)
{
setting2Counter = setting2Counter - 4;
}
if (setting2Counter < -999) // Sets the setting counter limit to -999. The user cannot decrease the counter beyond -999.
{
setting2Counter = -999;
}
}
if (buttonStateDown == LOW && directionPush == 2)
{
downPressCount++;
upPressCount = 0;
setting3Counter--;
if (downPressCount > 5)
{
setting3Counter = setting3Counter - 4;
}
if (setting3Counter < 0) // This code prevents the user from entering
{ // a number below "0".
setting3Counter = 0; // Remove this code if you want to allow in
} // negative numbers on a setting.
}
if (buttonStateDown == LOW && directionPush == 3)
{
downPressCount++;
upPressCount = 0;
setting4Counter--;
if (downPressCount > 5)
{
setting4Counter = setting4Counter - 4;
}
if (setting4Counter < 0) // This code prevents the user from entering
{ // a number below "0".
setting4Counter = 0; // Remove this code if you want to allow in
} // negative numbers on a setting.
}
if (buttonStateDown == LOW && directionPush == 4)
{
downPressCount++;
upPressCount = 0;
setting5Counter--;
if (downPressCount > 5)
{
setting5Counter = setting5Counter - 4;
}
if (setting5Counter < 0) // This code prevents the user from entering
{ // a number below "0".
setting5Counter = 0; // Remove this code if you want to allow in
} // negative numbers on a setting.
}
display.clearDisplay();
}
}
// ENTER BUTTON PRESS
if (currentButtonStateEnter != buttonStateEnter)
{
buttonStateEnter = currentButtonStateEnter;
if (buttonStateEnter == LOW && directionPush == 0) // The Enter button simply enters the setting and flashes a brief message.
{ // Please feel free to expand on this code to add more functions.
display.clearDisplay();
display.setCursor(0,0);
display.println("DEGREES F.");
display.setCursor(0,1);
display.println("ENTERED");
delay(2000);
}
if (buttonStateEnter == LOW && directionPush == 1)
{
display.clearDisplay();
display.setCursor(0,0);
display.println("DEGREES C.");
display.setCursor(0,1);
display.println("ENTERED");
delay(2000);
}
if (buttonStateEnter == LOW && directionPush == 2)
{
display.clearDisplay();
display.setCursor(0,0);
display.println("LBS WEIGHT");
display.setCursor(0,1);
display.println("ENTERED");
delay(2000);
}
if (buttonStateEnter == LOW && directionPush == 3)
{
display.clearDisplay();
display.setCursor(0,0);
display.println("INCHES");
display.setCursor(0,1);
display.println("ENTERED");
delay(2000);
}
if (buttonStateEnter == LOW && directionPush == 4)
{
display.clearDisplay();
display.setCursor(0,0);
display.println("MILES/HOUR");
display.setCursor(0,1);
display.println("ENTERED");
delay(2000);
}
display.clearDisplay();
}
// After a button is pushed and the count recorded, all the states reset back to LOW for the data to be processed correctly.
lastButtonStateLeft = currentButtonStateLeft; // resets the left button state to LOW
lastButtonStateRight = currentButtonStateRight; // resets the right button state to LOW
lastButtonStateUp = currentButtonStateUp; // resets the up button state to LOW
lastButtonStateDown = currentButtonStateDown; // resets the down button state to LOW
lastButtonStateEnter = currentButtonStateEnter; // resets the enter button state to LOW
}