当前位置: 首页 > 工具软件 > go-serial > 使用案例 >

go使用 serial包读取串口数据(通用)

阳英朗
2023-12-01

以下代码实现了 deepin 下监听串口,并获取串口发送的红外传感器、温湿度传感器数据。每 5 min采集一次,一次采集获取10条有效数据封装为数组返回供上层调用。

/*
 * 2019年软硬件课设周读取人体红外、温湿度传感器信息
 */
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"
}

 类似资料: