I want to modify this code so that the relay turns on as soon as I'm withing 2ft of the HC-SR04 but not turn the relay off till 15minutes after I'm outside that 2 foot range.
// defines pins numbers
const int trigPin = 11;
const int echoPin = 10;
const int relayPin = 6;
// defines variables
long duration;
int distance;
long distancemm;
void setup() {
// put your setup code here, to run once:
pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin, INPUT); // Sets the echoPin as an Input
pinMode(relayPin, OUTPUT);// Control Pin
//Serial.begin(9600); // Starts the serial communication
}
void loop() {
// put your main code here, to run repeatedly:
// Clears the trigPin
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
// Sets the trigPin on HIGH state for 10 micro seconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Reads the echoPin, returns the sound wave travel time in microseconds
duration = pulseIn(echoPin, HIGH);
// Calculating the distance
distance= duration*0.034/2;
distancemm = distance*10+30;
//Control
if (distancemm <= 610)
{
for (int i=0; i <= 50; i++){
digitalWrite(relayPin, HIGH);
delay(10);
}
}
else if (distancemm >= 611)
{
digitalWrite(relayPin, LOW);
}
else
{
//Safe! Continue usual tasks...
}
// Prints the distance on the Serial Monitor
//Serial.print("Distance: ");
//Serial.println(distance);
//Serial.print("Distance: ");
//Serial.print(distancemm);
//Serial.println("mm");
delay(250);
}
That's quite useless; once a pin is written HIGH, it will stay HIGH.
To answer your question, consider the use of a small finite state machine (FSM). You will have three states, I call the START, LIGHTON and TIMER.
You start in the START state where you wait till the distance is less than 610.
If that happens you switch to the LIGHTON state where you switch the relay on and wait till the distance is greater than 611.
If that happens you set the start time for a millis() based timer and switch to the TIMER state where you wait till the timer expires (current time - start time > 15 minutes).
If the timer expires, you go back to the start state.
In that last state you can also switch back to the LIGHTON state if the distance becomes less than 610 again. This is optional depending on your needs.
You can implement the FSM using e.g. switch/case statements.
If someone is willing to modify it for me that would be wonderful but I don't want to assume it is appropriate to ask for someone to do that. This is code I found online for basic distance sensor function which does work. I just need it to do a bit more. I'm new to Arduino and struggling. I'm in a group project building an arcade machine. I want to be able to walk up to the machine and the distance sensor to trigger the relay when I get close so that the screen and some leds turn on and then don't turn of till the user has walked away for at least 15mins. I'm trying to read about FSM as suggested by @sterretje but initially it seems a little out of my depth but I may need to just keep looking for FSM walk through geared towards newbies though it seems that's more of a novice skill set from how it's being presented in the guides I've found so far.
enum STATES
{
START,
LIGHTON,
TIMER,
};
const int8_t relayPin = 6;
const uint32_t duration = 900000UL;
void setup()
{
Serial.begin(115200);
pinMode(relayPin, OUTPUT);
}
void loop()
{
fsm();
}
/*
Read the distance
Returns:
distance in mm
*/
long readDistance()
{
long distancemm;
// to do
// distancemm = ...
// return the distance
return distancemm;
}
/*
finite statemachine for light control
*/
void fsm()
{
// state that we're in
static STATES state = START;
// start time for timer
static uint32_t startTime;
// read the distance
long distancemm = readDistance();
// state machine
switch (state)
{
case START:
if (distancemm <= 610)
{
// switch the light on
digitalWrite(relayPin, HIGH);
// go to next state
state = LIGHTON;
}
break;
case LIGHTON:
if (distancemm >= 611)
{
// 'start' the timer
startTime = millis();
// go to next state
state = TIMER;
}
break;
case TIMER:
// if timer expired
if (millis() - startTime >= duration)
{
// switch light off
digitalWrite(relayPin, LOW);
// go to START
state = START;
}
// if triggered again, go back to LIGHTON
if (distancemm <= 610)
{
state = LIGHTON;
}
break;
}
}
The enum is like an integer but only knows certain values. As shown, START equals 0 and the others are incremented by 1.
There are two functions.
fsm() is the implementation of the FSM. It reads the distance using the function readDistance() and next takes decisions in the switch/state.
You will have to implement the readDistance() by copying parts of your existing program (the triggering, the pulsin() and the calculation).
I hope that this gets you on track; ask what you don't understand.