개발 블로그
  • [Arduino | Linux] HTML/Javascript에서 릴레이 모듈 전원 제어하기
    2025년 04월 07일 23시 07분 27초에 업로드 된 글입니다.
    작성자: 이주여이

    1. ino

    #include <WiFi.h>
    #include <PubSubClient.h>
    #include <ArduinoJson.h>
    #include <NTPClient.h>
    #include "include/wifi.h"
    #include "include/mqtt.h"
    
    WiFiUDP      ntpUDP;
    
    unsigned long lastTime             = 0;
    const long interval                = 5000;
    const char* relayOnTopic           = "/relay/on";
    const char* relayOffTopic          = "/relay/off";
    int relayPin                       = 26;
    
    void setup() {
        Serial.begin(115200);
    
        setupWifi();
        setupMqtt();
    
        client.setServer(MQTT_SERVER, 1883);
        client.setCallback(callback);
    
        while(!client.connected()) {
            if(client.connect("ESP32Client")) {
                Serial.println("ESP32 연결 성공");
    
                client.subscribe(relayOnTopic);
                client.subscribe(relayOffTopic);
    
                Serial.println("mqtt 토픽 발행 성공");
            } else {
                Serial.println("ESP32 연결 실패");
                Serial.println("mqtt 토픽 발행 실패");
    
                delay(2000);
            }
        }
    
        timeClient.begin();
    
        pinMode(relayPin, OUTPUT);
        digitalWrite(relayPin, HIGH);
    }
    
    void callback(char* topic, byte* payload, unsigned int length) {
        String message = "";
    
        Serial.print("topic = ");
        Serial.println(topic);
    
        for (unsigned int i = 0; i < length; i++) {
            message += (char)payload[i];
        }
    
        Serial.print("message = ");
        Serial.println(message);
    
         if(strcmp(topic, relayOnTopic) == 0) {
             digitalWrite(relayPin, LOW);
         } else if(strcmp(topic, relayOffTopic) == 0) {
             digitalWrite(relayPin, HIGH);
         }
    }
    
    void loop() {
        // ... 관련없는 코드이므로 생략
    }
    
    void reconnectSetup() {
        while(!client.connected()) {
            if(client.connect("ESP32Client")) {
                Serial.println("mqtt 연결 성공");
            } else {
                Serial.println("mqtt 연결 실패 & 5초 후 재시도");
    
                delay(5000);
            }
        }
    }

    2. HTML

    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{fragments/layout-admin}" layout:fragment="body">
    <body>
        <section>
            <div id="control-wrap" style="display: block">
                <p class=l>Relay Module OFF</p>
                    <div class="round">
                    <input type=checkbox id="relay-module" name="relay-module" />
                    <div class="back">
                        <label class=but for="relay-module">
                            <span class="on">I</span>
                            <span class="off">0</span>
                        </label>
                    </div>
                </div>
                <p class=r>Relay Module ON</p>
            </div>
        </section>
    </body>
    
    <script src="https://cdn.jsdelivr.net/npm/mqtt@4.3.7/dist/mqtt.min.js"></script>
    <script th:src="@{/js/admin_relay_test.js}"></script>
    </html>

    3. Javascript

    let client;
    const brokerUrl     = '';
    const relayOnTopic  = '/relay/on';
    const relayOffTopic = '/relay/off';
    
    $(document).ready(() => {
        client = mqtt.connect(brokerUrl);
    
        client.on('connect', () => {
            console.log('mqtt 연결 성공');
        });
    
        $('#relay-module').change(function() {
            if($(this).is(':checked')) {
                client.publish(relayOnTopic, 'ON');
            } else {
                client.publish(relayOffTopic, 'OFF');
            }
        });
    });

     

     

     

    버튼 클릭할 때 마다 모니터링 화면에 토픽이랑 메세지가 표출되고 해당 토픽에 따라 릴레이 모듈을 제어한다.

     

    참고로 스위치 CSS는 여기서 가져왔다.

     

     

    Toggle switch with checkbox:checked

    Round switch button in css with animation cleaned up. Inspired on the design of Paul Flavius, see: http://psd.tutsplus.com/tutorials/interface-tutoria...

    codepen.io

    댓글