Go Down

Topic: Programming LCD display for swtching between inputs (Read 1 time) previous topic - next topic

kurtselva

Anyone can help?

I have made some changes to my codes. But I am still having problem when I press the set pushbutton.
It works fine till it blinks at the LCD position (15,0) but after that when I press the increment pushbutton to increase the values at the dayscounter, it goes back to the freqcounter and increases it. So the program does not run the code for the daycounter..

Anyone can help? The code is:
Code: [Select]
#include <LiquidCrystal.h>                // Include libraries
#include <Servo.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);    // initialize the library with the numbers of the interface pins
Servo myservo;

const int  incrementPin = 6;              // the pin that the increment pushbutton is attached to
const int  setPin = 7;                    // the pin that the set pushbutton is attached to

int freqstate = 0;                        // state of the frequency pushbutton (low or high)
int setstate = 0;
int daystate = 0;

void setup()
{
  pinMode(incrementPin, INPUT);    // initialize the button pin as a input:
  pinMode(setPin, INPUT);
  myservo.attach(9);               // attaches the servo on pin 9 to the servo object
   
  lcd.begin(20,4);                 // LCD has 20 columns, 4 rows
  lcd.setCursor(0,0);              // Choose column 0, row 0( 1st column, 1st row)
  lcd.print("Freq:     Days:");    // Print the stated
  lcd.setCursor(0, 1);             // Choose column 0, row 1
  lcd.print("1st feed time:");     // Print the stated
  lcd.setCursor (0, 2);            // Choose column 0, row 2
  lcd.print("current time:");      // Print the stated
  lcd.setCursor(0,3);              // Choose column 0, row 3(1st column, last row)
  lcd.print("");                   // Print the stated
   
}

void loop()
{
   for ( int freqcounter = 2; freqcounter < 5; freqcounter ++)  // freq value from 2 to 4
   {
     freqstate = digitalRead (incrementPin);
       if (freqstate == HIGH)
       {
         lcd.setCursor (5,0);         // set at 5th column, 0th row
         lcd.blink();
         lcd.print(freqcounter);                                 // print value of freq
       
         if (freqcounter > 4)                                    // if freq value more than 4, reset to 2
         {
           freqcounter = 2;
         }
         delay(300);
       }
     }
     
     setstate = digitalRead(setPin);            // read the pushbutton set input pin:
     if (setstate == HIGH)                    // if the state has changed, increment the counter
    {
                                 
      lcd.setCursor(15,0);
      lcd.blink();
     
   for ( int daycounter = 1; daycounter < 11; daycounter ++)  // freq value from 2 to 4
   {
     daystate = digitalRead (incrementPin);
       if (daystate == HIGH)
       {
         lcd.setCursor (15,0);         // set at 5th column, 0th row
         lcd.blink();
         lcd.print(daycounter);                                 // print value of freq
       
         if (daycounter > 10)                                    // if freq value more than 4, reset to 2
         {
           daycounter = 1;
           
         }
         
         
         delay(300);
       }
     }
}
}

       
         
     

UKHeliBob

What is the for loop doing there ?

The idea using your 2 buttons is to use one of them to change what you are setting (frequency, days or first feed time) and the other one to change the value.  So, each time you press the set button the program knows which setting to change.

Code: [Select]
loop()
read the whatToSet button
if button is pressed
  update a state counter (1=frequency, 2=days, 3= first feed time)
  deal with rollover
  move the LCD cursor
end of if

read the setValue button
if button is pressed
  if state counter is 1
    update frequency
  end of if
  else
  if state counter is 2
    update days
  end of if
  else
  if state counter is 3
    update first feed time
  end of if
end of if
end of loop()

Get this much working and you are well on the way
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

kurtselva

Looks like this was what I was looking for..

But I am unsure of programming the updating part and the rollover..
Can I get an example please?

UKHeliBob

You are already doing the rollover
Code: [Select]

if (freqcounter > 4)                                    // if freq value more than 4, reset to 2
{
   freqcounter = 2;
}


As to updating you do something similar.
Code: [Select]
if button is pressed
  if state counter is 1
    frequency counter = frequency counter +1 (CLUE:there is a neat way of doing this)
    deal with rollover (as above) 
    show frequency counter on the LCD
  end of if


Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

kurtselva

Oh so that is called rollover :)

How am I supposed to declare the state counter? As 1 = freq, 2 = day, 3 = time and son on...
So do I declare it as int statecounter = an array?
Or have differrent state counters for each input? Like statecounter1 = freq, statecounter2 = day and so one?

UKHeliBob

Declare the state counter as an int.  You can then increment it (and rollover) to your heart's content.  The check for what state the input is at is then easy

Code: [Select]

if (state == 1)
{
  //do stuff here
}

This being C you can also give each state its own name to make it more obvious what you are testing for but walk before you run and include plenty of comments.

By the way, your button input really needs to be debounced or it will be unreliable but you have plenty of other things to do so I suggest that you put it on the 'to do' list and accept odd responses to buttons for now.
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

kurtselva

I have tried doing the code. But there is problem.

When I press the setbutton, instead of the cursor going to the freq input, it goes to the days input and starts to increment non-stop immediately, without even pressing the increment button..

Made some changes but does not seem to rectify the problem..

Anyone able to spot the mistake?

Code: [Select]
#include <LiquidCrystal.h>                // Include libraries
#include <Servo.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);    // initialize the library with the numbers of the interface pins
Servo myservo;

const int  incrementPin = 6;              // the pin that the increment pushbutton is attached to
const int  setPin = 7;                    // the pin that the set pushbutton is attached to

int setState = 0;
int setCounter = 0;
int valueState = 0;
int freqCounter = 0;
int dayState = 0;
int dayCounter = 0;

void setup()
{
  pinMode(incrementPin, INPUT);    // initialize the button pin as a input:
  pinMode(setPin, INPUT);
  myservo.attach(9);               // attaches the servo on pin 9 to the servo object
   
  lcd.begin(20,4);                 // LCD has 20 columns, 4 rows
  lcd.setCursor(0,0);              // Choose column 0, row 0( 1st column, 1st row)
  lcd.print("Freq:     Days:");    // Print the stated
  lcd.setCursor(0, 1);             // Choose column 0, row 1
  lcd.print("1st feed time:");     // Print the stated
  lcd.setCursor (0, 2);            // Choose column 0, row 2
  lcd.print("current time:");      // Print the stated
  lcd.setCursor(0,3);              // Choose column 0, row 3(1st column, last row)
  lcd.print("");                   // Print the stated
   
}

void loop()
{
   setState = digitalRead(setPin);            // read the pushbutton set input pin:
     if (setState == HIGH)                    // if the state has changed, increment the counter
     {
       setCounter++;
       
       if (setCounter > 6)
       {
         setCounter = 1;
       }
     }
     
     valueState = digitalRead(incrementPin);
     if (valueState == HIGH)
     {
       if (setCounter == 1)
       {
         lcd.setCursor(5,0);
         lcd.blink();
         {
         freqCounter++;
         lcd.setCursor(5,0);
         lcd.print(freqCounter);
         }
         
         if (freqCounter > 4)
         {
           freqCounter = 2;
         }
       }
     }
     
     else if (setCounter == 2)
     {   
      lcd.setCursor(15,0);
      lcd.blink();
      {
      dayCounter++;
      lcd.setCursor(15,0);
      lcd.print(dayCounter);
         
         if (dayCounter > 10)
         {
           freqCounter = 1;
         }
       }
     }
     
}
       

PaulS

setCounter can have a value between 1 and 6, inclusive.

In the if(valueState == HIGH) block, you only deal with two of the setCounter variables.

You are not detecting edges, and incrementing setCounter only when there is a transition from released to switched for the pin that the switch is attached to. Why not?

You are not detecting edges, and incrementing variables in the if(valueState == HIGH) blocks. Why not?

You are not using the internal pullup resistors for the switch pins. Why not?

UKHeliBob

Time to add some debugging statements to your code.
Code: [Select]
Serial.println(setCounter);
before you read incrementPin.  This will show what it is and hence which setting the increment pin should affect.  Expect it not to be what you think it should be due to key bounce as I mentioned before.  Fix that in a crude way by reading the button twice with delay(50) between the reads to allow the bouncing to stop.  There is a much better way to do it but that can wait.

Serial.println() some messages at various parts of your code so that you can keep track of where it is when it is running and what the values of variables are.  Just before the 'if' tests is a good place.

One thing I did spot is that you have this
Code: [Select]
      dayCounter++;
      lcd.setCursor(15,0);
      lcd.print(dayCounter);
         
         if (dayCounter > 10)
         {
           freqCounter = 1;
         }


2 things about that.
(1) deal with the rollover before outputting dayCounter (same problem with resetting setCounter after outputting it)
(2) you are resetting freqCounter to 1 when dayCounter goes over 10.  I am sure that you can see why that is wrong

Fix those problems then if it still not working set setCounter to a fixed value as if the button had been read and see what happens
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

Go Up
 

Quick Reply

With Quick-Reply you can write a post when viewing a topic without loading a new page. You can still use bulletin board code and smileys as you would in a normal post.

Warning: this topic has not been posted in for at least 120 days.
Unless you're sure you want to reply, please consider starting a new topic.

Note: this post will not display until it's been approved by a moderator.
Name:
Email:

shortcuts: alt+s submit/post or alt+p preview