完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
课程设计要求
如下图: 我们选择采用C#进行开发,因为串口有距离限制不方便我们采集数据,所以我们决定用C#做一个TCP的服务器,进行数据观察以及数据采集。 将电脑作为TCP服务器 C#提供了丰富的网络开发API,根据socket通信基本流程图 总结通信的基本步骤:
//创建socket对象 Socket tcpServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); try { //绑定IP和申请端口 tcpServer.Bind(new IPEndPoint(IPAddress.Any, 8888)); } catch (Exception ex) { MessageBox.Show("错误: ip地址设置失败,请正确连接热点并检查ip地址", "提示",MessageBoxButtons.OK); t.Abort();//结束本线程 } server_open_flag = true; //标志服务器开启成功 server_open_change = true; //标志服务器开启状态改变 tcpServer.Listen(100);//设置客户端最大连接数 clientSocket = tcpServer.Accept(); //会一直阻塞等待连接 若没有链接则不会进行 # 处理接收到的数据 处理接收到的数据就较为简单,我们每个数据包会发送14个字节的数据,也就是两位的校验位和6个int16的数据,分别代表三个轴上的加速度计和陀螺仪数据。具体步骤如下:
while (true) { int buffer_num = data_buffer.Count; //提前存好,防止处理过程中Count变化 if (buffer_num >= 14) //至少14字节 { if (data_buffer[0] == 0x5A) //帧头 { if (data_buffer[1] == 0x01) //判断这一帧是否是心跳波形数据 { Action act = delegate () { cur_data.a_x = (Int16)(data_buffer[2] | data_buffer[3] << 8); cur_data.a_y = (Int16)(data_buffer[4] | data_buffer[5] << 8); cur_data.a_z = (Int16)(data_buffer[6] | data_buffer[7] << 8); cur_data.g_x = (Int16)(data_buffer[8] | data_buffer[9] << 8); cur_data.g_y = (Int16)(data_buffer[10]| data_buffer[11] << 8); cur_data.g_z = (Int16)(data_buffer[12]| data_buffer[13] << 8); ecg_add_data(cur_data.a_x, cur_data.a_y, cur_data.a_z, cur_data.g_x, cur_data.g_y, cur_data.g_z); }; data_save.Add(new datatype(cur_data.a_x, cur_data.a_y, cur_data.a_z, cur_data.g_x, cur_data.g_y, cur_data.g_z)); this.Invoke(act); data_buffer.RemoveRange(0, 13); //从缓存中删除前14个字节 } } else { //这里是很重要的,如果数据开始不是帧头,就删除一位 data_buffer.RemoveAt(0); } } if (main_form_close_flag == true) { t1.Abort(); //结束本线程 } } 曲线绘制 图表 我们采用自带的chart控件,在form中点击工具箱搜索即可寻找到该控件。 将chart移动到合适的位置后,我们可以在窗体加载函数中,将chart进行初始化配置,具体代码如下: ChartArea chartArea = new ChartArea(); chartArea.Name = "FirstArea"; chartArea.CursorX.AutoScroll = true; //是否滚动 chartArea.AxisX.ScrollBar.Enabled = true; //开启滚动条 chartArea.CursorX.IsUserEnabled = true; chartArea.CursorX.IsUserSelectionEnabled = true; chartArea.AxisX.ScaleView.Zoomable = true; chartArea.CursorX.SelectionColor = Color.SkyBlue; chartArea.CursorY.IsUserEnabled = true; chartArea.CursorY.AutoScroll = true; chartArea.CursorY.IsUserSelectionEnabled = true; chartArea.CursorY.SelectionColor = Color.SkyBlue; chartArea.CursorX.IntervalType = DateTimeIntervalType.Auto; chartArea.AxisX.ScrollBar.ButtonStyle = ScrollBarButtonStyles.All;//启用X轴滚动条按钮 chartArea.BackColor = Color.AliceBlue; //背景色 chartArea.BackSecondaryColor = Color.White; //渐变背景色 chartArea.BackGradientStyle = GradientStyle.TopBottom; //渐变方式 chartArea.BackHatchStyle = ChartHatchStyle.None; //背景阴影 chartArea.BorderDashStyle = ChartDashStyle.NotSet; //边框线样式 chartArea.BorderWidth = 1; //边框宽度 chartArea.BorderColor = Color.Black; chartArea.AxisX.MajorGrid.Enabled = false; chartArea.AxisY.MajorGrid.Enabled = false; // Axis chartArea.AxisY.Title = @"数值"; chartArea.AxisY.LabelAutoFitMinFontSize = 5; chartArea.AxisY.LineWidth = 2; chartArea.AxisY.LineColor = Color.Black; chartArea.AxisY.Enabled = AxisEnabled.True; chartArea.AxisX.Title = @"时间"; chartArea.AxisX.IsLabelAutoFit = true; chartArea.AxisX.LabelAutoFitMinFontSize = 5; chartArea.AxisX.LabelStyle.Angle = -15; chartArea.AxisX.LabelStyle.IsEndLabelVisible = true; //show the last label chartArea.AxisX.Interval = 10; chartArea.AxisX.IntervalAutoMode = IntervalAutoMode.FixedCount; chartArea.AxisX.IntervalType = DateTimeIntervalType.NotSet; chartArea.AxisX.TextOrientation = TextOrientation.Auto; chartArea.AxisX.LineWidth = 2; chartArea.AxisX.LineColor = Color.Black; chartArea.AxisX.Enabled = AxisEnabled.True; chartArea.AxisX.ScaleView.MinSizeType = DateTimeIntervalType.Months; chartArea.AxisX.Crossing = 0; chartArea.Position.Height = 85; chartArea.Position.Width = 85; chartArea.Position.X = 5; chartArea.Position.Y = 7; chart_ecg.ChartAreas.Add(chartArea); chart_ecg.BackGradientStyle = GradientStyle.TopBottom; //图表的边框颜色、 chart_ecg.BorderlineColor = Color.FromArgb(26, 59, 105); //图表的边框线条样式 chart_ecg.BorderlineDashStyle = ChartDashStyle.Solid; //图表边框线条的宽度 chart_ecg.BorderlineWidth = 2; //图表边框的皮肤 //chart_ecg.BorderSkin.SkinStyle = BorderSkinStyle.FrameThin3; chart_ecg.ChartAreas[0].AxisX.Interval = 0.5; //设置横坐标的分辨率 chart_ecg.ChartAreas[0].AxisX.ScaleView.Size = 1000; //设置横坐标长度 曲线 除了图表,我们还需要绘制曲线,我们采用Series进行绘制,一共需要6条曲线,初始化操作相同,下面就给出一条曲线的初始化操作: series1 = new Series(); series1.ChartArea = "FirstArea"; chart_ecg.Series.Add(series1); //Series1 style series1.ToolTip = "#VALX,#VALY"; //鼠标停留在数据点上,显示XY值 series1.Name = "a_x"; series1.ChartType = SeriesChartType.Line; // type:折线 series1.BorderWidth = 2; series1.Color = Color.Black; series1.XValueType = ChartValueType.Time;//x axis type series1.YValueType = ChartValueType.Int32;//y axis type //Marker series1.MarkerStyle = MarkerStyle.Square; series1.MarkerSize = 2; series1.MarkerColor = Color.Black; 然后就是绘制曲线了,代码如下: series1.Points.AddXY(osc_x, data1); 最后还有选择显示的曲线,直接用check控件即可,代码如下: series1.Enabled = check1.Checked; 综上,我们的曲线绘制部分就完成了。 文件写入 为了方便数据的处理,需要将接受到的数据写入到文件中,具体实现步骤如下:
class datatype { public Int16 a_x, a_y, a_z; public Int16 g_x, g_y, g_z; public datatype(Int16 ax = 0, Int16 ay = 0, Int16 az = 0, Int16 gx = 0, Int16 gy = 0, Int16 gz = 0) { this.a_x = ax; this.a_y = ay; this.a_z = az; this.g_x = gx; this.g_y = gy; this.g_z = gz; } public string data_to_string() { return a_x + "," + a_y + "," + a_z + "," + g_x + "," + g_y + "," + g_z ; } } 定义一个缓冲区,用于存放数据: private List 写入缓冲区很简单,直接写入该list即可。 然后便是写入文件: if (data_save.Count == 0) { MessageBox.Show("错误:缓存区为空", "提示", MessageBoxButtons.OK); return; } //文件名为当前时间 string Child_Address = Save_File_Address + "\" + DateTime.Now.ToString().Replace(@"/", ".").Replace(":", ".") + ".dyy";//创建文件 FileStream fs = new FileStream(Child_Address, FileMode.OpenOrCreate, FileAccess.ReadWrite); StreamWriter sw = new StreamWriter(fs); // 创建写入baidu流 for (int i = 0; i < data_save.Count; i++) { sw.WriteLine(data_save.data_to_string()); } //删除缓存区数据 data_save.RemoveRange(0, data_save.Count); sw.Close(); //关闭文件 最后加个按键控制就完事了。 |
|
|
|
只有小组成员才能发言,加入小组>>
705 浏览 0 评论
1114 浏览 1 评论
2491 浏览 5 评论
2826 浏览 9 评论
移植了freeRTOS到STMf103之后显示没有定义的原因?
2671 浏览 6 评论
使用eim外接fpga可是端口一点反应都没有有没有大哥指点一下啊
659浏览 9评论
667浏览 7评论
请教大神怎样去解决iMX6Q在linux3.0.35内核上做AP失败的问题呢
789浏览 6评论
634浏览 5评论
678浏览 5评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-25 13:59 , Processed in 1.090912 second(s), Total 81, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号