基本信息
规则
项目进度
视频课程
案例
内容介绍
软件 & 硬件
元器件
传感器类型:运动检测传感器 接口类型:I2C
红外遥控接收模块 工作电压:2.7V~5.5V 工作电流:1.2mA 接收角度:45°@垂直;45°@水平 贴片红外线接收头 38kHz
树莓派基金会推出的低成本、高性能、双核Arm Cortex M0+微控制器,主频可以到133MHz RAM容量:264KB GPIO端口数量:30
开关降压芯片 - 1.8-5.5V电压输入,3.3V 1.8V 1.2V或可调输出,输出电流可达800mA,
2.3~3.6V宽压 16Mbit Flash,功耗更低、速度更快
双向电位计游戏摇杆
高速红外LED, 940 nm, GaAlAs, MQW
软件
MicroPython是一款编程语言兼容Python3的软件,用C写成的,能够运行在微控制器的硬件上并进行了相应的优化。
C 编程是一种通用的、过程式的、命令式的计算机编程语言,由贝尔电话实验室的 Dennis M. Ritchie 于 1972 年开发,用于开发 UNIX 操作系统。
工具
针对初学者的Python IDE工具
平台
树莓派官方发布的基于自行设计芯片的邮票孔模块,双核Arm Cortex M0+,片内260KB RAM,板上有2MB Flash,售价仅4美元
电路图
物料清单
附件
-
Gamekit_rp2040_Gerber.rar
-
game2040-V3-20211228.pdf
测试代码:https://gitee.com/eetree-git/RP2040_Game_Kit
2022年寒假在家一起练活动已于2022年2月27日结束
2022年寒假练活动汇总:https://www.eetree.cn/project/detail/649
点击【支持一下】即可参与活动,购买及参加。
注:项目中必须用到此平台规定的板卡,其他板卡完成任务,不符合退款要求,收到板卡7天内如有质量问题可联系退换,使用之后不支持退换。
【基于树莓派Pico的嵌入式系统学习平台】所需完成的项目,任选其一完成即可(于1月14日前完成发货,活动时间截止到2022年2月27日):
项目1 - 能控制LCD和电脑界面的“鼠标”
-
利用板上的四向摇杆和按键设计一款“鼠标”
-
在240*240的LCD屏幕内可以通过该鼠标进行菜单选择和参数控制(在屏幕上要有上图中图形化的箭头形状)
-
通过USB端口可以控制PC屏幕上的光标移动和点击操作,行使电脑鼠标的功能
可以用箭头指示相应的按键方向,圆点指示按键
项目2 - 带学习功能的红外遥控器
-
通过板上的红外接收器,接收任何一款家用遥控器的控制信号,并能够对遥控器的控制信号进行识别
-
在LCD上绘制一个遥控器控制界面,并能够通过四向摇杆和按键来行使原来遥控器的控制操作
项目3 - 复古游戏移植
-
设计或移植一款经典的游戏(硬禾学堂上已经实现的贪吃蛇等游戏除外),通过LCD屏显示,通过按键和四向摇杆控制游戏的动作:
-
经典的Pong
-
挖地雷
-
打飞机
-
俄罗斯方块
- .......
-
在游戏中要通过蜂鸣器播放背景音乐
项目4 - 制作一款MCU、FPGA调试器、下载器
-
使用板上的扩展端口上的数字信号
-
可以对任意一款MCU或FPGA进行调试、固件的下载
项目5 - 制作一款简易的逻辑分析仪,并支持SPI、I2C的协议分析
-
使用板上的扩展端口上的数字信号
- 能够对SPI、I2C的外设进行控制设置、参数读写
- 数字信号的波形显示在LCD上或通过USB传输到PC上在上位机进行显示
项目6 - 实现历届全国大学生电子设计竞赛中的任意一个题目
-
使用板上的扩展端口上的数字信号以及2路模拟输入
- 自行搭配外围器件或模块
-
实现以下类型中的任意一个题目:
- 搭载模拟链路实现信号采集及分析,可以针对电路分析、测试测量类的题目
- 搭载传感器、电机、开关等实现控制类的题目
以上的6个项目不限用MicroPython或C/C++语言编写。
再补充3个新项目(后续还会补充):
项目7 - 制作一个模拟电压表
- 利用240*240的显示屏制作一个双通道电压表,类似上图的效果(其中的一个通道),通过指针的摆动显示当前的电压。
- 被测对象为四向摇杆的x、y轴电位计,这两个电位计分压从0-3.3V摆动,推动摇杆,表盘上的指针摆动,并在下面用数字的方式显示当前的电压值。
- 完成表盘的设计以及校准,能够准确测量电压,可以切换到12Pin扩展排针上的两个模拟通道输入端,对这两个输入信号进行测量 - 手指触碰表针摆动,
- 通过提供的杜邦线连接其它数据端口,编程数据端口输出低频率的数字波形(会在0-3.3之间摆动),看指针的摆动
- 指针摆动做出连续移动的效果,真实仿真模拟表盘的工作机制
项目8 - 利用姿态传感器制作一个水平仪
如上面几个图片的效果,在LCD屏上设计一款水平仪,通过一个滚动的小球或气泡,来显示当前板子的倾斜度,当板子处于水平位置的时候,小球停在屏幕的正中间,倾斜板子,小球偏移,并能够显示偏移的角度(二维信息)
项目9 - 制作一个可切换功能的计算器
用LCD做界面,用4向摇杆和两个按键做输入,用姿态传感器切换功能,制作一款具有四种计算功能、通过姿态传感器可以切换功能的计算器,比如下图中的三个功能,再增加一个程序员常用到的制式转换器。
制作者可以自己定义4种不同的功能,旋转板子可以切换到不同功能的界面,用四向摇杆和按键搭配进行计算。
项目10 - 制作一个离线语音助手(需自己搭配MEMS麦克风模块)
网上有人分享了利用MEMS Mic模块制作的USB麦克风,使用了DMA、PIO,并在PC上通过上位机软件对音频波形进行显示
我们更进一步,通过外接一个MEMS麦克风模块,将数据传输到PC或树莓派,通过TinyML制作一个简单的具有语音识别、语音播报功能的语音助手,这个语音助手可以离线使用。
项目11 - 制作一个图形化显示、超温报警的温度计
- 在LCD屏上显示一个图形化的温度计,并实时显示当前的温度(通过RP2040内部的温度传感器测量)
- 可以通过摇杆或按键设定报警温度阈值(如上图下面的部分,需要补充上数字)
- 可以对芯片稍微加温,使温度超过设定的阈值,温度图示颜色变红,且蜂鸣器发出报警声音
- 给芯片降温到阈值一下,温度传感器颜色变绿,蜂鸣器停止报警
————————————————————————————————————————
活动流程及时间安排
硬禾学堂为鼓励大家真心玩起来,我们活动一直在采用“玩转就免费”的方针,鼓励大家用心去学,本次的活动依旧采用这种方式:
- 购买:活动参与者需先从硬禾学堂购买板卡,于2022.2.27前均可购买,下单即参加活动(12月3日前下单的板卡不能用于退款)。希望大家尽快完成下单,以便工作人员有货时尽快发货。
- 发货:当天下午三点前下单的可当天发货,周末休息。因一些学校放假较早,保证稳妥寄送,下单前请填写一定可以收到货的地址。待同学们都收到板卡后,硬禾官方将采用每个板卡2-3场直播的方式教大家上手,并有技术交流群一起讨论学习,由于板卡数量有限,早参加早占取名额,也能尽早收到板卡。
- 活动时间:从收到板卡日起,活动参与者需于2022年2月27日晚12点前实现规定的功能,并按照规则将项目上传到电子森林项目网站,所需提交材料和电子森林使用说明请点此查阅,逾期提交者无效。
- 审核时间:硬禾学堂将于2022年3月18日前审核完毕并邮件告知审核通过者。
- 返款时间:审核结束之后,将于2022.2.21-2022.4.15期间完成退款。
- 毕业生福利:如果你是大四毕业生,在此活动中购买板卡,并用本板卡来完成你的毕设(不限制所做项目),可截止到2022年6月30日前上传你的毕设项目于电子森林,硬禾将给予退款(若中间申请开票,则不能再退款)。
注:本次寒假练所发板卡均配有数据线且包邮。
————————————————————————————————————————
以下说明包含寒假在家一起练材料提交说明以及电子森林项目网站使用说明(请认真查阅),活动期间所有活动板卡不开票,请备注开票的于活动结束之后联系工作人员统一开票,符合退款的不开票。
2022年“寒假在家一起练”材料提交及方式
一、完成项目之后在电子森林项目网站需提交以下材料
上传之前请先使用手机号注册电子森林账号:https://www.eetree.cn/,项目标题请命名为:用/基于xxx实现/完成/设计/制作xxx
1. 3-5分钟短视频(要求横屏且1080p)
- 简短的自我介绍
- 硬件介绍
- 项目设计思路
- 项目实现功能(重要的代码介绍和实物功能展示)
注:视频太短(仅几十秒),视频无板卡演示效果,拍摄不清晰,镜头太晃均不合格。
2. 项目总结报告(即说明文档)
- 项目描述(项目介绍、设计思路和框图/软件流程图、简单的硬件介绍、实现的功能及图片展示、主要代码片段及说明、遇到的主要难题及解决方法、未来的计划或建议等,需达到除代码之外的约1500字左右)
项目案例参考:https://www.eetree.cn/project/detail/167,https://www.eetree.cn/project/detail/498
- 可编译下载的代码(放在项目的附件,用于验证)
注:项目报告中没有源代码和实现结果的展示图者均被退回
二、项目提交后需提交以下材料到training@eetree.cn邮箱,以作项目关联和顺利返款
邮件请命名:2022寒假在家练+树莓派RP2040板+真实姓名
1. 电子森林注册昵称(不是用户名)
2. 下单时所留姓名和电话(如果你是大四毕业生,用此板卡来完成你的毕设,还需发送你的真实姓名+学校+专业+你的学生证+毕业设计课题)
订单查看方式:请关注“硬禾学堂”公众号,移动端点击底部“硬禾学堂”,进入后点击“我的”,即可查看全部订单信息。
3. 订单号和付款截图
在全部订单信息中点击对应订单即可复制订单号:

在“微信支付”中可截图付款凭证
注:如不参与退款,则无需发送邮件,仅提交项目即可,并在团队成员处添加个人姓名和学校
————————————————————————————————————————
电子森林项目网站使用说明
2. 请注意每编辑完成一个页面一定要点击底部“保存”
3. “基本信息”页
- 标题请按照规则填写
- 封面图一定要更换成适合本人项目的图,不要用默认的
- 视频请先上传到B站/优酷/腾讯,然后在“视频代码”处粘贴iframe格式代码
- 类型选择“分享类”
- 标签请填写3-5个描述你所做项目的关键词,其中一个要包括“2022寒假在家练”标签
- 在“高校”处选择个人学校
- 在“团队介绍”和“团队成员”处添加个人姓名和学校/公司
注:寒/暑假练项目均为个人项目,团队合作完成者仅退一人款
- 在“描述”中编辑项目总结报告
- 图片的上传请点击右上角的“上传”
- 代码的插入请使用插入工具
- 注意格式整洁,正文字号建议用12pt,标题建议用14pt,并加粗显示,正文首行不要缩进两字符
- 描述下面的“规则”、“参与推广”、“支付协议”则无需填写’
4. “进度”页和“软硬件”
- 在“进度”页中可添加个人的每一个阶段项目进程

- 在“软硬件”页中可选择使用的软件和工具,若没有则无需填写
- 在附件处一定要添加可下载的代码文件,若是文件太大, 可上传到百度网盘上,并在“描述”中粘贴链接
- 编辑完成后一定要点击“保存”
5. 其他页
- “视频课程”、“应用案例”和“商品”页若没有则无需填写
6. 点击“预览”,并“发布”项目
- 本人先点击“预览”查看自己的项目,若没有问题之后再点击“发布”
- 发布之后若查出存在问题,可点击“取消审核”再次修改。若在项目通过之后发现存在问题,依旧可再次修改项目,直到项目完善

与RP2040相关的一些参考项目 更新发布于 2021年12月11日
Fabien Chouteau's PicoProbe PCB Turns a Raspberry Pi Pico Into an Easy-to-Use SWD Debugger
ShawnHymel发布的Raspberry Pi Pico and RP2040 - C/C++ Part 2: Debugging with VS Code
基于树莓派Pico和ESP32制作的基于网页的示波器:
- Pi Pico ADC input using DMA and MicroPython
- Pi Pico wireless Web server using ESP32 and MicroPython
- Web display for Pi Pico oscilloscope
关于ADC采样和FFT:
树莓派和OpenOCD, 可用于制作下载器的参考
用网页实现示波器波形显示 - 有开源代码 更新发布于 2021年12月15日
用RP2040实现逻辑分析仪的一些参考资源 更新发布于 2021年12月16日
在RP2040上用CircuitPython玩Pipboy游戏 更新发布于 2021年12月16日
来源:https://learn.adafruit.com/pip-boy-2040
硬件构成:
安装CircuitPython: Install CircuitPython
编程Pip-Boy:Code the Pip-Boy 2040
# SPDX-FileCopyrightText: 2021 john park for Adafruit Industries
# SPDX-License-Identifier: MIT
import time
import board
from adafruit_simplemath import map_range
import displayio
from adafruit_seesaw.seesaw import Seesaw
import adafruit_imageload
from adafruit_st7789 import ST7789
displayio.release_displays()
i2c_bus = board.I2C()
ss = Seesaw(i2c_bus)
spi = board.SPI() # setup for display over SPI
tft_cs = board.D5
tft_dc = board.D6
display_bus = displayio.FourWire(
spi, command=tft_dc, chip_select=tft_cs, reset=board.D9
)
display = ST7789(display_bus, width=280, height=240, rowstart=20, rotation=270)
screen = displayio.Group() # Create a Group to hold content
display.show(screen) # Add it to the Display
# display image
image = displayio.OnDiskBitmap("/img/bootpip0.bmp")
palette = image.pixel_shader
background = displayio.TileGrid(image, pixel_shader=palette)
screen.append(background)
# load cursor on top
cursor_on = True
if cursor_on:
image, palette = adafruit_imageload.load("/img/cursor_green.bmp")
palette.make_transparent(0)
cursor = displayio.TileGrid(image, pixel_shader=palette)
screen.append(cursor)
cursor.x = 0 # hide cursor during bootup
cursor.y = 0
display.show(screen)
boot_file_names = [
"/img/bootpip0.bmp",
"/img/bootpip1.bmp",
"/img/bootpip2.bmp",
"/img/bootpip3.bmp",
"/img/bootpip4.bmp",
"/img/bootpip5.bmp",
"/img/statpip0.bmp",
]
screenmap = {
(0): (
"/img/statpip0.bmp",
"/img/statpip1.bmp",
"/img/statpip2.bmp",
"/img/statpip3.bmp",
"/img/statpip4.bmp",
"/img/statpip2.bmp",
"/img/statpip6.bmp",
"/img/statpip7.bmp",
"/img/statpip8.bmp",
),
(1): ("/img/invpip0.bmp", "/img/invpip1.bmp"),
(2): ("/img/datapip0.bmp", "/img/datapip1.bmp", "/img/datapip2.bmp"),
(3): ("/img/mappip0.bmp", "/img/mappip1.bmp", "/img/mappip2.bmp"),
(4): ("/img/radiopip0.bmp", "/img/radiopip1.bmp"),
(5): ("/img/holopip0.bmp", "/img/holopip1.bmp"),
}
BUTTON_UP = 6 # A is UP
BUTTON_RIGHT = 7 # B is RIGHT
BUTTON_DOWN = 9 # Y is DOWN
BUTTON_LEFT = 10 # X is LEFT
BUTTON_SEL = 14 # SEL button is unused
button_mask = (
(1 << BUTTON_UP)
| (1 << BUTTON_RIGHT)
| (1 << BUTTON_DOWN)
| (1 << BUTTON_LEFT)
| (1 << BUTTON_SEL)
)
ss.pin_mode_bulk(button_mask, ss.INPUT_PULLUP)
tab_number = 0
sub_number = 0
def image_switch(direction): # advance or go back through image list
# pylint: disable=global-statement
global tab_number
# pylint: disable=global-statement
global sub_number
# pylint: disable=global-statement
global image
# pylint: disable=global-statement
global palette
if direction == 0: # right
tab_number = (tab_number + 1) % len(screenmap)
if direction == 1: # left
tab_number = (tab_number - 1) % len(screenmap)
if direction == 2: # down
sub_number = (sub_number + 1) % len((screenmap[tab_number]))
if direction == 3: # up
sub_number = (sub_number - 1) % len((screenmap[tab_number]))
image = displayio.OnDiskBitmap(screenmap[tab_number][sub_number])
palette = image.pixel_shader
screen[0] = displayio.TileGrid(image, pixel_shader=palette)
last_joy_x = 0
last_joy_y = 0
# bootup images
for i in range(len(boot_file_names)):
image = displayio.OnDiskBitmap(boot_file_names[i])
palette = image.pixel_shader
screen[0] = displayio.TileGrid(image, pixel_shader=palette)
time.sleep(0.1)
while True:
time.sleep(0.01)
joy_x = ss.analog_read(2)
joy_y = ss.analog_read(3)
if (abs(joy_x - last_joy_x) > 3) or (abs(joy_y - last_joy_y) > 3):
if cursor_on:
cursor.x = int(map_range(joy_x, 10, 1023, 0, 264))
cursor.y = int(map_range(joy_y, 10, 1023, 224, 0))
last_joy_x = joy_x
last_joy_y = joy_y
buttons = ss.digital_read_bulk(button_mask)
if not buttons & (1 << BUTTON_UP):
image_switch(3)
time.sleep(0.15)
if not buttons & (1 << BUTTON_RIGHT):
sub_number = 0 # go back to top level screen of tab grouping
image_switch(0)
time.sleep(0.15)
if not buttons & (1 << BUTTON_DOWN):
image_switch(2)
time.sleep(0.15)
if not buttons & (1 << BUTTON_LEFT):
sub_number = 0
image_switch(1)
time.sleep(0.15)
if not buttons & (1 << BUTTON_SEL):
print("unused select button")
使用CircuitPython在RP2040上播放MP3音乐 更新发布于 2021年12月16日
来源:
Github上的资源:MP3_Playback_RP2040
完整的项目文件:Project Bundle
硬件部分:使用了PAM8302放大器
- PAM8302 A+ to Pico GP0
- PAM8302 A- to Pico GND
- PAM8302 VIN to Pico 3.3v
- PAM8302 GND to Pico GND
- PAM8302 screw terminal + to speaker +
- PAM8302 screw terminal - to speaker -
CircuitPython兼容的MP3文件:
CircuitPython supports any MP3 file, as long as it is the right bit rate and sample rate for your board.
Mono and stereo files less than 64kbit/s work, with sample rates from 8kHz to 24kHz. The RP2040 has a PWM output with 10 bits, so there's not much point in using high bit rates.
代码:
"""
CircuitPython single MP3 playback example for Raspberry Pi Pico.
Plays a single MP3 once.
"""
import board
import audiomp3
import audiopwmio
audio = audiopwmio.PWMAudioOut(board.GP0)
decoder = audiomp3.MP3Decoder(open("slow.mp3", "rb"))
audio.play(decoder)
while audio.playing:
pass
print("Done playing!")
在RP2040上移植游戏的参考 更新发布于 2021年12月18日
为树莓派Pico和其它支持任天堂Switch, XInput和DirectInput的RP2040微控制器设计的手柄固件 更新发布于 2021年12月26日
为树莓派Pico和其它支持任天堂Switch, XInput和DirectInput的RP2040微控制器设计的手柄固件
GP2040 Firmware
GP2040 is a gamepad firmware for the Raspberry Pi Pico and other boards based on the RP2040 microcontroller, and provides high performance with a rich feature set across multiple platforms. GP2040 is compatible with PC, MiSTer, Android, Raspberry Pi, Nintendo Switch, PS3 and PS4 (legacy controller support).
Full documentation can be found at https://gp2040.info.(这个链接会出现404错误,不过可以访问页面上的其它菜单)
Features
- Selectable input modes (XInput, DirectInput and Nintendo Switch)
- Overclocked polling rate to 1000 Hz (1 ms) in all modes, with less than 1 ms of input latency
- Multiple SOCD cleaning modes - Neutral, Up Priority (a.k.a. Hitbox), Second Input Priority
- Left and Right stick emulation via D-pad inputs
- Per-button RGB LED support
- PWM and RGB player indicator LED support (XInput only)
- Saves options to internal memory
- Support for 128x64 monochrome I2C displays using SSD1306, SH1106 or SH1107 display drivers.
- Built-in configuration app hosted via embedded webserver...no downloading a separate app!
Take a look at the GP2040 Usage page for more details.
Performance
Input latency is tested using the methodology outlined at WydD's inputlag.science website, using the default 1000 Hz (1 ms) polling rate in the firmware.
v0.3.1 | All | 1 ms | 0.56 ms | 1.32 ms | 0.85 ms | 0.24 ms | 95.95% | 4.05% | 0% |
Full results can be found in the GP2040 Firmware Latency Test Results Google Sheet.
Installation
Prebuilt uf2
files are available in the Releases section for the following boards and controllers:
- Raspberry Pi Pico and other pin-compatible boards such as the Pimoroni Pico Lipo (wiring diagram)
- Pico Fighting Board
- Crush Counter (formerly the OSFRD)
- DURAL
Several other working example configurations are located in the configs folder.
The instructions will slightly vary based on your device. These instructions are for a Raspberry Pi Pico.
If the device has been previously used for something other than GP2040, please flash this file first to clear the on-board storage: flash_nuke.uf2. After flashing the nuke file, waiting a minute for the clear program to run and the RPI-RP2 drive to reappear.
- Download the latest
GP2040.uf2
file from the Releases section for your board (e.g.GP2040-PiPico.uf2
for the Raspberry Pi Pico). - Unplug your Pico.
- Hold the BOOTSEL button on the Pico and plug into your computer. A new removable drive named
RPI-RP2
should appear in your file explorer. - Drag and drop the
GP2040.uf2
file into the removable drive. This will flash the board. - The board is now running the GP2040 firmware and will appear as a controller on your computer.
Support
If you would like to discuss features, issues or anything else related to GP2040 please create an issue or join the OpenStick GP2040 Discord channel.
Frequently Asked Questions Which input mode should I use?
Generally speaking, XInput will be the mode of choice for everything except Nintendo Switch and PlayStation 3. XInput mode is the most fully-featured, has the best compatibility with PC games and is compatible with console adapters like the Brook Wingman product line. All things being equal, performance is the same in all modes.
What is the extent of PS4 support in GP2040?
GP2040 will work on PS4 games that implement support for legacy PS3 controllers. Many of the popular PS4 fighting games have this support.
Does/can/will GP2040 natively support the PS4, PS5, Xbox One or Xbox Series consoles?
These consoles implement security to prevent unauthorized accessories from being used. The process of cracking or bypassing that security may not be legal everywhere. These consoles could be supported in the future if a user-friendly and completely legal implementation method is found.
Can I use multiple controllers with GP2040 on the same system?
Yes! Each board with GP2040 is treated as a separate controller. The one thing to keep in mind would be to only run the web configurator for one controller at a time.
Does GP2040 really have less than 1 ms of latency?
Yes...if your platform supports 1000 Hz USB polling. GP2040 is configured for 1000 Hz / 1 ms polling by default in all modes, however some systems override or ignore the polling rate the controller requests. PC and MiSTer are confirmed to work with 1000 Hz polling. Even if your system doesn't support a USB polling rate that high, you can feel comfortable knowing GP2040 is still reading and processing your inputs as fast as the target system will allow.
Do the additional features like RGB LEDs, Player LEDs and OLED displays affect performance?
No! The RP2040 chip contains two processing cores. GP2040 dedicates one core to reading inputs and sending them via USB, while the second core is used to handle any auxiliary modules like LEDs and display support. No matter how crazy the feature set of GP2040 becomes, it's unlikely your controller's input latency will be affected.
Why do the buttons have weird labels like B3, A1, S2, etc.?
GP2040 uses a generic system for handling button inputs that most closely maps to a traditional PlayStation controller layout with a few extra buttons. This means 4 face buttons (B1-B4), 4 shoulder buttons (L1, L2, R1, R2), Select and Start (S1, S2), 2 stick buttons (L3, R3) and 2 auxiliary buttons for things like Home and Capture (A1, A2) on the Switch. The GP2040 documentation and web configurator have a dropdown to change the labels to more familiar controller layouts. You can also refer to the button mapping table on the GP2040 Usage page.
Why use PlatformIO instead of <insert favorite project setup>?
Setting up a development environment to build Pico SDK projects is a manual process which requires several components to be installed and configured. Using PlatformIO allows easy installation and updating of build and project dependencies, and makes for a less confusing experience for new developers and people that just want to make a few tweaks for a custom build.
What kind of voodoo is that built-in web configurator?
There's no magic here, just some useful libraries working together:
- Single page application using React and Bootstrap is embedded in the GP2040 firmware
- TinyUSB library provides virtual network connection over USB via RNDIS
- lwIP library provides an HTTP server for the embedded React app and the web configuration API
- ArduinoJson library is used for serialization and deserialization of web API requests
Acknowledgements
- Ha Thach's excellent TinyUSB library examples
- fluffymadness's tinyusb-xinput sample
- Kevin Boone's blog post on using RP2040 flash memory as emulated EEPROM
- bitbank2 for the OneBitDisplay and BitBang_I2C libraries, which were ported for use with the Pico SDK
在树莓派Pico和RP2040上实现机器学习 更新发布于 2021年12月26日
文章链接:在Pico和RP2040上实现机器学习
Although the Raspberry Pi Pico comes with the RP2040 chip that lacks the performance to implement machine learning inference for its applications. However, we saw a person detection use case through ArduCAM and TensorFlow lite interface. But, the processing performance of the use case was on the slower side. Additionally, a recent Eben Upton presentation also unveiled that due to low power requirements the board compensates the processing efficiency. Hence, it offers low-performance for edge inference and machine learning use cases.
Eben Upton’s teaser on improvement in machine learning and the future scope of “Pi Silicon” revealed potential growth and development in edge inference applications. The demand for RP2040 boards has given rise to the market necessity for more boards. This demand can only be fulfilled if more boards with RP2040 chip are available in the market and company “partners such as Adafruit, Pimoroni, Adafruit and Sparkfun are start releasing their own hardware, many with features not found on the Pico.”
The RP2040 SoC enables the maximum performance for machine learning inference at the lowest power, this is due to its energy-efficient dual Arm Cortex-M0+ cores working at a comparatively higher frequency of 133 MHz. Hence, there are a few third-party Raspberry Pi RP2040 boards dedicated to ML applications. Some of these are:
Arduino Nano RP2040 Connect Board for Machine Learning InferenceArduino Nano RP2040 Connect board is one such board featuring an STMicro MEMS sensor with 9-axis IMU and microphone. These are for the data collection on which the edge inference modeling can be done. Additionally, it includes 16MB external SPI flash, a u-blox NINA WiFi & Bluetooth module for flexible connectivity. “This can allow the users to develop connected products leveraging the hardware powered by Raspberry silicon. A solid radio module with efficient performance, and the Arduino Create IoT Cloud.”
SparkFun also came up with a MicroMod RP2040 processor similar to its other processor cards which are compatible with different SparkFun carrier boards. Hence, the MicroMod RP2040 card can act as a dynamic add-on for various carrier boards depending on the applications of the users. Specifically, the ML carrier board would be a great fit for the RP2040 card due to its ML functionalities. For more information visit the detailed article on SparkFun’s processor cards and carrier boards.
Additionally, Arducam has specifically named its RP2040 board as Arducam Pico4ML. The board comes with all Tensorflow Lite Micro use-cases on a single platform. Arducam says “as the RP2040 SoC is based on a high-clocked dual Cortex-M0+, it’s also a remarkably good platform for endpoint AI, or more specifically TinyML.” The new ArduinoML TensorFlow Lite board comes with the following functionalities:
- Wake word detection
- Magic wand
- Person detection
- On-device LCD display
- Other sensor-based analysis
However, as discussed earlier the person detection example using Arducam and TensorFlow lite with Raspberry Pi Pico was quite slow. So, it is still a dilemma if the ML use cases will perform efficiently on the Arducam Pico4ML. The board is not yet released, so you can join the waitlist and follow the Twitter updates of the board. The links for the same are available on the product page.
Looking at the few drawbacks of the Raspberry Pi Pico in terms of machine learning, Eben Upton’s presentationhas also unveiled the Raspberry Pi’s plan to work on its current RP2040 chip to enhance its edge computing capacity for machine learning. The organization aims to build lightweight on-device AI accelerators for low power machine learning inference and edge computing.
康奈尔大学学生项目对RP2040的探索 更新发布于 2021年12月26日
这是美国康奈尔大学的学生项目,探索RP2040的功能和性能,值得我们学习和借鉴。
Cornell University ECE4760
RP2040 testing
Introduction
The RP2040 is a dual-core Cortex M0 produced by Raspberry Pi. It is attractive for this course because it is programmed bare-metal, supports C, inline ssembler, and MicroPython, and has an interesting set of hardware co-processors. In addition to the two M0 cores, and the usual peripheral hardware devices (ADC, UART, I2C, SPI, USB, PWM, timer), there are several heavy-weight hardware state-machine co-processors. These include:
- an extensive DMA system, 12 channels, 32-bits/clock cycle (register programmed)
- very high-speed, 8-way parallel, programmable, i/o processor (custom assembly language programmed)
- a set of 4-way parallel, interpolator pipelines with adders, shifters, and a variety of feedback (register programmed)
- two integer dividers (one per core, transport triggered)
- intercore hardware 32 bit x 8 word FIFOs and 32 simple spinlocks
For more information:
- RP2040 chip datasheet
- RP2040 PICO board datasheet
- PICO C SDK and Setting up for C (Hunter 2/14/2021)
- Micropython SDK
- PICO code examples
The following is organized by date for now.
Later there will be topics.
Testing in C (Hunter Adams)
Setting up for C (Hunter 2/14/2021)
Chained-DMA signal generator thru SPI DAC on RP2040 (Hunter 3/9/2021
Dual-core Direct Digital Synthesis (DDS) on RP2040 (Raspberry Pi Pico)(3/20/2021)
Testing in MicroPython (Bruce Land)
Setup for MicroPython (1/28/21)
Getting the system running requires the micropython image UF2 file to be downloaded to the board. Follow the simple directions on the linked page. Once you have installed micropython (MP) you can connect to the board with a terminal program, but Thonny is a simple IDE which includes an editor, downloader, file handler, and console.
After installing Thonny, setup the connection to the board with:
- in Tools > Options > Interpreter Tab
Choose: micropython(raspberry Pi PICO)
Choose: USB serial device (with appropriate device name) - in Run menu choose: Stop/restart
at this point you should see a python >>> prompt near the bottom of the window. - In the edit pane paste in:
from machine import Pin, Timer led=Pin(25,Pin.OUT) tim=Timer() def tick(timer): led.toggle() tim.init(freq=2.5,mode=Timer.PERIODIC,callback=tick)
- In Run menu choose: Run current script
The LED should blink if everything is correctly connected. - <cntl>c normally stops a program, but the test program starts a interrupt-service-routine.
<cntl>d will force a soft reset and kill the ISR.
The command tim.deinit() also stops the timer-triggered routine - The ISR runs at 10KHz, but fails at 100KHz and HANGS the system!
You have to unplug/plug the PICO to restart! My guess is that the ISR takes more than 10 microseconds and never actually exits if the ISR rate is too high. To test this hypothesis paste in:from machine import Pin, Timer led=Pin(15,Pin.OUT) x=0 while (x<300000): led.toggle() x += 1
This produces 24.6 KHz square wave with around 5% jitter=> loop at ~50 KHz or around 20 microsec/per loop. - Thonny can save a script directly to the MCU flash drive and can erase a file. If you save test.py, then at the command line type: import test it will run form the local file system.
- Choosing Tools>Open system shell opens a console directly to the >>> prompt.
To reconnect Thonny, you will have to close the console and restart the connection to the PICO.
The need for speed (2/2/21)
To get faster i/o you need to use hardware and not python loops. A very interesting feature of this chip is an 8-way parallel, hardware, state machine dedicated to fast i/o processing. Each of the 8 processors can run simple, deterministic, assembler programs (NOT ARM assembler, although that is also available). I stripped down the simplest example program to see how fast it would toggle a pin. The original example blinks the LED at a human rate. The folowing toggles a pin at 25 MHz! The clock frequency of the state machine can be set as high as 125 MHz (the system clock frequency). In the blink routine, the wrap statements act as a zero time, unconditional jump. The set commands set/clear a pin, while the [1] represents a delay parameter. The result is one state machine cycle for each set, followed by a one cycle delay after each set, for a loop-time of 4 cycles. At 100 MHz, that is a 25 MHz squarewave. The main program just turns on the statemachine for 3 seconds. If you delete the two [1] delays, the frequency will be 50 MHz.
import time
from rp2 import PIO, asm_pio
from machine import Pin
#
@asm_pio(set_init=rp2.PIO.OUT_LOW)
def blink():
wrap_target()
set(pins, 1) [1]
set(pins, 0) [1]
wrap()
# Instantiate a state machine with the blink program, at 100MHz, with set bound to Pin(15)
sm = rp2.StateMachine(0, blink, freq=100000000, set_base=Pin(15))
# Run the state machine for 3 seconds and scope pin 15.
sm.active(1)
time.sleep(3)
sm.active(0)
High speed interface: DVI from RP2040
The ARM assembler (2/2/21)
Micropython supports the ARM-Thumb assembler instructions. CPU registers R0-R7 can be used by the assembler, with function inputs in R0-R2 and function results being returned in R0. Also, when you name an array as an input parameter to an assembler funciton, python actually passes in the address to the array. To test this, I coded up a single instruction assembler function which returns the absolute memory address of an array. Python does not really want you to know about addresses, but DMA controllers need pointers to arrays to move data. The following routine just takes the input in R0, copies to itself, and exits, returning the address of the input array name. (formatted code)
# test assembler and
# implement 'addressof'
a=array.array('i',[ 1, 2, 3])
# invoke assembler
@micropython.asm_thumb
# passing an array name to the assembler
# actually passes in the address
def addressof(r0):
# r0 is the output register, so address beomes output
mov(r0, r0)
# now use the assembler routine
addr_a = addressof(a)
print(addr_a)
print(machine.mem32[addressof(a)+8]) # returns '3'
The complete two-assemblers (PIO and ARM_thumb) test code: code.
Note that some browsers do not like to see python code! You will need to rename the *.txt file.
Right-click the link and choose save link as...
(An image of the code.)
Code generation options in micropython (2/11/21)
Micropython (MP) generates a bytecode executable by default. Bytecode is compact, but slow compared to inline code. There are a least three other code generators. (see maximizing speed). The native code generator takes unmodified MP and generates a mix of inline and MP calls. The viper code generator requires some modifications/simplifications of MP source, including variable typing in some cases. It can generate inline assembler in some cases, but cannlot optimize across function calls. The assembler code generator allows you to enter ARM-M0 Thumb assembly code, linked by a simple memory map to the rest of the MP code.
I wrote a program to start testing these options, as well as other timing in MP.
( As usual, Windoze does not like to download Python, so you will need to rename it. )
- Function calls seem slow, so I wrote a null function which simply returns, and timed it. It turns out that function calls get faster over several invocations. The code imports the time utilities and the array functionality, the invokes the null function three times. The times vary, but the first, second, and third invocations typically have times of 35, 12, and 10 uSec. The array type packs elements in the same way that C does and is used to communicate with assembler.
- Any real program is going to put functions into a loop, so I tested the call time in the simplest possible functions, which call the null functions a few housand times. The same function was coded as default, native, and viper to compare how the call times change. The following times in uSec show that there is aa slight improvment when not using the default bytecode. This is because the bulk of the time is spent actually calling the function. But 5-6 microseconds is not too bad, about 780 cycles.
multiple fun_loop_time= 6.5367
multiple fun_native_time= 5.0878
multiple fun_viper_time= 5.0746 - This made me wonder how simple calculations would scale using the different code generators. I wrote four different versions of a simple increment loop and used default bytecode, native, viper, and assembler directives to compile them. The times below show a dramatic speed-up for viper-compiled code, but of course, hand coded assembler is faster. By cycle-counting the assembler code you can show that it is raw machine code.
bytecode_loop_time= 7.29907 usec
native_loop_time= 2.66444
viper_loop_time= 0.248029
asm_loop_time= 0.040052 - As a prototype for IIR filters, I wrote a looping multiply-store assembler function to see how fast it would execute. Again, cycle-counting shows that it is compiled to pure machine code. The load, multiply, store, increment, and branch took 8 machine cycles and measured ~64 nSec. If you do:
>>> import machine
>>> machine.freq()
the frequency reported is 125 MHz, so 8 cycles should take 64 microseconds.
Micropython co-routines (cooperative scheduling) and threading (multicore) (2/12/2021)
-- Cooperative scheduling
Cooperative scheduling on the rp2040 is similar to Protothreads on the PIC32. Asyncio is a stackless, non-premptive, light-weight task handler. Some descriptive material:
Cooperative scheduling Tutorial (uasyncio module) and demo code
Documentation for version 3
Async version 3 overview
--True threading is currently very limited. From the command line (import _thread, then help(_thread)) you can see that the functionality is a subset of Cpython thread. According to the pico python SDK manual, section 3.5, You can start just one thread on the second core. However the cpu manual indicates that there is hardware support for core-to-core communication in the form of two unidirectional FIFOs, and up to 32 hardware spin locks.
The first example starts two cooperative tasks on core0 using the asyncio library and one separate thread on core1. Programs on each core can determine which core they are running on by reading a memory address. The first part of the code defines the SIO base address, which happens to be the cpu id, and defines the core1 functions. Core1 just toggles an LED and prints out the core id. The second part defines the two asyncio, cooperative tasks running on core0. One task handles i/o to UART0, and the other blinks the onboard LED. The third part starts the two syncio tasks on core0 and the thread on core1, and allows for stopping the program with cntl-c on the REPL console. On both cores, the print command prints on the REPL (USB connection), and the streamwriter on core1 prints to UART0.
The second example tests the inter-core FIFO communication and inter-core spinlock hardware. Each core can write to one FIFO and read from the other FIFO. Each core has a FIFO read address, FIFO write address, and FIFO status, with bits to indicate that space is available to write, and that data is available to read. We need at least five functions, FIFO_read, FIFO_write (both bolcking), FIFO_read_status, FIFO_write_status, and FIFO_purge. FIFO_purge insures that there are no items in the FIFO left over from another program. The spinlocks require two functions, spin_acquire and spin_release. The spin_acquire function takes a lock number, 0 to 31, and can be either blocking or nonblocking. The code uses spin locks to protect a varialbe incremented by both cores. The FIFOs send the variable back and forth between the two cores. The overall effect is to increment the variable by two every time it is printed to the REPL console in CORE1 (CORE1 code). One of two tasks on CORE0 bounces the variable back to CORE1. To avoid deadlock after another program runs, the task initially clears the spinlock and checks to see if there is data in the FIFO.
The third example (3/15/2021) looks at communication between cores using shared memory. There are at least three ways to share memory. You can define an array in a task on one core, then pass the pointer (ctypes module; addressof()) via FIFO. You can define an array outside of a task, then jus use its name and index on both cores. You can declare a variable global, then use it on both cores.
The SIO Hardware divider (2/28/2021)
The SIO contains a 8-cycle hardware divider for each core. I wrote test code for it in micropython, then coded it again as a assembler program to test speed. If you stick to python, it is faster to just use the integer divide operator, //, than to invoke the hardware divider directly. The code shows how to directly touch hardware registers. Every time you load a divisor or dividend into the hardware divide inputs, a calculation is started. You can check a done-bit, or just wait 8 cycles. One test result is below. Dividing 37/6 give 5, with remainder 1. The assembler loop time is 168 nSec, of which 72 nSec is the actual divide.
HW div 7 36 5 1
asm_divloop_time = 0.16851 count= 100000
asm div 7 36 5 1
DMA direct memory access (3/5/2021)
Python does not really want you to know about addresses, but DMA controllers need pointers to arrays to move data. The array data type packs data sequentially, like C, and is adressable. A one line assembler program(see above) extracts the address of the zeroth element of an array, and the other elements can be accessed from this base pointer by addition.The DMA system has LOTs of options, including ability to loop on a section of memory, send one address repeatedly (perhaps from a peripherial), chain channels, start a transfer triggered by one of about 60 events, and transmit 8, 16 or 32-bit wide data. The data rate is very high, approaching one transfer per clock cycle.
-- The first example just copies one array to another. The code just sets up the options for channel control. First the addresses of the control registers, then the configuration bits. Then, Two arrays are defined, their addresses determined, and channel zero configured for no-interrupt, permanent trigger, read and write increment, and a data width of 32-bits.
DMA_src_addr = addressof(DMA_src)
machine.mem32[DMA_RD_ADDR0] = DMA_src_addr
DMA_dst_addr = addressof(DMA_dst)
machine.mem32[DMA_WR_ADDR0] = DMA_dst_addr
machine.mem32[DMA_TR_CNT0] = len(DMA_src)
# this writ starts the transfer
perm_trig = 0x3f # alwas go
data_32 = 0x02 # 32 bit
# set up control and start the DMA
machine.mem32[DMA_CTRL0] = (DMA_IRQ_QUIET | DMA_TREQ(perm_trig) |
DMA_WR_INC | DMA_RD_INC |
DMA_DATA_WIDTH(data_32) |
DMA_EN )
DMA-to-PWM sinewave synthesis (3/10/2021)
Using more features of the DMA channels allows us to trigger a DMA transfer form a peripherial, in this case, the overflow of the counter on a PWM channel. All of the channel trigger sources (except for permanent trigger and timers) are in the table below. Note that the numbers are decimal, not hex. The timer triggers (in hex) are:
0x3b → Select Timer 0 as TREQ
0x3c →Select Timer 1 as TREQ
0x3f → Permanent request, for unpaced transfers
For this example, we will use TREQ source 25 (DREQ_PWM_WRAP1) to trigger DMA channel zero.The source address for channel zero will be the adddress of the sine buffer memory. The destination address will be fixed at the PWM slice one compare register. The transfer count will be the length of the sine buffer. DMA channel zero will chain to DMA channel 1 after the entire sine buffer is sent. DMA channel 1 will have a source address equal to the address, of the address, of the sine buffer. It will have a destination address of the DMA channel zero source address register, and a tranfer count of one word. DMA channel 1 will reload the source address of channel zero, then chain back to channel zero. The effect is that the sine waveform buffer will be sent continuously to the PWM. Running the PWM at full cpu frequency, with a top-count of 256 (8-bit resolution), works out to a PWM frequency of 500 KHz. With a sine buffer of length 256, we can generate a very low distortion (better than -40db) sine at 1900 Hz. Making the table shorter, to length 32, means that we can generate sine waves of about 15 KHz, with distortion still below -30 db.
The code is rather lengthy because of all the low-level setup. There is currently no direct python support of DMA so all configuration is at the big-bang level. I did not like the python PWM abstraction, so I wrote my own to more easily set the PWM period. After setting up all of the bit-twiddling, I turned on DMA channel 1, then DMA channel zero, and finally the PWM to start everything (with the first overflow trigger).
DMA-to-PWM sinewave with settable frequency (3/16/2021)
For this example, we will use TREQ source DREQ_TIMER0 = 0x3b to trigger DMA channel zero. The timer refered to is DMA timer 0, which has settable frequency as X/Y<1 where X is the top 16 bits of a register, and Y is the bottom 16 bits. It is easy to show that the settability of the frequency is very good at audio frequencies, with a useful range of 7 Hz to 15 KHz. The rest of the DMA setup is the same as the last example. The algorithm for going from a desired output frequency, Fout, to the values of X and Y is slightly involved. For a sine table of length L, and cpu clock frequency of Fclk:
Fout = (Fclk/L)*(X/Y)
The two settable variables are X and Y, but they are not independent, and must be integers. The solution I used is to set Y to maximum value (0xFFFF), then solve for the integer X0, which will systemmatically cause Fout to be a little low. The next step is to lower Y slightly to set the closest possible frequency. To do that we are going to Taylor expand:
1/(0xFFFF - ΔY) as (2-16)/(1 -(2-16* ΔY)) yielding (2-16)*(1 +(2-16 * ΔY))
As long as ΔY<211 the approximation is good to 0.1%.
Now the output frequency can be written as
Fout = (Fclk/L)*X* (2-16)*(1 +(2-16 * ΔY))
The steps are: solve for X to give lower bound frequency, then compute a small correction.
X0 = Fout/Fclk * L * 216
ΔY =( Fout - Fout(int(X0)))/Fclk * L * 232/int(X0)
So the python code looks like:
#get exact X
X0 = (Fout/Fclk) * Ltable * 2**16
# compute actual freq using integer part of X
Fx = Fclk*int(X0)/(Ltable * 2**16)
# Taylor expanson for delta Y
dY = (Fout-Fx) * Ltable * 2**32 /(Fclk * int(X0))
machine.mem32[DMA_TIMER0] = (0xffff-int(dY)) | (int(X0)<<16)
A slight rearrangement of the PWM setup allows both the A and B outputs from PWM slice 1 to produce separate signals, in this case, sine waves in quadrature.
DMA-to-PWM sinewave looped to ADC-to-DMA-to-PWM (4/20/20)
The settable frequency sine wave described in the previous example was used as a source to drive an ADC input. The ADC was set up as the trigger for a DMA channel which transfered the measurement to a PWM channel. In the process of doing this, it was necessary to re-factor the hardware register definitions for better use of the hardware. The code has explicit functions for write, set, clear, and XOR of any IO register. GPIO registers, DMA registers, and PWM registers are named so that any channel/slice can be set up. An external circuit was built to lowpass filter two PWM channels and to connect the sinewave PWM filtered output to ADC channel 0 (GPIO 26). A comment in the code describes the circuit. Another comment summarizes the cpu-asynchronous hardware used. The only function of the main python program, after setting up all the async hardware, is to ask the user what frequency the sinewave should be. The image below shows the sine wave output in blue and the ADC-to-DMA-to-PWM loop back in yellow.
DMA inline arithmetic functions (3/27/2021)
-- The data sniff function can monitor a channel and perform operations on the data flowing by. The intention is to allow fast calcuation of check-sums, but the sniffer can also do 2's complement addition on the data flow. The sniff data register can be zeroed between DMA bursts, or can be preloaded with a value to be added. The sniff control register can be set to perform CCITT CRC in four forms, summation, and XOR reduction. The register can be read normal or bit-inverted. In addition, like all i/o block registers, the sniff data registers supports transport-triggered operations which can clear, set, or XOR bits when written. Using this allows AND, OR and XOR functions on single data words. The example code uses a DMA transfer to add three numbers, after first initilizing the sniff data register using transport-triggered logic operations. As usual there is a ton of setup, to get all the control bits in the right place, but then the actual implementation is short.
-- Refactoring the DMA setup code makes the code easier to read and allows use of DMA channels 0 to 11.
Interrupts in Micropython (4/29/2021)
Python only knows about i/o pin IRQs (nad maybe timers). We could set up an i/o pin as an output, then use a DMA channel triggered from any TREQ source (see table above) to set/clear the pin and trigger the pin ISR. The first test code uses direct control of the GPIO registers to trigger an ISR. This is a first step in using register loads from a DMA channel. The first part of the program just sets up the i/o register definitions. The second part sets up the python interrupt, then uses low-level register writes to trigger it. In real code, the DMA channel would do the register write to trigger the IRQ.
SIO Interpolator module (2/29/2021)
The SIO has two interpolation units for each CPU. The interpolators are register-programmed, single-cycle, arithmetic devices with a number of bewildering modes. One of the easiest to understand is the BLEND mode which computes
where Interpolator0 registers store the three input values, and one cycle later the output is ready. Note that alpha is actuall specified as an integer 0<=alpha<=255, understanding that the hardware treats it as divided by 256. The test code has a bulky register naming section, but a short implementation. The BLEND mode would not usually be used directly from python, but could used from assembler, or an ISR.
Interrupts and DMA transfers (4/27/2021)
There is one block of addresses for the SIO (0xd000_0000) which have a bus address only for the CPUs, but which do not appear on the system bus. It is therefore impossible for the DMA system to reach the SIO. While trying to understand this, I caused a lot of DMA bus errors. A DMA channel with set error bits is locked from execution, and Python soft-reset does not clear the bits. The bits have to be cleared by writing ones to the positions in the channel control register.
My goal for using the SIO interpolator module is to low-pass filter the ADC readings, then output them to a PWM channel. So how to get to the SIO? One possibiity is to trigger an ISR on the cpu. A DMA channel triggering on the ADC trigger request could cause an interrupt, but Python only knows about i/o pin IRQs. We could set up an i/o pin as an output, then use a DMA channel triggered from the ADC to set/clear the pin and trigger the pin ISR. A test code showing that this works.
MicroPython Notes (mostly for myself) (started 1/28/21)
- PICO micropython examples
- Micropython libraries/applications/projects --
- awesome micropython
- Paul Sokolovsky
- libraries -- may be a copy of 1
- projects -- hackster
- projects -- hackaday
- Typng help('modules') gives a list of available modules
(but excluding any modules you may have put into flash memory) - Once you have the module names, typing help(module) gives contents of the module
BUT you need to import it first!
example:
>>> help(machine)
object <module 'umachine'> is of type module
__name__ -- umachine
reset -- <function>
reset_cause -- <function>
bootloader -- <function>
freq -- <function>
mem8 -- <8-bit memory>
mem16 -- <16-bit memory>
mem32 -- <32-bit memory>
ADC -- <class 'ADC'>
I2C -- <class 'I2C'>
SoftI2C -- <class 'SoftI2C'>
Pin -- <class 'Pin'>
PWM -- <class 'PWM'>
SPI -- <class 'SPI'>
SoftSPI -- <class 'SoftSPI'>
Timer -- <class 'Timer'>
UART -- <class 'UART'>
WDT -- <class 'WDT'>
PWRON_RESET -- 1
WDT_RESET -- 3 - Wait! What is mem8, mem16, mem32?
Mostly useful for read/write control registers
read: machine.mem32[address]
write: machine.mem32[address] = integer - The contents of the RP2 module (PIO assembler functions)
is not well explained yet. Your best bet is to go to the examples,
because in the end, only the source matters. - The experimental 2 core _thread
>>> import _thread
>>> help(_thread)
object <module '_thread'> is of type module
__name__ -- _thread
LockType -- <class 'lock'>
get_ident -- <function>
stack_size -- <function>
start_new_thread -- <function>
exit -- <function>
allocate_lock -- <function>
The Locktype has the methods:
>>> help(_thread.LockType)
object <class 'lock'> is of type type
acquire -- <function>
release -- <function>
locked -- <function>
用树莓派Pico实现VS Code的调试器,支持CMSIS-DAP下载 更新发布于 2021年12月26日
来源:Raspberry Pico: Simple Debugging with just one Device
更多关于制作调试器的文章:设计MCU/FPGA下载器的一些资源链接
The Raspberry Pico is a new microcontroller launched in February 2021. The community was excited about this new board, and several people started amazing projects. I grabbed two boards early on, and while still working on my Arduino based robot, did the usual blinking led and potentiometer tutorials. For simplicity, I used the MicroPython SDK. It is setup in minutes, simple sketches are easy, and you can live-connect to the Pico and execute your program.
If you want to use the C SDK, you have a lot to do: Install build tools, CMake, download the SDK, define an SDK path, then add CMake files for your projects, adding all the required libraries etc. And the comfort level at which you arrive is ok — you still need to compile and manually upload the UF2 file to the Pico.
Can it be better and simpler? Yes! Thanks to the great wizio-pico project, VS Code integration can be achieved, including direct upload to your Pico. And when you consider the pico-debug project, you can also integrate full debugging capabilities for your programs.
This blog pot continues the Pico setup series and will detail how to setup a fully working debugger in VS Studio Code. Keep in mind that ultimately the steps are based on explanations from pico-debug project, and wizio-pico, but the setup is complex so I wrote a summarizing blog article. Follow along and you will be debugging your Pico C programs with the press of a simple launch button.
This article originally appeared at my blog.
Tool Overview
Before we arrive at the fully integrated debugging solution, it’s important to understand the tools that will do the heavy lifting for us.
The JTAG standard describes how to debug integrated circuits. The standard defines the communication protocol how the registers and bus systems on the circuits can be accessed. And it also describes the electrical interface, e.g. a serial port, to access the circuit. Instead of using a dedicated port, the SWD (Serial Wire Debug) protocol can use just two pins to interface with an ARM chip for debugging purposes. This standard is used by the tool OpenOCD, which is an acronym for On-Chip-Debugger. It uses the JTAG standard to establish a debugging session to an integrated circuit. Finally, the GNU Project Debugger GDB is an Open-Source workhorse for debugging applications, supporting C, C++ and others. GDB can connect to an OpenOCD session to start debugging. GDB itself is ultimately a CLI application, offering a dedicated language to load a program, set breakpoints and variables. Modern IDEs will interface with GDB and provide a powerful, visual debugging experience.
To use these tools, we need to setup a compiler that produces ARM code, GDB and OpenOCD. Let’s start!
Compiler & GDB
We need to install a cross-compiler that can produce ARM code: The gcc-arm-none-eabi
. Execute the following command to install this compiler and other required tools.
$> sudo apt update
$> sudo apt install cmake gcc-arm-none-eabi libnewlib-arm-none-eabi build-essential
Test that these tools are installed correctly:
$> arm-none-eabi-gcc -vUsing built-in specs.
COLLECT_GCC=arm-none-eabi-gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/arm-none-eabi/9.2.1/lto-wrapper
Target: arm-none-eabi
To install GDB:
apt install gdb-multiarch
And also, shortly test that it is correctly installed:
$> db-multiarch -vGNU gdb (Ubuntu 9.2-0ubuntu1~20.04) 9.2
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
OpenOCD
Following the pico-debug project explanations, we will install a special version of OCD that support the Raspberry Pico.
First we install regular Linux packages …
$> sudo apt install automake autoconf texinfo libtool libhidapi-dev libusb-1.0-0-dev
…and then we will clone a Git repository to compile and make the custom OCD version.
$> git clone https://github.com/majbthrd/openocd.git --recursive --branch rp2040_cmsisdap_demo --depth=1
$ cd openocd
$ ./bootstrap
$ ./configure --enable-cmsis-dap
$ make -j4
$ sudo make install
Again, we test that the installation is successful:
$> openocd -hOpen On-Chip Debugger 0.10.0+dev-gb4af1af-dirty (2021-03-21-10:40)
Licensed under GNU GPL v2
Preparing the Pico
With the toolchain installed and tested, we can continue to prepare the Pico itself. Again, two tasks need to be done:
- The Pico needs to be booted with a special UF2 image so that it can be used as a debugging device
- The target program needs to be compiled with a special debug compiler flag
Install the Debugging UF2 Image
First, grab the latest UF2 image from https://github.com/majbthrd/pico-debug/releases, then drag’n drop the file onto your mass storage mode mounted Pico. It will boot your raspberry Pico as a CMSIS-DAP device. This acronym stands for Cortex Microcontroller Software Interface Standard — Debug Access Port, which is both a protocol specification and a concrete firmware. Technically, it wraps the Picos’ Serial-Wire-Debug Interface and emulates a Debug Access Port (DAP) via USB. This standardized interface can be used by a connected host computer running a debugger.
Lets see if the image is processed correctly. When executing dmesg
, you should see the following output:
[50852.541543] usb 1-2: new full-speed USB device number 70 using xhci_hcd
[50852.690691] usb 1-2: New USB device found, idVendor=1209, idProduct=2488, bcdDevice=10.02
[50852.690696] usb 1-2: New USB device strings: Mfr=0, Product=1, SerialNumber=0
[50852.690698] usb 1-2: Product: CMSIS-DAP
The Pico is ready. Now, we compile the program to be available for debugging.
Compile the target program
When i began to write the article, I hoped that you just needed to make a small switch in the plattform.ini file, compile and have a debug able version of your program. However, this is not the case yet. If you want to use just one Pico for debugging, you need to use a special SDK for compiling your program. This SDK fixes some issues with USB system initialization that otherwise interferes with debugging. You can read the details at the github thread.
Until a better solution is available, we need to add special CMake compilation files.
Lets picture the final directory layout that we will obtain:
.
├── debug
│ ├── build
│ ├── CMakeLists.txt
│ ├── pico-debug.uf2
│ ├── pico_sdk_import.cmake
│ └── src -> /home/work/development/pico2/src/
├── include
│ ├── pico
│ │ └── config_autogen.h
│ └── README
├── lib
│ └── README
├── LICENSE.txt
├── platformio.ini
├── README.md
├── src
│ ├── CMakeLists.txt
│ └── main.c
└── test
└── README
The concrete steps are
- Create the directories
build
anddebug
- In
debug
, copy the special uf2 files, and add a symbolic link to thesrc
directory - In
debug
, put thisCMakeLists.txt
file into it.
cmake_minimum_required(VERSION 3.12)# Pull in SDK (must be before project)
include(pico_sdk_import.cmake)project(pico_examples C CXX ASM)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)set(PICO_EXAMPLES_PATH ${pwd})# Initialize the SDK
pico_sdk_init()add_subdirectory(src)
- In
src/
folder, add thisCMakeLists.txt
file.
add_executable(main
main.c
)# Pull in our pico_stdlib which pulls in commonly used features
target_link_libraries(main pico_stdlib)# create map/bin/hex file etc.
pico_add_extra_outputs(main)
Now we can compile the program.
- Set the environment variable
PICO_SDK_PATH
to point to the special SDK
export PICO_SDK_PATH=/home/work/development/pico-debug-sdk/
- Go to the
debug/build
folder, and run the following commands:
cmake -DCMAKE_BUILD_TYPE=Debug -g0 ..
The compilation process should start and show an output like follows:
Using PICO_SDK_PATH from environment ('/home/work/development/pico-debug-sdk/')
PICO_SDK_PATH is /home/work/development/pico-debug-sdk
Defaulting PICO_PLATFORM to rp2040 since not specified.
Defaulting PICO platform compiler to pico_arm_gcc since not specified.
PICO compiler is pico_arm_gcc
PICO_GCC_TRIPLE defaulted to arm-none-eabi
-- The C compiler identification is GNU 9.2.1
-- The CXX compiler identification is GNU 9.2.1
-- The ASM compiler identification is GNU
-- Found assembler: /usr/bin/arm-none-eabi-gcc
Using regular optimized debug build (set PICO_DEOPTIMIZED_DEBUG=1 to de-optimize)
Defaulting PICO target board to pico since not specified.
Using board configuration from /home/work/development/pico-debug-sdk/src/boards/include/boards/pico.h
-- Found Python3: /usr/bin/python3.8 (found version "3.8.5") found components: Interpreter
TinyUSB available at /home/work/development/pico-debug-sdk/lib/tinyusb/src/portable/raspberrypi/rp2040; adding USB support.
Compiling TinyUSB with CFG_TUSB_DEBUG=1
-- Found Doxygen: /usr/bin/doxygen (found version "1.8.17") found components: doxygen dot
ELF2UF2 will need to be built
-- Configuring done
-- Generating done
-- Build files have been written to: /home/work/development/pico2/debug/build
- In the
build
folder, you will now seesrc
- change into this directory, and executemake
cd src/
make
You should see this output:
Scanning dependencies of target ELF2UF2Build
[ 1%] Creating directories for 'ELF2UF2Build'
[ 3%] No download step for 'ELF2UF2Build'
[ 5%] No patch step for 'ELF2UF2Build'
[ 6%] No update step for 'ELF2UF2Build'
[ 8%] Performing configure step for 'ELF2UF2Build'
-- The C compiler identification is GNU 9.3.0
-- The CXX compiler identification is GNU 9.3.0
...
-- Build files have been written to: /home/work/development/pico2/debug/build/elf2uf2
[ 10%] Performing build step for 'ELF2UF2Build'
Scanning dependencies of target elf2uf2
[ 50%] Building CXX object CMakeFiles/elf2uf2.dir/main.cpp.o
[100%] Linking CXX executable elf2uf2
[100%] Built target elf2uf2
[ 11%] No install step for 'ELF2UF2Build'
[ 13%] Completed 'ELF2UF2Build'
[ 13%] Built target ELF2UF2Build
Scanning dependencies of target bs2_default
[ 15%] Building ASM object pico-sdk/src/rp2_common/boot_stage2/CMakeFiles/bs2_default.dir/boot2_w25q080.S.obj
[ 16%] Linking ASM executable bs2_default.elf
...
[100%] Linking CXX executable main.elf
[100%] Built target main
Done! You now have a debugable version of you program that can run on just one connected Pico.
Debugging on the CLI
We have installed the toolchain. We have prepared the Pico. Now, we can start the debugging process. In this section, we will directly use the CLI tools. In the next section, we will integrate these tools into Visual Studio Code.
OpenOCD: Executing as Normal User
In order to run OpenOCD as a normal user, we need to create an OpenOCD launch file, and add your normal user to a special group. The reference for these steps is this stackexchange post.
Create the file /etc/udev/rules.d/98-openocd.rules
and add this content:
ACTION!="add|change", GOTO="openocd_rules_end"
SUBSYSTEM!="usb|tty|hidraw", GOTO="openocd_rules_end"
ATTRS{product}=="*CMSIS-DAP*", MODE="664" GROUP="plugdev"
LABEL="openocd_rules_end"
Then, create a new Linux group, and add your personal user to that group.
$> sudo groupadd plugedev
$> sudo gpasswd -a devcon plugdev
$> sudo udevadm control --reload
Like before, we test this. See that your user is a member of the newly created group
$> groups
devcon adm dialout cdrom sudo dip plugdev lpadmin lxd sambashare
Start OpenOCD
Now we manually start the OpenOCD server. In the same directory in which you build it, execute this command:
$> cd openocd/tcl
$> openocd -f interface/cmsis-dap.cfg -f target/rp2040-core0.cfg -c "transport select swd" -c "adapter speed 4000"
If you are as curious as me about what this command means:
- The two
-f
flags indicate loading of configuration files, here we load the Debug Access Port (DAP) config and a config for the Pico board (RP2040) - The two
-c
flags indicate additional commands that are run, we will connect via serial wire debug and set the connection speed in kHz between the host and the Pico.
You should see this output:
Open On-Chip Debugger 0.10.0+dev-gb4af1af-dirty (2021-03-21-10:40)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
swd
adapter speed: 4000 kHz
Info : Hardware thread awareness created
Info : RP2040 Flash Bank Command
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : CMSIS-DAP: SWD Supported
Info : CMSIS-DAP: FW Version = 2.0.0
Info : CMSIS-DAP: Interface Initialized (SWD)
Info : SWCLK/TCK = 0 SWDIO/TMS = 0 TDI = 0 TDO = 0 nTRST = 0 nRESET = 0
Info : CMSIS-DAP: Interface ready
Info : clock speed 4000 kHz
Info : SWD DPIDR 0x0bc12477
Info : SWD DLPIDR 0x00000001
Info : rp2040.core0: hardware has 4 breakpoints, 2 watchpoints
Info : starting gdb server for rp2040.core0 on 3333
Info : Listening on port 3333 for gdb connections
Open a second terminal window, and navigate to the directory in which you compiled your Pico project. Then we will launch a GDB session.
$> cd debug/build/src
$> gdb-multiarch main.elf
You should see this output:
gdb-multiarch main.elf
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04) 9.2
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from src/main.elf...
With the GDB session open, we can now execute commands to perform the debugging. GDB has an elaborate language, we will focus on the main commands to drive a simple console-based debugging session.
(gdb) target remote localhost:3333
Remote debugging using localhost:3333
main () at /home/work/development/pico2/debug/src/main.c:37
37 int main() {
(gdb) load
Loading section .boot2, size 0x100 lma 0x10000000
Loading section .text, size 0x4b10 lma 0x10000100
Loading section .rodata, size 0xd84 lma 0x10004c10
Loading section .binary_info, size 0x20 lma 0x10005994
Loading section .data, size 0xa04 lma 0x100059b4
Start address 0x100001e8, load size 25528
Transfer rate: 8 KB/sec, 4254 bytes/write.
(gdb) monitor reset init
target halted due to debug-request, current mode: Thread
xPSR: 0xf1000000 pc: 0x000000ee msp: 0x20041f00
(gdb) b main
Breakpoint 1 at 0x100003d8: file /home/work/development/pico2/debug/src/main.c, line 37.
(gdb) c
Continuing.
Note: automatically using hardware breakpoints for read-only addresses.
Breakpoint 1, main () at /home/work/development/pico2/debug/src/main.c:37
37 int main() {
(gdb) n
38 setup();
(gdb) n
40 printf("Hello World\n");
(gdb) n
43 printf(".");
(gdb) n
44 blink();
(gdb) n
42 while (true) {
(gdb) p LED_GREEN
$1 = 15
(gdb)
If you came this far, it’s only a few steps more to setup debugging with your IDE.
Install additional VsCode extensions
C/C++ Extension Pack (by Microsoft)
Cortex-Debug (by marus25)
CMake Tools (by Microsoft)
Create the file .vscode/launch.json
, and enter this content:
{
"version": "0.2.0",
"configurations": [
{
"name": "Pico Debug",
"device": "RP2040",
"gdbPath": "gdb-multiarch",
"cwd": "${workspaceRoot}",
"executable": "${workspaceRoot}/debug/build/src/main.elf",
"request": "launch",
"type": "cortex-debug",
"servertype": "openocd",
"configFiles": ["interface/cmsis-dap.cfg", "target/rp2040-core0.cfg"],
"openOCDLaunchCommands": ["transport select swd", "adapter speed 4000"],
"svdFile": "${env:PICO_SDK_PATH}/src/rp2040/hardware_regs/rp2040.svd",
"searchDir": ["/home/work/development/openocd/tcl"],
"runToMain": true,
"postRestartCommands": ["break main", "continue"]
}
]
}
The important things to change are:
executable
: Needs to point to the debug-ready compiled filesvdFile
: SVD is a file format containing the specifics of a microcontroller, this file is used by openocd to provide hardware related debugging information like registers etc.serachDir
: Configure this to your OpenOCD installations tcl path
And now comes the final moment. in VS Code, click on Run/Start Debugging
, and a few seconds later you should see the following window:
With all the comfort of your IDE, you can now debug.
Conclusion
This blog post took out way longer in several aspects: The time to write it, the time to test all the options, and the length of this article. With all the setup done, you can write your Pico programs in an integrated IDE, have all the comfort of code highlighting, browsing library functions, and refactoring options. Also, with the one-click-and-upload feature, you can program almost like with an Arduino. And on top of that, you can compile a Debug version of your program and run the debugger from within Visual Studio Code. This should greatly enhance your development effectiveness.
To help you get started with future projects, check out my pico-project-setup repo on Github.
使用PulseView做逻辑分析仪的显示 更新发布于 2022年01月09日
关于PulseView:PulseView
The PulseView Open Source Project on Open Hub
参考文章:Using the USB Logic Analyzer with sigrok PulseView
红外遥控器的收、发设计资源 更新发布于 2022年02月07日
整理了一些与红外遥控接收和发射相关的技术资源,供做遥控器项目的同学做参考:
基于树莓派RP2040制作能控制LCD和电脑界面的“鼠标”
1.利用版上的四向摇杆和按键,通过USB端口可以控制PC屏幕上的光标移动和点击操作,行使电脑鼠标的功能 2.菜单的选择:速度控制并显示参数,模式转换 3.在LCD屏幕上显示鼠标的移动 4.灯效的改变 完整代码见附件
cyz
华北电力大学
基于RP2040的飞鼠控制器
基于平台一,使用板子上的摇杆,按键和陀螺仪,实现了摇杆控制鼠标和飞鼠功能
振青666
贵州大学
寒假在家一起练-基于树莓派rp2040实现复古游戏《俄罗斯方块》移植
1.编写(移植)《俄罗斯方块》游戏的运行逻辑; 2.依托Arduino提供的TFT_eSPI库编写LCD屏幕显示界面; 3.编写《俄罗斯方块》游戏的背景音乐; 4.依托RP2040游戏机平台进行软硬件逻辑结合;
bird
基于树莓派RP2040实现拼图游戏的移植报告
基于树莓派RP2040实现拼图游戏的移植,打乱读入图片的顺序,经由摇杆操控复原,复原时原图显现
Johnzax
中央民族大学
基于树莓派rp2040实现能控制LCD和电脑界面的“鼠标”
利用树莓派rp2040的四向摇杆和按键设计一款“鼠标”,该鼠标可以对240*240的LCD屏进行菜单选择和参数控制,同时,可以利用板子上的摇杆和按钮实现控制PC屏上的光标移动和点击操作,行使电脑鼠标的功能。
xiaoyu555
华北电力大学
基于RP2040的嵌入式系统实现控制LCD和电脑界面的鼠标
项目是以树莓派RP2040嵌入式平台为基础,采用micropython进行程序编写,实现能控制LCD和电脑界面的“鼠标”。
yzc
北京理工大学
基于树莓派RP2040设计模拟鼠标功能
本项目使用树莓派RP2040板卡实现模拟鼠标功能,并实现在PC端和RP2040端的任意切换,以及参数调整。并且加入点击动态反馈效果和模式选择状态反馈效果。
LIUZHIQIANG123
天津市职业大学
基于树莓派RP2040的嵌入式系统学习平台制作摇杆鼠标
基于树莓派RP2040的嵌入式系统学习平台制作摇杆鼠标,能够通过摇杆和按键实现鼠标的功能,包括长按、短按、拖动和滚动,并在LCD上显示鼠标图像。
student
南京邮电大学
基于树莓派Pico的嵌入式系统学习平台制作一款能控制LCD和电脑界面的“鼠标”
基于树莓派Pico的嵌入式系统学习平台制作的一款能控制LCD和电脑界面的“鼠标”
繁光与梦
华东理工大学
基于树莓派RP2040嵌入式系统开发板制作的鼠标项目
本项目是在硬禾学堂上”2022年寒假在家一起练活动平台”上选择的“能控制LCD和电脑界面的‘鼠标’任务,经过一段时间的认真学习和努力,已经可以做到使用开发板上的功能键控制LCD屏幕上的鼠标指针并进行选择,并且可以控制电脑的鼠标指针。
Elegy
北京理工大学
基于树莓派RP2040嵌入式学习平台实现温度计
基于树莓派RP2040的嵌入式系统学习平台实现的温度计,具有图形化显示、超温报警功能
Tein
西安培华学院
基于树莓派RP2040实现俄罗斯方块游戏移植
完成实习项目,基于树莓派RP2040的嵌入式系统学习平台,可以通过C/C++以及MicroPython编程来学习嵌入式系统的工作原理和应用。
aji
中央民族大学
基于micro python的复古游戏贪吃蛇改写与移植
本项目基于ZP2040开发板引脚及相关特性,通过修改相关参数与引脚,对控制方法进行相应修改与优化,将适用于其他开发板的贪吃蛇游戏移植到ZP2040上并成功运行。
ax57
中央民族大学
基于树莓派RP2040制作温度计
该项目是基于树莓派RP2040的嵌入式学习板、使用microPython进行编程的实现图形化显示以及超温报警的温度计。项目完全基于树莓派RP2040,未接外设。
小骏菌
四川大学
基于树莓派pico状态机的模拟鼠标
用状态机实现了一个菜单,基于树梅派pico的模拟鼠标,较好的实现了长按双击右键等功能,同时可以在树梅派pico的st7789的屏幕上流畅显示出鼠标的运动
zzc
北京理工大学
基于树莓派RP2040实现鼠标功能
使用RP2040micropython模拟实现鼠标功能,利用mma7660三轴姿态传感器实现滚轮效果,显示屏显示鼠标大概位置
listeningsnow
燕山大学里仁学院
基于硬禾学堂树莓派rp2040制作的模拟鼠标
本项目基于硬禾学堂的树莓派rp2040 Game kit硬件平台实现与电脑通信控制电脑鼠标以及LCD屏幕控制及参数调整。
NEFU-hjx
基于python实现小游戏
一进入游戏,主人公就会随机获取一个游戏已经设定的道具。最开始,主人公站在丛林的边缘,只有左右可选,左边是个洞穴,右边是沙滩。
李晓航
中央民族大学
基于树莓派RP2040的嵌入式系统学习平台制作模拟电压表
使用Micropython开发基于树莓派RP2040的嵌入式学习平台,制作的双通道电压表。
ezio
成都理工大学
基于树莓派RP2040利用姿态传感器制作水平仪
基于树莓派RP2040利用姿态传感器制作水平仪,使用st7789LCD实现显示,平台为MicroPython
Godalin
南京信息工程大学
基于树莓派RP2040制作推箱子小游戏
基于树莓派RP2040制作推箱子小游戏,主要是学习向,使用了240*240的lcd屏幕和和四向摇杆,并且使用micropython作为编程语言
段雨鑫
中央民族大学
用树莓派RP2040实现鼠标功能和lcd画板
本项目是基于树莓派RP2040设计的一款鼠标和lcd画板,可以正常驱动电脑鼠标,以及可以在lcd屏幕上画画,写字等。
DH蜡笔
金陵科技学院
基于树莓派RP2040的嵌入式学习板实现能控制LCD和电脑界面的“鼠标”
本项目基于树莓派RP2040,实现了四向摇杆控制LCD屏幕上图像化的鼠标移动和控制电脑鼠标移动
blackfish
北京理工大学
基于树莓派RP2040嵌入式学习平台制作的俄罗斯方块(Tetris)
通过学习树莓派RP2040嵌入式学习平台,通过micropython进行编程,使用240*240的彩色IPS LCD,蜂鸣器,四向摇杆,两个轻触按键等制作一个小游戏----俄罗斯方块
Windy-sha
华东理工大学
用树莓派RP2040制作鼠标
该项目基于树莓派RP2040的嵌入式系统,使用micropython编写,实现鼠标的功能。
maozi
基于树莓派RP2040的嵌入式系统学习平台完成复古打砖块小游戏移植
本项目是用基于树莓派RP2040的嵌入式系统学习平台完成的打方块小游戏移植,用到了电子森林提供的库函数和驱动,通过microPython编程实现了基本功能,主要参考了电子森林提供的贪吃蛇小游戏例程
Next
北京理工大学
基于树莓派RP2040制作的超温报警器
本项目使用了硬禾学堂针对"2022年寒假在家一起练"开发的"基于RP2040的嵌入式系统学习平台",设计的温度计,通过按键进行温度阈值设定,超过阈值会变颜色及报警,低于阈值温度时 停止报警,并显示红色
xinshuwei
南昌大学
基于树莓派RP2040的嵌入式系统实现复古游戏移植
基于树莓派RP2040实现对于复古游戏FC版《坦克大战》的移植,在LCD屏上显示并且玩家通过摇杆控制,A键攻击,四向摇杆进行坦克控制,生成地形,消灭敌方坦克就算获胜。
蓝鲸少年与海
北京理工大学
2022年寒假在家一起练——基于树莓派RP2040制作的模拟水平仪
基于树莓派RP2040、mma7660 、 st7789制作的一种模拟水平仪
老孙头
基于树莓派rp2040实现控制电脑鼠标和LCD鼠标
通过树莓派控制电脑鼠标,实现和鼠标相同的功能,在树莓派lcd显示屏上显示鼠标,并能进行菜单选择和参数控制
Mewtwo
东北林业大学
基于树莓派RP2040利用MMA7660重力感应传感器制作一个水平仪
基于树莓派RP2040,使用micropython编程语言,利用MMA7660重力感应传感器和ST7789LCD显示器制作一个水平仪
杨老基
北京理工大学
基于树莓派RP2040实现水平仪
本项目使用树莓派pico开发板,结合MMA7660重力传感器,制作了一款水平仪。
esp32小白
金陵科技学院
用基于树莓派RP2040的嵌入式系统学习板制作鼠标
本次是用基于树莓派RP2040的嵌入式系统学习板制作鼠标,运用其上的240*240分辨率的彩色IPS LCD,SPI接口,ST7789控制器,四向摇杆和2个轻触按键等实现模拟鼠标点击滑动等功能。
JJGong
四川大学
基于树莓派RP2040的嵌入式系统实现贪吃蛇小游戏
基于树莓派RP2040的嵌入式系统在Thonny平台上实现小游戏——贪吃蛇。 本次设计的是贪吃蛇,通过蜂鸣器播放背景音乐,显示将贪吃蛇显示到240*240的屏幕上。
li_
中央民族大学
用基于树莓派RP2040的嵌入式系统学习平台实现一个模拟电压表
2022寒假在家练 树莓派pico 模拟电压表使用microPython制作
pvfcd
北方工业大学
用基于树莓派RP2040核心设计控制LCD和电脑界面的“鼠标”
利用板上的四向摇杆和按键设计一款“鼠标” 在240*240的LCD屏幕内可以通过该鼠标进行菜单选择和参数控制(在屏幕上要有上图中图形化的箭头形状) 通过USB端口可以控制PC屏幕上的光标移动和点击操作,行使电脑鼠标的功能
mini城
北京科技大学
基于RP2040GameKit实现DAPLink调试器
使用RP2040制作一个DAPLink,可以实现对单片机的下载调试
yekai
中国计量大学
基于树莓派rp2040实现单板接小球游戏移植
基于rp2040实现复古游戏移植,实现移植,用过按键和四向摇杆进行控制。
hum2037
中央民族大学
基于硬禾学堂pico-game-kit制作冰墩墩水平仪
本文主要介绍用game-kit来制作一款精美的水平仪,重点介绍MMA7660加速度传感器数据读取及水平仪工作原理。
genvex
基于RP2040的gamkit的鼠标和屏幕指针的实现
通过寒假一起练活动,参与micropython的项目实现,将游戏机化身一个鼠标
飞跃1989
苏州大学
基于树莓派RP2040实现复古游戏“五子棋”的移植项目
这是我参加“硬禾学堂2022寒假在家练”活动所完成的项目,项目使用的是树莓派RP2040开发板。 项目实现的总体功能是将复古游戏“五子棋”移植到树莓派RP2040开发板上。
Yummy
中央民族大学
基于树莓派RP2040实现游戏“华容道”的移植项目
这里是我参加“硬禾学堂2022寒假在家练”活动所完成的项目,我选择的是设计或移植一款经典游戏——华容道,利用LCD屏显示,通过按键和四线遥感来控制游戏。
向死而生
中央民族大学
基于RP2040实现复古游戏移植---华容道
2021年1月底的时候,树莓派基金会推出了树莓派Pico。功能强劲,价格便宜的特性让Pico深受大家喜爱。这次看见2022年寒假在家一起练活动,有使用树莓派PICO主控芯片RP2040制作的嵌入式系统学习平台,就毫不犹豫地参加了进来。
1405818577
北京理工大学
用RP2040实现小车游戏
基于RP2040实现小车游戏,通过A,B按键来控制小车左右移动来躲避障碍物,每过一个障碍物就会得一分,碰到障碍物游戏结束。
luguoyang
中央民族大学
基于树莓派RP2040利用MMA7660重力感应传感器实现一个水平仪
基于树莓派RP2040利用MMA7660重力传感器实现一个水平仪并将结果显示在240 * 240 LCD显示屏上
tony
南京信息工程大学
基于RP2040 Game Kit的复古平台跳越游戏
由5个关卡构成的平台跳越游戏,需要操控主角收集金币并到达终点,使用Pico SDK开发。
迷湖浅浅
2022寒假在家一起练-基于RP2040 Game Kit实现复古小游戏:2048
使用RP2040 Game Kit 开发复古小游戏:2048
Huang
华南理工大学
基于树莓派rp2040实现制作一个图形化显示、超温报警的温度计
本次项目是使用硬禾学堂的树莓派rp2040完成了寒假一起练,制作了一个可以动态可视化调节温度的一个温度计
会把你变丑的黑魔仙
西安邮电大学
基于树莓派RP2040_game_kit屏幕驱动方法及Flappy_bird游戏移植
这一期活动主角是“2022寒假在家练”pico_game_kit,重点介绍game_kit在Arduino环境st7789屏幕的驱动问题及利用该屏幕驱动移植了一款经典小游戏,供大家借鉴参考。
genvex
基于树莓派RP2040的嵌入式系统学习平台设计的赛车游戏
仿照经典的“公路赛车”游戏,设计的一款纵向无限挑战游戏,在有限的三条车道内利用树莓派pico板卡的加速度传感器,实现汽车的自由移动,躲避障碍车,碰撞奖励车以获得尽可能高的分数,是一款十分考验反应力的游戏。
bear
深圳大学
基于RP2040嵌入式系统学习平台制作的图形化显示、超温报警的温度计
该项目是一个基于树莓派RP2040的嵌入式系统学习板、使用micropython进行编程实现的图形化显示、超温报警的温度计。
EIDog
北京理工大学
用树莓派RP2040的嵌入式系统学习平台制作一个图形化显示、超温报警的温度计
在LCD屏上显示一个图形化的温度计,并实时显示当前的温度(通过RP2040内部的温度传感器测量)
MMA
基于树莓派RP2040制作的任意波形发生器
使用树莓派微控制器RP2040,通过双路PWM + LPF生成DC-50KHz之间的任意波形,能够精准调节输出信号幅度和的频率。
adking
基于树莓派RP2040设计lcd与电脑的鼠标
本设计采用树莓派Pico核心芯片RP204 为处理核心,以硬禾学堂的游戏机上面的四向摇杆和3个轻触按键用做输入控制,实现了lcd与电脑上鼠标的控制。利用四向摇杆实现鼠标的移动,游戏机上面的按键则对应鼠标的左右键和鼠标中键
doctor雷
湖北理工学院
基于RP2040制作水平仪
预刷官方固件和参考相关文件,利用树莓派RP2040的姿态传感器完成水平仪的制作
wzx
北京理工大学
基于树莓派RP2040的24点小游戏
经典的童年小游戏--24点。它始于何年何月已无从考究,但它以自己独具的数学魅力和丰富的内涵正逐渐被越来越多的人们所接受。这种游戏方式简单易学,能健脑益智,是一项极为有益的活动。
是宋宋啊
金陵科技学院
基于树莓派RP2040的嵌入式系统学习平台实现能控制LCD和电脑界面的“鼠标
基于树莓派RP2040的嵌入式系统学习平台实现能控制LCD和电脑界面的“鼠标”
myd3
北京理工大学
基于RP2040实现坦克大战游戏制作
本项目依托2022寒假在家练,基于RP2040GameKit平台,实现了坦克大战游戏的制作。本项目通过LCD屏幕、按键和四向摇杆实现了游戏的游玩,并调用蜂鸣器实现了游戏配乐与游戏音效,取得了良好的游戏体验,具有一定的娱乐价值。
Iccccy
北京理工大学
基于树莓派RP2040嵌入式系统学习平台设计俄罗斯方块
通过树莓派RP2040以及microPython进行俄罗斯方块的开发,通过LCD屏显示,通过按键和四向摇杆控制游戏的动作;在游戏中要通过蜂鸣器播放背景音乐。
arbelat
北京理工大学
基于树莓派RP2040制作经典游戏Pong
用树莓派RP2040移植经典游戏Pong,可以选择游戏难度和背景音乐的开关,游戏中也会有难度的升级
程序abe
江苏科技大学
基于树莓派rp2040的嵌入式系统能控制LCD和电脑界面的“鼠标”
本次基于树莓派rp2040的嵌入式系统进行了能控制LCD和电脑界面的“鼠标”的设计,实现了给定的目标
zzzzzz
北京理工大学
基于树莓派RP2040的超温报警的温度计设计
本项目是基于树莓派RP2040设计制作一个图形化显示、超温报警的温度计,实现包括RP2040温度传感器读取、温度计UI绘制、摇杆控制行为识别、蜂鸣器驱动等功能组合的带有阈值可设的具有超温报警功能的温度计。
maskmoo
沈阳大学
基于RP2040游戏机的东百往事雷霆战机小游戏
“我徒弟呢?”虎酱徒弟惨遭杀马特军团绑架。为拯救徒弟,虎酱单刀赴会,一人单挑众杀马特士兵。此时,baby的杀马特军团长驾驶“反虎”式坦克,拦在虎酱面前。虎酱该如何处理这场危机?尽在《雷霆战机小游戏之东百往事》……
火箭恐龙
北京理工大学
基于树莓派RP2040实现模拟鼠标
本项目实现的是利用Micro python编程,以树莓派RP2040为载体,实现模拟鼠标。
Mhz
北京理工大学
用树莓派RP2040完成推箱子小游戏移植
利用硬禾学堂提供的树莓派RP2040游戏机套件,完成对于经典小游戏推箱子的移植。
Qin
中央民族大学
树莓派PICO——基于树莓派pico游戏机实现LCD屏幕和电脑鼠标的控制
1.利用板上的四向摇杆和按键设计一款“鼠标” 2.在240*240的LCD屏幕内可以通过该鼠标进行菜单选择和参数控制(在屏幕上要有上图中图形化的箭头形状) 3.通过USB端口可以控制PC屏幕上的光标移动和点击操作,行使电脑鼠标的功能
好喝的娃哈哈
济南大学
基于树莓派RP2040实现能控制LCD和电脑界面的“鼠标”
本项目使用了硬禾学堂针对"2022年寒假在家一起练"开发的"基于RP2040的嵌入式系统学习平台",通过软件编程(使用MicroPython),以Thonny为工具,实现可以实时控制LCD和电脑界面的“鼠标。
noahall
燕山大学
基于树莓派RP2040实现复古游戏“打砖块”的移植项目
这是我参加“硬禾学堂2022寒假在家练”活动所完成的项目,项目使用的是树莓派RP2040开发板。 项目实现的总体功能是将复古游戏“打砖块”移植到树莓派RP2040开发板上。
emmmmmm
中央民族大学
基于树莓派rp2040实现俄罗斯方块游戏
基于树莓派rp2040实现俄罗斯方块游戏的移植,运用Thonny进行编程,采用树莓派Pico核心芯片RP2040。
hhhYY
中央民族大学
2022寒假在家练——基于树莓派RP2040嵌入式系统实现的水平仪
该水平仪基于RP2040嵌入式系统实现,以mma7660三轴姿态传感器及st7789lcd显示屏实现的水平仪项目
小yang
四川大学
基于rp2040完成改编贪吃蛇小游戏
改写贪吃蛇小游戏,添加背景音乐、修改开屏特效、计分方式、北京颜色和结束游戏的提示语
漩涡绮纶
中央民族大学
2022寒假在家练——基于树莓派RP2040实现推箱子小游戏
使用Thonny IDE连接RP2040 Game Kit,基于MicroPython语言实现了一款经典的推箱子小游戏,将地图上所有箱子推到指定的标记点处即为游戏成功。
王雪怡
中央民族大学
树莓派RP2040--使用姿态传感器制作水平仪
1.树莓派RP2040开发套件简介 2.使用树莓派RP2040板载姿态传感器制作水平仪
Titan
基于树莓派RP2040的嵌入式系统学习平台制作模拟电压表
本项目基于树莓派Pico的嵌入式系统学习平台的数字电压表,可扩展性强、集成方便,利用PIco的AD转换器采集电压,利用LCD模拟指针式显示显示方式实现双路电压表测量和显示。
anyaoy
北京理工大学
基于树莓派RP2040的嵌入式系统学习平台制作一个图形化显示、超温报警的温度计
该项目是一个图形化显示、超温报警的温度计实现的功能有:1、在LCD屏上显示一个图形化的温度计,并实时显示当前的温度;2、可以通过摇杆或按键设定报警温度阈值;3、芯片温度超过设定的阈值,温度图示颜色变红,且蜂鸣器发出报警声音;
针针扎是带啥纸
电子科技大学
基于树莓派RP2040完成俄罗斯方块
利用树莓派RP2040和Thonny实现复古游戏移植,设计制作俄罗斯方块小游戏
HYYG
北京理工大学
基于树莓派rp2040的LCD及电脑鼠标
本项目用硬禾学堂的基于树莓派rp2040的开发套件,制作了一款可操控其LCD屏及PC指针的“鼠标”。此次设计用micropython进行编程。
2010522075
四川大学
基于树莓派RP2040设计的多功能游戏机
2022寒假在家练,基于树莓派RP2040设计的包含模拟鼠标、水平仪和贪吃蛇游戏的多功能游戏机。
我卡壳了
燕山大学
基于树莓派RP2040实现经典游戏“锯齿数独”的移植项目。
这是我参加“硬禾学堂2022寒假在家练”活动所完成的项目,项目使用的是树莓派RP2040开发板。该项目是基于树莓派RP2040实现经典游戏“锯齿数独”的移植项目。
530325
中央民族大学
基于树莓派RP2040设计简单的游戏并实现鼠标功能
用micropython在树莓派RP2040游戏机上编写一个简单的“别碰方块”小游戏,并且结合了鼠标移动,音乐播放和菜单选择。
usereetree
南京航空航天大学
基于树莓派RP2040制作能控制LCD和电脑界面的“鼠标”
通过microython进行编写,在树莓派RP2040芯片中实现鼠标的功能:鼠标的移动和电机,并且在LCD屏幕上进行显现。
典狱长先生
北京理工大学
基于RP2040开发板的水平仪实验作业
基于RP2040树莓派Pico开发板的水平仪实验作业,传感器芯片为板载MMA7660
大老韩
南开大学
基于树莓派RP2040-GameKit制作水平仪
基于GameKit板载的mma7660传感器制作的水平仪,实现了气泡与文字双重显示,大体标定合格
小栋栋
基于RP2040实现Pong游戏
基于RP2040实现了经典的Pong游戏,除了游戏规则和画面的实现,还实现了背景音乐的播放和暂停功能
xjy
中央民族大学
基于树莓派RP2040嵌入式学习平台所开发的俄罗斯方块游戏
一款基于树莓派RP2040嵌入式学习平台,运用micropython语言所开发的俄罗斯方块小游戏项目,在该平台上基本还原了我们平时所玩到的俄罗斯方块游戏。
Quhuner
北京理工大学
基于树莓派RP2040制作图形化显示、超温报警的温度计
该项目使用micropython编程,基于树莓派RP2040实现温度计。温度计能够显示温度,并且在温度高于阈值时,启动蜂鸣器,并将图像变红。
XZYZYZY
南京航空航天大学
使用树莓派RP2040嵌入式系统学习平台设计鼠标
该项目基于树莓派RP2040的嵌入式系统学习平台,使用micropython编写,最终呈现效果是模拟我们平常使用的鼠标
回龙观电工职业技术学校刘旋
华北电力大学
基于树莓派RP2040的嵌入式系统学习平台
基于树莓派RP2040设计的嵌入式系统学习板,通过MicroPython编程能够学习嵌入式系统的核心且基本的内容,板上有丰富的输入、输出外设,可以通过各种有趣的示例深刻体会嵌入式系统的控制机制。
团队介绍
-
苏州硬禾信息科技有限公司
猜你喜欢
基于树莓派RP2040的嵌入式系统学习平台制作摇杆鼠标
基于树莓派RP2040的嵌入式系统学习平台制作摇杆鼠标,能够通过摇杆和按键实现鼠标的功能,包括长按、短按、拖动和滚动,并在LCD上显示鼠标图像。
-
student
- 679
- 22/03/02