ESP-32(IoTExpress)でMicroPython I2C LCD(SC1602系)でNTPクロック。
ESP-32(IoT Express)でMicroPython I2C LCD(SC1602系)でNTPクロック。トラ技2017年11月号に掲載されていた白阪一郎氏のMicroPythonのサンプル製作記事でSC1602系パラレルI/F接続のLCDを使ったNTP時計の改造記事です。手持ちのLCDがI2CのI/Fに改造したものしか無かったため、それを使えるようにMicroPythoでI2C接続できるようにネットでググってライブラリ登録&コードを変更して動作できるようにしました。コードを転送後、μPyCraft上からこのようにDefault Runで起動するとスタンドアロンで動作させられるようにできます。モバイルバッテリーで動作させてみた、の図。とりあえず以下にコードを載せておきます。白阪氏のパラレルLCD使用のサンプルコード(ntpclock_lcd.py)からの変更内容は、パラレルLCD用のコード(ドライバ部)を削除、esp8266_i2c_lcd.pyとlcd_api.pyのimport、そして、mainにLCDへ表示するメソッドのコードを記述。NtpClock_i2c_LCD.py#ここから''' *category Micropython application *package NTP CLOCK for I2CLCD(SC1602&PCF8574) *author Ichiro Shirasaka *copyright 2017 Ichiro Shirasaka All Rights Reserved *UpDated for I2CLCD 2018/04/25''' from time import sleep_ms, ticks_msfrom machine import I2C, Pinfrom esp8266_i2c_lcd import I2cLcd# The PCF8574 has a jumper selectable address: 0x20 - 0x27DEFAULT_I2C_ADDR = 0x27#Convert local timedef localtime(esptime): global year,mon,day,hour,min,sec esptime +=9*3600 #GMT -> JST month1 = (31,28,31,30,31,30,31,31,30,31,30,31) month2 = (31,29,31,30,31,30,31,31,30,31,30,31) date = esptime // 86400 time = esptime % 86400 r1 = date % 1461 y1 = date // 1461 if r1 >= 366 : r2 = (r1-366) % 365 y2 = (r1-366) // 365 + 1 year = y1*4 + y2 + 2000 for n in range(12): if r2 - month1[n] < 0: mon = n+1 break r2 -= month1[n] day = r2 + 1 else: year = y1*4 + 2000 for n in range(12): if r1 - month2[n] < 0: mon = n+1 break r1 -= month1[n] day = r1 hour = time // 3600 min = (time % 3600) // 60 sec = time % 3600 % 60#calculate day of weekdef wday(year, mon, day): week = "Sun","Mon","Tue","Wed","Thu","Fri","Sat" if(mon < 3 ): year -= 1 mon += 12 return week[int((year + year/4 - year/100 + year/400 + (13 * mon + 8)/5 + day)%7)]try: import usocket as socketexcept: import sockettry: import ustruct as structexcept: import structNTP_DELTA = 3155673600 #2000.1.1 0:0:0 host = 'ntp.nict.jp'#Connect by Station modedef do_connect(): import network sta_if = network.WLAN(network.STA_IF) if not sta_if.isconnected(): print('connecting to network...') sta_if.active(True) sta_if.connect('SSID12345678','Password12345678') while not sta_if.isconnected(): pass print('network config:', sta_if.ifconfig())#Get time from NTP serverdef ttime(): NTP_QUERY = bytearray(48) NTP_QUERY[0] = 0x1b addr = socket.getaddrinfo(host, 123)[0][-1] s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.settimeout(1) res = s.sendto(NTP_QUERY, addr) msg = s.recv(48) s.close() val = struct.unpack("!I", msg[40:44])[0] return val - NTP_DELTA#NTP Clock Main processrtc_time = 0do_connect()rtc_time = ttime()#"""Test function for verifying basic functionality."""print("Running test_main")#lcd_init()i2c = I2C(scl=Pin(22), sda=Pin(21), freq=100000)lcd = I2cLcd(i2c, DEFAULT_I2C_ADDR, 2, 16)lcd.putstr("LCD is Works!")sleep_ms(3000)lcd.clear()while True: tick = ticks_ms() if tick % 1000 == 0: rtc_time += 1 localtime(rtc_time) lcd.move_to(0, 0) lcd.putstr("%4d/%2d/%2d (%s)" % (year, mon, day, wday(year, mon, day))) print("%4d/%2d/%2d (%s)" % (year, mon, day, wday(year, mon, day))) lcd.move_to(0, 1) lcd.putstr(" %2d:%02d:%02d" % (hour, min, sec)) print(" %2d:%02d:%02d" % (hour, min, sec)) if sec == 0 and min == 0: rtc_time = ttime() print('get time')#ここまで