【嵌入式设备】蓝牙鼠标遥控器

今天讲的这个产品也是刚开发的

主要就是可以遥控你的设备,进行一些自动化的操作流程,不需要再一个一个去单独进行操作,举个最简单的例子,比如你需要拨打一个电话号,你是不是需要一个一个数字去按,最终按下这个电话号的所有数字,那这个产品就是帮你简化这个步骤,按一下,他自己把剩下的数字都按下了。

当然我这个例子就是非常简单的,你可以自己设置更繁琐复杂的逻辑动作。

新开发的产品~蓝牙鼠标遥控器(多设备设定多个逻辑动作,自动化操作)

这里我就先展示一下刚举得例子,我写的一个代码

配置文件

javascript 复制代码
{
    "bluetooth_name": "xxx",
    "phone_number": "17349297033",
    "keypad_coordinates": {
      "1": [95, 478], "2": [270, 480], "3": [445, 470],
      "4": [89, 567], "5": [270, 567], "6": [446, 570],
      "7": [89, 650], "8": [270, 664], "9": [445, 670],
      "*": [89, 750], "0": [270, 764], "#": [445, 770]
    },
    "dial_button": [260, 835],
    "hangup_button": [400, 700]
  }

信号接收

python 复制代码
#ASK_433MHz_Receiver.py

from machine import Pin, Timer
import time

# 配置 GPIO 引脚用于接收 433MHz 射频信号
_ASK_MIN_BYTE_LEN_ = 3                  #   byte
_ASK_MAX_BYTE_LEN_ = 3                  #   byte
_ASK_MIN_NEW_FRAM_DETECT_TIME_ = 5000   #   us
_ASK_TOLERANCE_ = 0.9                   #   脉冲宽度容忍度

asklen =  (_ASK_MAX_BYTE_LEN_ * 16 + 1)   #完整aks数据位长度
datalen_max = (_ASK_MAX_BYTE_LEN_*8)      #射频最大数据位长度
datalen_min = (_ASK_MIN_BYTE_LEN_*8)      #射频最小数据位长度
detect_begin = False                      #是否接收到射频开始信号
detect_end = False                        #aks射频数据是否接收完成

# 定义用于存储脉冲的时间长度列表
buffer_int = []

ask_time = 0


#中断处理器
def irq_handler(pin):
    global buffer_int,ask_time,detect_begin,detect_end
    # print(f"中断触发,pin值: {pin.value()}")
    tackus = time.ticks_us()   # 当前时间戳(微秒)
    if not detect_end:
        dt = time.ticks_diff(tackus,ask_time)  # 计算脉冲间隔
        if not detect_begin:
            if dt > _ASK_MIN_NEW_FRAM_DETECT_TIME_ and pin.value():
                detect_begin = True   
                buffer_int = []     # 清空缓冲区
                # print("开始接收数据包...")
        else:
            if dt > _ASK_MIN_NEW_FRAM_DETECT_TIME_ and pin.value():
                if len(buffer_int) == asklen:
                    detect_end = True
                    # print("数据包接收完成:", buffer_int)  # 打印接收到的脉冲时间
                else:
                    detect_begin = False  # 重新开始检测
                    buffer_int = []
            else:
                buffer_int.append(dt)# 记录脉冲时间
                # print(f"脉冲时间: {dt} 微秒")  # 打印每次记录的脉冲间隔

    ask_time = tackus  # 获取当前的微秒时间

#初始化射频接收引脚
def ask_init(pin):
    rf_pin = Pin(pin, Pin.IN)  # 假设接收模块连接到 GPIO16
    rf_pin.irq(trigger=Pin.IRQ_RISING | Pin.IRQ_FALLING, handler=irq_handler)


#解码逻辑

def decodeData(buffer):
    # buffer_time = buffer[0] + buffer[1]
    buffer_time_high = [0,0]
    buffer_time_low = [0,0]
    if buffer[0] >buffer[1]:
        buffer_time_high[0] = buffer[0] - int(_ASK_TOLERANCE_ * buffer[0])
        buffer_time_high[1] = buffer[0] + int(_ASK_TOLERANCE_ * buffer[0])
        buffer_time_low[0] = buffer[1] -  int(_ASK_TOLERANCE_ * buffer[1])
        buffer_time_low[1] = buffer[1] +  int(_ASK_TOLERANCE_ * buffer[1])
    elif buffer[0] < buffer[1]:
        buffer_time_high[0] = buffer[1] - int(_ASK_TOLERANCE_ * buffer[1])
        buffer_time_high[1] = buffer[1] + int(_ASK_TOLERANCE_ * buffer[1])
        buffer_time_low[0] =  buffer[0] - int(_ASK_TOLERANCE_ * buffer[0])
        buffer_time_low[1] =  buffer[0] + int(_ASK_TOLERANCE_ * buffer[0])
    else:
        return None
    data_bit = 0 
    data_byte = [0,0,0]
    i = 0
    index = len(buffer)
    while(i < index - 1):
        if buffer[i] > buffer_time_low[0] and buffer[i] < buffer_time_low[1] and buffer[i+1] > buffer_time_high[0] and buffer[i+1] < buffer_time_high[1]: 
            data_bit += 1
        elif buffer[i+1] > buffer_time_low[0] and buffer[i+1] < buffer_time_low[1] and buffer[i] > buffer_time_high[0] and buffer[i] < buffer_time_high[1]:
            data_byte[data_bit // 8] |= 0x80 >> (data_bit % 8)# data_byte[data_bit // 8] = data_byte[data_bit // 8] | 0x80 >> (data_bit % 8)
            data_bit += 1
        else:
            break
        i +=2
    if data_bit % 8 != 0:
        return None
    if data_bit > datalen_max or data_bit < datalen_min:
        return None
    return data_byte

def reciveData():
    global detect_begin,detect_end,buffer_int
    if detect_end:
        dat = decodeData(buffer_int)
        detect_end = False
        detect_begin = False
        return dat
    return None
#初始化射频接收引脚并进入循环
#每当检测到完整数据包时,调用解码函数并输出结果

def main():
    global detect_begin,detect_end,buffer_int
    ask_init(16)
    while True:
        time.sleep_ms(1)  # 主循环继续运行
        if detect_end:
            print(len(buffer_int),buffer_int)
            dat = decodeData(buffer_int)
            if dat:
                print('data:%02x%02x%02x'%(dat[0],dat[1],dat[2]))
            detect_end = False
            detect_begin = False
            time.sleep_ms(100)

if __name__ == '__main__':
    main()

main.py

python 复制代码
import json
import time
from machine import Timer
import uartUtil
import touchTool
import ASK_433MHz_Receiver
from ASK_433MHz_Receiver import ask_init, decodeData


# 全局变量
tcount = 0
config = {}
devname = "fengmm521"  # 默认蓝牙名称
phone_number_coords = []



# 文件是否存在
def isExists(pth):
    try:
        f = open(pth, 'rb')
        f.close()
        return True
    except Exception:
        return False


# 读取 JSON 文件中的配置
def load_config():
    global config, devname, phone_number_coords
    with open("config.json", "r") as f:
        config = json.load(f)

    # 从 JSON 文件中读取蓝牙名称
    devname = config.get("bluetooth_name", "xxx")

    # 将电话号码转换为坐标列表
    phone_number = config.get("phone_number", "")
    keypad = config["keypad_coordinates"]
    phone_number_coords = [keypad[digit] for digit in phone_number]



# 从文件读取设备蓝牙名
def initDeviceName():
    global devname
    print("初始化设备...")
    load_config()
    if isExists('config.json'):
        with open('config.json', 'r') as f:
            config = json.load(f)
            devname = config.get("bluetooth_name", devname)  # 从配置文件中读取蓝牙名称
    print(f"蓝牙设备名称: {devname}")


# 点击屏幕上的某个坐标
def click(coord):
    x, y = coord
    touchTool.moveTo(x, y, True)
    time.sleep_ms(100)  # 点击延迟
    touchTool.moveTo(x, y, False)

# 遥控按键事件处理
def handle_remote_command(command):
    print(f"处理命令: {command}")  # 检查命令是否正确
    if command == 1:
        # 模拟拨号:依次点击号码的坐标
        for coord in phone_number_coords:
            print(f"点击坐标: {coord}")  # 确认每个号码对应的坐标
            click(coord)
    elif command == 2:
        # 点击拨号按钮
        print("拨号")
        click(config["dial_button"])
    elif command == 3:
        print("挂断")
        # 点击挂断按钮
        click(config["hangup_button"])

# 主函数
def main():
    print("start")
    initDeviceName()                 #设备设备名称
    print("device name:%s"%(devname))
    uartUtil.start()                 #初始化串口接收数据
    touchTool.set_screenWH(540,960)   #设置手机分辨率
    touchTool.start(devname)          
    time.sleep(1)                    #等3秒,手动配对成功,这个时间根据不同手机决定
    print("start and connect")

    ask_init(16)  # 初始化 433MHz 接收引脚
    
    print("开始监听遥控信号...")
    while True:
        time.sleep_ms(100)  # 保持主循环运行
        dat = ASK_433MHz_Receiver.reciveData()
        if dat:
            print(dat)
            if dat[2] == 120:#1
                handle_remote_command(1)
            elif dat[2] == 116:#1
                handle_remote_command(2)
            elif dat[2] == 124:#1
                handle_remote_command(3)

if __name__ == "__main__":
    main()
相关推荐
阿部多瑞 ABU4 分钟前
`chenmo` —— 可编程元叙事引擎 V2.3+
linux·人工智能·python·ai写作
acanab7 分钟前
VScode python插件
ide·vscode·python
知乎的哥廷根数学学派1 小时前
基于生成对抗U-Net混合架构的隧道衬砌缺陷地质雷达数据智能反演与成像方法(以模拟信号为例,Pytorch)
开发语言·人工智能·pytorch·python·深度学习·机器学习
WangYaolove13141 小时前
Python基于大数据的电影市场预测分析(源码+文档)
python·django·毕业设计·源码
知乎的哥廷根数学学派1 小时前
基于自适应多尺度小波核编码与注意力增强的脉冲神经网络机械故障诊断(Pytorch)
人工智能·pytorch·python·深度学习·神经网络·机器学习
修己xj2 小时前
从“死了么”到“活着记”:用Gmeek在数字世界留下思想印记
开源
cnxy1883 小时前
Python爬虫进阶:反爬虫策略与Selenium自动化完整指南
爬虫·python·selenium
鼎道开发者联盟3 小时前
2025中国AI开源生态报告发布,鼎道智联助力产业高质量发展
人工智能·开源·gui
大厂技术总监下海3 小时前
Rust的“一发逆转弹”:Dioxus 如何用一套代码横扫 Web、桌面、移动与后端?
前端·rust·开源
用户8356290780513 小时前
Python 实现 Excel 条件格式自动化
后端·python