// 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;
}