Problem with Arduino Serial Communication

Thread Starter

kurtruk

Joined Aug 26, 2012
140
I am working on a project and it is almost done except for a few things including increasing the baud rate. I use a verification where the Computer will say "Hello?" and if the arduino receives "Hello?" it will respond back "Hello!" which will then be verified by the computer. This works all fine until I increase the baud rate above 9600. I am changing the baud rate on both ends and I have tried for hours to mess with the timing and such, but nothing works. The odd thing is if I increase the baud rate on the arduino and then use the arduin IDE serial monitor and send "Hello?" at the same baud rate, it works. Therefor it is more than likely that the error is on the computer end.

I've attached the code the main thing to look at is the arduino Matrix Display 3.0 and the SerialClass and main.cpp. I've included all the code in case anyone wants to look at it.


Any help will be greatly appreciated.
 

Attachments

JohnInTX

Joined Jun 26, 2012
4,787
Try adding a short delay between characters sent by the Arduino. Even though the baud rate is fine, delays in processing the characters on the computer end can cause problems. Some versions of Hyperterminal are particularly bad in this regard. Sometimes you can get a little pacing by sending 2 stop bits instead of 1.

You can test it by with a wrap plug - jumper pins 2 and 3 on a DB9, stick it in the computer's port and send a text file to the serial port. If the computer is bogging down, you should be able to see it missing characters. Note that if you have flow control enabled you'll also need to jumper the handshaking lines.

You also could do a wrap plug on the Arduino side. Send long strings and compare what comes back.

If both ends work, it may be the cable/MAX232 etc. Some cheapo USB-RS232 adapters perform poorly under even reasonable comms loads plus there are counterfeit ones out there.

Good luck.
 

Thread Starter

kurtruk

Joined Aug 26, 2012
140
I've tried adding a delay in multiple place to no avail. I'm using USB not DB9. I've narrowed it down a little bit more. I set up so that if the arduino does not recieve the "Hello?" from the computer it sends back what it did receive.

When I try 14400 baud it sends back " He" or " He"

When I try 115200 baud it send back "≡≡He"

When I send "Hello?" the serial port I receive the correct response back.
So it is either seems to be in the computer sending the "Hello?"
or
The computer receiving the "Hello!"

Theres a part of my code that basically says if the number of characters in the serial buffer is less than the number that has been told to read, then read only the amount that is in the serial buffer. When I test it this if statement is always true with saying there are either 3 or 4 bytes to read in the buffer.
 
Last edited:

sirch2

Joined Jan 21, 2013
1,037
In my experience odd characters on the serial terminal are usually a timing issue. Something like not waiting long enough for characters to arrive or the serial read/write is being interrupted. The processor is running at 16MHz so it is many, many times faster than serial comms, as JohnInTx says, I usually fix this with delays.
 

djsfantasi

Joined Apr 11, 2010
9,163
Is there a true serial port on the computer or are you using a USB to serial adapter? On my computer, there is a property on the adapter for "latency" which I had to set to 1. Perhaps there's another similar property on your system.
 

Thread Starter

kurtruk

Joined Aug 26, 2012
140
I don't think latency is the issue and I couldn't find anything about it in the driver details.

I am communication in serial via USB (universal SERIAL bus).


I've found out that it seems as if the computer has to initiate the connection first. Because if I open the C++ end first then reset the arduino it works.

Is there a way I can make the C++ end hang until the arduino begins it serial imitation?

P.S. Thanks for all the help so far.
 

djsfantasi

Joined Apr 11, 2010
9,163
I don't know C++ that well, but in a serial library there is usually a function to test the status of the connection. Also, there is usually another function to test if there is any input ready to be read. So in pseudo code, you do something like this.

While (! Serial.ready) {};

If (Serial.bufferlen > 0) {
In.Char=Serial.read();
}
 

kubeek

Joined Sep 20, 2005
5,795
You need to do this in steps, first set up the arduino such that it lights a led for a short time when the correct data is received. It may be that the arduino receive function is too slow for this to work at high speeds or short intervals between characters - this is the problem with using arduino instead of plain old C, you have hard time finding how it really works under the hood.
Second, try sending the string from the arduino to Pc in a loop with a bit of delay between the strings and see what you get on the pc.
 

THE_RB

Joined Feb 11, 2008
5,438
You need to do this in steps, first set up the arduino such that it lights a led for a short time when the correct data is received. It may be that the arduino receive function is too slow for this to work at high speeds or short intervals between characters - this is the problem with using arduino instead of plain old C, you have hard time finding how it really works under the hood.
Second, try sending the string from the arduino to Pc in a loop with a bit of delay between the strings and see what you get on the pc.
You beat me to it! :)

Testing both in a loop (as the OP was doing) was a nightmare way to test!

Test in one direction only. And I like to vary the baudrate generator values up/down and find the min.max values where the serial stops working. Then choose a sweet spot in the middle, to give best reliability.

Another good tool to have (or make with an arduino) is a baudrate tester;


(Showing that my PC's 19200 baud is really 19234.8 baud which is 0.18% fast).
http://www.romanblack.com/bigpic6_proj1.htm
:)
 

Thread Starter

kurtruk

Joined Aug 26, 2012
140
I have done it in steps, very small steps indeed. Everything worked, and then I said "ok I'm going to increase the baud rate and make it faster." One step at a time. I went from 9600 to 14400. And things didn't work so I messed with the timing did a lot of troubleshooting and determined one thing. It works perfectly when the C++ computer end initiates the connection before the arduino starts its connection.

So what I am wondering if there is a way to pause/hang the arduino until the Computer connects to it. I have tried stuff like while(!Serial) and while(serial.available()), but neither has worked. Any ideas?
 

THE_RB

Joined Feb 11, 2008
5,438
Just make the arduino "listen", and it must receive a command byte from the PC before the arduino is allowed to transmit.
 

Thread Starter

kurtruk

Joined Aug 26, 2012
140
This is what I have been doing, However it only works if I start the two ends at a precise time (the computer end just a tad before the arduino). With only 9600 baud I was able to let the arduino "sit" and then start the computer end and all would work. Now however i have to start running everything at an exact time.

Here's the pertinent code:
Rich (BB code):
#include "DisplayArduinoClass.h"
 
 void setup(){
   
   Serial.begin(115200);
   
   DisplayArduinoClass obj;
   obj.Setup(); //Setup Pins and Set as OUTPUTS
   for(int i=0;i<50;i++){obj.rmsgByteMap = 0;}   //set 1st and last fifty to zero
   for(int i=0;i<50;i++){obj.gmsgByteMap = 0;}   //set 1st and last fifty to zero
   obj.refresh();
}

 void loop(){
    
   DisplayArduinoClass obj;
   obj.Setup();
  
  while(!Serial.available());   //wait for input
  delay(10);
  int byteIndex =0;
  char incomingString[6] = {0,0,0,0,0,0};
  while (Serial.available()>0){    //read incoming string    
      incomingString[byteIndex] = Serial.read(); 
      byteIndex++;
  }
  
  /* Confirm Connection*/
  
 
  if (incomingString [0] == 'H' && incomingString [1] == 'e' && incomingString [2] == 'l' && incomingString [3] == 'l' && incomingString [4] == 'o' && incomingString [5] == '?'){
    Serial.write(72); Serial.write(101);  Serial.write(108);  Serial.write(108);  Serial.write(111);  Serial.write(33); 
     
  }
  else Serial.print(incomingString);

  


Rich (BB code):
int main(int argc, _TCHAR* argv[])
{

    cout << "                Welcome to Matrix Display Windows Application" << endl;
    cout << "                                  Version 3.0" << endl;
    cout << "                                 Kurt Hoelsema" <<endl<<endl<<endl;
    //Sleep(700);


    Serial* SP = new Serial("COM6");    // adjust as needed  //choose serial port

    /*Test Connection*/
    if (SP->IsConnected()){



        unsigned char Hello[6] = {'H','e','l','l','o','?'};
        SP->WriteData(Hello, 6);
   
        char incomingString [6] = {0,0,0,0,0,0};
        Sleep(200);
        SP->ReadData(incomingString, 6);

        cout << "incomingString =" << incomingString[0]<< incomingString[1]<< incomingString[2]<< incomingString[3]<< incomingString[4]<< incomingString[5] << endl;
        if (incomingString [0] == 'H' && incomingString [1] == 'e' && incomingString [2] == 'l' && incomingString [3] == 'l' && incomingString [4] == 'o' && incomingString [5] == '!'){
            cout << "Connection Successful." << endl << endl << endl;
        }
        else{
         cout << "Error: Arduino did not respond back" << endl << endl << endl;
         Sleep(1000);
         exit(0);
        }
    }
 

djsfantasi

Joined Apr 11, 2010
9,163
Very strange. Have you brought this up on the Arduino forum ?

Can you try this on another computer? And have you checked the advanced Com port settings? My laptop has buffer settings and recommends using smaller buffers if it experiences connection problems… This may not apply to you, but I throw it in as another idea.
 

THE_RB

Joined Feb 11, 2008
5,438
Are you checking the Arduino USART for framing errors etc? Normally a serial module has error flags for the errors that might occur from signal breaks (plugging in etc).

You shoudl check the error flags and reset them and clear the buffer if needed.
 

Thread Starter

kurtruk

Joined Aug 26, 2012
140
The thing is I am not using a serial monitor. I am using a C++ program that implements serial communication. If I use Arduino IDE's serial monitor it behaves exactly as it should.
 

THE_RB

Joined Feb 11, 2008
5,438
You Arduino code uses this;
incomingString[byteIndex] = Serial.read();

Does Serial.read() return an error code if there was a framing error? Or does the arduino library have some other way to clear the USART?

Also you should set your PC transmitting code to use 8N2 (ie; 2 stops bits), that will make it easier to sync and less likely to give framing errors if the baudrates are not perfect.
 

Thread Starter

kurtruk

Joined Aug 26, 2012
140
due to lack of knowledge, I am unsure what you are talking about when you say framing errors.

It communicates perfectly, you just have to start each end at the precise time. Works for me. But if there is an easy fix then I would due it in a snap. After hours of trying to get it to work, I've decided that starting both ends isn't that much of a hassle.
 

Austin Clark

Joined Dec 28, 2011
412
If you're constantly connecting and disconnecting the serial connection (instead of connecting once and continuing to stream data) I believe you could be causing the Arduino to reset. This is done whenever a new serial connection is made in order for the bootloader to work with the Arduino IDE seamlessly.
 

Thread Starter

kurtruk

Joined Aug 26, 2012
140
The only reason that I connect and reconnect is when I test after changing something in the code.
Its just a mild annoyance to have to mess with starting both ends at the same time.
 
Top