电表采集与解析的C语言代码
时间: 2024-02-26 16:58:46 浏览: 92
以下是一个简单的电表采集与解析的C语言代码示例:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <windows.h>
#define BUFFER_SIZE 1024
int main()
{
// 初始化串口通信和数据存储变量
HANDLE hSerial = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hSerial == INVALID_HANDLE_VALUE)
{
printf("Failed to open serial port!\n");
return 0;
}
DCB dcbSerialParams = { 0 };
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
if (!GetCommState(hSerial, &dcbSerialParams))
{
printf("Failed to get serial port parameters!\n");
return 0;
}
dcbSerialParams.BaudRate = CBR_9600;
dcbSerialParams.ByteSize = 8;
dcbSerialParams.StopBits = ONESTOPBIT;
dcbSerialParams.Parity = NOPARITY;
if (!SetCommState(hSerial, &dcbSerialParams))
{
printf("Failed to set serial port parameters!\n");
return 0;
}
COMMTIMEOUTS timeouts = { 0 };
timeouts.ReadIntervalTimeout = 50;
timeouts.ReadTotalTimeoutConstant = 50;
timeouts.ReadTotalTimeoutMultiplier = 10;
timeouts.WriteTotalTimeoutConstant = 50;
timeouts.WriteTotalTimeoutMultiplier = 10;
if (!SetCommTimeouts(hSerial, &timeouts))
{
printf("Failed to set serial port timeouts!\n");
return 0;
}
time_t t;
struct tm now;
char filename[64];
char buffer[BUFFER_SIZE];
// 设定采集时间间隔,开始循环采集
while (1)
{
t = time(NULL);
localtime_s(&now, &t);
sprintf_s(filename, "meter_%04d%02d%02d_%02d%02d%02d.csv", now.tm_year + 1900, now.tm_mon + 1, now.tm_mday, now.tm_hour, now.tm_min, now.tm_sec);
FILE* fp;
if (fopen_s(&fp, filename, "a") != 0)
{
printf("Failed to open file %s!\n", filename);
return 0;
}
// 发送读取电表数据的指令
DWORD bytesWritten;
if (!WriteFile(hSerial, "RD\r\n", 5, &bytesWritten, NULL))
{
printf("Failed to write to serial port!\n");
fclose(fp);
continue;
}
// 等待串口接收数据完成
DWORD bytesRead;
if (!ReadFile(hSerial, buffer, BUFFER_SIZE, &bytesRead, NULL))
{
printf("Failed to read from serial port!\n");
fclose(fp);
continue;
}
// 解析数据,提取电表读数
char* p = strstr(buffer, "kWh");
if (p != NULL)
{
p -= 9;
*p = '\0';
float meterValue = atof(p - 7);
fprintf(fp, "%04d-%02d-%02d %02d:%02d:%02d,%.2f\n", now.tm_year + 1900, now.tm_mon + 1, now.tm_mday, now.tm_hour, now.tm_min, now.tm_sec, meterValue);
}
fclose(fp);
// 等待下一次采集时间点
Sleep(5000);
}
// 关闭串口通信
CloseHandle(hSerial);
return 0;
}
```
以上代码仅供参考,实际情况可能需要根据具体电表和串口通信方式进行修改。
阅读全文