解析串口数据并保存至txt中

在本次学习中可以知道:
串口文件的定义以及调用;
串口接收后对数据的判断与保存。

继前文可知接收串口的写法,然后就可以定义相关变量并对接收的数据作处理了。
在此,可以利用while语句不断接收函数,并且判断接收过来的数据内容,然后保存我想要的一部分数据到txt文件中。

代码

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <tchar.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include <math.h>

#define head_str0 "[INFO] frame:"
char head_str[14] = head_str0;

HANDLE hCom1;//串口句柄

typedef struct//这里是我串口要接收的数据的变量
{
	unsigned char id;
	bool used;
	float range;
	float velocity;
	float azimuth;
	float elevation;
	float x;
	float y;
	float z;
	float SNR;
	float timestamp;
} Target_t;

Target_t TargetList[100];
int main(void)
{
	unsigned int wCount;
	unsigned int rCount;
	hCom1 = CreateFile(_T("COM4"),//COM4口
		GENERIC_READ | GENERIC_WRITE,//允许读和写
		0,//独占方式
		NULL,
		OPEN_EXISTING,//打开而不是创建
		0,//同步方式
		NULL);

	FILE* fp1;
	
	if (hCom1 == (HANDLE)-1)
	{
		printf("打开COM失败!\n");
		return FALSE;
	}
	else
	{
		printf("COM打开成功!\n");
	}
	DCB dcb1;//一个串口结构体
	GetCommState(hCom1, &dcb1);
	dcb1.BaudRate = 921600;//波特率
	dcb1.ByteSize = 8;//每个字节有8位
	dcb1.Parity = NOPARITY;//无奇偶校验位
	dcb1.StopBits = TWOSTOPBITS;//两个停止位
	//dcb1.fParity = FALSE;
	//dcb1.fNull = FALSE;
	SetCommState(hCom1, &dcb1);

	COMMTIMEOUTS TimeOuts;
	//设定读超时,最长的等待时间
	TimeOuts.ReadIntervalTimeout = 2000;//1000
	TimeOuts.ReadTotalTimeoutMultiplier = 1000;//500
	TimeOuts.ReadTotalTimeoutConstant = 10000;//5000
	//设定写超时
	TimeOuts.WriteTotalTimeoutMultiplier = 1000;//500
	TimeOuts.WriteTotalTimeoutConstant = 4000;//2000
	SetCommTimeouts(hCom1, &TimeOuts);//设置超时
	SetupComm(hCom1, 20480, 20480);//输入缓冲区和输出缓冲区的大小都是1024
	PurgeComm(hCom1, PURGE_TXCLEAR | PURGE_RXCLEAR);//清空缓冲区
	wCount = 1;
	uint8_t rx=0;
	uint8_t flag = 0;
	uint8_t frame_start_flag = 0;
	uint8_t frame_end_flag = 0;
	unsigned char str[1024];
	memset(str, 0, 100);
	int i = 0;
	int j = 0;
	int k = 0;
	uint32_t frame;
	int k_buf[100];
	uint8_t numObjOut = 0;
	char txt_buf[20];
	while (1)//不断读取数据
	{
		if (!ReadFile(hCom1, &rx, wCount, &rCount, NULL))//类似于读文件,句柄,读取后存放的地址,要读取的字节数,实际读取的字节数
		{
			printf("读串口失败!");
			return FALSE;
		}
		if (rCount==1 && flag > 0)
		{
			str[i] = rx;
			i++;
		}
		//printf("flag:%d\n", flag);
		switch (flag)
		{
			case 0:
			{
				if (rCount == 1)
				{
					if (rx == '[')
					{
						flag++;
						str[i] = rx;
						i++;
					}
				}
			}break;
			case 1:
			{
				if (i >= 13)
				{
					if (memcmp(str, head_str, 13)==0)
					{
						flag++;						
					}
					else
					{
						flag = 0;
						i = 0;
						memset(str, 0, 1024);
					}
				}
			}break;
			case 2:
			{
				if (rx == '[')
				{
					sscanf((char*)&str[0], "[INFO] frame:%u", &frame);
					printf("frame: %d\n", frame);
					flag++;
				}
			}break;
			case 3:
			{

				sprintf(txt_buf,"./dir/%u.txt", frame);
				fp1 = fopen(txt_buf, "a+");//新建一个文本,将数据保存在其中
				for (j = 0; j < i; j++)
				{
					if (str[j] == 'd')
					{
						sscanf((char *)& str[j + 1], ":%u", &k_buf[k]);
						//j = j + 4;
						//if (str[j] == 'x')
						//{
						//	sscanf((char*)&str[j + 1], ":%f", &TargetList[k_buf[k]].x);
						//	printf("text: % 0.2f", TargetList[k_buf[k]].x);
						//}
						//j = j - 4;
						sscanf((char*)&str[j + 1], ":%u x:%f y:%f z:%f v:%f snr:%f time:%f",
													&TargetList[k_buf[k]].id, &TargetList[k_buf[k]].x, 
													&TargetList[k_buf[k]].y, &TargetList[k_buf[k]].z, 
													&TargetList[k_buf[k]].velocity, &TargetList[k_buf[k]].SNR, 
													&TargetList[k_buf[k]].timestamp);
						printf( "id:%u x:%0.2f y:%0.2f z:%0.2f v:%0.2f snr:%0.2f time:%0.2f\n", TargetList[k_buf[k]].id, TargetList[k_buf[k]].x,
							TargetList[k_buf[k]].y, TargetList[k_buf[k]].z,
							TargetList[k_buf[k]].velocity, TargetList[k_buf[k]].SNR,
							TargetList[k_buf[k]].timestamp);
						//TargetList[k_buf[k]].range = sqrt(pow(TargetList[k_buf[k]].x, 2) + pow(TargetList[k_buf[k]].y, 2) + pow(TargetList[k_buf[k]].z, 2));
						TargetList[k_buf[k]].range = sqrt((TargetList[k_buf[k]].x * TargetList[k_buf[k]].x) + 
														  (TargetList[k_buf[k]].y * TargetList[k_buf[k]].y) + 
														  (TargetList[k_buf[k]].z * TargetList[k_buf[k]].z));
						TargetList[k_buf[k]].azimuth = atan2(TargetList[k_buf[k]].x, TargetList[k_buf[k]].y);
						TargetList[k_buf[k]].elevation = asin(TargetList[k_buf[k]].z/TargetList[k_buf[k]].range);
						fprintf(fp1, "%f %f %f %f %f %f\n", TargetList[k_buf[k]].range,TargetList[k_buf[k]].velocity,
															TargetList[k_buf[k]].azimuth, TargetList[k_buf[k]].elevation,
															TargetList[k_buf[k]].SNR,TargetList[k_buf[k]].timestamp);
						
						k++;
					}
				}
				printf("k:%d\n",k);
				flag = 0;
				i = 0;
				memset(str, 0, 1024);
				k = 0;
				fclose(fp1);
			}break;
			default:
			{
			}break;
		}
	}
	//fprintf(fp1, "%02X ", str[j]);
	
	CloseHandle(hCom1);
}

参考文档

如何读取一个串口
createFileA 函数 (fileapi.h)
sscanf 函数的返回值是一个整数,表示成功解析并匹配的参数个数。
仰角和方位角(Elevation and Azimuth)

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Arduino串口数据可以通过多种方法保存。一种方法是使用pyserial模块来读取串口数据保存到本地。这个方法在之前的毕设笔记05有详细的介绍,其使用了pyserial模块来封装对串口的访问。通过这种方式,你可以将Arduino连接到树莓派,并保存所采集的温湿度数据。\[1\] 另一种方法是利用Excel自带的Data Streamer功能来读取串口数据保存。你可以启用Data Streamer加载项,并刷写代码将微控制器连接到电脑。然后,你可以使用Excel画图记录数据。这种方法在引用\[2\]有详细的介绍。 还有一种方法是使用插件ArduSpreadsheet来读取串口数据保存。你可以安装ArduSpreadsheet插件,并在Arduino代码使用相应的代码。这种方法在引用\[2\]也有详细的介绍。 需要注意的是,在使用ArduSpreadsheet插件时,你需要解压缩zip文件并将"ArduSpreadsheet"文件夹复制到Arduino的"工具"文件夹旁边。如果"工具"文件夹不存在,你可以自己创建它。\[3\] 综上所述,你可以根据自己的需求选择合适的方法来保存Arduino串口数据。 #### 引用[.reference_title] - *1* [毕设笔记06-使用Python读取Arduino+树莓派串口温湿度数据保存](https://blog.csdn.net/qq_41575882/article/details/103766908)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [【Arduino串口数据保存到excel常用三种方法】](https://blog.csdn.net/vor234/article/details/128445847)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值