记得上一次做了MQTT,手机查看温溼度吗?不知道的话,请参见Day2的内容回顾(没有,我怎么可能是为了赚阅览数这么肤浅的行为)。当时的D1 mini是单纯的发布讯息端,这一次,我们要令它身兼二职,感受时下流行的斜槓人生(误除了温溼度外,可以用手机给指令开灯,那我们开始吧!欧对了,我依然是跟着教程走的。
这次,我们的材料有:

图片源自网路一个灯泡外加灯座MQTT中介: io.adafruit.com手机APP: MQTT Client
先附上一张电晶体电路简图
我们一样将D1 mini零号作为温溼度感测使用,将14号作为输出高低电位讯号使用,来告诉继电器通电还是断电。
话说,有没有人对于电晶体的出现感到疑惑呢?或是,为甚么不能去掉电晶体这个步骤,直接接继电器呢?
其实呢,这跟电机系学到的电子学有点关係,想当年上课真的是皮绷得很紧,但好在,要解释这里的目的并不困难,在这里,电晶体与电阻组合成的电路,可以简称为开关,也就是状态处于三极区(triode)以及截止区(cut-off),完全不会用到饱和区(saturation)状态,甚么?听不懂?那有没有听过薛丁格的猫?介于生与死之间,没有不生不死这种状态,又换个比喻,这个电路像个耳朵,只介于有怀孕与没有怀孕之间,不会有既怀孕又没怀孕两种状态同时成立。而不管是生死还是怀不怀孕,其实就是开(三极区)和关(截止区)这两种状态,而这一切要归功于电路的设计。
恩,懂了。
那为甚么不直接跳过电晶体,直接使用Pin 14脚位讯号呢?其实,这是作为保护D1 mini的设计,如果直接将Pin 14脚连接继电器,做高低讯号传输,理论上是没问题的,然而,现实里,会有继电器的高电流逆流回Pin 14的可能性,到时候,可能会造成D1 mini毁损(钱钱飞了),严重一点,就是火灾现场了。但有了电晶体作为保护替死鬼,D1 mini就能逃过死劫。
以下为程式码:
from machine import Pinimport timeimport networkfrom umqtt.robust import MQTTClientimport dhtsensor = dht.DHT11(Pin(0)) #温溼度感测relay = Pin(14, Pin.OUT, value = 0) #命令继电器通电或断电的输出讯号client = MQTTClient( client_id = "temp_humi你开心取名就好", server = 'io.adafruit.com', user = 'adafruit 帐号', password = 'adafruit key', ssl = False)sta_if = network.WLAN(network.STA_IF)sta_if.active(True)sta_if.connect('Wifi', 'code')while not sta_if.isconnect(): print("No wifi signal") time.sleep(0.5) passprint("Wifi connected!")def get_msg(topic, msg): if msg == b"on": relay.value(1) elif msg == b"off": relay.value(0) print(msg) client.connect()client.set_callback(get_msg)client.subscribe(b" adafruit帐号/feeds/light")#订阅端设置,灯开关last_time = 0while True: if time.time() - last_time >= 3: sensor.measure() temp_humi = "%2d °C/ %2d%%" % ( sensor.temperature(), sensor.humidity()) client.publish(b"adafruit帐号/feeds/temp_humi", temp_humi.encode()) #发布端设定,温湿度 last_time =time.time() client.check_msg()
接下来,延续Day2的手机App设定,我们接着创建Publisher就行了。
轻点创建事件名称,会直接进入订阅端,选取上传图案
我们会进入发布端设定,这时在topic输入:Adafruit帐号/feeds/light,message输入:on或是off,并送出讯号就可以了。