Hey everyone, I’m currently working on creating a display robot for the upcoming Burning Man festival. I got stumped on the power systems amp relays and using interrupts. I’m using an Arduino Mega ADK, along with an 8 relay board hooked up to the Arduino.
We’re using delays because the relays aren’t fast, and they have to be done in a certain order. In addition, we need to give the equipment that’s attached to the relays time to power down before going to the next step.
The problem is I really want to implement this via interrupts, primarily for our most important functions, like the activity monitor, the rain monitor, and the fan functions. Here’s the code.
#include <Wire.h>
#include <RTClib.h>
RTC_DS1307 rtc; // To calculate the date and time functions for the main program
/************************************************************************
Setup the power system relays on the Arduino Mega
************************************************************************/
const int Relay01 = 39; // Across Generator relay 1:2
const int Relay02 = 37; // Across Generator relay 2:3
const int Relay03 = 35; // Across Generator relay 5:6
const int Relay04 = 33; // Amp 1
const int Relay05 = 31; // Amp 2
const int Relay06 = 29; // Amp 3
const int Relay07 = 27; // Cooling Fan
const int Relay08 = 25; // Night Lights
/*************************************************************************
Setup the Input Monitoring Pins: NOTE - for test purposes, we're using
rainPin 3 as the shutdown pin during simulation, cause we do want to shut
down the system when it's raining!
*************************************************************************/
const int activityPin = 2; // Activity Monitor pin on interrupt 2 - returns HIGH or LOW
const int rainPin = 3; // Rain Monitor pin on interrupt 3 - returns HIGH or LOW
const int temperaturePin = 21; // Temperature Monitor on interrupt 21 - returns HIGH or LOW
const int batteryPin = 4; // Battery Voltage check - on a scheduled time basis - returns HIGH or LOW
const int enginePin = 5; // Engine on or off check - returns HIGH or LOW
/**************************************************************************
Setup our variables that are read in from the input pins
**************************************************************************/
int val_activity = 0; // activity variable
int val_rain = 0; // rain variable
int val_temp = 0; // temperature variable
int val_battery = 0; // battery variable
int val_engine = 0; // engine variable
/***************************************************************************
Setup our integer variables for the engine logic to start or shut it off.
These correspond to the amp relays on the generator engine. NOT the relays
on the 8 relay board!
***************************************************************************/
int rel01;
int rel02;
int rel03;
void setup() {
/***************************************************************
Setup the Relay pins to output
***************************************************************/
pinMode(Relay01, OUTPUT);
pinMode(Relay02, OUTPUT);
pinMode(Relay03, OUTPUT);
pinMode(Relay04, OUTPUT);
pinMode(Relay05, OUTPUT);
pinMode(Relay06, OUTPUT);
pinMode(Relay07, OUTPUT);
pinMode(Relay08, OUTPUT);
/***************************************************************
Setup the 8 relay board all to HIGH. It's a negative logic board.
HIGH means the relay is OPEN. LOW means the relay is closed
****************************************************************/
digitalWrite(Relay01, HIGH);
digitalWrite(Relay02, HIGH);
digitalWrite(Relay03, HIGH);
digitalWrite(Relay04, HIGH);
digitalWrite(Relay05, HIGH);
digitalWrite(Relay06, HIGH);
digitalWrite(Relay07, HIGH);
digitalWrite(Relay08, HIGH);
/***************************************************************
Setup the Monitoring Pins to Input
***************************************************************/
pinMode(activityPin, INPUT);
pinMode(rainPin, INPUT);
pinMode(temperaturePin, INPUT);
pinMode(batteryPin, INPUT);
pinMode(enginePin, INPUT);
/*****************************************************************
Setup the RTC Clock Function
*****************************************************************/
#ifdef AVR
Wire.begin();
#else
Wire1.begin(); // Shield I2C pins connect to alt I2C bus on Arduino Due
#endif
rtc.begin();
if (! rtc.isrunning()) {
Serial.println("RTC is NOT running!");
// following line sets the RTC to the date & time this sketch was compiled
rtc.adjust(DateTime(__DATE__, __TIME__));
}
/*****************************************************************
Setup the Serial Port
*****************************************************************/
Serial.begin(9600);
/*****************************************************************
Attach the interrupts to test the system start and
system stop functions.
*******************************************************************/
attachInterrupt(2, system_start, RISING);
attachInterrupt(3, system_stop, RISING);
}
void loop() {
//val_activity = digitalRead(activityPin); // read in the activity pin
// val_rain = digitalRead(rainPin); // read in the shutdown pin
//Serial.println(val_activity);
//Serial.println(val_rain);
// buttontest(); // The button test simply emulates our inputs into the robot.
}
void buttontest() {
if (val_activity == 1) {
system_start();
} else {
}
if (val_rain == 1) {
system_stop();
} else {
}
}
void system_start() {
delay(500);
digitalWrite(Relay01, LOW); // attached to generator relay 1 and 2 CLOSED
rel01 = 0; // set rel01 value to 0 to indicate state for fan function
delay(500);
digitalWrite(Relay02, HIGH); // attached to generator relay 2 and 3 OPEN
rel02 = 1; // set rel02 value to 1
delay(500);
digitalWrite(Relay03, HIGH); // attached to generator relay 5 and 6 OPEN
delay(500);
rel03 = 1;
digitalWrite(Relay01, HIGH);
delay(500);
digitalWrite(Relay04, LOW); // turn on Amp 1
delay(500);
digitalWrite(Relay05, LOW); // turn on Amp 2
delay(500);
digitalWrite(Relay06, LOW); // turn on Amp 3
delay(500);
digitalWrite(Relay08, LOW); // turn on lights for the night
delay(500);
}
void system_stop() {
digitalWrite(Relay04, HIGH); // shutdown Amp 1
delay(500);
digitalWrite(Relay05, HIGH); // shutdown Amp 2
delay(500);
digitalWrite(Relay06, HIGH); // shutdown Amp 3
delay(500);
digitalWrite(Relay01, HIGH); // attached to generator relay 1 and 2
delay(500);
rel01 = 1;
digitalWrite(Relay02, LOW); // attached to generator relay 2 and 3 CLOSED for shutdown
rel02 = 0;
delay(500);
digitalWrite(Relay03, LOW); // attached to generator relay 5 and 6 CLOSED for shutdown
rel03 = 0;
digitalWrite(Relay08, LOW); // leave the lights alone
delay(500);
}
The problem with this second version is, obviously, the relays blaze with complete disregard to the delays. I understand that the hardware interrupts disable the delay() function, and the Millis() function in order for it to function AS an interrupt. No problems understanding that. My problem is this:
Is there another way to implement a time delay when using a hardware interrupt? So far, all the examples I see using Millis involve blinking an LED. I’ve gone way beyond that.
Any advice is appreciated.