HELP please! Arduino serial communication

:cold_sweat: I am really loozing it...

been working on this for a while and tought I had it nailed, but I am getting some really strange comm issue,
that looks like timming. Aint a programmer so please dont laugh to hard... :~

Application monitors serial port for known commands;
S = All Stop
C= Give me your bearing (format of response AZ=BBB, where BBB is the bearing in degrees with leading zeros)
MBBB = Move to Bearing (BBB)

when the PC application driving the Arduino starts up, it starts polling for Bearing every second by sending
C's. But the Arduino doesnt always respond...

My original issue was that the Arduino and the PC app would not link, to resolve this I had to insert a;

Serial.println();

It looked like the Arduino did not respond fast enough to the first C request for the PC app thus the PC apps considered
the link as failed and terminated...

then I noticed that the Arduino wasnt responding at all to the C commands, So I decided to insert a delay between the READ
command and the firts IF command to make certain the Arduino would be ready to respond to the data from teh serial port...

This did help... But... after tweeking the delay the best I can come up with is a response every second C command every

When I test the code manual using the serial terminal it works 100%...

I am assuming I aint dealing with the serial port properly and it could be optimised a LOT...

so here is my CRY for HELP!

... HELP! ...

thanks in advance...

Richard ve2dx

void GetSerialData() {
		serialdata = Serial.read(); 
		Serial.println();
                delay (1000);

		if (serialdata == 'C') {

			if (AZreal > 99) {
				String GS232Boutput = (AZ + AZreal);
				Serial.println(GS232Boutput); 
			}
			else {
				if (AZreal < 10) {
					String GS232Boutput = (AZ00 + AZreal);
					Serial.println(GS232Boutput);
				}
				else  {
					String GS232Boutput = (AZ0 + AZreal);
					Serial.println(GS232Boutput);
				}
			}
		}
		if (serialdata == 'M') {
			digitalWrite(CCW1output, LOW);
			digitalWrite(CW1output, LOW);
			digitalWrite(CW1speed, LOW);
			int X = 0;
			String serialstring;
			while (X < 3) {
				//Serial.println(X);
				serialdata = Serial.read();
				//serialdata = byte (serialdata);
				serialstring = String (serialstring + serialdata);
				//Serial.println(serialdata);
				//Serial.println(serialstring);
				X = X++;
			}

			AZrequested = serialstring.toInt();

			AZtemp = AZreal;
		}

		if (serialdata == 'S') {
			digitalWrite(CCW1output, LOW);
			digitalWrite(CW1output, LOW);
			digitalWrite(CW1speed, LOW);
			AZrequested = AZreal;
			//Serial.println(AZrequested);
		}

:cold_sweat:

There is a Serial.available() method that reports how many bytes of data there are to read. You should be using that function before ANY call to Serial.read().

My original issue was that the Arduino and the PC app would not link, to resolve this I had to insert a;
Serial.println();

That has to do with what told the PC application to stop reading a packet of data. Clearly, the carriage return/line feed character was defined as the end-of-packet marker, so you need to send one. The ln in the name means that that is what the function does.

when the PC application driving the Arduino starts up, it starts polling for Bearing every second by sending C's. But the Arduino doesnt always respond...

Handshaking is required. The PC should not send anything until the Arduino says "Hey, there, I'm ready. What's the holdup?" (or something like that).

then I noticed that the Arduino wasnt responding at all to the C commands, So I decided to insert a delay between the READ
command and the firts IF command to make certain the Arduino would be ready to respond to the data from teh serial port...

The Arduino did not appear to be fast enough, so you slowed it down some. If there is still a problem with it being too slow, will you be trying a longer do-nothing period to make it slower?

This did help... But... after tweeking the delay the best I can come up with is a response every second C command every

No, it didn't. The best "tweaking" of the delay() will involve the delete key or the backspace key, depending on which direction you choose to approach it.

To make any useful comments on your code, we'd need to see more of it. What are AZ, AZ0, AZ00, and AZreal? If AZreal is a String, it can't be greater than 10. If it is an integer, I'm not sure is can be concatenated onto a String object that way. In any case, there is a way to generate a fixed size character string to send that uses a lot less memory than the String class.

Thanks for the reply Paul... :slight_smile:

keep in mind I am NOT a programmer and these are some of my first steps with Arduino programming (other then a couple of traffic ligth test programs I did...) :roll_eyes:

I have no dougth that there probably are better ways of doing some of the routine and that your going to be rolling off your chair once you get the hole thing...

Ok, I am attaching the complete version of the GS232Bduino application...

you can email me direct at ve2dx at hotmail dot com, might make exchanges a little easier, and then we will come back and have a good laugh at all the dumb things I did in that code... :slight_smile:

GS232Bduino_1_3_0.pde (13.6 KB)

Got it! and it is working...

still required some of the timming stuff I talked about earlier, but the big difference, is I added a

while (Serial.available() > 0) {

in the begining of my

void GetSerialData() {

routine, this seams like it was enought to help...

thanks again for your help...

Richard ve2dx

void GetSerialData() {						// this is my subroutine that gets the GS232 data from the serial port
	 while (Serial.available() > 0) {         				// Is there any data for me on the serial port?
		RealBearing() ;					// Start RealBearing routine (get present Bearing).
 		serialdata = Serial.read(); 				// Lets read the data from the serial port
		delay (500);

// we need to respond to a C command with bearing info under the following format AZ=BBB where BBB is the bearing info with leading zeros.

		if (serialdata == 'C') { 				// if data received on serial port is equal to the letter C or c then we send 
								// the AZ=BBB response via the serial port.
			//Serial.println("detected C command");		// check fern
			if (AZreal > 99) {				// check if bearing is 3 digit (100 or more)
								// GS232A or B protocol dictates that the bearing must have leading zeros
				String GS232Boutput = (AZ + AZreal);	// setting my output string for the serial port (AZ=+AZreal)
				Serial.println(GS232Boutput); 		// output my position as GS232B (or GS232A if code was mods) protocol
			}					// end of IF
			else {					// if wasnt 3 digit then
				if (AZreal < 10) {			// check if bearing is a single digit (9 or less)
					String GS232Boutput = (AZ00 + AZreal);	// setting my output string for the serial port (AZ=00+AZreal)
					Serial.println(GS232Boutput); 	// output my position as GS232B (or GS232A if code was mods) protocol
				}				// end of IF
				else  {				// then bearing should be 2 digit (10 to 99)
					String GS232Boutput = (AZ0 + AZreal);	// setting my output string for the serial port (AZ=0+AZreal)
					Serial.println(GS232Boutput); 	// output my position as GS232B (or GS232A if code was mods) protocol
				}				// end of IF
			}					// end of IF
		}						// end of IF

// Next we will define our destination bearing
// we look for MBBB command from the serial port by detecting the M then getting the 3 digit bearing info BBB.

		if (serialdata == 'M') { 				// if data received on serial port is equal to the letter M then 
								// start looking for the next 3 numerical digit these will be requested 
			//Serial.println("detected M command");		// check fern
			digitalWrite(CCW1output, LOW);		// Turn OFF Counter Clockwise relay
			digitalWrite(CW1output, LOW);			// Turn OFF Clockwise relay
			digitalWrite(CW1speed, LOW);			// Turn OFF Speed relay			
			int X = 0;					// set my counter (X) to 0
			String serialstring;				// I need this to clear the serialstring value
			while (X < 3) {				// check to see the value of my counter as long as it is not equal to 3
				//Serial.println(X);			// check fern
				serialdata = Serial.read(); 		// ok lets read the first byte of data
				//serialdata = byte (serialdata);		// convert it to text
				serialstring = String (serialstring + serialdata);	// Assemble it with the previous character (or number)
				//Serial.println(serialdata);		// check fern
				//Serial.println(serialstring);		// check fern again
				X = X++;				// increment my counter by 1
			}					// end of WHILE
			//Serial.println(serialstring);			// check fern resulting text
			AZrequested = serialstring.toInt();		// set my requested bearing eual to convert resulting serial 3 digit datatext 
								// to do so I need to convert the string into integer (read up on toInt() command!!!)
			AZtemp = AZreal;				// for speed control I must set a start point its AZtemp
		}						// end of IF

// Now lets see if we got an ALL STOP command (S)?

		if (serialdata == 'S') { 					// if data received on serial port is equal to the letter C then we send 
								// the AZ=BBB response via the serial port.
			//Serial.println("detected S command");		// check fern
			digitalWrite(CCW1output, LOW);		// Turn OFF Counter Clockwise relay
			digitalWrite(CW1output, LOW);			// Turn OFF Clockwise relay
			digitalWrite(CW1speed, LOW);			// Turn OFF Speed relay
			AZrequested = AZreal;			// set AZrequested equal to AZreal, I stop the rotor by making them equal
			//Serial.println(AZrequested);			// check fern
		}						// End of IF
                  MoveAndDisplay();						// Start the rotor moving according to data available
	}							// End of IF
}								// End of IF
		serialdata = Serial.read(); 				// Lets read the data from the serial port
		delay (500);

You read one character, then wait half a second?
At 9600baud, your 128 byte receive buffer could overflow over three times in that period.

Hello AWOL nice AVATAR BTW!

I do but only in the begining of the sequence... anywhere I did not have this problem...

If I did not put the delay there, for some reason the Arduino would not find that first character...

if there is anything you can suggest to optimize (trash the delay!) I would be very happy to look atit with you...

thanks

Richard ve2dx