Arduino Lighthouse

Dear community members,

I hope this is the right place to post this, and I really hope that someone here will be able to look at my code and tell me where I'm going wrong. Thanks in advance for any advice/ aid offered.

Basically, my little girl is building a lighthouse for a show and tell project at school and whilst looking for a spinning light to stick in the top I came across arduino and decide that It would be the most practical way to implement the electronics, whilst also being fun and educational (for both me and her).
Anyway, my code so far looks like this.

#include<Servo.h> // Include servo library

const int button = 2; // Button is attached to pin 2
const int led = A0; // LED is on pin A0

Servo servo; // Create a servo object

int buttonPresses = 0; // Declare a variable to hold number of button pushes
int buttonState = 0; // Variable holds present state of button
int prevButtonState = 0; // Variable holds previous button state
int servoPos = 0; // Variable stores the position of the servo

void setup() {
servo.attach(3); // Servo is on pin 3

pinMode(button, INPUT); // Declare button (pin 2) as input
pinMode(led, OUTPUT); // Declare LED (pin A0) as output
}

void loop() {
buttonState = digitalRead(button); // Set the value of buttonState to current value of button (pin 2)
if(buttonState != prevButtonState) { // if buttonState is not the same as prevButtonState, then...
if(buttonState == HIGH) { // and if the current button state is high ...
buttonPresses = buttonPresses + 1; // Increase the press counter by 1
}
delay(60);
}

if (buttonPresses % 2 == 0) {
digitalWrite(led, HIGH);
}
else {
digitalWrite(led, LOW);
}
}
for(servoPos = 0; servoPos <= 180; servoPos++) {
servo.write(servoPos);
delay(80);
}
for(servoPos = 180; servoPos>=0; servoPos--) {
servo.write(servoPos);
delay(80);
}
}
else if (buttonPresses % 2 != 0) {
digitalWrite(led, LOW);
servo.write(0);
delay(20);
}
while (buttonPresses % 2 == 0) {
for(servoPos = 0; servoPos <= 180; servoPos++) {
servo.write(servoPos);
delay(20);
}
for(servoPos = 180; servoPos>=0; servoPos--) {
servo.write(servoPos);
delay(20);
}
break;
}
prevButtonState = buttonState; // Update lastButtonState for the next loop
}

I assume I'm getting stuck in a loop somewhere or that possibly my use of delay() is interrupting the flow. However I'm uncertain of how to go about fixing it.
What I'd like to happen it that a momentary push button attached to pin 2 is pressed counted and then the button press counter is an even number the servo on pin 9 sweeps back and forth continuously and the led lights.
Any and all help and suggestions welcome. Thanks again!

LH_test.ino (1.75 KB)

Delay isn't helping but this piece is a show stopping problem:

while (buttonPresses % 2 == 0) {
  for (servoPos = 0; servoPos <= 180; servoPos++) {
    servo.write(servoPos);
    delay(20);
  }
  for (servoPos = 180; servoPos >= 0; servoPos--) {
    servo.write(servoPos);
    delay(20);
  }
  break;
}

If buttonPresses %2 is 0, that loop will never terminate because there's nothing in there that will ever change buttonPresses. Try replacing the while with an if.

Edit: spelling
Edit two: Didn't notice the break statement. Weird thing to do but invalidates my analysis -- ignore.

Do you have a pull down resistor connected from the switch input to ground?

Please provide a better description of what the sketch does.

Add serial prints to the code so you can follow execution and see where it is getting stuck.

Please read the "how to use this forum-please read" stickies to see how to post your code.

Okay so I'll try to be as clear as I can. I have a momentary push button on pin 2 which is pulled down to ground. I have an LED on analog pin 0 and a servo on pin 9. What I want to happen is that when the arduino is powered on it begins checking the state. If a button press is detected it want the arduino to turn the LED on pin 2 on and also to begin sweeping the servo back and forth between 0 and 180. Then if the button is pressed again i want the LED to turn off and the servo to stop moving.
My understanding of what the code 'should' be doing is this; on power up the arduino checks the state of the button and stores this value in the buttonState variable. After the first time through the loop it also stores the state of the button for the previous time through the loop in the prevButtonState variable. When the button is pressed the value of buttonState is high, however the value of PrevButtonState is low (or vice versa). This information is used to count button presses and store the value in the pushCount variable. An if statement is then used to check if the value of pushCount is even or odd. If pushCount is even then the LED on pin 2 should be set high and the servo position should be set to the value of servoPos which is determined by the for loops. if the value of pushCount is odd the the LED should be set low and the servo should be set to 90 degrees using servo.write.

I have the code working with the LED, each time I push the button the LED goes on or off per button press. However, if I add the code to write the servo positions the whole program does nothing. There is no error but nothing works.

This is my most up to date code:

#include<Servo.h>  // Include servo library

const int button = 2; // Button is attached to pin 2
const int led = A0; // LED is on pin A0

Servo servo;  // Create a servo object

int pushCount = 0; // Declare a variable to hold number of button pushes
int buttonState = 0;  // Variable holds present state of button
int prevButtonState = 0;  // Variable holds previous button state
int servoPos = 0; // Variable stores the position of the servo

void setup() {
  servo.attach(9); // Servo on pin 9
  pinMode(button, INPUT); //  // Declare button (pin 2) as input
  pinMode(led, OUTPUT); // Declare LED (pin A0) as output
}

void loop() {
  buttonState = digitalRead(button); // Set the value of buttonState to the current value of button
  if(buttonState != prevButtonState) { // If button state if not the same as the prevButtonState ...
    if(buttonState == HIGH) { // And if buttonState is high
      pushCount++; // Increment pushCount value
    }
    delay(20);  // Wait 20ms
  }
  prevButtonState = buttonState; // Save current state of button as previous button state
  
  if(pushCount % 2 == 0) {  // If the value of pushCount is an even number
    for(servoPos=0; servoPos <=180; servoPos++) { // For loop sweeps value servoPos from 0 to 180
       servo.write(pos); // Write the value servoPos to the servo on pin 9
       delay(10); // Wait 10ms
    }
    for(servoPos=180; servoPos>=0; servoPos--) {  // For loop sweeps value the other way - I.e. from 180 to 0
       servo.write(pos);
       delay(10); // wait another 10ms
    }
    digitalWrite(led, ); // Turn LED on
  }
  else {  // Else if pushCount is NOT an even number
    digitalWrite(led, LOW);  // Turn LED off
    
    prevButtonState = buttonState;
  }
}

I think my problem might be that the arduino can't run the main loop to keep checking for button presses whilst also running the for loops to write servo positions.

Again, any help is massively appreciated. Bella has done such an incredible job making the light house out of paper mache and painting it, I would hate to not my part of it done on time.

When the code is in the for loops it is blocking anything else from happening. If you want non blocking code you will need to get away from the for loops. The Demonstration code for several things at the same time tutorial shows how to do that.

Edit: There is another tutorial (beginners guide to using millis()) that may be of interest.

@groundFungus - Thanks for replying so quickly! I suspected that the for loop might be causing some problems. However, my earlier code used a while loop and I had the same issue with that. Do you think it might work better if I use a simple function to set servoPos, it might help tidy up the if statements. I've been looking around for possible solutions to this on the internet and it seems that this is a common problem with any code that tryrs to sweep a servo back and forth whilst doing something else. Anyway, I'll have a look at the examples you've linked and then let you know how it goes.

Thanks again!

Here's another link you may like since it demonstrates timing by using servo's
Multitasking the Arduino