different problems in the same project

Hello, how are you? First, I want to thank you for the patience you have had with a novice like me and for all the help you gave me, I hope one day I can return the favor by contributing in the forum.

I am having a problem with a project, that although it is being functional, it is far from working correctly, for that, I would have to adjust some things; I must say that it is not a code written by me, I found it on the web and modified it according to my requirements .. (And therefore, the reason for the failures / errors).
The project itself is a small cabinet (like a fontain soda) that would dispense two liquids in a glass (for the example, we will use the code orange and passion fruit).

It has two modes: Automatic and Manual.
- In the automatic mode, the ratio of each liquid is chosen (70% of the first and 30% of the second) or (85% of the first and 15% of the second). The amount is "calculated" by the operating time of two pumps Diaphragm R385 commanded by a 4-channel relay module. A servo tilts the glass while the pumps are running and once finished it starts to go down.
- In manual mode one chooses the proportions holding the button which makes the relay activate and thus the pump works. The servo will be tilted manually by means of a 10k potentiometer (Not automatically because the operating times are chosen different from "Mode automatic "and could spill or return to 0º while a pump is running).
Problems that I am having and that I did not know how to solve With the program:
- When you start the program, it forces me to press the button down and then have to press the forward button, and just then "Automatic" or "Manual" appears; that is why it just starts printing on the LCD "press down to start "and then" welcome press >>> ".
- Something I would love to do is that after a time "x" (for example, 3 seconds ..) if no button has been pressed, return to the choice of "manual or automatic" and not have to press the back button all the time .

With the Buttons
When the pumps are operated manually, the button does not always read well and sometimes, while the button is pressed, it does not work, or while it is pressed, it cuts automatically, or it works intermittently. (This in Automatic mode does not happen, so related to the button itself, the connection diagram of the buttons is this
with the ServoMotor:
- ~~ I can decrease the degrees until it is vertical once the 2nd pump ends (it is only put in the 70% -30% mode but the operation would be the same, I am using that graduation to test the program but it applies to the two ... the only thing that varies is the time that each pump works), it could be like this but the main idea would be that if the time of pump # 2 is 4 seconds, for example, once 2 seconds have elapsed, it will start to drop and do not wait for I'm done. Honestly, I have the novice problem with using delay, I'm reading about millis (); but I still have not been able to make some functional lines, I know that with this I could manage to do these two things "simultaneously".~~
- And another problem I have with the servo (I add the code I have to use the manual servo but it is not in the FINAL program yet) is that in MANUAL mode I should tilt it using a potentiometer. That works correctly, but what I want to do is that the potentiometer can only be used while in the manual mode, and that it is "canceled or deactivated" in the automatic (The servo should work the same because its operation is already programmed but if one were to move the potentiometer nothing should happen in the mode automatic).
If you got here reading, I really appreciate it, I hope I have not written much but the least I can do is try to be as explicit as possible so that if someone wants to, they can help me try to solve any of the problems described. Thanks again!
attachments(
I hope I have uploaded all the files correctly, please excuse me if it was not.)
SERVOMOTOR
PUMP 12v R385
4 channel relay module


[/list]
FINAL2.ino (7.45 KB)

It is much easier for people to help you if you include your code in a Post using the code button </> so it is like this

#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(10);// 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
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;

  }
  
 

}

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(2);// The cup is Up here
   delay(1000);
   digitalWrite(8,0);
   delay (3000);
   digitalWrite(8,1);
  

   

    digitalWrite(9,0);
    delay(4000);
    digitalWrite(9,1);
  for (int  ang1 = 2; ang1 < 90 ; ang1++ )
    { MiServo.write(ang1);
      delay(65);}//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)> 800){//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)> 800){ //when "button ok" is press the pump works
      digitalWrite(9,0);}{
      digitalWrite(9,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;
};

...R

thanks robin,i tried but it appeared to me that it was very long.. :slight_smile:

i did not look beyond this:

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
Serial.println(val);

Please change the code so the Serial.println(val); is ONLY done when val is different from the last time through the loop.

Do this by comparing the value to the previous value and if equal, skip the print.

Paul

Paul_KD7HB:
i did not look beyond this:

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
Serial.println(val);

Please change the code so the Serial.println(val); is ONLY done when val is different from the last time through the loop.

Do this by comparing the value to the previous value and if equal, skip the print.

Paul

I have to apologize, I think that I have not erased when I was identifying each button, I thought I had all the tests to make the program "clean", it seems that I am missing ... I will review again ... know how to excuse me.

Hello community! I hope everyone is well, I come to "update" the post, I wanted to comment that the problem with the buttons has been solved, I explain how I realized in case someone in the future will serve my novice experience:

The situation that randomly connected and disconnected is that it did not take a stable value from the analogRead reading, so what I did is press a certain number of times and average the number obtained, and calculate a proportional that does not affect the value of the nearest button. ..that way the fluctuations of the measured values ​​does not affect the recognition of the signal to activate the pump ..

Also, for the moment adjusting the operating times of the pumps, I am able to coincide with the beginning of the decreasing angle of the servomotor, so for now until the tests are more rigorous, I would dare to say that it is at the right timing. I am going to study the millis issue in detail (); that is not under discussion).
So friends, I can cross those two items off the list.
I will continue investigating and testing new solutions for other problems .. If someone can and wants to guide me the sense that I must follow I would greatly appreciate it .. likewise thank you very much for taking the time to read the post if you got here !!!

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.

I think nobody can help you properly any more after spreading your project across several threads, and posting images off-site.
Read the forum posting guidelines before you start your next project.
Leo..

Thanks for the information you gave me, for fear of overloading the arduino (with the backlight, and some LEDs that I was planning to add), feed everything from the 5v coming from the source, what I will do is replace the power supply of at least the buttons and the lcd a on a terminal board powered by arduino.Thank you very much for that! I apologize if I have made any mistake, this is still new to me (including the forum format), I thought that creating a second post was the most indicated since the reason why the first one was created had already been solved and consider that each post should have its "content" (I assumed that talking about keypads or servo in a post of some pumps would lose the coherence of the thread a little)
Regarding the images, try to be as graphic as possible so that it can be understood, I am still "struggling" a bit to upload the photos only to the forum and not use external links, I will try to practice on some message of my own and then edit it to avoid generate discomfort ..

Thank you very much for your answer!!

When using external power supplies, you should at least tie the grounds together, the power supplies, the Arduino, and your circuit board. You don't want a potential difference between the boards that could zap across them and either hurt you or fry one of your components.