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

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

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

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

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

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

配置文件

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()
相关推荐
笨鸟先飞,勤能补拙4 小时前
AI 赋能网络安全:技术全景、成熟度评估与实战案例
人工智能·python·安全·web安全·网络安全·sqlite·github
长和信泰光伏储能4 小时前
京津冀光伏发电:绿色能源的未来之路
python·能源
浦信仿真大讲堂5 小时前
从重复操作到自动化闭环:如何让 CST 与 Python 真正协同起来
python·自动化·cst·仿真软件·达索软件
Gu Gu Study5 小时前
ScoutLoop开放域深度研究引擎(agent的初步设计想法)
人工智能·python
卷无止境6 小时前
写代码这件事,到底该讲究点什么?
后端·python
卷无止境6 小时前
循环复杂度到底在算什么,Python 代码怎么才能写得让人一看就懂
后端·python
lpfasd1236 小时前
MediaCrawler 项目深度分析
chrome·python·chrome devtools
Dxy12393102167 小时前
Python项目打包成EXE完整教程(PyInstaller实战避坑)
开发语言·python
冬奇Lab7 小时前
开源项目第172期:agentOS — 以库的形式给 AI Agent 一个操作系统,冷启动 92x 更快、内存 47x 更少
人工智能·开源·agent
bamb007 小时前
一个项目带你入门AI应用开发01
python