I hit the post button too early, here's the full post as it was meant:
Hello,
I try to give you the relevant infos on my project, if there's anything missing let me know.
General idea
I have a standalone atmega328p circuit and a relay (like this). The relay is connected to a 7 W ikea lamp. The atmega and the relay are connected via ULN2803a chip.
The general idea is to turn the lamp on and off via motion sensor and a light detection module. Basically everything is working so far.
Problems
Atmega+Relay+Motion Sensor+Lamp were running for about half a year and said setup. Occasionally the relay would turn on for a fraction of a second, and turn off again. The atmega reset apparently and afterwards the relay would stay on. This was my first atmega standalone circuit I ever build, so probably not the best soldering job I figured.
Now I wanted to add other functionality like the light module, a button to turn the lamp off when it's on, ... Upon reassembly the relay would rarely stay on. I switched the atmega circuit for some other circuit from an older project I didn't need anymore, same behaviour. After some headscratching I found out, that if I don't plug in the lamp, everything works.
Nothing had changed, except I redid the wiring (old project was a mess) and screwed / glued the circuits on a wooden plate.
Solution(s) / Further Info
Since I recently got a cheap china oscilloscope, I thought it might be fun to hook it up, and see if I might be able to see something. See the attached pictures. Relay on and off are without the power plug from the lamp beeing plugged in. Reset 1 and 2 are just 2 instances if me trying to capture what happens when the relays turns off again. One time it did turn off, but I got nothing on screen. Looks like there's an AC power surge that freezes the arduino.
The relay has JD-VCC and VCC jumpered. There is, just like in the picture, no additional GND. I assume for complete isolation I should find another 5V power supply. I still need to some reading on why this would be necessary as obviously the mains (lamp) side is isolated from the low voltage atmega side of the relay). I'm 90 % positive this could fix my problem.
I didn't place any caps on the VCC pins for the atmega on neither circuit. I didn't know better then.
I also added a simplyfied version of what the powerline for the atmega / relay look like and how they are hooked up. And I tried to add the recent additions the schematic I drew back then. It's probably really messy.
Questions
- How would I connect the second power supply? VCC to VCC of the formerly jumpered VCC Pin? Common GND with the atmega circuit then?
- Any other ideas that would maybe save me from using second power supply. 2 PSUs are quite costly for a single, simple project like that. I have enough lying around, but still. Maybe some solution with a diode to prevent current flow to the arduino?
- 7 W does not seem to be a lot of load, from what I read extra protection is needed when dealing with heavier loads.
Or should I always use a 2nd PSU? - Is there something else I could/should have tried to measure for further problem identification?
edit: Here's the code. I know there is a bug in the portion for the button to turn off the lamp, the state doesn't get saved. I can fix that myself. And there are some obsolete parts in the code (I originally planned to consider sunset / sunrise times), anyway:
int relayp1 = 6; // Relay Pin 1
int relayp2 = 5; // Relay Pin 2
int IRmotionPin = 3; // Input from Motion Sensor
int LED = 13; // LED
const byte LightSensor = 7;
byte turnOffLightState = 0;
int Light = 0;
int var = 0;
int value; // value (HIGH or LOW) of the motion sensor
#include <avr/wdt.h> // include watchdog timer
#include <DS3231.h>
DS3231 rtc(SDA, SCL);
void setup() {
//Serial.begin(9600);
wdt_enable(WDTO_8S); // If the system hangs for more than 8s, the system should reboot
wdt_reset();
// set all the pin modes
pinMode(relayp1, OUTPUT);
pinMode(relayp2, OUTPUT);
pinMode(LED, OUTPUT);
pinMode(IRmotionPin, INPUT);
pinMode(LightSensor, INPUT);
rtc.begin();
// set all the pins to initial conditions
digitalWrite(relayp1, LOW);
digitalWrite(relayp2, LOW);
digitalWrite(LED, HIGH);
delay(2000);
digitalWrite(LED, LOW);
attachInterrupt(digitalPinToInterrupt(2), turnOffLight, RISING);
wdt_reset();
}
void loop() {
wdt_reset();
if (turnOffLightState == 1) {
for (int i = 0; i <= 30; i++) {
delay(1000);
wdt_reset(); // reset the watchdog timer
}
turnOffLightState = 0;
}
value = digitalRead(IRmotionPin); // get the state of the sensor
if (value == 1 && digitalRead(LightSensor) == 1) // motion detected
{
int stayON = 1;
digitalWrite(relayp1, HIGH); // turn on the lamp
digitalWrite(relayp2, HIGH); // turn on the lamp
while (stayON == 1) {
for (int i = 0; i <= 120; i++) { // lamp should stay on for 2 minutes
delay(1000);
wdt_reset(); // reset the watchdog timer
}
if (digitalRead(IRmotionPin) == 1) {
stayON = 1;
}
else {
stayON = 0;
}
}
digitalWrite(relayp1, LOW);
digitalWrite(relayp2, LOW);
stayON = 0;
wdt_reset();
}
else
{
wdt_reset(); // if the reading is LOW, do nothing, BUT reset the watchdog timer
}
}
void turnOffLight() {
turnOffLightState = 1;
digitalWrite(relayp1, LOW);
digitalWrite(relayp2, LOW);
}
Thanks in advance!