Hi. I'm having some trouble wrapping my head around using millis. I've read examples, searched the forums but haven't seen anything specific to what I'm looking for and I can't seem to adapt other projects to my project.
I have a hall sensor fixed on my project and a magnet rotating around it. I want a light to come on when it senses the magnet. The magnet only triggers the hall sensor for less than a second but I want the light to remain on for 3 seconds when it is initially triggered.
I've tried using the "Blink without Delay" code and modifying it and put the light stuff in a separate function but I'm clearly missing something. Any help would be greatly appreciated.
// constants won't change. Used here to set a pin number:
const int ledPin = 7;// the number of the LED pin
const int hall = 2;
// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0; // will store last time LED was updated
// constants won't change:
const long interval = 3000; // interval at which to blink (milliseconds)
int magnet = 0;
void setup() {
// set the digital pin as output:
pinMode(ledPin, OUTPUT);
pinMode(hall, INPUT);
digitalWrite(ledPin, LOW);
}
void loop() {
magnet = digitalRead (hall);
if (magnet == 0) lightMe();
}
void lightMe () {
unsigned long currentMillis = millis();
digitalWrite(ledPin, HIGH);
if (millis >= currentMillis + interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
digitalWrite(ledPin, LOW);
}
}
My thinking was when the magnet pulls the pin LOW, start the funciton.
The currentMillis variable takes a snapshot of the current time.
Then in the if statement if current time is greater than or equal to the snapshot plus the interval, turn the light off.
Try renaming previousMillis to led_last_update
Then try if (currentMillis - led_last_update >= interval) {
and to keep timing consistent led_last_update += interval
Thank you for your reply. Here is the updated code:
// constants won't change. Used here to set a pin number:
const int ledPin = 7;// the number of the LED pin
const int hall = 2;
// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long led_last_update = 0; // will store last time LED was updated
// constants won't change:
const long interval = 3000; // interval at which to blink (milliseconds)
int magnet = 0;
void setup() {
// set the digital pin as output:
pinMode(ledPin, OUTPUT);
pinMode(hall, INPUT);
digitalWrite(ledPin, LOW);
}
void loop() {
magnet = digitalRead (hall);
if (magnet == 0) lightMe();
}
void lightMe () {
unsigned long currentMillis = millis();
digitalWrite(ledPin, HIGH);
if (currentMillis - led_last_update >= interval) {
// save the last time you blinked the LED
digitalWrite(ledPin, LOW);
}
led_last_update += interval;
}
The result is now the light only comes on when the magnet is triggering the sensor.
I have made a few corrections in the code. My assumptions are:
The hall effect sensor input is normally HIGH and goes LOW when it is triggered
When the sensor is triggered you want to light the LED for 3 seconds
While the LED is lit you want to ignore sensor triggers
Here is the updated code (compiled not tested):
// constants won't change. Used here to set a pin number:
const int ledPin = 7;// the number of the LED pin
const int hall = 2;
// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0; // will store last time LED was updated
// constants won't change:
const unsigned long interval = 3000; // interval at which to blink (milliseconds)
int ledState = LOW;
void setup()
{
// set the digital pin as output:
pinMode(ledPin, OUTPUT);
pinMode(hall, INPUT);
digitalWrite(ledPin, LOW);
}
void loop()
{
static int lastMagnet = digitalRead (hall);
int magnet = digitalRead (hall);
if (magnet != lastMagnet)
{
lastMagnet = magnet;
if (magnet == LOW && ledState == LOW)
{
// Turn LED on
ledState = HIGH;
digitalWrite(ledPin, HIGH);
previousMillis = millis();
}
}
ledTimer();
}
void ledTimer()
{
if (ledState == HIGH)
{
if (millis() - previousMillis > interval)
{
ledState = LOW;
digitalWrite(ledPin, LOW);
}
}
}
While you are looking at the code keep this in mind:
You want to trigger the LED when the sensor output BECOMES LOW not while it IS LOW. This is why you have to compare the sensor value to the previous sensor value.
When you are timing the LED you need to check every time during loop() not just when the sensor is LOW.
You need to keep up with the state of the LED so you will know whether you are waiting to turn the LED off or whether you are waiting for the sensor to go LOW so you can turn the LED on.