Dear all,
I would like to replace the delay function with sleep, and wake up after 0.5sec
With some effort, I modified the code from this blog into a 0.5sec timer.
Now I wanted to include the code into my sensor.
#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/wdt.h>
volatile int f_wdt=1;
/////////////////////////////////////////////////////////////////////////////////////////////////////////
#define echoPin 7 // Echo Pin
#define trigPin 8 // Trigger Pin
#define LEDPin 13 // Onboard LED
#define motorPin 3
//////////////////////////////////////////////////////////////////////////////////////////////////////
ISR(WDT_vect)
{
if(f_wdt == 0)
{
f_wdt=1;
}
else
{
Serial.println("WDT Overrun!!!");
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void enterSleep(void)
{
set_sleep_mode(SLEEP_MODE_PWR_DOWN); /* EDIT: could also use SLEEP_MODE_PWR_DOWN for lowest power consumption. */
sleep_enable();
/* Now enter sleep mode. */
sleep_mode();
/* The program will continue from here after the WDT timeout*/
sleep_disable(); /* First thing to do is disable sleep. */
/* Re-enable the peripherals. */
power_all_enable();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int motorState = 0; // motorState used to set the LED
unsigned long previousMillis; // will store last time LED was updated
unsigned long startTime;
long interval = 1000;
boolean lastTrip;
boolean lastTrip2;
//
int maximumRange = 200; // Maximum range needed
int minimumRange = 10; // Minimum range needed
int triggerDistance = 10;
int crashDistance = 5;
//long duration, distance; // Duration used to calculate distance
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setup()
{
pinMode(motorPin, OUTPUT);
Serial.begin (9600);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(LEDPin, OUTPUT); // Use LED indicator (if required)
////////////////////////////////////////////////////////////////////////////////////////////////////////
/*** Setup the WDT ***/
/* Clear the reset flag. */
MCUSR &= ~(1<<WDRF);
/* In order to change WDE or the prescaler, we need to
* set WDCE (This will allow updates for 4 clock cycles).
*/
WDTCSR |= (1<<WDCE) | (1<<WDE);
/* set new watchdog timeout prescaler value */
WDTCSR = 1<<WDP0 | 1<<WDP2; /* 0.5 seconds */
/* Enable the WD interrupt (note no reset). */
WDTCSR |= _BV(WDIE);
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
long getDistance()
{
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
long duration = pulseIn(echoPin, HIGH);
long dist = duration/58.2;
return dist;
}
//////////////////////////////////////////////////////////////////////////////////
void runMotor()
{
if( millis() - startTime < 3000) // Three Second Interval
{
analogWrite(motorPin, 25);
//or digitalWrite(motorPin, HIGH);
}
else
{
analogWrite(motorPin, 0);
//or digitalWrite(motorPin, LOW);
motorState = 0;
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
void runMotor2()
{
if( millis() - startTime < 3000) // Three Second Interval
{
analogWrite(motorPin, 200);
//or digitalWrite(motorPin, HIGH);
}
else
{
analogWrite(motorPin, 0);
//or digitalWrite(motorPin, LOW);
motorState = 0;
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
void loop()
{
long distance = getDistance();
if (distance > minimumRange)
{
Serial.println(distance);
digitalWrite(LEDPin, LOW);
}
if (distance < minimumRange)
{
Serial.println(distance);
digitalWrite(LEDPin, HIGH);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
boolean tripped = (distance <= triggerDistance ? 1 : 0); // flag if triggered
if (tripped)
{
if (tripped != lastTrip)
{
startTime = millis();
motorState = 1;
}
}
lastTrip = tripped;
if (motorState == 1)
{
runMotor();
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
boolean tripped2 = (distance <= crashDistance ? 1 : 0); // flag if triggered
if (tripped2)
{
if (tripped2 != lastTrip2)
{
startTime = millis();
motorState = 2;
}
}
lastTrip = tripped;
if (motorState == 2)
{
runMotor2();
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
if (distance > triggerDistance)
{analogWrite(motorPin, 0);
motorState = 0;
/* Don't forget to clear the flag. */
f_wdt = 0;
/* Re-enter sleep mode. */
delay (100);
enterSleep();
}
}
While it does function as delay 500ms when distance > triggerDistance,
when my runmotor () triggers, it locks up and the runmotor script and the motor won't stop
In addition, sometimes it runs a wrong script.
.
Interestingly, if I trigger the ultrasonic sensor and quickly removes the object in front of it,
the program WILL NOT lock up and functions normally.
Any ideas?