Latching/Bistable 12v relay controlling

Hi guys, been working on a little project for a couple of weeks now, essentially, a solar powered chicken coop door opener.

I was using a standard DPDT relay for this, and it was going mostly fine, but then I began to think about the power required to keep the relay in its open position and decided to swap it out for a latching relay instead.

Here is the datasheet for my relay: http://www.datasheetarchive.com/RSBL-12-S*-datasheet.html (second one down)

It has 2 coils, not the standard 1, and i'm trying to get this working with my arduino standalone board (on the same breadboard) and it's just not working. I originally had the relay wired up as shown here: Arduino Playground - HomePage which worked fine, however, after adding in the new relay, I simply added in another transistor/diode module for controlling the other coil, but it's not clicking in either direction, what am I doing wrong?

Many thanks!

Here's my code, the digitalWrite(LEDpin) parts are probably wrong, since I haven't been able to test it out yet.

Tell me what you guys think :slight_smile:

int LDR_pin = 0; // analog pin 0 (connect LDR here)

int LDR_val = 0; //initial LDR value

int LEDpin = 13; //This is the relays coil 1

int LEDpin2 = 12; //This is the relay

int counterclose = 0; //counter for closing validation

int counteropen = 0; //counter for opening validation

int Delay1 = 2;

int Delay2 = 2;

int TestEnablePin = 4; //connected to switch saying if the test mode is enabled, if yes, delay is much shorter
int TestEnable = 0; 


int threshold = 200; // a threshold to decide when the relay turns on



void setup(){



  // declaration of pin modes

  pinMode(LDR_pin, INPUT);

  pinMode(LEDpin, OUTPUT); 
  
  pinMode(LEDpin2, OUTPUT);

  pinMode(TestEnablePin, INPUT);


  // begin sending over serial port

  Serial.begin(9600);

}



void loop(){
  TestEnable = digitalRead(TestEnablePin);

  // read the value on analog input

  LDR_val = analogRead(LDR_pin);

  if (TestEnable == HIGH)
  { 
    Delay1 = 2;
    Delay2 = 2; 
  }
  else
  { 
    Delay1 = 1200;
    Delay2 = 1200; 
  }


  // if value greater than threshold turn on LED

  if (LDR_val < threshold) counterclose = counterclose+1;
  else counterclose = 0;

  if (counterclose > (Delay1))//set delay here, 1 loop = 1 second
    digitalWrite(LEDpin2, HIGH);
    delay(100);
    digitalWrite(LEDpin2, LOW);


  if (LDR_val > threshold) counteropen = counteropen+1;
  else counteropen = 0;

  if (counteropen > (Delay2))//set delay here, 1 loop = 1 second
    digitalWrite(LEDpin, HIGH);
    delay(100);
    digitalWrite(LEDpin, LOW);





  // output 'LDR_val' value into the console

  Serial.print("LDR = ");
  Serial.print(LDR_val);


  Serial.print(" Counter close = ");
  Serial.print(counterclose);

  Serial.print(" Counter open = ");
  Serial.print(counteropen);

  Serial.print(" testpin = ");
  Serial.print(TestEnable);

  Serial.print(" Delay1 = ");
  Serial.print(Delay1);

  delay(1000);




}
  if (counteropen > (Delay2))//set delay here, 1 loop = 1 second
    digitalWrite(LEDpin, HIGH);
    delay(100);
    digitalWrite(LEDpin, LOW);

This probably doesn't do what you think, add {} around the three lines that I guess are supposed to be inside the if(). Same on the next if().

delay (100) is 10th of a second.

Are the two pins driving transistors?


Rob

Yep, the 2 pins are connected to transistors. I wasn't actually using this code, I'm using the blink example at the moment, as in set pin 13 high, wait 1 second, set pin 13 low, wait 1 second, set pin 12 high, wait, set pin 12 low, etc, but i still can't get it to click.

I've attached an image below of how i'm connecting the relay up.

Where are you getting the 12 volts for your RSBL-12-S relay?

At the moment, that sketch isn't strictly true, the rails going around are +5v and ground respectively, as these go from a regulator as the power supply for the atmega328 chip which is on the same breadboard. The power for the relay is being provided by a 9v battery (definately clicks the relay, also works with other 12v relays), and i have ground from the right leg of the transistor going to 9v ground, and arduino ground.

SOLVED!!

Turns out, the transistors were duff. Whoops :cold_sweat:

Ok, now the relay's-a-tickin' what do I need to do to the code to make it only set pins 12 or 13 to high if they are not already?

The way it is at the moment, it detects light, once the counter fills up, clicks the relay, then keeps counting, and for every loop it goes around continues pulsing the relay. I just want it to click itself on, then stay like that, unless the LDR value drops back below the threshold again, in which case, it flips it.

Keep a status variable that tells you what state the relay is in, then test that before writing to the pin

if( should_set_relay() && relay_status != SET)
digitalWrite (setPin, HIGH)


Rob

Ok, so it's a boolean variable or a sting variable or doesn't it really matter?

I take it I can just set the variable to begin with, say set it closed to begin with, then have the variable shouldBe set to closed too, until counteropen becomes greater than delay2?

Where abouts in the code should these be? I'm a terrible coder, but getting there... slowly... :stuck_out_tongue:

Ok, had a crack at the code again, see what you guys think:

int LDR_pin = 0; // analog pin 0 (connect LDR here)

int LDR_val = 0; //initial LDR value

int LEDpin = 13; //This is the relays coil 1

int LEDpin2 = 12; //This is the relay coil 2

int counterclose = 0; //counter for closing validation

int counteropen = 0; //counter for opening validation

int Delay1 = 2;

int Delay2 = 2;

int TestEnablePin = 4; //connected to switch saying if the test mode is enabled, if yes, delay is much shorter
int TestEnable = 0; 

boolean relayState = false;
boolean relayShouldBe = false;


int threshold = 80; // a threshold to decide when the relay turns on



void setup(){



  // declaration of pin modes

  pinMode(LDR_pin, INPUT);

  pinMode(LEDpin, OUTPUT); 

  pinMode(LEDpin2, OUTPUT);

  pinMode(TestEnablePin, INPUT);


  // begin sending over serial port

  Serial.begin(9600);

}



void loop(){
  TestEnable = digitalRead(TestEnablePin);

  // read the value on analog input

  LDR_val = analogRead(LDR_pin);

  if (TestEnable == HIGH)
  { 
    Delay1 = 2;
    Delay2 = 2; 
  }
  else
  { 
    Delay1 = 1200;
    Delay2 = 1200; 
  }


  // if value greater than threshold turn on LED

  if (LDR_val < threshold) counterclose = counterclose+1;
  else counterclose = 0;

  if (counterclose > (Delay1)){
    relayShouldBe = false;
  }


  if (LDR_val > threshold) counteropen = counteropen+1;
  else counteropen = 0;

  if (counteropen > (Delay2)){//set delay here, 1 loop = 1 second
    relayShouldBe = true;
  }


  if (relayShouldBe == false && relayState == true){
    digitalWrite(LEDpin, HIGH);
    delay(100);
    digitalWrite(LEDpin, LOW);
  }

  if (relayShouldBe == true && relayState == false){
    digitalWrite(LEDpin2, HIGH);
    delay(100);
    digitalWrite(LEDpin2, LOW);
  }


  // output 'LDR_val' value into the console

  Serial.print("LDR = ");
  Serial.print(LDR_val);


  Serial.print(" Counter close = ");
  Serial.print(counterclose);

  Serial.print(" Counter open = ");
  Serial.print(counteropen);

  Serial.print(" testpin = ");
  Serial.print(TestEnable);

  Serial.print(" Delay1 = ");
  Serial.print(Delay1);

  delay(1000);




}

Turns out, the transistors were duff.

Did you kill them? There is no base resistors in that diagram.

that sketch isn't strictly true,

Then neither can our answers be.

Ok, had a crack at the code again, see what you guys think

So what does it actually do?

I had used the transistors previously without base resistors in a different circuit, I must have fried them then.

The sketch was just a simplified drawing of what I was trying to do (with a 390 ohm resistor to the base :P), you get the general idea, the transistors actually get their power from the same battery (about 10v) which powers the rest of the circuit, with the ground and +5v rails being connected to the arduino and anything else which requires 5 volts.

The code should monitor the LDR for its value, if it's above the threshold value which is preset in the code, it starts incrementing a counter (counteropen), which once that goes above a certain value (delay1) it clicks the relay on which should power the motor so it can open a chicken coop door. The same applies in reverse. The delay is both for validation and to make sure the chickens would definitely be inside the coop when it closes.

Make sense to you?

Any more questions, feel free to ask :slight_smile:

The sketch was just a simplified drawing of what I was trying to do

The problem is that in electronics a schematic is supposed to be what you are doing. How can we tell if you have missed something out in your implementation or just on the drawing.

That sounds fine but I would :-

  1. loop until the LDR reading goes above the threshold.
  2. Set a time for how long you want it to be this before the opening using openTime = millsi() + myDelay;
  3. If the LDR drops below this then reset openTime.
  4. when openTime exceeds the current time given by millis(); fire the relay.