Wait on switch input question

Hi, I'm new to Arduino and I'm stuck with a switch input problem. I would appreciate some help with my program please.

Essentially I'm writing the code for a car game which I am building and designing.

The problem I have is that the program does not wait on a switch input instead it continues to execute the code.

The program does respond to the switch input (coinsw) and the 4 select LEDS light, but I want it to wait until the player selects a car until it executes the rest of the code instead it continues and loops to the start of the program.

I need to write a switch detection routine which stops and waits until a button is pressed before continuing. I am finding this difficult to do.

Essentially, wait until carselect switch is pressed (do nothing until it is).

/* pauls car game */ int insertcoinPin = 36; int coinswPin = 2; int losePin = 37; int payoutPin = 3; int rcselectPin = 41; int bcselectPin = 40; int gcselectPin = 39; int wcselectPin = 38; int rcrevPin = 53; int bcrevPin = 51; int gcrevPin = 49; int wcrevPin = 48; int rcforwardPin = 52; int bcforwardPin = 50; int gcforwardPin = 48; int wcforwardPin = 46; int rcselectswPin = 35; int bcselectswPin = 34; int gcselectswPin = 33; int wcselectswPin = 32; int rcwinswPin = 31; int bcwinswPin = 30; int gcwinswPin = 29; int wcwinswPin = 28; int rcwreturnswPin = 27; int bcreturnswPin = 26; int gcreturnswPin = 25; int wcreturnswPin = 24; int payPin = 23; int buttonState = 0; // variable for reading the pushbutton status int redcarsw = 0; int bluecarsw = 0; int greencarsw = 0; int whitecarsw = 0; int redwinsw = 0; int bluewinsw = 0; int greenwinsw = 0; int whitewinsw = 0; long randNumber1; long randNumber2; long randNumber3; long randNumber4;

void setup() { //initialise pin as output pinMode (insertcoinPin, OUTPUT); pinMode (coinswPin, INPUT_PULLUP); pinMode (losePin, OUTPUT); pinMode (payoutPin, OUTPUT); pinMode (rcselectPin, OUTPUT); pinMode (bcselectPin, OUTPUT); pinMode (gcselectPin, OUTPUT); pinMode (wcselectPin, OUTPUT); pinMode (rcrevPin, OUTPUT); pinMode (bcrevPin, OUTPUT); pinMode (gcrevPin, OUTPUT); pinMode (wcrevPin, OUTPUT); pinMode (rcforwardPin, OUTPUT); pinMode (bcforwardPin, OUTPUT); pinMode (gcforwardPin, OUTPUT); pinMode (wcforwardPin, OUTPUT); pinMode (rcselectswPin, INPUT_PULLUP); pinMode (bcselectswPin, INPUT_PULLUP); pinMode (gcselectswPin, INPUT_PULLUP); pinMode (wcselectswPin, INPUT_PULLUP); pinMode (rcwinswPin, INPUT_PULLUP); pinMode (bcwinswPin, INPUT_PULLUP); pinMode (gcwinswPin, INPUT_PULLUP); pinMode (wcwinswPin, INPUT_PULLUP); pinMode (rcwreturnswPin, INPUT_PULLUP); pinMode (bcreturnswPin, INPUT_PULLUP); pinMode (gcreturnswPin, INPUT_PULLUP); pinMode (wcreturnswPin, INPUT_PULLUP); pinMode (payPin, OUTPUT); }

void loop() {

// read the state of the pushbutton value: buttonState = digitalRead(coinswPin);

// check if the pushbutton is pressed. // if it is, the buttonState is HIGH: if (buttonState == LOW) { // turn LED on: digitalWrite (insertcoinPin, LOW); digitalWrite (rcselectPin, HIGH); digitalWrite (bcselectPin, HIGH); digitalWrite (gcselectPin, HIGH); digitalWrite (wcselectPin, HIGH); } else { // turn LED off: digitalWrite (insertcoinPin, HIGH); digitalWrite (rcselectPin, LOW); digitalWrite (bcselectPin, LOW); digitalWrite (gcselectPin, LOW); digitalWrite (wcselectPin, LOW); }

redcarsw = digitalRead(rcselectswPin); bluecarsw = digitalRead(bcselectswPin); greencarsw = digitalRead(gcselectswPin); whitecarsw = digitalRead(wcselectswPin);

if (redcarsw == LOW) {digitalWrite (rcselectPin, HIGH); }

if (bluecarsw == LOW) { digitalWrite (bcselectPin, HIGH); }

if (greencarsw == LOW) { digitalWrite (gcselectPin, HIGH); }

if (whitecarsw == LOW) { digitalWrite (wcselectPin, HIGH); }

return;

redwinsw = digitalRead(rcwinswPin); bluewinsw = digitalRead(bcwinswPin); greenwinsw = digitalRead(gcwinswPin); whitewinsw = digitalRead(wcwinswPin);

randNumber1 = random(50, 300); randNumber2 = random(50, 300); randNumber3 = random(50, 300); randNumber4 = random(50, 300);

{digitalWrite (rcforwardPin, HIGH); delay(randNumber1); digitalWrite (rcforwardPin, LOW); delay(randNumber1);} {digitalWrite (bcforwardPin, HIGH); delay(randNumber2); digitalWrite (bcforwardPin, LOW); delay(randNumber2);} {digitalWrite (gcforwardPin, HIGH); delay(randNumber3); digitalWrite (gcforwardPin, LOW); delay(randNumber3);} {digitalWrite (wcforwardPin, HIGH); delay(randNumber4); digitalWrite (wcforwardPin, LOW); delay(randNumber4);} }

The problem I have is that the program does not wait on a switch input instead it continues to execute the code.

You need to make it do that.

Essentially, wait until carselect switch is pressed (do nothing until it is).

You don't have a carselect pin defined, nor have you posted any code that (fails in its) attempts to wait for a switch press.

{digitalWrite (rcforwardPin, HIGH); delay(randNumber1); digitalWrite (rcforwardPin, LOW); delay(randNumber1);}

These curly braces are not needed, nor are they desirable. One statement per line is the norm. For good reasons.

There are 4 cars, red, green, blue and white, the carselect pins are defined as follows;

int rcselectPin = 41; int bcselectPin = 40; int gcselectPin = 39; int wcselectPin = 38;

The code works in as far as it does respond to the switches, but I can't make the code stop and wait for the inputs.

I'm thinking along these lines to make it stop and wait for one of the 4 cars to be selected.

int button_pin = 4; // pin used to read the button void setup() { int start_click = LOW; // Initial state: no click yet pinMode( button_pin, INPUT); Serial.begin(9600); while ( !start_click ) { start_click = digitalRead( button_pin ); Serial.println("Waiting for button press");

If you want it to wait until pressed:

// stay in while loop until switch is read as a low
while (switchState == HIGH){
switchState = digitalread (switch_to_be_read);  // assumes Low when pressed, held high by internal pullup otherwise
}
// now swithState = LOW and can be used for other logic decisions

You could also make the reading of them part of a larger while, so they can be pressed in any order, and not advanced until all are pressed.

You could also make the reading of them part of a larger while, so they can be pressed in any order, and not advanced until all are pressed.

Or put them in a function, and have that function return only when any one of them is pressed. If that is what you want.

Thank you for your replies...

Initially insertcoin LED lights.

The program should wait on coinsw switch to be pressed.

When it is pressed, the 4 car select leds light.

One 1 car select switch needs to be press so only 1 car is selected. (there can be only 1 winner)

When the red car switch is pressed, the redcar LED lights (or blue or green or white depending on which car is selected).

The code must wait until a select switch is pressed.

I modify the code tonight and see if I can get it to wait on the switch input.

I am really new to Arduino, but I am confident the electronic part of the project is correct, as I can see the switches go LOW when they are pressed. My problem is purely software related and my lack of skill in this area.

Paul

One 1 car select switch needs to be press so only 1 car is selected. (there can be only 1 winner)

When the red car switch is pressed, the redcar LED lights (or blue or green or white depending on which car is selected).

The code must wait until a select switch is pressed.

I must surely be missing something, if the player of your game is selecting the winner in advance.

Ok... the concept goes like this. (I have only coded as far as the random pulse for the car motors which is why you can't see all of the game)

Insert coin LED lights Game waits on coin switch - when coin is inserted, a credit is recorded. Then the player select 1 of 4 cars (4 select LEDS light) Once a car is selected, all 4 cars advance down the track (randomly) until 1 car strikes a win switch at the end of the track. The winning car is recorded. If the winning car colour matches the selected car colour, the game records a win, and the game pays a coin. If the players car does not win, the game lights lose LED The cars will then return to the start position 1 at a time, until each car strikes each of the 4 return switches. The game restarts.

Paul

Then the player select 1 of 4 cars (4 select LEDS light)

A function like this would block waiting for one of the 4 switches to be pressed:

int pickCar()
{
   int carNum = -1;
   while(carNum == -1)
   {
      if(digitalRead(rcselectPin) == LOW) // or HIGH if using pulldown resistors
         carNum = 0;
      if(digitalRead(bcselectPin) == LOW) // or HIGH if using pulldown resistors
         carNum = 1;
      if(digitalRead(gcselectPin) == LOW) // or HIGH if using pulldown resistors
         carNum = 2;
      if(digitalRead(wcselectPin) == LOW) // or HIGH if using pulldown resistors
         carNum = 3;
   }
   return carNum;
}

When the switch is pressed, the return value tells you which one.

This is where arrays would be really useful. The return value could be used as an index, then.

I used your function (after reading up on functions and understanding that they are subroutines)

The code now runs, to the point where it waits on a switch input on carselect, but I'm struggling to read out the value of carNum.

I want a single car select lamp to remain lit when the car is selected, but I also want the value of the selected car stored for use later.

This is where I am so far...

/*
pauls first program
 */
int insertcoinPin = 36;
int coinswPin = 2;
int losePin = 37;
int payoutPin = 3;
int rcselectPin = 41;
int bcselectPin = 40;
int gcselectPin = 39;
int wcselectPin = 38;
int rcrevPin = 53;
int bcrevPin = 51;
int gcrevPin = 49;
int wcrevPin = 48;
int rcforwardPin = 52;
int bcforwardPin = 50;
int gcforwardPin = 48;
int wcforwardPin = 46;
int rcselectswPin = 35;
int bcselectswPin = 34;
int gcselectswPin = 33;
int wcselectswPin = 32;
int rcwinswPin = 31;
int bcwinswPin = 30;
int gcwinswPin = 29;
int wcwinswPin = 28;
int rcwreturnswPin = 27;
int bcreturnswPin = 26;
int gcreturnswPin = 25;
int wcreturnswPin = 24;
int payPin = 23;
int buttonState = 0;         // variable for reading the pushbutton status
int redcarsw = 0;
int bluecarsw = 0;
int greencarsw = 0;
int whitecarsw = 0;
int redwinsw = 0;
int bluewinsw = 0;
int greenwinsw = 0;
int whitewinsw = 0;
long randNumber1;
long randNumber2;
long randNumber3;
long randNumber4;
int carNum = -1;
int x = 0;

void setup()
{
  //initialise pin as output
  pinMode (insertcoinPin, OUTPUT);
  pinMode (coinswPin, INPUT_PULLUP);
  pinMode (losePin, OUTPUT);
  pinMode (payoutPin, OUTPUT);
  pinMode (rcselectPin, OUTPUT);
  pinMode (bcselectPin, OUTPUT);
  pinMode (gcselectPin, OUTPUT);
  pinMode (wcselectPin, OUTPUT);
  pinMode (rcrevPin, OUTPUT);
  pinMode (bcrevPin, OUTPUT);
  pinMode (gcrevPin, OUTPUT);
  pinMode (wcrevPin, OUTPUT);
  pinMode (rcforwardPin, OUTPUT);
  pinMode (bcforwardPin, OUTPUT);
  pinMode (gcforwardPin, OUTPUT);
  pinMode (wcforwardPin, OUTPUT);
  pinMode (rcselectswPin, INPUT_PULLUP);
  pinMode (bcselectswPin, INPUT_PULLUP);
  pinMode (gcselectswPin, INPUT_PULLUP);
  pinMode (wcselectswPin, INPUT_PULLUP);
  pinMode (rcwinswPin, INPUT_PULLUP);
  pinMode (bcwinswPin, INPUT_PULLUP);
  pinMode (gcwinswPin, INPUT_PULLUP);
  pinMode (wcwinswPin, INPUT_PULLUP);
  pinMode (rcwreturnswPin, INPUT_PULLUP);
  pinMode (bcreturnswPin, INPUT_PULLUP);
  pinMode (gcreturnswPin, INPUT_PULLUP);
  pinMode (wcreturnswPin, INPUT_PULLUP);
  pinMode (payPin, OUTPUT);
  }

void loop() {
  digitalWrite (insertcoinPin, HIGH);
    buttonState = digitalRead (coinswPin);
    
  while (buttonState == HIGH) { 
  buttonState = digitalRead (coinswPin);
  }
  digitalWrite (insertcoinPin, LOW);
  digitalWrite (rcselectPin, HIGH);
  digitalWrite  (bcselectPin, HIGH);
  digitalWrite (gcselectPin, HIGH);
  digitalWrite (wcselectPin, HIGH);
  
  int rcbuttonState = 0;
  int bcbuttonState = 0;
  int gcbuttonState = 0;
  int wcbuttonState = 0;
  
    rcbuttonState = digitalRead (rcselectswPin);
    bcbuttonState = digitalRead (bcselectswPin);
    gcbuttonState = digitalRead (gcselectswPin);
    wcbuttonState = digitalRead (wcselectswPin);
    
    rcbuttonState = digitalRead (rcselectswPin);
    
    int sens;
    
    sens = pickCar();

    digitalWrite(rcselectPin, LOW); digitalWrite(bcselectPin, LOW); digitalWrite (gcselectPin, LOW); digitalWrite (wcselectPin, LOW);
    
STUCK HERE... I can't read the value of carNum??

    
}




  int pickCar()
{
   int carNum = -1;
   while(carNum == -1)
   {
      if(digitalRead(rcselectswPin) == LOW) // or HIGH if using pulldown resistors
         carNum = 0; 
      if(digitalRead(bcselectswPin) == LOW) // or HIGH if using pulldown resistors
         carNum = 1;
      if(digitalRead(gcselectswPin) == LOW) // or HIGH if using pulldown resistors
         carNum = 2; 
      if(digitalRead(wcselectswPin) == LOW) // or HIGH if using pulldown resistors
         carNum = 3; 
   }
   return carNum;
}

Can you modify the post. Select all your code and hit the # icon. Then save it.
Instead of:-
sens = pickCar();
use

carNum = pickCar();

All the inputs and outputs are working (could do with some polishing) but for now it works. I wanted to add an attract mode sequence where the LEDS flash while the game waits for input.

In order to break out of the attract sequence, I need to use an interrupt on pin 21 of the mega. The button attached to pin21 is held LOW by a 10K pull down resistor and is hardware debounced using an RC circuit and a Schmitt trigger. The button definitely goes HIGH when pressed. The game responds to pin 21 as a normal switch input [but too slow], but not as an interrupt. Essentially my interrupt routine doesn't work.

The whole program is too long to post now, so I've removed all the non essential parts that don't effect the interrupt.

/*
pauls first program
 */
int insertcoinPin = 36;
const int interuptPin = 21; //Pin 2 interupt
const int IRQ = 2;
int losePin = 37;
int payoutPin = 3;
int rcselectPin = 41;
int bcselectPin = 40;
int gcselectPin = 39;
int wcselectPin = 38;
int rcrevPin = 53;
int bcrevPin = 51;
int gcrevPin = 49;
int wcrevPin = 47;
int rcforwardPin = 52;
int bcforwardPin = 50;
int gcforwardPin = 48;
int wcforwardPin = 46;
int rcwinPin = 45;
int bcwinPin = 44;
int gcwinPin = 43;
int wcwinPin = 42;
int rcselectswPin = 35;
int bcselectswPin = 34;
int gcselectswPin = 33;
int wcselectswPin = 32;
int rcwinswPin = 31;
int bcwinswPin = 30;
int gcwinswPin = 29;
int wcwinswPin = 28;
int rcreturnswPin = 27;
int bcreturnswPin = 26;
int gcreturnswPin = 25;
int wcreturnswPin = 24;
int payPin = 23;
int buttonState = 0;         // variable for reading the pushbutton status
int redcarsw = 0;
int bluecarsw = 0;
int greencarsw = 0;
int whitecarsw = 0;
int redwinsw = 0;
int bluewinsw = 0;
int greenwinsw = 0;
int whitewinsw = 0;
long randNumber1;
long randNumber2;
long randNumber3;
long randNumber4;
int carNum = -1;
int carWin = -1;
int carRet = -1;
int attract = -1;
int rcreturnState = 0;
int bcreturnState = 0;
int gcreturnState = 0;
int wcreturnState = 0;
int rsg3Pin = 3;
int rsg2Pin = 4;
int rsg1Pin = 5;
int pinState = 0;
volatile int state = HIGH;


void setup()
{
  //initialise pin as output
  pinMode (insertcoinPin, OUTPUT);
  pinMode (losePin, OUTPUT);
  pinMode (payoutPin, OUTPUT);
  pinMode (rcselectPin, OUTPUT);
  pinMode (bcselectPin, OUTPUT);
  pinMode (gcselectPin, OUTPUT);
  pinMode (wcselectPin, OUTPUT);
  pinMode (rcwinPin, OUTPUT);
  pinMode (bcwinPin, OUTPUT);
  pinMode (gcwinPin, OUTPUT);
  pinMode (wcwinPin, OUTPUT);
  pinMode (rcrevPin, OUTPUT);
  pinMode (bcrevPin, OUTPUT);
  pinMode (gcrevPin, OUTPUT);
  pinMode (wcrevPin, OUTPUT);
  pinMode (rcforwardPin, OUTPUT);
  pinMode (bcforwardPin, OUTPUT);
  pinMode (gcforwardPin, OUTPUT);
  pinMode (wcforwardPin, OUTPUT);
  pinMode (rcselectswPin, INPUT_PULLUP);
  pinMode (bcselectswPin, INPUT_PULLUP);
  pinMode (gcselectswPin, INPUT_PULLUP);
  pinMode (wcselectswPin, INPUT_PULLUP);
  pinMode (rcwinswPin, INPUT_PULLUP);
  pinMode (bcwinswPin, INPUT_PULLUP);
  pinMode (gcwinswPin, INPUT_PULLUP);
  pinMode (wcwinswPin, INPUT_PULLUP);
  pinMode (rcreturnswPin, INPUT_PULLUP);
  pinMode (bcreturnswPin, INPUT_PULLUP);
  pinMode (gcreturnswPin, INPUT_PULLUP);
  pinMode (wcreturnswPin, INPUT_PULLUP);
  pinMode (payPin, OUTPUT);
  pinMode (rsg3Pin, OUTPUT);
  pinMode (rsg2Pin, OUTPUT);
  pinMode (rsg1Pin, OUTPUT);
 pinMode (interuptPin, INPUT);
 attachInterrupt(IRQ, blink, RISING);

  }

void loop() {
  digitalWrite (insertcoinPin, HIGH);
  digitalWrite (interuptPin, LOW);
  
  {
  pinState = digitalRead (interuptPin);
    while (pinState == LOW) {
     pinState = digitalRead (interuptPin);
       attractCar();}
    
    }
        
        
        
  digitalWrite (insertcoinPin, LOW);
  

void blink()
{
  state=!state;
}

The whole program is too long to post now, so I've removed all the non essential parts that don't effect the interrupt.

Yes you have also removed the interrupt routine as well a lot of other code so making it imposable to compile. At the bottom of the reply box is an Additional Options triangle, click that and attach your code.

Do you understand how interrupts work? You can't break out of a loop with one or force a change in the main program other than setting a flag which is just the same as looking at the switch.

boozenet: In order to break out of the attract sequence, I need to use an interrupt on pin 21 of the mega.

I can't see why you would need to use an interrupt to do that.