Search code examples
macosswiftxcode6orsserialport

Why ORSSerialPort receive delegate don't work in my Swift project


i have a simple SerialController class :

class SerialController : NSObject, ORSSerialPortDelegate {
    var port : ORSSerialPort

    init(path: String){
        port=ORSSerialPort(path: path)
        port.close()
    }

    func open(){
        port.baudRate=9600
        port.delegate=self
        port.open()
    }

    func close(){
        port.delegate=nil
        port.close()
    }

    func SendString(data: String){
        port.sendData(data.dataUsingEncoding(NSUTF8StringEncoding))
    }

    func serialPortWasOpened(serialPort: ORSSerialPort!) {
        println("PORT IS OPEN....")
    }

    func serialPortWasClosed(serialPort: ORSSerialPort!) {
        println("PORT IS CLOSE")
    }

    func serialPort(serialPort: ORSSerialPort!, didReceiveData data: NSData!) {
        println(NSString(data: data, encoding: NSUTF8StringEncoding))
    }

    func serialPortWasRemovedFromSystem(serialPort: ORSSerialPort!) {
        println("PORT REMOVED")
    }

    func serialPort(serialPort: ORSSerialPort!, didEncounterError error: NSError!) {
        println("PORT ERR \(error)")
    }
}

and a simple code for sending data to FT232 adapter

func readLine()->String{
    return NSString(data:NSFileHandle.fileHandleWithStandardInput().availableData, encoding: NSUTF8StringEncoding)
}

let myPort = SerialController(path: "/dev/cu.usbserial-CN920229")

myPort.open()
println("type your data to send...")
let k = readLine()
myPort.SendString(k)
myPort.close()

RX and TX pin's of FT232 are connected together, and i want to receive echo of data. i can connect to my adapter and SendString method correctly send data to FT232 but receive don't work!. in cocoaDemo i test my FT232 and i can get correct response. what can i do?


Solution

  • The fundamental problem is that you immediately close the port and the program ends after sending data out on the port. You need to keep the program running and the port open to receive data. The simplest way to do this is to just spin the run loop after you send data:

    func readLine()->String?{
        return NSString(data:NSFileHandle.fileHandleWithStandardInput().availableData, encoding: NSUTF8StringEncoding)
    }
    
    let myPort = SerialController(path: "/dev/cu.USA19H141P1.1")
    
    myPort.open()
    println("type your data to send...")
    if let k = readLine() {
        myPort.SendString(k)
    }
    
    NSRunLoop.currentRunLoop().run() // <-- This will continue indefinitely.
    

    Note though that while this will allow you to receive data, it is of course not a very well structured program. You can only send one string per run of the program because you only call readLine() once instead of looping and calling it repeatedly. There's also no way to quit the program short of killing it with ⌘-. or similar.

    If you're planning to turn this into a real program that you use for something more than just a quick one-off test, I'd suggest looking at the CommandLineDemo project in ORSSerialPort's Examples folder. There are versions of that example available in both Swift and Objective-C.