Connect with us

Help with code (c language)

Discussion in 'Microcontrollers, Programming and IoT' started by dustin02rsx, Nov 1, 2012.

Scroll to continue with content
  1. dustin02rsx

    dustin02rsx

    36
    0
    May 18, 2011
    So this has been kind of stumping me the past couple days. Im doing a project in class where a subpart is going to be run off a push button that triggers 3 functions and then resets.

    In class we use ATmega16 microcontrollers in CodevisionAVR IDE
    ive also tried doing it on an arduino board at home with no success.

    Code:
    when a push button is pressed once
    {
    execute command
    }
    
    when the same push button is pressed a second time
    {
    execute another command
    }
    
    when the same push button is pressed a third time
    {
    execute a third command
    }
    
    when the same push button is pressed a fourth time
    {
    reset/off
    }
    here is what i have tried, it enters the first while loop but never exits (ignore the actual command codes inside the if statements as they were replaced with simple code just to check the push button would work, which it didnt)

    Code:
    #include <mega16.h>
    #include <delay.h>
    
    
    unsigned char i=5;
    
    void main (void)
    {
    
    DDRD = 0xFF;  // port d output
    DDRA = 0x00;  // port a input
    
    
    while(1)
    {
    
    if((PINA & 0x80)!= 0)             //if pb is pressed once
    {                                 //falls into while loop
    i=1;
    delay_ms(5);                      //to prevent multiple presses
    }
    
    
    while(i==1)
    {
    if(i==1)
    {
    OCR1A=55;                      //low setting PWM to portd for tac light
    }
    else if((PINA & 0x80)!= 0)         //if pb pressed twice
    {                                 //falls into second while loop
    i=2;
    delay_ms(5);
    }
    }
    
    
    while(i==2)
    {
    if(i==2)
    {
    OCR1A=255;                         //high PWM setting
    }
    else if((PINA & 0x80)!=0)
    {
    i=3;
    delay_ms(5);
    }
    }
    
    
    
    while(i==3)
    {
    if(i==3)
    {
    PORTD=PORTD|0x20;
    delay_ms(2);                         //strobe
    PORTD=PORTD & 0xDF;
    delay_ms(2);                        
    }
    else if((PINA & 0x80)!=0)
    {
    i=4;
    delay_ms(5);
    }
    }
    }
    }

    Ive been stumped on this, ive tried a series of nested if/else statements and while loops. I know i can do this with a for loop but im not positive how to implement the push button into a for loop.

    any advice?

    thanks
     
    Last edited: Nov 1, 2012
  2. CocaCola

    CocaCola

    3,635
    5
    Apr 7, 2012
    The quick and dirty in long hand pseudo basic, sorry my C is rusty and long hand pseudo basic should get the point across, even though the flow is done a little differently... FYI this is just a quick pseudo logic flow, not working code...

    Code:
    press = 0 'default clear value
    
    
    Main:
    
    IF pina = 1 THEN        'button pressed, debounce routine should/could be included
        WHILE pina = 1         'wait while button is held down
        WEND            'button no longer pressed continue
        press = press + 1    'count presses, increase by one
        GOSUB Action        'do whatever routines
    ENDIF
    
    GOTO Main            'loop back for to check for more button presses
    
    
    Action:
    
    If press = 1 THEN
        {do something}
        ENDIF
    
    IF press = 2 THEN
        {do something else}
        ENDIF
    
    IF press = 3 THEN
        {do another thing}
        ENDIF
    
    IF press = 4 THEN
        {
        press = 0
        RETURN
        }
        ENDIF
    RETURN                 'fail safe return code should never get this far
     
  3. dustin02rsx

    dustin02rsx

    36
    0
    May 18, 2011
    Im not familiar with the 'goto' command at all. I was always told not to use it and was never taught what it does.


    I also probably should have put in the original post the arduino code as i wont be back in that class until tuesday to try it there....


    here is what i have in arduino. i cannot for the life of me get it to respond to the push, then release of a push button. it responds on the push no problem. I am using a debouncing IC.

    Code:
    const int led = 10;     //led pin 10
    int pb = 7;                 //push button pin 7
    int i;
    
    
    void setup()
    {
      pinMode(led,OUTPUT);
      pinMode(pb,INPUT);
    }
    
    void loop()
    {
      
      pb=digitalRead(7);                       //pb = pushbutton state high or low
      i=1;                                            // counting variable
      
      if(pb==HIGH)                                //if pb is pressed
      {
       while(i<=4)                                  
       {
        delay(500); 
        digitalWrite(led,HIGH);
        delay(500);
        digitalWrite(led,LOW);
       
        if(pb==HIGH)
        {
        i++;
        }
       }
      }
    }

    in this current state i press the button and it goes into the while loop, but it completely ignores the nested "if" statement and increments the i variable regardless of the state of the push button and will stay in the while loop "x" number of times i have the while(i<=x) set for.
     
    Last edited: Nov 1, 2012
  4. CocaCola

    CocaCola

    3,635
    5
    Apr 7, 2012
    I only posted that code as a logic flowchart, I though I made that clear? It was never intended to be drop in code, just a pseudo map for you to follow that would get the desired results... Once you get it working long hand you can optimize if necessary... The way I wrote the program in my example was pretty much a 1:1 flowchart like transcribe, doing a flowchart of the logic before you write code is always beneficial...

    As for the GOTO I can't help you if you can't be bothered to help yourself a little bit... If you are unfamiliar with GOTO a quick Google search would easily set you straight in no time...

    I know 'GOTO' is taboo in C, but that doesn't mean you can't do the same thing another way or break the rules and use it any :) Any C programing tutorial will cover the 'preferred' way to avoid GOTO in C, probably in the first chapter...

    For now a Google search for "WHILE (1) vs GOTO" might be of interest to you...
     
  5. dustin02rsx

    dustin02rsx

    36
    0
    May 18, 2011
    thank you for your feedback.

    i didnt take it literal for drop in code. i converted your post into C/C++/whatever arduino uses syntactically and i didnt/dont know what goto does or another way to end a while loop. I thought that by making the while comparison false that would end it (that was my way around the goto statement) but for some reason the my nested if statement is being ignored and my variable to end the while statement is incrementing with the while loop instead of with the push button via the "if" statement.
     
  6. CocaCola

    CocaCola

    3,635
    5
    Apr 7, 2012
    In my example the Main loop never ends, it just temporarily jumps out (the GOSUB jump) to a subroutine to do the desired function after a button press and then returns to the Main loop where it left off (the RETURN) to wait for the next press as it loops endlessly...
     
  7. gorgon

    gorgon

    603
    24
    Jun 6, 2011
    You could use a 'switch' / 'case' structure to sort and process on different conditions of the same variable.

    To separate the key presses, use a 'no-pressed key' condition between keys to reset to an idle condition.

    You should also add an overall timer to reset any partial counts if no key pressed inside a time window. Remember to restart the timer for each key pressed.
     
  8. dustin02rsx

    dustin02rsx

    36
    0
    May 18, 2011
    got it working...

    ironically the fool proof code i put in there with a delay was really messing with the button read for starters. So i went to PWM which was the original intent.

    Secondly i wasnt reading the input again once it entered the first while loop. I looked up the goto function and tried it out since the comparison test was finicky...

    Now it almost works perfect, but im pretty sure something is up with my switch debounce IC as i still seem to get double clicks on my tact switch but ill wait to mess with anything until i can put it on an o-scope at school tuesday and see if its software or hardware related.

    edit: (definitely something wrong with my debounce IC because when i make the delay after the button press 300 it works perfect).


    thanks for the help

    Code:
    int PWMpin = 10;
    int i;
    
    void setup()
    { 
      pinMode(7,INPUT);
    }
    
    void loop()
    {
    
    i=0;
    bailout:      //goto return
    
    
    //delay(150);
    
    if(digitalRead(7)==HIGH)            //button pressed once
      {
        delay(100);
      i=1;                      //i==1
      while(i==1)
      { 
       if(digitalRead(7)==LOW)
        {
        analogWrite(PWMpin , 100);
    
        }
        else if(digitalRead(7)==HIGH)    //putton press 2
        {
          delay(100);
          i=2;                           //i=2
          while(i==2)
          {
            if(digitalRead(7)==LOW)
            {
                analogWrite(PWMpin, 250);
            }
             else if(digitalRead(7)==HIGH)  //button press 3rd time
            {
              digitalWrite(PWMpin, LOW);
              delay(100);
              i=0;     
              goto bailout;
            }
          }
        }
        }
      }
    }
    
     
    Last edited: Nov 3, 2012
  9. CocaCola

    CocaCola

    3,635
    5
    Apr 7, 2012
    My suggestion now to deal with the debounce...

    Before the debounce delay in your code put something like this

    while(digitalRead(7)==HIGH) // while button held down
    wend // loop indefinitely while button held down

    This way while the button is pressed it will hold, the second it's not pressed, it will hit the debounce time out and execute whatever... No need to double detect the low state of the pin after this (as in your code), the exit from the while statement is the detection of the release of the button and the debounce time out should catch most inadvertent presses... Doing this should avoid most debounce issues you are having...

    As for the goto, in you code simply wrap that entire bailout in a while(1) { ... } statement and it should loop the same as the goto jump back to the start... Personally I would just leave it like that if it's working and you understand it, but if it's for a school project you might get docked for the goto as it's taboo in C syntax...
     
Ask a Question
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.
Electronics Point Logo
Continue to site
Quote of the day

-