I am taking input through the serial port (using an Arduino) and I want to parse the data. Here is what I have so far:
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()
}
}
The serial port currently prints this (looped):
{"temperature":[27.7],"humidity":[46.9],"sensor":"DHT22"}
{"temperature":[25.41545],"sensor":"LM35DZ"}
{"blink":["true"],"actuator":"arduinoLED"}
I am trying to use goroutines to parse the data, and print this (should be looped as well):
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"}
However, I am not getting an output. The program simply isn't printing. I think it has to do with the way I am saving the data. Does anyone know how to fix this? And if it's fixed, whether this use of goroutines is the correct method to achieving what I want?
Thank you so much.
The obvious problem with your code is invalid use of the waitgroup - you init it with 2 and then wait for it in infinite loop... also, your code never reaches to the part where it calls readFirstLine
and readSecondLine
, it is stuck in the scanner loop
I think the basic structure youre after would be something like following:
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()
}
And the goroutines which process the data would be like:
func processSensorData(data chan string) {
for d := range data {
// do something with data
}
}