獲取傳感器消息通過mqtt通訊傳給網頁前端

      網友投稿 945 2022-05-28

      標題雖然這么長,但是做法卻十分簡單 總共分為兩個步驟 第一:獲取傳感器消息 第二:傳給mqtt網絡 第三:網頁根據mqtt消息采取動作 總結:就是硬件上面操作,網頁上實時查看硬件的操作動作 我們先來看第一個:獲取傳感器消息 首先看一下c#中對于串口通訊的操作(急于實現功能的各位可以跳過直接看下面的源碼)

      SerialPort類的常用屬性

      名  稱

      說  明

      BaseStream

      獲取 SerialPort 對象的基礎 Stream 對象

      BaudRate

      獲取或設置串行波特率

      BreakState

      獲取或設置中斷信號狀態

      BytesToRead

      獲取發送緩沖區中數據的字節數

      獲取傳感器消息通過mqtt通訊傳給網頁前端

      BytesToWrite

      獲取端口的載波檢測行的狀態

      CDHolding

      獲取“可以發送”行的狀態

      CtsHolding

      獲取或設置每個字節的標準數據位長度

      DiscardNull

      獲取或設置一個值,該值指示 Null 字節在端口和接收緩沖區之間傳輸時是否被忽略

      DsrHolding

      獲取數據設置就緒 (DSR) 信號的狀態

      DtrEnable

      獲取或設置一個值,該值在串行通信過程中啟用數據終端就緒 (DTR) 信號

      Encoding

      獲取或設置傳輸前后文本轉換的字節編碼

      Handshake

      獲取或設置串行端口數據傳輸的握手協議

      IsOpen

      獲取一個值,該值指示 SerialPort 對象的打開或關閉狀態

      NewLine

      獲取或設置用于解釋 ReadLine( )和WriteLine( )方法調用結束的值

      Parity

      獲取或設置奇偶校驗檢查協議

      ParityReplace

      獲取或設置一個字節,該字節在發生奇偶校驗錯誤時替換數據流中的無效字節

      PortName

      獲取或設置通信端口,包括但不限于所有可用的 COM 端口

      ReadBufferSize

      獲取或設置 SerialPort 輸入緩沖區的大小

      ReadTimeout

      獲取或設置讀取操作未完成時發生超時之前的毫秒數

      ReceivedBytesThreshold

      獲取或設置 DataReceived 事件發生前內部輸入緩沖區中的字節數

      RtsEnable

      獲取或設置一個值,該值指示在串行通信中是否啟用請求發送 (RTS) 信號

      StopBits

      獲取或設置每個字節的標準停止位數

      WriteBufferSize

      獲取或設置串行端口輸出緩沖區的大小

      WriteTimeout

      獲取或設置寫入操作未完成時發生超時之前的毫秒數

      名  稱

      說  明

      Close

      關閉端口連接,將 IsOpen 屬性設置為False,并釋放內部 Stream 對象

      Open

      從 SerialPort 輸入緩沖區中讀取

      Read

      從 SerialPort 輸入緩沖區中讀取

      ReadByte

      從 SerialPort 輸入緩沖區中同步讀取一個字節

      ReadChar

      從 SerialPort 輸入緩沖區中同步讀取一個字符

      ReadLine

      一直讀取到輸入緩沖區中的 NewLine 值

      ReadTo

      一直讀取到輸入緩沖區中指定 value 的字符串

      Write

      已重載。將數據寫入串行端口輸出緩沖區

      WriteLine

      將指定的字符串和 NewLine 值寫入輸出緩沖區

      首先要添加

      using System.IO; using System.IO.Ports;

      1...在類的內部定義SerialPort com;

      2...打開串口

      com = new SerialPort(); com.BaudRate = 115200; com.PortName = "COM1"; com.DataBits = 8; com.Open();//打開串口

      3...發送數據

      Byte[] TxData ={1,2,3,4,5,6,7,8 }; com.Write(TxData, 0, 8);

      4...接收數據 見下方源碼

      using System; using System.IO.Ports; using System.Linq; using System.Management; using System.Threading; using System.Windows.Forms; namespace CefSharp.MinimalExample.WinForms { public static class COMCtrl { public static string portName = ""; public static int baudRate = 115200; public static Parity parity = Parity.None; public static int dataBits = 8; public static StopBits stopBits = StopBits.One; public static string[] data;//用于存儲6位數據 static SerialPort sp = null;//串口控制 public static string sensorNum = "";//傳感器的序號 static CalcOnCrc16 OnCrc16; public static string audioName; public static void Init() { OnCrc16 = new CalcOnCrc16(); portName = GetPortName(); OpenPort(); } #region 打開與關閉端口 //獲取 static string GetPortName() { string i = GetComNum().ToString(); return "COM" + i; } //打開端口 public static void OpenPort() { sp = new SerialPort(portName, baudRate, parity, dataBits, stopBits); try { sp.Open(); sp.ReadTimeout = 400; } catch (Exception ex) { MessageBox.Show(ex.Message); } } //關閉端口 public static void ClosePort() { try { sp.Close(); } catch (Exception ex) { MessageBox.Show("端口關閉失敗" + ex.Message); } } #endregion static string Lock_Str = "Lock"; #region 獲取端口號 public static int GetComNum() { int comNum = -1; string[] strArr = GetHarewareInfo(HardwareEnum.Win32_PnPEntity, "Name"); foreach (string s in strArr) { if (s.Length >= 23 && s.Contains("CH340")) { int start = s.IndexOf("(") + 3; int end = s.IndexOf(")"); comNum = Convert.ToInt32(s.Substring(start + 1, end - start - 1)); } } return comNum; } private static string[] GetHarewareInfo(HardwareEnum hardType, string propKey) { System.Collections.Generic.List strs = new System.Collections.Generic.List(); try { using (ManagementObjectSearcher searcher = new ManagementObjectSearcher("select * from " + hardType)) { var hardInfos = searcher.Get(); foreach (var hardInfo in hardInfos) { if (hardInfo.Properties[propKey].Value != null) { String str = hardInfo.Properties[propKey].Value.ToString(); strs.Add(str); } } } return strs.ToArray(); } catch { return null; } finally { strs = null; } } public enum HardwareEnum { // 硬件 Win32_Processor, // CPU 處理器 Win32_PhysicalMemory, // 物理內存條 Win32_Keyboard, // 鍵盤 Win32_PointingDevice, // 點輸入設備,包括鼠標。 Win32_FloppyDrive, // 軟盤驅動器 Win32_DiskDrive, // 硬盤驅動器 Win32_CDROMDrive, // 光盤驅動器 Win32_BaseBoard, // 主板 Win32_BIOS, // BIOS 芯片 Win32_ParallelPort, // 并口 Win32_SerialPort, // 串口 Win32_SerialPortConfiguration, // 串口配置 Win32_SoundDevice, // 多媒體設置,一般指聲卡。 Win32_SystemSlot, // 主板插槽 (ISA & PCI & AGP) Win32_USBController, // USB 控制器 Win32_NetworkAdapter, // 網絡適配器 Win32_NetworkAdapterConfiguration, // 網絡適配器設置 Win32_Printer, // 打印機 Win32_PrinterConfiguration, // 打印機設置 Win32_PrintJob, // 打印機任務 Win32_TCPIPPrinterPort, // 打印機端口 Win32_POTSModem, // MODEM Win32_POTSModemToSerialPort, // MODEM 端口 Win32_DesktopMonitor, // 顯示器 Win32_DisplayConfiguration, // 顯卡 Win32_DisplayControllerConfiguration, // 顯卡設置 Win32_VideoController, // 顯卡細節。 Win32_VideoSettings, // 顯卡支持的顯示模式。 // 操作系統 Win32_TimeZone, // 時區 Win32_SystemDriver, // 驅動程序 Win32_DiskPartition, // 磁盤分區 Win32_LogicalDisk, // 邏輯磁盤 Win32_LogicalDiskToPartition, // 邏輯磁盤所在分區及始末位置。 Win32_LogicalMemoryConfiguration, // 邏輯內存配置 Win32_PageFile, // 系統頁文件信息 Win32_PageFileSetting, // 頁文件設置 Win32_BootConfiguration, // 系統啟動配置 Win32_ComputerSystem, // 計算機信息簡要 Win32_OperatingSystem, // 操作系統信息 Win32_StartupCommand, // 系統自動啟動程序 Win32_Service, // 系統安裝的服務 Win32_Group, // 系統管理組 Win32_GroupUser, // 系統組帳號 Win32_UserAccount, // 用戶帳號 Win32_Process, // 系統進程 Win32_Thread, // 系統線程 Win32_Share, // 共享 Win32_NetworkClient, // 已安裝的網絡客戶端 Win32_NetworkProtocol, // 已安裝的網絡協議 Win32_PnPEntity,//all device } #endregion //發送數據 public static void WriteData(byte[] bys) { if (sp.IsOpen) { sp.Write(bys, 0, bys.Length); //需要延遲執行接收程序 Thread.Sleep(50); lock (Lock_Str) { DataReceiveFunction(); } } } //獲取傳感器狀態 public static void GetSensorState() { //發送獲取傳感器代碼 WriteData(strToToHexByte("01 02 00 00 00 1E F8 02")); } //TO => 16進制 public static byte[] strToToHexByte(string hexString) { hexString = hexString.Replace(" ", ""); if ((hexString.Length % 2) != 0) hexString += " "; byte[] returnBytes = new byte[hexString.Length / 2]; for (int i = 0; i < returnBytes.Length; i++) returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16); return returnBytes; } //接收消息 #region constanc static byte[] MSG;//接收到硬件返回的字符 static byte[] buffer = new byte[1024];//硬件返回數組的緩存空間 static int buffLength = 0; static string Allbytes = ""; static string CheckCRC = ""; static string oldStr = "00000000000000000000000000000000"; //舊字符 static string newStr= "00000000000000000000000000000000"; //新字符 #endregion public static void DataReceiveFunction() { if (sp != null && sp.IsOpen) { try { Array.Clear(buffer, 0, buffer.Length); buffLength = sp.Read(buffer, 0, buffer.Length); MSG = new byte[buffLength - 2]; Array.Copy(buffer, 0, MSG, 0, buffLength - 2); //MCU返回的字符串轉換為十六進制輸出 for (int i = 0; i < buffLength; i++) { Allbytes += buffer[i].ToString("X2") + " "; } //MessageBox .Show (buffLength + "--------" + Allbytes); //切割后2位的字符串,用來crc校驗 string Checkbytes = ""; for (int i = 0; i < MSG.Length; i++) { Checkbytes += MSG[i].ToString("X2") + " "; } CheckCRC += buffer[buffLength - 1].ToString("X2"); CheckCRC += buffer[buffLength - 2].ToString("X2"); //BrowserForm.browserForm.RecMqttMsg.Text = CheckCRC ; //MessageBox .Show("CRC16計算:" + OnCrc16.CRC16(MSG).ToString("X4")); if (CheckCRC == (OnCrc16.CRC16(MSG).ToString("X4"))) { CheckCRC = ""; byte[] reverse = new byte[4]; //硬件返回的傳感器反序數組 Array.Copy(MSG, 3, reverse, 0, 4); byte[] forward = new byte[4]; //傳感器正向數組 for (int i = 0; i < 4; i++) { forward[i] = reverse[reverse.Count() - i - 1]; } string sensorStr = ""; for (int i = 0; i < 4; i++) { sensorStr += Convert.ToString(forward[i], 2).PadLeft(8, '0');//一位16進制的數轉換為8個單位 } newStr = ReverseD(sensorStr); //字符串有變化開始推送消息 if (newStr.CompareTo(oldStr) == 0) { } else { oldStr = newStr; //int i = oldStr.IndexOf("1"); //if (i != -1) //{ BrowserForm.browserForm.RecMqttMsg.Text = oldStr; //發送消息 MqttCtrl.client_sendMsg(oldStr); //} } } else { Console.WriteLine("檢測未通過!"); } Array.Clear(MSG, 0, MSG.Length); } catch (Exception ex) { Array.Clear(MSG, 0, MSG.Length); MessageBox.Show(ex.Message); //如果出錯就再調用一次 //DataReceiveFunction(); //MessageBox.Show("串口出錯!"); } } else { MessageBox.Show("串口意外關閉!"); } } public static string ReverseD(string text) { return new string(text.ToCharArray().Reverse().ToArray()); } public static void RequestSensor(string Number) { try { int number = int.Parse(Number); char state; state = oldStr[number]; MqttCtrl.client_sendMsg("SZYL:"+Number + "-" + state.ToString()); } catch (Exception) { throw; } } } }

      里面還有一個crc檢驗

      using System; namespace CefSharp.MinimalExample.WinForms { public class CalcOnCrc16 { public ushort CRC16(byte[] bytes) { ushort value; ushort newLoad = 0xffff, In_value; int count = 0; for (int i = 0; i < bytes.Length; i++) { value = (ushort)bytes[i]; newLoad = (ushort)(Convert.ToInt32(value) ^ Convert.ToInt32(newLoad)); In_value = 0xA001; while (count < 8) { if (Convert.ToInt32(newLoad) % 2 == 1)//判斷最低位是否為1 { newLoad -= 0x00001; newLoad = (ushort)(Convert.ToInt32(newLoad) / 2);//右移一位 count++;//計數器加一 newLoad = (ushort)(Convert.ToInt32(newLoad) ^ Convert.ToInt32(In_value));//異或操作 } else { newLoad = (ushort)(Convert.ToInt32(newLoad) / 2);//右移一位 count++;//計數器加一 } } count = 0; } return newLoad; } } }

      PS:這個單片機是我請求一次,它才發回消息,不是主動的發,所以我的程序里面還有計時器循環請求狀態. 下面就是發送到mqtt消息平臺,首先接收

      教程是這里的,如果看不懂直接看我源碼 https://help.aliyun.com/document_detail/59721.html?spm=a2c4g.11186623.6.590.666432b1pvEQrL

      using System; using System.Security.Cryptography; using System.Text; using System.Windows.Forms; using uPLibrary.Networking.M2Mqtt; using uPLibrary.Networking.M2Mqtt.Messages; namespace CefSharp.MinimalExample.WinForms { public class MqttCtrl { // //實例 ID,購買后從控制臺獲取 //static String instanceId = " "; // //此處填寫購買得到的 MQTT 接入點域名 // static String brokerUrl = " "; // //此處填寫阿里云帳號 AccessKey // static String accessKey = " "; // //此處填寫阿里云帳號 SecretKey // static String secretKey = ""; // //此處填寫在 MQ 控制臺創建的 Topic,作為 MQTT 的一級 Topic // static String parentTopic = " "; // //此處填寫客戶端 ClientId,需要保證全局唯一,其中前綴部分即 GroupId 需要先在 MQ 控制臺創建 // static String clientId = " " + DateTime.Now.Ticks.ToString(); // static MqttClient client = new MqttClient(brokerUrl); //實例 ID,購買后從控制臺獲取 static String instanceId = " "; //此處填寫購買得到的 MQTT 接入點域名 static String brokerUrl = " "; //此處填寫阿里云帳號 AccessKey static String accessKey = " "; //此處填寫阿里云帳號 SecretKey static String secretKey = ""; //此處填寫在 MQ 控制臺創建的 Topic,作為 MQTT 的一級 Topic static String parentTopic = "SJJK"; //此處填寫客戶端 ClientId,需要保證全局唯一,其中前綴部分即 GroupId 需要先在 MQ 控制臺創建 static String clientId = " " + DateTime.Now.Ticks.ToString(); static MqttClient client = new MqttClient(brokerUrl); public static void Init() { client.MqttMsgPublishReceived += client_recvMsg; client.MqttMsgPublished += client_publishSuccess; client.ConnectionClosed += client_connectLose; //username和 Password 簽名模式下的設置方法,參考文檔 https://help.aliyun.com/document_detail/48271.html?spm=a2c4g.11186623.6.553.217831c3BSFry7 String userName = "Signature|" + accessKey + "|" + instanceId; String passWord = HMACSHA1(secretKey, clientId); client.Connect(clientId, userName, passWord, true, 60); //訂閱 Topic,支持多個 Topic,以及多級 Topic //string[] subTopicArray = { parentTopic + "/SamJan", parentTopic + "/subDemo2/level3" }; string[] subTopicArray = { parentTopic + "/SamJan", parentTopic + "/SensorState" }; //string[] subTopicArray = { parentTopic + "/SensorState" }; byte[] qosLevels = { MqttMsgBase.QOS_LEVEL_AT_MOST_ONCE, MqttMsgBase.QOS_LEVEL_AT_MOST_ONCE }; //訂閱 client.Subscribe(subTopicArray, qosLevels); //client.Publish(parentTopic + "/SamJan", Encoding.UTF8.GetBytes("hello mqtt,尚哲智能"), MqttMsgBase.QOS_LEVEL_AT_LEAST_ONCE, false); //發送 P2P 消息,二級 topic 必須是 p2p,三級 topic 是接收客戶端的 clientId //client.Publish(parentTopic + "/p2p/" + clientId, Encoding.UTF8.GetBytes("(P2P) hello mqtt"), MqttMsgBase.QOS_LEVEL_AT_LEAST_ONCE, false); //System.Threading.Thread.Sleep(10000); //client.Disconnect(); } // public static void client_sendMsg(string msg) { client.Publish(parentTopic + "/SamJan", Encoding.UTF8.GetBytes(msg), MqttMsgBase.QOS_LEVEL_AT_LEAST_ONCE, false); } static void client_sendMsgByP2P(string msg) { client.Publish(parentTopic + "/p2p/" + clientId, Encoding.UTF8.GetBytes(msg), MqttMsgBase.QOS_LEVEL_AT_LEAST_ONCE, false); } static void client_disConnect() { client.Disconnect(); } static void client_recvMsg(object sender, MqttMsgPublishEventArgs e) { // access data bytes throug e.Message //MessageBox.Show("Recv Msg : Topic is " + e.Topic + " ,Body is " + Encoding.UTF8.GetString(e.Message)); if (e.Topic == "SJJK/SensorState") { COMCtrl.RequestSensor(Encoding.UTF8.GetString(e.Message)); } } static void client_publishSuccess(object sender, MqttMsgPublishedEventArgs e) { // access data bytes throug e.Message Console.WriteLine("Publish Msg Success"); } static void client_connectLose(object sender, EventArgs e) { // access data bytes throug e.Message Console.WriteLine("Connect Lost,Try Reconnect"); Init(); } public static string HMACSHA1(string key, string dataToSign) { Byte[] secretBytes = UTF8Encoding.UTF8.GetBytes(key); HMACSHA1 hmac = new HMACSHA1(secretBytes); Byte[] dataBytes = UTF8Encoding.UTF8.GetBytes(dataToSign); Byte[] calcHash = hmac.ComputeHash(dataBytes); String calcHashString = Convert.ToBase64String(calcHash); return calcHashString; } } }

      官方Demo: https://code.aliyun.com/aliware_mqtt/mqtt-demo/tree/master?spm=a2c4g.11186623.2.38.4181775ewvOQVo

      與前端妹子溝通好,你們就可以愉快的吵架了.

      MQTT web前端 硬件開發

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:深度學習入門篇,簡單的實例講明白圖像分類。
      下一篇:【愚公系列】2022年03月 漏洞掃描與利用之AWVS
      相關文章
      亚洲综合精品一二三区在线| 亚洲AV电影院在线观看| 亚洲第一视频网站| 亚洲无线观看国产精品| 久久久久亚洲AV成人网人人软件| 亚洲精品成人区在线观看| 亚洲乱理伦片在线观看中字| 亚洲偷自拍另类图片二区| 亚洲人成自拍网站在线观看 | 亚洲高清国产拍精品青青草原| 亚洲精品无码久久久久久| 亚洲精品无码久久久久久 | 国产成人亚洲精品青草天美| 久久亚洲综合色一区二区三区| 精品久久香蕉国产线看观看亚洲| 亚洲av中文无码乱人伦在线咪咕| 国产AV无码专区亚洲Av| 亚洲av无码成h人动漫无遮挡| 亚洲好看的理论片电影| 666精品国产精品亚洲 | 亚洲国产电影在线观看| 亚洲AV无码国产精品色| 亚洲人成77777在线播放网站不卡 亚洲人成77777在线观看网 | 色噜噜AV亚洲色一区二区| 国产亚洲一区二区三区在线| 亚洲av日韩av高潮潮喷无码| 亚洲视频在线观看视频| 亚洲一区二区三区四区视频| 亚洲日本在线电影| 亚洲国产美女精品久久久 | 亚洲天天做日日做天天欢毛片| 中文字幕亚洲精品资源网| 亚洲成人免费电影| 亚洲色偷偷色噜噜狠狠99 | 亚洲黄色免费在线观看| 亚洲精品福利你懂| 亚洲AV无码国产剧情| 久久亚洲2019中文字幕| 亚洲成a人片在线观看中文动漫 | 免费亚洲视频在线观看| 国产日产亚洲系列|