Easy MicroPython 教程与手册¶
简介¶
几年前,上海乐鑫公司开发了一个ESP8266芯片。该芯片的定位目标是低成本WiFi物联网解决方案,但是除了WiFi外,该芯片也自带了基础的逻辑计算和针脚输入输出的功能,类似于一个自带WiFi的Arduino。
然而纯粹的ESP8266芯片需要自己焊接针脚和板子,也只能用C语言进行开发,不太方便。后来有人创建了一个新项目:NodeMCU,该项目将ESP8266进行了简单的封装,同时开发了支持Lua语言的框架,自此ESP8266可以使用Lua脚本语言来编程。
再之后,澳大利亚程序员和物理学家Damien George开发的MicroPython,开始支持ESP8266,自此之后,就可以在ESP8266的设备(如NodeMCU)中刷入MicroPython框架,用Python来对NodeMCU进行编程。
也就是说,用20元左右,就可以打造一套用Python编写的,能够联网的Arduino。
但是MicroPython本身只完成了一些基础的功能,对于不同的传感器等操作并没有进一步的封装,如果想使用MicroPython去控制一些复杂的传感器,会需要一定的专业功底。
为此,我创建了Easy MicroPython项目。这是在MicroPython之上的一层封装,将针脚操作和传感器、控制器连接进行了进一步的简化,目的是为了让初学者更加方便、快捷地使用MicroPython。
本项目目前仅在基于ESP8266或ESP32的NodeMcu上进行过调试,其余硬件不保证兼容性。
安装与快速开始¶
首先你需要一块NodeMCU板,推荐基于ESP32的,功能更强大,基于ESP8266的也可以使用大部分的功能。
之后将你的NodeMCU板刷入MicroPython框架,具体方法可以查看 MicroPython官网
本框架本质上是一些封装好函数的py文件,放置于NodeMCU的根目录即可正常使用。
项目提供了一个自动刷入的程序,如果你对NodeMCU不熟悉,可以跟着以下步骤直接使用:
下载本项目:https://github.com/RainGather/Easy_MicroPython/releases
解压到一个目录中,例如:C:\nodemcu,请保证整个路径没有空格和中文,同时请务必放在C盘(放在其它盘符可能会导致未知的错误)
安装Python 3,同时请将Python路径加入到环境变量PATH中
将NodeMCU连接上电脑
双击flash.bat运行,第一次运行时,会自动尝试安装缺失的库文件,安装完后需关闭重新打开。
按指示选择端口和设备型号,等待框架刷入完成后关闭窗口。
在该目录下,新建HelloWorld.py,在里面可以写入本手册中的案例代码。例如:
print('Hello World')
双击upload.bat
按照指示选择端口和需刷入的文件,文件会自动列出在列表中,填写数字序号即可。
显示刷入成功后,按下[CTRL + D]或板子上的[RST]键重启板子运行。
如果一切正常,刷入窗口最后应该会出现Hello World字样。
窗口关闭后,可用用connect.bat重新连接至NodeMCU。
基础¶
输出高/低电平¶
用如下代码即可让针脚输出高电平:
p = OUT(0) # 0可以换成其它针脚,OUT、O、Out_三者同名同义
p.on()
用如下代码即可让针脚输出低电平:
p = OUT(0) # 0可以换成其它针脚
p.off()
获取高/低电平¶
用如下代码即可获取指定针脚的电平:
p = IN(0) # 可以将0换成其它针脚,IN、I、In_三者同名同义
v = p.value() # 将当前0针脚的电平值赋给v变量,高电平为1,低电平为0
PWM输出¶
PWM为脉冲宽度调制输出,可以理解成释放出最高电压一定百分比的电压。 并不是所有的针脚都支持PWM输出,其中
ESP8266: | 针脚D0, 2, 4, 5, 12, 13, 14 和 15支持PWM模拟输出 |
---|---|
ESP32: | GPIOs 0, 1, 2, 3, 4, 5, 12, 13, 14, 15, 16, 17, 18 ,19, 21, 22, 23, 25, 26, 27, 32, 33支持 |
MicroPython中,PWM的范围为0-1023.
可以用如下代码来产生PWM:
p = PWM(2) # 2针脚用于PWM输出
p.duty(512) # 占空比设置为512/1024
模拟输入¶
NodeMCU的ESP8266版本,只有一个A0模拟输入,其官方的读取方式也很简单,就没有再度封装:
from machine import ADC
a = ADC(0)
a.read()
舵机¶
将舵机信号线连到支持PWM的针脚。 一般常见的舵机,可以用如下代码直接控制:
d = SERVO(2) # 针脚2连接舵机信号线,可以交换
d.turn(90) # 转到90度。
一般舵机理论上转角为0-180度,但由于舵机的精度问题,尽量建议只使用30-150度。
如果有某些特殊的舵机,控制PWM频率是不同的,例如频率为440HZ,可以用如下代码控制:
d = SERVO(2, freq=440)
d.turn(90)
为了便于母语中文的初学者使用,SERVO与DUOJI做了映射,zhuan与turn做了映射,用DUOJI、zhuan代替上述的SERVO、turn词汇,也可以正常使用。
WiFi与物联网(MQTT)¶
用如下代码即可将NodeMCU连接至网络:
wifi('wifiname', 'wifipwd') # 请将内容改成自己的WiFi名和密码,注意不要有引号、中文等特殊字符,尽量纯英文+数字
连接网络后,即可使用urequests库,具体方法请查看 urequests源代码
本项目已集成MQTT,可以方便的基于MQTT开发物联网设备。
MQTT是一种针对物联网优化过的协议,其结构很简单,为’主题-内容’对应式结构,下面用一个例子来说明:
假设C1是放置于机房的温度传感器物联网设备,C2是放置于办公室的机房过热报警灯。 那么C1可以发布一个主题,名为’computer_room/temperature’,值为当前温度。 C2可以订阅一个主题,名字与上述C1名一致。 这样一旦’computer_room/temperature’这个主题发生改变,C2就可以立刻获取改变后的值。获取值以后,可以判断其是否高于某个温度,从而决定是否发出警报。
默认情况下,一旦连接wifi,就会连接上test.mosquitto.org的服务器,该服务器是公共服务器,如您只是测试使用,可用此服务器,如正式使用,请务必切换到安全的服务器。
用如下代码可以指定自己的MQTT服务器和验证方式:
wifi('wifiname', 'wifipwd', False) # 需要在连接WiFi时加入False参数,否则会直接连接到test.mosquitto.org服务器。
mqtt_init(host='www.yoursite.org', port=1883, user='yourusername', pwd='youruserpwd') # 如果你的mqtt服务器没有验证,则可以不填写mqtt_user与mqtt_pwd
发布主题:
pub('topic/can/split/like/path', 'str content') # 注意必须使用str类型,如果是数字类型请自行转换
主题只能用英文,消息如果包含中文,需要进行编码:
msg = '中文消息'
pub('topic/can/split/like/path', msg.encode('utf-8'))
订阅主题,并设置触发后的操作:
@sub('a/topic') # 主题可以模糊订阅,用+表示一个级数,#表示多个级数
def whatevername(topic, msg): # 一旦订阅的主题发生改变,此函数就会接受发生改变的主题topic和消息msg
# 接受到的topic和msg都是bytes类型,需要用decode转成字符串类型
topic = topic.decode('utf-8')
msg = msg.decode('utf-8')
print(topic, msg)
全局变量¶
由于封装的原因,普通的global可能无法正常使用,可以用g变量,该变量本身是一个字典类型,可以把要保存的数据存于该变量中。
例如:
g['save'] = 'test'
这样在其它地方调用:
print(g['save'])
就可以了。
时间相关¶
NodeMCU没有内置的时间,只提供一个time.time()函数获取已经通电了多少秒:
import time
print(time.time()) # 结果会是类似42,意思是已经通电42秒
为此本框架内置了NTP对时系统,如果你使用WIFI函数连接了网络,框架会尝试自动进行NTP对时,如果一切正常,使用time.time()就可用获取当前的时间戳(由于MicroPython的设置,时间戳是从2000年开始的,不是Linux的1970年开始):
import time
WIFI('wifiname', 'wifipwd')
print(time.time()) # 结果会是类似527648123这样的数字,意思是当前时间与2000年1月1日0时所差的秒数。
print(time.localtime()) # 结果会是类似(2018, 4, 16, 15, 59, 03, 0, 106), 意思是2018年4月16日15:59:03,最后两位数0和106暂时没用
由于网络原因,即使WIFI连接了,NTP对时也可能失败,可用用如下代码手工对时:
if not ntp_ok(): # 检测ntp是否已经成功校准,已校准的话返回True,否则返回False
set_ntp_time(tz=8) # tz为时区,北京时区为正8区,所以tz=8,如果是-6区就写tz=-6
非阻塞循环¶
如果采用如下方式进行循环:
while True:
print('hello world')
print('这一条永远不会被执行')
会产生阻塞,导致最下面的print命令永远不会被执行。
所以Easy MicroPython集成了一个非阻塞式的循环,用如下方式即可:
@loop
def any_name(): # 这个函数名可以任取
print('hello world1')
print('这条不会被阻塞,会执行')
@loop
def any_name2():
print('hello world2')
最终输出为:
这条不会被阻塞,会执行
hello world1
hello world2
hello world1
hello world2
hello world1
hello world2
...
传感器¶
超声波传感器¶
注意:超声波传感器的基础供电电压至少为5V,NodeMCU一般只能供给3.3V,所以需要自己搭建电路,否则不会正常工作!!!!
如下代码可以通过超声波传感器获取距离:
# 将ULTRASONIC换成CHAOSHENGBO同效
u = ULTRASONIC(1, 2) # 1是超声波探测器上的Echo_Pin脚所接的针脚号,2是超声波探测上的Trig_Pin脚所接的针脚号。部分厂商的针脚是相反的,如果无法正常使用,两者换一下再试试看。
u.get() # 获取距离,单位为米
DHT11温湿度传感器¶
DHT11是一种常见的温湿度传感器,淘宝上有售。 正确连接DHT11的电源线,并将DHT11的信号线,连入NodeMCU的任一数据口(在此处以D2口为例),用如下代码获取温湿度:
d = DHT11(2) # 2为温湿度传感器信号所连针脚
wendu, shidu = d.get() # 同时获取温度和湿度
DHT22温湿度传感器¶
DHT22是一种常见的温湿度传感器,淘宝上有售。 正确连接DHT22的电源线,并将DHT22的信号线,连入NodeMCU的任一数据口(在此处以D2口为例),用如下代码获取温湿度:
d = DHT22(2) # 2为温湿度传感器信号所连针脚
wendu, shidu = d.get() # 同时获取温度和湿度
代码案例¶
控制LED开关¶
将LED灯的正极接D0脚,负极接GND,用如下代码就可以控制LED的开关。
开灯:
# 设置针脚0为输出端,你也可以选择其他的针脚
p = OUT(0)
# 将针脚0设为高电平,这样连接针脚0的LED灯就会发光
p.on()
关灯:
# 设置针脚0为输出端,你也可以选择其他的针脚
p = OUT(0)
# 将针脚0设为低电平,这样连接针脚0的LED灯就会灭了
p.off()
LED闪烁¶
将LED连接到针脚0,随后可以用如下代码控制:
# 导入time库,可以使用等待等功能
import time
# 设置针脚0为输出端
p = OUT(0)
while True:
# 将针脚0设为高电平,这样连接针脚0的LED灯就会发光
p.on()
# 等待1秒
time.sleep(1)
# 将针脚0设为低电平,这样连接针脚0的LED灯就会灭了
p.off()
# 等待1秒
time.sleep(1)
呼吸灯¶
将LED正极连接到针脚2,用如下代码可以控制LED灯变成呼吸灯:
# 导入时间库,可以使用等待功能
import time
# 声明2针脚为PWM输出端,在ESP8266中针脚0, 2, 4, 5, 12, 13, 14 和 15支持PWM模拟输出
p = PWM(2)
while True:
# 将指针2的输出,从0逐渐增长到1024,0为最低输出(0V),1024为最高输出(5V或3.3V)
for i in range(1024):
# 设置针脚输出
p.duty(i)
# 等待0.005秒,防止闪烁过快
time.sleep(0.005)
# 将指针2的输出,从1024逐渐减少到0
for i in range(1024, 0, -1):
# 设置针脚输出
p.duty(i)
# 等待0.005秒,防止闪烁过快
time.sleep(0.005)
控制舵机角度作为雨刮器¶
将舵机信号线接到针脚2,并用如下代码控制舵机在30度与150度之间循环旋转:
import time
# 声明2针脚连接舵机的信号线,针脚1-8支持舵机控制,如舵机不是50HZ的,可以用SERVO(2, freq=频率)的方式来声明
servo = SERVO(2)
while True:
# 将舵机旋转30度,普通舵机理论上可以转0-180度,但由于舵机制作的精度原因,建议控制在30-150度左右旋转
servo.turn(30)
time.sleep(2)
# 将舵机旋转150度,普通舵机理论上可以转0-180度,但由于舵机制作的精度原因,建议控制在30-150度左右旋转
servo.turn(150)
time.sleep(2)
获取按钮是否按下¶
将按钮分别将针脚0连接到GND和VCC,并用如下代码获取针脚0连接的是GND还是VCC:
# 导入时间库,这样可以使用等待的功能
import time
# 将针脚0作为数字输入
p = IN(0)
while True:
# 获取针脚0上输入的电平高低,如果为高则为1,如果为低则为0
i = p.value()
# 将其值打印出来
print(i)
# 等待1秒,防止刷新太快
time.sleep(1)
获取温度传感器的值¶
将DHT11或DHT22的信号线连接到针脚2,用如下代码获取温湿度的值:
import time
# 2针脚连DHT11温湿度传感器的数据端,如果是DHT22请将下列代码中的DHT11改成DHT22
d = DHT11(2)
while True:
# 一口气获取温度和湿度
wendu, shidu = d.get()
# 打印温度到窗口
print(wendu)
# 打印湿度到窗口
print(shidu)
# 等待1秒
time.sleep(1)
指纹识别¶
本代码使用的是微雪指纹模块,其余指纹模块若想使用封装,可以私信联系我。
由于本指纹识别模块是串口通讯,而ESP8266由于其本身设计原因,无法简单通过UART0之外的串口来进行通讯,故而本代码只适合用于ESP32为核心的NodeMCU。
请将指纹模块的RX端接到SD3(GPIO10),将TX端接到SD2(GPIO9):
f = FINGER()
f.add_finger() # 添加指纹,会录入3次,3次正常则返回True,否则返回False
print(f.match_finger()) # 进行指纹比对,如果当前指纹在指纹库中存在,则返回其ID(ID必定大于0),否则返回0或者False
具体可以查看:微雪(waveshare)指纹传感器
串口模式¶
介绍¶
注意!!!!!!¶
串口模式一定要使用5V供电,3.3V的供电会导致串口出问题最终影响使用!!!!
再注意!!!!!!!¶
发送命令时,请等待几秒,例如连接好WiFi后,请等待5秒再发送下一个命令。否则可能导致命令被忽略!
由于某些原因,ESP8266的刷入在某些电脑中会出现各种问题。目前我暂时无法排查出问题在什么地方,同时为了方便大家在自己熟悉的环境中使用物联网,故而做了串口控制的功能。
Nodemcu的串口接收使用UART(0)口,发送使用UART(1)口,默认波特率为115200,在ESP8266板子中,接受就是RX口,发送就是D4口。接电路的时候需要将Nodemcu的rx、d4分别与上位机的tx、rx相接,同时需要共地。
串口控制的统一格式为:
[cmd|arg|arg|arg]
由于串口通讯某些时候会有干扰字符,故而使用尖括号括起命令的格式传输。例如,mqtt的订阅格式为:
[sub|title/subtitle]
这样在之后接收到mqtt的消息后,ESP8266会返回:
[sub|title/subtitle|msg]
请避免在arg或cmd中含有竖杠,目前没有做自动转义,如需竖杠符号在msg或arg中存在,请在上位机中自行完成转义工作。
命令发送后,如一切正常则会返回:
[sta|ok]
如果命令有误,则会返回:
[sta|nocmd]
串口MQTT控制¶
注意!!!!!!¶
串口模式一定要使用5V供电,3.3V的供电会导致串口出问题最终影响使用!!!!
再注意!!!!!!!¶
发送命令时,请等待几秒,例如连接好WiFi后,请等待5秒再发送下一个命令。否则可能导致命令被忽略!
连接Wifi:
[wif|wifiname|wifipwd]
如果WiFi连接错误会自动退出,返回:
[sta|exit]
设定服务器(默认为test.mosquitto.org,你可以自行搭建一个服务器,也可以使用他人的服务器,例如:https://www.cloudmqtt.com/,需注册):
[svr|test.mosquitto.org|1883|user|pwd]
其中端口号、用户名和密码可以为空:
[svr|test.mosquitto.org]
[svr|test.mosquitto.org|1883]
订阅主题:
[sub|title/subtitle]
主题有消息时会返回一条消息(请自行完成监听):
[sub|title/subtitle|msg]
发送消息:
[pub|title/subtitle|msg]
以上命令都会在成功执行后返回:
[sta|ok]
如需重启或重置,可以发送命令:
[sys|reboot]
会收到命令:
[sys|rebooting]
手机端MQTT连接推荐: https://apkpure.com/linear-mqtt-dashboard/com.ravendmaster.linearmqttdashboard