BPI-Pico-S3 与 Raspberry Pi Pico 板尺寸相同,搭载ESP32S3芯片,8M flash,4层PCB,电镀半孔工艺,陶瓷天线,支持 2.4 GHz Wi-Fi 和 Bluetooth® LE 双模无线通信,是一款专为物联网开发和Maker DIY设计的开发板。
出厂内置 tinyUF2 + CircuitPython,推荐使用上手CircuitPython开发。
BiliBili视频 https://www.bilibili.com/video/BV1yd4y1t75R
硬件接口示意图
使用增量型旋转编码器
接线参考
增量型旋转编码器BPI-PicoW-S3
GND | GND |
+ | VBUS |
SW | |
DT | GP0 |
CLK | GP1 |
增量型旋转编码器外观粗看与一些常见的旋转电位器相似,其关键的不同之处大致分为三点。
微控制器使用ADC外设来读取旋转电位器输出的模拟信号(电压值),确定转轴当前角位;微控制器通过GPIO接收增量型旋转编码器输出的数字信号,可通过软件程序判断信号所对应的转轴动作。
微控制器可在一定精度下,确定旋转电位器转轴当前角位,但因为模拟信号的持续性与抗干扰能力差的原因,无法准确判断它是否有动作;增量型旋转编码器仅在转轴运动到一个触点时,向微控制器发出一段动作数字信号,如果一个增量型旋转编码器一周有20个触点,它旋转一周就触发20次动作信号,微控制器可以精确的判断它是否动作,向哪个方向转动,信号触发了多少次。
旋转电位器通常不可向任意转向进行无限旋转,会停止在最大或最小限位点;增量型旋转编码器可向任意转向进行无限旋转。
增量型旋转编码器采用正交编码器生成其A和B的输出信号。从A和B输出****的脉冲是正交编码的,这意味着当增量编码器以恒定速度运动时,A和B波形是方波,A和B之间存在90度的相位差。最终A和B信号将从两个管脚传输给微控制器。
理论上,在任何特定时间,对于旋转编码器,A和B信号之间,顺时针旋转的相位差为+90°,逆时针旋转的相位差为−90°,具体则取决于设备内部的正交编码器设计。
A或B输出上的脉冲频率与转轴的速度(位置变化率)成正比。较高的频率表示较快的速度,而较低的频率表示较慢的速度。当转轴静止时,静态、不变的信号输出在A和B上,所以有很多测速方案使用增量型旋转编码器。
参考 。
用CircuitPython设计一个程序读取在GP0与GP1引脚上的信号,当其中一个发生变化时同时输出两个引脚当前的值,连接开发板与增量型旋转编码器后运行程序。
import board
import digitalio
dt = digitalio.DigitalInOut(board.GP0)
clk = digitalio.DigitalInOut(board.GP1)
dt.switch_to_input()
clk.switch_to_input()
dt_last_value = 0
clk_last_value = 0
while True:
if dt.value != dt_last_value or clk.value != clk_last_value:
dt_last_value = int(dt.value)
clk_last_value = int(clk.value)
print((dt_last_value,clk_last_value))
逐级转动转轴,观察输出信号,如果有逻辑分析仪或示波器也可接入观察。
转轴逆时针旋转时,REPL的输出。
转轴逆时针旋转时,逻辑分析仪所观察到的波形。
转轴顺时针旋转时,REPL的输出。
转轴逆时针旋转时,逻辑分析仪所观察到的波形。
(1, 1)
(1, 0)
(0, 0)
(0, 1)
(1, 1)
(1, 0)
(0, 0)
(0, 1)
(1, 1)
(1, 1)
(0, 1)
(0, 0)
(1, 0)
(1, 1)
(0, 1)
(0, 0)
(1, 0)
(1, 1)
首先可以观察到的现象是,转轴完成一级动作后,两个引脚上的信号都为1,可以设计程序,当值都变为1时输出一次计数值,计数值可作为判断编码器完成一次动作的依据。
import board
import digitalio
dt = digitalio.DigitalInOut(board.GP0)
clk = digitalio.DigitalInOut(board.GP1)
dt.switch_to_input()
clk.switch_to_input()
dt_last_value = 0
clk_last_value = 0
count = 0
while True:
if dt.value != dt_last_value or clk.value != clk_last_value:
dt_last_value = int(dt.value)
clk_last_value = int(clk.value)
print((dt_last_value,clk_last_value))
if (dt_last_value,clk_last_value) == (1,1):
print('--',count_1,'--')
count += 1
再确定编码器顺时针旋转与逆时针旋转的动作,在两个引脚上输出的信号变化的规律与差异。
逆时针旋转的规律为(1, 1)>(1, 0)>(0, 0)>(0, 1)>(1, 1)。
顺时针旋转的规律为(1, 1)>(0, 1)>(0, 0)>(1, 0)>(1, 1)。
由此可设计一个顺时针旋转使计数+1,逆时针旋转使计数-1的程序,并加入消抖除错的功能。
import board
import digitalio
import time
dt = digitalio.DigitalInOut(board.GP0)
clk = digitalio.DigitalInOut(board.GP1)
dt.switch_to_input()
clk.switch_to_input()
dt_last_value = 0
clk_last_value = 0
count = 0
start_sign = 0
clockwise_sign = 0
while True:
if dt.value != dt_last_value or clk.value != clk_last_value:
dt_last_value = int(dt.value)
clk_last_value = int(clk.value)
print((dt_last_value,clk_last_value))
if start_sign == 0 and (dt_last_value,clk_last_value) == (0,0):
start_sign = 1
elif start_sign == 1:
if (dt_last_value,clk_last_value) == (1, 0):
clockwise_sign = 1
elif (dt_last_value,clk_last_value) == (0, 1):
clockwise_sign = -1
elif (dt_last_value,clk_last_value) == (1, 1):
count = count + clockwise_sign
clockwise_sign = 0
start_sign = 0
print('--',count,'--')
此程序中的消抖除错功能的实现,并不是逐步判断验证是否符合信号规律,或许还有更多办法可以实现消抖除错,欢迎讨论。
另外 CircuitPython 的rotaryio模块可直接实现正反转计数功能。(内部程序有所差异,但最终实现功能基本一致)。
import rotaryio
import board
encoder = rotaryio.IncrementalEncoder(board.GP0,board.GP1)
last_position = 0
while True:
position = encoder.position
if position != last_position:
print(position)
last_position = position
BPI-PicoW-S3 + CircuitPython 教程聚合链接:https://forum.banana-pi.org.cn/t/topic/3986?u=wind_
BPI-PicoW-S3 wiki 页面:https://wiki.banana-pi.org/BPI-PicoW-S3
购买BPI-PicoW-S3:
比派科技官方速卖通店铺:https://www.aliexpress.com/item/1005004775634442.html
SinoVoip 官方速卖通店铺:https://www.aliexpress.com/item/1005004775859077.html
官方淘宝店铺:
OEM&OEM 定制服务: