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期
      • 前言
      • 当前模式
      • 安装 CircuitPython固件
        • 下载 CircuitPython
        • 刷入 CircuitPython
      • 开发环境
      • 示例
        • 打印开发板信息
        • 点灯
        • 按键
        • WIFI联网
        • 炫彩灯珠
      • 通信方式
        • 总线通信 - I2C
        • 总线通信 - SPI
      • 任务
        • 任务1:控制屏幕显示中文(必做任务)
        • 任务2:网络功能使用(必做任务)
        • 任务3:控制WS2812B(必做任务)
        • 分任务3:数据检测与记录
      • 参考
    • EEWORLD Follow me 第3期
  • 嵌入式
  • 笔记
NipGeihou
2023-10-14
目录

EEWORLD Follow me 第2期

# 前言

虽然专业有很多课程都是跟嵌入式相关的,但当时的我一心觉得未来一定是个软件工程师,而课程中的硬件基础,我嗤之以鼻,感觉都是几十年前的老古董,根本没听。近来发现,单纯的软件已经无法满足我对计算机科学的探索,我逐渐对硬件产生兴趣,一次偶然的机会得知「Follow me 第 2 期!与得捷电子一起解锁开发板超能力! (opens new window)」活动,基于能白嫖和借此入门嵌入式,参加了这个活动。

用到的开发板为: Adafruit ESP32-S3 TFT Feather (opens new window)

image-20231014132403485

# 当前模式

image-20231014132724016

正常情况下,将开发板通过 typec 连接电脑,根据屏幕的显示就能判断出当前的显示模式是什么,如屏幕没有画面时,则电脑显示的串口信息和磁盘信息对照上图来确认。

如果开发板是全新的,上电显示的应该是出厂模式。

# 安装 CircuitPython 固件

# 下载 CircuitPython

Feather ESP32-S3 TFT Download (opens new window)

image-20231014132553115

这个开发板支持 UF2,下载 UF2。

笔记

推荐下载 English 的,拼音看得比英文还难受。

# 刷入 CircuitPython

  • 开发板连接电脑,出厂模式下,双击 RST 键进入 UF2 模式

  • 把下载的 adafruit-circuitpython-adafruit_feather_esp32s3_tft-en_US-8.2.6.uf2 放入开发板磁盘 FTHRS3BOOT 根目录即可。

  • 文件拉进去后,开发板会自动重启,进入 CircuitPython 模式。

# 开发环境

VS Code + CircuitPython 插件

  • 安装 CircuitPython 插件
  • VScode 打开文件夹,选择开发板在 CircuitPython 模式的磁盘根目录
  • 点击 VScode 右下角,插头图标,选择串口,选择 ESP32 的

​ image-20231014134701490

  • 此时即可操作开发板

    image-20231014135024095

基本操作

Ctrl+C :在任意情况下输入,中断当前运行的程序

Ctrl+D :在空行的情况下输入,软重启开发板环境

Ctrl+E :在空行的情况下输入,进入粘贴模式,粘贴后 Ctrl+D 运行

PS: Ctrl+E 会与 Vscode 快捷键冲突,因此需要修改 !terminalFocus

image-20231014142744954

  • Ctrl + Shift + P
  • 搜索 CircuitPython: Show Available Libraries 选中

image-20231014135725414

# 示例

执行代码:

  • 代码编写在 code.py 中, Ctrl+D 软重启即可执行。
  • Ctrl+E 进入粘贴模式,粘贴代码,然后 Ctrl+D 执行

# 打印开发板信息

点击查看
# 基础模块
import board
dir(board)
print("开发板名称:", board.board_id)

# 引脚定义
import re

attrs = [i for i in dir(board) if not re.match(r'^[A-Z]', i)]
GPIOS = [i for i in dir(board) if re.match(r'^[A-Z]', i)]
gpio_used = []

print("数字引脚:", end="")
for i in GPIOS:
    if re.match(r'^D\d+', i):
        print(i, end=" ")
        gpio_used.append(i)
print("")

print("模拟引脚:", end="")
for i in GPIOS:
    if re.match(r'^A\d+', i):
        print(i, end=" ")
        gpio_used.append(i)
print("")

print("TFT:", end="")
for i in GPIOS:
    if re.match(r'^TFT|DISPLAY', i):
        print(i, end=" ")
        gpio_used.append(i)
print("")

print("串口:", end="")
for i in GPIOS:
    if re.match(r'^(TX|RX|UART)$', i):
        print(i, end=" ")
        gpio_used.append(i)
print("")

print("炫彩灯珠:", end="")
for i in GPIOS:
    if re.match(r'^NEOPIXEL', i):
        print(i, end=" ")
        gpio_used.append(i)
print("")

print("SPI:", end="")
for i in GPIOS:
    if re.match(r'^(MOSI|MISO|SCK|SPI)', i):
        print(i, end=" ")
        gpio_used.append(i)
print("")

print("I2C:", end="")
for i in GPIOS:
    if re.match(r'.*(SCL|SDA|I2C)', i):
        print(i, end=" ")
        gpio_used.append(i)
print("")

print("按键:", end="")
for i in GPIOS:
    if re.match(r'^(BUTTON|BOOT0)', i):
        print(i, end=" ")
        gpio_used.append(i)
print("")

print("LED:", end="")
for i in GPIOS:
    if re.match(r'(LED|L)', i):
        print(i, end=" ")
        gpio_used.append(i)
print("")

gpio_unused = [i for i in GPIOS if i not in gpio_used]
if len(gpio_unused):
    print("未分类属性:", gpio_unused)
if len(attrs):
    print("其他属性", attrs)

# 点灯

效果:循环亮 0.5 秒、暗 0.5 秒

# 基础模块,用于实现延迟
import time
# 开发板定义模块
import board
# 数字IO模块
import digitalio

# 初始化LED,board.LED 于 board.L等同
led = digitalio.DigitalInOut(board.LED)
# 设置为输出
led.direction = digitalio.Direction.OUTPUT
#led.switch_to_output()

while True:
    # 点亮LED,阻塞0.5秒
    led.value = True
    time.sleep(0.5)
    # 熄灭LED,阻塞0.5秒
    led.value = False
    time.sleep(0.5)

# 按键

效果:按下按钮,LED 灯亮起,屏幕打印 Button down ,松开按钮,LED 灯熄灭。

import board
import digitalio

# LED对象
# led.value:当前电平,亮-高-True,灭-低-False
led = digitalio.DigitalInOut(board.LED)
led.direction = digitalio.Direction.OUTPUT

# 按键对象
# board.BUTTON 与 board.BOOT0 等同
button = digitalio.DigitalInOut(board.BUTTON)
# 设置为输入,上拉,即button.value默认为不按-高-True,按下-低-False
button.switch_to_input(pull=digitalio.Pull.UP)

# 普通按键
isDown = False
while True:
    buttonIsDown = not button.value
    # 按键下与LED同步
    led.value = buttonIsDown
    if buttonIsDown and not isDown:
        # 按下 且为 第一次检测到按下
        isDown = True
        print("Button down")
    elif not buttonIsDown and isDown:
        # 松开 且为 第一次检测到松开
        isDown = False

笔记

button.switch_to_input(pull=digitalio.Pull.UP) 很绕,没按的时候是 True,按下的时候是 False,这还不能改成 Down,改了后会按键不会变 True,为了可读性,使用了一个变量 buttonIsDown 处理。

# WIFI 联网

官方教程:CircuitPython Internet Test | Adafruit ESP32-S3 TFT Feather | Adafruit Learning System (opens new window)

在根目录的 settings.toml 添加以下 WIFI 信息配置

CIRCUITPY_WIFI_SSID = "your-wifi-ssid"
CIRCUITPY_WIFI_PASSWORD = "your-wifi-password"
import os
import ssl

import adafruit_requests  # 需要安装扩展
import socketpool
import wifi

TEXT_URL = "http://wifitest.adafruit.com/testwifi/index.html"
# TEXT_URL = "https://honestqiao.gitee.io/web_esptool/"

print("ESP32-S3 网络功能测试")
print("开发板MAC地址:", [hex(i) for i in wifi.radio.mac_address])

# 连接WiFi
wifi.radio.connect(os.getenv("CIRCUITPY_WIFI_SSID"), os.getenv("CIRCUITPY_WIFI_PASSWORD"))

print("开发板已连接到WiFi")
print("开发板IP地址", wifi.radio.ipv4_address)

pool = socketpool.SocketPool(wifi.radio)
requests = adafruit_requests.Session(pool, ssl.create_default_context())

print("网络请求网址", TEXT_URL)
response = requests.get(TEXT_URL)
print("请求返回内容")
print("-" * 40)
print(response.text)
print("-" * 40)

print("测试完成")

# 炫彩灯珠

import time
import board
import neopixel # 需要安装扩展
import digitalio
from rainbowio import colorwheel

# WS2812B 电源控制
power = digitalio.DigitalInOut(board.NEOPIXEL_POWER)
power.direction = digitalio.Direction.OUTPUT
power.value = True

# WS2812B设置
pixel = neopixel.NeoPixel(board.NEOPIXEL, 1)
# 亮度
pixel.brightness = 0.5

# 颜色变换
def rainbow(delay):
    for color_value in range(255):
        pixel[0] = colorwheel(color_value)
        time.sleep(delay)

while True:
    rainbow(0.02)

# 通信方式

# 总线通信 - I2C

image-20231105160503071

image-20231105160733045

笔记

I2C 只使用两条双向漏极开路(Open Drain)线,其中一条线为传输数据的串行资料线(SDA, Serial DAta line),另一条线是启动或停止传输以及发送时钟序列的串行主频(SCL, Serial CLock line)线,这两条线上都有上拉电阻。I²C 允许相当大的工作电压范围,但典型的电压准位为 + 3.3V 或 + 5v。

参考:

  • 4 分钟看懂!I2C 通讯协议 最简单的总线通讯!_哔哩哔哩_bilibili (opens new window)
  • I²C - 维基百科,自由的百科全书 (opens new window)

# 总线通信 - SPI

image-20231105170955585

  • SCLK(Serial Clock):串列时脉,由主机发出
  • MOSI(Master Output, Slave Input):主机输出从机输入信号(数据由主机发出)
  • MISO(Master Input, Slave Output):主机输入从机输出信号(数据由从机发出)
  • SS(Slave Select):片选信号,由主机发出,一般是低电位有效

参考:

  • 深入理解 SPi 通讯协议,5 分钟看懂!_哔哩哔哩_bilibili (opens new window)
  • 串行外设接口(SPI) - 维基百科,自由的百科全书 (opens new window)

# 任务

# 任务 1:控制屏幕显示中文(必做任务)

任务要求:完成屏幕的控制,并且能显示中文

搭配器件:Adafruit ESP32-S3 TFT Feather

任务说明:这个任务可分为两点,一是如何在屏幕显示文本,二是在如何在屏幕显示中文文本。这个任务的难度并不大,跟着官方教程的步骤做就可以了。

主要的工作量还是在制作字体上:

  • 下载 FontForge:https://fontforge.org/en-US/downloads/

  • 安装:略

  • 修改 FontForge 的语言:

    • 找到 FontForge 的安装根目录
    • 编辑 fontforge.bat ,将其中的 ::set LANGUAGE=en 修改为 set LANGUAGE=zh_CN
  • 下载一个字体,如 HarmonyOS 字体 (opens new window)

  • 使用 FontForge 打开

  • 通过这个网站 https://www.branah.com/unicode-converter,将要保留的字体转为 UTF-16

    如 苟利国家生死以岂因祸福避趋之 转为 \u82df\u5229\u56fd\u5bb6\u751f\u6b7b\u4ee5\u5c82\u56e0\u7978\u798f\u907f\u8d8b\u4e4b

  • 在通过一些编辑器操作或者寻求 ChatGPT 的帮助,将其转换为

SelectMore(0uc6d0)
SelectMore(0u82df)
SelectMore(0u5229)
SelectMore(0u56fd)
SelectMore(0u5bb6)
SelectMore(0u751f)
SelectMore(0u6b7b)
SelectMore(0u4ee5)
SelectMore(0u5c82)
SelectMore(0u56e0)
SelectMore(0u7978)
SelectMore(0u798f)
SelectMore(0u907f)
SelectMore(0u8d8b)
SelectMore(0u4e4b)
  • 在 FontForge 左上角,选择 文件-执行脚本 ,输入上面的脚本,选择 FF ,,执行,此时已经选中了要留下的字符
  • 编辑-选中-反转选择
  • 编码-分离并移除字形
  • 编码-紧凑(隐藏未使用的字形)
  • 至此应该就只显示刚刚留下来的字体
  • 元素-字体信息-通用 ,去掉勾选 有垂直尺寸
  • 元素-可用位图部件 , 75dpi屏幕上点的大小 输入 20 ,确定
  • 元素-再生位图字形 ,直接点确定即可
  • 文件-生成字体 , 无轮廓字体 ,Generate

image-20231015012730730

import time
import board
import displayio
from adafruit_display_text import label
from adafruit_bitmap_font import bitmap_font

display = board.DISPLAY

font_cn_file = "fonts/HarmonyOS_Sans_SC-21.bdf"
font_cn = bitmap_font.load_font(font_cn_file)

text_group = displayio.Group(
    scale=1,
    x=0,
    y=0,
)

text_cn = "苟利国家生死以\n岂因祸福避趋之"
text_cn_area = label.Label(font_cn, text=text_cn, color=0xFFFFFF, x=20, y=50)
text_group.append(text_cn_area)

display.show(text_group)
while True:
    pass

image-20231015020444166

参考资料:

  • https://learn.adafruit.com/custom-fonts-for-pyportal-circuitpython-display
  • https://home.gamer.com.tw/creationDetail.php?sn=4117676

# 任务 2:网络功能使用(必做任务)

任务要求:完成网络功能的使用,能够创建热点和连接到 WiFi

搭配器件:Adafruit ESP32-S3 TFT Feather

任务说明:这个任务同样可分为两点,一是连接到 WIFI,二是创建热点。

连接到 WIFI

跟着官方教程就可以完成。

在 settings.toml 添加

CIRCUITPY_WIFI_SSID  = "WIFI SSID"
CIRCUITPY_WIFI_PASSWORD = "WIFI密码"

code.py

import os
import ssl

import adafruit_requests  # 需要安装扩展
import socketpool
import wifi

TEXT_URL = "http://wifitest.adafruit.com/testwifi/index.html"

# 连接WiFi
wifi.radio.connect(os.getenv("CIRCUITPY_WIFI_SSID"), os.getenv("CIRCUITPY_WIFI_PASSWORD"))

print("开发板已连接到WiFi")
print("开发板IP地址", wifi.radio.ipv4_address)

pool = socketpool.SocketPool(wifi.radio)
requests = adafruit_requests.Session(pool, ssl.create_default_context())

print("网络请求网址", TEXT_URL)
response = requests.get(TEXT_URL)
print("请求返回内容")
print("-" * 40)
print(response.text)
print("-" * 40)

while True:
    pass

创建热点

设置热点就更加简单了,只需要一个函数就可以。

import wifi

# 设置热点的SSID和密码
wifi.radio.start_ap("ESP32", "12345678")
print("MAC:", "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}".format(*wifi.radio.mac_address))
while True:
    pass

参考资料:

  • https://docs.circuitpython.org/en/latest/shared-bindings/wifi/index.html

# 任务 3:控制 WS2812B(必做任务)

任务要求:使用按键控制板载 Neopixel LED 的显示和颜色切换

搭配器件:Adafruit ESP32-S3 TFT Feather

功能说明:这个任务只要把官方视频的按键 + 炫彩灯珠结合一下就可以完成。

import random

import board
import digitalio
import neopixel  # 需要安装扩展

# WS2812B 电源控制
power = digitalio.DigitalInOut(board.NEOPIXEL_POWER)
power.direction = digitalio.Direction.OUTPUT
power.value = True

# WS2812B设置
pixel = neopixel.NeoPixel(board.NEOPIXEL, 1)
# 亮度
pixel.brightness = 0.1


# 按键对象
# board.BUTTON 与 board.BOOT0 等同
button = digitalio.DigitalInOut(board.BUTTON)
# 设置为输入,上拉,即button.value默认为不按-高-True,按下-低-False
button.switch_to_input(pull=digitalio.Pull.UP)


# 按键是否按下
isDown = False
while True:
    buttonIsDown = not button.value
    if buttonIsDown and not isDown:
        # 按下 且为 第一次检测到按下
        isDown = True
        # 随机颜色
        pixel.fill((random.randint(0, 255), random.randint(0, 255),random.randint(0, 255)))
    elif not buttonIsDown and isDown:
        # 松开 且为 第一次检测到松开
        isDown = False

# 分任务 3:数据检测与记录

按一定时间间隔连续记录温度 / 亮度信息,保存到 SD 卡,并可以通过按键调用查看之前的信息,并在屏幕上绘图

搭配器件:

  • Adafruit ESP32-S3 TFT Feather
  • Adafruit LTR-329(光线传感器)
  • Adafruit MCP9808(温度传感器)
  • CH376S(Micro SD 卡模块)

在本次实验中,需要用到 3 个模块,其中两个传感器使用 I2C 通信,SD 卡模块使用 SPI 通信,因此需要对着两种通信方式有所了解,并且了解 ESP32 开发板对应的引脚(参考 1)

adafruit_products_Adafruit_ESP32-S3_TFT_Feather_Pinout.png

接线

image-20231105182555929

  • LTR-329(光线传感器)- I2C
    • VIN:接 3.3V
    • GND:接地
    • SCL:接 SCL
    • SDA:接 SDA
  • MCP9808(温度传感器)- I2C
    • Vdd:接 3.3V
    • Gnd:接地
    • SCL:接 SCL
    • SDA:接 SDA
  • CH376S(Micro SD 卡模块)- SPI
    • GND:接地
    • VCC:接 5V(VUSB 引脚)
    • MISO:接 MISO
    • MOSI:接 MOSI
    • SCK:接 SCK
    • CS:A5(或任意 GPIO 接引)

笔记

在 USB 供电下,实测 VBAT 引脚电压 4V,VUSB 引脚电压 5V

参考代码
import asyncio
import os
import wifi
import socketpool
import adafruit_ntp
import rtc
import digitalio
import adafruit_sdcard
import storage
# 显示屏
import displayio
import terminalio
from adafruit_display_text import label

# 处理记录
async def hanlderRecord(ltr329, mcp,sdcard):
    # 挂载SD卡
    print("VfsFat")
    vfs = storage.VfsFat(sdcard)
    print("mount")
    storage.mount(vfs, "/sd")
    print("mount ok")
    
    # 清空文件
    # fo = open(filePath, "w")
    # fo.write("")
    # fo.close()

    while True:
        # 时间戳,可见光+红外光,可见光
        t = time.time()
        text = str(t) + ","

        # 光线传感器
        # 可见光+红外光
        text += str(ltr329.visible_plus_ir_light) + ","
        # 可见光
        text += str(ltr329.ir_light)+ "," 

        # 温度传感器
        text += str(mcp.temperature)

        # 写入SD卡,追加模式
        fo = open(filePath, "a")
        fo.write(text + "\r\n")
        fo.close()

        print(text)
        # 每60秒写入一次
        await asyncio.sleep(60)

# 格式化时间戳
def _format_datetime(timestamp):
    tz_offset_seconds = 60 * 60 * 8  # 东八区
    get_timestamp = int(timestamp + tz_offset_seconds)
    current_unix_time = time.localtime(get_timestamp)
    current_struct_time = time.struct_time(current_unix_time)
    return "{:02}-{:02} {:02}:{:02}".format(
        current_struct_time.tm_mon,
        current_struct_time.tm_mday,
        current_struct_time.tm_hour,
        current_struct_time.tm_min,
    )

# 打印记录
def printRecord(text_area,pageNum,pageSize):
    headerText = "Time  Visible+IR   IR   Temperature\r\n"
    with open(filePath, 'r') as file:
        lines = file.readlines()
        pageTotal = len(lines)
        maxPageNum = (pageTotal + pageSize - 1) // pageSize

        if pageNum < 1 or pageNum > maxPageNum:
            pageNum = 1

        start_index = (pageNum - 1) * pageSize
        end_index = start_index + pageSize
        page_lines = lines[start_index:end_index]

        text = ""
        # 生成文本
        for line in page_lines:
            # ,分割
            line = line.split(",")

            # 时间
            current_date = "{}".format(_format_datetime(int(line[0])))
            text += current_date+"\t"

            # 可见光+红外光
            text += line[1]+"\t"+line[2]+"\t"

            # 温度 精确到小数点后1位
            text += "{:.1f}".format(float(line[3]))+" C"
            
            text += "\r\n"

    floorText = "Page " + str(pageNum) + "/" + str(maxPageNum)
    text_area.text = headerText + text + floorText

# 处理屏幕输出
async def hanlderScreen(button):
    display = board.DISPLAY
    text_group = displayio.Group( scale=1, x=0, y=0 )
    text_area = label.Label(terminalio.FONT, text="", color=0x000000, x=0, y=5,background_color=0xFFFFFF)
    text_group.append(text_area)  # Subgroup for text scaling
    display.show(text_group)

    # 分页信息
    pageTotal = 0 # 总数据数
    pageNum = 1 # 当前页
    pageSize = 7 # 每页数据数
    
    printRecord(text_area,pageNum,pageSize)
    isDown = False
    while True:
        buttonIsDown = not button.value
        if buttonIsDown and not isDown:
            # 按下 且为 第一次检测到按下
            isDown = True
            print("Button down")
        elif not buttonIsDown and isDown:
            # 松开 且为 第一次检测到松开
            isDown = False
            pageNum+=1
            printRecord(text_area,pageNum,pageSize)
        await asyncio.sleep(0.1)


async def main(ltr329, mcp, sdcard,button):
    # 连接WiFi
    wifi.radio.connect(os.getenv("CIRCUITPY_WIFI_SSID"), os.getenv("CIRCUITPY_WIFI_PASSWORD"))
    print("开发板已连接到WiFi")
    print("开发板IP地址", wifi.radio.ipv4_address)
    pool = socketpool.SocketPool(wifi.radio)

    time.sleep(1)
    # 使用ntp时间更新系统时间
    ntp = adafruit_ntp.NTP(pool, server="time1.cloud.tencent.com")
    rtc.RTC().datetime = ntp.datetime

    asyncio.create_task(hanlderRecord(ltr329, mcp,sdcard))
    asyncio.create_task(hanlderScreen(button))
    while True:
        await asyncio.sleep(1)

import time
import board
from adafruit_ltr329_ltr303 import LTR329
import adafruit_mcp9808

# 光线传感器
i2c = board.I2C()  # uses board.SCL and board.SDA
time.sleep(0.1)  # sensor takes 100ms to 'boot' on power up
ltr329 = LTR329(i2c)

# 温度传感器
mcp = adafruit_mcp9808.MCP9808(i2c)

# 读卡器
spi = board.SPI()
cs = digitalio.DigitalInOut(board.A5)
sdcard = adafruit_sdcard.SDCard(spi, cs)
filePath = "/sd/record.csv"

# 按键对象
# board.BUTTON 与 board.BOOT0 等同
button = digitalio.DigitalInOut(board.BUTTON)
# 设置为输入,上拉,即button.value默认为不按-高-True,按下-低-False
button.switch_to_input(pull=digitalio.Pull.UP)

asyncio.run(main(ltr329, mcp, sdcard,button))

参考资料:

  1. Pinouts | Adafruit ESP32-S3 TFT Feather | Adafruit Learning System (opens new window)
  2. Overview | Adafruit LTR-329 and LTR-303 Light Sensors | Adafruit Learning System (opens new window)
  3. Overview | Adafruit MCP9808 Precision I2C Temperature Sensor Guide | Adafruit Learning System (opens new window)

# 参考

  • Adafruit ESP32-S3 TFT Feather 开发板使用入门 - Digi-Key: Follow Me 系列 (2) 直播回放 - EEWORLD 大学堂 (opens new window)

  • https://edm.eeworld.com.cn/Follow_me_2_Adafruit_ESP32_S3_TFT_Feather_files.pdf (opens new window)

  • DigiKey+EEWORLD 之 Follow me 活动第二期课程资料: DigiKey+EEWORLD 之 Follow me 活动第二期课程资料 (opens new window)

上次更新: 2024/03/11, 22:37:05
实践-使用ESP32提醒打卡
EEWORLD Follow me 第3期

← 实践-使用ESP32提醒打卡 EEWORLD Follow me 第3期→

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