开始之前
请认真阅读以下内容 http://www.1zlab.com/wiki/micropython-esp32/
一、准本工作
面包板、电源、ESP32、HT22、一大把面包线 、还有一颗勇往无前的心 ✿
二、ESP32刷写系统
1、开发环境介绍
ESP32支持的开发环境较多,列举部分如下,本文以Micro Python为开发语言。
Native C,官方提供的方案,可以选择裸机或者 FreeRTOS 进行开发;
Arduino,官方支持,使用 Arduino IDE 即可进行开发;
Python 固件,第三方支持,使用 MicroPython 进行开发;
nodemcu 固件,社区支持,使用 Lua 进行开发;
Espruino 固件,社区支持,使用 JavaScript 进行开发;
2、安装Python、esptool
下载python,安装后进入cmd
执行pip install esptool
安装esptool;pip install adafruit-ampy
安装ampy文件上传工具。
3、下载适合ESP32的Micro Python固件并完成烧录
在这里下载适合的固件,选择GENERIC对应最新版本,本文使用的是 GENERIC : esp32-idf3-20191220-v1.12.bin
CP210xUSB驱动 选择符合当前操作系统的版本; PUTTY 后续连接ESP32用。
通过开始之前的链接 相信你已经解决了ESP32连接电脑的问题,cmd执行 esptool.py --port COM3 erase_flash
擦除flash; esptool.py --chip esp32 --port COM3 write_flash -z 0x1000 C:\esp32-idf3-20191220-v1.12.bin
刷入flash。
4、接入WiFi为开发做准备
首先通过putty连接到ESP32,选择serial 波特率115200 端口COM3,连接后如下图:
执行以下代码连接WiFi:
>>> import network # 导入network模块
>>> wifi = network.WLAN(network.STA_IF) # 设置为STA_IF模式,即接入wifi路由器的模式,AP_IF为热点模式
>>> wifi.active(True) # 将wifi激活
>>> wifi.connect('Mr.Han','1234500890') #连接至wifi
安装EMP模块:
>>> import upip
I (240305) modsocket: Initializing
>>> upip.install('emp-1zlab')
Installing to: /lib/
Warning: micropython.org SSL certificate is not validated
Installing emp-1zlab 0.2.7 from https://files.pythonhosted.org/packages/78/84/a15769640950d1f0afd7759e61a1696f201b00dbbf32d5747c2d8fa633db/emp-1zlab-0.2.7.tar.gz
>>>
设置启动模式,注意:该操作会覆盖boot.py中的所有内容
>>> from emp_boot import set_boot_mode
>>> set_boot_mode()
[0] Boot with nothing
attention: this option will clear up boot.py, careful!
[1] Boot with wifi startup
this mode will auto start wifi connect program.
[2] Easy to develop
this mode is for developers.In this mode you can develop much easier via EMP-IDE(emp.1zlab.com)
Please input your choice [0-2]:
#选择2
参考文章:MicroPython-ESP32之更合理的建立wifi连接-1Z实验室How
摘抄文章内部分连接WiFi代码如下:
def do_connect():
import json
import network
# 尝试读取配置文件wifi_confi.json,这里我们以json的方式来存储WIFI配置
# wifi_config.json在根目录下
# 若不是初次运行,则将文件中的内容读取并加载到字典变量 config
try:
with open('wifi_config.json','r') as f:
config = json.loads(f.read())
# 若初次运行,则将进入excpet,执行配置文件的创建
except:
essid = input('wifi name:') # 输入essid
password = input('wifi passwrod:') # 输入password
config = dict(essid=essid, password=password) # 创建字典
with open('wifi_config.json','w') as f:
f.write(json.dumps(config)) # 将字典序列化为json字符串,存入wifi_config.json
#以下为正常的WIFI连接流程
wifi = network.WLAN(network.STA_IF)
if not wifi.isconnected():
print('connecting to network...')
wifi.active(True)
wifi.connect(config['essid'], config['password'])
while not wifi.isconnected():
pass
print('network config:', wifi.ifconfig())
if __name__ == '__main__':
do_connect()
import sys
# 添加路径
sys.path.append('examples')
def is_legal_wifi(essid, password):
'''
判断WIFI密码是否合法
'''
if len(essid) == 0 or len(password) == 0:
return False
return True
def do_connect():
import json
import network
# 尝试读取配置文件wifi_confi.json,这里我们以json的方式来存储WIFI配置
# wifi_config.json在根目录下
# 若不是初次运行,则将文件中的内容读取并加载到字典变量 config
try:
with open('wifi_config.json','r') as f:
config = json.loads(f.read())
# 若初次运行,则将进入excpet,执行配置文件的创建
except:
essid = ''
password = ''
while True:
essid = input('wifi name:') # 输入essid
password = input('wifi passwrod:') # 输入password
if is_legal_wifi(essid, password):
config = dict(essid=essid, password=password) # 创建字典
with open('wifi_config.json','w') as f:
f.write(json.dumps(config)) # 将字典序列化为json字符串,存入wifi_config.json
break
else:
print('ERROR, Please Input Right WIFI')
#以下为正常的WIFI连接流程
wifi = network.WLAN(network.STA_IF)
if not wifi.isconnected():
print('connecting to network...')
wifi.active(True)
wifi.connect(config['essid'], config['password'])
import utime
for i in range(200):
print('第{}次尝试连接WIFI热点'.format(i))
if wifi.isconnected():
break
utime.sleep_ms(100) #一般睡个5-10秒,应该绰绰有余
if not wifi.isconnected():
wifi.active(False) #关掉连接,免得repl死循环输出
print('wifi connection error, please reconnect')
import os
# 连续输错essid和password会导致wifi_config.json不存在
try:
os.remove('wifi_config.json') # 删除配置文件
except:
pass
do_connect() # 重新连接
else:
print('network config:', wifi.ifconfig())
if __name__ == '__main__':
do_connect()
5、GPIO针脚分布及介绍
ESP32使用Micro Python 开发时GPIO引脚定义如上图,参考来源1Zlab。由于封装原因并不是所有的引脚都引出。
功能简介 | 缩写 | 可用的GPIO编号 | 备注 |
---|---|---|---|
模拟信号采样 | ADC | 32, 33, 34, 35, 36, 39 | |
模拟信号输出 | DAC | 25, 26 | |
串行通信 | UART | 1(TX0),3(RX0), 10(TX1),9(RX1) ,17(TX2),16(RX2) | 共三组 |
探测由手指或其他物品直接接触或接近而产生的电容差异 | TOUCHPAD | 0, 2, 4, 12, 13, 14, 15, 27, 32, 33 | |
SPI总线接口 | SPI | hspi(14,12,13,15) vspi(23,19,18,5) | |
I2C总线接口 | I2C | SDA(21) SCL(22) | MicroPython并未实现硬件的I2C |
6、连接ESP32、1306OLED、DHT22
根据GPIO引脚定义,OLED屏幕I2C连线如下
I2COLED:VCC -----> 3V3 ;GND -----> GND ;SCL -----> GPIO22;SDA -----> GPIO23
DHT22:+ -----> 3V3 ;- -----> GND ;Data -----> GPIO21
接口位置在规范下是可以随意使用的,只需要在程序中做对应改动就可以了。
7、驱动OLED
目前淘宝上0.96英寸的oled基本上都是ssd1306芯片,部分1.3寸oled屏是sh1106芯片。
通过EMPIDE(推荐)或者ampy把文件上传到ESP32,需要注意的是ampy上传文件的时候需要提前断开putty和ESP32的连接,因为COM口同一时间只能有一个程序占用。
I、把以下三个驱动文件上传到ESP32
ssd1306.py 、 sh1106.py 、 dht.py
ampy --port COM3 put C:\ssd1306.py
ampy --port COM3 put C:\sh1106.py
ampy --port COM3 put C:\dht.py
# ampy put上传、run运行、rm删除、终端查看文件内容 print(open('main.py').read()) 列出目录内容 os.listdir()
II、编写驱动程序
#I2C SH1106 OLED
from sh1106 import SH1106_I2C
from machine import Pin, I2C
i2c = I2C(scl=Pin(22), sda=Pin(23),freq=100000)
oled = SH1106_I2C(128, 64, i2c)
oled.line(0,32,128,32,1)
oled.text('Hello',36,2)
oled.text('Micropython',24,54)
oled.show()
#I2C SSD1306 OLED
from machine import Pin,I2C
from ssd1306 import SSD1306_I2C
i2c = I2C(scl=Pin(22), sda=Pin(23),freq=100000)
oled = SSD1306_I2C(128, 64, i2c)
oled.text('Hello',36,2)
oled.text('Micropython',24,54)
oled.show()
OLED购买前需要和卖家核对驱动芯片是SH1106还是SSD1306。同时OLED有I2C和SPI模式,区分就是一个四线一个七线。
8、驱动DHT22
dht22也被称为AM2302是一款具有标准单总线接口,含有已校准数字信号输出的温湿度复合传感器。
得益于Python的精简,驱动起来异常简单
import dht
import machine
from machine import Pin
from dht import DHT22
d = dht.DHT22(machine.Pin(21))
d.measure()
print("temperature:",d.temperature())
print("humidity:",d.humidity())
9、整合各系统完成最终产品
#main.py
import time
import dht
import machine
from sh1106 import SH1106_I2C
from machine import Pin, I2C
from dht import DHT22
i2c = I2C(scl=Pin(22), sda=Pin(23),freq=100000)
d = dht.DHT22(machine.Pin(21))
oled = SH1106_I2C(128, 64, i2c)
while True:
d.measure()
temp_ = str(d.temperature())
hum_ = str(d.humidity())
oled.text('temp:'+ temp_ +'C',10,2)
oled.line(0,32,128,32,1)
oled.text('hum:'+ hum_ +'%',10,18)
oled.text('--Rc4x',80,50)
oled.show()
time.sleep(10)
oled.fill(0)
oled.show()
ESP32启动时会先从boot.py引导然后启动main.py,用户程序可以放到main.py
嗯、下雨了。