const int relay1 = 3;
const int relay2 = 4;
const int relay3 = 5;
const int relay4 = 6;
const int sensor1 = 8;
const int sensor2 = 9;
const int sensor3 = 10;
const int sensor4 = 11;
void setup() {
pinMode(relay1, OUTPUT);
pinMode(relay2, OUTPUT);
pinMode(relay3, OUTPUT);
pinMode(relay4, OUTPUT);
pinMode(sensor1, INPUT);
pinMode(sensor2, INPUT);
pinMode(sensor3, INPUT);
pinMode(sensor4, INPUT);
digitalWrite(relay1, LOW);
digitalWrite(relay2, LOW);
digitalWrite(relay3, LOW);
digitalWrite(relay4, LOW);
}
void loop() {
// read the state of the the input pin:
int sensor1 = digitalRead(8);
int sensor2 = digitalRead(9);
int sensor3 = digitalRead(10);
int sensor4 = digitalRead(11);
if (sensor1 == HIGH)
digitalWrite(relay1, HIGH);
else digitalWrite(relay1, LOW);
if (sensor2 == HIGH)
digitalWrite(relay2, HIGH);
else digitalWrite(relay2, LOW);
if (sensor3 == HIGH)
digitalWrite(relay3, HIGH);
else digitalWrite(relay3, LOW);
if (sensor4 == HIGH)
digitalWrite(relay4, HIGH);
else digitalWrite(relay4, LOW);
delay(6000);
}
Arduino UNO
4 relay module 5V
IR sensor MH-8
``
I've got a fairly simple question here. The issue I am having is that I'm trying to trigger one relay at a time from an IR sensor for 6 seconds. I can get it to run in a loop just fine but only one relay triggers at a time. I would like to be able to trigger all 4 of the relays independently without it waiting for the last relay to finish its 6 second cycle. Can anyone help please?
Your problem is caused by the use of the delay() function which stops anything else happening whilst the delay occurs. You need to use non blocking timing
Thanks, yep copy that. I understand i needed something like millis but am not sure how to use it accordingly. The "BlinkWithoutDelay" doesn't really give much. Do millis go after each relay command? 1,2,3, and 4?
Although it's not the cause of your problem, I noticed that you declared the global variables sensor1 - sensor4 as the pin numbers, then redefined them as the local variables that hold the state of those pins.
As for your delay problem, I suggest using millis() instead of delay() as that doesn't stop everything.
unsigned long relay1start;
unsigned long relay2start;
unsigned long relay3start;
unsigned long relay4start;
then in your loop:
if (sensor1 == HIGH) {
digitalWrite(relay1, HIGH);
relay1start = millis(); }
else if ((relay1start + 6000) < millis())
digitalWrite(relay1, LOW);
and repeat for the other three.
And of course, remove the delay(6000);
The other thing I would do, although it won't change the functionality, is to delete these:
// read the state of the the input pin:
int sensor1 = digitalRead(8);
int sensor2 = digitalRead(9);
int sensor3 = digitalRead(10);
int sensor4 = digitalRead(11);
This is good stuff! Thanks. So I'll remove the int sensor1 = digitalRead(8); 9, 10, and 11 as well since it is unnecessary. As far as replacing it with if digitalRead(sensor1) { . You mention replacing the first line of each test? Can you clarify where it goes. Forgive my beginner questions.
Thanks,
Welcome to the forum..
Looks like you're getting some great feedback already..
You know, maybe a good time to learn about arrays..
Give this a look over..
const byte relays[] = {3, 4, 5, 6};
const byte sensors[] = {8, 9, 10, 11};
unsigned long relayStart[4];
void setup() {
for (int i = 0; i < sizeof(relays); i++) {
pinMode(relays[i], OUTPUT);
digitalWrite(relays[i], LOW);
pinMode(sensors[i], INPUT);
}
}
void loop() {
for (int i = 0; i < sizeof(sensors); i++) {
if (digitalRead(sensors[i]) == HIGH) {
digitalWrite(relays[i], HIGH);
relayStart[i] = millis();
} else {
if ((relayStart[i] + 6000) < millis())
digitalWrite(relays[i], LOW);
}
}
}
Gotcha, thanks. So with all corrections made, it compiles ok but the function is backwards. Once the IR sensor is triggered, the relay doesn't come on until 6 seconds. I would like the relay to come on immediately after the IR sensor is triggered and then stay on for 6 secs. While being able to trigger the other relays at the same time as well. Here's the updated code:
unsigned long relay1start;
unsigned long relay2start;
unsigned long relay3start;
unsigned long relay4start;
const int relay1 = 3;
const int relay2 = 4;
const int relay3 = 5;
const int relay4 = 6;
const int sensor1 = 8;
const int sensor2 = 9;
const int sensor3 = 10;
const int sensor4 = 11;
void setup() {
pinMode(relay1, OUTPUT);
pinMode(relay2, OUTPUT);
pinMode(relay3, OUTPUT);
pinMode(relay4, OUTPUT);
pinMode(sensor1, INPUT);
pinMode(sensor2, INPUT);
pinMode(sensor3, INPUT);
pinMode(sensor4, INPUT);
digitalWrite(relay1, LOW);
digitalWrite(relay2, LOW);
digitalWrite(relay3, LOW);
digitalWrite(relay4, LOW);
int sensor1 = digitalRead(8);
int sensor2 = digitalRead(9);
int sensor3 = digitalRead(10);
int sensor4 = digitalRead(11);
}
void loop() {
if (digitalRead(sensor1) == HIGH) {
digitalWrite(relay1, HIGH);
relay1start = millis();
}
else if ((relay1start + 6000) < millis())
digitalWrite(relay1, LOW);
if (digitalRead(sensor2) == HIGH) {
digitalWrite(relay2, HIGH);
relay2start = millis();
}
else if ((relay2start + 6000) < millis())
digitalWrite(relay2, LOW);
if (digitalRead(sensor3) == HIGH) {
digitalWrite(relay3, HIGH);
relay3start = millis();
}
else if ((relay3start + 6000) < millis())
digitalWrite(relay3, LOW);
if (digitalRead(sensor4) == HIGH) {
digitalWrite(relay4, HIGH);
relay4start = millis();
}
else if ((relay4start + 6000) < millis())
digitalWrite(relay4, LOW);
}
You're welcome..
Actually only difference is using arrays..
but it does also use millis, should be functionally the same as your code..
Curious, I see that in your testing the relay operation is reversed??
If it does, sounds like the relays are LOW triggered, do they activate during setup??
If yes, then you need to reverse the relay logic, current assumption is HIGH activates relay..
If you remove this from your setup, all should be okay:
int sensor1 = digitalRead(8);
int sensor2 = digitalRead(9);
int sensor3 = digitalRead(10);
int sensor4 = digitalRead(11);
The problem here is that you are assigning the state of the sensor to the variable, whereas it should be the pin number. You check the value later in the loop in the - if (digitalRead(sensor1)) { - line.
Yes, that's correct. The time starts the last time the sensor was active.
if (digitalRead(sensor1) == HIGH) { // checking the value of sensor 1 and processes the instructions between the curly brackets that follow. By the way, since the results can only be 0 or 1, the "== HIGH" isn't really necessary.
digitalWrite(relay1, HIGH); // turns relay 1 on
relay1start = millis(); // assigns the current "time" to the variable relay1start
}
else if ((relay1start + 6000) < millis()) // else means if the sensor input is not active, check to see if it has been more than 6 seconds past the "time" recorded in the variable relay1start.
digitalWrite(relay1, LOW); // if it has been more than 6 seconds, turn the relay off.
In general - Arrays and structs are your friends.
Don't duplicate code in your sketch. Write code once - use it multiple times.
You should not use magic numbers. The I/O pins love to have a functional name.
Do you have experience with programming in C++?
The task can easily be realised with an object.
A structured array contains all information, such as pin addresses for the I/O devices, as well as the information for the timing.
A single service takes care of this information and initiates the intended action.
The structured array makes the sketch scalable until all I/O pins are used up without having to adapt the code for the service.
It is cool stuff, isn´t it?