So, I've now got the alarm function and the Servo function doing almost everything it needs to be doing.
So far I have managed to get each function to respond to each button, and a but closer to what I want,
The Alarm sounds (light and sound)
Both buttons are pressed simultaneously
The Alarm stops and the servo runs.
This is done with a simple if / else statement.
Here is the code...
#include <Servo.h>
class Flasher
{
// Class Member Variables
// These are initialized at startup
int ledPin; // the number of the LED pin
long OnTime; // milliseconds of on-time
long OffTime; // milliseconds of off-time
// These maintain the current state
int ledState; // ledState used to set the LED
unsigned long previousMillis; // will store last time LED was updated
// Constructor - creates a Flasher
// and initializes the member variables and state
public:
Flasher(int pin, long on, long off)
{
ledPin = pin;
pinMode(ledPin, OUTPUT);
OnTime = on;
OffTime = off;
ledState = LOW;
previousMillis = 0;
}
void Update()
{
// check to see if it's time to change the state of the LED
unsigned long currentMillis = millis();
if ((ledState == HIGH) && (currentMillis - previousMillis >= OnTime))
{
ledState = LOW; // Turn it off
previousMillis = currentMillis; // Remember the time
digitalWrite(ledPin, ledState); // Update the actual LED
}
else if ((ledState == LOW) && (currentMillis - previousMillis >= OffTime))
{
ledState = HIGH; // turn it on
previousMillis = currentMillis; // Remember the time
digitalWrite(ledPin, ledState); // Update the actual LED
}
}
};
class Sweeper
{
Servo servo; //the servo
int pos; // current servo position
int increment; //increment to move for each interval
int updateInterval; // interval between updates
unsigned long lastUpdate; //last update of position
public:
Sweeper(int interval)
{
updateInterval = interval;
increment = 1;
}
void Attach(int pin)
{
servo.attach(pin);
}
void Detach()
{
servo.detach();
}
void Update()
{
if ((millis() - lastUpdate) > updateInterval) // time to update
{
lastUpdate = millis();
pos += increment;
servo.write(pos);
Serial.println(pos);
if ((pos >= 125) || (pos <= 0)) // sets the distance of the sweep, then end of sweep
{
// reverse direction - DELETE THIS AND THE SERVO MOVES TO MAX. POS AND THEN STOPS
// BUT HOW DO I GET THE SERVO TO DO ONE UP / DOWN CYCLE THEN STOP?
increment = -increment;
}
}
}
};
Flasher LED(10, 200, 800); // pin, on time, off time
Flasher BUZZER(11, 100, 900); // pin, on time, off time
Sweeper sweeper1 (45); // controls the speed of the servo (lower = faster)
int BUTTON_A = 8;
int BUTTON_B = 9;
void setup()
{
pinMode(BUTTON_A, INPUT_PULLUP); // set the buttons as input - HIGH until pressed, then LOW
pinMode(BUTTON_B, INPUT_PULLUP);
Serial.begin(9600);
sweeper1.Attach(3); // attaches sweeper1 servo to pin 3
}
// pressing each button here stops the corresponging function DURING the button press
void loop()
{
if (!digitalRead(BUTTON_A) && !digitalRead(BUTTON_B)) // press both buttons to start servo
{
sweeper1.Update();
}
else // sound alarm
{
LED.Update();
BUZZER.Update();
}
}
Now I need to figure out how to...
When either button is pressed,
pause the alarm for the duration of the button press
When both buttons are pressed,
Stop the alarm for good
Run the servo up/down sequence only once.
I'm hoping to be able to loop different if / else statements in loops within loops to see if I can make this work. The servo running once is a bit of a mystery though. I did get it to stop with a WHILE(1) {} instruction in an early test but this was using delays, so I'm not sure how it will go with millis.
I feel like I am so close, but I have felt that way a lot already so I'm not about to start trusting my feelings on this.
More to come...
Comments
Post a Comment