vxristodoulou
vxristodoulou

Reputation: 11

ORSSerialPort.send doesn't send anything

I am new (very new!!) to swift and straggling to make my UI to send a string over the serial port. I've managed to open the port and read/parse the incoming traffic but when it comes to send a string, nothing is sent.

What I need to do is typing in the sendTextField and when press the SendButton to send the string to serial port. Also, when I print the data which is what I want to send over serial port, it prints the number of bytes I try to send (i.e. 5 bytes). Shouldn't this be the string "Hello" that I try to send to serial port?

I am using Xcode Version 11.2 (11B52) and Swift 5.

Any help will be really appreciated. Thank you in advance!

This is how I call the "send" function:

   @IBAction func SendButton(_ sender: Any) {
      let TxData = sendTextField.stringValue
      SFSerialIn.SendSerialData(TxData)      
   }

My main program is below:

import ORSSerial
import IOKit
import IOKit.serial


let SFSerialRegexp =
    "(?<SFmode>[A-Z]+),\\s*" + "(?<prox>[0-1]),\\s*"

class SFSerialIn: NSObject, ORSSerialPortDelegate {


    let path = "/dev/cu.usbserial-AI0484S9" 
    let baudRate: NSNumber = 115200

    var serialPort: ORSSerialPort?
    var delegate: SFSerialDelegate?

    var stringBuffer = ""
    var regex: NSRegularExpression!
    var receivedBufferStart = false

    override init() {
        regex = try! NSRegularExpression(pattern: SFSerialRegexp)
    }

    deinit {
        disconnect()
    }

    func SendSerialData(_ TxData: String){
       let data = Data(TxData.utf8)
       serialPort?.send(data)
       print(TxData)
       print(data)
    }  

    func connect() {
        if let serialPort = ORSSerialPort(path: path) {
            serialPort.baudRate = baudRate
            serialPort.delegate = self
            serialPort.open()
        } else {
            print("Failed to open serial port")
        }
    }

    func disconnect() {
        serialPort?.close()
        print("closing port...")
    }


    func serialPort(_ serialPort: ORSSerialPort, didReceive data: Data) {
        guard let string = String(data: data, encoding: .utf8)
            else {
            return
        }

        stringBuffer += string

        parseBuffer()
    }

    func parseBuffer() {
        let lines = stringBuffer.split { $0.isNewline }

        guard lines.count > 1 else {
            return
        }

        let nextLines = lines[1...].joined()

        if !receivedBufferStart {
            stringBuffer = nextLines
            receivedBufferStart = true
            return
        }

        let line = String(lines[0])
        if let matchResult = regex.firstMatch(in: line, range: NSRange(..<line.endIndex, in: line)) {
            let sensorFrame = SFFrame(matchResult: matchResult, string: line)
            delegate?.receive(sensorFrame: sensorFrame)
            stringBuffer = nextLines
            return
        }

        print("Failed to parse line :(")
        stringBuffer = nextLines
    }

    func serialPort(_ serialPort: ORSSerialPort, didEncounterError error: Error) {
        print("Serial port encountered error", error)
    }

    func serialPortWasOpened(_ serialPort: ORSSerialPort) {
        print("Serial port opened")
    }

    func serialPortWasClosed(_ serialPort: ORSSerialPort) {
        print("Serial port closed")
    }

    func serialPortWasRemovedFromSystem(_ serialPort: ORSSerialPort) {
        print("Serial port was removed from system")
    }
  }

protocol SFSerialDelegate {
    func receive(sensorFrame: SFFrame)
}

extension StringProtocol {
    var data: Data { .init(utf8) }
}

Upvotes: 1

Views: 282

Answers (1)

Andrew Madsen
Andrew Madsen

Reputation: 21373

It doesn't look to me like you're ever storing the opened serial port in your serialPort instance property. So, when you do serialPort?.send(data), serialPort is nil, and the ? (optional chaining) operator means that send() isn't called.

Try storing the serial port in your property after opening it:

func connect() {
    if let serialPort = ORSSerialPort(path: path) {
        serialPort.baudRate = baudRate
        serialPort.delegate = self
        serialPort.open()
        self.serialPort = serialPort
    } else {
        print("Failed to open serial port")
    }
}

Upvotes: 2

Related Questions