ETT :: Article :: >ESP8266/ESP32 :: ET-ESP8266-RS485 ตอนที่ 3 สั่งงานรีเลย์ผ่านเว็บ

© 2022,จารุต บุศราทิจ, กอบกิจ เติมผาติ
ปรับปรุงเมื่อ 2022-06-22

บทความนี้กล่าวถึงการใช้งานเครือข่ายไร้สายเพื่อให้โมดูล esp8266 เป็นผู้ให้บริการเว็บไซต์เพื่อให้ผู้เข้าใช้งานมองเห็นสถานะของรีเลย์ พร้อมทั้งสั่งเปิดหรือปิดรีเลย์บนบอร์ดดังภาพที่ 1 ด้วยภาษาไพธอนผ่านทาง MicroPython ที่ติดตั้งไว้บยบอร์ด ET-ESP8266-RS485


ภาพที่ 1 ภาค Relay บนบอร์ด ET-ESP8266-RS485

เป้าหมาย

อุปกรณ์ที่ต้องใช้

การใช้งานรีเลย์

บนบอร์ด ET-ESP8266 RS485 มีการเชื่อมต่อกับรีเลย์ตามผังวงจรในภาพที่ 2 โดยรีเลย์รองรับกระแสสูงสุด 10A ผ่านทางพอร์ต IO15 และการเปิดให้ส่งสัญญาณดิจิทัล HIGH และการปิดกระทำด้วยการส่ง LOW ส่วนตัวอย่างการต่อเป็นดังภาพที่ 3


ภาพที่ 2 วงจรของรีเลย์


ภาพที่ 3 ตัวอย่างการต่อ

หมายเหตุ :: การใช้งานรีเลย์ต้องต่อแหล่งจ่ายไฟเพิ่มเติมเพื่อขับรีเลย์ด้วยเสมอ

ตัวอย่างการสั่งงานเปิด/ปิดรีเลย์เป็นดังนี้


    from machine import Pin
    import time
    relay = Pin(15, Pin.OUT)
    relay.value(1)
    time.sleep_ms(2000)
    relay.value(0)    

คลาส Network

จากxบทความก่อนหน้านี้ได้เชื่อมต่อ esp8266 เข้ากับเครือข่ายไร้สายภายในบ้านโดยใช้ตัวเองเป็นโหนดหนึ่งของเครือข่าย ส่วนในบทความนี้มีความแตกต่างกันตรงที่เลือกใช้การทำงานในโหมดเป็นผู้ให้บริการเครือข่ายไร้สายหรือ Access Point (AP) Mode ที่ต้องเชื่อมต่อเพื่อเข้ามาเพื่อเข้าใช้ ซึ่งหมายเลข IP ของโมดูล esp8266 คือ

        
            192.168.4.1  
        
    

ตัวอย่างโปรแกรมเบื้องต้นสำหรับการให้โมดูลทำงานในโหมด AP เป็นดังนี้

        
        import network
        import time

        ssid = 'ETT8266_AP'
        password = '123456789'

        if_ap = network.WLAN(network.AP_IF)
        if (if_ap.active() == False):
            if_ap.active(True)
            if_ap.config(ssid, password)
            while not if_ap.active():
                time.sleep(0.3)
                print(".")
        print("network configuration:\n{}".format(if_ap.ifconfig()))
        if_ap.active(False)
        
    

ผลลัพธ์ของการทำงานเป็นดังนี้

        
            network configuration:
            ('192.168.4.1', '255.255.255.0', '192.168.4.1', '208.67.222.222')            
        
    

ดังนั้น เมื่อใช้โทรศัพท์เชื่อมต่อเข้า AP ชื่อ ETT8266_AP ด้วยรหัสผ่าน 123456789 จะได้หมายเลข IP จากโมดูล esp8266 ที่ทำหน้าที่แจกจ่าย IP Address ให้โหลดลูกข่าย โดยตัวโมดูลมีหมายเลขเป็น 192.168.4.1 มี sub netmask เป็น 255.255.255.0

แต่อย่างไรก็ดี จากตัวอย่างนั้นเป็นเพียงการเปิดโหมดทำงานเป็น AP พร้อมกำหนดค่า SSID และ PASSWORD สำหรับใช้ในการเข้าถึงโมดูล

ขั้นตอนการเขียนโปรแกรมในโหมด AP เป็นดังนี้

ตัวอย่างโค้ดที่ทำงานตามขั้นตอนทั้ง 8 เป็นดังนี้

        
            import socket
            import network
            
            ssid = 'ETT8266_AP'
            password = '123456789'
            
            if_ap = network.WLAN(network.AP_IF)
            if (if_ap.active() == True):
                if_ap.active(False)    
            
            if_ap.active(True)
            if_ap.config(essid=ssid, password=password)
            
            while if_ap.active() == False:
                time.sleep(0.3)
                print(".")
            
            def web_page():
                html = """
                    < html >< head >< meta name="viewport"
                    content="width=device-width, initial-scale=1" >
                    < body > < h1 >ETT< /h1 >
                  """
                return html
            
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            s.bind(('', 80))
            s.listen(2)
            
            while True:
                conn, addr = s.accept()
                print('conn {} from {}'.format(conn, addr))
                request = conn.recv(1024)
                print('request = {}'.format(request))
                response = web_page()
                conn.send('HTTP/1.1 200 OK\n')
                conn.send('Content-Type: text/html\n')
                conn.send('Connection: close\n\n')
                conn.send(response)
                conn.close()
                       
        
    

และได้ตัวอย่างของผลลัพธ์เป็นดังนี้ โดยจากผลลัพธ์จะพบว่ามีการร้องขอจาก IP หมายเลข 192.168.4.2 ได้ทำการร้องขอมาผ่านทาง WebKit ด้วย Chrome (ผู้เขียนใช้บอร์ด Raspberry Pi 4)

        
            conn  from ('192.168.4.2', 39423)
                request = b'GET / HTTP/1.1\r\nHost: 192.168.4.1\r\nConnection: 
                keep-alive\r\nX-Chrome-offline: persist=0 reason=error\r\nDNT: 
                1\r\nUpgrade-Insecure-Requests: 1\r\nUser-Agent: Mozilla/5.0 (Linux; 
                Android 8.1.0; vivo 1724) AppleWebKit/537.36 (KHTML, like Gecko) 
                Chrome/102.0.0.0 Mobile Safari/537.36\r\nAccept: text/html,application/
                xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;
                q=0.8,application/signed-exchange;v=b3;q=0.9\r\nAccept-Encoding: gzip,
                deflate\r\nAccept-Language: en-US,en;q=0.9,th;q=0.8\r\n\r\n'                       
        
    

หน้าจอของการเชื่อมต่อจากโทรศัพท์มือถือเป็นดังภาพที่ 4, 5 และตัวอย่างการทำงานดังภาพที่ 6


ภาพที่ 4 ชื่อ AP ที่สร้างขึ้น


ภาพที่ 5 ส่วนของการใส่รหัสผ่านสำหรับ AP


ภาพที่ 6 ตัวอย่างหน้าเว็บที่ได้

ตัวอย่างการเปิดปิดรีเลย์ผ่านเว็บ

ตัวอย่างโปรแกรมต่อไปนี้เป็นการปรับปรุงจากการแสดงผลหน้าเว็บ โดยเปิดช่องทางให้ผู้ใช้งานได้ตอบสนองกับหน้าเว็บผ่านทางปุ่ม (button) สำหรับกดเปิด (On) หรือ ปิด (Off) รีเลย์

เพื่อให้โปรแกรมสามารถตรวจสอบค่านำเข้าได้จึงออกแบบให้การกดปุ่มหนึ่งให้เรียก /?relay=On กับ /?relay=Off เพื่อนำมาเป็น URL สำหรับเรียกตัวเอง ด้วยเหตุนี้ เมื่อค้นแล้วพบข้อความทั้ง 2 จึงสามารถใช้เป็นเงื่อนไขประกอบการสั่งเปิดหรือปิดรีเลย์ แต่ ผู้เขียนโปรแกรมจะต้องแปลงข้อมูลที่ส่งมาให้เป็นข้อความด้วย str(conn.recv(1024))

การตรวจสอบว่าพบหรือไม่ใช้คำสั่ง find() และถ้าผลลัพธ์ตอบกลับมาเป็นค่า 6 แสดงว่าพบคำที่ค้นหา

จากหลักการทั้งหมดสามารถเขียนเป็นโค้ดโปรแกรมได้ดังนี้


    import socket
    import network
    from machine import Pin
    
    ssid = 'ETT8266_AP'
    password = '123456789'
    
    relay = Pin(15, Pin.OUT)
    
    if_ap = network.WLAN(network.AP_IF)
    if (if_ap.active() == True):
        if_ap.active(False) 

        if_ap.active(True)
        if_ap.config(essid=ssid, password=password)
        
        while if_ap.active() == False:
            time.sleep(0.3)
            print(".")
        
        def web_page():
            html = """
                < html>< head>< meta name="viewport"
                content="width=device-width, initial-scale=1">
                < body>< h1>ETT
              """
            html += "< a href='/?relay=on '>< button>ON";
            html += "< a href='/?relay=off '>< button>OFF";
            html += ""
            return html
        
        def do_on():
            relay.value(1)
        
        def do_off():
            relay.value(0)
        
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.bind(('', 80))
        s.listen(2)
        while True:
            conn, addr = s.accept()
            request = str(conn.recv(1024))

    relayOn = request.find("/?relay=on")
    relayOff = request.find("/?relay=off")
    if (relayOn==6):
        do_on()
    if (relayOff==6):
        do_off()

    response = web_page()
    conn.send('HTTP/1.1 200 OK\n')
    conn.send('Content-Type: text/html\n')
    conn.send('Connection: close\n\n')
    conn.send(response)
    conn.close()

ตัวอย่างหน้าจอเป็นดังภาพที่ 7


หน้าจอจากตัวอย่างโปรแกรมในบทความนี้

สรุป

จากบทความนี้จะพบว่าการใช้งานแบบ IoT เพื่อให้สามารถสั่งงานอุปกรณ์ผ่านทางเครือข่ายอินเทอร์เน็ตด้วยภาษาไพธอนนั้นมีหลักการหลัก ๆ คือ เปิดเข้าเชื่อมต่อเครือข่าย เปิดช่องสื่อสารผ่านทางพอร์ตหมายเลข 80 ออกแบบการสั่งงานด้วยชื่อ URL (เช่นในบทความนี้ใช้ /?relay=On และ /?relay=Off) การแปลงข้อมูลการร้องขอเป็นข้อความ การตรวจสอบเงื่อนไขที่ต้องการในข้อความ การตรวจสอบความตรงกันของข้อความที่ต้องการตรวจสอบ และการสั่งงานอุปกรณ์

หลังจากนี้ผู้อ่านจะสามารถนำไปประยุกต์เพื่อสั่งงาน และเมื่อนำตัวอย่างก่อนหน้านี้จะสามารถเพิ่มเติมเงื่อนไขของการตรวจสอบเวลาการเปิดหรือปิดรีเลย์ได้อีกด้วย สุดท้าย ขอให้สนุกกับการเขียนโปรแกรมและนำหลักการ IoT ไปประยุกต์ใช้กับวงจรอื่น ๆ ต่อไป เช่น เซ็นเซอร์อุณหภูมิ ความชื้น การส่องสว่าง เป็นต้น

ตอนที่ 1 :: ตอนที่ 2 :: ตอนที่ 3

--ไม่สามารถเข้าถึงฐานข้อมูลได้--