#4 제작 - 릴레이 멈춤 현상, RC스너버
이번에도 아두이노 Nano 보드를 사용하기로 했다.
DS1302 RTC 모듈로 현재 시각을 알아내어 SSD1306 디스플레이에 초 단위로 표시한다.
정해진 시간이 되면 릴레이를 통해 솔레노이드 밸브를 열고, 일정 시간이 지나면 밸브를 닫는다.
3 state 토글 스위치를 달아서 1. 항상 밸브 열기, 2. 항상 밸브 닫기, 3. 프로그래밍된 스케쥴대로 열고 닫기 의 3가지 옵션중 하나를 선택할 수 있도록 한다.
물이 많은 환경에서 사용되는 제품이므로 전기 합선을 막기 위해 어느 정도는 방수가 되도록 케이스를 제작한다.
악세사리 담는 플라스틱 반투명 보관함을 구입해 케이스로 개조했다. 밀폐되는게 아니라서 완전 방수는 안 되지만, 베란다에 놓고 사용하는 중에 물이 튀는 정도는 견딜 수 있을 거 같다. 솔레노이드 밸브에 연결되는 +극과 -극 선은 글루건으로 밀봉해 완전 방수가 되도록 할 생각이다.
아래와 같이 코딩하여 아두이노 IDE 를 통해 업로드했다.
#include <virtuabotixRTC.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 32
#define OLED_RESET -1
#define SCREEN_ADDRESS 0x3C // 0x3D for 128x64, 0x3C for 128x32
virtuabotixRTC myRTC(2,3,4);
String dayofweek;
String ctime;
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
int valvePin = 5;
int switch1Pin = 6;
int switch2Pin = 7;
int switch1Value;
int switch2Value;
void setup() {
Serial.begin(9600);
//myRTC.setDS1302Time(0, 36, 14, 1, 7, 1, 2024);
while(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS) && millis()<5000) {
}
display.display();
digitalWrite(valvePin, HIGH);
pinMode(valvePin, OUTPUT);
pinMode(switch1Pin, INPUT_PULLUP);
pinMode(switch2Pin, INPUT_PULLUP);
}
void loop() {
myRTC.updateTime();
ctime = String(myRTC.year) + "/" + String(myRTC.month) + "/" + String(myRTC.dayofmonth) + "\n";
ctime += String(myRTC.hours) + ":" + String(myRTC.minutes) + ":" + String(myRTC.seconds);
//Serial.println(ctime);
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println(ctime);
display.display();
isDelay = false;
switch1Value = digitalRead(switch1Pin);
switch2Value = digitalRead(switch2Pin);
if ( (switch1Value == 1) && (switch2Value == 1) ) {
if (digitalRead(valvePin) == LOW) {
Serial.println("Manual Stop");
digitalWrite(valvePin, HIGH);
delay(200);
isDelay = true;
}
}
else if ( (switch1Value == 1) && (switch2Value == 0) ) {
if (digitalRead(valvePin) == HIGH) {
Serial.println("Manual Start");
digitalWrite(valvePin, LOW);
delay(200);
isDelay = true;
}
}
else if ( (switch1Value == 0) && (switch2Value == 1) ) {
//Serial.println("Schedule");
if ( (myRTC.seconds % 10) == 0) {
if (digitalRead(valvePin) == HIGH) {
Serial.println("Start");
digitalWrite(valvePin, LOW);
delay(200);
isDelay = true;
}
}
else if ( (myRTC.seconds % 10) == 3) {
if (digitalRead(valvePin) == LOW) {
Serial.println("Stop");
digitalWrite(valvePin, HIGH);
delay(200);
isDelay = true;
}
}
}
if (isDelay == true) {
delay(800);
}
else {
delay(1000);
}
}
디스플레이에 현재 시각을 매초마다 표현해줘야 하므로, loop() 함수는 1초마다 반복 실행되는 것으로 구성했다.
3 state 토글 스위치가 세 번째 위치(3. 프로그래밍된 스케쥴대로 열고 닫기)일 때는, 현재 시각의 초 마지막이 0일 때마다 솔레노이드 밸브를 열고 3일 때마다 밸브를 닫는다.
잘 작동하는 듯 했으나, 몇 분이 지나면 아두이노가 멈춰버리는 문제가 계속 반복됐다. 보통 릴레이에 HIGH 나 LOW 신호가 들어가는 순간에 멈추면서 디스플레이에 표시되던 시계가 멈추고 릴레이 하단의 붉은 색 led 도 꺼져버렸다. 가끔은 시계가 리셋되기도 했다.
다른 Nano 보드로 변경해봐도 마찬가지여서 UNO 보드로도 테스트를 해 봤는데, 역시나 동일한 문제가 발생했다. 특정 모듈이나 프로그램 코드 상의 문제인가 싶어 릴레이를 제외한 다른 모듈을 모두 제거하고 코드 상에서도 지워보니 문제가 없었다. 그래서 다시 하나씩 모듈을 복원해가며 테스트를 해 봤는데, 다른 모듈이 하나라도 함께 사용되면 릴레이 모듈에서 문제가 발생한다는 것을 발견했다.
일단 전류 용량 부족으로 의심하고 릴레이 모듈의 전원을 다른 모듈과 분리해봤다. UNO 보드는 5V 핀이 2개라서 RTC 모듈과 디스플레이 모듈은 하나의 5V 핀을 공유하고, 릴레이 모듈은 남은 5V 핀을 혼자 사용하도록 할 수 있었다. 테스트를 해보니 더 이상 문제가 반복되지 않았다.
하지만 UNO 와 달리 Nano 는 5V 핀이 하나 뿐이라서 위의 방법을 사용할 수가 없다. 다른 아두이노 보드를 사용해야 하는가 싶어 인터넷을 검색해봤는데, 아두이노 보드의 VIN 핀에서도 5V 가 출력이 된다는 걸 알게됐다. 원래는 아두이노 보드에 전기를 공급하기 위한 input 핀인데, output 으로도 사용이 가능하다고 한다. 나는 Nano 보드에 USB C 타입 케이블로만 전기를 공급할 거라서 VIN 핀을 입력용으로 사용할 일이 없으므로 릴레이용 전원으로 VIN 핀을 사용하기로 했다.
아래와 같이 릴레이 모듈의 VCC 를 Nano 보드의 GND 핀 바로 옆에 있는 VIN 핀에 단독으로 연결했다. 실행해보니 전보다는 오래 버텼지만 결국 2~3분 후에는 동일하게 멈추는 현상이 재현됐다.
다시 인터넷을 검색하다보니 역전류에 대한 정보를 얻을 수 있었다. 릴레이와 같이 전기 소모가 많은 장치는 전원을 껏다 켜는 과정에서 순간적으로 역전류가 발생할 수 있는데, 이게 아두이노 Nano 보드로 흘러가면서 이상작동을 하게 되는 거 같다. 심한 경우는 보드가 망가질 수도 있다고 하고, 내 경우에는 아두이노 Nano 보드는 괜찮았지만 RTC 모듈이 리셋되는 바람에 현재시각 설정을 다시 한 적이 몇 번 있었다.
이러한 역전류를 막기 위해 RC스너버 라는 부품을 사용한다고 한다.

릴레이에서 사용중인 COM 과 NO 포트에서 전선을 하나씩 빼서 RC스너버의 연결 포트에 각각 연결했다. 이 연결 포트는 +- 같은 방향성은 없기 때문에 릴레이의 COM 에서 나온 전선을 RC스너버의 연결 포트 둘 중 아무 곳에나 연결한 후, NC 에서 나온 전선을 남은 연결 포트 한 곳에 연결하면 된다.
이렇게 연결해 놓고 테스트하니 비로소 멈춤 현상 없이 잘 작동하는 것을 확인할 수 있었다.