5 Buttons & 5 LEDs that can be used simultaneously (Timer?) no Delay

I am trying to configure a simple button/led setup.
I have 5 buttons and 5 LEDs.
I want that if I press Button1 the LED1 lights up for lets say 20/30 seconds, but at the sametime I want that Button 2 through 5 are still usable. And have the same function.

Also like you can see in my Code, it sends a command to a PC.
But somehow I can’t get it to work without using a Delay.

#include <WiFi.h>
#include <SPI.h>
#define INPUT_VOLTAGE 5

//Analog Pin declaration
int analogPin = 0;
int analogPin1 = 1;
int analogPin2 = 2;
int analogPin3 = 3;
//int analogPin4 = 4;
//int analogPin5 = 5;

//Digital Pin declaration
// Auf dem UNO Board mit WIFI Shield sind nur die Pins 2,3,5,6,8 100% nutzbar (4&10 müssen explizit am Anfang als Output und High deklariert werden)
int digitalPin= 2;
int digitalPin1=3;
int digitalPin2=5;
int digitalPin3=6;
//int digitalPin4=8;

float voltage = 0;
//client object
WiFiClient client;
// Wifi radio’s status
int status = WL_IDLE_STATUS;
int sensorValue = 0;

void setup()
{
// initialize the analog pins as INPTUT
analogReference(DEFAULT);
pinMode(analogPin,INPUT);
pinMode(analogPin1,INPUT);
pinMode(analogPin2,INPUT);
pinMode(analogPin3,INPUT);
//pinMode(analogPin4,INPUT);
//pinMode(analogPin5,INPUT);

//initialzie digitial pin

pinMode(digitalPin, OUTPUT); //Relay1
digitalWrite(digitalPin,HIGH); //Led 1 wird auf aus gesetzt
pinMode(digitalPin1, OUTPUT); //Relay2
digitalWrite(digitalPin1,HIGH);
pinMode(digitalPin2, OUTPUT); //Relay3
digitalWrite(digitalPin2,HIGH);
pinMode(digitalPin3, OUTPUT); //Relay4
digitalWrite(digitalPin3,HIGH);
//pinMode(digitalPin4, OUTPUT); //Relay4
//digitalWrite(digitalPin4,HIGH); //Led 4 wird auf high (durch Relay also aus) gesetzt

//Initialize serial and wait for port to open
Serial.begin(9600);

checkWifiShieldPresence();
//WiFi.config(ip);
attemptConnection();

// you’re connected now, so print out the data:
Serial.println(“You’re connected to the network”);
Serial.println("------------------------------------------");
printConnectionInfo();
}

bool checkWifiShieldPresence()
{
Serial.println(“Checking WiFi shield presence…”);
// check for the presence of the shield:
if (WiFi.status() == WL_NO_SHIELD)
{
Serial.println(“WiFi shield not present”);
// don’t continue:
while(true);
}
else
{
Serial.println(“WiFi shield present”);
}
return true;
}

bool attemptConnection()
{
while ( status != WL_CONNECTED)
{
Serial.print("Attempting to connect to WPA SSID: ");
Serial.println(ssid);
// Connect to WPA/WPA2 network:
status = WiFi.begin(ssid, pass);
}
return true;
}

void loop() {

//Read Input Pin A0
sensorValue = analogRead(analogPin);
voltage =sensorValue * (INPUT_VOLTAGE / 123.0);

if(voltage > INPUT_VOLTAGE-1)
{
Serial.println(“BUTTON 1 pressed”);
String message = “callFlashFunction,callCashpoint,1”;
toggleButton(message);
digitalWrite(digitalPin,LOW);
delay(200);
digitalWrite(digitalPin,HIGH);
}
delay(10);
voltage = 0;
sensorValue = 0;

//Read Input Pin A1
sensorValue = analogRead(analogPin1);
voltage =sensorValue * (INPUT_VOLTAGE / 123.0);
if(voltage > INPUT_VOLTAGE-1)
{
Serial.println(“BUTTON 2 pressed”);
String message = “callFlashFunction,callCashpoint,2”;

toggleButton(message);
digitalWrite(digitalPin1,LOW);
delay(200);
digitalWrite(digitalPin1,HIGH);
}
delay(10);
voltage = 0;
sensorValue = 0;

//Read Input Pin A2
sensorValue = analogRead(analogPin2);
voltage =sensorValue * (INPUT_VOLTAGE / 123.0);
if(voltage > INPUT_VOLTAGE-1)
{
Serial.println(“BUTTON 3 pressed”);
String message = “callFlashFunction,callCashpoint,3”;

toggleButton(message);
digitalWrite(digitalPin2,LOW);
delay(200);
digitalWrite(digitalPin2,HIGH);
}
delay(10);
voltage = 0;
sensorValue = 0;

//Read Input Pin A3
sensorValue = analogRead(analogPin3);
voltage =sensorValue * (INPUT_VOLTAGE / 123.0);
if(voltage > INPUT_VOLTAGE-1)
{
Serial.println(“BUTTON 4 pressed”);
String message = “callFlashFunction,callCashpoint,4”;

toggleButton(message);
digitalWrite(digitalPin3,LOW);
delay(200);
digitalWrite(digitalPin3,HIGH);
}
delay(10);
voltage = 0;
sensorValue = 0;

mrosenthal: I am trying to configure a simple button/led setup. I have 5 buttons and 5 LEDs. I want that if I press Button1 the LED1 lights up for lets say 20/30 seconds, but at the sametime I want that Button 2 through 5 are still usable. And have the same function.

Also like you can see in my Code, it sends a command to a PC. But somehow I can't get it to work without using a Delay.

Last time I posted some code how to handle a lot of buttons at the same time was today in this message.

Do you think you can write a "processing()" function for it in addition?

Or do you need some additional help with the programming logic for a non-blocking processing() function?

First of thank you for your reply!

Oh yes, I definitely need more help with that.
I feel like it is only a little change from my current program.

Maybe utilizing the timer library?

Thank you again!

Just to the left of the Quote button is the Code button. It’s supposed to be a paper page with <> on it.

That IDE “Copy for Forum !?feature?!” is complete nonsense for many years.
It’s funny how they can screw up the forum but can’t fix a long known problem.

Before you go much further, you should learn about arrays, indexes and loops.

And you need to learn how Blink Without Delay works so you can ditch those calls to delay().

At the first link at the bottom of this post is a complete commonsense lesson in making multiple things happen at once That explains the problem (blocking), why and how to deal with it.

With arrays each button and led can use the same piece of code as the others, by number.

Instead of

int analogPin = 0;
int analogPin1 = 1; 
int analogPin2 = 2;
int analogPin3 = 3;

This

byte analogPin[ 4 ] = { A0, A1, A2, A3 }; // byte??? Yup. int takes twice the RAM. byte is 0 to 255.

So analogPin1 becomes analogPin[ 0 ] and can do things like

  byte idx; // use as index into the analogPin[] array
  for ( i = 0; i < 4; i++ )
  {
    Serial.println( analogPin[ i ]; // prints each real pin number in turn
  }

Why do you use analog read for buttons? Do you have different buttons each with a different resistor going to the same analog pin? That’s about the legitimate use of that.

Regular analog read takes 100x or more longer than a digital read and buttons are usually digital.

Compounding that is that contact type buttons (the by far most) tend to ‘bounce’ on contact.
You either debounce in hardware (capacitor across each switch is one way) or you debounce in software which is what most people do, some code to replace physical parts.

There are loads of code examples to learn from and there is a lot of code that you can take and use directly. I have both and so do others. Nick Gammon has a blog where when appropriate he shows oscilloscope screens with what’s going on in a circuit, knowing instead of guessing teaching.

If you learn from other sketches, examples and what, and then fix your sketch, you will probably learn the most but it’s up to you to decide what direction you take. You can get help regardless.

mrosenthal: Oh yes, I definitely need more help with that. I feel like it is only a little change from my current program.

Your code looks like you didn't know thatt all "analogue" pins on the UNO can be used the same was as "digital" pins?!

You surely want to connect "buttons" on the pins and don't need any sensor readings?

mrosenthal: Maybe utilizing the timer library?

Or maybe not.

Please confirm this processing logic:

  • If a button is pressed
  • send a message to Serial (message depends on button)
  • put an LED to ON for x seconds (and OUT after that)
  • execute some other function (function depends on button)

Is this correct? Or am I missing something? Which LED pin(s) are to be used with which button pins?

The logic is this

-button is pressed +Send debug message into Serial (Button 1 pressed) +send a message to a PC (CallFlashFunction1) +put an LED to On for 20 seconds

LED 1 is controlled by Button1 and so on

mrosenthal: +put an LED to On for 20 seconds

The same LED for every button pressed?

Or a different LED for each button?

It is like this:

Button 1 turns on LED 1 Button 2 turns on LED 2 Button 3 turns on LED 3 and so on...

mrosenthal: It is like this:

Button 1 turns on LED 1 Button 2 turns on LED 2 Button 3 turns on LED 3 and so on...

Please make a pin number suggestion (analogue or digital pins possible) for - all 5 button pins - all 5 LED pins

In your comment I read // Auf dem UNO Board mit WIFI Shield sind nur die Pins 2,3,5,6,8 100% nutzbar

So which pins can be used for 5 buttons and 5 LEDs?

Or do you want to use a MEGA which has many more pins available than an UNO?

Button 1: analogPin = 0;
Button 2: analogPin1 = 1;
Button 3: analogPin2 = 2;
Button 4: analogPin3 = 3;
Button 5: analogPin4 = 4;

LED 1: digitalPin= 2;
LED 2: digitalPin= 3;
LED 3: digitalPin= 5;
LED 4: digitalPin= 6;
LED 5: digitalPin= 8;

UNO has 20 I/O pins that can be used as digital pins.

From ARDUINO FOUNDATIONS: http://arduino.cc/en/Tutorial/Foundations

Digital Pins: http://arduino.cc/en/Tutorial/DigitalPins

There's more but isn't it more fun to code when you don't know how the machine works?

mrosenthal: Button 1: analogPin = 0; Button 2: analogPin1 = 1; Button 3: analogPin2 = 2; Button 4: analogPin3 = 3; Button 5: analogPin4 = 4;

LED 1: digitalPin= 2; LED 2: digitalPin= 3; LED 3: digitalPin= 5; LED 4: digitalPin= 6; LED 5: digitalPin= 8;

OK, now it's clear which pins to use.

My basic data structure will then be this:

byte buttonPins[]={A0, A1, A2, A3, A4};// pin numbers of all buttons
#define NUMBUTTONS sizeof(buttonPins) // number of buttons (automatically calculated)
byte ledPins[]={2,3,5,6,8}; // pin numbers of all LEDs
#define NUMLEDS sizeof(ledPins) // number of LEDs (automatically calculated)

Stay tuned, I'll work something out for you. But first I'm going shopping now.

I’m back and here is the new demo sketch, handling 5 buttons and 5 LEDs:

#define INPUTMODE INPUT_PULLUP    // INPUT or INPUT_PULLUP
#define BOUNCETIME 5              // bouncing time in milliseconds
#define LEDONTIME 20000L          // led ON time in milliseconds

byte buttonPins[]={A0, A1, A2, A3, A4};// pin numbers of all buttons
#define NUMBUTTONS (sizeof(buttonPins))
// define a struct type for the LEDs
struct led_t {byte ledPin; boolean on; unsigned long onSince;}; 
led_t leds[]={   // define all LEDs, must be same number as NUMBUTTONS in this array
 {2,false,0,},   // ledPin, on, activeSince
 {3,false,0,},
 {5,false,0,},
 {6,false,0,},
 {8,false,0,},
};

byte buttonState[NUMBUTTONS];  // array holds the actual HIGH/LOW states
byte buttonChange[NUMBUTTONS]; // array holds the state changes when button is pressed or released
enum{UNCHANGED,BUTTONUP,BUTTONDOWN};

void input(){
// read the input state and state changes of all buttons
  static unsigned long lastButtonTime; // time stamp for remembering the time when the button states were last read
  memset(buttonChange,0,sizeof(buttonChange)); // reset all old state changes
  if (millis()-lastButtonTime<BOUNCETIME) return;  // within bounce time: leave the function
  lastButtonTime=millis(); // remember the current time
  for (int i=0;i<NUMBUTTONS;i++) 
  {
    byte curState=digitalRead(buttonPins[i]);        // current button state
    if (INPUTMODE==INPUT_PULLUP) curState=!curState; // logic is inverted with INPUT_PULLUP
    if (curState!=buttonState[i])                    // state change detected
    {
      if (curState==HIGH) buttonChange[i]=BUTTONDOWN;
      else buttonChange[i]=BUTTONUP;
    }
    buttonState[i]=curState;  // save the current button state
  }
}

void toggleButton(char* message)
{
  // just send the "message" to serial
  Serial.print("toggleButton: ");
  Serial.println(message);
}

void processing()
{
  char message[40];
  for (int i=0;i<NUMBUTTONS;i++)
  {
    if (buttonChange[i]==BUTTONDOWN)
    {
      digitalWrite(leds[i].ledPin,HIGH);
      leds[i].on= true;
      leds[i].onSince= millis();
      snprintf(message,sizeof(message),"Button%dpressed",i+1);
      Serial.println(message);
      snprintf(message,sizeof(message),"callFlashFunction,callCashpoint,%d",i+1);
      toggleButton(message);
    }
    if (millis()-leds[i].onSince>=LEDONTIME)
    {
      digitalWrite(leds[i].ledPin,LOW);
      leds[i].on= false;
    }
  }  
}

void output(){
// send a message to Serial if a button state (pressed/released) has changed
// button pressed: Send button pin number with minus sign
// button released: Send button pin number
  byte action;
  for (int i=0;i<NUMBUTTONS;i++)
  {
    switch (buttonChange[i])  
    {
      case BUTTONUP: Serial.println(buttonPins[i]);break;
      case BUTTONDOWN: Serial.println(-buttonPins[i]);break;
    }
  }
}


void setup() {
  Serial.begin(9600); // initialize Serial at 9600 baud
  Serial.println("Good night and good luck!");
  // then initialize all buttons
  for (int i=0;i<NUMBUTTONS;i++)
  {
    pinMode(buttonPins[i],INPUTMODE);
    pinMode(leds[i].ledPin,OUTPUT);
  }
}

void loop() {
  input();
  processing();
//  output();
}

The old “output()” function is commented out, the “processing()” function is new.

I have changed the data structure for the LEDs a bit and the LEDs are now in an “array of struct”, to remember on-state and the on-time within the same array element.

For the missing “toggleButton” function I have written some dummy code that just sends the message to Serial. I don’t know what shall happen in that function.