X
首页
技术
模拟电子
单片机
半导体
电源管理
嵌入式
传感器
最能打国产芯
应用
汽车电子
工业控制
家用电子
手机便携
安防电子
医疗电子
网络通信
测试测量
物联网
最能打国产芯
大学堂
首页
直播
专题
TI 培训
论坛
汽车电子
国产芯片
电机驱动控制
电源技术
单片机
模拟电子
PCB设计
电子竞赛
DIY/开源
嵌入式系统
医疗电子
颁奖专区
【厂商专区】
【电子技术】
【创意与实践】
【行业应用】
【休息一下】
最能打国产芯
活动中心
直播
发现活动
颁奖区
电子头条
参考设计
下载中心
分类资源
文集
排行榜
电路图
Datasheet
最能打国产芯
DigiKey得捷技术专区
[作品提交] 【得捷电子Follow me第2期】上手体验Adafruit ESP32-S3 TFT Feather
eew_nagvq9
2023-11-9 23:44
楼主
# 【得捷电子Follow me第2期】上手体验Adafruit ESP32-S3 TFT Feather ## //内容一:3-5分钟短视频// [任务视频链接](https://training.eeworld.com.cn/video/38262 "任务视频") ## //内容二: 任务/项目总结报告// ### 项目介绍 前段时间网上冲浪的时候无意中看到了DigiKey联合EEWORLD发起的Follow me任务返现活动,于是便有了下文。从8月下单订购,盼到10月终于收到了开发板,迫不及待上手体验下这款由Adafruit打造的开发板**Adafruit ESP32-S3 TFT Feather**。 开箱拿在手上,不由赞叹这款开发板之精致,小小的体积下塞下了1.14寸的IPS彩屏、支持RGB的NeoPixel和LED、贴片按钮、TYPE-C接口、STEMMA QT接口、电池接口、甚至还预留了充足的扩展IO。 得益于ESP32-S3的强大功能,**Adafruit ESP32-S3 TFT Feather**不仅拥有双核240MHz的主频,512KB的内置SRAM,更同时支持2.4GHzWiFi和Bluetooth 5(LE)和原生USB,能够满足不同场景下的使用需求。 由于我本身就从事嵌入式软件开发,平时工作中主要都是使用C/C++进行开发的,看到开发板还支持CircuitPython开发,那么不如这次就使用CircuitPython来体验一下**Adafruit ESP32-S3 TFT Feather**这款开发板吧!
### 任务一:控制屏幕显示中文 > 任务内容:完成屏幕的控制,并且能显示中文 > > 搭配器件:Adafruit ESP32-S3 TFT Feather 根据任务内容,我们可以将任务大致分解为如下2个子功能: 1. 实现显示屏; 2. 实现中文字体显示; 将任务拆分好以后,就可以开始着手实现了。 ##### 1.实现显示屏驱动 首先第一个功能是实现开发板上的显示屏驱动,我们根据开发板的屏幕驱动芯片(st7789)以及分辨率(240*135),找到对应的CircuitPython官方库中提供的显示例子(目录地址如下)。 这里插一下嘴,在很多时候官方库是我们学习开发板硬件,乃至编程语言的一个非常好的途径,而且这里Adafruit给出的官方库也提供了非常多且详细的例子给我们参考,后面很多的任务功能实现都参考了官方库中的例子。 > 官方库例子:.\adafruit-circuitpython-bundle-8.x-mpy-20231003\examples\st7789_240x135_simpletest.py # Release any resources currently in use for the displays displayio.release_displays() spi = board.SPI() tft_cs = board.D5 tft_dc = board.D6 display_bus = displayio.FourWire(spi, command=tft_dc, chip_select=tft_cs) display = ST7789( display_bus, rotation=270, width=240, height=135, rowstart=40, colstart=53 ) 根据例子不难看出,要实现屏幕驱动需要配置好屏幕的CS和DC引脚。 这时候就要翻出官方的文档[Adafruit Learning System](https://learn.adafruit.com/assets/114106),找到开发板屏幕的CS和DC引脚对应的标识符如下。 > CS=TFT_CS > > DC=TFT_DC 因此,我们将上述的例子中代码稍作修改: # Release any resources currently in use for the displays displayio.release_displays() spi = board.SPI() tft_cs = board.TFT_CS tft_dc = board.TFT_DC display_bus = displayio.FourWire(spi, command=tft_dc, chip_select=tft_cs) display = ST7789( display_bus, rotation=270, width=240, height=135, rowstart=40, colstart=53 ) 保存后复位开发板,可以看到屏幕上显示出英文"Hello World!",实现了屏幕驱动。
##### 2.实现中文字体显示 来到第二个功能:中文字体显示。 > 这里需要补充一下知识点,计算机在显示文字时,都是需要对文字进行渲染,再将文字变成一张张图片显示出来;对文字的不同渲染方法,就是我们所说的字体。由此可见,不同的字体其实就是一套一套对文字不同的渲染“公式”。在日常使用的计算机中,字体通常是在需要显示的时候才根据“公式”渲染出来,显示到屏幕上,这种渲染“公式”通常称为矢量字体;可见,使用“公式”渲染不可避免要进行一系列的计算;而在嵌入式系统中,我们通常不希望显示字体占用过多本就紧张的计算资源,所以工程师们就将字体渲染的过程提前到代码运行前,这种预先渲染的字体称为位图字体。 补充完知识之后,我们再回到这个中文字体显示这个功能。显然,我们需要制作中文位图字体,才能让显示屏显示出中文。这里依然是参考了[官方的文档](https://learn.adafruit.com/custom-fonts-for-pyportal-circuitpython-display/bitmap_font-library) 首先,选择自己喜欢的字体,使用[FontForge]([FontForge Open Source Font Editor](https://fontforge.org/en-US/))制作位图字体库,这里我使用“三极智黑体”制作了字体库“SJzhiheiti-22.bdf”。 然后,我们加入生成的字体库,并对上面功能的代码稍作修改: from adafruit_bitmap_font import bitmap_font …… # load bitmap font font_file = "fonts/SJzhiheiti-22.bdf" font = bitmap_font.load_font(font_file) # Draw a label text = "你好,世界!" text_area = label.Label(font, text=text, color=TEXT_COLOR) 保存后复位开发板,可以看到屏幕上显示出中文"你好,世界!"。
这里可以看到中文字太大了,一部分已经压到边框上,这时候我们调整一下缩放比例: …… # First set some parameters used for shapes and text BORDER = 20 FONTSCALE = 2 #缩放比例调整为2 BACKGROUND_COLOR = 0x00FF00# Bright Green FOREGROUND_COLOR = 0xAA0088# Purple TEXT_COLOR = 0xFFFF00 ……
重新运行发现字体完美显示,至此,我们完成了任务一的全部内容。 ### 任务二:网络功能使用 > 任务内容:完成网络功能的使用,能够创建热点和连接到WiFi > > 搭配器件:Adafruit ESP32-S3 TFT Feather 根据任务内容,我们不难将任务分解为下面2个子功能: 1. 实现连接WiFi功能; 2. 实现创捷WiFi热点功能; 为了更直观验证连接WiFi/创建WiFi热点后的网络功能,这里我加入了第3个子功能:实现简单的HTTP服务。 ##### 1.实现简单的HTTP服务 在实现任务内容之前,我们先实现HTTP服务;这样我们就能够在连接WiFi/连接WiFi热点后,通过浏览器访问开发板的HTTP服务验证其网络功能了。 这里依旧是根据我们需要实现的功能,找到对应的CircuitPython官方库中提供的HTTP服务例子(目录地址如下)。得益于官方库的强大功能,只需几行代码即可以实现我们所需要的功能。 > 官方库例子:.\adafruit-circuitpython-bundle-8.x-mpy-20231003\examples\httpserver_simpletest_auto.py pool = socketpool.SocketPool(wifi.radio) #这里制定了建立socket的网络出口 server = Server(pool, "/static", debug=True) @server.route("/") def base(request: Request): """ Serve a default static plain text message. """ return Response(request, "Hello from the CircuitPython HTTP Server!") server.serve_forever(str(wifi.radio.ipv4_address)) #这里绑定了http服务的地址 ##### 2.实现连接WiFi功能 在上面我们实现了一个简单的HTTP服务,是时候实现WiFi连接的功能来验证一下了。这里参考的是[官方的API文档](https://docs.circuitpython.org/en/8.2.x/shared-bindings/wifi/index.html) 根据官方的API文档,连接到WiFi也是仅需几行代码: #setup station wifi.radio.start_station() wifi.radio.connect(ssid="需要连接的WiFi名称", password="需要连接的WiFi密码") #需要注意只能连接2.4G频段WiFi wifi.radio.start_dhcp() 保存后复位开发板,可以看到开发板连接WiFi后获得IP地址: > Started development server on http://192.168.123.158:80
此时,使用电脑或手机浏览器访问IP:192.168.123.158,浏览器显示: > Hello from the CircuitPython HTTP Server!
同时,REPL输出请求响应信息: > 192.168.123.196 -- "GET /" 538 -- "200 OK" 125 -- 25ms 至此,我们完成了连接WiFi的功能,并完成HTTP服务的验证。 ##### 3.实现创建WiFi热点功能 有了上面的铺垫之后,实现WiFi热点创建的思路就呼之欲出了。同样地,[官方的API文档](https://docs.circuitpython.org/en/8.2.x/shared-bindings/wifi/index.html)也提到创建WiFi热点所需的接口。 根据官方的API文档,创建WiFi热点只需修改几行代码: # setup ap wifi.radio.start_ap(ssid="CircuitPython", password="") wifi.radio.set_ipv4_address_ap(ipv4=ipaddress.ip_address("192.168.1.1"), netmask=ipaddress.ip_address("255.255.255.0"), gateway=ipaddress.ip_address("192.168.1.1")) wifi.radio.start_dhcp_ap() …… server.serve_forever(str(wifi.radio.ipv4_address_ap)) 保存后复位开发板,可见HTTP服务绑定的IP地址: > Started development server on http://192.168.1.1:80
此时,使用电脑或者手机连接到开发板的WiFi热点“CircuitPython”,使用浏览器访问IP:192.168.1.1,浏览器显示: > Hello from the CircuitPython HTTP Server!
同时,REPL输出请求响应信息: > 192.168.1.2 -- "GET /" 387 -- "200 OK" 125 -- 23ms 至此,我们完成了创建WiFi热点的功能,并完成了任务二的全部内容。 ### 任务三:控制WS2812B > 任务内容:使用按键控制板载Neopixel LED的显示和颜色切换 > > 搭配器件:Adafruit ESP32-S3 TFT Feather 根据任务内容,可以将任务分解为下面3个子功能: 1. 实现板载Neopixel LED显示; 2. 实现按键按下检测; 3. 实现按键控制Neopixel LED颜色切换的逻辑; 这个任务的子功能1和2都可以在[官方入门教程](http://edm.eeworld.com.cn/dk_adafruit_esp32_s3_tft_feather_en.pdf)中找到,我会在不同的子功能代码块中标明对应的章节,具体原理就不再赘述了。 说实话,如果将这个任务作为任务一可能更有利于初学者入门这款开发板,事实上我也是从这个任务开始上手熟悉这款开发板的。让我们跟着入门教程开始吧! ##### 1.实现板载Neopixel LED显示 > 参考章节:NeoPixel LED (Page 137) 这里官方教程实现了Neopixel LED的不同RGB颜色轮流点亮显示: pixel = neopixel.NeoPixel(board.NEOPIXEL, 1) pixel.brightness = 0.3 while True: pixel.fill((255, 0, 0)) time.sleep(0.5) pixel.fill((0, 255, 0)) time.sleep(0.5) pixel.fill((0, 0, 255)) time.sleep(0.5) ##### 2.实现按键按下检测 > 参考章节:Digital Input (Page 128) 这里官方教程实现了按键对板载LED的点亮控制(这里的LED不是任务中的Neopixel LED): led = digitalio.DigitalInOut(board.LED) led.direction = digitalio.Direction.OUTPUT button = digitalio.DigitalInOut(board.BUTTON) button.switch_to_input(pull=digitalio.Pull.UP) while True: if not button.value: led.value = True else: led.value = False ##### 3.实现按键控制Neopixel LED颜色切换的逻辑 现在我们结合子功能1和2,加上我们的控制逻辑,便可以实现了按键控制Neopixel LED颜色切换: button = digitalio.DigitalInOut(board.BUTTON) button.switch_to_input(pull=digitalio.Pull.UP) pixel = neopixel.NeoPixel(board.NEOPIXEL, 1) pixel.brightness = 0.5 counter = 0 rgb_list = [0x000000, 0xFF0000, 0x00FF00, 0x0000FF, 0x00FFFF, 0xFF00FF, 0xFFFF00, 0xFFFFFF] #这里定义了LED的不同RGB颜色 while True: if not button.value: counter += 1 if counter>=len(rgb_list): counter = 0 pixel.fill((rgb_list[counter]>>16, rgb_list[counter]>>8, rgb_list[counter]&0xFF)) #这里将对应的RGB颜色设置到LED中 time.sleep(0.2)
至此,我们完成了任务三的全部内容。 ### 任务四:日历&时钟 > 任务内容:完成一个可通过互联网更新的万年历时钟,并显示当地的天气信息 > > 建议搭配器件:Adafruit ESP32-S3 TFT Feather 在任务四中我选择了分任务1,虽然任务内容比上面几个内容要复杂,但我们依然可以将其分解为下面5个子功能: 1. 实现WiFi连接互联网; 2. 获取当前时间信息; 3. 获取当前天气信息; 4. 实现本地时钟计时; 5. 实现屏幕显示时间和天气信息; 现在让我们开始最后一个任务吧! ##### 1.实现WiFi连接互联网 连接WiFi的功能其实在**任务二:网络功能使用**当中已经实现,这里把它再搬出来: #setup station wifi.radio.start_station() wifi.radio.connect(ssid="需要连接的WiFi名称", password="需要连接的WiFi密码") wifi.radio.start_dhcp() pool = socketpool.SocketPool(wifi.radio) 这样我们的开发板就有了连接互联网的能力。 ##### 2.获取当前时间信息 要从互联网获取时间信息主要常用的有两种方法:一是,通过ntp服务进行时间同步;二是,通过网络请求的方式获取。 为了和子功能3保持同步,我们使用第二种方法,即通过HTTP请求服务器的API获取时间。 这里用到的是AdafruitIO提供的免费时间API[Adafruit IO - Time Power-Up](https://io.adafruit.com/services/time),简单邮箱注册后就可以进行请求。 参考官方库给到的例子,我们不难写出HTTP请求的代码: > 官方库例子:.\adafruit-circuitpython-bundle-8.x-mpy-20231003\examples\json_stream_simpletest.py #request datetime aio_username = "AdafruitIO账号username" aio_key = "AdafruitIO账号的key" url_get_time = 'http://io.adafruit.com/api/v2/%s/integrations/time/struct?x-aio-key=%s' %(aio_username, aio_key) requests = adafruit_requests.Session(pool) response = requests.get(url_get_time) 填写正确的username和key之后,我们使用浏览器来测试下API,可以看到返回的是json格式的数据: > {"year":2023,"mon":11,"mday":7,"hour":21,"min":14,"sec":3,"wday":2,"yday":311,"isdst":0} 这时候我们继续参考官方库给的例子,看看如何解析json数据: jobj = json_stream.load(response.iter_content(32)) print('%d-%d-%d %d:%d:%d' %(jobj["year"],jobj["mon"],jobj["mday"],jobj["hour"],jobj["min"],jobj["sec"])) ##### 3.获取当前天气信息 实现时间信息获取之后,我们依葫芦画瓢获取一下当前天气的信息。 本来AdafruitIO也有提供的天气API,只可惜要付费才能使用;所以用到的是心知天气提供的免费天气API[心知天气 (seniverse.com)](https://www.seniverse.com/),这里依旧是简单邮箱注册就可以进行请求。 参考上面获取时间的方法,在这里我们以英文形式获取广州的天气情况: #request weather seniverse_private_key = "心知天气的private_key" url_get_weather = 'http://api.seniverse.com/v3/weather/now.json?key=%s&location=guangzhou&language=en' %(seniverse_private_key) requests = adafruit_requests.Session(pool) response = requests.get(url_get_weather) jobj = json_stream.load(response.iter_content(32)) for result in jobj["results"]: now_weather = result["now"] weather = now_weather["text"] temp = now_weather["temperature"] print('%s %s' %(weather,temp)) ##### 4.实现本地时钟计时 从互联网获取到时间信息之后,我们需要将其同步到本地的时钟当中,使得本地时钟可以校准到我们所设定的时间,并继续计时。这样我们之后想要获取当前时间时,就可以直接从本地时钟中读取,从而避免每次获取时间都要进行网络请求获取。 这里需要引入一个硬件概念,RTC实时时钟。简单来说RTC就是一个可以脱离CPU运行的计时器,有了它我们就可以在CPU不运行的情况下也可以进行计时。 同样的,我们也可以在官方库中找到RTC的使用例子: > 官方库例子:.\adafruit-circuitpython-bundle-8.x-mpy-20231003\example\ntp_set_rtc.py 不难看出,使用RTC只需要简单几行代码,同时我们结合子功能2中的获取到的时间信息,即可完成RTC时钟的设置和校准: #setup rtc rtc = rtc.RTC() requests = adafruit_requests.Session(pool) response = requests.get(url_get_time) jobj = json_stream.load(response.iter_content(32)) rtc.datetime = time.struct_time((jobj["year"], jobj["mon"], jobj["mday"], jobj["hour"], jobj["min"], jobj["sec"] , 0, -1, -1)) print(rtc.datetime) ##### 5.实现屏幕显示时间和天气信息 同样地,我们在**任务一:控制屏幕显示中文**中已经知道了如何在屏幕中显示文字,只需稍加修改,加入时间和天气的文字即可。 在这里我在主循环中加入时间、日期、天气的界面刷新代码,时间每秒刷新一次,日期和天气每分钟刷新一次: counter = 0 while True: txt1 = '%2.2d:%2.2d:%2.2d' %(rtc.datetime.tm_hour, rtc.datetime.tm_min, rtc.datetime.tm_sec) text_area1 = label.Label(terminalio.FONT, text=txt1, color=TEXT_COLOR) text_width1 = text_area1.bounding_box[2] * 3 text_group1 = displayio.Group(scale=3, x=(display.width-text_width1) // 2 , y=display.height // 2 - 10) text_group1.append(text_area1)# Subgroup for text scaling splash.append(text_group1) if not counter%60: txt2 = '%4.4d/%2.2d/%2.2d %s' %(rtc.datetime.tm_year, rtc.datetime.tm_mon, rtc.datetime.tm_mday, weather) text_area2 = label.Label(terminalio.FONT, text=txt2, color=TEXT_COLOR) text_width2 = text_area2.bounding_box[2] * 2 text_group2 = displayio.Group(scale=2, x=(display.width-text_width2) // 2, y=display.height // 2 + 20) text_group2.append(text_area2) # Subgroup for text scaling splash.append(text_group2) counter += 1 time.sleep(1) splash.remove(text_group1) if not counter%60: splash.remove(text_group2)
到这里,我们就已经将所有任务完成了! ### 心得体会 Adafruit ESP32-S3 TFT Feather这款开发板开发板提供的文档还是相当齐全的,而且社区资源也十分丰富,不仅有各种详细的教程,更有许多有意思的社区项目可供大家参考。同时,CircuitPython官方库的功能也十分强大,许多本来复杂的功能,都能用一两行代码就实现了,对创客十分友好。 美中不足的是,可能由于是国外的开发厂家,文档和社区都是英文,对初学者不是很友好;而且此次活动任务设置的难度梯度不是很合理,如果能把任务三和任务一对换一下,相信对于初学者会有更好的学习体验。 ## //内容三:可编译下载的代码// [任务代码连接](https://download.eeworld.com.cn/detail/eew_nagvq9/629836 "任务代码")
点赞
回复评论
暂无评论,赶紧抢沙发吧
最新活动
是德科技有奖直播 | 应对未来高速算力芯片的设计与测试挑战
免费申请 | 上百份MPS MIE模块,免费试用还有礼!
TI 有奖直播 | 使用基于 Arm 的 AM6xA 处理器设计智能化楼宇
Follow me第二季第3期来啦!与得捷一起解锁高性能开发板【EK-RA6M5】超能力!
报名直播赢【双肩包、京东卡、水杯】| 高可靠性IGBT的新选择——安世半导体650V IGBT
30套RV1106 Linux开发板(带摄像头),邀您动手挑战边缘AI~
随便看看
基于ARM_contexA9 led驱动编程
07年全国电子设计大赛报告(各类报告-全)
工程师情商低?看完这些你还这样认为吗?(是德科技印象测试部分作品欣赏1)
大侠帮忙看看这个Lm2678-adj的 电路
STM32 DMA+DAC 没有信号
最新uCOS-II v2.85源程序
AMD加入电源管理功能 解决Opteron散热问题
TI DSP具体型号含义
无线电收发设备的研究
開發mp3 player use VS1011
【pyboardCN V2】提交了原理图
symbol的问题
音频放大防自激问题求教
TJA1041-高速CAN 收发器
WinCE系统存储数据中的问题
答题赢Kindle:了解ADI 电网管理、能源计量方案,搞定智能电网项目
比尔盖茨的建议和忠告
各位觉得手机没有reset按键是设计缺陷吗?
atmega16中文资料
这样的一块M3不能通电使用真实暴殄天物
电子工程世界版权所有
京B2-20211791
京ICP备10001474号-1
京公网安备 11010802033920号
回复
写回复
收藏
回复