Python测试 - 读取蓝牙光电头电池电压

Python 测试 - 读取蓝牙光电头电池电压

1.环境准备

pip install pyserial

2.运行和使用说明

  • 运行程序 (默认COM3和9600):
python opbt_battery_voltage.py
  • 运行程序(可选择指定COM口和波特率):
python opbt_battery_voltage.py --port COM4 --baud 57600

– 程序将可能返回以下内容

Using COM port: COM25, Baud rate: 9600
Entering command mode...
Response: {"OK":true}
Querying battery voltage...
Response: {"BatteryVoltage":4020}

Battery voltage: 4020 mV (4.02 V)
Exiting command mode...
Response: {"OK":false}

3.程序说明

程序功能:

  • 通过串口连接OP-BT设备
  • 发送命令进入命令模式
  • 查询电池电压
  • 解析并显示电池电压
  • 退出命令模式
  • 关闭串口连接

关键步骤:

  • 使用串口通讯库操作串口
  • 发送JSON格式命令: {“AtCommandMode”:true} 进入命令模式
  • 发送{“BatteryVoltage”:"?"} 查询设备信息
  • 解析返回的JSON数据获取电池电压
  • 发送 {“AtCommandMode”:false} 退出命令模式

注意事项:

  • 需要根据实际情况修改串口号和波特率
  • 程序中有500ms的等待时间,可能需要根据设备响应速度调整
  • 解析JSON使用了简单的字符串查找方法,在实际应用中可能需要使用更健壮的JSON解析库 这个程序提供了一个基本框架,你可以根据需要扩展它来查询其他参数或执行其他命令。

4. 示例代码

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# opbt_battery_voltage.py

import serial
import time
import json
import re
import sys
import argparse

DEFAULT_COM = "COM3"  # Default COM port, can be modified as needed
DEFAULT_BAUDRATE = 9600  # Default baud rate, can be modified as needed
BUFFER_SIZE = 1024

def send_command(ser, command):
    """Send command and receive response"""
    # Clear buffers
    ser.reset_input_buffer()
    ser.reset_output_buffer()
    
    # Send command
    ser.write(command.encode())
    
    # Wait for device response
    time.sleep(0.5)  # Wait 500ms, can be adjusted based on device response time
    
    # Read response
    response = ser.read(BUFFER_SIZE).decode('utf-8', errors='ignore')
    return response

def parse_battery_voltage(json_response):
    """Parse battery voltage from JSON response"""
    try:
        # Try to parse as JSON
        data = json.loads(json_response)
        if "BatteryVoltage" in data:
            return data["BatteryVoltage"]
    except json.JSONDecodeError:
        # If not valid JSON, try regex
        match = re.search(r'"BatteryVoltage"\s*:\s*(\d+)', json_response)
        if match:
            return int(match.group(1))
    
    return -1  # Battery voltage not found

def main():
    # Parse command line arguments
    parser = argparse.ArgumentParser(description='Query OPBT device battery voltage')
    parser.add_argument('--port', default=DEFAULT_COM, help='COM port (default: COM3)')
    parser.add_argument('--baud', type=int, default=DEFAULT_BAUDRATE, help='Baud rate (default: 9600)')
    args = parser.parse_args()
    
    com_port = args.port
    baud_rate = args.baud
    
    print(f"Using COM port: {com_port}, Baud rate: {baud_rate}")
    
    try:
        # Open serial port
        ser = serial.Serial(
            port=com_port,
            baudrate=baud_rate,
            bytesize=serial.EIGHTBITS,
            parity=serial.PARITY_NONE,
            stopbits=serial.STOPBITS_ONE,
            timeout=1
        )
        
        # 1. Enter command mode
        print("Entering command mode...")
        response = send_command(ser, "{\"AtCommandMode\":true}\r\n")
        print(f"Response: {response}")
        
        if "\"OK\":true" not in response:
            print("Failed to enter command mode")
            ser.close()
            return 1
        
        # 2. Query battery voltage directly
        print("Querying battery voltage...")
        response = send_command(ser, "{\"BatteryVoltage\":\"?\"}\r\n")
        print(f"Response: {response}")
        
        # Parse battery voltage
        battery_voltage = parse_battery_voltage(response)
        if battery_voltage > 0:
            print(f"\nBattery voltage: {battery_voltage} mV ({battery_voltage/1000:.2f} V)")
        else:
            print("Unable to parse battery voltage")
        
        # 3. Exit command mode
        print("Exiting command mode...")
        response = send_command(ser, "{\"AtCommandMode\":false}\r\n")
        print(f"Response: {response}")
        
        # Close serial port
        ser.close()
        
    except serial.SerialException as e:
        print(f"Serial port error: {e}")
        return 1
    
    return 0

if __name__ == "__main__":
    sys.exit(main())