813|1

8

帖子

1

TA的资源

一粒金砂(中级)

楼主
 

【得捷电子Follow me第3期】任务提交贴【调整版】 [复制链接]

  本帖最后由 epix 于 2023-12-26 15:03 编辑

内容一:演示视频

https://training.eeworld.com.cn/video/38617

 

内容二:项目总结报告

任务1:使用MicroPython系统

下图是本次活动用到的所有器件. 核心器件为Seeed Studio XIAO ESP32C3. 另外, 图中已完成的有: USB线连接, 排针焊接, PCB天线安装, 扩展板安装. 另有两个传感器, 分别是环境光传感器和温湿度传感器, 以及配套的连接线.

扩展板上, 除了按键和连接器以外, 将会重点用到OLED显示器和蜂鸣器. 两个传感器分别为模拟接口和I2C接口, 将会连接至扩展板的IIC连接器和A0连接器.

硬件组装完成后, 首先刷写MicroPython系统.

主要用到乐鑫的ESP32刷写工具esptool和MicroPython的固件.

Esptool从官网 

链接已隐藏,如需查看请登录或者注册
 下载最新的Release. 这里使用的是Windows10操作系统, 所以下载的是 esptool-v4.6.2-win64.zip, 下载后解压备用.

MicroPython固件从官网 https://micropython.org/download/ESP32_GENERIC_C3/ 下载ESP32C3对应的固件. 这里下载的是 v1.21.0 (2023-10-05) .bin, 下载后放到esptool文件夹备用.

首先需要将开发板启动至bootloader模式. 按住reset键, 然后按住boot键, 然后松开reset键, 然后松开boot键即可

此时在计算机管理中, 能看到USB串行设备. 通过确认硬件ID VID:303A, 即可判断这就是Espressif Incorporated的设备, 即这里用到的开发板.

打开cmd并更改路径为esptool文件夹, 然后执行

esptool.exe --chip esp32c3 --port COM3 --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

等待一会儿

按下reset重启设备.

打开uPyCraft, 确保Tools – Serial 选择了COM3, board选择了esp32, 在下方看到>>>字样, 说明MicroPython刷写成功. 尝试直接执行print(‘Hello World!’), 成功回显, 说明MicroPython现在可以正常使用.

由于之前有用过PyCharm编写Python程序, 后续都将使用PyCharm (Community 2023.1.4)作为开发环境. PyCharm及Python安装配置不再赘述.

在PyCharm中安装MicroPython插件后, 新建一个项目, 在 File – Settings – Languages & Frameworks – MicroPython 页面打开MicroPython支持, 其中, Device type选择 Pyboard, Device Path填写COM3. PyCharm会提示需要安装依赖, 安装即可.

编写一个main.py 文件, 内容为打印字符串, 在文件上右键 Run ‘Flash main.py’ 即可运行. 从下方REPL中可以看到运行结果.

整个流程还是非常方便的, 从得捷网站下单, 物流送上门, 硬件组装, 软件安装, 命令测试都非常顺利.

任务2:驱动扩展板上的OLED屏幕

扩展板中OLED屏幕使用SSD1306驱动, 通过IIC通讯. 根据文档, 需要使用的是GPIO6/7两个针脚.

SSD1306驱动文件使用的是 

链接已隐藏,如需查看请登录或者注册
 直接将ssd1306.py加入项目, 并刷入核心版即可.

首先显示文字和简单图形.

  • from machine import Pin, I2C
  • import ssd1306
  • i2c = I2C(scl=Pin(7), sda=Pin(6))
  • oled = ssd1306.SSD1306_I2C(128, 64, i2c)
  • oled.fill(1)
  • oled.text('hello world', 1, 0)
  • oled.text('esp33c3', 0, 16)
  • oled.text('epix', 1, 32)
  • oled.rect(1, 48, 128, 16, 1)
  • oled.ellipse(97, 32, 16, 16, 1)
  • oled.show()

 

效果如图

显示图片

首先准备一张小于128*64的图片, 我这里使用了一张micropython的logo: 

链接已隐藏,如需查看请登录或者注册
 缩放为64*64, 二值化存为256色位图

这里我们偷懒一下, 不读调色板, 直接读64*64的数据, 反正要么黑色要么白色

  • import struct
  • with open('logo.bmp', 'rb') as f:
  • header_type = f.read(2)
  • assert header_type == b'BM'
  • f.seek(0x0A)
  • offset = struct.unpack('<l', f.read(4))[0]
  • print(offset)
  • f.seek(offset)
  • # data = f.read(64 * 64)
  • for i in range(64):
  • for j in range(64):
  • index = i * 64 + j
  • pixel = f.read(1)
  • oled.pixel(j+32, 63-i, 1 if pixel == b'\xff' else 0)
  • oled.show()

 

效果如图

任务3:控制蜂鸣器播放音乐

同样通过文档可以看到, 扩展板蜂鸣器接在GPIO5, 模拟信号输出. 只要直接输出波形即可.

用PWM可以直接实现方波. 然后控制PWM频率就可以控制音高, 设置50%占空比就可以发出声音.

先进行一个声音版blink测试.

  • from machine import Pin, PWM
  • import time
  • buzzer = PWM(Pin(5, Pin.OUT))
  • buzzer.freq(1000)
  • while True:
  • buzzer.duty_u16(32767)
  • time.sleep(1)
  • buzzer.duty_u16(0)
  • time.sleep(1)

实际效果见分帖

https://bbs.eeworld.com.cn/thread-1266332-1-1.html

接下来尝试演奏一些真正的曲子. 这里找了一个简单的欢乐颂的简谱作为演奏目标.

欢乐颂简谱本身只有12345五个音, 先把基础频率写好.

为了把简谱录入程序, 这里设计了一种简单的格式. 每个音符之间用逗号分隔.降八度的音高, 在音符前面加一个星号表示. 默认为四分音符, 后面跟下划线就变为八分音符. 后面加点就视为浮点音符. 后面加横线就延长一个四分音符的长度. 为了区分每个音符, 每个音符末尾会暂停声音50毫秒. 而如果出现了用波浪号代表的圆划线或延音线, 就连续演奏而不暂停.

最终代码如下:

  • note2freq = {'1': 262, '2': 294, '3': 330, '4': 349, '5': 392, }
  • song = '3,3,4,5,' \
  • '5,4,3,2,' \
  • '1,1,2,3,' \
  • '3.,2_,2-,' \
  • \
  • '3,3,4,5,' \
  • '5,4,3,2,' \
  • '1,1,2,3,' \
  • '2.,1_,1-,' \
  • \
  • '2,2,3,1,' \
  • '2,3_~,4_,3,1,' \
  • '2,3_~,4_,3,2,' \
  • '1,2,*5,3~,' \
  • \
  • '3,3,4,5,' \
  • '5,4,3,2,' \
  • '1,1,2,3,' \
  • '2.,1_,1-,'
  • tempo = 96
  • base_duration = 60 * 1000 / 96
  • gap_duration = 50
  • idx = 0
  • rich_notes = song.strip(',').split(',')
  • for rich_note in rich_notes:
  • freq_multiplier = 1
  • if rich_note[0] == '*':
  • freq_multiplier = 0.5
  • rich_note = rich_note[1:]
  • note = rich_note[0]
  • freq = int(note2freq[note] * freq_multiplier)
  • duration_multiplier = 1
  • gap = True
  • decos = rich_note[1:]
  • for deco in decos:
  • if deco == '.':
  • duration_multiplier *= 1.5
  • if deco == '_':
  • duration_multiplier *= 0.5
  • if deco == '-':
  • duration_multiplier *= 2
  • if deco == '~':
  • gap = False
  • duration = int(base_duration * duration_multiplier)
  • if gap:
  • duration -= gap_duration
  • buzzer.freq(freq)
  • buzzer.duty_u16(32767)
  • time.sleep_ms(duration)
  • if gap:
  • buzzer.duty_u16(0)
  • time.sleep_ms(gap_duration)
  • buzzer.duty_u16(0)

 

实际效果见分帖.
https://bbs.eeworld.com.cn/thread-1266332-1-1.html
注意正常可以区分各个音符, 而出现波浪号位置会连续演奏.

 

任务4:连接WiFi网络

连接WiFi可以说是ESP系列的强项了, MicroPython直接提供了简单连接库: network

先简单确保能够联网, 获得路由器分配的ip, 并显示信号强度. SSID和密码单独用一个文件存储, 方便修改.

  • import network
  • import time
  • from settings import SSID, PASSWORD
  • wlan = network.WLAN(network.STA_IF)
  • wlan.active(True)
  • wlan.connect(SSID, PASSWORD)
  • max_wait_sec = 15
  • for wait_sec in range(max_wait_sec):
  • if wlan.isconnected():
  • break
  • print('Waiting for connection...')
  • time.sleep(1)
  • if not wlan.isconnected():
  • raise RuntimeError('Could not connect to network')
  • print('Connected')
  • status = wlan.ifconfig()
  • rssi = wlan.status('rssi')
  • print(f'ip: {status[0]}')
  • print(f'rssi: {rssi}')

第一次联网图没截到, reset之后联网速度就很快了

然后访问网络资源. 例如得捷首页: https://www.digikey.cn/

直接使用MicroPython内置的requests库发起请求. 使用之前任务的显示屏相关代码将结果显示在屏幕上, 首先显示请求, 获得响应后显示内容.

由于整个网页很长, 这里只读了前1500Bytes, 然后提取网页标题, 显示出来. 但由于没有汉字字库, 只好把汉字去掉, 只显示英文等字符.

  • import requests
  • url = 'https://www.digikey.cn/'
  • oled.text(f'HTTP/1.0 GET', 0, 0)
  • oled.text(f'{url}', 0, 10)
  • oled.show()
  • resp = requests.get(url)
  • status_code = resp.status_code
  • content = resp.raw.read(1500)
  • text = content.decode('utf-8')
  • start = text.find('<title>')
  • end = text.find('</title>')
  • title = text[start + 7:end].strip()
  • print(title)
  • en_title = ''.join([char for char in title if char <= '\u4e00'])
  • print(en_title)
  • resp.close()
  • oled.text(str(status_code), 0, 30)
  • oled.text(en_title, 0, 40)
  • oled.show()

实际效果参考分帖 https://bbs.eeworld.com.cn/thread-1266333-1-1.html (为了演示效果, 在最前面清空显示器并等待了几秒)

 

可以看到请求还是花费了一点时间的.

REPL窗口里可以看到获取到的网页完整标题. 以及能显示的文字.

任务5:使用外部传感器

环境光传感器:

这是一颗模拟传感器. 通过Grove连接到核心板的GPIO2接口, 利用内置的ADC进行电压读取

ADC读取时可以以u16格式读数, 也可以直接拿到具体电压值. 直接调用方法即可.

这颗环境光传感器使用的是SENBA的LS06-S传感器, 串联一颗68k电阻, 中间输出至LM358. 由于输出与光照强度不太不线性, 这里不计算具体照度值, 只做定性分析.

旁边放一个手机作为亮度参考.

读取的数据通过显示屏显示.

代码如下

  • adc = ADC(Pin(2), atten=ADC.ATTN_11DB)
  • while True:
  • light_adc = adc.read_u16()
  • light_uv = adc.read_uv()
  • oled.fill(0)
  • oled.text(f'light_adc: {light_adc}', 0, 0)
  • oled.text(f'light_mv: {light_uv / 1000}', 0, 10)
  • oled.show()
  • sleep(1)

运行效果参考分帖https://bbs.eeworld.com.cn/thread-1266335-1-1.html.

可以看到, 一开始亮度较高, 手机和显示屏显示的数字都较大, 用手遮住光线, 手机和显示屏显示的数字都变得很小. 移开手后恢复较大数值. 下面绿色电路板仅为固定作用

 

 

温湿度传感器:

这颗是数字传感器, 通过I2C协议传输数据. 使用的芯片是AHT20, 可以直接按照规格书的说明通过I2C协议通信. 由于使用广泛, 已经有写好的库了, 这里直接调用ahtx0.py 即可. 首先需要确保此文件已写入核心板.

旁边放一个温湿度表作为参考.

同样, 读取的数据通过显示屏显示. 这里限制了读取速度为2秒一次, 以防止读取本身的发热

代码如下

  • import ahtx0
  • aht20 = ahtx0.AHT20(i2c)
  • while True:
  • t = aht20.temperature
  • h = aht20.relative_humidity
  • oled.fill(0)
  • oled.text(f'T: {t}', 0, 0)
  • oled.text(f'H: {h}', 0, 10)
  • oled.show()
  • sleep(2)

运行效果参考分帖 https://bbs.eeworld.com.cn/thread-1266335-1-1.html.

可以看到, 一开始温度与湿度与温湿度表相近, 读取较为准确. 用手指堵住sensor后, 由于人体的温度和汗液, 导致湿度和温度都有明显的快速上升.

任务6:远程控制滚轮

任务动机

看漫画/视频时, 翻页/快进快退总需要手动控制, 但有时是躺在床上椅子上的奇葩姿势, 按鼠标键盘并不方便, 如果使用蓝牙鼠标键盘, 则会有个头过大按键过小等问题. 这里翻页/快进快退需求很简单, 就是两个键. 所以就直接做一个吧.

方案选择

要做滚轮显然需要能检测滚动的东西, 一般是旋转编码器, 常用的有光栅/机械/磁, 这几种鼠标上都有用. 光栅需要做对管, 机械一般是通过触点接通切换来实现相对位置编码器, 磁编码器是用霍尔元件. 现在有部分鼠标/手柄使用了磁编码器, 有一些明显的好处, 结构简单, 无机械接触. 这里我也是用磁编码器实现. 旋转轴是竖直的, 与一般鼠标滚轮不同. 这样做的好处是不必松开手指就可以旋转无限圈.

控制方式上, 可以通过核心板上的各种连接实现, USB/WiFi/BLE. 这里由于本核心板USB只支持串口, 所以放弃USB方式. WiFi控制的话, 还需要服务端. BLE就是普通蓝牙鼠标的方式. 这里选择WiFi方式控制, 直接HTTP发送滚动请求. 好处是无视蓝牙范围限制, 扩展WiFi比扩展蓝牙简单多了. 缺点是只有有服务端的电脑才能被控制, 以及经过HTTP会增加许多延迟.

服务端不打算手写, 直接用Unified Remote Server(以下简称UR), 虽然UR没有直接开放api, 不过有个简单的网页前端. 只要模拟网页前端即可.

硬件实现

磁编码器型号选择上, AS5600似乎更流行一点, 最后使用的是MT6701, 精度稍微高一点.

磁铁使用圆磁铁, 注意要使用直径充磁的方向, 才能正常被磁编码器检测.

MT6701支持多种通信方式, 这里选择与任务2中相同的I2C接口通信. 封装选择SOP-8, 手动焊接容易一点. 首先参考MT6701文档的I2C参考电路设计:

画一个简单的PCB.

编码器部分体积越小越好, 选择较薄的PCB打板, 人肉SMT. 接口使用MX 51146, 容易插拔也够小.

另做一条MX51146连接线.

为了旋转顺滑, 使用了一颗滚珠轴承.

整个编码器部分的机械结构

外形

剖面

爆炸图

外壳使用尼龙3D打印

组装好的编码器部分

编码器部分与核心版的电源和I2C接口连接即可.

考虑到本身就是无线控制, 连上一颗 14500锂电池.

所有硬件就安装完了.

软件实现

首先是MT6701的数据读取.

先从REPL扫一下I2C设备:

60是之前用过的显示屏驱动, 81是RTC. 糟糕, 好像没有发现MT6701.

还是得看文档, 文档里提到I2C的地址是0x06, 而MicroPython的I2C.scan只会扫描地址大于0x08的设备.

按照文档, 直接按照地址读是有信息的.

按照计算公式, 一圈是16384

拿出Serial Studio读一下试试

  • while True:
  • high_bit = i2c.readfrom_mem(0x06, 0x03, 1)
  • low_bit = i2c.readfrom_mem(0x06, 0x04, 1)
  • value = int.from_bytes(high_bit + low_bit, 'big') >> 2
  • print(f'/*{value}*/')
  • time.sleep_ms(1)
  •  

serialstudio效果参考分帖视频 https://bbs.eeworld.com.cn/thread-1266941-1-1.html

 

可以观测到正反转时读取到角度绝对值的变化, 过零点时的突变.

这样只要连续读取角度值, 然后计算与之前记录值的变化, 大于阈值就算转了一下就可以了. 过零点的情况需要特判一下.

UR控制方面, 参考一篇home-assistant论坛的文章, 然后抓包一下网页端

不难发现用这个就可以模拟左右箭头.

这样就都连起来了, 只要旋转超过阈值, 就根据旋转方向, 发送左键或右键指令

简单把代码整理一下. 就可以运行了. 快进快退视频. 

参考分帖视频 https://bbs.eeworld.com.cn/thread-1266941-1-1.html

 

翻漫画之类图片当然也可以.

参考分帖视频 https://bbs.eeworld.com.cn/thread-1266941-1-1.html

 

未来计划

做个更好的外壳, 把电池等都装好.

扩展板不是必须的, 可以去掉, 大幅减小设备体积.

逆向UR的socket接口, 实现更低的控制延迟.

Wireshark抓包其实能看到类似的控制内容, 但是还需要更多逆向.

做个BLE版, 方便给安卓设备使用.

分帖汇总

必做任务1:使用MicroPython系统

[作品提交] 【得捷Follow me第3期】任务1:使用MicroPython系统
必做任务2:驱动扩展板上的OLED屏幕

[作品提交] 【得捷Follow me第3期】任务2:驱动扩展板上的OLED屏幕
必做任务3:控制蜂鸣器播放音乐

[作品提交] 【得捷Follow me第3期】任务3:控制蜂鸣器播放音乐
必做任务4:连接WiFi网络

[作品提交] 【得捷Follow me第3期】任务4:连接WiFi网络
必做任务5:使用外部传感器

[作品提交] 【得捷Follow me第3期】任务5:使用外部传感器
可选任务6:

[作品提交] 【得捷Follow me第3期】任务6:远程控制滚轮

总结(心得体会)

很幸运有机会参加这次活动. Seeed Studio XIAO ESP32C3 开发板本身还是很好玩的, 尺寸超小, 接口够全, USB-C接口. 板载4M存储啥都放得下. 扩展板把屏幕和各种接口都集成好了, 各种传感器/电池都方便连接, RESET键用着很顺手.  MicroPython非常简单, 就和在电脑上跑Python脚本一样, 直接有一个REPL对调试有很大帮助. 无线功能很强大, 连接WiFi很容易, 上网以后有无限可能. 之后将继续使用XIAO和MicroPython进行更多开发.

 

内容三:可编译下载的代码

https://download.eeworld.com.cn/detail/epix/630280

 

最新回复

大佬用心了,这第二版的任务提交,花了不少心思吧,感谢分享!  详情 回复 发表于 2023-12-25 07:27
点赞 关注
 
 

回复
举报

7204

帖子

11

TA的资源

版主

沙发
 
大佬用心了,这第二版的任务提交,花了不少心思吧,感谢分享!
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条
有奖直播:当AI遇见仿真,会有什么样的电子行业革新之路?
首场直播:Simcenter AI 赋能电子行业研发创新
直播时间:04月15日14:00-14:50

查看 »

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网 1

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表