Hi,
I've used the provided example in
http://playground.arduino.cc/Interfacing/Cocoa, the one that uses IOKit/ioctl in order to receive serial data from an Arduino UNO and send it to a Mac mini. I've done some changes but the serial code has not changed. I'm able to receive data normally but I've a problem when I stop the application and close the communication, simply it hangs and the only way to close the application is killing it.
The serial port is open with this code:
if (serialFileDescriptor == -1) {
// check if the port opened correctly
errorMessage = @"Error: couldn't open serial port";
} else {
// TIOCEXCL causes blocking of non-root processes on this serial-port
success = ioctl(serialFileDescriptor, TIOCEXCL);
if ( success == -1) {
errorMessage = @"Error: couldn't obtain lock on serial port";
} else {
success = fcntl(serialFileDescriptor, F_SETFL, 0);
if ( success == -1) {
// clear the O_NONBLOCK flag; all calls from here on out are blocking for non-root processes
errorMessage = @"Error: couldn't obtain lock on serial port";
} else {
// Get the current options and save them so we can restore the default settings later.
success = tcgetattr(serialFileDescriptor, &gOriginalTTYAttrs);
if ( success == -1) {
errorMessage = @"Error: couldn't get serial attributes";
} else {
// copy the old termios settings into the current
// you want to do this so that you get all the control characters assigned
options = gOriginalTTYAttrs;
/*
cfmakeraw(&options) is equivilent to:
options->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
options->c_oflag &= ~OPOST;
options->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
options->c_cflag &= ~(CSIZE | PARENB);
options->c_cflag |= CS8;
*/
cfmakeraw(&options);
// set tty attributes (raw-mode in this case)
success = tcsetattr(serialFileDescriptor, TCSANOW, &options);
if ( success == -1) {
errorMessage = @"Error: coudln't set serial attributes";
} else {
// Set baud rate (any arbitrary baud rate can be set this way)
success = ioctl(serialFileDescriptor, IOSSIOSPEED, &baudRate);
if ( success == -1) {
errorMessage = @"Error: Baud Rate out of bounds";
} else {
// Set the receive latency (a.k.a. don't wait to buffer data)
success = ioctl(serialFileDescriptor, IOSSDATALAT, &mics);
if ( success == -1) {
errorMessage = @"Error: coudln't set serial latency";
}
}
}
}
}
}
}
And the port is closed when a button is pressed in the graphical interface with this code, also from the examples:
if (serialFileDescriptor != -1) {
[self appendToIncomingText:@"Trying to close the serial port...\n"];
close(serialFileDescriptor);
serialFileDescriptor = -1;
// wait for the reading thread to die
while(readThreadRunning);
// re-opening the same port REALLY fast will fail spectacularly... better to sleep a sec
sleep(0.5);
[Start setTitle:@"Start"];
}
The application hangs in the close function.
I've tried several things, different parameters and settings at open time, but basically the result is always the same: it hangs in the close function.
Does anybody have solved this issue ?
Regards,
Joan
Moderator edit:
[code] [/code] tags added.