简 介: ※对于购买自网络的基于
ESP8266
的实验模块进行了初步的测试,它其中的一些示例进行了练习。特别是对于基于ESP8266
的特殊的一些外设的测试。
关键词
:ESP8266,MicroPython
§01esp8266模块
一、背景介绍
从TB购买到乐鑫esp8266模块MicroPython开发板MQTT物联网人工智能最小系统。下面对于它进行初步测试。
1、模块套件
模块的套件包括主板以及I2C
的OLED
显示模块。
▲ 图1.1.1 购买到的模块
(1)资料下载
▲ 图1.1.2 与销售商的对话
hi
,这是我用百度网盘分享的文件~
复制这段内容打开「百度网盘」APP
即可获取。
链接: /s/1hA-FbQrO2pdcm-idR7OpEw提取码:6666
(2)下载目录
1.MicroPython之LED闪烁2.MicroPython之按键3.MicroPython之外部中断4.MicroPython之定时器5.MicroPython之I2C总线OLED显示屏6. MicroPython之RTC实时时钟7. MicroPython之ADC8.MicroPython之PWM呼吸灯9.MicroPython之连接无线路由器10.MicroPython之Socket通信12.MicroPython之开源项目8266动画animation_on_esp8266CH340_341驱动MicroPython视频教程python基本方法.docx动画演示.mp4技术交流群.txt开发板原理图.pdf专用播放器解压密码123456.rar
2、接入USB
可以看到模块上面使用CH340
作为USB-UART
转接。接入电脑后可以看到电脑设备中出现 虚拟串口。
▲ 图1.1.3 电脑中的USB虚拟串口
3、电路板原理图
▲ 图1.1.4 核心板管脚定义
▲ 图1.1.5 按键与电源
▲ 图1.1.6 USB 与下载电路
二、调试MicroPython
基于串口REPL
可以对ESP8266
模块进行MicroPython
编程。REPL
的操作界面使用STM32Bootloader
。 对于STM32Bootloader
网络命令MPDLD
进行改造。在下载MicroPython
程序之前通过发送Ctrl+C(0x3)
使得程序从前执行程序中返回。
1、Help()信息
MicroPython v1.11-8-g48dcbbe60 on -05-29; ESP module with ESP8266Type "help()" for more information.>>> help()Welcome to MicroPython!For online docs please visit /en/latest/esp8266/ .For diagnostic information to include in bug reports execute 'import port_diag'.Basic WiFi configuration:import networksta_if = network.WLAN(network.STA_IF); sta_if.active(True)sta_if.scan() # Scan for available access pointssta_if.connect("<AP_name>", "<password>") # Connect to an APsta_if.isconnected() # Check for successful connection# Change name/password of ESP8266's AP:ap_if = network.WLAN(network.AP_IF)ap_if.config(essid="<AP_NAME>", authmode=network.AUTH_WPA_WPA2_PSK, password="<password>")Control commands:CTRL-A -- on a blank line, enter raw REPL modeCTRL-B -- on a blank line, enter normal REPL modeCTRL-C -- interrupt a running programCTRL-D -- on a blank line, do a soft reset of the boardCTRL-E -- on a blank line, enter paste modeFor further help on a specific object, type help(obj)>>>
2、基本程序
from machineimport Pinimport timewhile True:print("Hello.")time.sleep_ms(200)
程序下载之后,在串口的REPL
中重复显示:“hello
”
§02基础测试
一、基础测试
1、测试LED
(1)测试代码
from machineimport Pinimport timeled = Pin(2, Pin.OUT)while True:led(1)time.sleep(0.5)led(0)time.sleep(0.5)
(2)结果
▲ 图2.1.1 LED闪烁
2、测试按键
(1)测试代码
电路板上有两个按钮:KEY1
:GPIO0
,KEY2
:GPIO14
from machineimport Pinimport timeled = Pin(2, Pin.OUT)key = Pin(0, Pin.IN, Pin.PULL_UP)state = 1print("Press key to change LED state....")while True:if key.value() == 0:time.sleep_ms(10)if key.value() == 0:state = not stateled(state)while not key.value():pass
(2)测试结果
▲ 图2.1.2 测试按键结果
将上面的key
定义修改成:
key = Pin(14, Pin.IN, Pin.PULL_UP)
可以使用另外一个按钮来切换LED的状态。
3、测试外部重点
(1)测试代码
from machineimport Pinimport timeled = Pin(2, Pin.OUT)key = Pin(14, Pin.IN, Pin.PULL_UP)state = 1print("Press key to change LED state....")def fun(key):global statetime.sleep_ms(10)if key.value() == 0:state = not stateled.value(state)key.irq(fun, Pin.IRQ_FALLING)
(2)测试结果
按动KEY2
可以切换LED
状态。
▲ 图2.1.3 按动KEY2可以切换LED状态
4、测试定时器
from machineimport Pin,Timerimport timeled = Pin(2, Pin.OUT)count = 1print("Change LED state....")def fun(tim):global countcount += 4print(count)led.value(count%2)tim = Timer(-1)tim.init(period=500, mode=Timer.PERIODIC, callback=fun)
周期输出打印的字符。
5、测试OLED
▲ 图2.1.4 OLED与ESP8266连接关系
(1)测试代码
from machineimport Pin,Timer,I2Cimport timefrom micropython import constimport framebufSET_CONTRAST = const(0x81)SET_ENTIRE_ON = const(0xa4)SET_NORM_INV = const(0xa6)SET_DISP = const(0xae)SET_MEM_ADDR = const(0x20)SET_COL_ADDR = const(0x21)SET_PAGE_ADDR = const(0x22)SET_DISP_START_LINE = const(0x40)SET_SEG_REMAP = const(0xa0)SET_MUX_RATIO = const(0xa8)SET_COM_OUT_DIR= const(0xc0)SET_DISP_OFFSET= const(0xd3)SET_COM_PIN_CFG= const(0xda)SET_DISP_CLK_DIV = const(0xd5)SET_PRECHARGE = const(0xd9)SET_VCOM_DESEL= const(0xdb)SET_CHARGE_PUMP= const(0x8d)class SSD1306(framebuf.FrameBuffer):def __init__(self, width, height, external_vcc):self.width = widthself.height = heightself.external_vcc = external_vccself.pages = self.height // 8self.buffer = bytearray(self.pages * self.width)super().__init__(self.buffer, self.width, self.height, framebuf.MONO_VLSB)self.init_display()def init_display(self):for cmd in (SET_DISP | 0x00, # offSET_MEM_ADDR, 0x00, # horizontalSET_DISP_START_LINE | 0x00,SET_SEG_REMAP | 0x01, # column addr 127 mapped to SEG0SET_MUX_RATIO, self.height - 1,SET_COM_OUT_DIR | 0x08, # scan from COM[N] to COM0SET_DISP_OFFSET, 0x00,SET_COM_PIN_CFG, 0x02 if self.height == 32 else 0x12,SET_DISP_CLK_DIV, 0x80,SET_PRECHARGE, 0x22 if self.external_vcc else 0xf1,SET_VCOM_DESEL, 0x30, # 0.83*VccSET_CONTRAST, 0xff, # maximumSET_ENTIRE_ON, # output follows RAM contentsSET_NORM_INV, # not invertedSET_CHARGE_PUMP, 0x10 if self.external_vcc else 0x14,SET_DISP | 0x01): # onself.write_cmd(cmd)self.fill(0)self.show()def poweroff(self):self.write_cmd(SET_DISP | 0x00)def poweron(self):self.write_cmd(SET_DISP | 0x01)def contrast(self, contrast):self.write_cmd(SET_CONTRAST)self.write_cmd(contrast)def invert(self, invert):self.write_cmd(SET_NORM_INV | (invert & 1))def show(self):x0 = 0x1 = self.width - 1if self.width == 64:x0 += 32x1 += 32self.write_cmd(SET_COL_ADDR)self.write_cmd(x0)self.write_cmd(x1)self.write_cmd(SET_PAGE_ADDR)self.write_cmd(0)self.write_cmd(self.pages - 1)self.write_data(self.buffer)class SSD1306_I2C(SSD1306):def __init__(self, width, height, i2c, addr=0x3c, external_vcc=False):self.i2c = i2cself.addr = addrself.temp = bytearray(2)super().__init__(width, height, external_vcc)def write_cmd(self, cmd):self.temp[0] = 0x80 # Co=1, D/C#=0self.temp[1] = cmdself.i2c.writeto(self.addr, self.temp)def write_data(self, buf):self.temp[0] = self.addr << 1self.temp[1] = 0x40 # Co=0, D/C#=1self.i2c.start()self.i2c.write(self.temp)self.i2c.write(buf)self.i2c.stop()class SSD1306_SPI(SSD1306):def __init__(self, width, height, spi, dc, res, cs, external_vcc=False):self.rate = 10 * 1024 * 1024dc.init(dc.OUT, value=0)res.init(res.OUT, value=0)cs.init(cs.OUT, value=1)self.spi = spiself.dc = dcself.res = resself.cs = csimport timeself.res(1)time.sleep_ms(1)self.res(0)time.sleep_ms(10)self.res(1)super().__init__(width, height, external_vcc)def write_cmd(self, cmd):self.spi.init(baudrate=self.rate, polarity=0, phase=0)self.cs(1)self.dc(0)self.cs(0)self.spi.write(bytearray([cmd]))self.cs(1)def write_data(self, buf):self.spi.init(baudrate=self.rate, polarity=0, phase=0)self.cs(1)self.dc(1)self.cs(0)self.spi.write(buf)self.cs(1)i2c = I2C(sda=Pin(2), scl=Pin(14))oled = SSD1306_I2C(128, 64, i2c, addr=0x3c)oled.text('Hello world!', 0, 0)oled.text('OLED test', 0, 50)oled. show()
(2)测试结果
▲ /显示结果
6、测试PWM
from machineimport Pin,PWMimport timeimport mathled = PWM(Pin(2), freq=100)def pulse(l, t):for i in range(20):l.duty(int(math.sin(i/10*math.pi) * 500 + 500))time.sleep_ms(t)for i in range(10):pulse(led, 30)
▲ 图2.1.6 利用PWM形成呼吸灯
§03快速参考
通用方法
machine
类库:
import machinemachine.freq()# get the current frequency of the CPUmachine.freq(160000000) # set the CPU frequency to 160 MHz
esp类库:
import espesp.osdebug(None) # turn off vendor O/S debugging messagesesp.osdebug(0)# redirect vendor O/S debugging messages to UART(0)
联网
network类库:
import networkwlan = network.WLAN(network.STA_IF) # create station interfacewlan.active(True) # activate the interfacewlan.scan() # scan for access pointswlan.isconnected()# check if the station is connected to an APwlan.connect('essid', 'password') # connect to an APwlan.config('mac')# get the interface's MAC adddresswlan.ifconfig() # get the interface's IP/netmask/gw/DNS addressesap = network.WLAN(network.AP_IF) # create access-point interfaceap.active(True) # activate the interfaceap.config(essid='ESP-AP') # set the ESSID of the access point
连接到本地WiFi网络:
def do_connect():import networkwlan = network.WLAN(network.STA_IF)wlan.active(True)if not wlan.isconnected():print('connecting to network...')wlan.connect('essid', 'password')while not wlan.isconnected():passprint('network config:', wlan.ifconfig())
延迟和时间
time 类库
import timetime.sleep(1) # sleep for 1 secondtime.sleep_ms(500)# sleep for 500 millisecondstime.sleep_us(10) # sleep for 10 microsecondsstart = time.ticks_ms() # get millisecond counterdelta = time.ticks_diff(time.ticks_ms(), start) # compute time difference
计时器
mport timetime.sleep(1) # sleep for 1 secondtime.sleep_ms(500)# sleep for 500 millisecondstime.sleep_us(10) # sleep for 10 microsecondsstart = time.ticks_ms() # get millisecond counterdelta = time.ticks_diff(time.ticks_ms(), start) # compute time difference
引脚和GPIO
使用machine.Pin类库:
from machine import Pinp0 = Pin(0, Pin.OUT) # create output pin on GPIO0p0.high()# set pin to highp0.low()# set pin to lowp0.value(1) # set pin to highp2 = Pin(2, Pin.IN)# create input pin on GPIO2print(p2.value()) # get value, 0 or 1p4 = Pin(4, Pin.IN, Pin.PULL_UP) # enable internal pull-up resistorp5 = Pin(5, Pin.OUT, value=1) # set pin high on creation
可用引脚为:0,1,2,3,4,5,12,13,14,15,16,其对应于ESP8266芯片的实际GPIO引脚号。请注意,许多终端用户板使用自己的adhoc引脚编号(标记为D0,D1,…)。由于MicroPython支持不同的单板和模块,所以选择物理引脚编号作为最低的公分母。对于逻辑引脚和物理芯片引脚之间的映射,请参阅电路板文档。
注意,引脚(1)和引脚(3)分别是REPL UART TX和RX。还要注意,Pin(16)是一个特殊的引脚(用于从深睡眠模式唤醒),可能不适用于更高级别的类 Neopixel。
PWM(脉宽调制)
除引脚(16)外的所有引脚都可以使能PWM。所有通道都有一个频率,范围介于1到1000(以Hz为单位)。占空比介于0和1023之间。
使用machine.PWM类:
from machine import Pin, PWMpwm0 = PWM(Pin(0))# create PWM object from a pinpwm0.freq() # get current frequencypwm0.freq(1000) # set frequencypwm0.duty() # get current duty cyclepwm0.duty(200)# set duty cyclepwm0.deinit() # turn off PWM on the pinpwm2 = PWM(Pin(2), freq=500, duty=512) # create and configure in one go
ADC(模数转换)
ADC在专用引脚上可用。请注意,ADC引脚上的输入电压必须在0v和1.0v之间。
使用machine.ADC类:
from machine import ADCadc = ADC(0) # create ADC object on ADC pinadc.read() # read value, 0-1024
SPI总线
有两个SPI驱动程序。一个在软件(bit-banging)中实现,并可在所有引脚上工作:
from machine import Pin, SPI# construct an SPI bus on the given pins# polarity is the idle state of SCK# phase=0 means sample on the first edge of SCK, phase=1 means the secondspi = SPI(-1, baudrate=100000, polarity=1, phase=0, sck=Pin(0), mosi=Pin(2), miso=Pin(4))spi.init(baudrate=200000) # set the baudratespi.read(10) # read 10 bytes on MISOspi.read(10, 0xff)# read 10 bytes while outputing 0xff on MOSIbuf = bytearray(50)# create a bufferspi.readinto(buf) # read into the given buffer (reads 50 bytes in this case)spi.readinto(buf, 0xff) # read into the given buffer and output 0xff on MOSIspi.write(b'12345')# write 5 bytes on MOSIbuf = bytearray(4)# create a bufferspi.write_readinto(b'1234', buf) # write to MOSI and read from MISO into the bufferspi.write_readinto(buf, buf) # write buf to MOSI and read MISO back into buf
硬件SPI更快(高达80Mhz),但仅适用于以下引脚: MISOGPIO12 MOSI是GPIO13,SCK是GPIO14。它具有与上述bitbanging SPI类相同的方法,除了构造函数和init的引脚参数(正如固定的那样):
from machine import Pin, SPIhspi = SPI(1, baudrate=80000000, polarity=0, phase=0)
I2C总线
I2C驱动程序通过以下程序来实现,并可在TPYBoard v202所有引脚上工作:
from machine import Pin, I2C # construct an I2C busi2c = I2C(scl=Pin(5), sda=Pin(4), freq=100000)i2c.readfrom(0x3a, 4) # read 4 bytes from slave device with address 0x3ai2c.writeto(0x3a, '12') # write '12' to slave device with address 0x3abuf = bytearray(10)# create a buffer with 10 bytesi2c.writeto(0x3a, buf) # write the given buffer to the slave
深度睡眠模式
将GPIO16连接到复位引脚(HUZZAH上的RST)。可以使用以下代码进行睡眠,唤醒并检查复位原因:
import machine# configure RTC.ALARM0 to be able to wake the devicertc = machine.RTC()rtc.irq(trigger=rtc.ALARM0, wake=machine.DEEPSLEEP)# check if the device woke from a deep sleepif machine.reset_cause() == machine.DEEPSLEEP_RESET:print('woke from a deep sleep')# set RTC.ALARM0 to fire after 10 seconds (waking the device)rtc.alarm(rtc.ALARM0, 10000)# put the device to sleepmachine.deepsleep()
OneWire驱动
OneWire驱动程序通过以下程序实现,并可在TPYBoard v202所有引脚上工作:
from machine import Pinimport onewireow = onewire.OneWire(Pin(12)) # create a OneWire bus on GPIO12ow.scan()# return a list of devices on the busow.reset() # reset the busow.readbyte() # read a byteow.writebyte(0x12)# write a byte on the busow.write('123') # write bytes on the busow.select_rom(b'12345678') # select a specific device by its ROM code
DS18S20和DS18B20的驱动程序:
import time, ds18x20ds = ds18x20.DS18X20(ow)roms = ds.scan()ds.convert_temp()time.sleep_ms(750)for rom in roms:print(ds.read_temp(rom))
确保在数据线上放置4.7k的上拉电阻。请注意,convert_temp()每次要采样温度时都必须调用该方法。
NeoPixel驱动
使用neopixel类库:
from machine import Pinfrom neopixel import NeoPixelpin = Pin(0, Pin.OUT) # set GPIO0 to output to drive NeoPixelsnp = NeoPixel(pin, 8) # create NeoPixel driver on GPIO0 for 8 pixelsnp[0] = (255, 255, 255) # set the first pixel to whitenp.write() # write data to all pixelsr, g, b = np[0] # get first pixel colour
对于NeoPixel的入门使用:
import espesp.neopixel_write(pin, grb_buf, is800khz)
APA102驱动
使用apa102类库:
from machine import Pinfrom apa102 import APA102clock = Pin(14, Pin.OUT)# set GPIO14 to output to drive the clockdata = Pin(13, Pin.OUT)# set GPIO13 to output to drive the dataapa = APA102(clock, data, 8) # create APA102 driver on the clock and the data pin for 8 pixelsapa[0] = (255, 255, 255, 31) # set the first pixel to white with a maximum brightness of 31apa.write() # write data to all pixelsr, g, b, brightness = apa[0] # get first pixel colour
对于APA102的入门使用:
import espesp.apa102_write(clock_pin, data_pin, rgbi_buf)
DHT驱动
DHT驱动程序通过以下代码实现,并可在TPYBoard v202所有引脚上工作:
import dhtimport machined = dht.DHT11(machine.Pin(4))d.measure()d.temperature() # eg. 23 (째C)d.humidity() # eg. 41 (% RH)d = dht.DHT22(machine.Pin(4))d.measure()d.temperature() # eg. 23.6 (째C)d.humidity() # eg. 41.3 (% RH)
※ 测试总结 ※
对于购买自网络的基于ESP8266的实验模块进行了初步的测试,它其中的一些示例进行了练习。特别是对于基于ESP8266的特殊的一些外设的测试。
■ 相关文献链接:
乐鑫esp8266模块MicroPython开发板MQTT物联网人工智能最小系统
● 相关图表链接:
图1.1.1 购买到的模块图1.1.2 与销售商的对话图1.1.3 电脑中的USB虚拟串口图1.1.4 核心板管脚定义图1.1.5 按键与电源图1.1.6 USB 与下载电路图2.1.1 LED闪烁图2.1.2 测试按键结果图2.1.3 按动KEY2可以切换LED状态图2.1.4 OLED与ESP8266连接关系/显示结果图2.1.6 利用PWM形成呼吸灯