//------------------------------------------------------------------------------ // Purpose: To make sure that the xmodem calls were read by the device without // clearing the data // // Param port: The serial port that we should utilize //------------------------------------------------------------------------------ func verifyWrite(port *serial.Port) { var err error n, readBuff := 1, make([]byte, 5) for n > 0 && err != io.EOF { n, err = port.Read(readBuff) } }
func readFreesizedSerialPortLoop(port *serial.Port, readpipe chan []byte) error { readBuf := make([]byte, 256) var sumBuf = []byte{} readPointer := 0 defer port.Close() for { num, err := port.Read(readBuf) if err == io.EOF { // No more data comes if readPointer > 0 { log.Debugf("read data to send: %v", sumBuf) readpipe <- sumBuf readPointer = 0 sumBuf = []byte{} log.Debugf("sumBuf cleared: %v", sumBuf) } continue } if err != nil { return fmt.Errorf("cannnot open serial port: serialPort: %v, Error: %v", port, err) } if num > 0 { readPointer += num for index := range readBuf[:num] { sumBuf = append(sumBuf, readBuf[index]) } log.Debugf("read partial data: %v to sumBuf: %v", readBuf, sumBuf) continue } } }
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 readSizedSerialPortLoop(bufSize int, port *serial.Port, readpipe chan []byte) error { readBuf := make([]byte, 512) var sumBuf = []byte{} var renewBuf = []byte{} sendBuf := make([]byte, 256) for { num, err := port.Read(readBuf) if err == io.EOF { continue } if err != nil { return fmt.Errorf("cannnot open serial port: serialPort: %v, Error: %v", port, err) } if num > 0 { log.Debugf("readBuf: %v, len: %v", readBuf, len(readBuf)) for index := range readBuf[:num] { sumBuf = append(sumBuf, readBuf[index]) } for len(sumBuf) >= bufSize { sendBuf = sumBuf[:bufSize] readpipe <- sendBuf // Truncate sumBuf by Size log.Debugf("sumBuf: %v, len: %v", sumBuf, len(sumBuf)) renewBuf = []byte{} for index := bufSize; index < len(sumBuf); index++ { renewBuf = append(renewBuf, sumBuf[index]) } sumBuf = renewBuf log.Debugf("renewed sumBuf: %v, len: %v / Size: %v", sumBuf, len(sumBuf), bufSize) } } } }
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 readFromTelescope(s *serial.Port, channel chan []byte) { for { buf := make([]byte, 1024) bytesRead, _ := s.Read(buf) fmt.Println(buf[:bytesRead]) channel <- buf[:bytesRead] } }
func readSerial(p serial.Port) string { if Verbose { log.Printf("Reading from serial '%v'\n", p) } buf := make([]byte, 1024) r, _ := p.Read(buf) return strings.TrimSpace(string(buf[:r])) }
func read(s *serial.Port) ([]byte, error) { buf := make([]byte, 15) for numRead := 0; numRead < 15; { n, err := s.Read(buf[numRead:]) if err != nil { log.Fatal("COMMS, read: %s", err) } numRead = numRead + n } if checksum(buf[:14]) != buf[14] { log.Printf("COMMS, read: Checksum doesn't match. Calculated: %x, received: %x", checksum(buf[:14]), buf[14]) return nil, errors.New("Non-matching checksum") } return buf[:14], nil }
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) }
func readSerial(s *serial.Port, output chan<- string) { buf := make([]byte, 128) re := regexp.MustCompile(commandRegex) var message string for { n, err := s.Read(buf) if err != nil { log.Fatal(err) } message += string(buf[:n]) message = strings.Replace(message, "\r", "", -1) message = strings.Replace(message, "\n", "", -1) results := re.FindStringSubmatch(message) if 0 < len(results) { log.Println(results[0]) output <- results[0] message = "" } } }
func readSerial(p serial.Port) string { buf := make([]byte, 1024) r, _ := p.Read(buf) return strings.TrimSpace(string(buf[:r])) }
// 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] }