Code help needed for relay shield for Halloween

Well, it’s that time of year again… Halloween Prop building time! This years prop requires help with the code that will enable several boards to shake that are covering a window.

I have a photon in a v2 relay shield powering 2 separate 12VDC automotive door lock actuators. Each actuator is connected to 2 wooden boards. I flashed the Photon with one of the library relay shield programs to test it out, and it works fine. Now it needs a little coding magic that I cannot provide.

I ordered a motion sensor that is taking its sweet time getting here. I would like it to trigger a routine. I do not know if the trigger will be high or low as of right now.

Currently, the code turns all relays on and off continuously by a time I specify. I would like the actuators to alternate so that all boards aren’t shaking in unison. Additionally, there should be a time limit on the total runtime per triggering episode.

Any help would be greatly appreciated!

Something like this?

if (triggered){
    for(uint8_t i = 3; i <= 7; i++ ){
        if(i != 7) digitalWrite(i,HIGH);
        if(i != 3) digitalWrite(i-1,LOW);
        delay(1000);
    }
}

Assuming you are using the default pins on the relay shield V2

This sure looks fun! :ghost:

My apologies, I am not very well versed in code.

Is that for the motion sensor only?
I am using the default Particle App “2-control-all-relays.ino”.

I have modified some code that was written for me by harrisonhjones. It worked a week ago, now it is unpredictable. Can someone look at it and help me fix it?

int RELAY1 = D3;
int RELAY2 = D4;
int MOTION1 = D0;
 
unsigned long lastMotionTime = 0; 
int propDelay = 250; // In milliseconds(1/4 second)
int propOnTime = 10000; // In milliseconds(10 seconds)
int state = 0;          // Normal operation = 0, Waiting to actuate prop in 1/4 second = 1, Actuating props for 10 seconds = 2
 
void setup()
{
    // Initilize the pins
    pinMode(RELAY1, OUTPUT);
    pinMode(RELAY2, OUTPUT);
    pinMode(MOTION1, INPUT);
    
    // Initialize all relays to an OFF state
    digitalWrite(RELAY1, LOW);
    digitalWrite(RELAY2, LOW);
    
    
    // Register two functions, one to allow for individual actuation of each relay and the other to test the effect
    Spark.function("relay", relayControl);
    Spark.function("test", test);
    
}
 
void loop()
{
    // In the normal "reset" state wait for a LOW signal on the motion detector. When that motion is seen record the time and go to the next state 
    if(state == 0)
    {
       if(digitalRead(MOTION1) == HIGH)
        {
            lastMotionTime = millis();
            state = 1;
        }
        else
        {
            // In the normal state the relays should not be ON"
            digitalWrite(RELAY1, LOW);
            digitalWrite(RELAY2, LOW);
            
        }
    }
    // Wait for 10 seconds then go to the next state
    else if(state == 1)
    {
        if((millis() - lastMotionTime) > propDelay)
        {
            state = 2;
        } 
    }
    // For the next 20 seconds bring the relays "ON". Once 20 seconds has passed go back to the normal or "rest" state
    else if(state == 2)
    {
        if((lastMotionTime + propOnTime) < millis())
        {
            state = 0;
        }
        else
        {
            digitalWrite(RELAY1, HIGH);
        delay(75);    
            digitalWrite(RELAY2, HIGH);
            
        }    
        delay(100);
        {
            digitalWrite(RELAY1, LOW);
        delay(200);
            digitalWrite(RELAY2, LOW);
            
        }    
        delay(75);
        {
            digitalWrite(RELAY1, HIGH);
        delay(400);    
            digitalWrite(RELAY2, HIGH);
            
        }   
        delay(100);
        {
            digitalWrite(RELAY1, LOW);
        delay(100);    
            digitalWrite(RELAY2, LOW);
            
        }
    }
    // Catch any mistakes and just go back to the normal state
    else
    {
        state = 0;
    }
    
}
 
int test(String command)
{
    // To test just simulate a low signal on the motion
    lastMotionTime = millis();
    state = 1;
}
 
// Taken from the relay example code in the SparkCore docs
// command format r1,HIGH
int relayControl(String command)
{
  int relayState = 0;
  // parse the relay number
  int relayNumber = command.charAt(1) - '0';
  // do a sanity check
  if (relayNumber < 1 || relayNumber > 3) return -1;
 
  // find out the state of the relay
  if (command.substring(3,7) == "HIGH") relayState = 1;
  else if (command.substring(3,6) == "LOW") relayState = 0;
  else return -1;
 
  // write to the appropriate relay
  digitalWrite(relayNumber-1, relayState);
  return 1;
}