zoukankan      html  css  js  c++  java
  • C#和Modbus通信工程

    先介绍一下,这个项目是Modbus和C#关于声音播放器的内容。这篇文章介绍的事ModBus中串口的协议,相信看到这篇文章的都知道ModBus协议,先介绍主流的两种串口和TCP协议。
    下载虚拟串口软件地址:https://files.cnblogs.com/files/wxylovejx/%E8%99%9A%E6%8B%9F%E4%B8%B2%E5%8F%A3VSPD6.9.zip

    下载调试精灵软件地址:

    https://files.cnblogs.com/files/wxylovejx/Modbus%E8%B0%83%E8%AF%95%E7%B2%BE%E7%81%B5-%E7%9B%91%E8%A7%86%E8%B0%83%E8%AF%95%E4%B8%B2%E5%8F%A3%E7%A8%8B%E5%BA%8FV1.024.zip


    关于Modbus的内容就不多介绍,我介绍也是去网上查,可以先去查一下Modbus原理。

    根据CModbusSlave类。先行下载研究类库:里面有方法读取,编写。根据读取寄存器内容(一个和多个)对应方法。CModbusSlave类下载地址:项目中包含

    C#连接串口:

    private static void ThreadSendCom()
    {
    Form1 operform2 = Form1.Instance();
    while (true)//线程一直在发送,主程序做好标记,
    {
    //开始读写模块,功能16写
    //把数字量模拟量进行IO分配。
    Writing = false;
    if (MainAskForStop)
    {
    Thread.Sleep(100);
    continue;
    }
    try
    {
    if (!operform2.myserialPort.IsOpen)//避免这个访问无效
    Thread.Sleep(500);
    else if (operform2.myserialPort.IsOpen)//只要代开串口了,就发
    {
    Writing = true;
    //Zigbee no need
    //等待80ms,实际上可以更快,但是一定是完成通信后再继续。如果无法完成。在
    //多个模块时,后续无法通信,干脆一直等待。AS3730模块程序可能有问题,有时需要
    //关闭,打开串口才能通信。
    if (ReciveOK)//20170521,如果没有收到就无限等待。避免485冲突,以后修改为以太网的。
    {
    //CModbusMasterAndModelConfig.SendDataToAS3700(operform2.myserialPort,0);
    if (MainAskForStop)
    {
    Writing = false;
    break;//直接跳出
    }
    Form1.SendCounter++;//每个模块一次
    //SendID[ModelIndex] = 3;//标记
    ReciveOK = false;
    Thread.Sleep(80);
    while (ReciveOK == false && MainAskForStop == false)//不断等待
    {
    Thread.Sleep(80);//20170521总是AS3700错误,修改到2倍等待时间。,增加到120,8个模块,880ms。以前80ms,等待100ms,再次发送。要求模块不要超过10个,而且模块的返回时间不要超过150ms
    }
    }
    else if (MainAskForStop == false)
    {
    Thread.Sleep(80);
    }

    Writing = false;
    }
    }
    catch (Exception ew1)
    {
    Debug.WriteLine(ew1.ToString());
    Writing = false;
    }
    }//while串口打开的,就不断执行,否则退出。
    }

    private void OpenComm()
    {
    //if (MasterComPort > 0 && MasterComPort < 255)
    //{
    // try
    // {
    // //lock (m_locker)
    // //{
    // if (myserialPort.IsOpen)
    // {
    // myserialPort.Close(); //如果是打开的,则关闭一次
    // }
    // myserialPort.PortName = "COM" + MasterComPort.ToString();
    // myserialPort.BaudRate = 115200;// 20160525修改为115200,以前是9600;
    // myserialPort.Parity = Parity.None;
    // myserialPort.DataBits = 8;
    // myserialPort.StopBits = StopBits.One;
    // myserialPort.Encoding = Encoding.ASCII;// Encoding.ASCII;
    // myserialPort.ReceivedBytesThreshold = 1;//一个数据就中断
    // myserialPort.WriteTimeout = 1000;
    // myserialPort.ReadTimeout = 1000;
    // //打开串口,主站采用线程不断发送
    // if (myserialPort.IsOpen == false)//如果=0,可能没有设置,就没有从站
    // {
    // myserialPort.Open();
    // if (thIsStart == false)
    // {
    // Thread th = new Thread(new ThreadStart(ThreadSendCom)); //也可简写为new Thread(ThreadMethod);
    // th.Name = "CIS_AS3700_COM_SEND";
    // th.Start(); //启动线程
    // thIsStart = true;//只启动一次
    // }
    // }
    // //}

    // }
    // catch (Exception ew1)
    // {
    // if (hadShowComError == false)
    // {
    // MessageBox.Show("指定的IO模块通信串口COM" + MasterComPort + "异常,可能不存在或已经打开", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Warning);
    // hadShowComError = true;
    // }
    // Debug.WriteLine(ew1.ToString());
    // }
    //}
    if (SlaveComPort > 0 && SlaveComPort < 255)
    {
    if (myserialPortS.IsOpen) myserialPortS.Close(); //如果是打开的,则关闭一次
    myserialPortS.PortName = "COM" + SlaveComPort.ToString();
    myserialPortS.BaudRate = 115200;// 20160525修改为115200,以前是9600;
    myserialPortS.Parity = Parity.None;
    myserialPortS.DataBits = 8;
    myserialPortS.StopBits = StopBits.One;
    myserialPortS.Encoding = Encoding.ASCII;
    myserialPortS.ReceivedBytesThreshold = 1;
    //打开从站串口,但是没有必要开启线程。
    try
    {
    if (myserialPortS.IsOpen == false)
    {
    myserialPortS.Open();
    }
    }
    catch (Exception ew2)
    {
    if (hadShowComError == false)
    {
    MessageBox.Show("指定的Modbus从站串口" + SlaveComPort + "异常,可能不存在或已经打开", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Warning);
    hadShowComError = true;
    }
    }
    }
    }

     C#接受数据:

    private void myserialPortS_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
    {
    SerialPort a = myserialPortS;//传递到静态的CModbusSlave

    try//20170626出现串口是关闭的。
    {
    byte[] b = new byte[myserialPortS.BytesToRead];//定义byte数组,serialPort读取数据
    myserialPortS.Read(b, 0, b.Length);
    bufferSlave.AddRange(b);
    if (bufferSlave.Count >= 8) //数据超过45个,所以一定要返回20个数据。0,0,0
    {//进行从站分析,并发送数据。
    //byte SoundfileIndex = bufferSlave.ToArray()[5];
    //if (SoundfileIndex == 1)
    //{
    // var p3 = new System.Windows.Media.MediaPlayer();
    // p3.Open(new System.Uri("C:\Users\Administrator\Desktop\sound\到站提示音.mp3"));
    // p3.Play();
    //}
    //if(SoundfileIndex==2)
    //{
    // var p3 = new System.Windows.Media.MediaPlayer();
    // p3.Open(new System.Uri("C:\Users\Administrator\Desktop\8960.wav"));
    // p3.Play();
    //}
    //var p = new System.Windows.Media.MediaPlayer();
    if (CModbusSlave.checkComm0Modbus(a, bufferSlave.ToArray(), (UInt16)(bufferSlave.Count))=="0")
    {

    //p.Open(new System.Uri("C:\Users\Administrator\Desktop\sound\地铁关门报警声.mp3"));
    // p.Stop();
    wmp.controls.stop();
    }
    if (CModbusSlave.checkComm0Modbus(a, bufferSlave.ToArray(), (UInt16)(bufferSlave.Count)) == "1")
    {
    //p.Open(new System.Uri("C:\Users\Administrator\Desktop\sound\地铁关门报警声.mp3"));
    //p.Play();
    // wmp.URL = "C:\Users\Administrator\Desktop\sound\地铁关门报警声.mp3";
    wmp.URL =listView1.Items[0].Tag.ToString();
    wmp.controls.play();
    }
    if (CModbusSlave.checkComm0Modbus(a, bufferSlave.ToArray(), (UInt16)(bufferSlave.Count)) == "2")
    {
    //p.Open(new System.Uri("C:\Users\Administrator\Desktop\sound\火车到站鸣笛声.mp3"));
    //p.Play();
    wmp.URL = listView1.Items[1].Tag.ToString();
    wmp.controls.play();

    }
    if (CModbusSlave.checkComm0Modbus(a, bufferSlave.ToArray(), (UInt16)(bufferSlave.Count)) == "3")
    {

    wmp.URL = listView1.Items[2].Tag.ToString();
    wmp.controls.play();
    }
    if (CModbusSlave.checkComm0Modbus(a, bufferSlave.ToArray(), (UInt16)(bufferSlave.Count)) == "4")
    {

    wmp.URL = listView1.Items[3].Tag.ToString();
    wmp.controls.play();
    }
    if (CModbusSlave.checkComm0Modbus(a, bufferSlave.ToArray(), (UInt16)(bufferSlave.Count)) == "5")
    {

    wmp.URL = listView1.Items[4].Tag.ToString();
    wmp.controls.play();
    }
    if (CModbusSlave.checkComm0Modbus(a, bufferSlave.ToArray(), (UInt16)(bufferSlave.Count)) == "6")
    {

    wmp.URL = listView1.Items[5].Tag.ToString();
    wmp.controls.play();
    }

    bufferSlave.RemoveRange(0, bufferSlave.Count);//全部删除
    }
    }
    catch (Exception ew1)
    {
    }
    }

    项目下载地址:https://files.cnblogs.com/files/wxylovejx/SoundPlayback.zip

    不要让过去的自己,绑架现在的自己。不要让现在的自己,讨厌未来的自己。不要让未来的你,后悔现在的自己。
  • 相关阅读:
    107、Java中String类之判断开头或结尾
    106、Java中String类之使用contains()方法判断子字符串是否存在
    105、Java中String类之利用indexOf()方法判断子字符串是否存在
    104、Java中String类之使用indexOf()等功能查找
    103、Java中String类之compareTo()方法
    102、Java中String类之相等判断(忽略大小写)
    101、Java中String类之判断是否由数字组成
    100、Java中String类之字符串转为大写
    099、Java中String类之字符数组与字符串的转换
    098、Java中String类之charAt()方法
  • 原文地址:https://www.cnblogs.com/wxylovejx/p/8384825.html
Copyright © 2011-2022 走看看