func newSerialProxy(devicename string, options Options) (interface{}, error) { opt := rs232.Options{BitRate: options.BitRate, DataBits: options.DataBits, StopBits: options.StopBits, Timeout: options.Timeout} dev, err := rs232.Open(devicename, opt) return dev, err }
// Start processing text lines to and from the serial interface. // Send a bool to adjust RTS or an int to pulse DTR for that many milliseconds. // Registers as "SerialPort". func (w *SerialPort) Run() { if port, ok := <-w.Port; ok { opt := rs232.Options{BitRate: 57600, DataBits: 8, StopBits: 1} dev, err := rs232.Open(port.(string), opt) // flow.Check(err) if err != nil { glog.Warningln("cannot connect to", port.(string)) return } // try to avoid kernel panics due to that wretched buggy FTDI driver! // defer func() { // time.Sleep(time.Second) // dev.Close() // }() // time.Sleep(time.Second) // separate process to copy data out to the serial port go func() { for m := range w.To { switch v := m.(type) { case string: dev.Write([]byte(v + "\n")) case []byte: dev.Write(v) case int: dev.SetDTR(true) // pulse DTR to reset time.Sleep(time.Duration(v) * time.Millisecond) dev.SetDTR(false) case bool: dev.SetRTS(v) } } }() scanner := bufio.NewScanner(dev) for scanner.Scan() { w.From.Send(scanner.Text()) } } }
func connect(port string) *serflash.Conn { var dev io.ReadWriter if _, err := os.Stat(port); os.IsNotExist(err) { // if nonexistent, it's an ip address + port and open as network port dev, err = net.Dial("tcp", port) Check(err) // RTS and DTR will be ignored unless telnet is specified } else { // else assume the tty is an existing device, open as rs232 port opt := rs232.Options{BitRate: 115200, DataBits: 8, StopBits: 1} dev, err = rs232.Open(port, opt) Check(err) } if *telnetFlag { dev = serflash.UseTelnet(dev) } return serflash.New(dev, *debugFlag, *waitFlag) }
// listenToSerial reads incoming serial text lines and publishes them to MQTT. func listenToSerial(device, topic string) *rs232.Port { options := rs232.Options{BitRate: 57600, DataBits: 8, StopBits: 1} serial, err := rs232.Open(device, options) if err != nil { log.Print(err) return nil } scanner := bufio.NewScanner(serial) go func() { for scanner.Scan() { // TODO support binary data with Bytes() i.s.o. Text() as option? // this is likely to break in some places, e.g. "jet sub ..." // solution could be to use some special topic naming convention // also would need to enable read timeout for framing the data // sendToHub(topic, scanner.Bytes(), false) sendToHub(topic, scanner.Text(), false) } log.Println("unexpected EOF:", device) // TODO: serial.Close() ? }() return serial }
// Start processing text lines to and from the serial interface. // Send a bool to adjust RTS or an int to pulse DTR for that many milliseconds. // Registers as "SerialPort". func (w *SerialPort) Run() { baud := uint32(57600) databits := uint8(8) stopbits := uint8(1) initdata := make([]interface{}, 0) //initialization data sequence (if supplied) for param := range w.Param { p := param.(flow.Tag) switch p.Tag { case "baud": baud = uint32(p.Msg.(float64)) case "databits": databits = uint8(p.Msg.(float64)) case "stopbits": stopbits = uint8(p.Msg.(float64)) case "init": initdata = append(initdata, p.Msg) //initialization sequence } } if port, ok := <-w.Port; ok { opt := rs232.Options{BitRate: baud, DataBits: databits, StopBits: stopbits} dev, err := rs232.Open(port.(string), opt) flow.Check(err) // try to avoid kernel panics due to that wretched buggy FTDI driver! // defer func() { // time.Sleep(time.Second) // dev.Close() // }() // time.Sleep(time.Second) //handle initialization data (this loop only happens once) go func() { for _, data := range initdata { switch data.(type) { case map[string]interface{}: hash := data.(map[string]interface{}) for k, v := range hash { switch k { case "delay": if d, ok := v.(float64); ok { <-time.After(time.Millisecond * time.Duration(int(d))) } } } default: _, _ = writeHandler(dev, data) } } }() // separate process to copy data out to the serial port go func() { for m := range w.To { _, _ = writeHandler(dev, m) } }() scanner := bufio.NewScanner(dev) for scanner.Scan() { msg := scanner.Text() w.From.Send(msg) } } }