工业协议

 工业通讯

1.串口通信

"github.com/tarm/serial"

package main

 

import (

         "encoding/hex"

         "fmt"

         "github.com/tarm/serial"

         "strconv"

         "time"

)

 

func SensorInfo() ([10]bool, [10]float64, [10]float64) {

         var existPeople [10]bool

         var temperature [10]float64

         var humidity [10]float64

 

         config := &serial.Config{

                  Name: "/dev/ttyUSB0",

                  Baud: 115200,

         }

        

         fmt.Println("打开端口中...")

         s, err := serial.OpenPort(config)

         checkErr(err)

         defer s.Close()

         bufTemp := make([]byte, 11)

 

         // 获取50条数据(未处理)

         var rawStrList []string

         for i := 0; i < 50; i++ {

                  fmt.Print("【读取数据中...】")

                  num, err := s.Read(bufTemp)

                  checkErr(err)

                  if num > 0 {

                          strTemp := hex.EncodeToString(bufTemp)

                          fmt.Println(strTemp)

                          rawStrList = append(rawStrList, strTemp)

                  }

         }

        

         // 获取所有硬件的地址(为了从中筛选出温湿度传感器信息)

         var mapTemp map[string]int

         mapTemp = make(map[string]int)

         for i := 0; i < len(rawStrList); i++ {

                  if _, ok := mapTemp[rawStrList[i][10:16]]; ok {

                          mapTemp[rawStrList[i][10:16]]++

                  } else {

                          mapTemp[rawStrList[i][10:16]] = 1

                  }

         }

        

         // 调用 getCorrentAddr() 获取温湿度传感器的地址

         hmdtAddr, teprtAddr := getCorrentAddr(mapTemp)

         tmpIndex := 0

         hmdtIndex := 0

         expIndex := 0

         for i, value := range rawStrList {

                  fmt.Print("【INFO】teprtAddr:" + teprtAddr + " " + "hmdtAddr:" + hmdtAddr)

                  fmt.Println(" value[10:16]:" + value[10:16] + " " + value[18:20] + " " + rawStrList[i][16:18])

                  if tmpIndex < 10 && value[10:16] == teprtAddr {

                          temperatureTemp, err := strconv.ParseInt(value[18:20]+rawStrList[i][16:18], 16, 32)

                          checkErr(err)

                          temperature[tmpIndex] = float64(temperatureTemp) / 100.0

                          tmpIndex++

                  }

                  if hmdtIndex < 10 && value[10:16] == hmdtAddr {

                          humidityTemp, err := strconv.ParseInt(value[18:20]+rawStrList[i][16:18], 16, 32)

                          checkErr(err)

                          humidity[hmdtIndex] = float64(humidityTemp) / 100.0

                          hmdtIndex++

                  }

                  if expIndex < 10 && value[20:22] == "00" {

                          if value[16:18] == "00" {

                                   existPeople[expIndex] = true

                                   expIndex++

                          } else {

                                   existPeople[expIndex] = false

                                   expIndex++

                          }

                  }

         }

        

         // 返回采集到的信息

         return existPeople, temperature, humidity

}

 

func main() {

         // 测试。每 5 min 采集一次

         test()

}

 

func test(){

         for true{

                  fmt.Println("【INFO】采集数据中...")

                  esists, hmdts, tprts := SensorInfo(); // 采集数据

                  for i:=0; i<10; i++ {

                          fmt.Println("【INFO】教室",i+1,"温度:", float32(tprts[i]), " 湿度:", float32(hmdts[i]), " 有人:",esists[i])

                  }

                  fmt.Println("【INFO】数据更新成功!")

                  // 线程休眠 5 min

                  time.Sleep(time.Duration(100)*time.Second)

         }

 

}

 

/*

        检查错误。错误不能乱处理,有时候函数多返回值可能值为空,如果随便的处理错误将导致无法避免 

    空指针异常

*/

func checkErr(e error) {

         if e != nil {

                  fmt.Println(e)

         }

}

 

func getCorrentAddr(mapTemp map[string]int) (string, string) {

         // 将map转为slice

         var list []string

         for key, _ := range mapTemp{

                  list = append(list, key)

         }

         // 从多个string中取出前5位相同的2个string

         myMap := make(map[string]int)

         for i:=0; i<len(list); i++{

                  if _, ok := myMap[list[i][:5]]; ok {

                          myMap[list[i][:5]]++

                  } else {

                          myMap[list[i][:5]] = 1

                  }

         }

         max := 0

         targetStr := ""

         for key, value := range myMap{

                  if value > max {

                          max = value

                          targetStr = key

                  }

         }

 

         return targetStr+"1", targetStr+"2"

}

 

USB转i2c/spi/uart适配器,和单片机通讯基本上可以可以通过工具不同研究下面的协议

 

2.工业协议解决方案

广播

有关部分协议基于专用的芯片

ProfiNet采用了专门的芯片、网卡、交换机等以太网基础设施,虽然

EtherCAT,ProfiNet应用层协议是公开的,但这些芯片却是专用(厂商不提供芯片内部电路与程序),国内的制造商要想开发符合ProfiNet标准的设备,确要依赖于这些芯片,受制于提供芯片的公司.

https://img-blog.csdn.net/20170811153242293?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaGljY2MyMDEy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

3设备通讯配件选件

modbus 没有考虑优先仲裁

 

RTU转TCP后网络结构更灵活。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

MD-620属于透明传输

 

属于透明传输无法进行协议转换

一个232,一个485透明传输无法转成多主站需要网关设备

需要网关设备

 

(主站令牌),可以转换为TCP协议后可实现多主机一从机通讯

 

MOD2004-LITE网关  多主站RTU

 

 

 

 

 

 

 

 

发布了67 篇原创文章 · 获赞 2 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_42544051/article/details/103122228