I am relatively new to Arduino. This is my second project.
I am trying to setup a relay timer where the trigger switch can be used to both initiate the timer and activate the relay, as well as reset the relay and turn it off if required. Currently I have the duration set to 10sec, but in my live environment it will be 5 minutes. Hence the requirement to reset / manually turn off the relay.
Currently I have the initial trigger of the interrupt working perfectly. But the reset function is not working at all. Below is my code. Any help is welcomed.
#define relayPin 2 // the pin relay is connected
#define triggerPin 3 // the pin where start switch is connected
long triggerTime = 0;
int duration = 10000;
volatile byte relayState;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);// initialize serial monitor with 9600 baud
pinMode(relayPin, OUTPUT);
digitalWrite(relayPin, LOW);
pinMode(triggerPin, INPUT);
attachInterrupt(digitalPinToInterrupt(triggerPin), trigger, RISING);
Serial.println("Routine Begin");
}
void loop() {
// put your main code here, to run repeatedly:
if( (millis() - triggerTime) > duration && relayState == HIGH)
{
controlRelay();
Serial.print("Time - ");
Serial.println(millis() - triggerTime);
triggerTime = 0;
}
else
{
delay(50);
}
}// loop end
void trigger()
{
if(relayState == HIGH)
{
controlRelay();
Serial.println("Relay RESET");
triggerTime = 0;
}
else
{
triggerTime = millis();
controlRelay();
Serial.print("Time - ");
Serial.println(triggerTime / 1000);
}
}// trigger end
void controlRelay()
{
if(relayState == HIGH)
{
digitalWrite(relayPin, LOW);
relayState = LOW;
Serial.println("Relay OFF");
}
else
{
digitalWrite(relayPin, HIGH);
relayState = HIGH;
Serial.println("Relay ON");
}
}
The interrupt service routine trigger() should simply set a flag that the interrupt occurred, and exit. All other actions are carried out by the main program.
That flag might be a volatile global variable set equal to 1, which is reset to zero when the main program finishes the intended action.
You have the triggerPin set as INPUT. That suggests you have the switch wired with one side connected to the trigger pin and the other to 5V. If the is the case, when the switch is pressed, the pin will go high but when you release the switch it will be floating unless you have a resistor attached which pulls it low.
Another way of hooking up a button is to tie the switch to the pin and Ground and then set the pin mode to INPUT_PULLUP. With that configuration the pin is HIGH when the switch is open and low when the switch is closed. You can then change your code to do whatever you want when it is High or LOW . Example: ```
attachInterrupt(digitalPinToInterrupt(triggerPin), trigger, FALLING);
Thanks @PickyBiker, I got it working with your solution. Also had to introduce some debounce code for the input.
Here's my final code for critique and / or assistance for anyone else with a similar situation. (PS, i still need to clean it up a bit and remove all the serialprint's I was using to assist with debugging.)
#define relayPin 2 // the pin relay is connected
#define triggerPin 3 // the pin where start switch is connected
long triggerTime = 0;
long duration = 300000;
volatile byte relayState;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);// initialize serial monitor with 9600 baud
pinMode(relayPin, OUTPUT);
digitalWrite(relayPin, LOW);
pinMode(triggerPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(triggerPin), trigger, FALLING);
Serial.println("Routine Begin");
}
void loop() {
// put your main code here, to run repeatedly:
if( (millis() - triggerTime) > duration && relayState == HIGH)
{
controlRelay();
Serial.print("Time - ");
Serial.println(millis() - triggerTime);
triggerTime = 0;
}
else
{
delay(50);
}
}// loop end
void trigger()
{
static unsigned long last_interrupt_time = 0;
unsigned long interrupt_time = millis();
if (interrupt_time - last_interrupt_time > 300)
{
if(relayState == HIGH)
{
controlRelay();
Serial.println("Relay RESET");
triggerTime = 0;
}
else
{
triggerTime = millis();
controlRelay();
Serial.print("Time - ");
Serial.println(triggerTime / 1000);
}
}
last_interrupt_time = interrupt_time;
}// trigger end
void controlRelay()
{
if(relayState == HIGH)
{
digitalWrite(relayPin, LOW);
relayState = LOW;
Serial.println("Relay OFF");
}
else
{
digitalWrite(relayPin, HIGH);
relayState = HIGH;
Serial.println("Relay ON");
}
}