I need to turn one relay on momentarily after another relay turns off.

I am very new to coding and i am working on a project to assemble parts. I have a ldr to turn on motor connected to relay1 and i would like for relay 2 to turn on momentarily after the part passes over the ldr to eject the assembled part but it cant always be on or it would get in the way of the next part coming through. here is my code so far

int relay1=8;
int relay2=7;
#define LDRpin A0 // pin where we connected the LDR and the resistor

int LDRValue = 0;
void setup() {
  // put your setup code here, to run once:
pinMode(relay1,OUTPUT);
Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  LDRValue = analogRead(LDRpin); // read the value from the LDR
  Serial.println(LDRValue);      // print the value to the serial port
  delay(100); 

   if(LDRValue>500)
digitalWrite(relay1,HIGH );
else
digitalWrite(relay1,LOW );
}

Try a state machine to sequence relays like this:

const byte relay1 = 8;
const byte relay2 = 7;

#define LDRpin A0 // pin where we connected the LDR and the resistor

#define RELAY2_TIME     250     //250mS

int LDRValue = 0;

void setup() 
{
    // put your setup code here, to run once:
    pinMode( relay1, OUTPUT );
    pinMode( relay2, OUTPUT );
    Serial.begin( 9600 );
    
}//setup

void loop() 
{
    RelayStateMachine();
    
}//loop


#define ST_WAIT_PART        0
#define ST_PART_PRESENT     1
#define ST_TIME_RLY2        2
void RelayStateMachine( void )
{
    static byte
        stateRelays = ST_WAIT_PART;
    static unsigned long
        timeMonitor = 0,
        timeRelays = 0;
    unsigned long
        timeNow;

    timeNow = millis();

    
    LDRValue = analogRead(LDRpin); // read the value from the LDR
    if( (timeNow - timeMonitor) >= 100 )
    {
        //send LDR value to serial port at ~10Hz
        timeMonitor = timeNow;
        Serial.print( "LDR: " );
        Serial.println( LDRValue );
        
    }//if

    switch( stateRelays )
    {
        case    ST_WAIT_PART:
            if( LDRValue > 500 )
            {
                //LDR shows something there; turn on relay1
                digitalWrite( relay1, HIGH );
                stateRelays = ST_PART_PRESENT;
                
            }//if
 
            
        break;
        
        case    ST_PART_PRESENT:
            if( LDRValue <= 500 )
            {
                //part has passed; turn off relay 1 and turn on relay 2
                //set up for timing relay 2 on time
                digitalWrite( relay1, LOW );
                digitalWrite( relay2, HIGH );
                timeRelays = timeNow;
                stateRelays = ST_TIME_RLY2;
                
            }//if
            
        break;

        case    ST_TIME_RLY2:
            //relay 2 stays on for RELAY2_TIME mS. When that time has passed turn it off
            //and return to state waiting for another part
            if( (timeNow - timeRelays) < RELAY2_TIME )
                return;
                
            digitalWrite( relay2, LOW );
            stateRelays = ST_WAIT_PART;
        
        break;
                
    }//switch
    
}//RelayStateMachine

Thank you that is close but relay 2 controls a solenoid and cant always be on or it will block the next part from falling into place. and when i said im new to this im really new. thank you for your time

kevpkos:
Thank you that is close but relay 2 controls a solenoid and cant always be on or it will block the next part from falling into place. and when i said im new to this im really new. thank you for your time

The code as written should only close relay 2 for 250mS after relay 1 opens.

Have you tried it?

i tested it and when light is present relay 2 is always open and when light is not present relay 2 turns off then relay1 turns on then relay 2 activates after 250 ms and stays on then when light is reintroduced relay 2 turns off then relay 1 turn off then relay 2 turns back on. sorry if thats confusing.

kevpkos:
i tested it and when light is present relay 2 is always open and when light is not present relay 2 turns off then relay1 turns on then relay 2 activates after 250 ms and stays on then when light is reintroduced relay 2 turns off then relay 1 turn off then relay 2 turns back on. sorry if thats confusing.

I based my code on yours and your limited description of what's going on.

In your code, if the LDR "reads" more than 500 the relay1 pin is set "high", otherwise the relay1 pin is set "low":

   if(LDRValue>500)
digitalWrite(relay1,HIGH );
else
digitalWrite(relay1,LOW );

That is emulated in the first two states of the state machine:

        case    ST_WAIT_PART:
            if( LDRValue > 500 )
            {
                //LDR shows something there; turn on relay1
                digitalWrite( relay1, HIGH );
                stateRelays = ST_PART_PRESENT;
                
            }//if
 
            
        break;
        
        case    ST_PART_PRESENT:
            if( LDRValue <= 500 )
            {
                //part has passed; turn off relay 1 and turn on relay 2
                //set up for timing relay 2 on time
                digitalWrite( relay1, LOW );
                digitalWrite( relay2, HIGH );
                timeRelays = timeNow;
                stateRelays = ST_TIME_RLY2;
                
            }//if
            
        break;

I assumed the LDR reads less than 500 when the part passes over the LDR. In state 2, the relay1 pin is set low and the relay2 pin is set high. It should stay high for 250mS and then go low:

        case    ST_TIME_RLY2:
            //relay 2 stays on for RELAY2_TIME mS. When that time has passed turn it off
            //and return to state waiting for another part
            if( (timeNow - timeRelays) < RELAY2_TIME )
                return;
                
            digitalWrite( relay2, LOW );
            stateRelays = ST_WAIT_PART;
        
        break;

You don't say what "momentary" is so I guessed at 250mS.

In your last post you say:

when light is present relay 2 is always open and when light is not present relay 2 turns off then relay1 turns on then relay 2 activates after 250 ms and stays on then when light is reintroduced relay 2 turns off then relay 1 turn off then relay 2 turns back on.

You're right, this is confusing.

  1. How did your original code operate relay 1?
  2. To me, the terms "open" and "off" mean the same thing when applied to SPST-NO relays (again, another assumption on my part because your post was non-specific.)
  3. What does the serial monitor output of the LDR say? Does it make sense?
  4. How do you have your relays wired? Does a high on the pin energize the coil or de-energize it?

If you want more help you're going to have to be more clear and explain your setup better. I tried.

LDR reads LOW in the dark and it is used to sense a part overhead so perhaps

        case    ST_WAIT_PART:
            if( LDRValue <= 500 )
            {
                //LDR shows something there; turn on relay1
                digitalWrite( relay1, HIGH );
                stateRelays = ST_PART_PRESENT;
                
            }//if
 
            
        break;
        
        case    ST_PART_PRESENT:
            if( LDRValue > 500 )
            {
                //part has passed; turn off relay 1 and turn on relay 2
                //set up for timing relay 2 on time
                digitalWrite( relay1, LOW );
                digitalWrite( relay2, HIGH );
                timeRelays = timeNow;
                stateRelays = ST_TIME_RLY2;
                
            }//if
            
        break;

I have a technique for switch-case statements that have timed delays that uses 1 timer code up front.

Here it is shown as a way to remove delay() calls from switch-case code. I came up with this trick while un-blocking a greenhouse control sketch. I didn't know about some of the devices the code was for or what that code even did. I didn't bother learning it either, this trick let me change only how the waiting is done and the rest I didn't touch was all correct.

// add-a-sketch_un-delay 2018 by GoForSmoke @ Arduino.cc Forum
// Free for use, Apr 30/18 by GFS. Compiled on Arduino IDE 1.6.9.
// This sketch shows a general method to get rid of delays in code.
// You could upgrade code with delays to work with add-a-sketch.

#include <avr/io.h>
#include "Arduino.h"

iconst byte ledPin = 13;
unsigned long delayStart, delayWait;

void setup()
{
  Serial.begin( 115200 );
  Serial.println( F( "\n\n\n  Un-Delay Example, free by GoForSmoke\n" ));
  Serial.println( F( "This sketch shows how to get rid of delays in code.\n" ));

  pinMode( ledPin, OUTPUT );
};


/* The section of the original sketch with delays:
 * 
 * digitalWrite( ledPin, HIGH );   --  0
 * delay( 500 );
 * digitalWrite( ledPin, LOW );    --  1
 * delay( 250 );
 * digitalWrite( ledPin, HIGH );   --  2
 * delay( 250 );
 * digitalWrite( ledPin, LOW );    --  3
 * delay( 250 );
 * digitalWrite( ledPin, HIGH );   --  4
 * delay( 1000 );
 * digitalWrite( ledPin, LOW );    --  5
 * delay( 1000 );
 */

byte blinkStep; // state tracking for BlinkPattern() below

void BlinkPattern()
{
  //  // start of one-shot timer
  if ( delayWait > 0 ) // one-shot timer only runs when set
  {
    if ( millis() - delayStart < delayWait )
    {
      return; // instead of blocking, the undelayed function returns
    }
    else
    {
      delayWait = 0; // time's up! turn off the timer and run the blinkStep case
    }
  }
  // end of one-shot timer

  // here each case has a timed wait but cases could change Step on pin or serial events.
  switch( blinkStep )  // runs the case numbered in blinkStep
  {
    case 0 :
    digitalWrite( ledPin, HIGH );
    Serial.println( F( "Case 0 doing something unspecified here at " ));
    Serial.println( delayStart = millis()); // able to set a var to a value I pass to function
    delayWait = 500; // for the next half second, this function will return on entry.
    blinkStep = 1;   // when the switch-case runs again it will be case 1 that runs
    break; // exit switch-case

    case 1 :
    digitalWrite( ledPin, LOW );
    Serial.println( F( "Case 1 doing something unspecified here at " ));
    Serial.println( delayStart = millis());
    delayWait = 250;
    blinkStep = 2;
    break;

    case 2 :
    digitalWrite( ledPin, HIGH );
    Serial.println( F( "Case 2 doing something unspecified here at " ));
    Serial.println( delayStart = millis());
    delayWait = 250;
    blinkStep = 3;
    break;

    case 3 :
    digitalWrite( ledPin, LOW );
    Serial.println( F( "Case 3 doing something unspecified here at " ));
    Serial.println( delayStart = millis());
    delayWait = 250;
    blinkStep = 4;
    break;

    case 4 :
    digitalWrite( ledPin, HIGH );
    Serial.println( F( "Case 4 doing something unspecified here at " ));
    Serial.println( delayStart = millis());
    delayWait = 1000;
    blinkStep = 5;
    break;

    case 5 :
    digitalWrite( ledPin, LOW );
    Serial.print( F( "Case 5 doing something unspecified here at " ));
    Serial.println( delayStart = millis());
    delayWait = 1000;
    blinkStep = 0;
    break;
  }
}


void loop()  // runs over and over, see how often
{            
  BlinkPattern();
}

Blackfin:
I based my code on yours and your limited description of what's going on.

In your code, if the LDR "reads" more than 500 the relay1 pin is set "high", otherwise the relay1 pin is set "low":

   if(LDRValue>500)

digitalWrite(relay1,HIGH );
else
digitalWrite(relay1,LOW );




That is emulated in the first two states of the state machine:



case    ST_WAIT_PART:
           if( LDRValue > 500 )
           {
               //LDR shows something there; turn on relay1
               digitalWrite( relay1, HIGH );
               stateRelays = ST_PART_PRESENT;
               
           }//if

break;
       
       case    ST_PART_PRESENT:
           if( LDRValue <= 500 )
           {
               //part has passed; turn off relay 1 and turn on relay 2
               //set up for timing relay 2 on time
               digitalWrite( relay1, LOW );
               digitalWrite( relay2, HIGH );
               timeRelays = timeNow;
               stateRelays = ST_TIME_RLY2;
               
           }//if
           
       break;




I assumed the LDR reads less than 500 when the part passes over the LDR. In state 2, the relay1 pin is set low and the relay2 pin is set high. It should stay high for 250mS and then go low:



case    ST_TIME_RLY2:
           //relay 2 stays on for RELAY2_TIME mS. When that time has passed turn it off
           //and return to state waiting for another part
           if( (timeNow - timeRelays) < RELAY2_TIME )
               return;
               
           digitalWrite( relay2, LOW );
           stateRelays = ST_WAIT_PART;
       
       break;




You don't say what "momentary" is so I guessed at 250mS.

In your last post you say:

You're right, this is confusing.

1) How did your original code operate relay 1?
2) To me, the terms "open" and "off" mean the same thing when applied to SPST-NO relays (again, another assumption on my part because your post was non-specific.)
3) What does the serial monitor output of the LDR say? Does it make sense?
4) How do you have your relays wired? Does a high on the pin energize the coil or de-energize it?

If you want more help you're going to have to be more clear and explain your setup better. I tried.

Blackfin:
I based my code on yours and your limited description of what's going on.

In your code, if the LDR "reads" more than 500 the relay1 pin is set "high", otherwise the relay1 pin is set "low":

   if(LDRValue>500)

digitalWrite(relay1,HIGH );
else
digitalWrite(relay1,LOW );




That is emulated in the first two states of the state machine:



case    ST_WAIT_PART:
           if( LDRValue > 500 )
           {
               //LDR shows something there; turn on relay1
               digitalWrite( relay1, HIGH );
               stateRelays = ST_PART_PRESENT;
               
           }//if

break;
       
       case    ST_PART_PRESENT:
           if( LDRValue <= 500 )
           {
               //part has passed; turn off relay 1 and turn on relay 2
               //set up for timing relay 2 on time
               digitalWrite( relay1, LOW );
               digitalWrite( relay2, HIGH );
               timeRelays = timeNow;
               stateRelays = ST_TIME_RLY2;
               
           }//if
           
       break;




I assumed the LDR reads less than 500 when the part passes over the LDR. In state 2, the relay1 pin is set low and the relay2 pin is set high. It should stay high for 250mS and then go low:



case    ST_TIME_RLY2:
           //relay 2 stays on for RELAY2_TIME mS. When that time has passed turn it off
           //and return to state waiting for another part
           if( (timeNow - timeRelays) < RELAY2_TIME )
               return;
               
           digitalWrite( relay2, LOW );
           stateRelays = ST_WAIT_PART;
       
       break;




You don't say what "momentary" is so I guessed at 250mS.

In your last post you say:

You're right, this is confusing.

1) How did your original code operate relay 1?
2) To me, the terms "open" and "off" mean the same thing when applied to SPST-NO relays (again, another assumption on my part because your post was non-specific.)
3) What does the serial monitor output of the LDR say? Does it make sense?
4) How do you have your relays wired? Does a high on the pin energize the coil or de-energize it?

If you want more help you're going to have to be more clear and explain your setup better. I tried.

Sorry I am very new to alot of electronics and coding so thank you for bearing with me. ill try to be more specific. the original code was meant to close relay1 (applys power to the motor). it seams that with the current code you wrote it rests at ST_PART_PRESENT with relay 2 set to high which closes the relay (applys power to the solenoid). what i am going for with the code is when a part passes over the ldr and no light is present i would like relay1 to close (apply power to the motor) and when the part passes through the rollers on the machine and past the ldr thus exposing it to light i would like to open relay1 (removing power from motor) and close relay2 for about 1000ms (applying power to the solenoid and ejecting the part) and then return to both relays open waiting for another part to pass over the ldr. and again thank you very much for your time and help.

When the LDR is dark the pin as set should give very low numbers like less than 50 not less than 500.
When it is not dark, look for more than 100 or maybe 200. In between is no change.

LDR is a little slow to change but less than a blink, my favorite light sensor is the greatly-faster photo-transistor.

That LDR could be wired to a digital pin on one side and ground on the other. With the pin mode set to INPUT_PULLUP, any time light falls on the sensor the pin will read LOW while sensor in darkness would read HIGH. The digital read is 20x or more faster than the analog read.

What you don't know can be learned. Instant prepared answers! https://www.arduino.cc/en/Tutorial/Foundations

It beats spending hours doing what won't work with more mysteries than solid, you need solid to build on.
The top 3 topics are basic knowhow you need get out of start.