摘要
这篇文章介基于安信可 NodeMCU 绍了ESP8266 MicroPython固件的烧录,开发环境的使用,给出了LED,RGB呼吸灯,TCP 客户端,TCP 服务器,HTTP获取网页,MQTT通信等示例程序。
硬件设备如下图:
固件烧录
要在8266上运行Python程序,就必须先烧录MicroPython固件,最新版的MicroPython固件可以从如下网站下载:https://micropython.org/download/esp8266/
只不过MicroPython下载的固件可能会启动失败,提示如下错误:
load 0x3ffe8400, len 1080, room 0
tail 8
chksum 0xc4
csum 0xc4
rf_cal[0] !=0x05,is 0xFF
你们可以使用我合成的完整的固件,下载地址:MicroPython_4MB.bin
烧录方式如下:
① 打开烧录工具
②选择MicroPython固件
③勾选DoNotChgBin
④设置串口及波特率
⑤点击START开始烧录
开发环境
理论上我们刚才烧录完MicroPython的固件,就可以运行Python代码了,但是为了写代码更加开心,强力建议大家使用如下开发环境:uPyCraft IDE
下载后直接双击打开就可,如果提示安装字体请点击OK暗转安装,不安装的话代码很难看。
软件运行的界面如下图所示:
第一步,连接我们的8266开发板,操作如下:
第二步,下载代码并运行
① 依次点击File >> Examples >> Basic >> blink.py
② 点击右侧的 运行按钮,运行示例代码
③运行成功开发板上的灯开始闪烁
GPIO的应用
硬件原理图
从原理图上可以看出:
绿色灯 ---- GPIO2
红色灯 ---- GPIO4
蓝色灯 ---- GPIO5
按 键 ---- GPIO0
GPIO相关函数:
from machine import Pin #导入Pin功能模块
p0 = Pin(0, Pin.OUT) #将 GPIO0设为输出
p0.on() # 将P0设为高电平
p0.off() #将P0设为低电平
p0.value(1) #将P0设为高电平
p2 = Pin(2, Pin.IN) # 将GPIO2设为输入
print(p2.value()) # 获取GPIO2的值(0或者1)
PWM 的应用
PWM相关函数:
from machine import PWM #导入PWM模块
pwm_r = PWM(Pin(2)) # 使用GPIO2创建一个PWM, 频率默认为500,占空比默认为0
pwm_r = PWM(Pin(2),1000,500) # 使用GPIO2创建一个PWM, 并设置频率为1000, 占空比为500
pwm_r.duty() # 获取pwm_r的占空比
pwm_r.duty(500) # 设置占空比为500 (其范围是 0 ~ 1023)
pwm_r.freq() # 获取pwm_r的频率
pwm_r.freq() # 设置pwm_r的频率为1000(其范围是1 ~ 1000)
PWM实现颜色渐变
完整代码:
from machine import Pin,PWM
import time
led_r =PWM(Pin(4),1000,0)
led_g =PWM(Pin(2),1000,0)
led_b =PWM(Pin(5),1000,0)
stage = 1
r = 1000 #RGB初值
g = 0
b = 0
while True:
if stage == 1: #第一阶段,红灯逐渐变暗,绿灯逐渐变亮
r -= 10
g += 10
if r == 0: #红灯亮度变为零时,跳转到第二阶段
stage = 2
elif stage == 2: #第二阶段,绿灯逐渐变暗,蓝灯逐渐变亮
g -= 10
b += 10
if g == 0: #绿灯亮度变为零时,跳转到第三阶段
stage = 3
elif stage == 3: #第三阶段,蓝灯逐渐变暗,红灯逐渐变亮
b -= 10
r += 10
if b == 0: #蓝灯亮度变为零时,跳转到第一阶段
stage = 1
led_r.duty(r)
led_g.duty(g)
led_b.duty(b)
time.sleep(0.01)
WiFi 连接
AP模式
import network #导入Wlan相关功能
wifi = network.WLAN(network.AP_IF) # 初始化WiFi为AP模式
wifi.config(essid='ESP-AP123',password='12345678') # 设置热点的SSID
wifi.active(True) # 开启WiFi
wifi.isconnected() # 检查当前是否有设备连接
STA 模式
import network
wifi = network.WLAN(network.STA_IF) # 将模块设为STA模式
wifi.active(True) # 开启WIFI
if not wifi.isconnected(): # 如果wifi模块未连接到热点
print('WiFi 连接中...')
wifi.connect('ZTE-706', 'Qwer123456') #连接自己的手机热点
while not wifi.isconnected(): #等待wifi连接
pass
print('WiFi 连接成功' , wifi.ifconfig()) #连接成功
TCP Client 通信
import network
wifi = network.WLAN(network.STA_IF) # 将模块设为STA模式
wifi.active(True) # 开启WIFI
if not wifi.isconnected(): # 如果wifi模块未连接到热点
print('WiFi 连接中...')
wifi.connect('ZTE-706', 'Qwer123456') #连接自己的手机热点
while not wifi.isconnected(): #等待wifi连接
pass
print('WiFi 连接成功' , wifi.ifconfig()) #连接成功
import socket #导入Socket功能模块
try: # Socket连接可能会失败,所以使用try
s = socket.socket() # 建立一个Socket
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) #设置socket参数
s.connect('122.114.122.174',41791) #连接指定TCP服务器
print('TCP Connected ok!!连接成功') # 连接成功
except: # 连接失败
print("TCP 连接失败")
if (s):
s.close()
while True:
data = s.recv(128) #接收到数据
if(len(data) == 0): #数据为零表示Socket被关闭
print("连接关闭")
s.close()
break
print(data) #输出收到的数据
ret=s.send(data) #数据原样发回
TCP Server
import network
wifi = network.WLAN(network.STA_IF) # 将模块设为STA模式
wifi.active(True) # 开启WIFI
if not wifi.isconnected(): # 如果wifi模块未连接到热点
print('WiFi 连接中...')
wifi.connect('ZTE', 'Qwe123456') #连接自己的手机热点
while not wifi.isconnected(): #等待wifi连接
pass
print('WiFi 连接成功' , wifi.ifconfig()) #连接成功
import socket
addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
s = socket.socket()
s.bind(addr)
s.listen(1)
print('TCP开始监听', addr)
while True:
cl,addr = s.accept()
print('client connected from', addr)
while True:
data = cl.recv(1024)
if(len(data) == 0): #无数据关闭Socket
print("Close socket")
s.close()
break
print(data.decode('utf-8'))
cl.send(data) #将数据原样发回
HTTP 请求
import time
import network
from machine import Pin
import network
led_r=Pin(4,Pin.OUT) #create LED object from pin4,Set Pin4 to output
led_r.value(0)
wifi = network.WLAN(network.STA_IF)
wifi.active(True)
if not wifi.isconnected():
print('WiFi 连接中 ...')
wifi.connect('ZTE-706', 'a123456789') #连接你自己手机的热点
while not wifi.isconnected(): #等待wifi连接
pass
print('WiFi 连接成功:', wifi.ifconfig())
import urequests #导入urequests功能模块
# 发起HTTP 请求
r = urequests.get('http://www.weather.com.cn/data/cityinfo/101010100.html')
print(r.status_code) #打印HTTP状态码
print(r.reason) #打印HTTP状态
print(r.content) #打印网页源代码(字节形式)
print(r.text) #打印网页源代码(字符串形式)
MQTT 通信
本实验采用的是免费MQTT服务器: http://tools.emqx.io
8266模块下载simple.py程序
MQTT通信依赖simple.py文件,所以实验前必须下载该文件,步骤如下:
MQTT通信完整源代码:
import time
import network
from machine import Pin
import network
led_r=Pin(4,Pin.OUT) #create LED object from pin4,Set Pin4 to output
led_r.value(0)
wifi = network.WLAN(network.STA_IF)
wifi.active(True)
if not wifi.isconnected():
print('WiFi 连接中 ...')
wifi.connect('ZTE-706', 'a123456789') #连接你自己手机的热点
while not wifi.isconnected(): #等待wifi连接
pass
print('WiFi 连接成功:', wifi.ifconfig())
from simple import MQTTClient # 从Simple 导入MQTT
def mqtt_recv_cb(topic, msg): # MQTT收到消息回调函数
global state
print((topic, msg)) # 打印收到的消息
try:
c = MQTTClient('Client ID自己改', 'aligenie.xuhongv.com') #设置MQTT客户端
c.set_callback(mqtt_recv_cb) #设置回填函数
c.connect() # 连接MQTT服务器
print('MQTT 连接成功')
c.subscribe('xaiot') #订阅主题 xaiot
c.publish('zhang',"dd", retain = True) # 向主题zhang 发送消息 dd
while True: # 无限循环接收消息
c.wait_msg()
finally:
if(c is not None):
c.disconnect() # 断开MQTT的连接
print('MQTT 已关闭')
扩展篇:HTTP 实现网页配网
源代码:
import time
import network
wifi = network.WLAN(network.AP_IF)
wifi.active(True) # 开启WiFi
wifi.config(essid='ESP-AP123',password='12345678') # 设置热点的SSID
html = """<!DOCTYPE html>
<html>
<head> <meta charset="utf-8"> <title>设置wifi密码</title> </head>
<body>
<form name="input" action="setwifi" method="get" text-align="center">
路由器账号: <input type="text" name="ssid"><br>
路由器密码: <input type="text" name="pwd"><br/>
<input type="submit" value="提交">
</form>
</body>
</html>
"""
html_ok = """<!DOCTYPE html>
<html>
<head> <meta charset="utf-8"> <title>设置wifi密码</title> </head>
<body><h1>设置成功</h1></body>
</html>
"""
ssid = '' # 用来存储WiFi账号和密码
pwd = ''
import socket
addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
s = socket.socket()
try:
s.bind(addr)
except:
print("HTTP Server 启动失败,请重启设备!!")
while True:
pass
s.listen(1)
print('listening on', addr)
while True:
cl,addr = s.accept()
print('client connected from', addr)
cl_file = cl.makefile('rwb', 0)
while True:
line = cl_file.readline()
if line.decode('utf-8').find('T /setwifi') > 0:
wifi_data = line.decode('utf-8')
wifi_data = wifi_data.replace('GET /setwifi?ssid=','')
wifi_data = wifi_data.replace('&pwd=',',')
wifi_data = wifi_data.replace(' HTTP/1.1\r\n','')
tmp = wifi_data.split(',')
print(tmp[0],tmp[1])
ssid = tmp[0]
pwd = tmp[1]
print("收到账号密码:",ssid,pwd)
if not line or line == b'\r\n':
break
cl.send('HTTP/1.0 200 OK\r\nContent-type: text/html; charset=UTF-8\r\n\r\n')
if len(ssid) > 0: # 已收到WiFi密码
cl.send(html_ok)
cl.close()
s.close()
break
else:
cl.send(html)
cl.close()
sta = network.WLAN(network.STA_IF) # 将模块设为STA模式
sta.active(True) # 开启WiFi
print('WiFi 连接中...')
sta.connect(ssid, pwd) #连接手机B的手机热点
while not sta.isconnected(): #等待wifi连接
pass
print("WiFi 连接成功" , sta.ifconfig()) #连接成功
参考资料
https://micropython.nxez.com/2018/11/30/getting-started-with-micropython-on-esp32-and-esp8266.html
MicroPython 官网:https://micropython.org/download/esp8266/
MicroPython 文档:http://docs.micropython.org/en/latest/esp8266/quickref.html