I'm using Xcode with an arduino and when I open a serial port I get a bit transmitted on the TX line to the Arduino RX pin. This confuses software serial if I tunnel though the Arduino to the peripheral. I can see it on a logic analyzer attached to the Arduino RX serial pin. Right now I have a hack in place that after the port opens (delay 2 seconds in Xcode program) and let the software serial timeout before sending the real array of chars down the serial. I've posted my x code ANSI C code below.
ttyport = open(serialport, O_RDWR | O_NOCTTY | O_NONBLOCK); //open the serial port
How do I stop that one bit from being generated when i open the port? I've included my TTY configure function below:
Thanks for the reply. Right now I have the circuit as a bare minimum. Logic analyzer channel 1 attached to pin 0 RX and logic anayzer channel 2 to software serial port. I am using the software serial example code with the hello work serial prints removed. No other hardware attached on other code on arduino. When I open the tty on the mac I get a sudo start byte that goes low for 40us. The tx line on the software serial then goes low for 1.5s and does not recover to send usable data. The 10 bits per byte package on pin 0 looks great. When I write to the serial port I get a start byte the 8 bytes and a stop byte. If I do not wait for the tx line on the software serial to time out before I send real data the arduino software serial library garbled the data. They are really 2 problems here. One is I don't need an attention byte when opening the tty port. That used to be common to wake up the modems back in the day. Google searching this the raspberry pi used to do this as well but it was removed from the default operation of the tty port. The other problem is the time out of the software serial on the arduino. It does not time out from that one bit until 1.5s pass. The hardware serial port on the arduino has no problem ignoring this bit and processes the data properly.
What is generating data on the pin that is used for software serial?
Or are you using Software serial just to transmit - in which case, what is connected to it to receive the data?
Pin0, which you mention. is Rx for HardwareSerial and I presume the data on that comes from you MAC.
Post the actual code you are using so I can try it. (and please use code tags so it looks like this)
I am using an Uno R3 and I did use code blocks above with my xcode! The code serial data is coming from the Mac. Even if I send no raw data if I just do an open on the TTY I can see a one bit signal on pin 0 which causes a 1.5s signal on the software serial [tx] pin.
ohh sorry you wanted the arduino code as well. here it is:
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3); // RX, TX
void setup()
{
Serial.begin(9600);
mySerial.begin(9600);
}
void loop() // run over and over
{
if (mySerial.available())
Serial.write(mySerial.read());
if (Serial.available())
mySerial.write(Serial.read());
}
Below is the full Xcode program and a link to a screen shot from my logic analyzer. My logic analyzer is attached to Pin 0 hardware RX and pin 3 Software Serial TX. I shouldn't have to state the obvious but I will: the grounds are tied together. As you can see in the captured waveform from the logic analyzer when I open the serial port i get a short 1 bit pulse and the software serial transmits that pulse for 1.5 seconds till it times out. Then after my 2 second wait (hard coded into Xcode program I send my real data and the real data gets retransmitted to the software serial port. if i send my serial data from Xcode during that long pulse being shown on the software serial port my data never gets transmitted out. I'm using arduino 1.0.5 and Xcode 5.1.1 The Xcode program is just a console C program.
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
void init_port(int *fd, unsigned int baud) //configure serial port settings.
{
struct termios options;
tcgetattr(*fd,&options);
switch(baud)
{
case 9600: cfsetispeed(&options,B9600);
cfsetospeed(&options,B9600);
break;
case 19200: cfsetispeed(&options,B19200);
cfsetospeed(&options,B19200);
break;
case 38400: cfsetispeed(&options,B38400);
cfsetospeed(&options,B38400);
break;
case 115200: cfsetispeed(&options,B115200);
cfsetospeed(&options,B115200);
break;
default:cfsetispeed(&options,B9600);
cfsetospeed(&options,B9600);
break;
}
options.c_cflag |= (CLOCAL | CREAD); // Ignore modem controls
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8; // 8 bit chars
options.c_cflag &= ~(PARENB | PARODD); // shut off parody
options.c_cflag &= ~CSTOPB; //no scts stop
options.c_cflag &= ~CRTSCTS; // no rts cts control
options.c_iflag &= ~IGNBRK; //disable break processing
options.c_iflag = 0; // no echo
options.c_iflag &= ~(IXON | IXOFF | IXANY); // no software flow control
options.c_oflag = 0; // no remapping
options.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG |IEXTEN);
options.c_cc[VMIN] = 0; // read doesn't block
options.c_cc[VTIME] = 5; // 0.5s read timeout
tcsetattr(*fd,TCSANOW,&options);
}
int main(int argc, const char * argv[])
{
const char serialport[] = "/dev/tty.usbmodemfa141"; // virtural TTY of Arduino
int ttyport; // serial port
ttyport = open(serialport, O_RDWR | O_NOCTTY | O_NONBLOCK); //open the serial port
if(ttyport == -1) // if the serial port won't open let the user know
{
perror("Unable to open serial port\r\n");
exit(EXIT_FAILURE);
}
printf("Opening Serial Port!\r\n");
sleep(2);
init_port(&ttyport,9600); //set serial port to 9600,8,n,1
write(ttyport, "TEST", 4); // write the line to the serial port
close(ttyport); // close the serial port
exit(EXIT_SUCCESS);
}
Your PC sends a byte to the Arduino. The Arduino receives it on Pin0 (Hardware Serial). If the Arduino receives a byte on Serial it sends that byte on SoftwareSerial (Pin3). But there is some error in the data and the PC does not receive what it expects?
Your code also seems to check for input to SoftwareSerial and if it finds it, it sends it to the PC. But I haven't seen any reference to what is sending data to SoftwareSerial?
I wonder are you expecting too much of SoftwareSerial. It can only send or receive, not both at the same time and maybe you need a delay between switching. Or maybe each time you try to send a byte it initializes SoftwareSerial and that causes your glitch.
And you still haven't suggested how I might replicate your problem in an effort to help. I don't have XCode and I don't know what it is. But I doubt it is specific to the problem.
UPDATE* the problem does not exit when I build the code on my UBUNTU 14.04LTZ box using ECLIPSE IDE and a linux cross compiler. The issue appears to be when I build the app on my MAC using XCODE. When I open the port on my linux box there is no bit transmitted during the open tty call.
Robin.. I appreaciate the help but without you even knowing what xcode is I don't think that you will be able to help me and I've found a linux fourm that better understands my problem so I'm talking with them about how to fix this problem. Once I get it solved I'll post the fix. If a mac device driver guy can chime in that might help me too.
I am not trying to do bi directional communication. I think my code is well commented and documented and the problem is very duplicatable. Thank you once again but this is all the input I can give to get help!
stealthtransam:
but without you even knowing what xcode is I don't think that you will be able to help me
That may indeed be true but I suspect this is not simply an XCode problem. The Arduino hasn't the slightest idea what puts the data onto the USB cable.
And you haven't said what is the consequence (if any) of the problem your logic analyzer has found - i.e. is there any real problem at all?