前言
这学期开了一门《嵌入式应用系统开发》的课程,本身学软件,对硬件方面也不是特别精通,整理一下我自己学习过程中的想法和笔记分享出来仅供参考。
0 实验目的
示波器 重点 1数据库记录和显示数据 2 chart控件
1 实验前的准备
首先假设你是有一定C#基础的,因为我是利用C#来编程的,然后开始我们这次实验。所要用的的工具如下:
- VS2010
- Arduino
- 51单片机
2 连接上单片机
连接单片机后,会有未识别的设备显示=>桌面电脑图标,属性找到设备管理器,设备里找到未识别设备=>右键更新驱动=>找到arduino所在路径下drivers文件夹选中,更新驱动=>提示警告一律不管,更新,成功后关闭窗口=>打开arduino后注意首先修改工具里端口的选择
3 单片机代码部分
int grad=0; //角度
float x;
char val;
void setup() {
Serial.begin(9600); //波特率
pinMode(13,OUTPUT);
}
void loop(){
x=sin(grad/180.0*3.1415) +2; //利用三角函数生成一个0-2的浮点数
grad=grad+2; Serial.print(x);
delay(200);
val=Serial.read();
switch(val)
{case '1': digitalWrite(13,HIGH);break;
case '2': digitalWrite(13,LOW);break; }
}
4 C#代码部分
主界面完整程序代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Threading;
using System.IO.Ports;
using serial_test;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;
using System.Data;
using System.Data.OleDb;
//using System.Data.SqlClient;
namespace serial_test
{
public partial class Form1 : Form
{
// StringBuilder currentline = new StringBuilder(),currentline2 = new StringBuilder();
private float[] arry = new float[180];
private Series series = new Series();
int num=0;
OleDbConnection conn;
OleDbCommand cmd;
string str_connection;
string strp = System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
public Form1()
{
str_connection = " provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\\serial_test\\db.accdb";
conn = new OleDbConnection(str_connection);
conn.Open();
InitializeComponent();
foreach (string s in SerialPort.GetPortNames()) //列出所有端口号供选择
comboBox1.Items.Add(s);
comboBox1.SelectedIndex = comboBox1.Items.Count - 1;
series.ChartType = SeriesChartType.Spline;
series.Name = "电压";
this.myChart.Series.Add(series);
}
//provider=Microsoft.ACE.OLEDB.12.0;;Data Source=d:\D:\serial_test\db.accdb"
public void form1_load(){
// string str_source = "Data Source=" + strp + "\\db.accdb";
;
}
//定义 SerialPort对象
SerialPort port1;
string sql;
//初始化SerialPort对象方法.PortName为COM口名称,例如"COM1","COM2"等,注意是string类型
public void InitCOM(string PortName)
{
port1 = new SerialPort(PortName);
port1.BaudRate = 9600;//默认的波特率
port1.Parity = Parity.None;//无奇偶校验位
port1.StopBits = StopBits.Two;//两个停止位
port1.ReceivedBytesThreshold = 3;//设置缓冲区字节数, DataReceived 事件会在达到这个字符数后被引发。
port1.DataReceived += new SerialDataReceivedEventHandler(DataReceived);//DataReceived事件委托
}
//DataReceived事件委托方法
private void DataReceived(object sender, SerialDataReceivedEventArgs e)
{
try{ while (port1.BytesToRead > 0)
{
SerialPort sp = (SerialPort)sender;
strp = sp.ReadExisting();
}
Invoke(new MethodInvoker(delegate()
{
float x;
label2.Text = strp;
try {
x = float.Parse(strp);
} catch (Exception) { return; }
array_show(x);
/***********************************************************/
try
{
sql = "insert into tab1 (sind) values (" + x + ")";
cmd = new OleDbCommand(sql,conn);
cmd.ExecuteNonQuery();
/*
conn = new OleDbConnection(str_connection);
conn.Open();
cmd = new OleDbCommand(sql, conn);
int i = cmd.ExecuteNonQuery();
*/
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString());
}
/*******************************/
}));
// currentline.Clear();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString());
}
}
private void array_show(float x)
{
series.Points.AddXY(num++, x);
while (this.myChart.Series[0].Points.Count >= 180)
{
foreach (Series s in this.myChart.Series)
s.Points.RemoveAt(0);
}
Int64 axisMinimum = (Int64)this.myChart.Series[0].Points[0].XValue;
this.myChart.ChartAreas[0].AxisX.Minimum = axisMinimum;
this.myChart.ChartAreas[0].AxisX.Maximum = axisMinimum + 180;
}
//打开串口的方法
public void OpenPort()
{
try{
port1.Open(); button1.Enabled = false;
}
catch (Exception ex) {
MessageBox.Show(ex.Message);
return;
}
if (port1.IsOpen) {
label1.Text="已连接!";
System.Threading.Thread.Sleep(200);
} else label1.Text="无法打开串口!";
}
//关闭串口的方法
public void ClosePort()
{
port1.Close();
button1.Enabled = true;
if (!port1.IsOpen) label1.Text="串口连接已关闭!";
}
//读取选择的端口,然后初始化和打开端口
private void button1_Click(object sender, EventArgs e)
{
string com= comboBox1.Text.ToString();
InitCOM(com);
OpenPort();
}
//关闭端口
private void button2_Click(object sender, EventArgs e)
{
ClosePort();
}
private void button3_Click(object sender, EventArgs e)
{
port1.WriteLine("2");
}
private void button4_Click(object sender, EventArgs e)
{
port1.WriteLine("1");
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void BtnView_Click(object sender, EventArgs e)
{
Form2 aa = new Form2();
aa.Show();
}
private void BtnView2_Click(object sender, EventArgs e)
{
Form3 aa = new Form3();
aa.Show();
}
}
}
5 C#滚动轴查看历史数据
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;
using System.Data.OleDb;
namespace serial_test
{
public partial class Form2 : Form
{
OleDbConnection conn;
OleDbCommand cmd;
private Series series = new Series();
string str_connection;
int num = 0;
public Form2()
{
InitializeComponent();
str_connection = "provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\\serial_test\\db.accdb";
series.ChartType = SeriesChartType.Spline;
series.Name = "电压";
this.chart1.Series.Add(series);
}
private void hScrollBar1_ValueChanged(object sender, EventArgs e)
{
conn = new OleDbConnection(str_connection);
conn.Open();
string sql = "select *from tab1";
long b, n;
OleDbDataAdapter da = new OleDbDataAdapter(sql, conn);
DataSet ds = new DataSet();
da.Fill(ds);
n = ds.Tables[0].Rows.Count;
b = Convert.ToInt64(hScrollBar1.Value/100.0*(n-180))+180;
label1.Text = n.ToString() + " " + b.ToString();
sql="select * from (select top 180 * from (select top "+b+" * from tab1 order by id asc) order by id desc) order by id asc";
da = new OleDbDataAdapter(sql, conn);
ds = new DataSet();
da.Fill(ds);
num = (int)b-180;
for (int i = 0; i < 180; i++)
array_show(float.Parse(ds.Tables[0].Rows[i].ItemArray[1].ToString()));
}
private void array_show(float x) {
series.Points.AddXY(num++,x);
while(this.chart1.Series[0].Points.Count>=180)
{
foreach (Series s in this.chart1.Series)
s.Points.RemoveAt(0);
}
Int64 axisMinimum = (Int64)this.chart1.Series[0].Points[0].XValue;
this.chart1.ChartAreas[0].AxisX.Minimum = axisMinimum;
this.chart1.ChartAreas[0].AxisX.Maximum = axisMinimum + 180;
}
private void Form2_Load(object sender, EventArgs e)
{
conn = new OleDbConnection(str_connection);
conn.Open();
string sql = "select *from tab1";
long b, n;
OleDbDataAdapter da = new OleDbDataAdapter(sql, conn);
DataSet ds = new DataSet();
da.Fill(ds);
n = ds.Tables[0].Rows.Count;
b = Convert.ToInt64(hScrollBar1.Value) + 180;
sql = "select * from (select top 180 * from (select top " + b + " * from tab1 order by id asc) order by id desc) order by id asc";
da = new OleDbDataAdapter(sql, conn);
ds = new DataSet();
da.Fill(ds);
num = (int)b - 180;
for (int i = 0; i < 180; i++)
array_show(float.Parse(ds.Tables[0].Rows[i].ItemArray[1].ToString()));
}
}
}
6 Chart图表自带滚动轴显示历史数据
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.OleDb;
using System.Windows.Forms.DataVisualization.Charting;
namespace serial_test
{
public partial class Form3 : Form
{
OleDbConnection conn;
OleDbCommand cmd;
string str_connection;
private Series series = new Series();
private float[] points = new float[180];
public Form3()
{
InitializeComponent();
str_connection = "provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\\serial_test\\db.accdb";
series.ChartType = SeriesChartType.Spline;
series.Name = "电压";
this.chart1.Series.Add(series);
}
private void chart1_Click(object sender, EventArgs e)
{
}
private void Form3_Load(object sender, EventArgs e)
{
conn = new OleDbConnection(str_connection);
conn.Open();
string sql = "select *from tab1";
long b, n;
OleDbDataAdapter da = new OleDbDataAdapter(sql, conn);
DataSet ds = new DataSet();
da.Fill(ds);
n = ds.Tables[0].Rows.Count;
// label1.Text = n.ToString() + " " + b.ToString();
sql = "select top 180 * from tab1 order by id asc";
da = new OleDbDataAdapter(sql, conn);
ds = new DataSet();
da.Fill(ds);
for (int i = 0; i < points.Length; i++)
{
points[i] = Convert.ToSingle(float.Parse(ds.Tables[0].Rows[i].ItemArray[1].ToString()));
this.chart1.Series[0].Points.AddXY(i + 1, points[i]);
}
//while (this.chart1.Series[0].Points.Count >= 180)
//{
// foreach (Series s in this.chart1.Series)
// s.Points.RemoveAt(0);
//}
//Int64 axisMinimum = (Int64)this.chart1.Series[0].Points[0].XValue;
//this.chart1.ChartAreas[0].AxisX.Minimum = axisMinimum;
//this.chart1.ChartAreas[0].AxisX.Maximum = axisMinimum + 180;
}
}
}
5 运行结果
C#程序运行结果:
C#滚动轴显示历史数据界面:
Chart图表自带滚动轴显示历史数据界面:
程序中使用的access数据库:
6 总结
这个实验我们分别利用C#滚动轴组件和Chart图标内置来实现。C#滚动轴显示在数值变动时,相应的从数据库中查询所需要的数据,类似于数据库的分页查询显示,每拖动一次滚动轴,就从数据库中查询一次;Chart图标内置将数据源(采集得到的数据),第一次查询就已经查询出全部的数据内容,在坐标系中将数据实时、逐点的显示出来,反映被测物理量的变化趋势。