Maker Pro
Maker Pro

Help with code (c language)

dustin02rsx

May 18, 2011
36
Joined
May 18, 2011
Messages
36
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:

CocaCola

Apr 7, 2012
3,635
Joined
Apr 7, 2012
Messages
3,635
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
 

dustin02rsx

May 18, 2011
36
Joined
May 18, 2011
Messages
36
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:

CocaCola

Apr 7, 2012
3,635
Joined
Apr 7, 2012
Messages
3,635
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 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...
 

dustin02rsx

May 18, 2011
36
Joined
May 18, 2011
Messages
36
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...

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.
 

CocaCola

Apr 7, 2012
3,635
Joined
Apr 7, 2012
Messages
3,635
i didnt/dont know what goto does or another way to end a while loop

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...
 

gorgon

Jun 6, 2011
603
Joined
Jun 6, 2011
Messages
603
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.
 

dustin02rsx

May 18, 2011
36
Joined
May 18, 2011
Messages
36
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:

CocaCola

Apr 7, 2012
3,635
Joined
Apr 7, 2012
Messages
3,635
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...
 
Top