前言
介绍一款将串口接收的数据绘制成曲线,方便观察和记录。
一、JXChart 是什么?
JXChart 是一个用于PC电脑端的UART数据接收工具,通过约定的通信协议进行数据传输,并将数据通过曲线的方式展示出来。
通过常见的数据接发(RX接收、TX发送),实现数据交互。软件界面如下图:
实际操作界面
下载地址
更多我们未能呈现的示例,还有待您在阅读文档、以及不断使用的过程,去深入挖掘。
最新app获取:
百度盘:https://pan.baidu.com/s/1xY1PU-we3AM3_545WFgZRQ?pwd=btij
腾讯微云:https://share.weiyun.com/qDfi5jLN
二、使用方法
1.硬件
需要PC电脑端支持串口功能(或USB转串口助手)
2.通信协议(内置协议)
方式1:带校验和通信-单笔数据
头码HEAD(2个字节) + 命令码CMD(1字节) + 数据长度LENGTH(1个字节) + 数据DATA(N字节) + 校验码CS(1字节)
HEAD:固定为0x4A 0x58
CMD:
0x01:无符号整型(1字节,标准C)
0x02:无符号整型(2字节,标准C)
0x03:无符号整型(4字节,标准C)
0x04:有符号整型(1字节,标准C)
0x05:有符号整型(2字节,标准C)
0x06:有符号整型(4字节,标准C)
0x07:有符号整型(2字节,高字节为符号)
0x08:有符号整型(3字节,高字节为符号)
0x09:有符号整型(5字节,高字节为符号)
0x0A:浮点型(3字节,标准C)
0x0B:浮点型(4字节,标准C)
LENGTH:即 DATA的总长度(不含CS)
DATA:数据包含了通道和对应的数值,DATA=通道[1字节]+数值VALUE[长度要根据CMD来选择]
CS等于HEAD、CMD、LENGTH、DATA单字节累计后取低8位,再取反。
例如,将一个长度为2字节的无符号整型数值“10000”,发送到通道“1”,则操作如下:
2字节的无符号整型对应的命令码CMD是0x02
send_buff[8]={0x4A,0x58,0x02,0x03,0x01,0x27,0x10,CS};
//0x4A,0x58 是头码
//0x02 是命令码
//0x03 是后面的数据长度(不含校验码)
//0x01 是通道编号
//0x27,0x10 是 10000 的 16 进制码(标准C写法)
Arduino 完整代码如下
void setup()
{
Serial.begin(9600);
}
void loop() {
//向通道 1 发送 10000 (2字节无符号整型)
char send_buff2[8]={0x4A,0x58,0x02,0x03,0x01,0x27,0x10,0x00};
//0x4A,0x58 是头码
//0x02 是命令码
//0x03 是后面的数据长度(不含校验码)
//0x01 是通道编号
//0x27,0x10 是 10000 的 16 进制码(标准C写法)
char CS2 = 0;
for(char i = 0;i< sizeof(send_buff2);i++){
CS2 += send_buff2[i];//累加
}
CS2 = ~(CS2&0xff);//累加后低8位取反
send_buff2[sizeof(send_buff2)-1]=CS2;//校验和写到数组的最后
Serial.write(send_buff2,sizeof(send_buff2));//
delay(1000);
}
其他格式命令范例如下
void setup()
{
Serial.begin(9600);
}
void loop() {
//向通道 1 发送 100 (1字节无符号整型)
char send_buff1[7]={0x4A,0x58,0x01,0x02,0x01,0x64,0x00};
//0x4A,0x58 是头码
//0x01 是命令码
//0x02 是后面的数据长度(不含校验码)
//0x01 是通道编号
//0x64 是 100 的 16 进制码(标准C写法)
char CS1 = 0;
for(char i = 0;i< sizeof(send_buff1);i++){
CS1 += send_buff1[i];//累加
}
CS1 = ~(CS1&0xff);//累加后低8位取反
send_buff1[sizeof(send_buff1)-1]=CS1;//校验和写到数组的最后
Serial.write(send_buff1,sizeof(send_buff1));//
//向通道 1 发送 10000 (2字节无符号整型)
char send_buff2[8]={0x4A,0x58,0x02,0x03,0x01,0x27,0x10,0x00};
//0x4A,0x58 是头码
//0x02 是命令码
//0x03 是后面的数据长度(不含校验码)(不含校验码)
//0x01 是通道编号
//0x27,0x10 是 10000 的 16 进制码(标准C写法)
char CS2 = 0;
for(char i = 0;i< sizeof(send_buff2);i++){
CS2 += send_buff2[i];//累加
}
CS2 = ~(CS2&0xff);//累加后低8位取反
send_buff2[sizeof(send_buff2)-1]=CS2;//校验和写到数组的最后
Serial.write(send_buff2,sizeof(send_buff2));//
//向通道 1 发送 100000 (4字节无符号整型)
char send_buff3[10]={0x4A,0x58,0x03,0x05,0x01,0x00,0x01,0x86,0xA0,0x00};
//0x4A,0x58 是头码
//0x03 是命令码
//0x05 是后面的数据长度(不含校验码)
//0x01 是通道编号
//0x00,0x01,0x86,0xA0 是 100000 的 16 进制码(标准C写法)
char CS3 = 0;
for(char i = 0;i< sizeof(send_buff3);i++){
CS3 += send_buff3[i];//累加
}
CS3 = ~(CS3&0xff);//累加后低8位取反
send_buff3[sizeof(send_buff3)-1]=CS3;//校验和写到数组的最后
Serial.write(send_buff3,sizeof(send_buff3));//
//向通道 1 发送 -100 (1字节有符号整型)
char send_buff4[7]={0x4A,0x58,0x04,0x02,0x01,0x9C,0x00};
//0x4A,0x58 是头码
//0x04 是命令码
//0x02 是后面的数据长度(不含校验码)
//0x01 是通道编号
//0x9C 是 -100 的 16 进制码(标准C写法)
char CS4 = 0;
for(char i = 0;i< sizeof(send_buff4);i++){
CS4 += send_buff4[i];//累加
}
CS4 = ~(CS4&0xff);//累加后低8位取反
send_buff4[sizeof(send_buff4)-1]=CS4;//校验和写到数组的最后
Serial.write(send_buff4,sizeof(send_buff4));//
//向通道 1 发送 -10000 (2字节有符号整型)
char send_buff5[8]={0x4A,0x58,0x05,0x03,0x01,0xD8,0xF0,0x00};
//0x4A,0x58 是头码
//0x05 是命令码
//0x03 是后面的数据长度(不含校验码)
//0x01 是通道编号
//0xD8,0xF0 是 -10000 的 16 进制码(标准C写法)
char CS5 = 0;
for(char i = 0;i< sizeof(send_buff5);i++){
CS5 += send_buff5[i];//累加
}
CS5 = ~(CS5&0xff);//累加后低8位取反
send_buff5[sizeof(send_buff5)-1]=CS5;//校验和写到数组的最后
Serial.write(send_buff5,sizeof(send_buff5));//
//向通道 1 发送 -100000 (4字节有符号整型)
char send_buff6[10]={0x4A,0x58,0x06,0x05,0x01,0xFF,0xFE,0x79,0x60,0x00};
//0x4A,0x58 是头码
//0x06 是命令码
//0x05 是后面的数据长度(不含校验码)
//0x01 是通道编号
//0xFF,0xFE,0x79,0x60 是 -100000 的 16 进制码(标准C写法)
char CS6 = 0;
for(char i = 0;i< sizeof(send_buff6);i++){
CS6 += send_buff6[i];//累加
}
CS6 = ~(CS6&0xff);//累加后低8位取反
send_buff6[sizeof(send_buff6)-1]=CS6;//校验和写到数组的最后
Serial.write(send_buff6,sizeof(send_buff6));//
//向通道 1 发送 -50 (2字节整型,高字节为符号)
char send_buff7[8]={0x4A,0x58,0x07,0x03,0x01,0xFF,0x32,0x00};
//0x4A,0x58 是头码
//0x07 是命令码
//0x03 是后面的数据长度(不含校验码)
//0x01 是通道编号
//0xFF 代表负数(0x00 代表正数)
//0x32 是 50 的 16 进制码(标准C写法)
char CS7 = 0;
for(char i = 0;i< sizeof(send_buff7);i++){
CS7 += send_buff7[i];//累加
}
CS7 = ~(CS7&0xff);//累加后低8位取反
send_buff7[sizeof(send_buff7)-1]=CS7;//校验和写到数组的最后
Serial.write(send_buff7,sizeof(send_buff7));//
//向通道 1 发送 -1000 (3字节整型,高字节为符号)
char send_buff8[9]={0x4A,0x58,0x08,0x04,0x01,0xFF,0x03,0xE8,0x00};
//0x4A,0x58 是头码
//0x08 是命令码
//0x04 是后面的数据长度(不含校验码)
//0x01 是通道编号
//0xFF 代表负数(0x00 代表正数)
//0x03,0xE8 是 1000 的 16 进制码(标准C写法)
char CS_8 = 0;
for(char i = 0;i< sizeof(send_buff8);i++){
CS_8 += send_buff8[i];//累加
}
CS_8 = ~(CS_8&0xff);//累加后低8位取反
send_buff8[sizeof(send_buff8)-1]=CS_8;//校验和写到数组的最后
Serial.write(send_buff8,sizeof(send_buff8));//
//向通道 1 发送 -100000 (5字节整型,高字节为符号)
char send_buff9[11]={0x4A,0x58,0x09,0x06,0x01,0xFF,0x00,0x01,0x86,0xA0,0x00};
//0x4A,0x58 是头码
//0x09 是命令码
//0x04 是后面的数据长度(不含校验码)
//0x01 是通道编号
//0xFF 代表负数(0x00 代表正数)
//0x00,0x01,0x86,0xA0 是 100000 的 16 进制码(标准C写法)
char CS_9 = 0;
for(char i = 0;i< sizeof(send_buff9);i++){
CS_9 += send_buff9[i];//累加
}
CS_9 = ~(CS_9&0xff);//累加后低8位取反
send_buff9[sizeof(send_buff9)-1]=CS_9;//校验和写到数组的最后
Serial.write(send_buff9,sizeof(send_buff9));//
//向通道 1 发送 -100.5 (3字节浮点型)
char send_buff10[9]={0x4A,0x58,0x0A,0x04,0x01,0xC2,0xC9,0x00,0x00};
//0x4A,0x58 是头码
//0x0A 是命令码
//0x04 是后面的数据长度(不含校验码)
//0x01 是通道编号
//0xC2,0xC9,0x00 是 -100.5 的 16 进制码(标准C写法)
char CS_10 = 0;
for(char i = 0;i< sizeof(send_buff10);i++){
CS_10 += send_buff10[i];//累加
}
CS_10 = ~(CS_10&0xff);//累加后低8位取反
send_buff10[sizeof(send_buff10)-1]=CS_10;//校验和写到数组的最后
Serial.write(send_buff10,sizeof(send_buff10));//
//向通道 1 发送 1000.5 (4字节浮点型)
char send_buff11[10]={0x4A,0x58,0x0B,0x05,0x01,0x44,0x7A,0x20,0x00,0x00};
//0x4A,0x58 是头码
//0x0B 是命令码
//0x05 是后面的数据长度(不含校验码)
//0x01 是通道编号
//0x44,0x7A,0x20,0x00 是 1000.5 的 16 进制码(标准C写法)
char CS_11 = 0;
for(char i = 0;i< sizeof(send_buff11);i++){
CS_11 += send_buff11[i];//累加
}
CS_11 = ~(CS_11&0xff);//累加后低8位取反
send_buff11[sizeof(send_buff11)-1]=CS_11;//校验和写到数组的最后
Serial.write(send_buff11,sizeof(send_buff11));//
delay(1000);
}
方式2:ASCII码传送
例如,发送到通道“CH1”,数值为“12345”,则操作如下:
依次发送 ASCII 码: {CH1,12345}
前提是需要将数值转换成 ASCII 码
例如数值 12345,对应的 16 进制是 0x30,0x39,那要如何才能转成 ASCII 码 12345 呢?
Arduino 发送方法举例
void setup()
{
Serial.begin(9600);
}
void loop() {
//向通道 CH1 发送 12345 ,发送的 ASCII 字符串格式是 {CH1,12345},对应的 16 进制如下
char start_code[]={
0x7B,//{ 头码
0x43,//C 通道名
0x48,//H 通道名
0x31,//1 通道名
0x2C,//, 逗号隔开
};
Serial.write(start_code,sizeof(start_code));//发送头码和通道名,并且用逗号隔开
int value=12345;//要发送的数值 12345
char value_buff[16]={0};
char pos=0;
while(value)
{
value_buff[pos]=value%10+0x30;//求余数。余数+0x30就可以转成ASCII码
value=value/10;
pos++;
}
//上面 value_buff 得到的是反序,即54321,需要从高往低发送,处理过程如下
for(char i=0;i<pos;i++)
{
Serial.print(value_buff[pos-i-1]);//
}
//之后发送结束码
char end_code[]={
0x7D,//} 结束码
};
Serial.write(end_code,sizeof(end_code));//发送结束码
//char buff[11]={0x7B,0x43,0x48,0x31,0x2C,0x31,0x32,0x33,0x34,0x35,0x7D};
//Serial.write(buff,11);//
//0x7B 代表 ASCII 码 {
//0x43,0x72,0x31 代表 CH1 。也可以是其他英文字母或者数字的 ASCII 码值,即 0~9、A~Z、a~z,对应的 16 进制范围是 0x30~0x39、0x41~0x5A、0x61~0x7A
//0x44 是分割符,固定为 0x44
//0x31,0x30,0x30,0x30,0x30 ASCII 代表 12345
//0x7D 代表 ASCII 码 }
delay(1000);
}
对应的ascii字符串格式是:
Serial.write("{CH1,12345}",11);//向 CH1 通道发送 12345
方式3:固定头码结束码传送
如果觉得校验码计算或者数值转ASCII码很麻烦,可以采用这种方式来发送
例如要向通道 11 发送正整数 10000
void setup()
{
Serial.begin(9600);
}
void loop() {
//向通道 11 发送正整数 10000(2字节整型)。
char buff2[11]={0xA1,0xA1,0xA1,11,0x27,0x10,0xB1,0xB1,0xB1};
//0xA1,0xA1,0xA1,0xA1 是头码
//11 是通道编号
//0x27,0x10 是 10000 的 16 进制码(标准C写法)
//0xB1,0xB1,0xB1,0xB1 是结束码
Serial.write(buff2,sizeof(buff2));
delay(1000);
}
其他格式命令范例如下
void setup()
{
Serial.begin(9600);
}
void loop() {
//---------正整数---------
//向通道 11 发送正整数 100(1字节整型)。
char buff1[8]={0xA1,0xA1,0xA1,11,0x64,0xB1,0xB1,0xB1};
//0xA1,0xA1,0xA1 是头码
//11 是通道编号
//0x64 是 100 的 16 进制码(标准C写法)
//0xB1,0xB1,0xB1 是结束码
Serial.write(buff1,sizeof(buff1));
//向通道 11 发送正整数 10000(2字节整型)。
char buff2[9]={0xA1,0xA1,0xA1,11,0x27,0x10,0xB1,0xB1,0xB1};
//0xA1,0xA1,0xA1 是头码
//11 是通道编号
//0x27,0x10 是 10000 的 16 进制码(标准C写法)
//0xB1,0xB1,0xB1 是结束码
Serial.write(buff2,sizeof(buff2));
//向通道 11 发送正整数 100000(4字节整型)。
char buff3[11]={0xA1,0xA1,0xA1,11,0x00,0x01,0x86,0xA0,0xB1,0xB1,0xB1};
//0xA1,0xA1,0xA1 是头码
//11 是通道编号
//0x00,0x01,0x86,0xA0 是 100000 的 16 进制码(标准C写法)
//0xB1,0xB1,0xB1 是结束码
Serial.write(buff3,sizeof(buff3));
//---------有符号整数---------
//向通道 11 发送 -100(1字节有符号整数)
char buff4[8]={0xA2,0xA2,0xA2,11,0x9C,0xB2,0xB2,0xB2};
//0xA2,0xA2,0xA2 是头码
//11 是通道编号
//0x9C 是 -100 的 16 进制码(标准C写法)
//0xB2,0xB2,0xB2 是结束码
Serial.write(buff4,sizeof(buff4));
//向通道 11 发送 -10000(2字节有符号整数)
char buff5[9]={0xA2,0xA2,0xA2,11,0xD8,0xF0,0xB2,0xB2,0xB2};
//0xA2,0xA2,0xA2 是头码
//11 是通道编号
//0xD8,0xF0 是 -10000 的 16 进制码(标准C写法)
//0xB2,0xB2,0xB2 是结束码
Serial.write(buff5,sizeof(buff5));
//向通道 11 发送 -100000(4字节有符号整数)
char buff6[11]={0xA2,0xA2,0xA2,11,0xFF,0xFE,0x79,0x60,0xB2,0xB2,0xB2};
//0xA2,0xA2,0xA2 是头码
//11 是通道编号
//0xFF,0xFE,0x79,0x60 是 -100000 的 16 进制码(标准C写法)
//0xB2,0xB2,0xB2 是结束码
Serial.write(buff6,sizeof(buff6));
//---------浮点型---------
//向通道 11 发送 1000.5 (4字节浮点型)
char buff7[11]={0xA3,0xA3,0xA3,11,0x44,0x7A,0x20,0x00,0xB3,0xB3,0xB3};
//0xA3,0xA3,0xA3 是头码
//11 是通道编号
//0x44,0x7A,0x20,0x00 是 1000.5 的 16 进制码(标准C写法)
//0xB3,0xB3,0xB3 是结束码
Serial.write(buff7,sizeof(buff7));
//向通道 11 发送 -1000.5 (4字节浮点型)
char buff8[11]={0xA3,0xA3,0xA3,11,0xC4,0x7A,0x20,0x00,0xB3,0xB3,0xB3};
//0xA3,0xA3,0xA3 是头码
//11 是通道编号
//0xC4,0x7A,0x20,0x00 是 -1000.5 的 16 进制码(标准C写法)
//0xB3,0xB3,0xB3 是结束码
Serial.write(buff8,sizeof(buff8));
//向通道 11 发送带符号整数 100.5 (3字节浮点型)
char buff9[10]={0xA3,0xA3,0xA3,11,0x42,0xC9,0x00,0xB3,0xB3,0xB3};
//0xA3,0xA3,0xA3 是头码
//11 是通道编号
//0x42,0xC9,0x00 是 100.5 的 16 进制码(标准C写法)
//0xB3,0xB3,0xB3 是结束码
Serial.write(buff9,sizeof(buff9));
//向通道 11 发送带符号整数 -100.5 (3字节浮点型)
char buff10[10]={0xA3,0xA3,0xA3,11,0xC2,0xC9,0x00,0xB3,0xB3,0xB3};
//0xA3,0xA3,0xA3 是头码
//11 是通道编号
//0xC2,0xC9,0x00 是 -100.5 的 16 进制码(标准C写法)
//0xB3,0xB3,0xB3 是结束码
Serial.write(buff10,sizeof(buff10));
delay(1000);
}
3.下载地址
更多我们未能呈现的示例,还有待您在阅读文档、以及不断使用的过程,去深入挖掘。
最新app获取:
百度盘:https://pan.baidu.com/s/1xY1PU-we3AM3_545WFgZRQ?pwd=btij
腾讯微云:https://share.weiyun.com/qDfi5jLN
总结
曲线显示,更直观、更高效。