toggle an output (and have it shown on a display)

Hi, so i'm not sure how to go about starting this code. I have a fan, LEDs, and lasers hooked up to an uno, and a 128x64 I2c oled display. I want to be able to show on whats on and whats off on the display. the part that has me stumped it how to scroll through option screens with one button, and switch the output state with another.

Ill try to make this sound more clear... how would I make a button make the screen say on, and then off when I press it again? would i use some sort of Boolean function to toggle between the two? and how would I go about selecting different functions from a list of 3 different functions?

I am trying to do something I haven't tried before to expand my knowledge, but I have hit a wall. any guidance you could provide would be greatly appreciated!

side note: I am familiar with writing text to the display, and setting up a very basic input, but that is about as much as I know for this project.

You can have a variable that says what the display state should be, ON or OFF. You can have a code inside of void loop() that watches the button (and debounces it) for being pressed.

So the screen state variable says OFF. When the button is detected as just pressed, that screen state represents THE PAST and so your code changes the variable to reflect THE NEW STATE which is whatever the PAST was not. OFF becomes ON.

This is automation, you deal in time and track what has happened and what's supposed to be happening through values in variables.

You deal in TIME. Every pass through void loop() happens AFTER the last. If your code does not block then that last pass may be less than 20 microseconds ago but even that is LATER -- always LATER.

You can make any automation work like a game. A turn-based automation will be jerky and an RTS automation may be smooth.

Check out the BlinkWithoutDelay sketch in your IDE Examples, section 2. The same lesson is covered on this forum and the web, I give addresses to Nick Gammon's tutorials in my sig space below. These lessons can open up automation for anyone, they're well worth the time to not just go through but to practice on.

Hopefully some or all of this can change your view and make coding projects easier.

ok so I took a look at your links and I think I have an idea for part of the project. I think i can go about it like this:

//include libraries

void setup(){
//setup pin modes
//setup serial communication to display


}


void loop(){

 if (digitalRead(buttonState) == HIGH ){
   
        toggleLaser();

}

}



void toggleLaser ()
  {
   if (digitalRead (Laser) == LOW)
      digitalWrite (Laser, HIGH);
          
          display.println("ON");         //for sake of time i'm not including the code to set cursor, and color
          display.display();

   else
      digitalWrite (Laser, LOW);

          display.println("OFF");
          display.display();


  }

I think this would be the best way to do it? If this would work I'm still not sure of how to change between what i'm toggling. id rather not have to connect a button for every output. as far as I can figure out I might be able to achieve that maybe like this?:

void loop(){

if (buttonOne == HIGH){

x++;
delay(100);

}


if (x == 1){

laserDisplay();                                          //displays the laser info screen

      if (digitalRead(buttonTwo) == HIGH){
         toggleLaser();                                 //same type of code from above
}

if (x == 2){

ledDisplay();                                                //displays the LED info screen

      if (digitalRead(buttonTwo) == HIGH){
           toggleLED();
}


if (x == 3){

fanDisplay();                                           //displays the fan info screen

      if (digitalRead(buttonTwo) == HIGH){
           toggleFan();
}
}

if (x == 4){
int x = 0;           // equal to zero so there is a buffer where nothing will be affected
}


}

would this work? or is there a more simple way of achieving the end results?

I think you're missing it. It's not

 if (digitalRead(buttonState) == HIGH ){

it's

 if (buttonStateJustChanged){

or,

 if (button_State_Now_Low_and_The_Last_Time_We_Looked_It_Was_High){

Check out IDE/file/examples/digital/state change detection.

i guess i’m confused. I thought that this would work:

if (digitalRead(button state) == HIGH){

    toggleOutput();
    delay(debounceTime);

}

this is the code i’ve been trying to throw together:

#include <SPI.h>                          //oled libraries
#include <Wire.h>                         // "
#include <Adafruit_GFX.h>                 // "
#include <Adafruit_SSD1306.h>             // "

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);     //define display

int x;                                   //used to switch between function screens
int buttonOne = 4;
int buttonTwo = 5;
int led = 6;                            //led pin on board
int fan = 7;                            //fan pin on board
int laser = 8;                          //laser pin on board
int debounce = 200;                     //universal wait after button push

void setup() {
  Serial.begin(9600);                   //begin serial communications for display
  pinMode(buttonOne, INPUT_PULLUP);     //use internal resistors
  pinMode(buttonTwo, INPUT_PULLUP);     //connect pin to ground via switch/button
  pinMode(laser, OUTPUT);
  pinMode(fan,OUTPUT);
  pinMode(led,OUTPUT);
  
  display.begin(SSD1306_SWITCHCAPVCC, 0x3c); //initializes display with logo ****make sure line doesn't read 0x3D but instead 0x3c****
  display.display();                         //must use display.display(); after every display command
  delay(2000);
  display.clearDisplay();                    //to avoid weird characters try to clear display befor updating text
}

void loop() {
  if (buttonOne == HIGH) {
    x++;
    delay(debounce);                                  //crude debounce
  }


  if (x == 0) {
    mainDisplay();
  }

  if (x == 1) {
    laserDisplay();                                          //displays the laser info screen
    if (digitalRead(buttonTwo) == HIGH) {
      toggleLaser();
      delay(debounce);
    }
  }

  if (x == 2) {
    ledDisplay();                                              //displays the LED info screen
    if (digitalRead(buttonTwo) == HIGH) {
      toggleLED();
      delay(debounce);
    }
  }

  if (x == 3) {

    fanDisplay();                                           //displays the fan info screen
    if (digitalRead(buttonTwo) == HIGH) {
      toggleFan();
      delay(debounce);
    }
  }

  if (x == 4) {
    int x = 0;           // equal to zero so there is a buffer where nothing will be affected
  }


}




/*
   Main display screen code===================================================================================================
*/

void mainDisplay() {
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0, 0);
  display.println("Mode");

  display.setTextColor(WHITE);
  display.println("Laser");
  if (digitalRead(laser) == HIGH) {
    display.setTextColor(WHITE);
    display.setCursor(64, 0);
    display.print("ON");
  }
  else {
    display.setTextColor(WHITE);
    display.setCursor(64, 0);
    display.print("off");
  }
  display.setTextColor(WHITE);
  display.println("led");
  if (digitalRead(led) == HIGH) {
    display.setTextColor(WHITE);
    display.setCursor(64, 0);
    display.print("ON");
  }
  else {
    display.setTextColor(WHITE);
    display.setCursor(64, 0);
    display.print("off");
  }

  display.setTextColor(WHITE);
  display.println("Fan");
  if (digitalRead(fan) == HIGH) {
    display.setTextColor(WHITE);
    display.setCursor(64, 0);
    display.print("ON");
  }
  else {
    display.setTextColor(WHITE);
    display.setCursor(64, 0);
    display.print("off");
  }

  display.display();
  delay(200);
  display.clearDisplay();
}

/*
   Laser code==========================================================================================================
*/

void laserDisplay() {

  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0, 0);
  display.println("Mode");

  display.setTextColor(WHITE);
  display.println("Laser");
  if (digitalRead(laser) == HIGH) {
    display.setTextColor(WHITE);
    display.setCursor(64, 0);
    display.print("ON");
  }
  else {
    display.setTextColor(WHITE);
    display.setCursor(64, 0);
    display.print("off");
  }
}
//==================================
void toggleLaser()  {
  if (digitalRead(laser) == LOW)
    digitalWrite (laser, HIGH);
  laserDisplay();

  else
    digitalWrite(laser, LOW);
  laserDisplay();
}


/*
   LED code =========================================================================================================
*/

void ledDisplay() {

  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0, 0);
  display.println("Mode");

  display.setTextColor(WHITE);
  display.println("led");
  if (digitalRead(led) == HIGH) {
    display.setTextColor(WHITE);
    display.setCursor(64, 0);
    display.print("ON");
  }
  else {
    display.setTextColor(WHITE);
    display.setCursor(64, 0);
    display.print("off");
  }
}

void toggleLED() {
  if (digitalRead(led) == LOW) {
    digitalWrite (led, HIGH);
    ledDisplay();
  }
  else {
    digitalWrite(led, LOW);
    ledDisplay();
  }


  /*
     Fan code =========================================================================================================
  */

  void fanDisplay() {

    display.clearDisplay();
    display.setTextSize(1);
    display.setTextColor(WHITE);
    display.setCursor(0, 0);
    display.println("Mode");

    display.setTextColor(WHITE);
    display.println("Fan");
    if (digitalRead(fan) == HIGH) {
      display.setTextColor(WHITE);
      display.setCursor(64, 0);
      display.print("ON");
    }
    else {
      display.setTextColor(WHITE);
      display.setCursor(64, 0);
      display.print("off");
    }

  }

  void toggleFan() {
    if (digitalRead(fan) == LOW) {
      digitalWrite(fan, HIGH);
      fanDisplay();
    }

    else {
      digitalWrite(fan, LOW);
      fanDisplay();
    }
  }

sorry about its length, and the other stuff thrown in that doesn’t exactly lend its self to this discussion.

The code to watch the button state has to deal with button “bounce”, sparks that cross the gap when the contacts are very close and can look like many button presses.

You can get button code from a lot of people and there will be differences. Mine maintains a status variable while some others do it different. I’ll attach the library files and example sketch here. you can put them all in the project folder unless you want to use the library with other sketches then they need to go into the right libraries folder which I haven’t bothered with in a long while.

All those delays screw your code from any other way to debounce at all. They also slow your code at best.

Don’t expect that library to work with blocking code (delays). DO mess with the library example to first find out how it works and then to make it do what you want.

Remember that you want to toggle the led on with one press and off with the next. With every new press, reverse the led.

Gammon Forum : Electronics : Microprocessors : How to do multiple things at once ... like cook bacon and eggs <---- the do multiple things at the same time lesson explained

button.h (1.06 KB)

button.cpp (2.19 KB)

button_class.ino (927 Bytes)

will this work with internal pull up resistors?

It sets the read pin to ground-safe INPUT_PULLUP, the internal 20K to 50K resistance and reverse-logic are used.

You don't need to add any pull-anythings. I test with a jumper as button. I ground it to press.