0
votes

I am programming C on an Arduino and I am very much a beginner. My goal with this program is to display a binary number on LED's and then let the player guess the binary number. The player then presses a button equal to the decimal value of the displayer binary number. When the players starts pressing the button, they get two seconds for every press. If they don't click again in those two seconds they lose, or they guess the right amount and win.

The only thing my messy program doesn't do is give a two second period every button press. Even after extensive reading I am confused on milli();. Aside from the bad coding, could I change something in my program to give players a two second window when pressing the button? I am convinced that there is a just a minute detail that I am overlooking. Thanks for your time.

const int buttonPin = 2;     
const int ledPinValue1 =  3;     
const int ledPinValue2 =  4;      
const int ledPinValue4 =  5;     
const int ledPinValue8 =  6;  

int teller = 0;
int buttonStatus = 0;
int lastButtonStatus;

unsigned long interval=5000;    // the time we need to wait
unsigned long previousMillis = 0; // millis() returns an unsigned long.
unsigned long currentMillis = 0;
unsigned long elapsed;
unsigned long midElapsed;

unsigned long minus=5000;

int secondLoop = 0;

boolean allowTimer = false;
boolean allowMilliAfterFirstRound; //without this, when the second loop commences milli = milli - milli


void setup() {
    Serial.begin(9600);

    pinMode(ledPinValue1, OUTPUT);
    pinMode(ledPinValue2, OUTPUT);
    pinMode(ledPinValue4, OUTPUT);
    pinMode(ledPinValue8, OUTPUT);
    pinMode(buttonPin, INPUT);
}

void loop() {
    boolean initiateLoss = true; // ++++
    int randomNumber = 5; //Replace with randomcode
    currentMillis = millis();

    knopStatus = digitalRead(buttonPin);

    if (randomNumber == 1 || randomNumber == 3 || randomNumber == 5 || randomNumber == 7 || randomNumber == 9 || randomNumber == 11 || randomNumber == 13 || randomNumber == 15){
        digitalWrite(ledPinValue1, HIGH);
    }
    else {
        digitalWrite(ledPinValue1, LOW);
    }
    if (randomNumber == 2 || randomNumber == 3 || randomNumber == 6 || randomNumber == 7 || randomNumber == 10 || randomNumber == 11 || randomNumber == 14 || randomNumber == 15){
        digitalWrite(ledPinValue2, HIGH);
    }
    else {
        digitalWrite(ledPinValue2, LOW);
    } 
    if (randomNumber == 4 || randomNumber == 5 || randomNumber == 6 || randomNumber == 7 || randomNumber == 12 || randomNumber == 13 || randomNumber == 14 || randomNumber == 15){
        digitalWrite(ledPinValue4, HIGH);
    }
    else {  
        digitalWrite(ledPinValue4, LOW);
    } 
    if (randomNumber == 8 || randomNumber == 9 || randomNumber == 10 || randomNumber == 11 || randomNumber == 12 || randomNumber == 13 || randomNumber == 14 || randomNumber == 15){
        digitalWrite(ledPinValue8, HIGH);
    }
    else {
        digitalWrite(ledPinValue8, LOW);
    }

    //------------------------------------------------------------------------------------

    if (knopStatus != lastButtonStatus) {

        if (knopStatus == HIGH) {
            teller++;
            Serial.print("number of button pushes:  ");
            Serial.println(teller, DEC);
            allowTimer = true;


        }    
        delay(50);
    }

    //------------------

    if (allowTimer == true){        


        if (allowMilliAfterFirstRound == true) {
            currentMillis = currentMillis - currentMillis;
            allowMilliAfterFirstRound = false;
        }

        if (teller == randomNumber){ // WIN
            Serial.print("You won!");
            Serial.println();
            initiateLoss = false;
            randomNumber = 3; // remove when randomnumber is added
            teller = 0;
            previousMillis = millis();
        }  

        if ((unsigned long)(currentMillis - previousMillis) > interval && initiateLoss == true) {  // LOST!
            elapsed = currentMillis - previousMillis; 
            Serial.print("Time elapsed at time of failure: ");                             
            Serial.print(elapsed);
            Serial.println();
            Serial.print("currentMillis is now: ");
            Serial.print(currentMillis); // 5000, 10000, 15000, 20000 etc
            Serial.println();
            Serial.print("previousMillis is now: ");
            Serial.print(previousMillis); // 5000, 10000, 15000, 20000 etc
            Serial.println();
            previousMillis = millis();

            Serial.println();
            Serial.print("You lost!");
            Serial.println();
            Serial.print("Begin!");
            Serial.println();
            teller = 0;

        }
    }
    lastButtonStatus = knopStatus;  // save the current state as the last state, for next time through the loop 
}
2

2 Answers

0
votes

There's bugs, for instance:

if (allowMilliAfterFirstRound == true) {
    currentMillis = currentMillis - currentMillis;
    allowMilliAfterFirstRound = false;
}

And allowMilliAfterFirstRound is not initialized, nor assigned elswhere...

More generally, the code shows that you understand millis correctly. What's missing is a management of the 2 states the program can be in:

  1. Display number, then waiting for the player's answer: counting time until timeout
  2. Displaying a win/lost message, just waiting for a button press to start another guess (?)

previousMillis should be initialized when going from state 2 to 1.

0
votes

I would do something like this:

void loop() {

if (not yet displayed) {
[all the code to display the number on leds]
}

if (button pressed) { 
allowTimer = true;  // Start!
}

if (allowTimer) /* If timer started */ {
   while (millis() - previousMillis <= 2000) /* The famous 2 sec */ {

      if (button pressed) {
      previousMillis = millis(); /* Update timing */
      teller++;
      }
   }
   if(teller == randomNumber) {
   [Hooray, you won or whatever message and stuff you like]
   }
   else {
   [Sorry, you lost]
   }

}

Of course you should replace my writings with your code.

TIP: For a single instruction in any statement you don't need parentheses:

if (condition) {
onlyOneInstruction;
}

is the same as

if (condition) onlyOneInstruction;

EDIT: Also, you try to compare knopStatus (undeclared, maybe you meant buttonStatus) with lastButtonStatus, which isn't initialised. This gives you an error.