ステッピングモーターで遠隔地からカメラを左右に向ける
 
前の記事で昔々買っておいたステッピングモーターの記事を書きました。


この仕組みを使ってカメラの撮影方向を左右に変更できる装置を作ってみました。
 
■映像
 

■回路図

 

 

 

■WEB画面操作

 

左右に45°と細かく4°ぐらい旋回するボタンを付けました。

 

■プログラム

https://drive.google.com/file/d/1IofmumkqOpXvEN2CH41RIN7VR7gZVCr_/view?usp=sharing


#
#ステッピングモーターで台を左右に振る
#  ESP32 micro python system
#
#  ESP32---ULN2003制御ボード---28BYJステッピングモーター
#
# 接続
#  ESP32 ULN2003
#   25      1
#   26      2
#   27      3
#   13      4
#   5V      5V
#   GNS     GND
#
# 仕様
#  自動的にWIFI接続して
#  webサーバーを起動する
#  webサーバー画面のボタンを押すと
#  ステッピングモーターが回転する
#

 

途中省略

 


def migi(flag, conn):
    header_send200(conn)
    #conn.send('HTTP/1.1 200 OK¥n')
    #conn.send('Content-Type: text/html¥n')
    #conn.send('Connection: close¥n¥n')
    html_form = """
        <html>
        <head>
            <title>MigiHidariSys </title>
            <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
            <meta http-equiv="refresh" content="0;URL=/">
        </head>
        <body>
            <h1>MigiHidariSys ステータス</h1>
    """
    conn.send(html_form)
    conn.send("serialno:"+serialno+"<br>¥n")
    conn.send("<br>¥n")
    conn.send("MigiHidariSys:<br>¥n")
    conn.send("<blockquote>¥n")
    conn.send("右を向きました<br>¥n")
    conn.send("</blockquote>¥n")
    html_form = """
            メニュー<br>
            <blockquote>
                <a href="/">戻る</a><br>
            </blockquote>
        </body>
        </html>
    """
    conn.send(html_form)
    #
    LED_ON()
    # ステッピングモーター制御
    if flag == True:
        log(WRN, SV, "debug migi 1")
        my_motor.step(-288)
        log(WRN, SV, "debug migi 2")
    else :
        log(WRN, SV, "debug migi 3")
        my_motor.step(-25)
        log(WRN, SV, "debug migi 4")
    #
    LED_OFF()
    log(WRN, SV, "migi kaiten.")

def hidari(flag, conn):
    header_send200(conn)
    #conn.send('HTTP/1.1 200 OK¥n')
    #conn.send('Content-Type: text/html¥n')
    #conn.send('Connection: close¥n¥n')
    html_form = """
    <html>
    <head>
        <title>MigiHidariSys </title>
        <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
        <meta http-equiv="refresh" content="0;URL=/">
    </head>
    <body>
        <h1>MigiHidariSys ステータス</h1>
    """
    conn.send(html_form)
    conn.send("serialno:"+serialno+"<br>¥n")
    conn.send("<br>¥n")
    conn.send("MigiHidariSys:<br>¥n")
    conn.send("<blockquote>¥n")
    conn.send("左を向きました<br>¥n")
    conn.send("</blockquote>¥n")
    html_form = """
        メニュー<br>
        <blockquote>
            <a href="/">戻る</a><br>
        </blockquote>
    </body>
    </html>
    """
    conn.send(html_form)
    #
    LED_ON()
    # ステッピングモーター制御
    if flag == True:
        log(WRN, SV, "debug hidari 1")
        my_motor.step(267)
        log(WRN, SV, "debug hidari 2")
    else :
        log(WRN, SV, "debug hidari 3")
        my_motor.step(25)
        log(WRN, SV, "debug hidari 4")
    #
    LED_OFF()
    log(WRN, SV, "hidari kaiten.")
 

 

途中省略

 

#
#WEB画面
#
def s_Th():
    try :
        conn = ""
        log(INF, NO, "start s_Th()")
        
        global wifi_error_flag
        global senser_error_flag
        global network_error_flag
        
        global logBuffer
        
        #
        log(INF, NO, "s_Th socket.getaddrinfo()")
        addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
        #
        log(INF, NO, "s_Th socket.socket()")
        s = socket.socket()
        #
        log(INF, NO, "s_Th s.bind(addr)")
        s.bind(addr)
        #
        log(INF, NO, "s_Th s.listen(1)")
        s.listen(1)
        #
        log(INF, NO, "s_Th s.settimeout(600)")
        s.settimeout(600)    #acceptのタイムアウトを600秒に設定
        
    except Exception as e:
        last_log = trace_point
        log(WRN, SV, "s_Th() exception")
        log(WRN, SV, "s_Th() lastlog="+last_log)
        log(WRN, SV, "s_Th() exception string="+str(e))
        log(WRN, SV, "s_Th() I will restart now.")
        error_LED( 5 )
        machine.reset()
        
    #
    while True:
        try :
            PILOT_LED_ON( )
            log(INF, NO, "s_Th s.accept()")
            try:
                conn, addr = s.accept()
            except:
                log(INF, NO, "s_Th error s.accept")
                utime.sleep(0.1)
                continue
            #
            PILOT_LED_OFF( )
            utime.sleep(0.03)
            PILOT_LED_ON( )
            conn.settimeout(1)
            #リクエストを読み込む
            log(INF, NO, "s_Th conn.recv()")
            request = conn.recv(1000)
            request = request.decode('utf8')
            log(INF, NO, "s_Th "+request)
            log(INF, NO, "addr "+str(addr))
            #
            #リセットフラグ
            reset_flag = 0
            # / へのアクセス
            if request.find('GET / ') != -1 :
                header_send200(conn)
                #conn.send('HTTP/1.1 200 OK¥n')
                #conn.send('Content-Type: text/html¥n')
                #conn.send('Connection: close¥n¥n')
                html_form = """
                <html>
                <head>
                    <title>MigiHidariSys </title>
                    <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
                </head>
                <body>
                    <h1>MigiHidariSys </h1>
                """
                conn.send(html_form)
                conn.send("serialno:"+serialno+"<br>¥n")
                conn.send("<br>¥n")
                conn.send("MigiHidariSys:<br>¥n")
                conn.send("<blockquote>¥n")
                conn.send("<a href='/hid2'><font size='+2'>←</font></a> ¥n")
                conn.send("<a href='/hidari'>←</a> ¥n")
                conn.send("<a href='/migi'>→</a> ¥n")
                conn.send("<a href='/mig2'><font size='+2'>→</font></a><br>¥n")
                conn.send("</blockquote>¥n")
                html_form = """
                    メニュー<br>
                    <blockquote>
                        <a href="/status">ステータス</a><br>
                    </blockquote>
                </body>
                </html>
                """
                conn.send(html_form)
                
            # /migi へのアクセス
            elif request.find('GET /migi') != -1 :
                migi(False, conn)
            # /hidari へのアクセス
            elif request.find('GET /hidari') != -1 :
                hidari(False, conn)
            # /mig2 へのアクセス
            elif request.find('GET /mig2') != -1 :
                migi(True, conn)
            # /hid2 へのアクセス
            elif request.find('GET /hid2') != -1 :
                hidari(True, conn)
            # ステータス
            elif request.find('GET /status') != -1 :
                header_send200(conn)
                #conn.send('HTTP/1.1 200 OK¥n')
                #conn.send('Content-Type: text/html¥n')
                #conn.send('Connection: close¥n¥n')
                html_form = """
                    <html>
                    <head>
                        <title>MigiHidariSys ステータス画面</title>
                        <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
                    </head>
                    <body>
                        <h1>MigiHidariSys ステータス画面</h1>
                """
                conn.send("<blockquote>¥n")
                conn.send(html_form)
                
                # 状態表示
                conn.send("状態<br>¥n")
                conn.send("<blockquote>¥n")
                if wifi_error_flag == 0 :
                    conn.send("WIFI接続:正常<br>¥n")
                else :
                    conn.send("WIFI接続:異常<br>¥n")
                
                if network_error_flag == 0 :
                    conn.send("ネットワーク:正常<br>¥n")
                else :
                    conn.send("ネットワーク:異常<br>¥n")
                cpu_ondo = str(int((esp32.raw_temperature() -32 ) / 1.8))
                conn.send("CPU温度:"+cpu_ondo+"℃<br>¥n")
                #GC実行
                gc.collect()
                conn.send("メモリ状況:<br>¥n")
                conn.send("<blockquote>¥n")
                conn.send("使用中:"+str(gc.mem_alloc())+"<br>¥n")
                conn.send("空き :"+str(gc.mem_free())+"<br>¥n")
                conn.send("</blockquote>¥n")
                #MAC
                conn.send("MAC:"+ubinascii.hexlify(machine.unique_id(), '-').decode()+"<BR>¥n")
                
                conn.send("</blockquote>¥n")
                #設定情報
                conn.send("設定情報<br>¥n")
                conn.send("<blockquote>¥n")
                #設定ファイルからパラメータを読み込む
                fSetup = open("config.inf", "r")
                for f in fSetup:
                  one = f[0:1]
                  if one == '#' :
                    continue
                  f=f.replace('¥n', '')
                  f=f.replace('¥r', '')
                  conn.send(f+"<br>¥n")
                conn.send("</blockquote>¥n")
                
                conn.send("Software<br>¥n")
                conn.send("<blockquote>¥n")
                conn.send(VersionStr+"<br>¥n")
                conn.send("</blockquote>¥n")
                
                html_form = """
                        メニュー<br>
                        <blockquote>
                            <a href="/detail_log">直近ログ確認</a><br>
                            <a href="/error_log">エラーログ確認</a><br>
                            <a href="/reset">リセット</a><br>
                            <a href="/">戻る</a><br>
                        </blockquote>
                    </body>
                    </html>
                """
                conn.send(html_form)
            #直近ログ
            elif request.find('GET /detail_log') != -1 :
                header_send200(conn)
                #conn.send('HTTP/1.1 200 OK¥n')
                #conn.send('Content-Type: text/html¥n')
                #conn.send('Connection: close¥n¥n')
                html_form = """
                    <html>
                    <head>
                        <title>MigiHidariSys 直近ログ確認</title>
                        <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
                    </head>
                    <body>
                        <h1>MigiHidariSys 直近ログ確認</h1>
                        <br>
                        <a href="/status">メニューに戻る</a>
                        <br>
                        <blockquote>
                """
                conn.send(html_form)
                for log_record in logBuffer :
                    if type(log_record) is str :
                        conn.send(log_record)
                        conn.send("<br>¥n")
                html_form = """
                        </blockquote>
                    </body>
                    </html>
                """
                conn.send(html_form)
            #ファイル一覧
            elif request.find('GET /error_log') != -1 :
                header_send200(conn)
                #conn.send('HTTP/1.1 200 OK¥n')
                #conn.send('Content-Type: text/html¥n')
                #conn.send('Connection: close¥n¥n')
                html_form = """
                    <html>
                    <head>
                        <title>MigiHidariSys エラーログ確認</title>
                        <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
                    </head>
                    <body>
                        <h1>MigiHidariSys エラーログ確認(ファイル一覧)</h1>
                        <br>
                        <a href="/status">メニューに戻る</a>
                        <br>
                        <blockquote>
                """
                conn.send(html_form)
                files = os.listdir()
                for file_name in files :
                    if file_name.find('.log') != -1 :
                        conn.send("<a href=¥""+file_name+"¥">"+file_name+"</a>")
                        conn.send("<br>¥n")
                html_form = """
                        </blockquote>
                    </body>
                    </html>
                """
                conn.send(html_form)
            #ファイルログ
            elif ( request.find('GET /MH.log') != -1 or request.find('GET /MH.1.log') != -1 or request.find('GET /MH.2.log') != -1 or request.find('GET /MH.3.log') != -1 or request.find('GET /MH.4.log') != -1 or request.find('GET /MH.5.log') != -1 or request.find('GET /MH.6.log') != -1 or request.find('GET /MH.7.log') != -1 or request.find('GET /MH.8.log') != -1 or request.find('GET /MH.9.log') != -1 or request.find('GET /MH.10.log') != -1 ) :
                header_send200(conn)
                #conn.send('HTTP/1.1 200 OK¥n')
                #conn.send('Content-Type: text/html¥n')
                #conn.send('Connection: close¥n¥n')
                html_form = """
                    <html>
                    <head>
                        <title>MigiHidariSys エラーログ確認(ログ内容)</title>
                        <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
                    </head>
                    <body>
                        <h1>MigiHidariSys エラーログ確認(ログ内容)</h1>
                        <br>
                        <a href="error_log">ファイル一覧に戻る</a>
                        <br>
                        <blockquote>
                """
                conn.send(html_form)
                filename = request.replace('GET /', '').strip().split(' ', 1)[0].split('?', 1)[0]
                conn.send("----------filename=")
                conn.send(filename)
                conn.send("----------<br><br>")
                
                f = open(filename, 'r')
                with open(filename) as fh:
                    for line in fh:
                        conn.send(line.strip())
                        conn.send("<br>¥n")
                html_form = """
                        </blockquote>
                    </body>
                    </html>
                """
                conn.send(html_form)
            elif request.find('GET /reset') != -1 :
                header_send200(conn)
                #conn.send('HTTP/1.1 200 OK¥n')
                #conn.send('Content-Type: text/html¥n')
                #conn.send('Connection: close¥n¥n')
                html_form = """
                    <html>
                    <head>
                        <title>MigiHidariSys リセット</title>
                        <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
                    </head>
                    <body>
                        <h1>MigiHidariSys をリセットしました</h1>
                    </body>
                    </html>
                """
                conn.send(html_form)
                reset_flag = 1
            elif request.find('GET /favicon.ico') != -1 :
                conn.send('HTTP/1.1 404 notfound¥n')
                conn.send('Content-Type: text/html¥n')
                conn.send('Connection: close¥n¥n')
            else :
                log(INF, NO, "s_Th other")
                #try :
                #    conn.send('HTTP/1.1 500 Internal Server Error¥n')
                #    conn.send('Content-Type: text/html¥n')
                #    conn.send('Connection: close¥n¥n')
                #    utime.sleep(5)
                #except :
                #    log(INF, NO, "s_Th error con.send")
            conn.close()
            #リセット操作
            if reset_flag == 1 :
                log(INF, NO, "utime.sleep(5)")
                utime.sleep(5)
                log(INF, NO, "s_Th:machine.reset()")
                machine.reset()
            #
            utime.sleep(0.1)
            #GC実行
            gc.collect()
        except Exception as e:
            if str(e) == '[Errno 104] ECONNRESET' :
                log(INF, NO, "s_Th [Errno 104] ECONNRESET")
                conn.close()
                continue
            if str(e) == '[Errno 110] ETIMEDOUT' :
                log(INF, NO, "s_Th [Errno 110] ETIMEDOUT")
                conn.close()
                continue
            last_log = trace_point
            log(WRN, SV, "s_Th() exception")
            log(WRN, SV, "s_Th() lastlog="+last_log)
            log(WRN, SV, "s_Th() exception string="+str(e))
            log(WRN, SV, "s_Th() I will restart now.")
            error_LED( 5 )
            machine.reset()