Go Down

Topic: Programs Stops  8x into loop() (Read 787 times) previous topic - next topic

dougvanzee

This is my first project, a game for karate students.  Whenever I run the program on my Duemilanove 328, it freezes up after about 8 times through looping.  Reconnecting power, from USB or 12V, restarts the process.  

Here's my code.
Code: [Select]
//game variables
int interval = 5000;                      
int gametime = 0;            
int buzz = 0;
int buzztime = 0;
int buzzPin = 8;

//player variables
int winner = 5;

int button1 = 4;
int button2 = 5;
int button3 = 6;
int button4 = 7;

int val1 = 0;
int val2 = 0;
int val3 = 0;
int val4 = 0;

int ledPin1 = 10;
int ledPin2 = 11;
int ledPin3 = 12;
int ledPin4 = 13;

///////

void setup()
{
 pinMode(buzzPin, OUTPUT);
 pinMode(ledPin1, OUTPUT);
 pinMode(ledPin2, OUTPUT);
 pinMode(ledPin3, OUTPUT);
 pinMode(ledPin4, OUTPUT);
 pinMode(button1, INPUT);
 pinMode(button2, INPUT);
 pinMode(button3, INPUT);
 pinMode(button4, INPUT);
}

/////////

void loop()
{
 if (millis() - gametime > interval) {
   gametime = millis();
   buzztime = millis();
   winner = 0;
   digitalWrite(ledPin1, LOW);
   digitalWrite(ledPin2, LOW);
   digitalWrite(ledPin3, LOW);
   digitalWrite(ledPin4, LOW);
 }
 
 if (millis() - gametime < 500) {
         digitalWrite(buzzPin, HIGH);
       }
       else {
         digitalWrite(buzzPin, LOW);
       }
       

 if (winner == 0) {
   val1 = digitalRead(button1);
   val2 = digitalRead(button2);
   val3 = digitalRead(button3);
   val4 = digitalRead(button4);
   
   if (val1 == LOW) {
     digitalWrite(ledPin1, HIGH);
     winner = 1;
   }
   if (val2 == LOW) {
     digitalWrite(ledPin2, HIGH);
     winner = 2;
   }
   if (val3 == LOW) {
     digitalWrite(ledPin3, HIGH);
     winner = 3;
   }
   if (val4 == LOW) {
     digitalWrite(ledPin4, HIGH);
     winner = 4;
   }
 }
}  


any help would be much appreciated.

AlphaBeta

#1
Apr 13, 2009, 10:12 am Last Edit: Apr 13, 2009, 07:40 pm by AlphaBeta Reason: 1
This was frustrating!

I can not see where the logic error is.

Are you sure it is the code that causes the error?

Does it happen regardless of what you do while it is running?


[edit]
Cool idea, and a clean implementation. :)

Yet another bug caused by arduino examples being non-educative about datatypes.

Playground->DatatypePractices
[/edit]

Ray Andrews

gametime is never set except for in this section of code, after you've waited over 5000 ms

Quote
 if (millis() - gametime > interval) {


after you've gone through that procedure 7-8 times, gametime will be outside of the range of an int (+/- 32767)

halley

Ray Andrews found it -- lesson: always use a long type variable when dealing with millis().  Then you have many days before it fails in the same way.

dougvanzee

Ah! Thats makes sense! thanks for the help!

Ray Andrews

Just out of curiosity, what exactly is it supposed to do ?  I cant quite make it out.  :-?

dougvanzee

There's a push button in four karate targets.  When the buzzer sounds, whoever hits the target (pushbutton) first wins, and that person's LED turns on. I'm adding LCDs with times and points in a week or two, also variable points using a potentiometer.

If you have any suggestions on improving the code or hardware, I'd appreciate!

BetaDelta

The code so far is good.

Maybe you could condense the button checks to:

if ( digitalRead(button1) == 1) {
  ...
}

which will save a few lines.

You could even make a function to test buttons based on the button name.

/me
"C++ : Where friends have access to your private members." - Gavin Russell Baker

Ray Andrews

#8
Apr 13, 2009, 10:21 pm Last Edit: Apr 13, 2009, 11:12 pm by SteelToad Reason: 1
This code is a little smaller, and allows for a maximum reaction time, as well as recording the reaction time for each student.

Code: [Select]

const int buzzer_pin = 8;
const int button_pin[4] = {4,5,6,7};
const int light_pin[4] = {10,11,12,13};

const int buzzer_time = 500;          // how long does the buzzer ring
const unsigned long max_time = 5000;  // how long does the round last

unsigned long start_time = 0;
unsigned long game_time = 0;
unsigned long reaction_time[4] = {0,0,0,0};

boolean winner_determined = false;


void setup()
 {
 pinMode(buzzer_pin, OUTPUT);
 for (int x=0; x<4; x++)
   pinMode(light_pin[x], OUTPUT);
 start_time = millis();
 }

void loop()
 {
 game_time = millis() - start_time;
 
 digitalWrite(buzzer_pin, game_time < buzzer_time );
 
 for (int student=0; student < 4; student++)
   {
   if (digitalRead(button_pin[student]))
     {
     if (reaction_time[student] == 0)  
       reaction_time[student] = game_time;
     if (!winner_determined)  
       {
       winner_determined = true;
       digitalWrite(button_pin[student],HIGH);
       }
     }
   if (game_time > max_time && reaction_time[student] == 0)
     reaction_time[student] = max_time;
   }
 }

dougvanzee

hey thanks for that! i'll try it out.

dougvanzee

what would be the best way to add a pause function to this to resume where the program left off.  I'd have a pushbutton attached for this.

Go Up