One of the most important things that I learned yesterday was that the Delay function is not your friend.
At first it is all "Hey, I'll do whatever you want, whenever you want", but then as soon as you try to do anything else at the same time the possessive nature of the Delay function shows itself. Now it is a case of "Honey, if you even think of bringing anything else into this loop that we've got going on then I'll make your life a living hell."
OK, so maybe that picture is not the best one, but who wants their code to do only one thing?
anyway...
It is time to ditch the delay and learn how to use millis.
[hours pass]
With help from the excellent tutorials by Bill Earl on the Adafruit website I have re-written the code to use 'millis' to do the timing of the light, buzzer and servo.
So far so good.
#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
increment = -increment;
}
}
}
};
Flasher LED(10, 300, 700); // pin, on time, off time
Flasher BUZZER(11, 200, 800); // pin, on time, off time
Sweeper sweeper1 (45); // controls the speed of the servo (lower = faster)
void setup()
{
Serial.begin(9600);
sweeper1.Attach(3); // attaches sweeper1 servo to pin 3
}
void loop()
{
sweeper1.Update();
LED.Update();
BUZZER.Update();
}
The next step is to make them work with button pushes using the AND function.
At first it is all "Hey, I'll do whatever you want, whenever you want", but then as soon as you try to do anything else at the same time the possessive nature of the Delay function shows itself. Now it is a case of "Honey, if you even think of bringing anything else into this loop that we've got going on then I'll make your life a living hell."
OK, so maybe that picture is not the best one, but who wants their code to do only one thing?
anyway...
It is time to ditch the delay and learn how to use millis.
[hours pass]
With help from the excellent tutorials by Bill Earl on the Adafruit website I have re-written the code to use 'millis' to do the timing of the light, buzzer and servo.
So far so good.
#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
increment = -increment;
}
}
}
};
Flasher LED(10, 300, 700); // pin, on time, off time
Flasher BUZZER(11, 200, 800); // pin, on time, off time
Sweeper sweeper1 (45); // controls the speed of the servo (lower = faster)
void setup()
{
Serial.begin(9600);
sweeper1.Attach(3); // attaches sweeper1 servo to pin 3
}
void loop()
{
sweeper1.Update();
LED.Update();
BUZZER.Update();
}
The next step is to make them work with button pushes using the AND function.
Comments
Post a Comment