视频演示:https://training.eeworld.com.cn/video/38854
代码: https://download.eeworld.com.cn/detail/%E7%99%BD%E6%97%A0%E5%B8%B8120/630311
任务4替换源码链接:https://download.eeworld.com.cn/detail/%E7%99%BD%E6%97%A0%E5%B8%B8120/630355
额外传感器展示代码:https://download.eeworld.com.cn/detail/%E7%99%BD%E6%97%A0%E5%B8%B8120/630354
板卡的使用教程:https://wiki.seeedstudio.com/XIAO_ESP32C3_MicroPython/
本期板卡介绍:基于 Espressif ESP32-C3 Wi-Fi/蓝牙双模芯片的 IoT 迷你开发板。ESP32-C3 是一款32 位 RISC-V CPU,具有强大的计算能力,包含FPU(浮点运算单元),可进行32 位单精度运算。它具有出色的射频性能,支持IEEE 802.11 b/g/n Wi-Fi和蓝牙 5 (LE)协议。正如其名,Seeed Studio XIAO ESP32C3具有小巧精致的外形,还可通过表面贴装整合到更复杂的PCB上。
特性
- 强大的 CPU:ESP32-C3,32 位 RISC-V 单核处理器,运行频率高达 160 MHz
- 完整的WiFi子系统:符合IEEE 802.11b/g/n协议,支持Station模式、SoftAP模式、SoftAP+Station模式、混杂模式
- 蓝牙 LE 子系统:支持蓝牙 5 和蓝牙网状网络的功能
- 超低功耗:深度睡眠功耗约43μA
- 更好的射频性能:可连接外部射频天线
- 电池充电芯片:支持锂电池充放电管理
- 丰富的片上资源:400KB SRAM、4MB板载闪存
- 超小尺寸:小至拇指 (20x17.5mm) XIAO 系列经典外形,适用于可穿戴设备和小型项目
- 可靠的安全功能:支持 AES-128/256、哈希、RSA、HMAC、数字签名和安全启动的加密硬件加速器
- 丰富的接口:1xI2C、1xSPI、2xUART、11xGPIO(PWM)、4xADC、1xJTAG
- 单面元件布局、支持表面贴装设计
板卡的引脚图
板卡的基本布局:包含一个Boot按钮和一个复位按钮,天线接口,Type-C可以用来烧录调试xiao。
SEEED STUDIO EXPANSION BASE XIAO
扩展板简单介绍:
包含OLED显示屏,蜂鸣器,grove接口,电源管理芯片,RTC时钟,用户按钮,MicroSD卡槽
任务1:使用MicroPython系统(必做任务)
任务1主要实现的是板卡microPython固件的烧录和thonny开发软件的连接。
固件下载网址:https://micropython.org/download/ESP32_GENERIC_C3/
这里选取最新的的版本
烧录指令
esptool.exe --chip esp32c3 --port COM8 --baud 921600 --before default_reset --after hard_reset --no-stub write_flash --flash_mode dio --flash_freq 80m 0x0 ESP32_GENERIC_C3-20231005-v1.21.0.bin
等待一段时间后烧录成功
此时连接thonny,选择对应的设备即可说明microPython固件烧录成功。
任务2:驱动扩展板上的OLED屏幕(必做任务)
任务2调用了ssd1306屏幕驱动库,来显示简单的文字描述,较为复杂的显示效果在任务4.
源码如下:
import time
from machine import Pin, SoftI2C
import ssd1306
import math
i2c = SoftI2C(scl=Pin(7), sda=Pin(6)) # Adjust the Pin numbers based on your connections
oled_width = 128
oled_height = 64
oled = ssd1306.SSD1306_I2C(oled_width, oled_height, i2c)
oled.fill(0) # Clear the screen
oled.text("FW3!", 10, 15)
oled.text("task2", 30, 40)
oled.text("GAOZG", 30, 55)
oled.show() # Show the text
效果如下;
任务3:控制蜂鸣器播放音乐(必做任务)
首先驱动蜂鸣器
import time
from time import sleep
import machine
from machine import Pin, SoftI2C
# Buzzer settings
buzzer_pin = machine.Pin(5, machine.Pin.OUT)
buzzer = machine.PWM(buzzer_pin)
buzzer.freq(1047)
# Buzzer working
while True:
buzzer.duty(10)
time.sleep(1)
buzzer.duty(0)
time.sleep(1)
使用不同的频率即可让蜂鸣器发出不同的声音,再加上一段延时即可让蜂鸣器播放一段音乐
这里找到了官网制作的一个加勒比海盗的主题曲:
import machine
import time
# Buzzer settings
buzzer_pin = machine.Pin(5, machine.Pin.OUT)
buzzer = machine.PWM(buzzer_pin)
buzzer.freq(1047)
# Defining frequency of each music note
NOTE_C4 = 262
NOTE_D4 = 294
NOTE_E4 = 330
NOTE_F4 = 349
NOTE_G4 = 392
NOTE_A4 = 440
NOTE_B4 = 494
NOTE_C5 = 523
NOTE_D5 = 587
NOTE_E5 = 659
NOTE_F5 = 698
NOTE_G5 = 784
NOTE_A5 = 880
NOTE_B5 = 988
# Music notes of the song, 0 is a rest/pulse
notes = [
NOTE_E4, NOTE_G4, NOTE_A4, NOTE_A4, 0,
NOTE_A4, NOTE_B4, NOTE_C5, NOTE_C5, 0,
NOTE_C5, NOTE_D5, NOTE_B4, NOTE_B4, 0,
NOTE_A4, NOTE_G4, NOTE_A4, 0,
NOTE_E4, NOTE_G4, NOTE_A4, NOTE_A4, 0,
NOTE_A4, NOTE_B4, NOTE_C5, NOTE_C5, 0,
NOTE_C5, NOTE_D5, NOTE_B4, NOTE_B4, 0,
NOTE_A4, NOTE_G4, NOTE_A4, 0,
NOTE_E4, NOTE_G4, NOTE_A4, NOTE_A4, 0,
NOTE_A4, NOTE_C5, NOTE_D5, NOTE_D5, 0,
NOTE_D5, NOTE_E5, NOTE_F5, NOTE_F5, 0,
NOTE_E5, NOTE_D5, NOTE_E5, NOTE_A4, 0,
NOTE_A4, NOTE_B4, NOTE_C5, NOTE_C5, 0,
NOTE_D5, NOTE_E5, NOTE_A4, 0,
NOTE_A4, NOTE_C5, NOTE_B4, NOTE_B4, 0,
NOTE_C5, NOTE_A4, NOTE_B4, 0,
NOTE_A4, NOTE_A4,
#Repeat of first part
NOTE_A4, NOTE_B4, NOTE_C5, NOTE_C5, 0,
NOTE_C5, NOTE_D5, NOTE_B4, NOTE_B4, 0,
NOTE_A4, NOTE_G4, NOTE_A4, 0,
NOTE_E4, NOTE_G4, NOTE_A4, NOTE_A4, 0,
NOTE_A4, NOTE_B4, NOTE_C5, NOTE_C5, 0,
NOTE_C5, NOTE_D5, NOTE_B4, NOTE_B4, 0,
NOTE_A4, NOTE_G4, NOTE_A4, 0,
NOTE_E4, NOTE_G4, NOTE_A4, NOTE_A4, 0,
NOTE_A4, NOTE_C5, NOTE_D5, NOTE_D5, 0,
NOTE_D5, NOTE_E5, NOTE_F5, NOTE_F5, 0,
NOTE_E5, NOTE_D5, NOTE_E5, NOTE_A4, 0,
NOTE_A4, NOTE_B4, NOTE_C5, NOTE_C5, 0,
NOTE_D5, NOTE_E5, NOTE_A4, 0,
NOTE_A4, NOTE_C5, NOTE_B4, NOTE_B4, 0,
NOTE_C5, NOTE_A4, NOTE_B4, 0,
#End of Repeat
NOTE_E5, 0, 0, NOTE_F5, 0, 0,
NOTE_E5, NOTE_E5, 0, NOTE_G5, 0, NOTE_E5, NOTE_D5, 0, 0,
NOTE_D5, 0, 0, NOTE_C5, 0, 0,
NOTE_B4, NOTE_C5, 0, NOTE_B4, 0, NOTE_A4,
NOTE_E5, 0, 0, NOTE_F5, 0, 0,
NOTE_E5, NOTE_E5, 0, NOTE_G5, 0, NOTE_E5, NOTE_D5, 0, 0,
NOTE_D5, 0, 0, NOTE_C5, 0, 0,
NOTE_B4, NOTE_C5, 0, NOTE_B4, 0, NOTE_A4
]
# Durations (in ms) of each music note of the song
# Quarter Note is 250 ms when songSpeed = 1.0
durations = [
125, 125, 250, 125, 125,
125, 125, 250, 125, 125,
125, 125, 250, 125, 125,
125, 125, 375, 125,
125, 125, 250, 125, 125,
125, 125, 250, 125, 125,
125, 125, 250, 125, 125,
125, 125, 375, 125,
125, 125, 250, 125, 125,
125, 125, 250, 125, 125,
125, 125, 250, 125, 125,
125, 125, 125, 250, 125,
125, 125, 250, 125, 125,
250, 125, 250, 125,
125, 125, 250, 125, 125,
125, 125, 375, 375,
250, 125,
#Rpeat of First Part
125, 125, 250, 125, 125,
125, 125, 250, 125, 125,
125, 125, 375, 125,
125, 125, 250, 125, 125,
125, 125, 250, 125, 125,
125, 125, 250, 125, 125,
125, 125, 375, 125,
125, 125, 250, 125, 125,
125, 125, 250, 125, 125,
125, 125, 250, 125, 125,
125, 125, 125, 250, 125,
125, 125, 250, 125, 125,
250, 125, 250, 125,
125, 125, 250, 125, 125,
125, 125, 375, 375,
#End of Repeat
250, 125, 375, 250, 125, 375,
125, 125, 125, 125, 125, 125, 125, 125, 375,
250, 125, 375, 250, 125, 375,
125, 125, 125, 125, 125, 500,
250, 125, 375, 250, 125, 375,
125, 125, 125, 125, 125, 125, 125, 125, 375,
250, 125, 375, 250, 125, 375,
125, 125, 125, 125, 125, 500
]
def play_song():
total_notes = len(notes)
for i in range(total_notes):
current_note = notes[i]
wait = durations[i]
if current_note != 0:
buzzer.duty(512) # Set duty cycle for sound
buzzer.freq(current_note) # Set frequency of the note
else:
buzzer.duty(0) # Turn off the sound
time.sleep_ms(wait)
buzzer.duty(0) # Turn off the sound
while True:
# Play the song
play_song()
任务4:连接WiFi网络(必做任务)
本任务使用了network,urequests,ujson等内置库来获取网络时间并在ssd1206上面显示。
程序调用了network库来实现上网功能,此时板卡可以连接到2.4GHz无线网络,然后使用urequests库来实现数据请求,本次使用的是worldtimeapi.org网站免费的api,可以在该网站的Q&A中找到使用说明,选择对应的城市拼接好API,然后在游览器中打开请求,即可看到我们需要的数据,然后使用ujson库来解析提取我们需要的信息,展示在屏幕上即可完成任务4.
from machine import Pin, SoftI2C
import ssd1306
from time import sleep
import time
import network
import urequests
import ujson
# ESP32 Pin assignment
# i2c = SoftI2C(scl=Pin(22), sda=Pin(21))
oled_width = 128
oled_height = 64
oled = ssd1306.SSD1306_I2C(oled_width, oled_height, i2c)
station = network.WLAN(network.STA_IF)
station.active(True)
# Network settings
wifi_ssid = "xghdb"
wifi_password = "aa15222531066"
url = "http://worldtimeapi.org/api/timezone/Asia/Shanghai"
print("Scanning for WiFi networks, please wait...")
authmodes = ['Open', 'WEP', 'WPA-PSK' 'WPA2-PSK4', 'WPA/WPA2-PSK']
for (ssid, bssid, channel, RSSI, authmode, hidden) in station.scan():
print("* {:s}".format(ssid))
print(" - Channel: {}".format(channel))
print(" - RSSI: {}".format(RSSI))
print(" - BSSID: {:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}".format(*bssid))
print()
# Continually try to connect to WiFi access point
while not station.isconnected():
# Try to connect to WiFi access point
print("Connecting...")
station.connect(wifi_ssid, wifi_password)
time.sleep(10)
# Display connection details
print("Connected!")
print("My IP Address:", station.ifconfig()[0])
while True:
# Perform HTTP GET request on a non-SSL web
response = urequests.get(url)
# Check if the request was successful
if response.status_code == 200:
# Parse the JSON response
data = ujson.loads(response.text)
# Extract the "datetime" field for New York
ny_datetime = data["datetime"]
# Split the date and time components
date_part, time_part = ny_datetime.split("T")
# Get only the first two decimal places of the time
time_part = time_part[:8]
# Get the timezone
timezone = data["timezone"]
# Clear the OLED display
oled.fill(0)
# Display the New York date and time on separate lines
oled.text("Shanghai Date:", 0, 0)
oled.text(date_part, 0, 10)
oled.text("Shanghai Time:", 0, 20)
oled.text(time_part, 0, 30)
oled.text("Timezone:", 0, 40)
oled.text(timezone, 0, 50)
# Update the display
oled.show()
else:
oled.text("Failed to get the time for Beijing!")
# Update the display
oled.show()
效果如下:
任务5:使用外部传感器(必做任务)
光传感器:https://wiki.seeedstudio.com/Grove-Light_Sensor/
Grove - Light 传感器集成了一个光敏电阻器(光敏电阻器)来检测光的强度。光敏电阻的电阻随着光强度的增加而减小。板载双运算放大器芯片 LM358 产生与光强度相对应的电压(即基于电阻值)。输出信号为模拟值,光线越亮,数值越大。将获得的这个电压值采集到板卡模拟脚后即可换算出对应的值。这里调用ADC库
from machine import ADC
from time import sleep
from machine import Pin, SoftI2C
import ssd1306
i2c = SoftI2C(scl=Pin(7), sda=Pin(6)) # Adjust the Pin numbers based on your connections
oled_width = 128
oled_height = 64
oled = ssd1306.SSD1306_I2C(oled_width, oled_height, i2c)
adc = ADC(2, atten=ADC.ATTN_11DB)
while True:
light_adc = adc.read()
light_uv = adc.read_uv()
print(f'light_adc={light_adc},{light_uv/1000:.0f}mv')
oled.fill(0)
oled.text(f'adc={light_adc}', 0, 15)
oled.text(f'{light_uv/1000:.0f}mV',0,30)
oled.show()
sleep(0.5)
显示效果如下:
AHT20 温湿度传感器
AHT20产品官网链接:https://wiki.seeedstudio.com/Grove-AHT20-I2C-Industrial-Grade-Temperature&Humidity-Sensor/
下载ahtx0库,接好模块后,直接调用AHT20库即可读取温湿度值
下面是显示的代码
from machine import ADC
from time import sleep
from machine import Pin, SoftI2C
import ssd1306
from ahtx0 import AHT20
i2c = SoftI2C(scl=Pin(7), sda=Pin(6)) # Adjust the Pin numbers based on your connections
oled_width = 128
oled_height = 64
aht20 = AHT20(i2c)
oled = ssd1306.SSD1306_I2C(oled_width, oled_height, i2c)
while True:
temp = aht20.temperature
humi = aht20.relative_humidity
print(f'temp={temp},humi={humi}')
oled.fill(0)
oled.text(f'temp={temp:0.1f}C', 0, 15)
oled.text(f'humi={humi:0.1f}%', 0, 30)
oled.show()
sleep(0.5)
显示效果如下:
其他购买的模块测试:
待补充
对本次活动的心得体会
感谢得捷和eeword的活动,让我有机会体验ESP32-C3 XIAO的开发,希望活动能继续办下去。
本次活动学习了microPython基础语法,学会了一些简单外设的驱动,学会了如何编译下载程序,如何点亮一块OLED屏幕,也学习了如何使用开源库来完成项目,多学习借鉴代码对自己项目的完成有很大的帮助。最后祝活动越办越好。
|