Go Down

Topic: 4 bottons in one analog input  (Read 466 times) previous topic - next topic

lionele23

Oct 17, 2020, 02:51 am Last Edit: Oct 17, 2020, 02:56 am by lionele23

Hello people, how are you? I hope you are all well and healthy. I am taking up a project after everything that happened in the world, and I find myself with a problem that I cannot solve alone, so I ask for your help to try to solve it together;
I'm doing a project (in my other posts there are messages related to it) that consists of 4 buttons (up / down / left / right) connected to an analog input. The problem is that I can't understand why even averaging the value it delivers, I can't it gives me a stable value. I touch the buttons and it did not give me the values ​​that it should give.
As it is a keypad made by me, I made another one and at first it worked fine, but then it started to fail.In this last one, they all work except the back button that gives me values ​​between 400 and 700 every time I touch it. Difference from for example the ok button that gives me 822/823 (and which I averaged between 800 and 850) and the one above that gives me 1023.

I don't know if I could explain myself well, but does anyone have an idea why this is happening?
Thank you very much for reading and I wish you all good work and health.






Code: [Select]
val = analogRead(A1);//pushbottons reading
Serial.println(val);

 

  if(val> 1000 && button_flag == 0){
    button_up();
    button_flag = 1;
 };
  if(val > 900 && val < 1000 && button_flag == 0){ 
  button_down();
    button_flag = 1;
 };
  if(val > 870 && val < 900 && button_flag == 0){ 
  button_back();
    button_flag = 1;
 };
  if(val > 800 && val < 850 && button_flag == 0){ 
  button_ok();
    button_flag = 1;
 };
  if(val < 100 && button_flag == 1){ //reset button flag
  button_flag = 0;

  }






Railroader

A good, very good, habbit when writing code is to use comments telling what the lines of code are exoected to do. I don't find one single comment. The code is sterile.
You should also show the entire code. Else You have to find the fault Yourself.
Use Your knowledge. If that's not enough, look for education.
Having knowledge, think outside the box to gain more of it. Only trains run like the train, on the rails. The rest run between the rails.

lionele23

Code: [Select]


#include <LiquidCrystal_I2C.h> //
#include<Wire.h>
#include <Servo.h>
Servo MiServo;
LiquidCrystal_I2C lcd(0x27,16,2);


const int op_cnt = 13;
int current_id;
bool operation;
bool onoff;
struct menu_item {
  int id; //id of menu item (might be same as number in array
  int parent;  //id of upper level menu item
  int sub;  //id of sub menu item, "0" means operation
  int next; //id of next menu item at same level
  int npp;  //not used
  String text; //menu item text
  int operation; //operation code
  int ang1;

} ;

menu_item menus[op_cnt];

// initialize the library with the numbers of the interface pins


String lcd_line1;
String lcd_line2;
int show_data;
unsigned long times;

int button_flag;

//Custom arrow char
byte arrow[8] = {
  B00000,
  B00000,
  B01110,
  B01110,
  B01110,
  B01110,
  B00000,
  B00000
};

void setup() {
   Serial.begin(9600);
   MiServo.attach(11);// pin Servo
  digitalWrite(8,1);// high state to be able to command the relay with low
  digitalWrite(9,1);//  high state to be able to command the relay with low

  pinMode (8,OUTPUT);//Relay Pump nº1
  pinMode (9,OUTPUT);//Relay Pump Nº2
  lcd.init();
  lcd.backlight();
  lcd.clear();
  lcd.print("press down");
  lcd.setCursor(0,1);
  lcd.print("to start..");
  delay(2000);
  
  times = 0;
  current_id = 0;
  operation = false;
 
  menus[0].id = 0;
  menus[0].parent = 0;
  menus[0].npp = 0;
  menus[0].next = 0;
  menus[0].sub = 1;
  menus[0].text = "Welcome!!!                                Press>>>";
  menus[0].operation = 0;  

  
  menus[1].id = 1; menus[1].parent = 0; menus[1].npp = 1; menus[1].next = 2; menus[1].sub = 3; menus[1].text = " MANUAL"; menus[1].operation = 0;
  
  menus[2].id = 2; menus[2].parent = 0; menus[2].npp = 2; menus[2].next = 1; menus[2].sub = 11; menus[2].text =" AUTOMATIC"; menus[2].operation = 0;

 
  menus[3].id = 3; menus[3].parent = 1; menus[3].npp = 1; menus[3].next = 4; menus[3].sub = 0; menus[3].text = "  orange"; menus[3].operation = 110;
  
  menus[4].id = 4; menus[4].parent = 1; menus[4].npp = 2; menus[4].next = 3; menus[4].sub = 0; menus[4].text = "  maracuya"; menus[4].operation = 120;


  
  menus[11].id = 11; menus[11].parent = 2; menus[11].npp = 1; menus[11].next = 12; menus[11].sub = 0; menus[11].text = " 70% 30% "; menus[11].operation = 210;
  menus[12].id = 12; menus[12].parent = 2; menus[12].npp = 2; menus[12].next = 11; menus[12].sub = 0; menus[12].text = " 85% 15% "; menus[12].operation = 220;
  
  
  button_flag = 0;
  
  lcd.begin(16, 2);
  lcd.createChar(8,arrow);
  


}
  


void loop() {
 digitalWrite(8,1);// high state to be able to command the relay with low
  digitalWrite(9,1);//  high state to be able to command the relay with low
   int val;
  val = analogRead(A1);//pushbottons reading

  

  if(val> 1000 && button_flag == 0){
    button_up();
    button_flag = 1;
 };
  if(val > 900 && val < 1000 && button_flag == 0){  
  button_down();
    button_flag = 1;
 };
  if(val > 870 && val < 900 && button_flag == 0){  
  button_back();
    button_flag = 1;
 };
  if(val > 800 && val < 850 && button_flag == 0){  
  button_ok();
    button_flag = 1;
 };
  if(val < 100 && button_flag == 1){ //reset button flag
  button_flag = 0;

  }
  
 

}

void button_up(){
  if(operation == false){
    //get previous id and set menu
    for(int i = 0; i < op_cnt; i++){
      if(menus[i].next == current_id){
        current_id = i;
        break;
      };
    };
    draw_menu(current_id);
  };
}

void button_down(){
  //get next id and set menu
  if(operation == false){
    //get previous id and set menu
  current_id = menus[current_id].next;
    draw_menu(current_id);
  };
}

void button_back(){
  //get parent and set menu
  if(menus[current_id].parent == current_id){
    //turn off screen
  
    onoff = false;
  }
  else{
    if(operation == true){ draw_menu(current_id); operation = false;}else{
      if(operation == false){
        //get previous id and set menu
        current_id = menus[current_id].parent;
        draw_menu(current_id);
      };
    };
  };
}

void button_ok(){
  if(onoff == false){
    onoff = true;
    lcd.display();
  
  }else{
  //get sub or operation and set menu
    if(operation == false && menus[current_id].sub != 0){
      current_id = menus[current_id].sub;
      draw_menu(current_id);
    }else{
      if(operation == false && menus[current_id].sub == 0){
      //handle operations
        show_function(menus[current_id].operation);
        operation = true;
      }else{
        if(operation == true){
          trigger_operation(menus[current_id].operation);
        };
      };
    };
  };
}

void draw_menu(int id){
  lcd.clear();
  
  lcd_line1 = menus[id].text;
  if(menus[id].next != id){
    lcd_line2 = menus[menus[id].next].text;
  }else lcd_line2 = "";
  
  lcd.setCursor(0, 0);
  lcd.print(lcd_line1);
lcd.write(8);
  lcd.setCursor(0, 1);  
  lcd.print(lcd_line2);
  lcd.setCursor(0, 0);



    }
void show_function(int function){
  lcd.clear();
  lcd.setCursor(0,0);
  switch(function){
    case 110:

    lcd.print("to serve orange");
    lcd.setCursor(0,1);
lcd.print ("HOLD  >>>");
    
    
    
    return;
    
    break;
    
    case 120:
  
    lcd.print(" To serve maracuya");
    lcd.setCursor(0,1);
    lcd.print(" hold >>> ");
    
    
  

    
    
    break;
    
    case 210:
 
    lcd.print("Serving  70%30 ");
    lcd.setCursor(0,1);
    lcd.print("wait please");
  
  
  MiServo.write(32);// The cup is Up here
   delay(1000);
   digitalWrite(8,0);
   delay (2000);
   digitalWrite(8,1);
  

  

    digitalWrite(9,0);
    delay(12000);
    digitalWrite(9,1);
  for (int  ang1 = 32; ang1 < 90 ; ang1++ )
    { MiServo.write(ang1);
      delay(50);}//the cup is down here
    
    
    
     lcd.clear();
  
    
    lcd.setCursor(0,0);
    lcd.print(" finished  ");
    lcd.setCursor(0,1);
    lcd.print(" Press <<<<");
  
    
  

    
    break;
    
    case 220:

    lcd.print("Serving 85%15 ");
    lcd.setCursor(0,1);
    lcd.print("wait please");
   digitalWrite(8,0);
   delay (2000);
   digitalWrite(8,1);
  

    digitalWrite(9,0);
    delay(4000);
    digitalWrite(9,1);
  
     lcd.clear();
  
    
    lcd.setCursor(0,0);
    lcd.print(" finished  ");
    lcd.setCursor(0,1);
    lcd.print(" Press <<<<");
        
    delay(2000);
    
  

    
    
    break;
  }
}

void trigger_operation(int function){
  const String on = "ON";
  const String off = "OFF";
  lcd.setCursor(0,1);
  switch(function){
    case 110: while(analogRead(1)> 700){//when the "button ok"is press the pump works
        
      digitalWrite(8,0);}{

      digitalWrite(8,1);
  
    
        lcd.clear();lcd.setCursor(0,0);
      lcd.print(" if you are done");
        lcd.setCursor(0,1);
        lcd.print (" press <<<");
    }
  
    break;
    case 120:
 while(analogRead(1)> 700){ //when "button ok" is press the pump works
      digitalWrite(9,0);}{
      digitalWrite(9,1);
      Serial.println(analogRead(1));
  
      
  
    
      lcd.clear();lcd.setCursor(0,0);
      lcd.print("if you are done ");
        lcd.setCursor(0,1);
        lcd.print (" press  <<< ");
      
    }
  
    
  ; break;
  
  };
 
}




bool switch_relay(int port){
  digitalWrite(port, !digitalRead(port));
  return true;
};





I understand what you are saying and I think you are right, and I apologize for it. Post the complete code with all the comments that I could add to make it a little easier to interpret the code.
I hope it is more consistent this time, but I am available to provide any other information that is relevant.
Thank you!!!


Railroader

The resistor ladder is not the best. Try 4 * 1kOhm. That wull give You a better separation of the values. Make a test print of the readings to know the center of the actual values, verifying the theoretical value.
Use Your knowledge. If that's not enough, look for education.
Having knowledge, think outside the box to gain more of it. Only trains run like the train, on the rails. The rest run between the rails.

lionele23

The resistor ladder is not the best. Try 4 * 1kOhm. That wull give You a better separation of the values. Make a test print of the readings to know the center of the actual values, verifying the theoretical value.
I understand, tomorrow I will make a new keypad with these resistances and I will get the average reading of each button, but I still have a doubt, which I would appreciate if you could help solve:
Why do the buttons change the value? You take out the resistances and measure them out and they continue to maintain their value, but if you read the value when pressing a button it is lower or higher than it should according to the resistance ... in the previous button I was failing the "down" button ... when I made this new one it worked fine for one or two days and then the "back" button stopped working correctly.
The 5v voltage is delivered from the arduino and the masses are all linked together (in fact, those 5v and mass also feed the servomotor from a terminal block and there is no problem with it ..)
thank you very much

TomGeorge

#5
Oct 17, 2020, 11:45 am Last Edit: Oct 17, 2020, 11:46 am by TomGeorge
Hi,
Can I suggest you get rid of ALL the ; after the } in your code?


Quote
current_id = menus[current_id].parent;
       draw_menu(current_id);
     };<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   };<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
 };<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
}
This may help.
https://www.arduino.cc/reference/en/language/structure/control-structure/if/
Tom... :)
Everything runs on smoke, let the smoke out, it stops running....

Railroader

Show us a drawing. I suspect a power issue might be the reason.
Use Your knowledge. If that's not enough, look for education.
Having knowledge, think outside the box to gain more of it. Only trains run like the train, on the rails. The rest run between the rails.

lionele23

Hello, thanks for your answer ... I tried to erase what you indicated but it marks me an error while compiling ... I don't know what I'm doing wrong in that sense.

There I upload a wiring diagram, the power part comes from the pc atx source and the button ladder, the lcd screen and the potentiometer comes from a 5v arduino terminal block.



thanks you so much!!


Railroader

What is that box "5 volt Arduino"? Does it come from the Arduino 5 volt pin?
It's feeding the display, and the pot. As the UNO is fed by the Vin You can't consume that power from the 5 volt pin.
Use Your knowledge. If that's not enough, look for education.
Having knowledge, think outside the box to gain more of it. Only trains run like the train, on the rails. The rest run between the rails.

lionele23




yes, the 5v arduino box is the 5v output pin.
I connect it that way since in another publication that I did that had a problem with the same project they recommended me to do it like this.


he said:
I see in your
other thread (post#19) that you power the button ladder from a different 5volt supply.
That's asking for trouble.

The button string MUST be powered from the 5volt/GND pins of the Arduino for stable A/D results.

Then you only need ONE analogRead (with de-bounce).



Also dangerous (for the Arduino pin) to power the LCD from a different 5volt supply.

Railroader

The Arduino is powered by 9 volt to Vin. There is no way that the poor 5 volt converter on the Arduino board should feed the LCD. When the converter gets overheated it cuts down that 5 volt. The pot can be ok but nothing more.
Why not use the 5 volt from the ATX to the LCD?
Use Your knowledge. If that's not enough, look for education.
Having knowledge, think outside the box to gain more of it. Only trains run like the train, on the rails. The rest run between the rails.

TomGeorge

Hi,
What is this structure supposed to do?

Quote
case 110:
      while (analogRead(1) > 700)
      { //when the "button ok"is press the pump works


        digitalWrite(8, 0);
      }
      {
        digitalWrite(8, 1);
        lcd.clear(); lcd.setCursor(0, 0);
        lcd.print(" if you are done");
        lcd.setCursor(0, 1);
        lcd.print (" press <<<"); 
      }


      break;
Did you begin and write this code, or have  you got it from another source.
The formatting and syntax is all over the place.
Tom... :)
Everything runs on smoke, let the smoke out, it stops running....

lionele23

Thank you very much for your patience and the help you give me, I tell you:
At first I had the lcd screen fed directly from the 5v of the atx but then they told me that it would be risky for it and I put it in the voltage provided by the 5v output pin of the arduino.
Do you think it's okay to leave the potentiometer and the button ladder on the arduino's output pin and feed the screen separately?

tom i'm just a learner of this great arduino world so NO i didn't write the code far from it i got one that suited my needs and used it.
In that part of the code while the "OK" button is pressed, the relay engages one of the diaphragm pumps that moves the liquids, when you release the button, it disengages the pump.

TomGeorge

Hi,
Have you fixed all the { , } , and ; problems.

Tom... :)
Everything runs on smoke, let the smoke out, it stops running....

Railroader

Thank you very much for your patience and the help you give me, I tell you:
At first I had the lcd screen fed directly from the 5v of the atx but then they told me that it would be risky for it and I put it in the voltage provided by the 5v output pin of the arduino.
Do you think it's okay to leave the potentiometer and the button ladder on the arduino's output pin and feed the screen separately?

tom i'm just a learner of this great arduino world so NO i didn't write the code far from it i got one that suited my needs and used it.
In that part of the code while the "OK" button is pressed, the relay engages one of the diaphragm pumps that moves the liquids, when you release the button, it disengages the pump.

Feeding the pot and the ladder will be ok but use higher values in the redistor ladder, some 2.2 - 4.7 kOhm to lower the current there.
Use Your knowledge. If that's not enough, look for education.
Having knowledge, think outside the box to gain more of it. Only trains run like the train, on the rails. The rest run between the rails.

Go Up