func writeToTelescope(s *serial.Port, channel chan []byte) { for { data := <-channel fmt.Println(data) s.Write(data) s.Flush() } }
func writeSerial(p serial.Port, s string) (err error) { _, err = p.Write([]byte(s + "\n")) if err != nil { log.Fatal(err) } return err }
func sendCommand(p *serial.Port, command string, waitForOk bool) string { log.Println("--- SendCommand: ", command) var status string = "" p.Flush() _, err := p.Write([]byte(command)) if err != nil { log.Fatal(err) } buf := make([]byte, 32) var loop int = 1 if waitForOk { loop = 10 } for i := 0; i < loop; i++ { // ignoring error as EOF raises error on Linux n, _ := p.Read(buf) if n > 0 { status = string(buf[:n]) log.Printf("SendCommand: rcvd %d bytes: %s\n", n, status) if strings.HasSuffix(status, "OK\r\n") || strings.HasSuffix(status, "ERROR\r\n") { break } } } return status }
func passToSerial(serialPort *serial.Port, message ColorMessage) []byte { // Write JSON Command messageBytes, err := json.Marshal(message) _, err = serialPort.Write(messageBytes) if err != nil { log.Println("Error: Write error", err) return nil } // Read JSON Response var outputBytes []byte var readCount int byteBuffer := make([]byte, 8) for { n, err := serialPort.Read(byteBuffer) if err != nil { log.Println("Error: Read error", err) break } readCount++ outputBytes = append(outputBytes, byteBuffer[:n]...) if bytes.Contains(byteBuffer[:n], []byte("\n")) { // Stop at the termination of a JSON statement break } else if readCount > 15 { // Prevent from read lasting forever break } } return outputBytes }
func writeSerial(p serial.Port, s string) (err error) { if Verbose { log.Printf("Writing '%s' to serial '%v'\n", p, s) } _, err = p.Write([]byte(s + "\n")) if err != nil { log.Fatal(err) } return err }
func write(s *serial.Port, msg []byte) { _, err := s.Write(msg) if err != nil { log.Fatal(err) } _, err = s.Write([]byte{checksum(msg)}) if err != nil { log.Fatal(err) } }
func writeSerial(s *serial.Port, input <-chan string) { for { message := <-input message += "\n" log.Println(message) n, err := s.Write([]byte(message)) if err != nil { log.Fatal(err) } log.Printf(string(n)) } }
func requestDatagram(s *serial.Port) error { n, err := s.Write([]byte("DUMP\r")) if err != nil { return err } buf := make([]byte, 38) // Datagram length is 38 bytes incl. \n n, err = s.Read(buf) if err != nil { return err } // check for correct size if n != 38 { return errors.New("received datagram with invalid size (must: 38, was: " + strconv.Itoa(n) + ")") } return processDatagram(buf) }
// viaRTU is a private method which applies the given function validator, // to make sure the functionCode passed is valid for the operation // desired. If correct, it creates an RTUFrame given the corresponding // information, attempts to open the serialDevice, and if successful, transmits // it to the modbus server (slave device) specified by the given serial connection, // and returns a byte array of the slave device's reply, and error (if any) func viaRTU(connection *serial.Port, fnValidator func(byte) bool, slaveAddress, functionCode byte, startRegister, numRegisters uint16, data []byte, timeOut int, debug bool) ([]byte, error) { if fnValidator(functionCode) { frame := new(RTUFrame) frame.TimeoutInMilliseconds = timeOut frame.SlaveAddress = slaveAddress frame.FunctionCode = functionCode frame.StartRegister = startRegister frame.NumberOfRegisters = numRegisters if len(data) > 0 { frame.Data = data } // generate the ADU from the RTU frame adu := frame.GenerateRTUFrame() if debug { log.Println(fmt.Sprintf("Tx: %x", adu)) } rtsDownChan <- len(adu) if SendHook != nil { SendHook.WriteHook(connection, true) } // transmit the ADU to the slave device via the // serial port represented by the fd pointer _, werr := connection.Write(adu) if werr != nil { if debug { log.Println(fmt.Sprintf("RTU Write Err: %s", werr)) } return []byte{}, werr } // allow the slave device adequate time to respond time.Sleep(time.Duration(frame.TimeoutInMilliseconds) * time.Millisecond) // then attempt to read the reply response := make([]byte, RTU_FRAME_MAXSIZE) n, rerr := connection.Read(response) if rerr != nil { if debug { log.Println(fmt.Sprintf("RTU Read Err: %s", rerr)) } return []byte{}, rerr } // check the validity of the response if response[0] != frame.SlaveAddress || response[1] != frame.FunctionCode { if debug { log.Println("RTU Response Invalid") } if response[0] == frame.SlaveAddress && (response[1]&0x7f) == frame.FunctionCode { switch response[2] { case EXCEPTION_ILLEGAL_FUNCTION: return []byte{}, MODBUS_EXCEPTIONS[EXCEPTION_ILLEGAL_FUNCTION] case EXCEPTION_DATA_ADDRESS: return []byte{}, MODBUS_EXCEPTIONS[EXCEPTION_DATA_ADDRESS] case EXCEPTION_DATA_VALUE: return []byte{}, MODBUS_EXCEPTIONS[EXCEPTION_DATA_VALUE] case EXCEPTION_SLAVE_DEVICE_FAILURE: return []byte{}, MODBUS_EXCEPTIONS[EXCEPTION_SLAVE_DEVICE_FAILURE] } } return []byte{}, MODBUS_EXCEPTIONS[EXCEPTION_UNSPECIFIED] } // confirm the checksum (crc) response_crc := crc(response[:(n - 2)]) if response[(n-2)] != byte((response_crc&0xff)) || response[(n-1)] != byte((response_crc>>8)) { // crc failed (odd that there's no specific code for it) if debug { log.Println("RTU Response Invalid: Bad Checksum") } // return the response bytes anyway, and let the caller decide return response[:n], MODBUS_EXCEPTIONS[EXCEPTION_BAD_CHECKSUM] } // return only the number of bytes read return response[:n], nil } return []byte{}, MODBUS_EXCEPTIONS[EXCEPTION_ILLEGAL_FUNCTION] }