最近再搞PID,发现一款不错的软件
Minibalance
链接:https://pan.baidu.com/s/1I9bME3g851ylhY6bTixE0w
提取码:1234
首先将库文件拷贝到您的Arduino安装目录下的Libraries文件夹下。
然后打开arduino软件,进行编译上上传,然后用管理员运行上位机Minibalance,然后点击下面的打开串口,设置好波特率,就可以看到数据变换的波形了:
官方调试代码:
/****************************************************************************
作者:平衡小车之家
产品名称:Minibalance For Arduino
****************************************************************************/
#include <DATASCOPE.h> //这是PC端上位机的库文件
DATASCOPE data;
unsigned char Send_Count; //上位机相关变量
float a;
int show1,show2,show3,show4;
/**************************************************************************
函数功能:虚拟示波器往上位机发送数据 作者:平衡小车之家
入口参数:无
返回 值:无
**************************************************************************/
void DataScope(void)
{
int i;
data.DataScope_Get_Channel_Data(show1, 1); //显示第一个数据,角度
data.DataScope_Get_Channel_Data(show2, 2);//显示第二个数据,左轮速度 也就是每40ms输出的脉冲计数
data.DataScope_Get_Channel_Data(show3, 3);//显示第三个数据,右轮速度 也就是每40ms输出的脉冲计数
data.DataScope_Get_Channel_Data(show4, 4);//显示第四个数据,电池电压,单位V
Send_Count = data.DataScope_Data_Generate(4);
for ( i = 0 ; i < Send_Count; i++)
{
Serial.write(DataScope_OutPut_Buffer[i]);
}
delay(50); //上位机必须严格控制发送时序
}
/**************************************************************************
函数功能:初始化 相当于STM32里面的Main函数 作者:平衡小车之家
入口参数:无
返回 值:无
**************************************************************************/
void setup() {
Serial.begin(128000); //开启串口,设置波特率为 128000
}
/**************************************************************************
函数功能:主循环程序体
入口参数:无
返回 值:无
**************************************************************************/
void loop() {
a+=0.1;
if(a>3.14) a=-3.14;
show1=100*sin(a);
// show2=500* tan(a);
show3=100*cos(a);
show4=100*a;
Serial.begin(128000), DataScope(); //使用上位机时,波特率是128000
delay(50);
}
官方标志库函数解析:
#ifndef _DATASCOPE_H__
#define _DATASCOPE_H__
//导入Arduino核心头文件
#include"Arduino.h"
extern unsigned char DataScope_OutPut_Buffer[42]; //输出的数据是42字节的
class DATASCOPE //data.的类
{
public:
DATASCOPE(); //
void Float2Byte(float *target,unsigned char *buf,unsigned char beg); //两个浮点数数据,可以理解为数据处理
void DataScope_Get_Channel_Data(float Data,unsigned char Channel); //数据获取通道 入口参数分别是 数据存哪 存通道几
unsigned char DataScope_Data_Generate(unsigned char Channel_Number); //数据生成发送
};
#endif
DATASCOPE:
DATASCOPE();
没搞懂,里面啥都没写
Float2Byte:
void Float2Byte(float *target,unsigned char *buf,unsigned char beg); //数据处理
{
unsigned char *point;
point = (unsigned char*)target; //得到float的地址
buf[beg] = point[0];
buf[beg+1] = point[1];
buf[beg+2] = point[2];
buf[beg+3] = point[3];
}
/*
会在DataScope_Get_Channel_Data中调用,主要是负责处理数据的
将数据存进一个地址里面
*/
DataScope_Get_Channel_Data:
void DATASCOPE::DataScope_Get_Channel_Data(float Data,unsigned char Channel)
{
if ( (Channel > 10) || (Channel == 0) ) return; //通道个数大于10或等于0,直接跳出,不执行函数
else
{
switch (Channel)
{
case 1: Float2Byte(&Data,DataScope_OutPut_Buffer,1); break;
case 2: Float2Byte(&Data,DataScope_OutPut_Buffer,5); break;
case 3: Float2Byte(&Data,DataScope_OutPut_Buffer,9); break;
case 4: Float2Byte(&Data,DataScope_OutPut_Buffer,13); break;
case 5: Float2Byte(&Data,DataScope_OutPut_Buffer,17); break;
case 6: Float2Byte(&Data,DataScope_OutPut_Buffer,21); break;
case 7: Float2Byte(&Data,DataScope_OutPut_Buffer,25); break;
case 8: Float2Byte(&Data,DataScope_OutPut_Buffer,29); break;
case 9: Float2Byte(&Data,DataScope_OutPut_Buffer,33); break;
case 10: Float2Byte(&Data,DataScope_OutPut_Buffer,37); break;
}
}
}
/*
选择通道几,最多有10个通道
数据入口参数data,在例程中是int show1,show2,show3,show4;可以自己加
*/
void DATASCOPE::DataScope_Get_Channel_Data(float Data,unsigned char Channel)
{
if ( (Channel > 10) || (Channel == 0) ) return; //通道个数大于10或等于0,直接跳出,不执行函数
else
{
switch (Channel)
{
case 1: Float2Byte(&Data,DataScope_OutPut_Buffer,1); break;
case 2: Float2Byte(&Data,DataScope_OutPut_Buffer,5); break;
case 3: Float2Byte(&Data,DataScope_OutPut_Buffer,9); break;
case 4: Float2Byte(&Data,DataScope_OutPut_Buffer,13); break;
case 5: Float2Byte(&Data,DataScope_OutPut_Buffer,17); break;
case 6: Float2Byte(&Data,DataScope_OutPut_Buffer,21); break;
case 7: Float2Byte(&Data,DataScope_OutPut_Buffer,25); break;
case 8: Float2Byte(&Data,DataScope_OutPut_Buffer,29); break;
case 9: Float2Byte(&Data,DataScope_OutPut_Buffer,33); break;
case 10: Float2Byte(&Data,DataScope_OutPut_Buffer,37); break;
}
}
}
unsigned char DATASCOPE::DataScope_Data_Generate(unsigned char Channel_Number)
{
if ( (Channel_Number > 10) || (Channel_Number == 0) ) { return 0; } //通道个数大于10或等于0,直接跳出,不执行函数
else
{
DataScope_OutPut_Buffer[0] = '$'; //帧头
switch(Channel_Number)
{
case 1: DataScope_OutPut_Buffer[5] = 5; return 6;
case 2: DataScope_OutPut_Buffer[9] = 9; return 10;
case 3: DataScope_OutPut_Buffer[13] = 13; return 14;
case 4: DataScope_OutPut_Buffer[17] = 17; return 18;
case 5: DataScope_OutPut_Buffer[21] = 21; return 22;
case 6: DataScope_OutPut_Buffer[25] = 25; return 26;
case 7: DataScope_OutPut_Buffer[29] = 29; return 30;
case 8: DataScope_OutPut_Buffer[33] = 33; return 34;
case 9: DataScope_OutPut_Buffer[37] = 37; return 38;
case 10: DataScope_OutPut_Buffer[41] = 41; return 42;
}
}
return 0;
}
/*没看懂。。。*/
/*应该是四字节为1位,调用选择去发送数据,然后在主程序调用void DataScope(void)就可以了*/
cpp.c
#include"DATASCOPE.h"
#include"Arduino.h"
unsigned char DataScope_OutPut_Buffer[42] = {0}; //串口发送缓冲区
DATASCOPE::DATASCOPE()
{
}
void DATASCOPE::Float2Byte(float *target,unsigned char *buf,unsigned char beg)
{
unsigned char *point;
point = (unsigned char*)target; //得到float的地址
buf[beg] = point[0];
buf[beg+1] = point[1];
buf[beg+2] = point[2];
buf[beg+3] = point[3];
}
void DATASCOPE::DataScope_Get_Channel_Data(float Data,unsigned char Channel)
{
if ( (Channel > 10) || (Channel == 0) ) return; //通道个数大于10或等于0,直接跳出,不执行函数
else
{
switch (Channel)
{
case 1: Float2Byte(&Data,DataScope_OutPut_Buffer,1); break;
case 2: Float2Byte(&Data,DataScope_OutPut_Buffer,5); break;
case 3: Float2Byte(&Data,DataScope_OutPut_Buffer,9); break;
case 4: Float2Byte(&Data,DataScope_OutPut_Buffer,13); break;
case 5: Float2Byte(&Data,DataScope_OutPut_Buffer,17); break;
case 6: Float2Byte(&Data,DataScope_OutPut_Buffer,21); break;
case 7: Float2Byte(&Data,DataScope_OutPut_Buffer,25); break;
case 8: Float2Byte(&Data,DataScope_OutPut_Buffer,29); break;
case 9: Float2Byte(&Data,DataScope_OutPut_Buffer,33); break;
case 10: Float2Byte(&Data,DataScope_OutPut_Buffer,37); break;
}
}
}
unsigned char DATASCOPE::DataScope_Data_Generate(unsigned char Channel_Number)
{
if ( (Channel_Number > 10) || (Channel_Number == 0) ) { return 0; } //通道个数大于10或等于0,直接跳出,不执行函数
else
{
DataScope_OutPut_Buffer[0] = '$'; //帧头
switch(Channel_Number)
{
case 1: DataScope_OutPut_Buffer[5] = 5; return 6;
case 2: DataScope_OutPut_Buffer[9] = 9; return 10;
case 3: DataScope_OutPut_Buffer[13] = 13; return 14;
case 4: DataScope_OutPut_Buffer[17] = 17; return 18;
case 5: DataScope_OutPut_Buffer[21] = 21; return 22;
case 6: DataScope_OutPut_Buffer[25] = 25; return 26;
case 7: DataScope_OutPut_Buffer[29] = 29; return 30;
case 8: DataScope_OutPut_Buffer[33] = 33; return 34;
case 9: DataScope_OutPut_Buffer[37] = 37; return 38;
case 10: DataScope_OutPut_Buffer[41] = 41; return 42;
}
}
return 0;
}