37种传感器(七)之旋转编码传感器模块+Stduino Nano&UNO 关键词:
9 p: n: y5 W- W+ l51、stm32、arduino、stduino、单片机、stduino UNO&Nano、旋转编码传感器模块 说明:; H1 w" K: I0 d9 r, i
旋转编码器可通过旋转来计数(即可从0开始不但加一或者减一,计数范围没有限制),实现精确数字的调节。电机角度等需要特别精确调节的元器件可以利用编码器来实现精细控制。配合旋转编码器上的按键,可以复位到初始状态,即从0开始计数。 依照内部数字读取办法,编码器能够分为机械式和非机械式两种:机械式选用电刷输出,电刷接触到导电区则引脚输出高电平,接触到绝缘区则为低电平;非机械式的承受灵敏元件是光敏元件或磁敏元件,选用光敏元件时以透光区和不透光区来表明输出是“高”还是“低”。
+ W- ]& {% j: {( @! q& J3 D目前常用的增量式编码器全部为机械式编码器,优点在于好用且成本低,高端的一般为非机械光电式的。我们采用的模块也使用得机械式。9 x% q; B( b* M
如果你手上有一个旋转编码器,你可以试着拧一下:并不是连续旋转,而是拧的得时候会明显感受到不连续,一下一下的。因此,我们可以实现精确的计数,这与电位器是不同的 那么问题来了,怎么计数呢?我们可以做以下规定: 以顺时针方向为正,凡往顺势针方向转一下,则计数加一,同理转N下,则计数加n。反之,如果向逆时针转一下,则计数减一,同理转N下,则计数减n。 逆时针同理。 现在问题又来了,旋转编码器怎么告诉微处理器,我的旋转方向是什么呢?这些我们打开旋转编码器的微观结构: 实际上旋转编码器内部结构如下所示。基本上由绝缘圆盘(灰色)和放置在圆盘顶部的导电垫(蓝色)组成。# t" L! h4 a, y+ t) m$ B$ `
这些导电垫分离放置,因此当旋转旋钮时,旋转一单位,原先空着的部分会被导电垫填充,而导电垫离开的位置则重新恢复绝缘。因此,当导电垫通过A和B输出引脚时,引脚会输出高电平信号,反之则不会输出高电平。因此只要判断引脚信号与上一次是否相同,就能得知是否发生了旋转。 如下图,每一次旋转的时候,当顺时针旋转,A总是先比B接触到导电垫,或者离开导电垫,因此A总是比B先改变电平输出状态,此时当A发生变化后一定与B信号不同。下图为两次顺时针旋转时,A、B电平变化(红色为输出高电平信号)
而当逆时针旋转时,B先于A转换电平,因此当检测到A发生变化时,此时B已经完成了信号转换,此时A、B信号相同。 实验目的:2 e" i; G( ~$ V+ a. B3 u
利用旋转编码器实现计数。 器材:
: z2 T% L( N6 t3 a" ^StduinoUno/Nano;杜邦线;旋转编码器模块。 电路连接:
代码展示: - <font face="Arial" size="2">#define outputA 81 }6 @9 W4 o1 h! b) z5 j/ W% K
- #define outputB 7
0 }! R" ?7 H, F$ N - int counter = 0;
" [4 T1 f8 H; u8 O1 [- f. O& R) ` - int aState;1 G( W: B2 L% c# s# o/ G; k! n
- int aLastState; ( q! |" }5 X# m
- void setup()& W& F, h- o3 C: x/ J' o9 B
- {; t9 C- I, z+ g+ E; ^8 ]0 E* ^
- pinMode (outputA,INPUT);
( V& f" Q! b6 j( S2 X - pinMode (outputB,INPUT);
) U1 E1 I/ ~' S2 x' G -
% p, _* a4 h$ j1 z! w9 j - Serial.begin (9600);
9 }2 O8 Z; C$ t# P; S - , {( w+ {7 [. l
- aLastState = digitalRead(outputA); * w, {, {/ s2 x, C
- }
# Z) O7 x% f4 j1 U3 m - void loop()
. A: ~' w; Z& [4 o3 l# ] - {
+ ?8 G5 y$ M, X+ R9 f8 U - aState = digitalRead(outputA); // 读取当前A电平% g8 W5 H/ A; b
- //如果当前A电平与上一次(初始)A电平不同,说明发生了旋转9 g5 x# E# S- K( P
- if (aState != aLastState)$ H5 l/ a8 `7 [; N8 C: V& C
- { % Q! z6 y7 Y4 T1 v2 f4 Z! w; j
- // 如果A\B电平不同,说明A先于B变化,因此是顺时针旋转。顺时针旋转则计数加一;反之则减一6 W/ N3 h5 Z0 r: O. D6 Q
- if (digitalRead(outputB) != aState)
, H Q3 d) N- H# `+ Q" L - {* z9 h. V% b- A8 a, n9 e6 w7 F
- counter ++;& N6 S5 g7 ]9 {: I4 b3 x
- } else
0 c6 R4 s! K. o! p - {7 Z- z" I& @ O
- counter --;
; E# n) ^. C v: w* a. R - }
5 e9 h' C( w# o' U" ]. J# @# N - Serial.print("Position: ");1 j* D* c1 f8 |2 w' ~" w: `9 x
- Serial.println(counter);4 g1 @1 ?: \5 G* n' i1 R
- }* Y5 v& Q1 u; M& O
- aLastState = aState; //更新aLastState状态的记录
6 a& M1 r+ R" g2 ^ - }</font>
复制代码 . H |; ^ R+ t: t6 s7 m/ |
实验效果:: n5 s* ?: X% k1 G- z
当顺时针旋转的时候,计数数目逐次加一;当逆时针旋转时,技术数目逐次减一。下面所示为顺时针旋转八个单位的过程中串口输出情况。
1 k: S* e- u/ m" Z1 L7 d
6 r0 j; w" ^0 s, ?: ?
! ?0 g% `+ s4 e$ C
' j. \$ J" A/ ^8 t |