70Watt Latching Solenoid - erratic control issue

Hi all -

I have a 70 watt latching, pulse controlled solenoid that I'm trying to control with an Arduino.

To do so I'm using a DPDT relay wired in an H bridge configuration (in reality you'll see in the code that I've used two SPSTs programmed to always maintain opposite states...I didn't have a DPDT that could handle 70 watts DC so I went this route for the moment). Supply is a pretty standard 12V 100watt power supply (powering a 5V arduino pro mini via the RAW input). To apply the pulse and ensure that current only reaches the solenoid during the pulse period, a second SPST relay is wired in series ahead of the DPDT on the positive side, so the unpowered SPSTs switch to switch polarity, and the third SPST switches on and off to apply the pulse (relay has a 10ms max operate time, and ON pulse is 100ms, OFF pulse is 900ms with opposite polarity so speed shouldn't be an issue). I made a quick diagram on tinkercad of what the basic circuit looks like (I didn't include the protection diodes across the relay coils, but they are there in the real circuit).

The final design will respond to the rise and fall on a digital signal from a DAQ, but for now Im testing with barebones code that should latch and unlatch every 5 seconds. The solenoid mostly behaves but sometimes fails to latch or unlatch. I've also noticed that while watching the built-in LED that should be ON while latched and OFF while unlatched, the unlatched phase starts to get shorter and ends with a bump of the solenoid and a blink on the LED...this shouldnt be happening as far as I can tell from the code, and also doesnt begin to happen until a few cycles in, so I'm thinking the solenoid may be giving me a big kickback and throwing things out of whack somehow since the Arduino is powered from the same supply...if that's the case I'm having trouble imagining where the protection diode (assuming that's still the solution) would go given the switching polarity. Im also suspicious Im missing something fundamental about how these pulsed latching things work, because early in experimenting I was able to get the thing to latch and unlatch (unreliably) using only pulses and never switching polarity. Is there some way to determine if the polarity relative to the solenoid terminals should be a particular direction for the ON vs OFF, or does it only matter they they are opposite? Switching the leads it's always more reliable in one direction than the other while the program is running, but maybe that's more to do with pulse length?

In the final code Ill get rid of delay and do something more elegant, but for proof of concept that I could provide suitable pulses to operate the solenoid delay seemed fine for such a simple program...but maybe it's also causing some problem I didnt anticipate?

Thanks in advance for any input!

#define relay1 5 
#define relay2 6 
#define pulseRelay 10
#define button 2


boolean latched = false;

int value;

void setup() {
  // put your setup code here, to run once:
  pinMode(relay1, OUTPUT);
  pinMode(relay2, OUTPUT);
  pinMode(pulseRelay, OUTPUT);
  pinMode(button, INPUT_PULLUP);
  digitalWrite(pulseRelay, LOW);
  delay(30);
  digitalWrite(relay1, HIGH); //Again - the real circuit uses 2 SPST programmed to recieve opposite signals
  delay(30);                   // to reverse polarity. These two only see power when the "pulseRelay" is HIGH
  digitalWrite(relay2, LOW);
  delay(30);

  debouncer.attach(button);
  debouncer.interval(5); // interval in ms

 Serial.begin(9600);

}

void loop() {
 
  shutterToggle(latched);
  delay(5000);
  latched = !latched;
  Serial.println(latched);
  
}
void shutterToggle(boolean state){
  if ( !state ){ //latched - i.e. shutter open
  digitalWrite(LED_BUILTIN, HIGH);
  digitalWrite(relay1, HIGH);
  delay(20);
  digitalWrite(relay2, LOW);
  delay(20);
  digitalWrite(pulseRelay, HIGH);
  delay(110);
  digitalWrite(pulseRelay, LOW);

 }else if ( state ){ // not latched / shutter closed
  digitalWrite(LED_BUILTIN, LOW);
  digitalWrite(relay1, LOW);
  delay(20); 
  digitalWrite(relay2, HIGH);
  delay(20);
  digitalWrite(pulseRelay, HIGH);
  delay(900);
  digitalWrite(pulseRelay, LOW);
 }  
}

Shouldn't this delay be <=100ms?

 digitalWrite(pulseRelay, HIGH);
 delay(900);
 digitalWrite(pulseRelay, LOW)

On the data sheet it lists 100ms for ON pulse and 900ms for OFF so I think that should be correct unless it related to polarity during an ON vs OFF...but the datasheet doesn't seem to indicate any preferred directionality - only the timing difference and that the polarity should be reversed.

Why dont you use an optocoupler ? For example use a TLP521-1 and connect anode to arduino cathode to gnd. Then connect the emitter to the 12 V collector to the + lead of solenoid. And connect - lead of the solenoid to gnd. And its done. Why use relay while you have much faster ways.

On the data sheet it lists 100ms for ON pulse and 900ms for OFF

Agreed, that's what you want to do but that is not what the program is doing.

Look at the delay again. You're turning the "pulseRelay" ON for 900ms in the "else if(!state)" block.

This second block should just be an "else" rather than testing again. It's a boolean, it's either true or false. Testing both cases is a poor practice.

You're possibly overheating the coil and causing it to bind. Just remember the 900ms off time is furnished by the 5000ms delay in the main loop. When writing tests, I would put any necessary delays all in one place for clarity.

Try this code for the subroutine.

void shutterToggle(boolean state) {
  if ( !state )
  { //latched - i.e. shutter open
    digitalWrite(LED_BUILTIN, HIGH);
    digitalWrite(relay1, HIGH);
    digitalWrite(relay2, LOW);
    delay(20);
    digitalWrite(pulseRelay, HIGH);
    delay(100);
    digitalWrite(pulseRelay, LOW);
    delay(900);
  }
  else { // not latched / shutter closed
    digitalWrite(LED_BUILTIN, LOW);
    digitalWrite(relay1, LOW);
    digitalWrite(relay2, HIGH);
    delay(20);
    digitalWrite(pulseRelay, HIGH);
    delay(100);
    digitalWrite(pulseRelay, LOW);
    delay(900);
  }
}

Hi,
Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Your fritzy does not label any of the relay pins or show how you are controlling the yellow relay.
We need to see how you have the solenoid connected to the relay, not what it looks like on proto board.

Thanks.. Tom.. :slight_smile:

Ahh I didn't catch that...was writing something with state machines last week and guess I used else if as a force of habit! Ill give your code a try and see what happens!

Tom - sorry about the image, the low res dropped the diagram drawn on the top of the relays. However - I'm pretty confident the relays are wired properly to deliver reversible polarity (not necessarily to protect from kickback though, if that's necessary here) . As far as the solenoid connection - 1 leg of the solenoid connects to common of relay one, the other to common of relay two. NO relay 1&2 = V+, NC relay 1&2 = V-. Relay 3 common connected to V+ straight off supply, NO connected to NO of relay 1 & 2 (if that's too annoying to read Ill post a better schematic tomorrow (if avr_fred's coding suggestions haven't solved the problem already).

Nurimo - Availability mostly. I needed to try to get this going quickly and SPST relays were what I had on hand, and I've used them a lot more than optocouplers. I generally know what an optocoupler does and how it works, but not how to pick an appropriate one - plus the relays are plenty fast for this application.

Ok - these code changes did the trick! Looking at the datasheet again I see where I went wrong - I didn't read the 100 ON 900 OFF as a duty cycle for both on and off pulses. Rather, I had interpreted that to mean an ON pulse translated to voltage applied for 100ms then off (for no critical time) and an off pulse to be reversed polarity applied for 900ms then off. Any pulses duty cycle being 100 on 900 off makes perfect sense now, and seems to be working 100% as expected.

Thanks everyone!!