Single button Multiple functions

Hello guys XD I'm an Arduino newbie :P I want, as the title says, switch between functions using a single pushbutton. The state counter should increase from 0 to 2 and when it reaches 3 go back at 0. 2 pins are used for the pushbutton. "OUTbutton" is used as OUTPUT and "INbutton" as input and Arduino reads this value to switch. (i know, it's stupid to use 2 buttons when only one is enough) Compiling works, but when uploaded, Arduino starts from ohm() and gets stuck there, not even updating :0 I am posting void loop() here, which does not work as it was meant to..

void loop()
{
  buttonstate = digitalRead(inbutton);
if (buttonstate != lastbuttonstate)
{
 if (buttonstate == HIGH)
   {
   actual++;
   }
 else delay(10);
lastbuttonstate = buttonstate; 
switch(actual){
  case 0:
  range();
  break;
  case 1:
  ohm();
  break;
  case 2:
  farad();
  break;
  case 3:
  actual = 0;
  break;
}
}
}

Sorry for my english, any help would be very appreciated XD

Post the whole sketch, not just the part you think is relevant.

You need to look at the state change detection example. Only increment actual when the switch transitions from released to pressed (or from pressed to released).

Snippets are not preferred here. Post ALL of your code.

Arduino starts from ohm() and gets stuck there, not even updating

We, of course, have no clue what ohm() does (see why snippets are not preferred?). If you call delay() in it, though, you won't be reading the switch while the delay() is happening.

Sorry, thought it was enough =)
Anyway each function works if alone in the program and updates as expected.

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);
int outbutton = 8;
int inbutton = 9;
int buttonstate;
int lastbuttonstate = LOW;
int actual;
int trigpin = A4;
int echopin = A5;
int aPinIn = A0;
int val = 0; 
float Vout = 0.0;
float Vin = 4.66; 
float Rknown = 10000.0; 
float Runknown = 0.0;
float U = 0.0;
float I = 0.0; 
int backlight = 13;
int analogPin = 1; 
int chargePin = 6;      
int dischargePin = 7;  
float resistorValue = 1000.0;   
unsigned long startTime;
unsigned long elapsedTime;
float microFarads;              
float nanoFarads;
float picoFarads;

void setup(){
 pinMode(outbutton, OUTPUT);
 digitalWrite(outbutton, HIGH);
 pinMode(inbutton, INPUT);
 lcd.begin(16, 2);
 pinMode(backlight, OUTPUT);
 pinMode(chargePin, OUTPUT);   
 digitalWrite(chargePin, LOW); 
 pinMode(trigpin, OUTPUT);
 pinMode(echopin, INPUT);
 digitalWrite(backlight, HIGH);
} 



void loop()
{
  buttonstate = digitalRead(inbutton);
if (buttonstate != lastbuttonstate)
{
 if (buttonstate == HIGH)
   {
   actual++;
   }
 else delay(10);
lastbuttonstate = buttonstate; 
switch(actual){
  case 0:
  range();
  break;
  case 1:
  ohm();
  break;
  case 2:
  farad();
  break;
  case 3:
  actual = 0;
  break;
}
}
}

void range() {
  float duration; 
  float cm;
  pinMode(trigpin, OUTPUT);
  digitalWrite(trigpin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigpin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigpin, LOW);

  pinMode(echopin, INPUT);
  duration = pulseIn(echopin, HIGH);
 
  cm = microsecondsToCentimeters(duration);
  
  if (cm > 500){
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Fuori raggio");
    lcd.setCursor(0,1);
    lcd.print("d'azione");
  }
  
  else {

  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Oggetto rilevato");
  lcd.setCursor(0, 1);
  lcd.print(cm);
  lcd.print(" cm distante");
  }
   delay(500);
 }
float microsecondsToCentimeters(float microseconds){
return microseconds / 29 / 2;
}

 

void ohm(){
lcd.clear();
 val = analogRead(aPinIn);
 Vout = (Vin/1024.0) * val;
 U = (Vin - Vout);
 I = (U/Rknown);
 Runknown = (Vout/I);
 lcd.print("Vout: ");
 lcd.print(Vout);
lcd.setCursor(0, 1); 
 lcd.print("R: ");
 lcd.print(Runknown);

 delay(1000); 

}


 void farad(){
   digitalWrite(chargePin, HIGH);  
   startTime = millis();
   while(analogRead(analogPin) < 648){ 
   }
   elapsedTime= millis() - startTime; 
   microFarads = ((float)elapsedTime / resistorValue) * 1000;
    
   if(elapsedTime == 0){
     lcd.clear();
     lcd.print("Inserire un");
     lcd.setCursor(0, 1);
     lcd.print("Capacitore");     
     delay(1000);
   }
   if (microFarads >= 1){
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print((long)microFarads);   
     lcd.print(" microFarad");    
     lcd.setCursor(0,0);
   }
   else if (microFarads <= 1){

     nanoFarads = microFarads * 1000.0; 
     lcd.clear();
     lcd.setCursor(0,0);                                  
     lcd.print((long)nanoFarads); 
     lcd.print(" nanoFarad");  
     lcd.setCursor(0,0);
   }
   if (nanoFarads >= 1){
     picoFarads = nanoFarads * 1000.0; 
     lcd.clear();
     lcd.setCursor(0,0);                                  
     lcd.print((long)picoFarads);
     lcd.print(" picoFarad");  
     lcd.setCursor(0,0);
   }
 
   digitalWrite(chargePin, LOW);   
   pinMode(dischargePin, OUTPUT);   
   digitalWrite(dischargePin, LOW); 
   while(analogRead(analogPin) > 0){
                                    
   }
   pinMode(dischargePin, INPUT);    
 }
delay(1000);

Why?

If no switch is pressed, the code should start in range(). If that is not what is happening, you have a hardware problem with how the switch is wired. How is it wired?

Oops :stuck_out_tongue:
This code is pretty much a copy and paste between other my school science projects, and i left it there. My bad =)
I don’t think it will affect the performance or behavior of the program though.
The infrared sensor in the image is in reality an ultrasonic module (HC-SR04) and the switch is actually a pushbutton.
Sorry for these mistakes, it is and old image.
Anyway, thanks for the speedy replies =)

According to your picture, your switch is wired wrong, the blue wire is not even connected to it, nor is it in the middle pin of the switch (the common pin).

What is the purpose of the 1k and 220 ohm resistors, going from A0 to D6 and D7? Never mind, I see.

Here it is again the breadboard view (this time is correct), but the problem it’s not in the hardware.
I believe it is in the loop() section of the source. I’m trying another solution in the meanwhile =)

It starts in ohm() because the first buttonstate reading is HIGH (assuming the button is not pressed when the code starts), while lastbuttonstate is initialized to LOW. Those two are different and the current state is HIGH, so actual gets incremented to 1 in the first iteration of loop(). If you don't want that to happen, initialize lastbuttonstate to HIGH.

It wasn't bad :roll_eyes:, but it needed to be cleaned up.

void loop()
{
  buttonstate = digitalRead(inbutton);
   if (buttonstate && buttonstate != lastbuttonstate)
    {
      if(actual == 3) actual = 0;
      else actual++;
    }
  lastbuttonstate = buttonstate;

  switch(actual)
  {
    case 0:
    range();
    break;

    case 1:
    ohm();
    break;

    case 2:
    farad();
    break;

    case 3:     // not needed anymore
    actual = 0; //
    break;      //
   }
}

Even with your corrections does not work =( It keeps switching between functions very fast What about a "pause" during function execution? Something like:

while (digitalRead(inbutton)==0)
  {
    delay(10);                        //  debounce
  }

Where should i put this snippet?

Well it does something, so what is it doing?

xawos_newbie: Even with your corrections it doesn't work =(

How about giving a better description of what it is doing right now? Instead of saying "it is stuck", be more explicit: It keeps running the ohm function over and over again or When I press the button multiple times, it will only run the ohm function on each button press; it doesn't run the other functions at all.

Sorry, i'm not used to forums although i read them almost daily :P The Arduino now keeps switching very fast between the 3 functions and they are not readable. When i press the button it does not stop.

Why is your momentary switch connected to two digital pins? It should be connected to a single digital pin (the pin you read) and ground. You also need a pullup resistor. You can simply enable to the pullup resistor using digitalWrite(inbutton, HIGH); after the pinMode() call.

This is going to increment the cases when the button is HIGH. Right now the pin your reading for your button is "floating", you might need a pull down resistor.

if (buttonstate && buttonstate != lastbuttonstate)

Change it to this.

if (buttonstate == HIGH && buttonstate != lastbuttonstate) // makes sure the button is HIGH

If you read this the first time, I changed it, because I confused myself. I iz Idiot :P

Your suggestions changed the situation… Now the program sits on range() and repeats it over and over.
I’ve tried 4 different pushbuttons and they are not the problem. I’ve tried with few other sketches and they work as expected.
I’ve also tried with another Arduino 2009, uploaded the program and nothing, still the same situation.
The code, up to date with the modifications is here:

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);
int inbutton = 9;
int buttonstate = LOW;
int lastbuttonstate = HIGH;
int actual;
int trigpin = A4;
int echopin = A5;
int aPinIn = A0;
int val = 0; 
float Vout = 0.0;
float Vin = 4.66; 
float Rknown = 10000.0; 
float Runknown = 0.0;
float U = 0.0;
float I = 0.0; 
int backlight = 13;
int analogPin = 1; 
int chargePin = 6;      
int dischargePin = 7;  
float resistorValue = 1000.0;   
unsigned long startTime;
unsigned long elapsedTime;
float microFarads;              
float nanoFarads;
float picoFarads;

void setup(){
 pinMode(inbutton, INPUT);
 digitalWrite(inbutton, HIGH);
 lcd.begin(16, 2);
 pinMode(backlight, OUTPUT);
 pinMode(chargePin, OUTPUT);   
 digitalWrite(chargePin, LOW); 
 pinMode(trigpin, OUTPUT);
 pinMode(echopin, INPUT);
 digitalWrite(backlight, HIGH);
} 



void loop()
{
    buttonstate = digitalRead(inbutton);
   if (buttonstate && buttonstate != lastbuttonstate)
    {
      if(actual == 3) actual = 0;
      else actual++;
    }
  lastbuttonstate = buttonstate;
 
  switch(actual)
  {
    case 0:
    range();
    break;

    case 1:
    ohm();
    break;

    case 2:
    farad();
    break;

   }
}

void range() {
  float duration; 
  float cm;
  pinMode(trigpin, OUTPUT);
  digitalWrite(trigpin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigpin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigpin, LOW);

  pinMode(echopin, INPUT);
  duration = pulseIn(echopin, HIGH);
 
  cm = microsecondsToCentimeters(duration);
  
  if (cm > 500){
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Fuori raggio");
    lcd.setCursor(0,1);
    lcd.print("d'azione");
    delay(250);
  }
  
  else {

  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("L'oggetto dista");
  lcd.setCursor(0, 1);
  lcd.print(cm);
  lcd.print(" cm");
  delay(250);
  }
 }
float microsecondsToCentimeters(float microseconds){
return microseconds / 29 / 2;
}

 

void ohm(){
lcd.clear();
 val = analogRead(aPinIn);
 Vout = (Vin/1024.0) * val;
 U = (Vin - Vout);
 I = (U/Rknown);
 Runknown = (Vout/I);
 lcd.print("Vout: ");
 lcd.print(Vout);
lcd.setCursor(0, 1); 
 lcd.print("R: ");
 lcd.print(Runknown);
}


 void farad(){
   digitalWrite(chargePin, HIGH);  
   startTime = millis();
   while(analogRead(analogPin) < 648){ 
   }
   elapsedTime= millis() - startTime; 
   microFarads = ((float)elapsedTime / resistorValue) * 1000;
    
   if(elapsedTime == 0){
     lcd.clear();
     lcd.print("Inserire un");
     lcd.setCursor(0, 1);
     lcd.print("Capacitore");     
     delay(1000);
   }
   if (microFarads >= 1){
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print((long)microFarads);   
     lcd.print(" microFarad");    
     lcd.setCursor(0,0);
   }
   else if (microFarads <= 1){

     nanoFarads = microFarads * 1000.0; 
     lcd.clear();
     lcd.setCursor(0,0);                                  
     lcd.print((long)nanoFarads); 
     lcd.print(" nanoFarad");  
     lcd.setCursor(0,0);
   }
   if (nanoFarads >= 1){
     picoFarads = nanoFarads * 1000.0; 
     lcd.clear();
     lcd.setCursor(0,0);                                  
     lcd.print((long)picoFarads);
     lcd.print(" picoFarad");  
     lcd.setCursor(0,0);
   }
 
   digitalWrite(chargePin, LOW);   
   pinMode(dischargePin, OUTPUT);   
   digitalWrite(dischargePin, LOW); 
   while(analogRead(analogPin) > 0){
                                    
   }
   pinMode(dischargePin, INPUT);    
 }

xawos_newbie: I've tried 4 different pushbuttons

Did you fix the wiring, though?

yes, i did. One wire now goes to pin 9, the other to vcc