I am working on a project using raspberry pi and an arduino. I'm writing a GO program on the raspberry pi to receive UART data from the Arduino at 115200 baud rate every second. The raspberry pi reads the UART data, saves it to a file (based on the value to either file1
or file2
, etc), and then send the file to ftp server.
Since uploading to server might take time depending on network I want to use go concurrency so that UART reading and saving to file are not interrupted. The following is pseudocode (skeleton) that I am trying to apply. My thinking in the code is the filepaths will be buffered in the channel sequencially and the upload is performed in the same order. Am I doing it correctly? Is there a better way to approach the problem?
package main
import "strings"
func SendFile(filePath string) {
}
// based on the value of the data, SaveToFile saves the data to either file1, file2 or file3
func SaveToFile(uartData []string) filePath string {
return filePath
}
func main() {
ch := make(chan string, 1000)
//uartInit initialization goes here
uart := uartInit()
//infinite loop for reading UART...
for {
buf := 1024 // UART buffer
data := uart.Read(buf)
uartData = strings.Split(string(buf), " ")
//channel receives filepath
ch <- SaveToFile(uartData)
//channel sends filepath
go SendFile(<-ch)
}
}
You are writing one string to the channel, and reading it back. The sendFile() runs in a different goroutine, but there is no need for the channel in the way you're using it. You could simply do
fname:= SaveToFile(uartData)
go SendFile(fname)
However, I don't think this is what you want to do.
Instead, you should have a goroutine in which you read data from the UART, and write to a buffered channel. Listening to that channel is another goroutine that writes blocks of data to a file. When it is ready to be sent, create a third goroutine to send the file.
After reading the comments and some online resources the following approach seems to work fine so far. The first 8 minutes in this video was quite helpful to understand the concept. The defer close(ch)
is something I'm uncertain, though.
package main
import "strings"
func SendFile(ch chan string) {
for filePath := range ch {
//upload file here
}
}
func SaveToFile(uartData []string) filePath string {
return filePath
}
func main() {
ch := make(chan string, 1000)
defer close(ch)
go SendFile(<-ch)
uart := uartInit()
for {
data := uart.Read(buf)
uartData = strings.Split(string(buf), " ")
ch <- SaveToFile(uartData)
}
}