MinGW C 测试 - 读取蓝牙光电头电池电压
1.环境准备
2.编译和使用说明
- 使用Visual Studio或MinGW编译此程序:
gcc -o opbt_battery.exe opbt_battery_voltage.c
- 运行程序(可选择指定COM口和波特率):
opbt_battery.exe COM3 9600
- 运行结果
Using COM port: com3, Baud rate: 9600
Entering command mode… Response: {“OK”:true} Querying battery voltage… Response: {“BatteryVoltage”:4011}
Battery voltage: 4011 mV (4.01 V) Exiting command mode… Response: {“OK”:false}
## 3.程序说明
**程序功能:**
- 通过串口连接OP-BT设备
- 发送命令进入命令模式
- 查询设备配置信息(包含电池电压)
- 解析并显示电池电压
- 退出命令模式
**关键步骤:**
- 使用Windows API (CreateFile, WriteFile, ReadFile等)操作串口
- 发送JSON格式命令: {"AtCommandMode":true} 进入命令模式
- 发送 {"BatteryVoltage":"?"} 查询设备信息
- 解析返回的JSON数据获取电池电压
- 发送 {"AtCommandMode":false} 退出命令模式
**注意事项:**
- 需要根据实际情况修改串口号和波特率
- 程序中有500ms的等待时间,可能需要根据设备响应速度调整
- 解析JSON使用了简单的字符串查找方法,在实际应用中可能需要使用更健壮的JSON解析库
这个程序提供了一个基本框架,你可以根据需要扩展它来查询其他参数或执行其他命令。
## 4. 示例代码
```c
// opbt_battery_voltage.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#define BUFFER_SIZE 1024
#define DEFAULT_COM "COM3" // Default COM port, can be modified as needed
#define DEFAULT_BAUDRATE 9600 // Default baud rate, can be modified as needed
// Send command and receive response
int sendCommand(HANDLE hSerial, const char* command, char* response, int responseSize) {
DWORD bytesWritten = 0;
DWORD bytesRead = 0;
BOOL status;
// Clear receive buffer
PurgeComm(hSerial, PURGE_RXCLEAR | PURGE_TXCLEAR);
// Send command
status = WriteFile(hSerial, command, strlen(command), &bytesWritten, NULL);
if (!status || bytesWritten != strlen(command)) {
printf("Failed to send command\n");
return -1;
}
// Wait for device response
Sleep(500); // Wait 500ms, can be adjusted based on device response time
// Read response
memset(response, 0, responseSize);
status = ReadFile(hSerial, response, responseSize - 1, &bytesRead, NULL);
if (!status) {
printf("Failed to read response\n");
return -1;
}
response[bytesRead] = '\0'; // Ensure string is null-terminated
return bytesRead;
}
// Parse battery voltage from JSON response
int parseBatteryVoltage(const char* jsonResponse) {
char* batteryStr = strstr(jsonResponse, "\"BatteryVoltage\":");
if (batteryStr == NULL) {
return -1; // Battery voltage field not found
}
// Move pointer to value position
batteryStr += strlen("\"BatteryVoltage\":");
// Skip spaces
while (*batteryStr == ' ') {
batteryStr++;
}
// Parse value
return atoi(batteryStr);
}
int main(int argc, char* argv[]) {
HANDLE hSerial;
DCB dcbSerialParams = {0};
COMMTIMEOUTS timeouts = {0};
char response[BUFFER_SIZE];
char comPort[20] = DEFAULT_COM;
int baudRate = DEFAULT_BAUDRATE;
// Process command line arguments
if (argc >= 2) {
strcpy(comPort, argv[1]);
}
if (argc >= 3) {
baudRate = atoi(argv[2]);
}
printf("Using COM port: %s, Baud rate: %d\n", comPort, baudRate);
// Open serial port
hSerial = CreateFile(comPort,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hSerial == INVALID_HANDLE_VALUE) {
printf("Failed to open COM port %s, error code: %d\n", comPort, GetLastError());
return 1;
}
// Configure serial port parameters
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
if (!GetCommState(hSerial, &dcbSerialParams)) {
printf("Failed to get COM port status\n");
CloseHandle(hSerial);
return 1;
}
dcbSerialParams.BaudRate = baudRate;
dcbSerialParams.ByteSize = 8;
dcbSerialParams.StopBits = ONESTOPBIT;
dcbSerialParams.Parity = NOPARITY;
if (!SetCommState(hSerial, &dcbSerialParams)) {
printf("Failed to set COM port parameters\n");
CloseHandle(hSerial);
return 1;
}
// Set timeouts
timeouts.ReadIntervalTimeout = 50;
timeouts.ReadTotalTimeoutConstant = 1000;
timeouts.ReadTotalTimeoutMultiplier = 10;
timeouts.WriteTotalTimeoutConstant = 1000;
timeouts.WriteTotalTimeoutMultiplier = 10;
if (!SetCommTimeouts(hSerial, &timeouts)) {
printf("Failed to set COM port timeouts\n");
CloseHandle(hSerial);
return 1;
}
// 1. Enter command mode
printf("Entering command mode...\n");
if (sendCommand(hSerial, "{\"AtCommandMode\":true}\r\n", response, BUFFER_SIZE) > 0) {
printf("Response: %s\n", response);
if (strstr(response, "{\"OK\":true}") == NULL) {
printf("Failed to enter command mode\n");
CloseHandle(hSerial);
return 1;
}
} else {
printf("Failed to send command\n");
CloseHandle(hSerial);
return 1;
}
// 2. Query battery voltage directly
printf("Querying battery voltage...\n");
if (sendCommand(hSerial, "{\"BatteryVoltage\":\"?\"}\r\n", response, BUFFER_SIZE) > 0) {
printf("Response: %s\n", response);
// Parse battery voltage
int batteryVoltage = parseBatteryVoltage(response);
if (batteryVoltage > 0) {
printf("\nBattery voltage: %d mV (%.2f V)\n", batteryVoltage, batteryVoltage / 1000.0);
} else {
printf("Unable to parse battery voltage\n");
}
} else {
printf("Failed to send command\n");
}
// 3. Exit command mode
printf("Exiting command mode...\n");
if (sendCommand(hSerial, "{\"AtCommandMode\":false}\r\n", response, BUFFER_SIZE) > 0) {
printf("Response: %s\n", response);
}
// Close serial port
CloseHandle(hSerial);
return 0;
}