废话少说,直接上空调板子:YAPOF3。红外接收发射模块用的某宝上发现的YF-33(遗憾解码还没搞清楚,不然做个lirc.conf功能才多)。最后是语音识别用的幻尔的,某宝自然也有,它是个i2c的接口。

 

 本篇胡说八道其实纯粹为了留个地方以后知道怎么在python脚本里面写串口指令。接下来就顺带着讲一下全流程吧。

1. 先把幻尔的语音模块里面录好几个要说的话。

# initiate_yuyin.py
# encoding: utf-8
'''
Company: 深圳市幻尔科技有限公司
官网:hiwonder.com
日期:2019/9/20
by Aiden
'''
'''
 * 只能识别汉字,将要识别的汉字转换成拼音字母,每个汉字之间空格隔开,比如:幻尔科技 --> huan er ke ji
 * 最多添加50个词条,每个词条最长为79个字符,每个词条最多10个汉字
 * 每个词条都对应一个识别号(1~255随意设置)不同的语音词条可以对应同一个识别号,
 * 比如“幻尔科技”和“幻尔”都可以将识别号设置为同一个值
 * 模块上的STA状态灯:亮起表示正在识别语音,灭掉表示不会识别语音,当识别到语音时状态灯会变暗,或闪烁,等待读取后会恢复当前的状态指示
'''
#使用例程
import smbus
import time
import numpy

class ASR:

    # Global Variables
    address = None
    bus = None

    ASR_RESULT_ADDR = 100
    #识别结果存放处,通过不断读取此地址的值判断是否识别到语音,不同的值对应不同的语音

    ASR_WORDS_ERASE_ADDR = 101
    #擦除所有词条

    ASR_MODE_ADDR = 102
    #识别模式设置,值范围1~3
    #1:循环识别模式。状态灯常亮(默认模式)
    #2:口令模式,以第一个词条为口令。状态灯常灭,当识别到口令词时常亮,等待识别到新的语音,并且读取识别结果后即灭掉
    #3:按键模式,按下开始识别,不按不识别。支持掉电保存。状态灯随按键按下而亮起,不按不亮

    ASR_ADD_WORDS_ADDR = 160
    #词条添加的地址,支持掉电保存

    def __init__(self, address, bus=1):
        self.address = address
        self.bus = smbus.SMBus(bus)

    def readByte(self):
        return self.bus.read_byte(self.address)

    def writeByte(self, val):
        value = self.bus.write_byte(self.address, val)
        if value != 0:
            return False
        return True

    def writeData(self, reg, val):
        self.bus.write_byte(self.address,  reg)
        self.bus.write_byte(self.address,  val)

    def getResult(self):
        if ASR.writeByte(self, self.ASR_RESULT_ADDR):
            return -1
        value = self.bus.read_byte(self.address)
        return value
    '''
    * 添加词条函数,
    * idNum:词条对应的识别号,1~255随意设置。识别到该号码对应的词条语音时,
    *        会将识别号存放到ASR_RESULT_ADDR处,等待主机读取,读取后清0
    * words:要识别汉字词条的拼音,汉字之间用空格隔开
    *
    * 执行该函数,词条是自动往后排队添加的。
    '''
    def addWords(self, idNum, words):
        buf = [idNum]
        for i in range(0, len(words)):
            buf.append(eval(hex(ord(words[i]))))
        self.bus.write_i2c_block_data(self.address, self.ASR_ADD_WORDS_ADDR, buf)
        time.sleep(0.05)

    def eraseWords(self):
        result = self.bus.write_byte_data(self.address, self.ASR_WORDS_ERASE_ADDR, 0)
        time.sleep(0.06)
        if result != 0:
           return False
        return True

    def setMode(self, mode):
        result = self.bus.write_byte_data(self.address, self.ASR_MODE_ADDR, mode)
        if result != 0:
           return False
        return True

if __name__ == "__main__":
    addr = 0x79 #传感器iic地址
    asr = ASR(addr)

    if 1:
        asr.eraseWords()
        asr.setMode(1)
        asr.addWords(1,'miao le ge mi mi mi')  # 唤醒词条在此
        asr.addWords(2,'da kai kong tiao zhi leng')  # 打开空调制冷
        asr.addWords(3,'kong tiao zhi re kai')  # 空调制热开
        asr.addWords(4,'guan bi kong tiao') # 关闭空调

2. 开启唤醒模式,操控空调。

# yuyin.py
# encoding: utf-8
import smbus
import time
import serial

ser = serial.Serial(
    port='/dev/ttyUSB0',
    baudrate=9600,
    parity=serial.PARITY_NONE,
    stopbits=serial.STOPBITS_ONE,
    bytesize=serial.EIGHTBITS,
    timeout=1
    )

class ASR:

    # Global Variables
    address = None
    bus = None

    ASR_RESULT_ADDR = 100

    ASR_MODE_ADDR = 102

    ASR_ADD_WORDS_ADDR = 160
    #词条添加的地址,支持掉电保存

    def __init__(self, address, bus=1):
        self.address = address
        self.bus = smbus.SMBus(bus)

    def readByte(self):
        return self.bus.read_byte(self.address)

    def writeByte(self, val):
        value = self.bus.write_byte(self.address, val)
        if value != 0:
            return False
        return True

    def writeData(self, reg, val):
        self.bus.write_byte(self.address,  reg)
        self.bus.write_byte(self.address,  val)

    def getResult(self):
        if ASR.writeByte(self, self.ASR_RESULT_ADDR):
            return -1
        value = self.bus.read_byte(self.address)
        return value

    def setMode(self, mode):
        result = self.bus.write_byte_data(self.address, self.ASR_MODE_ADDR, mode)
        if result != 0:
           return False
        return True

if __name__ == "__main__":
    addr = 0x79 #传感器iic地址
    asr = ASR(addr)

    #来自串口指令那个图片给的发送地址。这儿就已经用了3个,这个模块一共才4个位置。
    arr_data2 = [0x01,0x06,0x00,0x01,0x00,0x02,0x59,0xCB]
    arr_data3 = [0x01,0x06,0x00,0x01,0x00,0x03,0x98,0x0B]
    arr_data4 = [0x01,0x06,0x00,0x01,0x00,0x01,0x19,0xCA]

    if 1:
        asr.setMode(2)  #启动唤醒模式
        #asr.addWords(1,'miao le ge mi mi mi')  # 唤醒
        #asr.addWords(2,'da kai kong tiao zhi leng')  # 打开空调制冷
        #asr.addWords(3,'kong tiao zhi re kai')  # 空调制热开
        #asr.addWords(4,'guan bi kong tiao') # 关闭空调
    while 1:
        data = asr.getResult()
        #print("result:", data)
        if data == 2:
            #echo -en '\x01\x06\x00\x01\x00\x02\x59\xCB' > /dev/ttyUSB0
            ser.write(serial.to_bytes(arr_data2))
        elif data == 3:
            #echo -en '\x01\x06\x00\x01\x00\x03\x98\x0B' > /dev/ttyUSB0
            ser.write(serial.to_bytes(arr_data3))
        elif data == 4:
            #echo -en '\x01\x06\x00\x01\x00\x01\x19\xCA' > /dev/ttyUSB0
            ser.write(serial.to_bytes(arr_data4))
        else:
            continue
        time.sleep(0.5)

2023-09-01:换了一款红外模块,BQ-TTL-IRTM。这个直接解码出来的一长串hex code再发回给空调就好。意味着可以一个个定义:开,26度制冷4风,制热blablabla 。

GitHub - Michshelle/BQ-TTL-IRTM_Hiwonder: on Rpi4 for Speech recognition + IR transmission

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐