Pages: [1] 2   Go Down
Author Topic: Chest game Counter  (Read 706 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 24
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,
 I'm new in using arduino and i have a little knowledge of C language. I tried searching but it seems hard for me to check where's the problem in my program. I don't know how to debug arduino as well..

my Project:
a Chest Game Counter
a player is given 5secs each turn
when they press the set button the remaining time is added to there next turn
they lost if the time goes 0sec.

my problem is that whenever i upload the program in the arduino it doesn't alternate the players, and it doesn't even count.
here's my code

tnx for your kind help and sorry for a newbie question..
tnx more power.

Code:
void setup() {
  pinMode(13, INPUT); //player 1 input
  pinMode(12, INPUT); //player 2 input
  pinMode(11, OUTPUT); //player 1 indicator
  pinMode(10, OUTPUT); //player 2 indicator
  pinMode(7, OUTPUT);     
  pinMode(6, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(2, OUTPUT);
  pinMode(1, OUTPUT);
  pinMode(0, OUTPUT);
}
int pturn = 1;
int counter;
int p1global;
int p2global;

void loop() {

loop1:  //main loop, alternating turns
  pturn = pturn^1;
  switch (pturn) {
  case 0:
    digitalWrite(11, HIGH);
    digitalWrite(10, LOW);
    goto p1;
    break;
  case 1:
    digitalWrite(11, LOW);
    digitalWrite(10, HIGH);
    goto p2;
    break;
  }
p1: //computation for the timer1
  counter = 5;
  p1global = p1global + counter;
  counter = p1global;
  delay(1000);
  goto segmentout;
dlp1:
  counter = p1global - 1;
  p1global = counter;
  delay(1000);
  goto segmentout;

p2:   //computation for the timer1
  counter = 5;
  p2global = p2global + counter;
  counter = p2global;
  delay(1000);
  goto segmentout;
dlp2:
  counter = p2global - 1;
  p2global = counter;
  delay(1000);
  goto segmentout;

segmentout: //7-segment display
  switch (counter) {
  case 9:
    digitalWrite(7, LOW);
    digitalWrite(6, LOW);
    digitalWrite(5, LOW);
    digitalWrite(4, LOW);
    digitalWrite(3, HIGH);
    digitalWrite(2, LOW);
    digitalWrite(1, LOW);
    digitalWrite(0, HIGH);
    switch (pturn){
    case 0:
      if (digitalRead(13) == HIGH){
        goto loop1;
      };
      if (digitalRead(13) == LOW){
        goto dlp1;
      };
      break;
    case 1:
      if (digitalRead(12) == HIGH){
        goto loop1;
      };
      if (digitalRead(12) == LOW){
        goto dlp2;
      };
      break;
    }
    break;
  case 8:
    digitalWrite(7, LOW);
    digitalWrite(6, LOW);
    digitalWrite(5, LOW);
    digitalWrite(4, LOW);
    digitalWrite(3, HIGH);
    digitalWrite(2, LOW);
    digitalWrite(1, LOW);
    digitalWrite(0, LOW);
    switch (pturn){
    case 0:
      if (digitalRead(13) == HIGH){
        goto loop1;
      };
      if (digitalRead(13) == LOW){
        goto dlp1;
      };
      break;
    case 1:
      if (digitalRead(12) == HIGH){
        goto loop1;
      };
      if (digitalRead(12) == LOW){
        goto dlp2;
      };
      break;
    }
    break;
  case 7:
    digitalWrite(7, LOW);
    digitalWrite(6, LOW);
    digitalWrite(5, LOW);
    digitalWrite(4, LOW);
    digitalWrite(3, LOW);
    digitalWrite(2, HIGH);
    digitalWrite(1, HIGH);
    digitalWrite(0, HIGH);
    switch (pturn){
    case 0:
      if (digitalRead(13) == HIGH){
        goto loop1;
      };
      if (digitalRead(13) == LOW){
        goto dlp1;
      };
      break;
    case 1:
      if (digitalRead(12) == HIGH){
        goto loop1;
      };
      if (digitalRead(12) == LOW){
        goto dlp2;
      };
      break;
    }
    break;
  case 6:
    digitalWrite(7, LOW);
    digitalWrite(6, LOW);
    digitalWrite(5, LOW);
    digitalWrite(4, LOW);
    digitalWrite(3, LOW);
    digitalWrite(2, HIGH);
    digitalWrite(1, HIGH);
    digitalWrite(0, LOW);
    switch (pturn){
    case 0:
      if (digitalRead(13) == HIGH){
        goto loop1;
      };
      if (digitalRead(13) == LOW){
        goto dlp1;
      };
      break;
    case 1:
      if (digitalRead(12) == HIGH){
        goto loop1;
      };
      if (digitalRead(12) == LOW){
        goto dlp2;
      };
      break;
    }
    break;
  case 5:
    digitalWrite(7, LOW);
    digitalWrite(6, LOW);
    digitalWrite(5, LOW);
    digitalWrite(4, LOW);
    digitalWrite(3, LOW);
    digitalWrite(2, HIGH);
    digitalWrite(1, LOW);
    digitalWrite(0, HIGH);
    switch (pturn){
    case 0:
      if (digitalRead(13) == HIGH){
        goto loop1;
      };
      if (digitalRead(13) == LOW){
        goto dlp1;
      };
      break;
    case 1:
      if (digitalRead(12) == HIGH){
        goto loop1;
      };
      if (digitalRead(12) == LOW){
        goto dlp2;
      };
      break;
    }
    break;
  case 4:
    digitalWrite(7, LOW);
    digitalWrite(6, LOW);
    digitalWrite(5, LOW);
    digitalWrite(4, LOW);
    digitalWrite(3, LOW);
    digitalWrite(2, HIGH);
    digitalWrite(1, LOW);
    digitalWrite(0, LOW);
    switch (pturn){
    case 0:
      if (digitalRead(13) == HIGH){
        goto loop1;
      };
      if (digitalRead(13) == LOW){
        goto dlp1;
      };
      break;
    case 1:
      if (digitalRead(12) == HIGH){
        goto loop1;
      };
      if (digitalRead(12) == LOW){
        goto dlp2;
      };
      break;
    }
    break;
  case 3:
    digitalWrite(7, LOW);
    digitalWrite(6, LOW);
    digitalWrite(5, LOW);
    digitalWrite(4, LOW);
    digitalWrite(3, LOW);
    digitalWrite(2, LOW);
    digitalWrite(1, HIGH);
    digitalWrite(0, HIGH);
    switch (pturn){
    case 0:
      if (digitalRead(13) == HIGH){
        goto loop1;
      };
      if (digitalRead(13) == LOW){
        goto dlp1;
      };
      break;
    case 1:
      if (digitalRead(12) == HIGH){
        goto loop1;
      };
      if (digitalRead(12) == LOW){
        goto dlp2;
      };
      break;
    }
    break;
  case 2:
    digitalWrite(7, LOW);
    digitalWrite(6, LOW);
    digitalWrite(5, LOW);
    digitalWrite(4, LOW);
    digitalWrite(3, LOW);
    digitalWrite(2, LOW);
    digitalWrite(1, HIGH);
    digitalWrite(0, LOW);
    switch (pturn){
    case 0:
      if (digitalRead(13) == HIGH){
        goto loop1;
      };
      if (digitalRead(13) == LOW){
        goto dlp1;
      };
      break;
    case 1:
      if (digitalRead(12) == HIGH){
        goto loop1;
      };
      if (digitalRead(12) == LOW){
        goto dlp2;
      };
      break;
    }
    break;
  case 1:
    digitalWrite(7, LOW);
    digitalWrite(6, LOW);
    digitalWrite(5, LOW);
    digitalWrite(4, LOW);
    digitalWrite(3, LOW);
    digitalWrite(2, LOW);
    digitalWrite(1, LOW);
    digitalWrite(0, HIGH);
    switch (pturn){
    case 0:
      if (digitalRead(13) == HIGH){
        goto loop1;
      };
      if (digitalRead(13) == LOW){
        goto dlp1;
      };
      break;
    case 1:
      if (digitalRead(12) == HIGH){
        goto loop1;
      };
      if (digitalRead(12) == LOW){
        goto dlp2;
      };
      break;
    }
    break;
  case 0:
    digitalWrite(7, LOW);
    digitalWrite(6, LOW);
    digitalWrite(5, LOW);
    digitalWrite(4, LOW);
    digitalWrite(3, LOW);
    digitalWrite(2, LOW);
    digitalWrite(1, LOW);
    digitalWrite(0, LOW);
    switch (pturn){
    case 0:
      digitalWrite(11, HIGH);
      digitalWrite(10, LOW);
      digitalWrite(7, HIGH);
      digitalWrite(6, HIGH); 
      digitalWrite(5, HIGH);
      digitalWrite(4, HIGH);
      digitalWrite(3, HIGH);
      digitalWrite(2, HIGH);
      digitalWrite(1, HIGH);
      digitalWrite(0, HIGH);
      goto halt;
      break;
    case 1:
      digitalWrite(11, LOW);
      digitalWrite(10, HIGH);
      digitalWrite(7, HIGH);
      digitalWrite(6, HIGH); 
      digitalWrite(5, HIGH);
      digitalWrite(4, HIGH);
      digitalWrite(3, HIGH);
      digitalWrite(2, HIGH);
      digitalWrite(1, HIGH);
      digitalWrite(0, HIGH);
      goto halt;
      break;
    }
    break;
  }
halt:
  delay(999999);
}

Logged

London
Offline Offline
Full Member
***
Karma: 0
Posts: 168
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Goto? Blimey, not seen those used for a while.
Logged

Current Projects: Rodentometer - Hamster Endurance Moni

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

More gotos than comments.
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.

Gosport, UK
Offline Offline
Faraday Member
**
Karma: 19
Posts: 3114
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

What's the Chest Game?
Logged

New Jersey
Offline Offline
Faraday Member
**
Karma: 48
Posts: 3417
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

First thing to do is to rewire your seven seg display so you're not using pins 0 and 1. Then you can use Serial.println to get some debugging data out to you.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

(Hopefully not starting another goto war).

Next thing to do is completely rewrite without using a single "goto". You don't need them, they are confusing.

After that maybe simplify the way you do the 7-segment displays.
Logged

Offline Offline
God Member
*****
Karma: 3
Posts: 813
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Goto is sometimes useful. However, probably not in this case.

Interactive, real-time code generally wants to be built as a state machine, and each iteration through "loop()" just looks for a transition from the current state to some new state.

You probably want to write loop() something simple, like:

Code:
enum {
  PRE_START, PLAYER_A, PLAYER_B, GAME_OVER
};
int state;

...

loop() {
  switch (state) {
    case PRE_START: pre_start(); break;
    case PLAYER_A: update_player(0); break;
    case PLAYER_B: update_player(1); break;
    case GAME_OVER: end_game(); break;
  }
  update_display();
}

Now, you need to declare the state you need to duplicate per player: basically just "amount of time left" and "time since last turn started." Put that in a struct or class for the player, and have an array of two of these, for player A and player B. Using the array means that update_player() can take the player argument as an index, and you don't need to duplicate code for both players.

Finally, write the functions pre_start(), update_player(), end_game() and update_display() to do the right thing. For example, update_player() might do something like:

Code:
struct PlayerData {
  unsigned long startTimeMs;
  unsigned long timeLeftMs;
};
PlayerData players[2] = { { 0, 60000 }, { 0, 60000 } };

void update_player(int p) {
  if (millis() - players[p].startTimeMs > players[p].timeLeftMs) {
    player_lost();
    return;
  }
  if (player_button_pressed(p)) {
    next_player();
  }
}

Again, break it down: player_lost() would set state to "game_over" and set some internal variable to which player lost. next_player() would switch the state from PLAYER_A to PLAYER_B or vice versa, and calculate the timeLeftMs for the player you switch away from.

Keep going, breaking each individual little thing down into a separate function, and you'll find that the structure of your program improves.

Another thing that's nice about this approach is that you can make the functions do nothing first -- or Serial.print() something -- or set an LED -- so it's easy to see that the structure behaves the way you want it, so far, before you go to the next level.
Logged

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

i'm really new in programming, as much as i want to try this code "jwatte" i can't understand it...is there a simpliest way to do it??


I tried breaking up the code and remove the "goto", and made the first part of my program as:

Code:
void setup() {
  pinMode(11, OUTPUT); //player 1 indicator
  pinMode(10, OUTPUT); //player 2 indicator
}

int pturn = 1;
int counter;
int p1global;
int p2global;

void loop() {
  pturn = pturn^1;
  if (pturn == 0){
    digitalWrite(11, HIGH);
    digitalWrite(10, LOW);
    counter = 5000;
    p1global = p1global + counter;
    while ( counter > 0 ){
      p1global = p1global - 1000;
      delay(1000);
    }

  }
  else {
    digitalWrite(11, LOW);
    digitalWrite(10, HIGH);
    delay(1000);
  }
}

my problem is i don't know how to display the value of p1global in the seven segment every second.
should i put codes like below.

note: i aim to use 2 BCD decoder-to-7segement tandem.
Code:
  switch (p1global) {
  case 9:
    digitalWrite(7, LOW);
    digitalWrite(6, LOW);
    digitalWrite(5, LOW);
    digitalWrite(4, LOW);
    digitalWrite(3, HIGH);
    digitalWrite(2, LOW);
    digitalWrite(1, LOW);
    digitalWrite(0, HIGH);
}
Logged

Offline Offline
God Member
*****
Karma: 3
Posts: 813
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
void loop() {
  pturn = pturn^1;


This will switch the turn each time through loop(). But loop() gets run many thousands of times per second.
Instead, you want to switch the player turn only when a button is pressed. Otherwise, you want to just keep counting down for the current player.
Also, you don't want to display the time remaining once a second. You want to display the time remaining all the time. The amount of time remaining, rounded to seconds, happens to actually change only once per second. But it's perfectly fine (and common) to output the data you want to display each time through loop().

You can drive a seven-segment display from digital pins like that. However, you will find it hard to drive more than one element/digit that way. Typically, you'll want a total of 8 digits (four per player) for a chess clock. You will probably want a latching digit controller, like the 4511, one for each digit. If wiring all that up seems difficult to you, then perhaps this project is a bit too much as a beginner project?

The way it would work:
Each 7-segment display digit is driven by a 4511 BCD-to-7-segment decoder/driver.
All of the drivers are wired to take their input from the same output pins on the Arduino -- say, pins 2, 3, 4 and 5. (Save 0 and 1 for the serial port)
You select which of the 8 you want to drive using the latch function on each of the chips.
You use pins 6 .. 13 to select which digit to update. Each output should be tied into the latch function of one 4511.

Thus, to update the value of a digit, you:
1) write the output pin of the digit you want to select low, and all other select pins (6 .. 13) high.
2) write the value of the digit as a binary number on pins 2, 3, 4 and 5.
To update all eight digits, you do this 8 times, with different values for the ID in step 1.

Note that the 4511 latch allows you to update the value when it is low, and stores the last written value when it's high, so the normal state for the "chip select" output pins (6 .. 13) would be "high."
Logged

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

Mr. jwatte thank you for enlightening me.

I'm not sure if i got it right.. but i tried to hard code the program again...and added comments.

i tried uploading it but at some point it work as I intended but randomly, there are times that after 1sec and i didn't input anything yet it will change turn. i wasn't able to check yet if it displays in the 7segment.

advance thanks for checking my codes...

code modified
Code:
void setup() {
  pinMode(12, OUTPUT);    //player turn indicator for player 1
  pinMode(11, OUTPUT);    //player turn indicator for player 1

  pinMode(10, OUTPUT);    //output MSB binary
  pinMode(9, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(3, OUTPUT);    //output LSB binary
}
int p1global;
int p2global;
int out_counter;
int sensorValue = 0;
int x;
int counter1;
int counter2;
int p_turn = 1;

void loop() {
  delay(10);
  counter1 = 5;              //setting counter to 5 secs for player1
  counter2 = 5;              //setting counter to 5 secs for player2
  switch (p_turn) {         //swtitch-case for player turn
  case 1:                   //player 1 turn functions
    digitalWrite (12,HIGH); //indicates player 1 turn
    digitalWrite (11,LOW);
    p1global = p1global + counter1; //putting the current time
    for (x = p1global; x > 0; x--) { //counter loop for x is the number of times decrement
      p1global = p1global - 1;       //decrements the universal time for player1
      out_counter = p1global;        //put universal time to the out_counter for display
      out_segment();                 //call display function
      sensorValue = analogRead(A1);  //put analog A1 input to sensorValue
      if(sensorValue == 1){     //check for sensor value
       p_turn = p_turn^1;        //alternates the player turn
        x = 0;                       //stops the loop
        break;                      
      }
      else {                          
        delay(1000);                  //1 sec interval
      }    
    }
    break;
  default:                            //player 1 turn functions
    digitalWrite (12,LOW);
    digitalWrite (11,HIGH);
    p2global = p2global + counter2;
    for (x = p2global; x > 0; x--) {
      p2global = p2global - 1;
      out_counter = p2global;
      out_segment();      
      sensorValue = analogRead(A2);
      if(sensorValue == 1){
      p_turn = p_turn^1;        //alternates the player turn
        x = 0;  
        break;
      }
      else {      
        delay(1000);
      }    
    }
    break;
  }
}  

void out_segment() {
  switch (out_counter){
  case 99:
      digitalWrite(10, HIGH);
      digitalWrite(9, LOW);
      digitalWrite(8, LOW);
      digitalWrite(7, HIGH);
      digitalWrite(6, HIGH);
      digitalWrite(5, LOW);
      digitalWrite(4, LOW);
      digitalWrite(3, HIGH);

  }
}
« Last Edit: February 12, 2012, 06:53:36 am by tacet777 » Logged

New Jersey
Offline Offline
Faraday Member
**
Karma: 48
Posts: 3417
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Read jwatte's post again. You still have exactly the same issue with pturn - it changes on every iteration of loop.
Logged

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

wildbill...tnx for pointing it out...

i placed the pturn = pturn^1; inside the condition for the input..

will it function well now??

and how about the way i display the timer??will it work with said code?
Logged

New Jersey
Offline Offline
Faraday Member
**
Karma: 48
Posts: 3417
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

On second thought, I suggest you start from scratch. Write a program that reads two digital inputs, representing the player's buttons and control two leds to indicate whose turn it is. Then write another that has a function that outputs a number to your seven segment displays. Once those two are working, combine them and add in the timing piece - your big bang approach is making it more difficult.

If you choose to continue as you are though, note that your reading of the buttons is currently analog - it will not do what you want.
Logged

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

Then write another that has a function that outputs a number to your seven segment displays. Once those two are working, combine them and add in the timing piece

can you please explain this...

tnx
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Your code without the gotos looks much better. I suggest you, at this stage, get the hang of reading switches and just turning a single LED or two on and off. Then you will find out things like trying to toggle and LED every time through loop() is too fast.

This stuff DOES work, and it is very satisfying to make it do so, but for the sake of your sanity solve one problem at a time. For example, make a simple program that turns an LED on when you press a switch, and turn it off when you press a different switch. The things you learn there will carry you through to more complex projects.
Logged

Pages: [1] 2   Go Up
Jump to: