Pages: [1] 2   Go Down
Author Topic: Trouble with programming logic  (Read 891 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello. I tried to do a basic countdown timer, that shows output on LCD. This is the code
Code:
#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
const int SSB = 6;// StartStop button
const int RB = 7;// Reset button
const int PB= 8;//Setup button
int StartStop=0;
int Reset=0;
int Setup=0;
int htime=0, mtime=0, stime=0; // variables for hours, minutes and seconds

void setup()
{
  lcd.begin(20, 4);
  lcd.print("Countdown timer");
  lcd.setCursor(2,1);
  lcd.print(":");//printing separation marks
  lcd.setCursor(5,1);
  lcd.print(":");  //printing separation marks
  pinMode(SSB, INPUT);
  pinMode(RB, INPUT);
  pinMode(PB, INPUT);  
}

void loop()
{
  Reset=digitalRead(RB);
  delay(50);
  if (Reset == HIGH){htime=0; mtime=0; stime=0;}//if reset is pressed all time variables go to 0
  lcd.setCursor(6, 1);//used to print all zeros on LCD
  lcd.print(stime);//used to print all zeros on LCD
  lcd.setCursor(3, 1);//used to print all zeros on LCD
  lcd.print(mtime);//used to print all zeros on LCD
  lcd.setCursor(3, 1);//used to print all zeros on LCD
  lcd.print(htime);//used to print all zeros on LCD
  StartStop=digitalRead(SSB);//if start is presed program goes to count function
  delay(50);
  if(StartStop == HIGH){count;}//if start is presed program goes to count function
  Setup=digitalRead(PB);
  delay(50);
  if (Setup==HIGH)//if setup is pressed stime is incremented.
  {
    lcd.setCursor(6, 1);
    stime++;
    lcd.print(stime);
    if (stime>=60) //after stime reaches 60 seconds it should increment mtime, reset stime to 0 and start counting again.
    {
      stime==0;
      lcd.setCursor(3, 1);
      mtime++;
      lcd.print(mtime);
      if (mtime>=60)
      {
        mtime=0;
        lcd.setCursor(3, 1);
        htime++;
        lcd.print(htime);
      }
    }
  }
}
void count()// count function
{
  do
  {
    do
      {
        do
          {
            lcd.setCursor(6, 1);
            stime--;//program enters this do-while loop and decrement stime to 0 and then mtime, and htime
            lcd.print(stime);
            delayMicroseconds(16667);//specific delay because I need it to go faster then seconds
            if(StartStop == HIGH) {loop;}//if startstop button is pressed program jumps to loop -> changed "loop" to "return"
            if (Reset == HIGH){htime=0; mtime=0; stime=0; loop;};//resets time variables and jumps to loop-> changed "loop" to "return"
          }while(stime>=0);
        lcd.setCursor(3, 1);
        mtime--;
if (mtime>0){stime=60;}// added this line. count shoud be countdown timer with specific time
        lcd.print(mtime);
      }while(mtime>=0);
      lcd.setCursor(3, 1);
      //lcd.print(htime);
      htime--;
if (htime>0){mtime=60;}// added this line. count shoud be countdown timer with specific time
      lcd.print(htime);
  }while(htime<=0);
}

My problem is in loop, where stime should be reseted it keeps counting to 61, 62, and further. Also reset and startstop doesn't work. I tested button they are connected properly, and LCD works.
« Last Edit: January 20, 2013, 12:49:21 pm by schumo » Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 614
Posts: 49372
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Also reset and startstop doesn't work.
Quote
I tested button they are connected properly
One of these two statements is wrong. If the switches are wired correctly, the they should work. That they don't means that the switches are not wired correctly.

It is far easier to connect one side of the switch to ground, and the other side to a digital pin, and turn on the pullup resistor, than it is to deal with external pullup or pulldown resistors.
Logged

Scotland
Offline Offline
Edison Member
*
Karma: 26
Posts: 1325
Have you had your Arduino fix today?
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

stime==0;

should be stime = 0;
Logged

Drew.
http://www.uk-pcb.co.uk - My UK Based PCB Fab & Assembly Company
Design work undertaken
SMD & Thru-Hole assembly

Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for the quick reply. Buttons work, i tested it in different code, where i count every time i press it. They are not disconnected or anything. I just realized that reset works, but because of LCD i thought it doesn't work(LCD resets first number, and when coundown reaches next digit it overwrite the previous.) There is still problem with StartStop
Quote
stime==0;

should be stime = 0;
i would never see that smiley
« Last Edit: January 20, 2013, 12:07:03 pm by schumo » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

After further testing, i thing that the problem is with the function, because after clicking startstop button program doesn't enter count subroutine
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 614
Posts: 49372
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

That count() function is atrocious.

Code:
            if(StartStop == HIGH) {loop;}//if startstop button is pressed program jumps to loop
This isn't how to call a function. Even if it were, you should NEVER call loop() from another function. Learn to use return or break statements.

A do/while loop is executed at least once. In some cases, that is one too many times. A while statement is executed at least zero times. In most cases, that is a better minimum number of times.

// Comments are a good thing. There is nothing to explain what the oddball count() function is doing. Or, is supposed to do.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm new at this so some mistakes are expected smiley I changed the count so it doesn't use loop, but return. Count function should count backward to 0, from the previusly set variables htime, mtime and stime. I will edit my first post to comment that. thx
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 614
Posts: 49372
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
  if(StartStop == HIGH){count;}//if start is presed program goes to count function
The comment is wrong. This is not how to call count().
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 302
Posts: 26324
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
if(StartStop == HIGH) {loop;}//if startstop button is pressed program jumps to loop
No it doesn't, nor should you even attempt to.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 217
Posts: 13734
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
i would never see that
even with many years experience these kind or typos slip through.

Furthermore your code is not structured in layout. Good layout helps creating readable code.
Good variable names help too.

Here a partially code that is more structured to get started.
Not all details are filled in, but you should be able to fix those
Code:
#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

const int SSB = 6;    // StartStop button
const int RB = 7;     // Reset button
const int PB = 8;      //Setup button
int StartStop = 0;
int Reset = 0;
int Setup = 0;

int hours = 1;
int minutes = 2;
int seconds = 20;

unsigned long lastSecond;
int running = 0;             // state of the timer  0 = idle    1 = running   ...

void setup()
{
  lcd.begin(20, 4);
  lcd.print("Countdown timer");
  lcd.setCursor(2,1);
  lcd.print(":"); //printing separation marks
  lcd.setCursor(5,1);
  lcd.print(":");  //printing separation marks
  pinMode(SSB, INPUT);
  pinMode(RB, INPUT);
  pinMode(PB, INPUT);  
  
  lastSecond = millis();
}

void loop()
{
  // MAKE THE MEASUREMENTS
  int startstop = digitalRead(SSB);
  int reset = digitalRead(RB);
  int setup = digitalRead(PB);
  unsigned long now = millis();

  // DO THE MATH
  if (reset == HIGH)
  {
    hours = 0;
    minutes = 0;
    seconds = 0;
    return;               // loop will automatically be called again after return
  };
  if ( startstop == HIGH )
  {
    // fix the start stop state here
    running = 1;
  }
  if (running == 1)
  {
    // adjust the seconds minutes and hours here when a second has passed.
    // tip: look at blink without delay for timing  
     // tip use the var lastsecond
  }


   // DISPLAY THE RESULTS
   lcd.setCursor(0, 1);
   lcd.print(hours);
   lcd.setCursor(3, 1);
   lcd.print(minutes);
   lcd.setCursor(6, 1);
   lcd.print(seconds);
}

Your turn to :
- implement the seconds minutes and hours math
- implement the start stop behaviour
- fix the errors in the display
- maybe some other issues I forgot
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thank allot, this is a great reference. Trouble is that this is my school assingment, and is very specific. Time must be fastened. I real second my timer must count 60 seconds. Thats why i tried using delaymicros.
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 217
Posts: 13734
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

thats only a small delta. and yes then you need micros.
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

After 8 hours of working i was able to make my program work. There were many mistakes, mostly in coding. Every thing works great except when counting startstop button won't go to loop: If anybody have some sugestions would be most appreciated. The problematic part is commented, its in "count" function.
Code:
#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
const int SSB = 6;
const int RB = 7;
const int PB= 8;
int StartStop=0;
int Reset=0;
int Setup=0;
int htime=1, mtime=58, stime=54;

void setup()
{
  Serial.begin(9600);
  lcd.begin(20, 4);
  lcd.print("Count");
  lcd.setCursor(3,1);
  lcd.print(":");
  lcd.setCursor(7,1);
  lcd.print(":"); 
  pinMode(SSB, INPUT);
  pinMode(RB, INPUT);
  pinMode(PB, INPUT); 
}
void loop()
{
  delay(100);
  Reset=digitalRead(RB);
  delay(50);
  if (Reset == HIGH){htime=0; mtime=0; stime=0;}
  lcd.setCursor(9, 1);
  lcd.print(stime);
  lcd.setCursor(5, 1);
  lcd.print(mtime);
  lcd.setCursor(1, 1);
  lcd.print(htime);
  StartStop=digitalRead(SSB);
  delay(50);
  if(StartStop == HIGH){count();}
  Setup=digitalRead(PB);
  delay(50);
  if (Setup==HIGH)
  {
    lcd.setCursor(9, 1);
    stime++;
    lcd.print(stime);
    Serial.print(stime);
    if (stime>=60)
    {
      stime=0;
      lcd.setCursor(5, 1);
      mtime++;
      lcd.print(mtime);
      Serial.print(mtime);
      if (mtime>=60)
      {
        mtime=0;
        lcd.setCursor(1, 1);
        htime++;
        lcd.print(htime);
        Serial.print(htime);
      }
    }
  }
}
void count()
{
  do
  {
    do
      {
        do
          {
            StartStop=digitalRead(SSB);
            delay(10);
            if(StartStop == HIGH) {loop();}                                                     //this thing here for some reason won't work
            Reset=digitalRead(RB);
            if (Reset == HIGH){ htime=0; mtime=0; stime=0; loop();};               //reset works, but jump to loop won't
            delay(10);
            lcd.setCursor(9, 1);
            stime--;
            lcd.print(stime);
            Serial.print(stime);
            //delay(16);
           }while(stime>0);
        lcd.setCursor(5, 1);
        mtime--;
        lcd.print(mtime);
         Serial.print(mtime);
        if (mtime>0){stime=60;}
      }while(mtime>0);
      lcd.setCursor(1, 1);
      htime--;
      lcd.print(htime);
      Serial.print(htime);
      if (htime>0){mtime=60;}
  }while(htime>=0);
}
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 614
Posts: 49372
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You (still) should not be calling loop(). If you want count() to end at that point, return.

You are still using do/while statements, where while statements are more appropriate.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have tried to use return but it stops the program for a moment then continues. Like i said i'm new to this. I could rewrite it to while loops but, if you could write specific line to exit count() it would be helpfull. I have tried return, break, even goto but nothing seems to work
Logged

Pages: [1] 2   Go Up
Jump to: