【ESP32】microPython으로 스마트 락을 만들어 보았다

소개



연구실의 열쇠를 빌리러 가는 것이 귀찮아! 스마트 락을 원해!

기성품은 고가! (2만 정도)(시란지만)

그럼 만들자,

ESP-WROOM-32와 microPython으로 실험실의 열쇠를 스마트 락화시켜 본 이야기

왜 microPython?



사용하고 싶었기 때문에. 단지 그것뿐.

개요



소스 코드 & 3D 데이터



GitHub에 있습니다.

사양 및 요구 사항


  • 브라우저 (로컬)에서 잠금/잠금 해제
  • Slack에 열린/잠금 해제 알림을 게시
  • 키가 닫힐 때 LED가 켜짐
  • 물리 키로도 열고 잠글 수 있습니다
  • 내부에서 삼턴을 조작 할 수 있어야합니다

  • 준비하는 것


  • 마이크로 컴퓨터 ESP-WROOM-32
  • 서보 모터 SG-90 (샘턴이 단단한 경우 SG-92R을 권장합니다)
  • 브레드 보드
  • LED
  • 저항 (10kΩ)
  • AC 어댑터
  • (3D 프린터)
  • (Fusion360)
  • Wi-Fi

  • ESP32를 microPython 환경으로 만드는 방법은 MicroPython 문서 등을 참조하십시오.

    배선도





    삼턴을 돌리는 메커니즘



    물리키에서도 개정/시정할 수 있도록 하기 위해 이런 느낌으로 만듭니다.
    좌우 90도 회전시킵니다.

    잠길 때





    개정 시





    원래 상태로 되돌리면 물리 키를 사용할 때 삼턴을 돌리는 메커니즘이 방해가되지 않도록합니다.

    3D 프린터로 본체 작성



    Fusion360으로 모델링하여 인쇄합니다.
    서보 모터를 삽입하는 구멍은 SG-90의 치수로 하고 있습니다.


    Slack 토큰 획득



    다음 절차에 따라 토큰을 얻습니다.
    Slack API를 사용하여 메시지 보내기

    microPython 코드



    main.py

    main.py
    import gc
    import ssl
    import esp
    import time
    import socket
    import network
    from machine import Pin,PWM
    from utime import sleep_ms, ticks_ms
    
    
    gc.collect()
    esp.osdebug(None)
    
    ssid = 'SSIDをここに入力'
    password = 'パスワードをここに入力'
    
    station = network.WLAN(network.STA_IF)
    station.active(True)
    station.connect(ssid, password)
    
    # ピン指定
    ledpin = 32
    servo = 13
    
    led = Pin(ledpin, Pin.OUT)
    servo1 = PWM(Pin(servo), freq = 100)
    
    def web_page():
    
        if led.value() == 1:
            gpio_state="OPEN"
        else:
            gpio_state="CLOSE"
    
        html = """
        <html lang = "ja">
        <head>
        <title>Key</title>
        <meta charset="UTF-8" name="viewport" content="width=device-width, initial-scale=1">
        <link rel="icon" href="data:,">
        <style>
          html{font-family: Helvetica; display:inline-block; margin: 0px auto; text-align: center;}
        h1{color: #0F3376; padding: 2vh;}p{font-size: 1.5rem;}.button{display: inline-block; background-color: #e7bd3b; border: none;
        border-radius: 4px; color: white; padding: 16px 40px; text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}
        .button2{background-color: #4286f4;}
        </style>
        </head>
        <body>
        <h1>かぎ</h1>
        <p>now: <strong>""" + gpio_state + """</strong></p>
        <p><a href="/?led=on"><button class="button">OPEN</button></a></p>
        <p><a href="/?led=off"><button class="button button2">CLOSE</button></a></p>
        </body>
        </html>
       """
        return html
    
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 接続待ちするIpアドレスとポート番号指定
    s.bind(('', 80))
    # 接続を待つ,サーバー受け入れ最大数
    s.listen(5)
    
    def open():
        se = socket.socket()
        ai = socket.getaddrinfo("slack.com", 443)
        addr = ai[0][-1]
        se.connect(addr)
        se = ssl.wrap_socket(se)
        send_data = "token=【Slackのトークン】&channel=%23【チャンネル名】&text=Opend the lab from ESP32"
        se.write(b"POST /api/chat.postMessage HTTP/1.1\r\n")
        se.write(b"Host: slack.com\r\n")
        se.write(b"Accept: */*\r\n")
        se.write(b"Content-Length: %d\r\n" % len(send_data))
        se.write(b"Content-Type: application/x-www-form-urlencoded\r\n")
        se.write(b"Connection: close\r\n")
        se.write(b"\r\n")
        se.write(send_data)
        se.close()
        led.on()
        servo1.duty(240)
        time.sleep_ms(2000)
        servo1.duty(150)
        time.sleep_ms(2000)
    
    def close():
        se = socket.socket()
        ai = socket.getaddrinfo("slack.com", 443)
        addr = ai[0][-1]
        se.connect(addr)
        se = ssl.wrap_socket(se)
        send_data = "token=【Slackのトークン】&channel=%23【チャンネル名】&text=Closed the lab from ESP32"
        se.write(b"POST /api/chat.postMessage HTTP/1.1\r\n")
        se.write(b"Host: slack.com\r\n")
        se.write(b"Accept: */*\r\n")
        se.write(b"Content-Length: %d\r\n" % len(send_data))
        se.write(b"Content-Type: application/x-www-form-urlencoded\r\n")
        se.write(b"Connection: close\r\n")
        se.write(b"\r\n")
        se.write(send_data)
        se.close()
        led.off()
        servo1.duty(60)
        time.sleep_ms(2000)
        servo1.duty(150)
        time.sleep_ms(2000)
    
    while True:
        # 接続を受け付ける
        # 誰かがアクセスしてきたら、コネクションとアドレスを入れる
        conn, addr = s.accept()
        # byte形式で通信を行う
        # データを受け取る
        request = conn.recv(1024)
        request = str(request)
        led_on = request.find('/?led=on') #o
        led_off = request.find('/?led=off') #o
    
        if led_on == 6:
            open()
        if led_off == 6:
            close()
    
        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.sendall(response)
        conn.close()
    



    스마트 폰에서 액세스



    uPyCraft를 사용하여 ESP32에 쓸 수 있으면 스마트 폰 브라우저에서 http://localhost:80에 액세스 해보십시오. 어쩌면 뭔가 표시 될 것입니다.

    구현



    이런 식으로 구현했습니다.

    좋은 웹페이지 즐겨찾기