I'm trying to build a (very basic) pinball machine with an Arduino Uno. This part of the code will detect when a ball passes 3 lanes. When a lane is passed, it will activate the lane(laneState), reward a score(+10) and light up an LED.
The Expected Result:
- When all 3 lanes are LIT, assign a score of the lane passage(+10), assign a bonus score(+100) and reset all laneStates to 0 and turn all leds to LOW.
- 110 points are being added in total
Actual Result:
- the last lane passed lights back up as active (while I set all of them to inactive)
- 120 points are being added in total (instead of 110?)
Any hints on why I see this behaviour are very welcome!
The sketch and board can be found here: https://circuits.io/circuits/2739062-poc-lane-passage-001/ Turn on 'Code Editor' and enable the Serial Monitor to see the scores.
More info: I looked into using interrupts, but that is not an option here (the Uno only has 2 pins for interrupts, I need 3)
Thanks!
EDIT: added the code here too:
// Scores
int totalScore = 0;
const int lanePassageScore = 10; // 10 points for passing a lane
const int allLaneActiveBonus = 100; // 100 points for activating ALL lanes
// Digital pins to detect the state of the buttons
const int laneButtonPin[] = {2,3,4};
const int laneStateLedPin[] = {10,11,12};
// all three lanes are 'inactive' at the start of the game
int laneButtonState[] = {0,0,0};
int lastLaneButtonState[] = {0,0,0};
int laneState[] = {0,0,0};
void setup() {
Serial.begin(9600); // for debugging
}
void loop() {
// detect if lanes 1 to 3 were activated
detectLaneButtonPassage(0); // Lane 1
checkAllLanesLit();
detectLaneButtonPassage(1); // Lane 2
checkAllLanesLit();
detectLaneButtonPassage(2); // Lane 3
checkAllLanesLit();
Serial.println(totalScore); // for debugging
delay(5);
}
void detectLaneButtonPassage(int laneId){
// Check state of the button
laneButtonState[laneId] = digitalRead(laneButtonPin[laneId]);
if(laneButtonState[laneId] != lastLaneButtonState[laneId]){
if(laneButtonState[laneId] == HIGH){
// The lane button change to an ON position, toggle the lane state
if(laneState[laneId] == 0){
// lane was not yet active, it becomes active now
laneState[laneId] = 1;
digitalWrite(laneStateLedPin[laneId], HIGH);
rewardScore(lanePassageScore);
}else{
// lane was already active, it becomes inactive now
laneState[laneId] = 0;
digitalWrite(laneStateLedPin[laneId], LOW);
rewardScore(lanePassageScore/2);
}
}
}
lastLaneButtonState[laneId] = laneButtonState[laneId];
}
void rewardScore(int score){
totalScore += score;
}
void checkAllLanesLit(){
// Check if ALL lanes are activated
if(laneState[0]==1 && laneState[1]==1 && laneState[2]==1){
// reset all buttons and states
for(int laneId=0; laneId<=2; laneId++){
laneButtonState[laneId] = 0;
lastLaneButtonState[laneId] = 0;
laneState[laneId] = 0;
digitalWrite(laneStateLedPin[laneId], LOW); //Turn off led
}
rewardScore(allLaneActiveBonus);
}
}