NipGeihou's blog NipGeihou's blog
  • Java

    • 开发规范
    • 进阶笔记
    • 微服务
    • 快速开始
    • 设计模式
  • 其他

    • Golang
    • Python
    • Drat
  • Redis
  • MongoDB
  • 数据结构与算法
  • 计算机网络
  • 应用

    • Grafana
    • Prometheus
  • 容器与编排

    • KubeSphere
    • Kubernetes
    • Docker Compose
    • Docker
  • 组网

    • TailScale
    • WireGuard
  • 密码生成器
  • 英文单词生成器
🍳烹饪
🧑‍💻关于
  • 分类
  • 标签
  • 归档

NipGeihou

我见青山多妩媚,料青山见我应如是
  • Java

    • 开发规范
    • 进阶笔记
    • 微服务
    • 快速开始
    • 设计模式
  • 其他

    • Golang
    • Python
    • Drat
  • Redis
  • MongoDB
  • 数据结构与算法
  • 计算机网络
  • 应用

    • Grafana
    • Prometheus
  • 容器与编排

    • KubeSphere
    • Kubernetes
    • Docker Compose
    • Docker
  • 组网

    • TailScale
    • WireGuard
  • 密码生成器
  • 英文单词生成器
🍳烹饪
🧑‍💻关于
  • 分类
  • 标签
  • 归档
  • 资料

  • 笔记

    • 嵌入式工具
    • 电池

    • 从墨水屏项目中学习嵌入式
    • 合宙ESP32C3上手
    • 实践-使用ESP32提醒打卡
    • EEWORLD Follow me 第2期
    • EEWORLD Follow me 第3期
      • 前言
      • 任务
        • 任务1:使用MicroPython系统(必做任务)
        • 任务2:驱动扩展板上的OLED屏幕(必做任务)
        • 任务3:控制蜂鸣器播放音乐(必做任务)
        • 任务4:连接WiFi网络(必做任务)
        • 任务5:使用外部传感器(必做任务)
        • 分任务1:寻找WiFi发射源的位置
        • 分任务2:温湿度数据记录仪
        • 分任务3:开灯提醒器
      • 参考资料
  • 嵌入式
  • 笔记
NipGeihou
2023-11-09
目录

EEWORLD Follow me 第3期

# 前言

经过 2 期的活动,感觉 EE 还是挺好玩的,而且说得上是有手就行,因此在第 3 期 (opens new window)活动开始时,我也在第一时间申请了。第 3 期的难度,看起来比第 2 期要难,起码从器件的数量来看是这样的。

本期的板子为:Seeed Studio XIAO ESP32C3

img

# 任务

# 任务 1:使用 MicroPython 系统(必做任务)

任务要求:熟悉 Seeed Studio XIAO ESP32C3 开发板基本操作,安装 esptool,并给开发板刷写 MicroPython 系统,完成入门程序的运行

搭配器件:Seeed Studio XIAO ESP32C3

准备

  • 下载 MicroPython 固件:MicroPython - Python for microcontrollers (opens new window)

    • 本文使用v1.21.0 (2023-10-05) .bin (opens new window)
  • 下载 esptool 工具:Releases · espressif/esptool (opens new window)

    • 本文使用esptool-v4.6.2-win64.zip (opens new window)

笔记

esptool 的安装方法有很多种,如直接从 git 仓库从下载源码执行的,也有 pip install esptool 的,我这里使用 git 仓库 Release 预编译的。

烧录

根据固件下载页面的 MicroPython - Python for microcontrollers (opens new window) 安装说明,修改:

# 擦除闪存
#esptool.py --chip esp32c3 --port /dev/ttyUSB0 erase_flash
.\esptool.exe --chip esp32c3 --port COM10 erase_flash

# 从地址 0x0 开始烧录
#esptool.py --chip esp32c3 --port /dev/ttyUSB0 --baud 460800 write_flash -z 0x0 esp32c3-20220117-v1.18.bin
.\esptool.exe --chip esp32c3 --port COM10 --baud 460800 write_flash -z 0x0 ESP32_GENERIC_C3-20231005-v1.21.0.bin

# 成功烧录的日志结尾
...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...
  • 将 COM10 修改为实际串口

连接

使用 Thonny 连接

image-20231203142558629

# 任务 2:驱动扩展板上的 OLED 屏幕(必做任务)

任务要求:使用扩展板上的 OLED 屏幕显示文字和图形

搭配器件:Seeed Studio XIAO ESP32C3、Seeed Studio Expansion Board Base for XIAO

官方示例
  • 编辑 MicroPython 设备的 boot.py 文件

  • 粘贴下面的官方示例代码

import time
from machine import Pin, SoftI2C
import ssd1306
import math

# ESP8266 Pin assignment
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("Hello, Seeder!", 10, 15)
oled.text("/////", 30, 40)
oled.text("(`3`)y", 30, 55)
oled.show()  # Show the text
  • 保存

  • 终端 Ctrl + D 重新加载

  • 报错:找不到 ssd1306 模块

MPY: soft reboot
Traceback (most recent call last):
  File "boot.py", line 3, in <module>
ImportError: no module named 'ssd1306'
MicroPython v1.21.0 on 2023-10-06; ESP32C3 module with ESP32C3
Type "help()" for more information.
  • Thonny - 工具 - 包管理 - 搜索 ssd1306 ,安装
  • 终端 Ctrl + D 重新加载

e879a37ecf4fb1151423384ad00f5eb

  • 安装 ssd1306 驱动
  • 显示文字
from machine import Pin, SoftI2C
import ssd1306

# i2c引脚
i2c = SoftI2C(scl=Pin(7), sda=Pin(6))
oled_width = 128
oled_height = 64
oled = ssd1306.SSD1306_I2C(oled_width, oled_height, i2c)

# 清除屏幕
oled.fill(0)
# 显示内容
oled.text("Hello", 10, 15)
oled.text("Follow Me 3!", 10, 25)
# 填充正方形
oled.fill_rect(10, 35, 12, 12, 1)
oled.show()

参考:

  • MicroPython for ESP32C3 | Seeed Studio Wiki (opens new window)

# 任务 3:控制蜂鸣器播放音乐(必做任务)

任务要求:使用 Seeed Studio XIAO ESP32C3 控制蜂鸣器发出不同频率的声音,并播放一段音乐

搭配器件:Seeed Studio XIAO ESP32C3、Seeed Studio Expansion Board Base for XIAO

播放三次 1000, 2000, 3000 赫兹的声音后,播放音乐《小星星》

import machine
import time

# 蜂鸣器
buzzer_pin = machine.Pin(5, machine.Pin.OUT)
buzzer = machine.PWM(buzzer_pin)
buzzer.freq(1047)

# 定义每个音符的频率
NOTE_C4 = 262
NOTE_D4 = 294
NOTE_E4 = 330
NOTE_F4 = 349
NOTE_G4 = 392
NOTE_A4 = 440
NOTE_B4 = 494
NOTE_C5 = 523

# 歌曲的音符,0是一个休息/脉冲
notes = [
    NOTE_C4, NOTE_C4, NOTE_G4, NOTE_G4, NOTE_A4, NOTE_A4, NOTE_G4,
    NOTE_F4, NOTE_F4, NOTE_E4, NOTE_E4, NOTE_D4, NOTE_D4, NOTE_C4,
    NOTE_G4, NOTE_G4, NOTE_F4, NOTE_F4, NOTE_E4, NOTE_E4, NOTE_D4,
    NOTE_G4, NOTE_G4, NOTE_F4, NOTE_F4, NOTE_E4, NOTE_E4, NOTE_D4,
    NOTE_C4, NOTE_C4, NOTE_G4, NOTE_G4, NOTE_A4, NOTE_A4, NOTE_G4,
    NOTE_F4, NOTE_F4, NOTE_E4, NOTE_E4, NOTE_D4, NOTE_D4, NOTE_C4
]

# 歌曲中每个音符的持续时间(毫秒)
durations = [
    500, 500, 500, 500, 500, 500, 1000,
    500, 500, 500, 500, 500, 500, 1000,
    500, 500, 500, 500, 500, 500, 1000,
    500, 500, 500, 500, 500, 500, 1000,
    500, 500, 500, 500, 500, 500, 1000,
    500, 500, 500, 500, 500, 500, 1000
]

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)  
            # 设置音符的频率
            buzzer.freq(current_note)  
        else:
            # 关闭声音
            buzzer.duty(0)
        time.sleep_ms(wait)
        # 关闭声音
        buzzer.duty(0)



# 依次发出1000, 2000, 3000赫兹的声音
freqArr = [1000, 2000, 3000]
for freq in freqArr:
    buzzer.freq(freq)
    buzzer.duty(255)
    time.sleep(1)
    buzzer.duty(0)
    time.sleep(1)

# 播放歌曲
play_song()

# 任务 4:连接 WiFi 网络(必做任务)

任务要求:将 Seeed Studio XIAO ESP32C3 连接到 WiFi 网络,并访问互联网信息

搭配器件:Seeed Studio XIAO ESP32C3、Seeed Studio Expansion Board Base for XIAO、RF ANT 2.4GHZ/5.5GHZ PCB TRACE

实现效果:使用 WIFI 连接互联网,获取当前广州的温湿度信息,并显示到屏幕上。

import ujson as json
import utime as time
import urequests
import network
from machine import Pin, SoftI2C
import ssd1306

# i2c引脚
i2c = SoftI2C(scl=Pin(7), sda=Pin(6))
oled_width = 128
oled_height = 64
oled = ssd1306.SSD1306_I2C(oled_width, oled_height, i2c)


# WIFI信息设置
wifi_ssid = "@NipGeihou"
wifi_password = "01230123"

station = network.WLAN(network.STA_IF)
station.active(True)

while not station.isconnected():
    print("Connecting...")
    station.connect(wifi_ssid, wifi_password)
    time.sleep(10)

print("Connected!")
# 获取广州天气信息
response = urequests.get(
    "https://aider.meizu.com/app/weather/listWeather?cityIds=101280101")
res = json.loads(response.text)
temp = res.get("value", [{}])[0].get("realtime", {}).get("temp")
sd = res.get("value", [{}])[0].get("realtime", {}).get("sD")

# 清除屏幕
oled.fill(0)
# 显示内容
oled.text("GuangZhou", 10, 15)
oled.text(temp+"C "+sd+"%", 10, 25)
oled.show()


ec44e110e788bfabfd9e71879d973c9

# 任务 5:使用外部传感器(必做任务)

任务要求:连接环境光传感器或温湿度传感器,获取传感器的数值,并转换成真实的物理量

搭配器件: Seeed Studio XIAO ESP32C3、Seeed Studio Expansion Board Base for XIAO、 Grove - AHT20 I2C Industrial Grade Temperature and Humidity Sensor、Grove - Light Sensor v1.2

d12d109166a0b8c2af784a7d82f1625

温湿度传感器

通过查阅 Grove - AHT20 I2C Industrial Grade Temperature&Humidity Sensor | Seeed Studio Wiki (opens new window) 可知传感器使用的 i2c 协议 ,需连接到扩展板上方的接口。

img

1701598334003

  • 通过在 PyPI・The Python Package Index (opens new window) 搜索 aht20 可找到 micropython-ahtx0 0.1.2 (opens new window)
  • 下载驱动 micropython-ahtx0-0.1.2.tar.gz
  • Thonny - 工具 - 包管理 - 从本地文件中安装,选择下载的驱动安装
  • 根据上图的引脚可知,i2c 对应的引脚为 SDA:GPIO6,SCL:GPIO7

光线传感器

查阅 Grove - Light Sensor | Seeed Studio Wiki (opens new window) 文档可知,此传感器使用 ADC。将传感器接到左下方接口,即 A0 GPIO2 。

import machine
adc = machine.ADC(0)
print(adc.read())

Grove - Light Sensor | Seeed Studio Wiki (opens new window) 文档中的示例似乎是旧的版本的,在 v1.2 版本的模块将传感器更改为 LS06-S光敏传感器 ,一番查找后,也没弄找到什么有用的信息,在他人的任务帖中说到这个传感器的 最大量程为 350 Lux ,在网上找来找去都没看到有说 350 Lux 的,最后在传感器包装袋里的纸中看到 Maxlue detected:350 lux 。因此可知 读值0 -> 0 lux 4095->350 lux 。

参考:

  • class ADC – analog to digital conversion — MicroPython latest documentation (opens new window)

代码

from machine import Pin, SoftI2C,ADC
import ssd1306
import ahtx0
import time

# i2c引脚
i2c = SoftI2C(scl=Pin(7), sda=Pin(6))
# 温湿度传感器
tempSensor = ahtx0.AHT20(i2c)
# 光线传感器
lightSensor = ADC(Pin(2))
# 应用输入衰减, 11dB 衰减, 允许输入电压范围 (150mV - 2450mV)
lightSensor.atten(ADC.ATTN_11DB)
# ESP32C3 为12位ADC  4095
lightSensor.width(ADC.WIDTH_12BIT)  
# 屏幕
oled_width = 128
oled_height = 64
oled = ssd1306.SSD1306_I2C(oled_width, oled_height, i2c)

while True:
    # 清除屏幕
    oled.fill(0)
    # 显示内容
    # 温湿度数据
    oled.text("TEMP: %0.2f C" % tempSensor.temperature, 10, 15)
    oled.text("RH: %0.2f %%" % tempSensor.relative_humidity, 10, 25)
    
    # 光线数据
    lightSensorValue = lightSensor.read()
    lux = lightSensorValue / 4095 * 350
    oled.text("LUX: %0.2f" % lux, 10, 35)
    oled.show()
    time.sleep(1)

# 分任务 1:寻找 WiFi 发射源的位置

实时测量 WiFi 信号强度,同时移动开发板位置,找到 WiFi 发射源(例如路由器)的位置。

import network
import time
from time import sleep
import machine
from machine import Pin, SoftI2C
import ssd1306
import math

# ESP32C3 Pin assignment
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)

# Network settings
wifi_ssid = "Your Own SSID"
wifi_password = "Your Own Password"
machine.freq(160000000)  # Set CPU frequency to 160 MHz (ESP8266 specific)
oled.text("Starting up...", 0, 0)
oled.show()

station = network.WLAN(network.STA_IF)
station.active(True)
station.connect(wifi_ssid, wifi_password)
time.sleep(1)

while not station.isconnected():
    time.sleep(1)

oled.fill(0)
oled.text("Connecting to", 0, 0)
oled.text(wifi_ssid, 0, 20)
oled.show()
time.sleep(2)

oled.fill(0)
ip_address = station.ifconfig()[0]  # Get the IP address
oled.text("Connected! ", 0, 0)
oled.text("IP Address:", 0, 20)
oled.text(ip_address, 0, 40)
oled.show()
time.sleep(2)

# Buzzer settings
buzzer_pin = machine.Pin(5, machine.Pin.OUT)
buzzer = machine.PWM(buzzer_pin)
buzzer.freq(1047)
buzzer.duty(0)

center_x = oled_width // 2
center_y = oled_height // 2
square_size = 6  # Size of each square
num_squares = 12  # Number of squares
angle_increment = 2 * math.pi / num_squares

x_pos = [12, 38, 64, 90]
statuses = ["poor", "normal", "good", "excellent"]

def calculate_block_count(rssi):
    # Determine the number of blocks based on RSSI values
    if -80 <= rssi < -60:
        return 1
    elif -60 <= rssi < -40:
        return 2
    elif -40 <= rssi < -20:
        return 3
    elif -20 <= rssi <= 10:
        return 4

def draw_blocks(count):
    for i in range(count):
        y_pos = 50 - calculate_block_height(i)
        oled.fill_rect(x_pos[i], y_pos, 24, calculate_block_height(i), 1)
    for i in range(count, 4):  # Clear unused area
        y_pos = 50 - calculate_block_height(i)
        oled.fill_rect(x_pos[i], y_pos, 24, calculate_block_height(i), 0)

def calculate_block_height(index):
    return 10 * (index + 1)

loop_count = 0  # Initialize loop count

while loop_count < 2:  # Execute the loop 24 times
    oled.fill(0)  # Clear the screen
    
    for i in range(num_squares):
        angle = i * angle_increment
        x = int(center_x + (center_x - square_size-30) * math.cos(angle))
        y = int(center_y + (center_x - square_size-30) * math.sin(angle))
        
        # Draw all squares
        for j in range(num_squares):
            angle_j = j * angle_increment
            x_j = int(center_x + (center_x - square_size-30) * math.cos(angle_j))
            y_j = int(center_y + (center_x - square_size-30) * math.sin(angle_j))
            
            oled.fill_rect(x_j, y_j, square_size, square_size, 1)  # Draw the square
        
        oled.fill_rect(x, y, square_size, square_size, 0)  # Erase the current square
        oled.show()
        time.sleep_ms(100)  # Pause before next iteration
        
    loop_count += 1  # Increase loop count

oled.fill(0)  # Clear the screen after finishing the loops
oled.show()

while True:
    oled.fill(0)
    station = network.WLAN(network.STA_IF)
    time.sleep(0.1)
    rssi = station.status('rssi')
    rssi_duty = 160 + 2 * int(rssi)
    rssi_duty_2 = int(rssi_duty / 2)
    rssi_abs = abs(int(rssi)) / 100
 
    block_count = calculate_block_count(rssi)
    status = statuses[block_count - 1]  # Get the status text based on block count
    
    draw_blocks(block_count)
    
    oled.text(status, 11, 56)
    
    oled.text("RSSI:", 0, 0)
    oled.text(str(rssi), 40, 0)
    # Update the display
    oled.show()

    buzzer.duty(rssi_duty)
    time.sleep(rssi_abs)
    buzzer.duty(0)
    time.sleep(rssi_abs)
    buzzer.duty(rssi_duty_2)
    time.sleep(rssi_abs)
    buzzer.duty(0)
    time.sleep(rssi_abs)

# 分任务 2:温湿度数据记录仪

任务要求:定时记录温湿度传感器的值,并展示出来。可记录到开发板内置存储中,也可以通过物联网服务发送数据到云端。

笔记

这个我选的分任务跟 2 期的是类似的,甚至说更简单,因为只要求使用一个传感器,不需要用到光线传感器,为了提升自己,在这里我选择加入光线传感器,并使用物联网服务发送数据到云端。

# 分任务 3:开灯提醒器

任务要求:监测环境光强度,如果光线太暗,通过屏幕和蜂鸣器提醒用户开灯,达到保护视力的效果。

搭配器件: Seeed Studio XIAO ESP32C3、Seeed Studio Expansion Board Base for XIAO、Grove - Light Sensor v1.2

7e4b5ae04a502f7c6dfbc2f5882531e

from machine import Pin, SoftI2C,ADC,PWM
import ssd1306
import time

# i2c引脚
i2c = SoftI2C(scl=Pin(7), sda=Pin(6))
# 蜂鸣器
buzzer_pin = Pin(5, Pin.OUT)
buzzer = PWM(buzzer_pin)
buzzer.freq(1047)
# 光线传感器
lightSensor = ADC(Pin(2))
# 应用输入衰减, 11dB 衰减, 允许输入电压范围 (150mV - 2450mV)
lightSensor.atten(ADC.ATTN_11DB)
# ESP32C3 为12位ADC  4095
lightSensor.width(ADC.WIDTH_12BIT)  
# 屏幕
oled_width = 128
oled_height = 64
oled = ssd1306.SSD1306_I2C(oled_width, oled_height, i2c)

while True:
    # 清除屏幕
    oled.fill(0)
    # 显示内容
    # 温湿度数据
    # 光线数据
    lightSensorValue = lightSensor.read()
    lux = lightSensorValue / 4095 * 350
    oled.text("LUX: %0.2f" % lux, 10, 15)
    text = "Normal"
    # 高于200时提示
    if lux > 200:
        text = "Too Bright!!"
        buzzer.duty(512)
    # 低于50时提示
    elif lux < 50:
        text = "Too Dark!!"
        buzzer.duty(512)
    else:
        buzzer.duty(0)
    oled.text(text, 10, 25)
    
    oled.show()
    time.sleep(1)

# 参考资料

  • Getting Started with Seeed Studio XIAO ESP32C3 | Seeed Studio Wiki (opens new window)
  • Expansion Board Base for XIAO | Seeed Studio Wiki (opens new window)
  • MicroPython for ESP32C3 | Seeed Studio Wiki (opens new window)(基本就是照着这个做一遍)
上次更新: 2024/03/11, 22:37:05
EEWORLD Follow me 第2期

← EEWORLD Follow me 第2期

最近更新
01
元器件
05-23
02
iSCSI服务搭建
05-10
03
磁盘管理与文件系统
05-02
更多文章>
Theme by Vdoing | Copyright © 2018-2025 NipGeihou | 友情链接
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式