匿名四轴作为一个玩四轴的人必备入门级工具,匿名地面站简直好用的一批,这里有匿名科创对他们的地面站的介绍和下载方法,匿名视频。可谓功能相当强大,使用起来及其方便,大家如果想获得资源可以直接从网上寻找下载,本文主要对匿名地面站4.50版本进行协议解析,让大家理解相关的通讯协议,便于使用先进的资源进行小四轴的调试使用。

地面站相关协议解析

所谓的通讯协议,说白了就是一个暗号,你要和地面站进行通讯,就要按照地面站制定的规则进行通讯,首先要先向地面站汇报统一暗号(0xaaa)然后是你来的任务(编码位)有多少东西(数据位长度),你带来的东西(想要传输的数据),最终确认(校验值)。大家只需要按照这个已经约定好的暗号和地面站通讯,他就能理解我们带来了什么,同样地面站也会以另一种格式传输给我们相关的指令但是基本类似,只需要按照约定好的内容对传来的指令进行解析就能得到相应的数据。

数据传输指令

/
//Data_Exchange函数处理各种数据发送请求,比如想实现每5ms发送一次传感器数据至上位机,即在此函数内实现
void ANO_DT_Data_Exchange(void)
{static u8 cnt = 0;static u8 senser_cnt    = 10;static u8 status_cnt    = 15;static u8 rcdata_cnt    = 20;static u8 motopwm_cnt   = 20;static u8 power_cnt     =   50;if((cnt % senser_cnt) == (senser_cnt-1))f.send_senser = 1;  if((cnt % status_cnt) == (status_cnt-1))f.send_status = 1;  if((cnt % rcdata_cnt) == (rcdata_cnt-1))f.send_rcdata = 1;  if((cnt % motopwm_cnt) == (motopwm_cnt-1))f.send_motopwm = 1; if((cnt % power_cnt) == (power_cnt-1))f.send_power = 1;       cnt++;
/if(f.send_version){f.send_version = 0;ANO_DT_Send_Version(4,300,100,400,0);}
/else if(f.send_status){f.send_status = 0;ANO_DT_Send_Status(Roll,Pitch,Yaw,baroAlt,0,fly_ready);}
/else if(f.send_senser){f.send_senser = 0;ANO_DT_Send_Senser(mpu6050.Acc.x,mpu6050.Acc.y,mpu6050.Acc.z, mpu6050.Gyro.x,mpu6050.Gyro.y,mpu6050.Gyro.z,ak8975.Mag_Adc.x,ak8975.Mag_Adc.y,ak8975.Mag_Adc.z,0);}
/else if(f.send_rcdata){f.send_rcdata = 0;ANO_DT_Send_RCData(Rc_Pwm_In[0],Rc_Pwm_In[1],Rc_Pwm_In[2],Rc_Pwm_In[3],Rc_Pwm_In[4],Rc_Pwm_In[5],Rc_Pwm_In[6],Rc_Pwm_In[7],0,0);}
/   else if(f.send_motopwm){f.send_motopwm = 0;ANO_DT_Send_MotoPWM(1,2,3,4,5,6,7,8);}
/else if(f.send_power){f.send_power = 0;ANO_DT_Send_Power(123,456);}
/else if(f.send_pid1){f.send_pid1 = 0;ANO_DT_Send_PID(1,ctrl_1.PID[PIDROLL].kp,ctrl_1.PID[PIDROLL].ki,ctrl_1.PID[PIDROLL].kd,ctrl_1.PID[PIDPITCH].kp,ctrl_1.PID[PIDPITCH].ki,ctrl_1.PID[PIDPITCH].kd,ctrl_1.PID[PIDYAW].kp,ctrl_1.PID[PIDYAW].ki,ctrl_1.PID[PIDYAW].kd);}
/else if(f.send_pid2){f.send_pid2 = 0;ANO_DT_Send_PID(2,ctrl_1.PID[PID4].kp,ctrl_1.PID[PID4].ki,ctrl_1.PID[PID4].kd,ctrl_1.PID[PID5].kp,ctrl_1.PID[PID5].ki,ctrl_1.PID[PID5].kd, ctrl_1.PID[PID6].kp,ctrl_1.PID[PID6].ki,ctrl_1.PID[PID6].kd);}
/else if(f.send_pid3){f.send_pid3 = 0;ANO_DT_Send_PID(3,ctrl_2.PID[PIDROLL].kp,ctrl_2.PID[PIDROLL].ki,ctrl_2.PID[PIDROLL].kd,ctrl_2.PID[PIDPITCH].kp,ctrl_2.PID[PIDPITCH].ki,ctrl_2.PID[PIDPITCH].kd,ctrl_2.PID[PIDYAW].kp,ctrl_2.PID[PIDYAW].ki,ctrl_2.PID[PIDYAW].kd);}
/
}

这个函数执行的功能其实就是判断一下我多久该发一次数据,有些数据比较重要(比如姿态信息)需要经常传输一下,有些相对而言更新慢一点没有太大问题(比如电压),而有一些只需要等待接收到发送指令以后再发送就OK(比如PID信息),然后得到相应的命令以后将数据按照约定的格式传输给上位机。

数据传输
void ANO_DT_Send_Power(u16 votage, u16 current)
{u8 _cnt=0;u16 temp;data_to_send[_cnt++]=0xAA;data_to_send[_cnt++]=0xAA;data_to_send[_cnt++]=0x05;data_to_send[_cnt++]=0;temp = votage;data_to_send[_cnt++]=BYTE1(temp);data_to_send[_cnt++]=BYTE0(temp);temp = current;data_to_send[_cnt++]=BYTE1(temp);data_to_send[_cnt++]=BYTE0(temp);data_to_send[3] = _cnt-4;u8 sum = 0;for(u8 i=0;i<_cnt;i++)sum += data_to_send[i];data_to_send[_cnt++]=sum;ANO_DT_Send_Data(data_to_send, _cnt);
}

这个是传输电压和电源的传输协议,协议内容也是按照前面已经规定的格式进行传输的,发送帧头,功能码,数据内容,校验值等相关的内容。函数任务就是将这些信息都整合到一个数组里面,然后将相关的内容通过使用的数据传输方式进行数据传输。传输其他的内容乃至高级数据都是通过类似的方式完成的。在此不多做介绍。

传输方式定义并传输
void ANO_DT_Send_Data(u8 *dataToSend , u8 length)
{
#ifdef ANO_DT_USE_USB_HIDUsb_Hid_Adddata(data_to_send,length);
#endif
#ifdef ANO_DT_USE_USART2Usart2_Send(data_to_send, length);
#endif
}

这个其实就是一个传输函数,前面两个函数已经确定了数据格式,这里只需要根据相关的东西进行数据传输,传输格式可以根据自己方便进行选择,比如USB,或者串口模块等等。

接收数据解析
void ANO_DT_Data_Receive_Prepare(u8 data)
{static u8 RxBuffer[50];static u8 _data_len = 0,_data_cnt = 0;static u8 state = 0;if(state==0&&data==0xAA){state=1;RxBuffer[0]=data;}else if(state==1&&data==0xAF){state=2;RxBuffer[1]=data;}else if(state==2&&data<0XF1){state=3;RxBuffer[2]=data;}else if(state==3&&data<50){state = 4;RxBuffer[3]=data;_data_len = data;_data_cnt = 0;}else if(state==4&&_data_len>0){_data_len--;RxBuffer[4+_data_cnt++]=data;if(_data_len==0)state = 5;}else if(state==5){state = 0;RxBuffer[4+_data_cnt]=data;ANO_DT_Data_Receive_Anl(RxBuffer,_data_cnt+5);}elsestate = 0;
}

首先将接收到的数据进行解析,解析主要是一位一位进行解析,层层递进,将解析得到的数据传过来,和相应的协议进行对比,如果正确就将数据传输到下一个模块

数据赋值
void ANO_DT_Data_Receive_Anl(u8 *data_buf,u8 num)
{u8 sum = 0;for(u8 i=0;i<(num-1);i++)sum += *(data_buf+i);if(!(sum==*(data_buf+num-1)))       return;     //判断sumif(!(*(data_buf)==0xAA && *(data_buf+1)==0xAF))     return;     //判断帧头if(*(data_buf+2)==0X01){if(*(data_buf+4)==0X01)mpu6050.Acc_CALIBRATE = 1;if(*(data_buf+4)==0X02)mpu6050.Gyro_CALIBRATE = 1;if(*(data_buf+4)==0X03){mpu6050.Acc_CALIBRATE = 1;      mpu6050.Gyro_CALIBRATE = 1;         }}if(*(data_buf+2)==0X02){if(*(data_buf+4)==0X01){f.send_pid1 = 1;f.send_pid2 = 1;f.send_pid3 = 1;f.send_pid4 = 1;f.send_pid5 = 1;f.send_pid6 = 1;}if(*(data_buf+4)==0X02){}if(*(data_buf+4)==0XA0)     //读取版本信息{f.send_version = 1;}if(*(data_buf+4)==0XA1)     //恢复默认参数{Para_ResetToFactorySetup();}}if(*(data_buf+2)==0X10)                             //PID1{ctrl_1.PID[PIDROLL].kp  = 0.001*( (vs16)(*(data_buf+4)<<8)|*(data_buf+5) );ctrl_1.PID[PIDROLL].ki  = 0.001*( (vs16)(*(data_buf+6)<<8)|*(data_buf+7) );ctrl_1.PID[PIDROLL].kd  = 0.001*( (vs16)(*(data_buf+8)<<8)|*(data_buf+9) );ctrl_1.PID[PIDPITCH].kp = 0.001*( (vs16)(*(data_buf+10)<<8)|*(data_buf+11) );ctrl_1.PID[PIDPITCH].ki = 0.001*( (vs16)(*(data_buf+12)<<8)|*(data_buf+13) );ctrl_1.PID[PIDPITCH].kd = 0.001*( (vs16)(*(data_buf+14)<<8)|*(data_buf+15) );ctrl_1.PID[PIDYAW].kp   = 0.001*( (vs16)(*(data_buf+16)<<8)|*(data_buf+17) );ctrl_1.PID[PIDYAW].ki   = 0.001*( (vs16)(*(data_buf+18)<<8)|*(data_buf+19) );ctrl_1.PID[PIDYAW].kd   = 0.001*( (vs16)(*(data_buf+20)<<8)|*(data_buf+21) );ANO_DT_Send_Check(*(data_buf+2),sum);Param_SavePID();}if(*(data_buf+2)==0X11)                             //PID2{ctrl_1.PID[PID4].kp     = 0.001*( (vs16)(*(data_buf+4)<<8)|*(data_buf+5) );ctrl_1.PID[PID4].ki     = 0.001*( (vs16)(*(data_buf+6)<<8)|*(data_buf+7) );ctrl_1.PID[PID4].kd     = 0.001*( (vs16)(*(data_buf+8)<<8)|*(data_buf+9) );ctrl_1.PID[PID5].kp     = 0.001*( (vs16)(*(data_buf+10)<<8)|*(data_buf+11) );ctrl_1.PID[PID5].ki     = 0.001*( (vs16)(*(data_buf+12)<<8)|*(data_buf+13) );ctrl_1.PID[PID5].kd     = 0.001*( (vs16)(*(data_buf+14)<<8)|*(data_buf+15) );ctrl_1.PID[PID6].kp   = 0.001*( (vs16)(*(data_buf+16)<<8)|*(data_buf+17) );ctrl_1.PID[PID6].ki     = 0.001*( (vs16)(*(data_buf+18)<<8)|*(data_buf+19) );ctrl_1.PID[PID6].kd     = 0.001*( (vs16)(*(data_buf+20)<<8)|*(data_buf+21) );ANO_DT_Send_Check(*(data_buf+2),sum);Param_SavePID();}if(*(data_buf+2)==0X12)                             //PID3{   ctrl_2.PID[PIDROLL].kp  = 0.001*( (vs16)(*(data_buf+4)<<8)|*(data_buf+5) );ctrl_2.PID[PIDROLL].ki  = 0.001*( (vs16)(*(data_buf+6)<<8)|*(data_buf+7) );ctrl_2.PID[PIDROLL].kd  = 0.001*( (vs16)(*(data_buf+8)<<8)|*(data_buf+9) );ctrl_2.PID[PIDPITCH].kp = 0.001*( (vs16)(*(data_buf+10)<<8)|*(data_buf+11) );ctrl_2.PID[PIDPITCH].ki = 0.001*( (vs16)(*(data_buf+12)<<8)|*(data_buf+13) );ctrl_2.PID[PIDPITCH].kd = 0.001*( (vs16)(*(data_buf+14)<<8)|*(data_buf+15) );ctrl_2.PID[PIDYAW].kp   = 0.001*( (vs16)(*(data_buf+16)<<8)|*(data_buf+17) );ctrl_2.PID[PIDYAW].ki   = 0.001*( (vs16)(*(data_buf+18)<<8)|*(data_buf+19) );ctrl_2.PID[PIDYAW].kd   = 0.001*( (vs16)(*(data_buf+20)<<8)|*(data_buf+21) );ANO_DT_Send_Check(*(data_buf+2),sum);Param_SavePID();}if(*(data_buf+2)==0X13)                             //PID4{ANO_DT_Send_Check(*(data_buf+2),sum);}if(*(data_buf+2)==0X14)                             //PID5{ANO_DT_Send_Check(*(data_buf+2),sum);}if(*(data_buf+2)==0X15)                             //PID6{ANO_DT_Send_Check(*(data_buf+2),sum);}
}

本模块代码虽多,但执行的功能相对比较简单,主要是将传过来的八位数据转换成对应格式的数据然后更新到相对应的变量里面。

匿名四轴地面站V4.5使用方法研究相关推荐

  1. 测试基于STM32的ADIS16405评估板,并在匿名四轴上实时显示3轴陀螺仪+3轴加速度计+3轴磁力计 波形。本文最后还公开一个基于C# 的串口波形显示客户端源码。

    标题:测试基于STM32的ADIS16405评估板,并在匿名四轴上实时显示3轴陀螺仪+3轴加速度计+3轴磁力计 波形.本文最好还公开一个基于C# 的串口波形显示客户端源码. 这里附上该评估板的原理图和 ...

  2. 穿越NAT的p2p通信方法研究

    穿越NAT的p2p通信方法研究 日期:2008-12-08 来源:P2P网  作者:未知 字体:大 中 小 <script src="http://www.ppcn.net/ads/b ...

  3. 匿名网络追踪溯源机制及方法

    Tor作为匿名网络的代表,被誉为"暗网之王",而TOR这个网络具有双面性.Tor通过保护通信双方的身份信息,能有效防止用户个人信息的泄露,成为一种新的网络访问方式.但同时,攻击者也 ...

  4. DFSS项目选择方法研究(转载)

    DFSS项目选择方法研究 http://www.quality-world.cn/guanli/2396.html 摘要:六西格玛设计(DFSS)在六西格玛领域受到的关注越来越多.对于项目组合的DFS ...

  5. 典型方法_华北电力大学 赵振兵等: 输电线路典型金具视觉检测方法研究

    关注高电压技术,关注学科发展 本期精选 2020年第9期 结合KL散度和形状约束的Faster R-CNN典型金具检测方法赵振兵,李延旭,甄珍,翟永杰,张珂,赵文清DOI:10.13336/j.100 ...

  6. mSystems:生物地球化学进入病毒时代-采用多样的方法研究病毒和生物地球化学循环...

    翻译:周之超@UW-Madison 生物地球化学进入病毒时代:采用多样的方法研究病毒和生物地球化学循环 Biogeochemistry Goes Viral: towards a Multifacet ...

  7. s域到c语言离散化方法,离散化方法研究.docx

    离散化方法研究.docx 东南大学自动化学院实 验 报 告课程名称 计算机控制技术 第 二 次实验实验名称 离散化方法的研究 院 (系) 自动化 专 业 自动化 姓 名 学 号 实 验 室 实验组别 ...

  8. Android App定位和规避内存泄露方法研究

    from:http://site.douban.com/android/widget/notes/350758/note/167481484/ 工作中刚好用到,网上搜到的,觉得不错,与大家分享 And ...

  9. [原创]关于在VS2008和VS2010中禁用及卸载Visual Assist X的方法研究

    [原创]关于在VS2008和VS2010中禁用及卸载Visual Assist X的方法研究 禁用和启用   此方法对于VS2008和VS2010 都适用. 在VS2008或VS2010菜单栏中选择& ...

最新文章

  1. struts2操作json成字符串格式错误被转义及其前台访问json对象的方法
  2. 王者服务器维护宝箱礼包都没领,王者荣耀:S19战令最后一天,还没领取奖励的玩家要注意了...
  3. 电脑开机动画_领克的开机画面,你修改了?
  4. WeTest功能优化第3期:业内首创,有声音的云真机
  5. [PL/SQL]使用存储过程实现导出指定数据到文件(仿EXP)|转|
  6. 微控制器8位到32位变迁
  7. QT样式表(QStyleSheet)
  8. C# WinForm登录窗口代码
  9. 线性方程组的求解(C++)
  10. 【语言处理与Python】1.3计算语言:简单的统计
  11. 推荐一个完全免费的高质量素材网站
  12. 科研论文研读工具及英文论文写作
  13. 工业物联网的体系架构
  14. android电视盒子蓝牙遥控器app,Android TV 智能电视/盒子 APP 开发焦点控制 两种方法实例...
  15. 猴子摘香蕉问题python_猴子搬香蕉问题的C语言解
  16. 计算机系统最重要的是什么,操作系统最重要的两个作用是什么
  17. python设置Excel单元格的数据有效性
  18. 计数排序 | Counting Sort
  19. img 获取二次元图片地址
  20. 极流行的四型人格分类,你是哪一种?

热门文章

  1. PostgreSQL数据库触发器实验
  2. c语言数星星结构体,1469: 数星星(结构体专题)
  3. 那个拒绝硅谷来了阿里的实习工程师,后来怎么样了?
  4. BCSP-玄子前端开发之JavaScript+jQuery入门CH13_表单校验
  5. Java中“...“的含义
  6. java计算机毕业设计中医药科普网站源码+mysql数据库+系统+部署+lw文档
  7. 本地部署在线客服系统、客服机器人
  8. NameNode Last Checkpoint报错误[Checkpoint Critical]
  9. 专利文档一般有哪些内容
  10. 欢迎报名广东省教育厅2022年科技劳动教育实践活动