armadsen / ORSSerialPort

Serial port library for Objective-C and Swift macOS apps
MIT License
751 stars 183 forks source link

Cannot receive data, sending works #174

Open r00li opened 3 years ago

r00li commented 3 years ago

Hi! I've been trying to use this library with a simple arduino based project and I am having some issues. I am using the 2.1 version installed through swift package manager on Mac Os Catalina.

The whole connecting part works nicely. I can open the connection to a port, I get the serialPortWasOpened delegate call, ... If I send some data to the device this works as well (device has display so I can see that the data is received correctly).

The issue is that I am unable to receive any data from device. The serialPort(_ serialPort: ORSSerialPort, didReceive data: Data) delegate function is never called. Whenever I press a button on the device it should send some data back (I can confirm that it does this with Arduino serial monitor), but I never get that data using this library. I've also tried using the ORSSerialPortDemo example and I get the same behavior. Computer -> device works, but I get no data back.

LSDdev commented 2 years ago

Hi! I've been trying to use this library with a simple arduino based project and I am having some issues. I am using the 2.1 version installed through swift package manager on Mac Os Catalina.

The whole connecting part works nicely. I can open the connection to a port, I get the serialPortWasOpened delegate call, ... If I send some data to the device this works as well (device has display so I can see that the data is received correctly).

The issue is that I am unable to receive any data from device. The serialPort(_ serialPort: ORSSerialPort, didReceive data: Data) delegate function is never called. Whenever I press a button on the device it should send some data back (I can confirm that it does this with Arduino serial monitor), but I never get that data using this library. I've also tried using the ORSSerialPortDemo example and I get the same behavior. Computer -> device works, but I get no data back.

Hi,

I'm faced with this same setup and problem too. Did you find solution? Delegate is set properly as open/closed delegate calls comes through, Arduino receives serial data ok but nothing is received ever.

r00li commented 2 years ago

Sadly I did not, no. Since I only needed the basics for a simple hobby project I just switched to using https://github.com/yeokm1/SwiftSerial

It's not as pretty, but it works just fine.

LSDdev commented 2 years ago

After digging this bit more, it looks like the file descriptor & dispatch source are not working the way they are supposed. Thus the block handling incoming data is never executed.

dispatch_source_t readPollSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, self.fileDescriptor, 0, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));
dispatch_source_set_event_handler(readPollSource, ^{
        ...This block never executed when data comes in from serial port...
        }

On my case I did check that the property fileDescriptor was same value as what lsof reported (on terminal) for the opened port. Didn't know what else to look for.

Dirk- commented 2 years ago

@LSDdev @r00li What happens if you open the port in your app and then open Serial Monitor in the Arduino IDE? In my case my app starts receiving data. I then can close the Arduino Serial Monitor and it continues to work. I suspect something is missing from serial port or Grand Central Dispatch initialization inside ORSSerialPort. I tried to find it, but to no avail yet.

Dirk- commented 2 years ago

I found a solution:

Somehow, RTS and DTR have to be set to TRUE for a successful connection with an Arduino on recent macOS versions.

In the openOrClosePort method of ORSSerialPortDemo, for example, you could do this:

- (IBAction)openOrClosePort:(id)sender
{
    self.serialPort.isOpen ? [self.serialPort close] : [self.serialPort open];
    // For Arduino:
    if (self.serialPort.isOpen) {
        self.serialPort.RTS = TRUE;
        self.serialPort.DTR = TRUE;
    }
}

It is not sufficient to set usesDTRDSRFlowControl or usesRTSCTSFlowControl to TRUE. No need to change these flags.

cbackas42 commented 1 year ago

I'm having this exact same issue; the dispatch source never fires when trying to talk to an Arduino device. I also DO get data if I use a simpler approach like SwiftSerial, but I vastly prefer the way this project deals with received data (well, assuming it ever receives any!) I have also noticed that the dispatch source callback will fire if i pull the cable, so it clearly is running.

However, in my case calling serialPort.RTS = true, serialPort.DTS = true didn't help anything.

cbackas42 commented 1 year ago

I've spent a maddening amount of time on this. No matter what I do or setting I change, dispatch_source just will never fire on this thing. I tried implementing select() instead, and that also doesn't work - it'll return 0 when the timeout hits always.

However, if I just blindly read() from the fd, there is data there! (This is why SwiftSerial is working, it doesn't check first)