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.
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?
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
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);
}
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.
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.
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.
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...
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);
}
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.
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 :-
loop until the LDR reading goes above the threshold.
Set a time for how long you want it to be this before the opening using openTime = millsi() + myDelay;
If the LDR drops below this then reset openTime.
when openTime exceeds the current time given by millis(); fire the relay.