Seeking assistance - New to Arduino SOLVED THANK YOU

Hello and thank you for taking the time to have a look at my problem.

I am new to Arduino and have a project which I am using to slowly learn coding. Unfortunately my progress has stalled as I have hit a snag. Two to be precise.

The first snag :
I am using PIR Sensors to trigger relays. Simple stuff I know.

I have 2 (two) PIR sensors connected to a uno wifi using Digi 6 (Sensor 1) & Digi 7 (Sensor 2). For some reason, once uploaded and running, it ignores Sensor 1 but always triggers on Sensor 2. I have swapped PIR to ensure it's not hardware related, and I have also removed Digi 7 from my code and have been able to trigger the program using Digi 6. However, when I have both as Inputs, it ignores 6 and only triggers on 7.

The second Snag:
I have a smoke machine on Digi 9 (Smoke), and I would like to have it turn on and off during the program. At the moment I can only get it to run at the start and then it stays on for the duration. I have tried to find some other examples, however when I implement the changes, my code seems to break. Ideally, I would like it to run as follows.

@ start - Smoke for 6 seconds then stop
@ 4 seconds - Turn on Laser & LED and run for 1min 02 Seconds
@ 9 seconds - Turn on Reaper & Fence and run for 58 Seconds
@ 10 seconds - Turn on smoke for 4 seconds then stop
@ 25 seconds - Turn on smoke for 4 seconds then stop
@ 40 seconds - Turn on smoke for 4 seconds then stop
@ 60 seconds - Turn on smoke for 4 seconds then stop

My code is below. Any help is appreciated

int Smoke = 9;
int Laser = 10;
int LED = 11;
int Reaper = 12;
int Fence = 13;
int sensor1 = 6;              // the pin that the sensor1 is atteched to
int sensor2 = 7;              // the pin that the sensor2 is atteched to
int state = LOW;             // by default, no motion detected
int val = 0;                 // variable to store the sensor status (value)

void setup() { 
  pinMode(Smoke, OUTPUT);      // initalize Smoke as an output
  pinMode(Laser, OUTPUT);      // initalize Laser as an output
  pinMode(LED, OUTPUT);      // initalize Smoke as an output
  pinMode(Reaper, OUTPUT);      // initalize Laser as an output
  pinMode(Fence, OUTPUT);      // initalize Smoke as an output
  pinMode(sensor1, INPUT);    // initialize sensor as an input
  pinMode(sensor2, INPUT);    // initialize sensor as an input
  Serial.begin(9600);        // initialize serial
}

void loop(){
  val = digitalRead(sensor1);   // read sensor value
  val = digitalRead(sensor2);   // read sensor value
  if (val == HIGH) {           // check if the sensor is HIGH
    digitalWrite(Smoke, HIGH);   // turn LED ON
    delay(4000);                // delay 4000 milliseconds 
    digitalWrite(Laser, HIGH);   // turn LED ON
    digitalWrite(LED, HIGH);   // turn LED ON
    delay(5000);                // delay 5000 milliseconds 
    digitalWrite(Reaper, HIGH);   // turn LED ON
    digitalWrite(Fence, HIGH);   // turn LED ON
    delay(58000);             // delay 58000 milliseconds 
    if (state == LOW) {
      Serial.println("Motion detected!"); 
      state = HIGH;       // update variable state to HIGH
    }
  }
  
  else {
      digitalWrite(Smoke, LOW); // turn LED OFF
      digitalWrite(Laser, LOW); // turn LED OFF
      digitalWrite(LED, LOW); // turn LED OFF
      digitalWrite(Reaper, LOW); // turn LED OFF
      digitalWrite(Fence, LOW); // turn LED OFF
      delay(62000);             // delay 62000 milliseconds 
      
      if (state == HIGH){
        Serial.println("Motion stopped!");
        state = LOW;       // update variable state to LOW
    }
  }
}

You store the information of both sensors in the same variable; so digitalRead(sensor2) overwrites the previous value. You can use 2 variables (e.g. val1 and val2) but your code does not seem to require them to be stored. So you can use

if(digitalRead(sensor1) == HIGH)
{
  ...
  ...
}
if(digitalRead(sensor2) == HIGH)
{
  ...
  ...
}

if the two sensors need to trigger different things.

Or you can use

if(digitalRead(sensor1) == HIGH && digitalRead(sensor2) == HIGH)
{
  ...
  ...
}

if both sensors need to be triggered before something happens

Or

if(digitalRead(sensor1) == HIGH || digitalRead(sensor2) == HIGH)
{
  ...
  ...
}

if either sensors need to be triggered before something happens

You cannot use the same variable name to hold the state of both PIR sensors. And val is not a very descriptive name for a variable. I suggest something like sensor1State and sensor2State. Those names more accurately describe what the variable is for. Descriptive names for variables and functions help to self comment the code.

Your comment does not match the actual code. No comment is better than a wrong comment.

The delay() function halts almost all processor activity (blocks execution). You should try to learn to write non-blocking code.

Non-blocking timing tutorials:
Blink without delay().
Beginner's guide to millis().
Several things at a time.

sorry the comment was what I started with and I never changed when I modified the delay.

Also thank you for the link suggests, I did find these during my travels, however I wasn't able to work out how to do as I detailed above.

Also, even corrected, a comment which just echoes the code is of no real value.

I am sorry I don't understand what is meant by this. I am extremely noob at this, and I have come this far by trial and error, a little bit of cut and paste and a whole like of patients.

Thank you for those suggestions. I will give them a try.

The point of comments is to tell the reader something they don't know, often explaining why you're doing something when it isn't clear from the code.

Comments like this though are just to satisfy someone's insistence that every line has a comment because it merely echoes the code:

    delay(4000);                // delay 4000 milliseconds 

understood Thank you

Hi
see if this code meets your need.

int Smoke = 9;
int Laser = 10;
int LED = 11;
int Reaper = 12;
int Fence = 13;
int sensor1 = 6;              // the pin that the sensor is atteched to
int sensor2 = 7;              // the pin that the sensor is atteched to
bool state = false;           // by default, no motion detected
unsigned long cycleTime = 0;
//-------------------------------------------------------------------
void setup() {
  pinMode(Smoke, OUTPUT);      // initalize Smoke as an output
  pinMode(Laser, OUTPUT);      // initalize Laser as an output
  pinMode(LED, OUTPUT);      // initalize Smoke as an output
  pinMode(Reaper, OUTPUT);      // initalize Laser as an output
  pinMode(Fence, OUTPUT);      // initalize Smoke as an output
  pinMode(sensor1, INPUT);    // initialize sensor as an input
  pinMode(sensor2, INPUT);    // initialize sensor as an input
  Serial.begin(9600);        // initialize serial
}
//-------------------------------------------------------------------
void loop() {
  if (((digitalRead(sensor1) == HIGH) or (digitalRead(sensor2) == HIGH)) and (state == false)) {   // check if the sensor is HIGH
    state = true;                                              // Enable cycle
    Serial.println(" Start ");
    delay(100);
    cycleTime = millis();
  }
  cycle();
}
//-------------------------------------------------------------------
void cycle()
{
  if (state == true)
  {
    if (millis() - cycleTime < 6000)
    {
      //Serial.println(" @Start ");
      digitalWrite(Smoke, HIGH);          // turn LED ON
    }
    else
    {
      digitalWrite(Smoke, LOW); // turn LED OFF
      //Serial.println(" end@Start ");
    }
    if ((millis() - cycleTime > 4000) and (millis() - cycleTime < 62000))
    {
      digitalWrite(Laser, HIGH);          // turn LED ON
      //Serial.println(" laseON ");
    }
    else
    {
      digitalWrite(Laser, LOW); // turn LED OFF
      //Serial.println(" laseOFF ");
    }
    if (millis() - cycleTime > 9000 and millis() - cycleTime < 58000)
    {
      digitalWrite(Reaper, HIGH);   // turn LED ON
      digitalWrite(Fence, HIGH);   // turn LED ON
      //Serial.println(" ReaperON  FenceON ");
    }
    else
    {
      digitalWrite(Reaper, LOW); // turn LED OFF
      digitalWrite(Fence, LOW); // turn LED OFF
      //Serial.println(" ReaperOFF  FenceOFF ");
    }
    if (millis() - cycleTime > 10000 and millis() - cycleTime < 14000)
    {
      digitalWrite(Smoke, HIGH);          // turn LED ON
      //Serial.println(" SmokeON 10000 ");
    }
    else
    {
      digitalWrite(Smoke, LOW); // turn LED OFF
    }
    if (millis() - cycleTime > 25000 and millis() - cycleTime < 29000)
    {
      digitalWrite(Smoke, HIGH);          // turn LED ON
      //Serial.println(" SmokeON 25000 ");
    }
    else
    {
      digitalWrite(Smoke, LOW); // turn LED OFF
    }
    if (millis() - cycleTime > 40000 and millis() - cycleTime < 44000)
    {
      digitalWrite(Smoke, HIGH);          // turn LED ON
      //Serial.println(" SmokeON 40000 ");
    }
    else
    {
      digitalWrite(Smoke, LOW); // turn LED OFF
    }
    if (millis() - cycleTime > 60000 and millis() - cycleTime < 64000)
    {
      digitalWrite(Smoke, HIGH);          // turn LED ON
      //Serial.println(" SmokeON 60000 ");
    }
    else
    {
      digitalWrite(Smoke, LOW); // turn LED OFF
    }
    if (millis() - cycleTime > 64100 )
      state = false;
  }
}

Hi ruilviana,

Thanks for your suggestion. I have tried the code and the timings work, however the smoke relay isn't throwing over due to low voltage for some reason. I made sure I was using a PSU for power, and it was still doing it.

If I modified the coding, I got the following results

Below resulted in the first Smoke cue throwing the relay, but the second just the relay light turned on but the relay didn't throw due to low volage.

//-------------------------------------------------------------------
void cycle()
{
  if (state == true)
  {
    if (millis() - cycleTime < 6000)
    {
      //Serial.println(" @Start ");
      digitalWrite(Smoke, HIGH);          // turn LED ON
    }
    else
    {
      digitalWrite(Smoke, LOW); // turn LED OFF
      //Serial.println(" end@Start ");
    }
    if ((millis() - cycleTime > 4000) and (millis() - cycleTime < 62000))
    {
      digitalWrite(Laser, HIGH);          // turn LED ON
      //Serial.println(" laseON ");
    }
    else
    {
      digitalWrite(Laser, LOW); // turn LED OFF
      //Serial.println(" laseOFF ");
    }
    if (millis() - cycleTime > 9000 and millis() - cycleTime < 58000)
    {
      digitalWrite(Reaper, HIGH);   // turn LED ON
      digitalWrite(Fence, HIGH);   // turn LED ON
      //Serial.println(" ReaperON  FenceON ");
    }
    else
    {
      digitalWrite(Reaper, LOW); // turn LED OFF
      digitalWrite(Fence, LOW); // turn LED OFF
      //Serial.println(" ReaperOFF  FenceOFF ");
    }
    if (millis() - cycleTime > 10000 and millis() - cycleTime < 14000)
    {
      digitalWrite(Smoke, HIGH);          // turn LED ON
      //Serial.println(" SmokeON 10000 ");
    }
    else
    {
      digitalWrite(Smoke, LOW); // turn LED OFF
    }
    if (millis() - cycleTime > 64100 )
      state = false;
  }
}

I then tried the following which resulted in the first smoke cue relay light coming on, but not throwing the relay due to low voltage, yet the second cue @ 10secs did throw strangely.

//-------------------------------------------------------------------
void cycle()
{
  if (state == true)
  {
    if (millis() - cycleTime < 6000)
    {
      //Serial.println(" @Start ");
      digitalWrite(Smoke, HIGH);          // turn LED ON
    }
    else
    {
      digitalWrite(Smoke, LOW); // turn LED OFF
      //Serial.println(" end@Start ");
    }
    if (millis() - cycleTime > 10000 and millis() - cycleTime < 14000)
    {
      digitalWrite(Smoke, HIGH);          // turn LED ON
      //Serial.println(" SmokeON 10000 ");
    }
    else
    {
      digitalWrite(Smoke, LOW); // turn LED OFF
    }
    if (millis() - cycleTime > 64100 )
      state = false; 
  }
}

If I run the following code below, the first smoke cue triggers the relay correctly and LED, Laser, Reaper & Fence all start as intended.

//-------------------------------------------------------------------
void cycle()
{
  if (state == true)
  {
    if (millis() - cycleTime < 6000)
    {
      //Serial.println(" @Start ");
      digitalWrite(Smoke, HIGH);          // turn LED ON
    }
    else
    {
      digitalWrite(Smoke, LOW); // turn LED OFF
      //Serial.println(" end@Start ");
    }
    if ((millis() - cycleTime > 4000) and (millis() - cycleTime < 64000))
    {
      digitalWrite(LED, HIGH);          // turn LED ON
      //Serial.println(" LEDON ");
    }
    else
    {
      digitalWrite(LED, LOW); // turn LED OFF
      //Serial.println(" LEDOFF ");
    }
        if ((millis() - cycleTime > 4000) and (millis() - cycleTime < 62000))
    {
      digitalWrite(Laser, HIGH);          // turn LED ON
      //Serial.println(" laseON ");
    }
    else
    {
      digitalWrite(Laser, LOW); // turn LED OFF
      //Serial.println(" laseOFF ");
    }
  if (millis() - cycleTime > 9000 and millis() - cycleTime < 58000)
    {
      digitalWrite(Reaper, HIGH);   // turn LED ON
      digitalWrite(Fence, HIGH);   // turn LED ON
      //Serial.println(" ReaperON  FenceON ");
    }
    else
    {
      digitalWrite(Reaper, LOW); // turn LED OFF
      digitalWrite(Fence, LOW); // turn LED OFF
      //Serial.println(" ReaperOFF  FenceOFF ");
    }

From here if I add back in the smoke cue at 10 secs, only the first Smoke Cue triggers the relay correctly, however the second one just turns the light on due to under voltage.

Weird, however maybe there is an easy solution??

Thank you in advance.

How many relays do you have?

Please provide some form of schematic. Here's why:

To avoid a long litany of questions about hardware, it's best to provide some form of schematic. It can be a phot of a pen-on-paper drawing. Show all power connections, voltages, resistances, etc.

I’m using 2x4 way arduino boards powered by seperate 12v 1 amp power supply.

Controlled by arduino uno wifi board. Powered by 9v power supply

Triggered by 2 arduino PIR sensors

Hi,
I made some changes in the code to block possible "chime" of the relays.
Test again.

int Smoke = 9;
int Laser = 10;
int LED = 11;
int Reaper = 12;
int Fence = 13;
int sensor1 = 6;              // the pin that the sensor is atteched to
int sensor2 = 7;              // the pin that the sensor is atteched to
bool state = false;           // by default, no motion detected
unsigned long cycleTime = 0;
//-------------------------------------------------------------------
void setup() {
  pinMode(Smoke, OUTPUT);      // initalize Smoke as an output
  pinMode(Laser, OUTPUT);      // initalize Laser as an output
  pinMode(LED, OUTPUT);      // initalize Smoke as an output
  pinMode(Reaper, OUTPUT);      // initalize Laser as an output
  pinMode(Fence, OUTPUT);      // initalize Smoke as an output
  pinMode(sensor1, INPUT);    // initialize sensor as an input
  pinMode(sensor2, INPUT);    // initialize sensor as an input
  Serial.begin(9600);        // initialize serial
}
//-------------------------------------------------------------------
void loop() {
  if (((digitalRead(sensor1) == HIGH) or (digitalRead(sensor2) == HIGH)) and (state == false)) {   // check if the sensor is HIGH
    state = true;                                              // Enable cycle
    Serial.println(" Start ");
    delay(100);
    cycleTime = millis();
  }
  cycle();
}
//-------------------------------------------------------------------
void cycle()
{
  if (state == true)
  {
    if (millis() - cycleTime < 6000)
    {
      //Serial.println(" @Start ");
      digitalWrite(Smoke, HIGH);          // turn LED ON
    }
    if ((millis() - cycleTime >= 6000) and (millis() - cycleTime < 10000))
    {
      digitalWrite(Smoke, LOW); // turn LED OFF
      //Serial.println(" end@Start ");
    }
    if ((millis() - cycleTime > 4000) and (millis() - cycleTime < 62000))
    {
      digitalWrite(Laser, HIGH);          // turn LED ON
      //Serial.println(" laseON ");
    }
    else
    {
      digitalWrite(Laser, LOW); // turn LED OFF
      //Serial.println(" laseOFF ");
    }
    if (millis() - cycleTime > 9000 and millis() - cycleTime < 58000)
    {
      digitalWrite(Reaper, HIGH);   // turn LED ON
      digitalWrite(Fence, HIGH);   // turn LED ON
      //Serial.println(" ReaperON  FenceON ");
    }
    else
    {
      digitalWrite(Reaper, LOW); // turn LED OFF
      digitalWrite(Fence, LOW); // turn LED OFF
      //Serial.println(" ReaperOFF  FenceOFF ");
    }
    if (millis() - cycleTime > 10000 and millis() - cycleTime < 14000)
    {
      digitalWrite(Smoke, HIGH);          // turn LED ON
      //Serial.println(" SmokeON 10000 ");
    }
    if ((millis() - cycleTime >= 14000) and (millis() - cycleTime < 25000))
    {
      digitalWrite(Smoke, LOW); // turn LED OFF
    }
    if (millis() - cycleTime > 25000 and millis() - cycleTime < 29000)
    {
      digitalWrite(Smoke, HIGH);          // turn LED ON
      //Serial.println(" SmokeON 25000 ");
    }
    if ((millis() - cycleTime >= 29000) and (millis() - cycleTime < 40000))
    {
      digitalWrite(Smoke, LOW); // turn LED OFF
    }
    if (millis() - cycleTime > 40000 and millis() - cycleTime < 44000)
    {
      digitalWrite(Smoke, HIGH);          // turn LED ON
      //Serial.println(" SmokeON 40000 ");
    }
    if ((millis() - cycleTime >= 44000) and (millis() - cycleTime < 60000))
    {
      digitalWrite(Smoke, LOW); // turn LED OFF
    }
    if (millis() - cycleTime > 60000 and millis() - cycleTime < 64000)
    {
      digitalWrite(Smoke, HIGH);          // turn LED ON
      //Serial.println(" SmokeON 60000 ");
    }
    if (millis() - cycleTime >= 64000)
    {
      digitalWrite(Smoke, LOW); // turn LED OFF
    }
    if (millis() - cycleTime > 64100 )
      state = false;
  }
}
1 Like

Where is the power for the relay coils coming from? It’s a common problem when using multiple relays to find that the Arduino can’t supply enough current.

Ground of Arduino and 12V should be connected!
That connection is missing in your scheme.

@build_1971, that depends on the relay module; ones with optocoupler don't need that.

But there needs to be a path back to the Arduino for the signals. great detective :wink:

You are completely right... after all the idea of a relay is to get separated circuits...