红外遥控模块
哎,,图便宜买了个三个针(数据线,接地线,电源线)的,,给我整吐了。。。
原理:
按下遥控器的某一个键,遥控器会发出一连串经过调制后的信号,这个信号经过红外一体化模块接收后,输出解调后的数字脉冲,每个按键对应不同的脉冲,故识别出不同的脉冲就能识别出不同的按键。
反正就是测量高电平的时间,长的就是1,短的就是0。我查的是高电平1.685ms,低电平就是0.56ms,但是不对啊,,,我试了一下分界是10ms,,这差的有点多。。这是为什么呢。。。
下面就是遥控器发送数据的格式,也就是说我们就要那八位数据码就行,引导码9ms , 后面的高电平是结果码 4.5ms (也不知道是不是真的),然后就是遥控器按键发送的数据码(二进制)
from pyb import *
from time import sleep
x=Pin('X1') # 数据线连到了x1 口
def test(): # 逻辑挺简单的,就是试了很多很多次,,,,
n=0
N=32
global list1
list1=[]
while(x.value()): # 等待信号出现
sleep(0.0001)
while(not x.value()): # 跳过引导码
sleep(0.0001)
while N:
while(x.value()): # 跳过结果码
sleep(0.0001)
while(not x.value()):
sleep(0.0001)
while(x.value()): # 高电平计时
sleep(0.0001)
n+=1
if(n>=100):
list1.append('1')
else:
list1.append('0')
# print(n)
n=0
N-=1
def aaa(): # 反正我试的系统码1全是0,如果出现1,,我也不知道咋回事,偶尔会出现吧。。
if(list1[0]=='0'):
list2=list1[16:24]
else:
list2=list1[17:25]
list2.reverse() # 研究了很多次,得到的数据是反的,,,啊,,这是为什么
return int(''.join(list2),2)
def led():
a=aaa() # 控制一下灯吧,,
if(a==69):
LED(1).toggle()
elif(a==70):
LED(2).toggle()
else:
LED(3).toggle()
while 1:
test()
sleep(1)
led()
然后又买了个四个线的(VCC GND RXD TXD),使用UART串行总线控制,,,这个就简单很多很多很多了。。。
import pyb,time
x=pyb.Pin('X1',pyb.Pin.OUT_PP)
uart=pyb.UART(3,9600,timeout=50) # 使用 Y9 Y10 ..注意不要把TX RX 插反啊。。。
while True:
if uart.any() > 0:
val = uart.read()[-1] # 使用uart.any() 我们获得三个数据,前两个固定的,系统码之类的吧 ,后面就是需要的数据码了。
N=10 # 按下 |<< 键就逆时针转三秒, >>| 键就顺时针
if val == 68:
while N:
x.high()
pyb.udelay(24200)
x.low()
pyb.delay(300)
N-=1
elif val == 64:
while N:
x.high()
pyb.udelay(10000)
x.low()
pyb.delay(300)
N-=1
print('end')
class UART 双工串行通信总线
作为一个小白我是一个字都不认识的。。。
串行并行:并行通信就是一个时刻可以传输多个位,需要的线多。串行就是一个时间就能传一位,一根线就行
双工:通信允许数据在两个方向上同时传输。(A-B, B-A),单工嘛,就是只能传一个方向。
接口:TX数据发送,RX数据接收。两个设备间将TX与RX相连,RX与TX相连即可正常工作。最常用到的就是我们电脑上的USB那就是个最典型的UART接口。将由计算机内部传送过来的并行数据转换为输出的串行数据流。将计算机外部来的串行数据转换为字节,供计算机内部并行数据的器件使用。
通信协议:
- 空闲位:总线处于空闲时信号线为高电平,
- 起始位:0表示开始。
- 数据位 5-9位,构成一个字符。
- 奇偶校验位:就不用把。。
- 停止位:可以是1/1.5/2位的高电平。
- 波特率:数据传输速率(bits per second bps) 常见的5900 115200.
9600 8N1(9600波特率,8个数据位,没有校验位,1位停止位)。。。
from pyb import UART # 实例化,,python就是简洁清楚啊。。。
uart=UART(1,9600)
uart.init(9600,bits=8,parity=None,stop=1) # 数据位可以是7 8 9 奇偶校验位就None, 停止位可以是1 2
# 如果奇偶校验位是NOne,就只支持8 9 如果启用奇偶校验支持7 8
类方法
class pyb.UART(bus ,,,,,,)
使用给定的总线构建一个UART对象,Pyboard 的 bus 可以是 1-4,6 XA XB YA YB.Pyboard Lite bus can be 1, 2, 6, ‘XB’, or ‘YA’. For Pyboard D bus can be 1-4, ‘XA’, ‘YA’ or ‘YB’。没有其他参数就只创建但不初始化。给了别的参数就用来初始化
Pyboard 的UART 总线引脚:
- UART(4) is on XA: (TX, RX) = (X1, X2) = (PA0, PA1)
- UART(1) is on XB: (TX, RX) = (X9, X10) = (PB6, PB7)
- UART(6) is on YA: (TX, RX) = (Y1, Y2) = (PC6, PC7)
- UART(3) is on YB: (TX, RX) = (Y9, Y10) = (PB10, PB11)
- UART(2) is on: (TX, RX) = (X3, X4) = (PA2, PA3)
UART.init(baudrate, bits=8, parity=None, stop=1, timeout=0, flow=0, timeout_char=0, read_buf_len=64)
初始化,分别是时钟速率,每个字符的位数,奇偶校验,停止位数,流量控制类型(可以是0,RTS,CTS),等待写入/读取第一个字符的超时(毫秒),写入或读取字符之间等待的超时(毫秒),读取缓存区的字符长度(0就是禁用)
如果奇偶校验=无,则仅支持8位和9位。启用奇偶校验后,仅支持7位和8位。
UART.deinit()
关闭总线
UART.any()
返回等待的字节数(可以为0)
UART.read([nbytes ])
读取字符。指定了 nbytes 最多就读取这么多。如果nbytes 可以在内存中使用,就立刻返回,没指定就返回尽量多的字符或超时后返回。注意:对于9位字符,每个字符占用两个字节,nbytes 必须是偶数,并且字符数为 nbytes/2
UART.readchar()
在总线上收到一个字符,返回值:读取的字符为整数,超时就返回-1。
UART.readinto( buf, [ nbytes])
将字符读取到缓冲区中,如果指定了nbytes 就读取这么多字符,否则就读取 len(buf) 字节,返回值:在超时前读取或储存到 buf or None 的字节数
UART.readline()
读取一行,以换行符结尾。如果存在这样的行,则立即返回。如果超时过去,则无论是否存在换行符,都会返回所有可用数据。
UART.write(buf)
将字节缓存区写入总线,如果字符为7 或 8位,每个字节位一个字符,如果字符是九位,每个字符使用两个字节。并且 buf 必须包含偶数个字节。返回值:写入的字节数,如果超时或没写入就返回None。
UART.writechar(char)
在总线上写一个字符,char是要写入的整数,返回值: None ,如果使用CTS流量控制参考下面的
UART.sendbreak()
在总线上发送一个停止条件,这将总线拉低持续13位,返回None。
常量 UART.RTS/ UART.CTS 选择流量控制类型。
流量控制
UART(2) and UART(3) 支持 RTS/CTS 硬件流量控制,使用以下引脚:
- UART(2) is on: (TX, RX, nRTS, nCTS) = (X3, X4, X2, X1) = (PA2, PA3, PA1, PA0)
- UART(3) is on :(TX, RX, nRTS, nCTS) = (Y9, Y10, Y7, Y6) = (PB10, PB11, PB14, PB13)
UART的 init 方法的 flow 设置了一个或RTS CTS两个全部,相关的流量控制引脚就会被配置。nRTS 是低电平有效输出,nCTS是低电平有效输入,且启用上拉电阻。为了实现流量控制,板子的nCTS 信号连接到目标的nRTS, 将板子的nRTS 连接到目标的nCTS.。
CTS:目标控制板子的发送器
启用了CTS 流量控制,写入行为如下(下面的目标就是跟板子连的器件):
如果板子的UART.write(buf) 方法被调用,当nCTS is False 时,传输可以在任何时间停止。如果在超时时间内没有发送整个缓冲区就会导致超时。。这个方法返回写入的字节数,可以让用户来写入其余的数据,如果发生超时,字符将保留在UART中,等待nCTS。 组成此字符的字节数将包含在返回值中。。。。啊。。什嘛玩意
在nCTS is False 时调用 UART.writechar() ,这个方法会超时,除非目标即时声明 nCTS.。如果超时就引发 OSError 116。只要目标声明nCTS,字符就会被发送。
RTS:板子控制不要的发送器
如果使用缓存区输入(read_buf_len > 0) ,传入的字符将被缓冲。如果缓冲区满了,下一个到达的字符就会导致nRTS 变成 False:目标应该停止传输。在从缓冲中读取完了字符nRTS 就会变成True。
注意,any() 方法返回缓冲中的字节数。假如缓存中有n个字节,如果缓存满了另一个字符来了,nRTS 变成False, any() 会返回数字 n 。读取字符时,附加字符将被放置在缓冲区中,并将包含在之后调用的 any() 方法中。
如果不使用缓冲输入(read_buf_len == 0),则字符的到达将导致nRTS变为False,直到读取字符为止。