Go - разобранный ввод последовательного порта с использованием goroutines, не печатающих - PullRequest
0 голосов
/ 01 июня 2018

Я принимаю данные через последовательный порт (используя Arduino) и хочу проанализировать данные.Вот что у меня есть:

package main

import (
    "log"
    "github.com/tarm/serial"
    "bufio"
    "sync"
    "fmt"
)


func readFirstLine(data []string, wg *sync.WaitGroup){
    defer wg.Done()

    fmt.Printf("This is the sensor data:\n%q\n%q", data[0], data[1])

}

func readSecondLine(data []string, wg *sync.WaitGroup){
    defer wg.Done()

    fmt.Printf("This is the actuator data:\n%q", data[2])
}

func main() {
    usbRead := &serial.Config{Name: "COM5", Baud: 9600, ReadTimeout: 0}
    port, err := serial.OpenPort(usbRead)
    var wg sync.WaitGroup
    wg.Add(2)


    if err != nil {
        log.Fatal(err)
    }
    data := []string{}
    scanner := bufio.NewScanner(port)


    for scanner.Scan() {
        data = append(data, scanner.Text())
    }


    for {

    go readFirstLine(data, &wg)
    go readSecondLine(data, &wg)
    wg.Wait()

    }
}   

Последовательный порт в настоящее время печатает это (зациклено):

{"temperature":[27.7],"humidity":[46.9],"sensor":"DHT22"}
{"temperature":[25.41545],"sensor":"LM35DZ"}
{"blink":["true"],"actuator":"arduinoLED"}

Я пытаюсь использовать goroutines для анализа данных и распечатать это(также должно быть зациклено):

This is the sensor data: 
{"temperature":[27.7],"humidity":[46.9],"sensor":"DHT22"}
{"temperature":[25.41545],"sensor":"LM35DZ"}
This is the actuator data: 
{"blink":["true"],"actuator":"arduinoLED"}

Однако я не получаю вывод.Программа просто не печатает.Я думаю, что это связано с тем, как я сохраняю данные.Кто-нибудь знает, как это исправить?И если это исправлено, является ли это использование goroutines правильным методом для достижения того, чего я хочу?

Спасибо большое.

1 Ответ

0 голосов
/ 01 июня 2018

Очевидная проблема с вашим кодом - недопустимое использование группы ожидания - вы инициируете ее с 2, а затем ждете ее в бесконечном цикле ... кроме того, ваш код никогда не достигает той части, где он вызывает readFirstLine и readSecondLine, он застрял в цикле сканера

Я думаю, что базовая структура, которую вы ищете, будет выглядеть примерно так:

func main() {
    // create channels for data
    sensor := make(chan string)
    actuator := make(chan string)
    // launch goroutines which process the data
    var wg, pg sync.WaitGroup
    pg.Add(2)
    go func() {
       defer pg.Done()
       processSensorData(sensor)
    }()
    go func() {
       defer pg.Done()
       processActuatorData(actuator)
    }()
    // read from the data source
    usbRead := &serial.Config{Name: "COM5", Baud: 9600, ReadTimeout: 0}
    port, err := serial.OpenPort(usbRead)
    if err != nil {
        log.Fatal(err)
    }
    scanner := bufio.NewScanner(port)

    for scanner.Scan() {
        data := scanner.Text()
        wg.Add(1)
        go func(data string) {
           defer wg.Done()
           // figure out data packet type and
           // send it into approprioate channel
           if strings.Contains(data, `"sensor"`) {
              sensor <- data
           } else {
              actuator <- data
           }
        }(data)
    }
    // wait for all data to be sent for processing
    wg.Wait()
    // close the channels so goroutines terminate
    close(sensor)
    close(actuator)
    // wait for all data to be processed
    pg.Wait()
}

И процедуры, которые обрабатывают данные, будут выглядеть так:

func processSensorData(data chan string) {
   for d := range data {
      // do something with data
   }
}
...