继上次的读卡之后,要做一个地磅的读取。

下面是我在读卡Demo上改的读取地磅的。

地磅是一直向串口发送数据的,所以需要截取数据来一直判断数据是否合法,然后计算出结果。

其中遇到了一个小问题,文末有介绍。

本人初学菜鸟,大牛们有意见欢迎评论。

 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.IO.Ports;
using System.IO;
using System.Threading; namespace WindowsFormsApplicationcs
{
public partial class FormMain : Form
{
//声明端口对象
SerialPort myport = null;
//处理数据的数据数组
byte[] buf = new byte[];
//声明委托类型
public delegate void Displaydelegate(byte[] buf);
//委托变量
public Displaydelegate disp_delegate; public FormMain()
{
InitializeComponent();
//安全线程外更新空间
//Form.CheckForIllegalCrossThreadCalls = false;
} //窗口加载
private void FormMain_Load(object sender, EventArgs e)
{
Form.CheckForIllegalCrossThreadCalls = false;
txtPort.Text = "COM3";
myport = new SerialPort();
disp_delegate = new Displaydelegate(DispUI);
} //打开串口按钮
private void button1_Click(object sender, EventArgs e)
{
try
{ //设置串口端口
myport.PortName = txtPort.Text.ToString();
//设置比特率
myport.BaudRate = Convert.ToInt32(cmbBaud.Text);
//设置数据位
myport.DataBits = Convert.ToInt32(cmbBits.Text);
//设置停止位
switch (cmbStopBits.SelectedIndex)
{
case : myport.StopBits = StopBits.None; break;
case : myport.StopBits = StopBits.One; break;
case : myport.StopBits = StopBits.OnePointFive; break;
case : myport.StopBits = StopBits.Two; break;
} //设置奇偶校验位
switch (cmbParity.SelectedIndex)
{
case : myport.Parity = Parity.Even; break;
case : myport.Parity = Parity.Mark; break;
case : myport.Parity = Parity.None; break;
case : myport.Parity = Parity.Odd; break;
case : myport.Parity = Parity.Space; break;
} //缓冲区只接受一个字符
myport.ReceivedBytesThreshold = ;
//接收事件添加委托
myport.DataReceived += new SerialDataReceivedEventHandler(this.myport_DataReceived);
//打开串口
myport.Open();
if (myport.IsOpen)
{
MessageBox.Show("端口已打开");
this.tstldqzt.Text = "当前状态:端口已打开";
}
else
{
MessageBox.Show("端口未能打开!");
}
}
catch (Exception ex)
{
MessageBox.Show("端口打开出现错误!\n" + ex.Message.ToString());
}
} //委托方法
//接收数据
private void myport_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
Thread.Sleep();
if (myport.BytesToRead > )//如果缓冲区内有数据
{
myport.Read(buf, , );//从缓冲区读取数据到buf暂存数组,
} if (buf[] == 0x02)//如果开头等于2,则表明是信息开始 0x02
{
try
{
while (myport.BytesToRead == );
myport.Read(buf, , );//从缓冲区读取一条正确数据到buf暂存数组
string s = string.Empty; for (int i = ; i < ; i++)
{
s += (char)buf[i];
} StringBuilder b = new StringBuilder(""); if (s.Substring(, ) == "-")
b.Append("-"); int strint = Convert.ToInt32(s.Substring(,));
int dianint = Convert.ToInt32(s.Substring(,)); switch (dianint)
{
case : strint = strint / ; break;
case : strint = strint / ; break;
case : strint = strint / ; break;
case : strint = strint / ; break;
}
b.Append(strint);
txtReceive.Text += "开始" + b + "结束\r\n"; //this.Invoke(disp_delegate, buf);
}
finally
{
myport.DiscardInBuffer();//清空缓冲区
}
}
} //更新ui方法
public void DispUI(byte[] buf)
{ } //关闭方法
private void button2_Click(object sender, EventArgs e)
{
myport.Close();
if (!myport.IsOpen)
{
this.tstldqzt.Text = "当前状态:端口已关闭";
MessageBox.Show("端口已关闭");
}
} //清屏按钮
private void button3_Click(object sender, EventArgs e)
{
this.txtReceive.Clear();
} //菜单栏关于
private void tsmiabout_Click(object sender, EventArgs e)
{
frmAbout frmabout = new frmAbout();
frmabout.ShowDialog();
} //菜单栏保存结果
private void tsmisave_Click(object sender, EventArgs e)
{
if (this.txtReceive.Text == "")
{ MessageBox.Show("当前结果为空,请先测试"); }
string path = Directory.GetCurrentDirectory() + "\\端口测试结果.txt";
File.WriteAllText(path, this.txtReceive.Text.ToString(), Encoding.ASCII);
} }
}

这里其实有个问题,就是一个窗口一般会涉及到多个串口设备的通讯,

公司目前的需求也不例外,可以看到我使用了一个thread.sleep,

这样虽然当时解决了问题,但是当一个窗口有多个串口通讯更新ui的时候应该会出现问题,

但因为当时手头没有设备也没做进一步的测试,。

因为不加这句话就会无法实时更新ui,当时打了一个多小时的短点记了好多数据,

才确定了不是数据处理那部分的问题,思考一下原因应该是while把线程堵死了,一直在做运算。

但是使用invoke不是新开线程委托吗?为什么也是更新不了ui。

百度了发现如下解释

invoke是在拥有此控件的基础窗口句柄的线程上指定指定的委托

begininvoke是在创建此控件的基础窗口句柄的线程上异步执行指定的委托

使用begininvoke应该就可以不干扰其他的串口通讯更新ui了

Winform 串口通讯之地磅的更多相关文章

  1. Winform 串口通讯之读卡器

    老板给我的第一个硬件就是一个读卡器, 说让我做一下试试,于是从网上查了查就写了出来,相当的简单. 但是后来还有一个地磅的串口通讯,我整整搞了一天. 在窗体类的构造函数中写入 Form.CheckFor ...

  2. WinForm—串口通讯

    ialPort(串行端口资源) 常用属性: BaudRate 此串行端口上要使用的波特率 DataBits 每发送/接收一个字节的数据位数目 DtrEnable 在通讯过程中是否启用数据终端就绪(St ...

  3. C#串口通讯

    本文提供一个用C#实现串口通讯实例,亲自编写,亲测可用! 开发环境:VS2008+.net FrameWork3.5(实际上2.0应该也可以) 第一步 创建一个WinForm窗体,拉入一些界面元素 重 ...

  4. C#串口通讯概念以及简单实现

    最近在研究串口通讯,其中有几个比较重要的概念,RS-232这种适配于上位机和PC端进行连接,RS-232只限于PC串口和设备间点对点的通信.它很简单的就可以进行连接,由于串口通讯是异步的,也就是说你可 ...

  5. 嵌入式Linux学习笔记(六) 上位机QT界面实现和串口通讯实现

    目录 (1).参考资料 (2).QT界面布局实现 (3).数据和操作逻辑 在上一章我们实现了下位机的协议制定,并通过串口通讯工具完成了对设备内外设(LED)的状态修改,下面就要进行上位机软件的实现了( ...

  6. C#串口通讯实例

    本文参考<C#网络通信程序设计>(张晓明  编著) 程序界面如下图: 参数设置界面代码如下: using System; using System.Collections.Generic; ...

  7. delphi之动态库调用和串口通讯

    串口通讯: Spcomm 控件属性: CommName  :表示COM1,COM2等串口的名字: BaudRate:设定波特率9600,4800等 StartComm StopComm 函数Write ...

  8. 用SPCOMM 在 Delphi中实现串口通讯 转

      用Delphi 实现串口通讯,常用的几种方法为:使用控件如MSCOMM和SPCOMM,使用API函数或者在Delphi 中调用其它串口通讯程序.利用API编写串口通信程序较为复杂,需要掌握大量通信 ...

  9. 西门子plc串口通讯方式

    西门子plc串口通讯的三种方式 时间:2015-10-25 14:31:55编辑:电工栏目:西门子plc 导读:西门子plc串口通讯的三种方式,分为RS485 串口通信.PPI 通信.MPI 通信,自 ...

随机推荐

  1. 正则表达式入门之学习路线&七个问题

    由于工作需求,需要使用正则表达式查找满足某种模式的字符串,但因为之前都没有接触过相关内容,最开始的时候看了一些已经被别人写好了的正则表达式,本来打算可能可以直接使用: 最全的常用正则表达式大全——包括 ...

  2. 20155303 2016-2017-2 《Java程序设计》第三周学习总结

    20155303 2016-2017-2 <Java程序设计>第三周学习总结 教材学习内容总结 第四章 学会如何查询Java API文件对于Java的学习很有帮助,可以了解到如何使用各种方 ...

  3. 关于项目中根据当前数据库中最大ID生成下一个ID问题——(五)

    1.关于部门管理时候根据上级产生下级部门ID的问题(传入一个参数是上级部门id)

  4. c++ 类的构造顺序

    在单继承的情况下,父类构造先于子类,子类析构先于父类,例: class A { public: A() { cout << "A" << endl; } ~ ...

  5. Python大数据处理案例

    分享 知识要点:lubridate包拆解时间 | POSIXlt利用决策树分类,利用随机森林预测利用对数进行fit,和exp函数还原 训练集来自Kaggle华盛顿自行车共享计划中的自行车租赁数据,分析 ...

  6. 十一、springboot之web开发之Filter

    我们常常在项目中会使用filters用于录调用日志.排除有XSS威胁的字符.执行权限验证等等.Spring Boot自动添加了OrderedCharacterEncodingFilter和Hidden ...

  7. python网络编程--线程锁(互斥锁Mutex)

    一:为什么需要线程锁 一个进程下可以启动多个线程,多个线程共享父进程的内存空间,也就意味着每个线程可以访问同一份数据,此时,如果2个线程同时要修改同一份数据,会出现什么状况? 很简单,假设你有A,B两 ...

  8. tf.nn.embedding_lookup函数

    tf.nn.embedding_lookup(params, ids, partition_strategy='mod', name=None, validate_indices=True, max_ ...

  9. 浅谈js设计模式之策略模式

    策略模式有着广泛的应用.本节我们就以年终奖的计算为例进行介绍. 很多公司的年终奖是根据员工的工资基数和年底绩效情况来发放的.例如,绩效为 S的人年终奖有 4倍工资,绩效为 A的人年终奖有 3倍工资,而 ...

  10. No.11 selenium学习之路之加载浏览器插件for Firefox

    打开帮助 —— 故障排除信息