■動作テスト:mqttあり

・コードはベタで載せます。

・参照URLの改行異常有無にご留意のうえ適宜調整ください。

・今回は取り急ぎmqttありのテストです。
・受信(subscribe)は以前の記事ご参照

(修正前の問題点)
 ・受信と送信の時刻がずれる→NTPで時刻合わせをしたい。

 ・月日時分秒は一桁だと文字数が減る→0埋めしたい。
(修正方法)
 ↓コレだけで一気に片付きました。

 出典1

  https://interface.cqpub.co.jp/wp-content/uploads/if2207_144.pdf

 

【フォルダ構成】

 

【動作テストコード:mqttあり】

###### server room monitor ######
# version 0.2
# required W5100-EVB-PICO
# required UF2 for W5100-EVB-PICO
#   https://micropython.org/download/W5100S_EVB_PICO/
# required rtc DS3231
# required labrary for mqtt
# get simple.py from as bellows;
# https://github.com/micropython/micropython-lib/blob/master/micropython/umqtt.simple/umqtt/simple.py
# set simple.py in umqtt folder
# get robust.py from as bellows;
# https://github.com/micropython/micropython-lib/tree/master/micropython/umqtt.robust
# set robust.py in umqtt folder
# robust.py adds auto-reconnect facilities for some of networking errors.
from umqtt.simple import MQTTClient

#typical UF2 for PICO has no network-library
#so,required UF2 for W5100-EVB-PICO
import network

#libraries for connecting to NTP
import ntptime
import utime

#library for AHT20 as Humidity and Temperature Sensor
from ahtx0 import AHT20

#ds3231 require special library
# arranged by kabayon 241111
from ds3231 import DS3231

#ssd1306 oled-dsiplay require special library
#import ssd1306

from machine import Pin,SPI
from machine import SoftI2C

from time import sleep_ms
import time

# スイッチ(入力)オブジェクト設定
as01 = machine.Pin(2, machine.Pin.IN, machine.Pin.PULL_UP)
as02 = machine.Pin(3, machine.Pin.IN, machine.Pin.PULL_UP)
as03 = machine.Pin(4, machine.Pin.IN, machine.Pin.PULL_UP)
as04 = machine.Pin(5, machine.Pin.IN, machine.Pin.PULL_UP)
ms01 = machine.Pin(7, machine.Pin.IN, machine.Pin.PULL_UP)
ms02 = machine.Pin(8, machine.Pin.IN, machine.Pin.PULL_UP)
ms03 = machine.Pin(9, machine.Pin.IN, machine.Pin.PULL_UP)

sts_as01 = as01.value()
sts_as02 = as02.value()
sts_as03 = as03.value()
sts_as04 = as04.value()
dec_address = 8*sts_as01 + 4*sts_as02 + 2*sts_as03 + sts_as04
bit_address = str(sts_as01) + str(sts_as02) + str(sts_as03) + str(sts_as04)
sts_ms01 = ms01.value()
sts_ms02 = ms02.value()
sts_ms03 = ms03.value()
dec_mode = 4*sts_ms01 + 2*sts_ms01 + sts_ms03
bit_mode = str(sts_ms01) + str(sts_ms02) + str(sts_ms03)
#print("address - ",bit_address,dec_address,"  mode - ",bit_mode,dec_mode)
set_on =1
set_off=0
if sts_ms03==1:
    mode_ntp_get=set_on
else:
    mode_ntp_get=set_off
if sts_ms02==1:
    mode_continuous=set_on
else:
    mode_continuous=set_off
    
#set i2c0
sda_i2c0 = 0
scl_i2c0 = 1
freq_i2c0= 400000
i2c0 = SoftI2C(scl=Pin(scl_i2c0), sda=Pin(sda_i2c0), freq=freq_i2c0) 

#set AHT20-object
aht21 = AHT20(i2c0)

#set RTC-object
rtc_ds3231 = DS3231(i2c0)
sleep_ms(2000)

#def MQTT connect
def mqtt_connect():
    client = MQTTClient(client_id, address_mqtt_broker, keepalive=60)
    client.connect()
    print('Connected to %s MQTT Broker'%(address_mqtt_broker))
    return client

#def reconnect & reset
def reconnect():
    print('Failed to connected to MQTT Broker. Reconnecting...')
    time.sleep(5)
    machine.reset()

#connect to w5100
#initialize W5100
#set valiables for SPI
spi_chn = 0
baud_rate = 400000
pin_mosi = 19
pin_miso = 16
pin_sck  = 18
pin_cs   = 17
pin_reset= 20
#set spi-object with spi-channel,bauerate,mosi,miso,sck
spi=SPI(spi_chn,baud_rate, mosi=Pin(pin_mosi),miso=Pin(pin_miso),sck=Pin(pin_sck))
#set WIZNET5100 with spi-object,pin-CS,pin-reset
nic = network.WIZNET5K(spi,Pin(pin_cs),Pin(pin_reset))
#activate nic, after that RJ45-lamp is on and blinking
nic.active(True)

#setting ip-parameter
address_me = '192.168.10.88'
net_mask   = '255.255.255.0'
address_rooter = '192.168.10.1'
address_dns = '192.168.10.1'
nic.ifconfig((address_me,net_mask,address_rooter,address_dns))
#check nic-connection
while not nic.isconnected():
    time.sleep(1)
    print('--- waiting connection to nic')
print('nic connect to network')
    
# get UTC from NTP and convert JST
import ntptime
import utime
ntptime.settime() 
JST_OFFSET = 9*60*60
# 時刻を取得、JST で表示する
(year_ntp, month_ntp, day_ntp, hour_ntp, minute_ntp, second_ntp, weekday_ntp, year_day_ntp) = utime.localtime(utime.time() + JST_OFFSET)
#set time_ntp to rtc
if mode_ntp_get==set_on:
    rtc_ds3231.set_time(year_ntp, month_ntp, day_ntp, hour_ntp, minute_ntp, second_ntp, weekday_ntp, 00)

#set configuration for mqtt-broker and topic
address_mqtt_broker = '192.168.10.24'
client_id = 'kabaw5101'
topic_pub = b'test_mqtt/kabaw5101'
try:
    client = mqtt_connect()
except OSError as e:
    reconnect()
if mode_continuous==set_on:
    i_max=300000
else:
    i_max=1 #one-shot

#interval 600000msec=10minutes
time_interval=600000

for i in range(0,i_max):
    time_rtc = rtc_ds3231.get_time()
    year_rtc  = f"{time_rtc[0]:4d}"
    month_rtc = f"{time_rtc[1]:02d}"
    day_rtc   = f"{time_rtc[2]:02d}"
    hour_rtc  = f"{time_rtc[3]:02d}"
    minute_rtc = f"{time_rtc[4]:02d}"
    second_rtc= f"{time_rtc[5]:02d}"
    time_record = year_rtc+month_rtc+day_rtc+hour_rtc+minute_rtc+second_rtc
    #print("temp:",aht21.temperature,"  humd:",aht21.relative_humidity)
    temperature_record = str
    temp_now = aht21.temperature
    humd_now = aht21.relative_humidity
    aht20_record ="T" + str(round(temp_now,1)) + "H" + str(round(humd_now,1))
    data_record = "A"+bit_address+"M"+bit_mode+"D"+time_record+aht20_record
    print(data_record)
    topic_msg = data_record
    client.publish(topic_pub, topic_msg)
    if i_max==1:
        sleep_ms(100)
        print ("one-shot end")
    else:
        sleep_ms(time_interval)

print ("program end at i_max:",i_max)
 

 

■動作結果

【Publish側】PICO接続Thonnyのコンソール表示

MPY: soft reboot
--- waiting connection to nic
--- waiting connection to nic
nic connect to network
Connected to 192.168.10.24 MQTT Broker
A0101M111D20241112134401T25.6H50.7
A0101M111D20241112134406T25.7H50.8
A0101M111D20241112134411T25.6H50.7
A0101M111D20241112134416T25.6H50.5
A0101M111D20241112134421T25.6H50.6
A0101M111D20241112134426T25.6H50.7
A0101M111D20241112134431T25.6H50.6
A0101M111D20241112134436T25.6H50.6
A0101M111D20241112134441T25.7H50.7
A0101M111D20241112134447T25.7H50.6

 

【Subscribe側】VSCODE上のJupyterコンソール表示

Connected with result code 0
2024/11/12 13:44:00,b'A0101M111D20241112134401T25.6H50.7',test_mqtt/kabaw5101,0
2024/11/12 13:44:05,b'A0101M111D20241112134406T25.7H50.8',test_mqtt/kabaw5101,0
2024/11/12 13:44:10,b'A0101M111D20241112134411T25.6H50.7',test_mqtt/kabaw5101,0
2024/11/12 13:44:15,b'A0101M111D20241112134416T25.6H50.5',test_mqtt/kabaw5101,0
2024/11/12 13:44:20,b'A0101M111D20241112134421T25.6H50.6',test_mqtt/kabaw5101,0
2024/11/12 13:44:25,b'A0101M111D20241112134426T25.6H50.7',test_mqtt/kabaw5101,0
2024/11/12 13:44:31,b'A0101M111D20241112134431T25.6H50.6',test_mqtt/kabaw5101,0
2024/11/12 13:44:36,b'A0101M111D20241112134436T25.6H50.6',test_mqtt/kabaw5101,0
2024/11/12 13:44:41,b'A0101M111D20241112134441T25.7H50.7',test_mqtt/kabaw5101,0
2024/11/12 13:44:46,b'A0101M111D20241112134447T25.7H50.6',test_mqtt/kabaw5101,0

 

Pub側のDデータ(時刻)はRTC(DS3231)の時刻です。

Sub側にはNTCで時刻合わせされた受信時刻が記載されています。

短時間のテストでは送信時刻とSub受信時刻のズレは概ね1秒以内です。

今回使用のDS3231はMEMS方式ですが、結構ずれやすいとの話があるようですので、1週間ほど連続稼働してズレを確認したいと思います。(後日報告予定)

 

【241112当日追記】

・2時間連続稼働して、ズレはほぼなしでした。

2024/11/12 14:29:30,b'A0101M111D20241112142930T26.2H51.6',test_mqtt/kabaw5101,0
・・・
2024/11/12 16:38:42,b'A0101M111D20241112163842T25.6H54.0',test_mqtt/kabaw5101,0

5秒毎のmqttだとデータが無駄に多くなりますので、

sleepの値を1時間にしてデータ取り再開しました。

 

【241118追記】

Connected with result code 0
2024/11/18 11:15:36,b'A0101M100D20241118111535T25.4H56.0',test_mqtt/kabaw5101,0

一旦停止して電源ケーブルを外し、RTCは電池だけで維持して一週間ほど立ちましたが、時刻のズレは1秒以内に収まっていました。

ディップスイッチでモードをセットするようにして、NTP時刻取得&RTC修正モード

、ワンショットモードを設け、より実用的にしました。

 

【追記241124】

コードを貼り替えました。

また、久々にNTPと同期させずに起動、接続してみました。
Connected with result code 0
2024/11/24 14:10:56,b'A0101M100D20241124141052T20.9H43.5',test_mqtt/kabaw5101,0
2024/11/24 14:11:55,b'A0101M100D20241124141151T20.7H43.8',test_mqtt/kabaw5101,0
おおお、4秒ズレました。

ここ1週間で急に気温が低下してきましたし、暑い寒いを鑑みて、

定期的に、例えば毎日1回、NTPと同期したほうがよいようです。

多少のコード追記は後日トライします。

 

以上、本件終了。