基於C#實現與JY61姿態角度傳感器通信


產品介紹:

 此六軸模塊采用高精度的陀螺加速度計 MPU6050,通過處理器讀取 MPU6050 的測量數據 然后通過串口輸出,免去了用戶自己去開發 MPU6050 復雜的 IIC 協議,同時精心的 PCB 布局和工藝保證了 MPU6050 收到外接的干擾最小,測量的精度最高。
 模塊內部自帶電壓穩定電路,可以兼容 3.3V/5V 的嵌入式系統,連接方便。
 采用先進的數字濾波技術,能有效降低測量噪聲,提高測量精度。
 模塊保留了 MPU6050 的 IIC 接口,以滿足用戶訪問底層測量數據(加速度、角速度) 的需求。
 模塊內部集成了姿態解算器,配合動態卡爾曼濾波算法,能夠在動態環境下准確輸出 模塊的當前姿態,姿態測量精度 0.05 度,穩定性極高,性能甚至優於某些專業的傾角 儀!
 采用郵票孔鍍金工藝,品質保證,可嵌入用戶的 PCB 板中。【來自JY61中文說明書】

通信協議:

電平:TTL 電平(非 RS232 電平,若將模塊錯接到 RS232 電平可能造成模塊損壞) 波特率:115200/9600,停止位 1,校驗位 0。
1、 上位機至模塊
指令內容 功能 備注 0xFF0xAA0x52 角度初始化 使 Z 軸角度歸零 0xFF0xAA0x67 加速度計校准 校准加速度零偏 0xFF0xAA0x60 休眠及解休眠 待機模式和工作模式 0xFF0xAA0x61 使用串口,禁用 IIC 設置為串口輸出 0xFF0xAA0x62 禁用串口,使用 IIC 接口 設置為 IIC 接口輸出 0xFF0xAA0x63 波特率 115200,回傳速率 100HZ 設置波特率為 115200 0xFF0xAA0x64 波特率 9600,回傳速率 20HZ 設置波特率為 9600 0xFF0xAA0x65 水平安裝 模塊水平放置 0xFF0xAA0x66 垂直安裝 模塊垂直放置 說明: 1.模塊上電以后需先保持靜止,模塊內部的MCU會在模塊靜止的時候進行自動校准(消 除陀螺零漂),校准以后 Z 軸的角度會重新初始化為 0,Z 軸角度輸出為 0 時,可視為自動 校准完成的信號。 2.出廠默認設置使用串口時,波特率 115200,幀率 100Hz(100HZ 指的是 1 秒回傳 100 個加速度、角速度、角度數據包)。配置可通過上位機軟件配置,因為所有配置都是掉電 保存的,所以只需配置一次就行。
2、 模塊至上位機:
模塊發送至上位機每幀數據分為 3 個數據包,分別為加速度包,角速度包和角度包,3 個數據包順序輸出。波特率 115200 時每隔 10ms 輸出 1 幀數據。
2.1 加速度輸出:
0 0x55 包頭

1 0x51 標識這個包是加速度包

2 AxL X 軸加速度低字節

3 AxH X 軸加速度高字節

4 AyL Y 軸加速度低字節

5 AyH Y 軸加速度高字節

6 AzL Z 軸加速度低字節

7 AzH Z 軸加速度高字節

8 TL 溫度低字節

9 TH 溫度高字節

10 Sum 校驗和

加速度計算公式: ax=((AxH<<8)|AxL)/32768*16g(g 為重力加速度,可取 9.8m/s2) ay=((AyH<<8)|AyL)/32768*16g(g 為重力加速度,可取 9.8m/s2) az=((AzH<<8)|AzL)/32768*16g(g 為重力加速度,可取 9.8m/s2) 溫度計算公式: T=((TH<<8)|TL)/340+36.53 ℃ 校驗和: Sum=0x55+0x51+AxH+AxL+AyH+AyL+AzH+AzL+TH+TL
2.2 角速度輸出:
0 0x55 包頭

1 0x52 標識這個包是角速度包

2 wxL X 軸角速度低字節

3 wxH X 軸加速度高字節

4 wyL Y 軸加速度低字節

5 wyH Y 軸加速度高字節

6 wzL Z 軸加速度低字節

7 wzH Z 軸加速度高字節

8 TL 溫度低字節

9 TH 溫度高字節

10 Sum 校驗和 角速度

計算公式: wx=((wxH<<8)|wxL)/32768*2000(°/s) wy=((wyH<<8)|wyL)/32768*2000(°/s) wz=((wzH<<8)|wzL)/32768*2000(°/s) 溫度計算公式: T=((TH<<8)|TL)/340+36.53 ℃ 校驗和: Sum=0x55+0x52+wxH+wxL+wyH+wyL+wzH+wzL+TH+TL

2.3 角度輸出:
0 0x55 包頭

1 0x53 標識這個包是角度包

2 RollL X 軸角度低字節

3 RollH X 軸角度高字節

4 PitchL Y 軸角度低字節

5 PitchH Y 軸角度高字節

6 YawL Z 軸角度低字節

7 YawH Z 軸角度高字節

8 TL 溫度低字節

9 TH 溫度高字節

10 Sum 校驗和 角速度

計算公式: 滾轉角(x 軸)Roll=((RollH<<8)|RollL)/32768*180(°) 俯仰角(y 軸)Pitch=((PitchH<<8)|PitchL)/32768*180(°) 偏航角(z 軸)Yaw=((YawH<<8)|YawL)/32768*180(°) 溫度計算公式: T=((TH<<8)|TL)/340+36.53 ℃ 校驗和: Sum=0x55+0x53+RollH+RollL+PitchH+PitchL+YawH+YawL+TH+TL

基於C#實現通信

代碼

復制代碼
  1 using DAL;
  2 using Modules;
  3 using System;
  4 using System.Collections.Generic;
  5 using System.ComponentModel;
  6 using System.Data;
  7 using System.Drawing;
  8 using System.IO.Ports;
  9 using System.Linq;
 10 using System.Text;
 11 using System.Threading.Tasks;
 12 using System.Windows.Forms;
 13 
 14 namespace MCUProject
 15 {
 16     public partial class FrmMain : Form
 17     {
 18         public FrmMain()
 19         {
 20             InitializeComponent();
 21             this.Load += FrmMain_Load;
 22         }
 23 
 24         private void FrmMain_Load(object sender, EventArgs e)
 25         {
 26             string[] portList = SerialPort.GetPortNames();
 27             if (portList.Length > 0)
 28             {
 29                 this.cmb_Port.Items.AddRange(portList);
 30                 this.cmb_Port.SelectedIndex = 1;
 31             }
 32 
 33             this.cmb_Paud.Items.AddRange(new string[] { "自定義", "2400", "9600", "115200", "1382400" });
 34 
 35             this.cmb_Paud.SelectedIndex = 3;
 36         }
 37 
 38         //創建通信對象
 39         JY61 objJY = new JY61();
 40 
 41         CommParam objParam = new CommParam();
 42 
 43         bool IsConnected = false;
 44 
 45         private  const float AccelerateScale = 16.0f / 32768.0f;
 46 
 47         private const float AngularSpeedScale =2000.0f / 32768.0f;
 48 
 49         private const float AngularScale = 180.0f / 32768.0f;
 50 
 51         private const float TempScale = 1.0f / 340.0f;
 52 
 53         private const float TempOffset = 36.53f;
 54 
 55         private void btn_Connect_Click(object sender, EventArgs e)
 56         {
 57             try
 58             {
 59                 objJY.OpenMyCom(int.Parse(this.cmb_Paud.Text.Trim()), this.cmb_Port.Text.Trim(), 8, Parity.None, StopBits.One);
 60             }
 61             catch (Exception ex)
 62             {
 63                 IsConnected = false;
 64                 MessageBox.Show("連接失敗:" + ex.Message);
 65                 return;
 66             }
 67             IsConnected = true;
 68             objJY.myShowMsg = this.ShowMsg;
 69             this.timer1.Enabled = true;
 70         }
 71 
 72         private void btn_DisConn_Click(object sender, EventArgs e)
 73         {
 74             objJY.CloseMyCom();
 75         }
 76 
 77         /// <summary>
 78         /// 數據解析
 79         /// </summary>
 80         /// <param name="b"></param>
 81         private void ShowMsg(byte[] b)
 82         {
 83             //數據解析過程
 84             if (b.Length==32)
 85             {
 86                 //報文的篩選和判斷
 87                 if (b[0] == 0x55 && b[1] == 0x51 && b[11] == 0x55 && b[12] == 0x52 && b[22] == 0x55 && b[23] == 0x53)
 88                 {
 89                     //正式根據協議進行解析
 90 
 91                     //加速度解析
 92                     objParam.AccelerateSpeedX = GetActualValue(GetByteArray(b,2,2), AccelerateScale, 0.0f);
 93                     objParam.AccelerateSpeedY = GetActualValue(GetByteArray(b, 4, 2), AccelerateScale, 0.0f);
 94                     objParam.AccelerateSpeedZ= GetActualValue(GetByteArray(b, 6, 2), AccelerateScale, 0.0f);
 95 
 96                     objParam.AngularSpeedX = GetActualValue(GetByteArray(b, 13, 2), AngularScale, 0.0f);
 97                     objParam.AngularSpeedY = GetActualValue(GetByteArray(b, 15, 2), AngularScale, 0.0f);
 98                     objParam.AngularSpeedZ = GetActualValue(GetByteArray(b, 17, 2), AngularScale, 0.0f);
 99 
100                     objParam.AngularX = GetActualValue(GetByteArray(b, 24, 2), AngularScale, 0.0f);
101                     objParam.AngularY = GetActualValue(GetByteArray(b, 26, 2), AngularScale, 0.0f);
102                     objParam.AngularZ = GetActualValue(GetByteArray(b, 28, 2), AngularScale, 0.0f);
103 
104                     objParam.Temp= GetActualValue(GetByteArray(b, 8, 2), TempScale, TempOffset);
105 
106                 }
107             }
108         }
109 
110 
111         private float GetActualValue(byte[] val, float scale, float offset)
112         {
113             //y=kx+b
114             int x = BitConverter.ToInt16(val, 0);
115             return scale * x + offset;
116         }
117 
118         /// <summary>
119         /// 自定義截取字節數組
120         /// </summary>
121         /// <param name="byteArr"></param>
122         /// <param name="start"></param>
123         /// <param name="length"></param>
124         /// <returns></returns>
125         private byte[] GetByteArray(byte[] byteArr, int start, int length)
126         {
127             byte[] Res = new byte[length];
128             if (byteArr != null && byteArr.Length >=start+ length)
129             {
130                 for (int i = 0; i < length; i++)
131                 {
132                     Res[i] = byteArr[i + start];
133                 }
134 
135             }
136             return Res;
137         }
138 
139         private void timer1_Tick(object sender, EventArgs e)
140         {
141             this.lbl_AngularSpeedX.Text = objParam.AngularSpeedX.ToString("f2") ;
142             this.lbl_AngularSpeedY.Text = objParam.AngularSpeedY.ToString("f2") ;
143             this.lbl_AngularSpeedZ.Text = objParam.AngularSpeedZ.ToString("f2") ;
144 
145 
146             this.lbl_AngularX.Text = objParam.AngularX.ToString("f2") ;
147             this.lbl_AngularY.Text = objParam.AngularY.ToString("f2") ;
148             this.lbl_AngularZ.Text = objParam.AngularZ.ToString("f2") ;
149 
150             this.lbl_SpeedX.Text = objParam.AccelerateSpeedX.ToString("f2");
151             this.lbl_SpeedY.Text = objParam.AccelerateSpeedY.ToString("f2");
152             this.lbl_SpeedZ.Text = objParam.AccelerateSpeedZ.ToString("f2");
153         }
154 
155         /*
156          上位機免費公開課鏈接:https://ke.qq.com/course/301616?taid=3872982464502320
157         
158          */
159     }
160 }
復制代碼
 1 using System;
 2 using System.Collections.Generic;
 3 using System.IO.Ports;
 4 using System.Linq;
 5 using System.Text;
 6 using System.Threading.Tasks;
 7 
 8 namespace DAL
 9 {
10     public delegate void ShowMsgDelegate(byte[] Msg);
11     public class JY61
12     {
13         //添加串口對象
14         private SerialPort MyCom = new SerialPort();
15 
16         public ShowMsgDelegate myShowMsg;
17 
18         #region 串口的打開與關閉
19 
20         public void OpenMyCom(int iBaudRate, string iPortName, int iDataBits, Parity iParity, StopBits iStopBits)
21         {
22             //如果打開,先關閉
23             if (MyCom.IsOpen)
24             {
25                 MyCom.Close();
26             }
27 
28             //串口對象初始化
29             MyCom.BaudRate = iBaudRate;
30             MyCom.PortName = iPortName;
31             MyCom.DataBits = iDataBits;
32             MyCom.Parity = iParity;
33             MyCom.StopBits = iStopBits;
34 
35             MyCom.ReceivedBytesThreshold = 1;
36             MyCom.DataReceived += MyCom_DataReceived;
37 
38             MyCom.Open();
39 
40         }
41 
42 
43         public void CloseMyCom()
44         {
45             if (MyCom.IsOpen)
46             {
47                 MyCom.Close();
48             }
49         }
50 
51         #endregion
52 
53         #region 事件接收
54         private void MyCom_DataReceived(object sender, SerialDataReceivedEventArgs e)
55         {
56             int byteToRead = MyCom.BytesToRead;
57             if (byteToRead > 0)
58             {
59                 byte[] array = new byte[byteToRead];
60                 MyCom.Read(array, 0, byteToRead);
61                 //數據就在Array里面
62                 myShowMsg(array);
63             }
64         }
65 
66         #endregion
67 
68 
69 
70     }
71 }
復制代碼


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM