https://www.cnblogs.com/yangfengwu/p/11087613.html

页面修改成这样子

           

现在看串口发送数据

点击点亮 发送0xaa 0x55 0x01

我电脑上安装了虚拟串口软件,虚拟出来了COM1和COM2,然后COM1发送的数据会发给COM2  COM2发送的数据会发给COM1

大家如果有两个串口模块也可以

https://jingyan.baidu.com/article/e3c78d648965303c4c85f535.html

那个按钮的程序这样写

测试一下

现在看串口接收数据

说一下哈,这个是上位机的串口中断函数,就是只要接收到数据就会进入这个中断

现在咱读出来接收的数据,然后显示在

读取数据给了好几个方法

咱就说1个,哈哈哈,其实自己一选择方法的时候就有中文注释......

大家注没注意

现在调用一个函数读出来,然后显示出来

ReadExisting()   这个方法就会返回缓冲区里面的所有字节,注意返回的是字符串形式的

调用这个方法就是  serialPort1.ReadExisting();       serialPort1就是咱的

因为咱就是要里面的数据所以

string str = serialPort1.ReadExisting();//读出来当前缓存里面的所有数据

Invoke((new Action(() =>
{
    这里面放要操作的主线程的控件的方法
})));

其实这个方法主要是方便解决一个问题,稍候再说,咱先测试一下哈

说明可以了,现在呢,咱去掉

大家可以点开那个  如何跨线程调用 Windows 窗体控件

大家可以看这个 https://www.cnblogs.com/yangfengwu/p/5761841.html   (最好别看,看了就会感觉麻烦)

4.0之后引进了这种方法

对于初学者知道这个就可以了,像C#,C++,JAVA等等这种高级语言哈,因为可以做界面了,,高级语言规定,操作页面不能在子线程中进行

哪些是子线程呢!..像上面那个串口中断函数,还有自己创建的任务Thread,,,等等吧

好现在,咱接收16进制,

接收到

0xaa 0x55 0x01

0xaa 0x55 0x00

好,上菜

        //串口接收到数据就会进入
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
int len = serialPort1.BytesToRead;//获取可以读取的字节数
if (len > )
{
byte[] recvBytes = new byte[len];//创建接收的数组
serialPort1.Read(recvBytes, , len);//接收数据
if (recvBytes[] == 0xaa && recvBytes[] == 0x55)//判断数据
{
if (recvBytes[] == 0x01)//
{
Invoke((new Action(() =>
{
button3.Text = "熄灭";
label5.Text = "点亮";
})));
}
else if (recvBytes[] == 0x00)
{
Invoke((new Action(() =>
{
button3.Text = "点亮";
label5.Text = "熄灭";
})));
}
}
}
//string str = serialPort1.ReadExisting();//读出来当前缓存里面的所有数据
//Invoke((new Action(() =>
//{
// //显示在文本框里面
// textBox1.AppendText(str);
//})));
}

测试

虽然可以了,但是这样写不保险...

原因是那个中断是不定长的数据就进去(受到电脑整体运行状态的影响),所以呢咱优化下

        //串口接收到数据就会进入
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
int len = serialPort1.BytesToRead;//获取可以读取的字节数
if (len > )
{
byte[] recvBytes = new byte[len];//创建接收的数组
serialPort1.Read(recvBytes, , len);//接收数据 for (int i = ; i < len; i++)//拷贝数据到UsartReadBuff
{
UsartReadBuff[i+ UsartReadCnt] = recvBytes[i];//从上次的地方接着填入数据
}
UsartReadCnt = UsartReadCnt + len;//记录上次的数据个数
if (UsartReadCnt >= )//接收到可以处理的数据个数
{
UsartReadCnt = ;
if (UsartReadBuff[] == 0xaa && UsartReadBuff[] == 0x55)//判断数据
{
if (UsartReadBuff[] == 0x01)//
{
Invoke((new Action(() =>
{
button3.Text = "熄灭";
label5.Text = "点亮";
})));
}
else if (UsartReadBuff[] == 0x00)
{
Invoke((new Action(() =>
{
button3.Text = "点亮";
label5.Text = "熄灭";
})));
}
}
}
}
//string str = serialPort1.ReadExisting();//读出来当前缓存里面的所有数据
//Invoke((new Action(() =>
//{
// //显示在文本框里面
// textBox1.AppendText(str);
//})));
}

自己测试哈

现在说一下

如果接收的是字符串,想显示出来

如果发过来了16进制   注意哈,发过来的是16进制  假设 00  就是数字0   因为那个文本框显示的时候是显示的字符串

所以需要转成  "00"    发过来0F   需要显示字符串形式的  "0F"

给大家准备好了

        /// <字节数组转16进制字符串>
/// <param name="bytes"></param>
/// <returns> String 16进制显示形式</returns>
public static string byteToHexStr(byte[] bytes)
{
string returnStr = "";
try
{
if (bytes != null)
{
for (int i = ; i < bytes.Length; i++)
{
returnStr += bytes[i].ToString("X2");
returnStr += " ";//两个16进制用空格隔开,方便看数据
}
}
return returnStr;
}
catch (Exception)
{
return returnStr;
}
}
        //串口接收到数据就会进入
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
int len = serialPort1.BytesToRead;//获取可以读取的字节数
if (len > )
{
byte[] recvBytes = new byte[len];//创建接收的数组
serialPort1.Read(recvBytes, , len);//接收数据 Invoke((new Action(() =>//显示字符串
{
textBox1.AppendText("字符串:"+Encoding.Default.GetString(recvBytes)); //显示在文本框里面
}))); Invoke((new Action(() =>//显示16进制
{
textBox1.AppendText("\r\n16进制:" + byteToHexStr(recvBytes) + "\r\n"); //显示在文本框里面
}))); for (int i = ; i < len; i++)//拷贝数据到UsartReadBuff
{
UsartReadBuff[i+ UsartReadCnt] = recvBytes[i];//从上次的地方接着填入数据
}
UsartReadCnt = UsartReadCnt + len;//记录上次的数据个数
if (UsartReadCnt >= )//接收到可以处理的数据个数
{
UsartReadCnt = ;
if (UsartReadBuff[] == 0xaa && UsartReadBuff[] == 0x55)//判断数据
{
if (UsartReadBuff[] == 0x01)//
{
Invoke((new Action(() =>
{
button3.Text = "熄灭";
label5.Text = "点亮";
})));
}
else if (UsartReadBuff[] == 0x00)
{
Invoke((new Action(() =>
{
button3.Text = "点亮";
label5.Text = "熄灭";
})));
}
}
}
}
}

现在看发送

发送就只做字符串发送哈,,,16进制发送后期补上,,大家先吸收吸收现在的....

执行文件

我把16进制发送用到的函数放在这里,后期再回来加上

        /// <字符串转16进制格式,不够自动前面补零>
///
/// </summary>
/// <param name="hexString"></param>
/// <returns></returns>
private static byte[] strToToHexByte(String hexString)
{
int i;
bool Flag = false; hexString = hexString.Replace(" ", "");//清除空格
if ((hexString.Length % ) != )
{
Flag = true;
}
if (Flag == true)
{
byte[] returnBytes = new byte[(hexString.Length + ) / ]; try
{
for (i = ; i < (hexString.Length - ) / ; i++)
{
returnBytes[i] = Convert.ToByte(hexString.Substring(i * , ), );
}
returnBytes[returnBytes.Length - ] = Convert.ToByte(hexString.Substring(hexString.Length - , ).PadLeft(, ''), ); }
catch
{
for (i = ; i < returnBytes.Length; i++)
{
returnBytes[i] = ;
}
MessageBox.Show("超过16进制范围A-F,已初始化为0", "提示");
}
return returnBytes;
}
else
{
byte[] returnBytes = new byte[(hexString.Length) / ];
try
{
for (i = ; i < returnBytes.Length; i++)
{
returnBytes[i] = Convert.ToByte(hexString.Substring(i * , ), );
}
}
catch
{
for (i = ; i < returnBytes.Length; i++)
{
returnBytes[i] = ;
}
MessageBox.Show("超过16进制范围A-F,已初始化为0", "提示");
}
return returnBytes;
}
}

对了,其实上位机串口是有空闲时间中断的(异常捕获),只不过,我还没细研究呢!!!

https://www.cnblogs.com/yangfengwu/p/11094009.html

9-ESP8266 SDK开发基础入门篇--编写串口上位机软件的更多相关文章

  1. 8-ESP8266 SDK开发基础入门篇--编写串口上位机软件

    https://www.cnblogs.com/yangfengwu/p/11087558.html 咱用这个编写 ,版本都无所谓哈,只要自己有就可以,不同版本怎么打开 https://www.cnb ...

  2. 26-ESP8266 SDK开发基础入门篇--编写WIFI模块 SmartConfig/Airkiss 一键配网

    https://www.cnblogs.com/yangfengwu/p/11427504.html SmartConfig/Airkiss 配网需要APP/微信公众号,这节大家先使用我做好的APP/ ...

  3. 29-ESP8266 SDK开发基础入门篇--编写TCP 客户端程序(Lwip RAW模式,非RTOS版,精简入门)

    https://www.cnblogs.com/yangfengwu/p/11456667.html 由于上一节的源码长时间以后会自动断开,所以再做这一版非RTOS版的,咱直接用lua源码里面别人写的 ...

  4. 28-ESP8266 SDK开发基础入门篇--编写wifi模块TCP 客户端程序(官方API版,非RTOS版)

    https://www.cnblogs.com/yangfengwu/p/11432795.html 注:这节实现的功能是WIFI模块作为TCP 客户端,连接咱的TCP服务器,然后实现透传 本来想着做 ...

  5. 27-ESP8266 SDK开发基础入门篇--编写Android SmartConfig一键配网程序

    style="font-size: 18pt;">https://www.cnblogs.com/yangfengwu/p/11429007.html https://wik ...

  6. 22-ESP8266 SDK开发基础入门篇--编写Android TCP客户端 , 连接和断开

    https://www.cnblogs.com/yangfengwu/p/11192618.html 有些很细致的东西参考这篇   https://www.cnblogs.com/yangfengwu ...

  7. 23-ESP8266 SDK开发基础入门篇--编写Android TCP客户端 , 加入消息处理

    https://www.cnblogs.com/yangfengwu/p/11203546.html 先做接收消息 然后接着 public class MainActivity extends App ...

  8. 1-ESP8266 SDK开发基础入门篇--开发环境搭建

    因为今天终于做好了自己的另一块工控板,所以我就开始写基础公开篇的内容,希望自己小小的努力能够帮到大家 自己做的另一块板子 https://www.cnblogs.com/yangfengwu/cate ...

  9. 25-ESP8266 SDK开发基础入门篇--控制WIFI连接路由器

    https://www.cnblogs.com/yangfengwu/p/11324411.html 说个事情,现在SDK的版本已经出到3.0了,但是我还是使用2.0 如果只是为了学习研究   选择3 ...

随机推荐

  1. 转!!通俗理解数字加密,数字签名,数字证书和https

    原博文地址:https://www.jianshu.com/p/4932cb1499bf 前言 最近在开发关于PDF合同文档电子签章的功能,大概意思就是在一份PDF合同上签名,盖章,使其具有法律效应. ...

  2. 全栈项目|小书架|服务器端-NodeJS+Koa2 实现书籍详情接口

    通过上篇文章 全栈项目|小书架|微信小程序-首页水平轮播实现 我们实现了前端(小程序)效果图的展示,这篇文章来介绍服务器端的实现. 书籍详情分析 书籍详情页面如下: 从上图可以分析出详情页面大概有以下 ...

  3. 深度剖析java中JDK动态代理机制

    https://www.jb51.net/article/110342.htm 本篇文章主要介绍了深度剖析java中JDK动态代理机制 ,动态代理避免了开发人员编写各个繁锁的静态代理类,只需简单地指定 ...

  4. spring Boot 学习(四、Spring Boot与任务)

    一.异步任务 在Java应用中,绝大多数情况下都是通过同步的方式来实现交互处理的:但是在 处理与第三方系统交互的时候,容易造成响应迟缓的情况,之前大部分都是使用 多线程来完成此类任务,其实,在Spri ...

  5. JavaScript判断是否是正确数值 isNaN

    NaN在JavaScript中表示不是数字 JavaScript中isNaN函数方法是返回一个 Boolean 值,指明提供的值是否是保留值 NaN (不是数字). 使用方法:isNaN(numVal ...

  6. js中cssText批量修改元素样式

    平常编写代码,更改一个元素样式的时候,自己都是用 obj.style.width = "200px"; obj.style.position = "absolute&qu ...

  7. Shallow copy and Deep copy

    Shallow copy and Deep copy 第一部分: 一.来自wikipidia的解释: Shallow copy One method of copying an object is t ...

  8. 【转载】TX - row lock contention 的一些场景

    TX - row lock contention 的一些场景 原创 2016-07-11 易欣 云和恩墨 易欣(Eson) 云和恩墨技术专家 本文整理来自7月7日周四晚云和恩墨大讲堂嘉宾易欣分享的主题 ...

  9. centos7 docker安装Jenkins BlueOcean

    Jenkins是一款Java开发的跨平台持续集成和持续发布的开源项目,Jenkins已经作为各大公司进行CI/CD的首选工具.而BlueOcean是Jenkins推出的一个插件,其目的就是让程序员执行 ...

  10. MySQL MHA--故障切换模式(GTID模式和非GTID模式)

    GTID和非GTID故障切换模式选择 MySQL 5.6版本引入GTID来解决主从切换时BINLOG位置点难定位的问题,MHA从0.56版本开始支持基于GTID的复制,在切换时可以采用GTID模式和非 ...