Go Down

Topic: Serial 57600 bps with GPIO not possible? (Read 2036 times) previous topic - next topic

acid

I am using AltSoftSerial to receive data from GPS receiver at 57600 bps with Arduino UNO. GPS is set to 5Hz with 6 message types. Real data amount is ~ 24000 bps. Here is how I calculate, hope correct.

1 message is roughly 100 bytes(exaggerated). I have 6 of messages. So 100x6=600 bytes. I am receiving this with 5Hz so in 1 second I get 5x600 = 3000 bytes, which is 24000 bps.

In the main loop, I've removed any UART coomunication, to save time. So the following is my sketch:

Code: [Select]
void setup() {
  pinMode(LED_PIN_RED, OUTPUT); 
  pinMode(LED_PIN_GREEN, OUTPUT); 
  altSerial.begin(57600);
}

unsigned short prevFailed = 0;

void loop() {
  char c;
  unsigned long chars;
  unsigned short sentences, failed;

  while(altSerial.available())
  {
     c = altSerial.read();
     if(c != -1)
     {
        gps.stats(&chars, &sentences, &failed);
        if (gps.encode(c))
        {
          if(failed > prevFailed)
          {
             digitalWrite(LED_PIN_RED, HIGH);
             delay(1);
             digitalWrite(LED_PIN_RED, LOW);
             prevFailed = failed;
          }
          else
          {
             digitalWrite(LED_PIN_GREEN, HIGH);
             delay(1);
             digitalWrite(LED_PIN_GREEN, LOW);
          }
        }
     }
  }

}


TinyGPS used to parse NMEA sentences. LEDs are used to indicate success and errors. I got red LED flashing couple times in 10 second, while green LED is flashing very intensively, so good data has bigger proportion.

I know that I could connect GPS receiver to single UART on UNO, but first of all I need to debug my program, which is sensitive about data accuracy. Besides, documentation of AltSoftSerial says:

A commonly asked question is the maximum baud rate these library can support. Both can work with approximately 1 bit time of interrupt latency from OTHER code. So if other interrupts take a maximum of 15 µs (eg, some libraries), then a baud rate of 57600 ought to be possible. Without other libraries, on Teensy or Arduino (with the issue 776 fix), interrupt latency is about 3 to 4 µs. 115200 baud is possible.

However, the maximum baud rate is often not the most important question. Each library imposes interrupt latency on other libraries. AltSoftSerial causes approximately 2-3 µs latency. NewSoftSerial causes 10 bit times of latency for other libraries. Running at 57600 baud, that's 174 µs! This latency is the primary difference between AltSoftSerial and NewSoftSerial.
I have tried to increase RX_BUFFER_SIZE in AltSoftSerial.cpp to different values. No good.

So how to achieve this 57600 kbps?

CrossRoads

Does the GPS actually support output at 57.6K?
Most start at 4800 default, you have to send it a command to change the data rate.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

acid

Yes it does. It is LS20031 based on mt3339. Connecting GPS to PC with 57600 will produce no error.

Paul Stoffregen

#3
Nov 11, 2012, 02:45 am Last Edit: Nov 11, 2012, 02:54 am by Paul Stoffregen Reason: 1
Have you tried something like this, with Serial set to 115200?

Code: [Select]

void loop() {
 if (altSerial.available()) {
   char c = altSerial.read();
   Serial.write(c);
 }
}


Does all the data appear in the serial monitor, or is something clearly something missing?

Also, does your program work with slower update rates, like 4 Hz or 1 Hz ?

Another question would be if TinyGPS is capable of 5 Hz operation on 8 bit AVR?  It does a lot of float and 32 bit long math.  Can you try driving a pin high right before the call to TinyGPS stuff and low right after, like this:

Code: [Select]

        digitalWrite(2, HIGH);
        gps.stats(&chars, &sentences, &failed);
        boolean result = gps.encode(c);
        digitalWrite(2, LOW);


Just measure pin 2 with a multimeter.  If you have a duty cycle measurement, use it.  Otherwise, just look at the approximate average voltage.  If it's tiny, then not much CPU time is being spent inside TinyGPS.  But it it's something like 3 volts, then the number crunching might be too much for AVR-based Arduino.

acid


Have you tried something like this, with Serial set to 115200?

Code: [Select]

void loop() {
 if (altSerial.available()) {
   char c = altSerial.read();
   Serial.write(c);
 }
}


Does all the data appear in the serial monitor, or is something clearly something missing?

I have tried that and that's why I eliminated HW serial output to see if this is causing issue. Data is corrupting once in 3-10 second.
Receiving $@PGSA,A,1,,,,,,,,,,,,,,,*1E instead of $GPGSA,A,1,,,,,,,,,,,,,,,*1E
Receiving $@PRMC,073405.491,V,,,,,0.00,0.00,111112,,,N*47 insted of $GPRMC...
Strage, that only G character gets overwrited with @.

Quote


Also, does your program work with slower update rates, like 4 Hz or 1 Hz ?

Another question would be if TinyGPS is capable of 5 Hz operation on 8 bit AVR?  It does a lot of float and 32 bit long math.  Can you try driving a pin high right before the call to TinyGPS stuff and low right after, like this:

Code: [Select]

        digitalWrite(2, HIGH);
        gps.stats(&chars, &sentences, &failed);
        boolean result = gps.encode(c);
        digitalWrite(2, LOW);


Just measure pin 2 with a multimeter.  If you have a duty cycle measurement, use it.  Otherwise, just look at the approximate average voltage.  If it's tiny, then not much CPU time is being spent inside TinyGPS.  But it it's something like 3 volts, then the number crunching might be too much for AVR-based Arduino.


I've measured with multimeter. Frequency is about 3Khz, duty cycle is 4.5%. Not sure if this is fine.

Osgeld

maybe the wrong part for the application, use a 644 or any of the other handful of arduino compatible chips with more than one hardware uart
http://arduino.cc/forum/index.php?action=unread;boards=2,3,4,5,67,6,7,8,9,10,11,66,12,13,15,14,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,86,87,89,1;ALL

acid

#6
Nov 11, 2012, 09:05 am Last Edit: Nov 11, 2012, 06:23 pm by acid Reason: 1

maybe the wrong part for the application, use a 644 or any of the other handful of arduino compatible chips with more than one hardware uart


Price-wise 644 is much more expensive comparing with 328. Also I want to make sure that it's impossible to get 57600 bps on 328.

acid

#7
Nov 11, 2012, 09:24 am Last Edit: Nov 11, 2012, 10:51 am by acid Reason: 1

Also, does your program work with slower update rates, like 4 Hz or 1 Hz ?


I've just tested with 1Hz, with the same simple program presented in first post. Error rate decreased, but still can see the red LED blinking like once per 10 sec. I just guess that this is related to the strange '@' char.

Update:
Indeed. Tested with Serial output (GPS 1Hz) and '@' character appears occasionally in the sentence(this time at random locations), overwriting the right character.

This is the list off erroneous sentences received through serial:
http://pastebin.com/DgDkygPR

Paul Stoffregen

Ouch.  Maybe it's a bug in AltSoftSerial?

Could you try sending the data from a PC to AltSoftSerial's receive pin at 57600, with the sketch sending it back to the serial monitor at 115200?

If that also shows the problem, could you please send me the exact code and specific details of the hardware, operating system, software versions and everything else you're using, so I can try to set up the same system here and see if I can reproduce the problem?

acid

I'm trying to do it now. I see you are trying to eliminate the possibility of GPS of sending wrong data, but again, if I connect GPS directly to PC, there is no error at all.

Paul Stoffregen

Actually, I do believe the GPS is sending good data.

I simply don't have that GPS unit.... so I'm hoping for a test that I can reproduce here with the equipment I have.

acid

Got it. Will get you some result shortly.

acid

Paul, I think I have good news for you :) I was able to reproduce it with Serial2Serial scenario like you described and hit to same '@' symbol.
Let me summarize shortly.

acid

1. Arduino UNO as prototype platform with Arduino 1.0.1 IDE + Latest AltSoftSerial library
2. Exact code I copied from sketch

Code: [Select]
#include <AltSoftSerial.h>

AltSoftSerial altSerial;

void setup() {
  Serial.begin(115200);
  altSerial.begin(57600);
}

void loop() {
if (altSerial.available()) {
    char c = altSerial.read();
    Serial.write(c);
  }
}


3. Windows 7 is operating system, but not sure how it may be related.
4. For Serial2Serial test I was using simple C# app I made (let me know if you will need it) which is sending the following pattern every 1 second.

Code: [Select]
            serialPort.WriteLine("$Lorem ipsum dolor sit amet, consectetur adipiscing elit *EA");
            serialPort.WriteLine("$Ut enim ad minim veniam, quis nostrud exerc *EB");
            serialPort.WriteLine("$Tia non ob ea soluad incommod quae egen ium improb fugiend *EC");


This time the characters are randomly replaced with '`' as you can see here
Note, that if text is little bit shorter, longer or maybe different, then '@' character appears.

Let me know if you need more information.
Thanks!

acid

After testing more, the problem is not consistent. Each time I reset the board, I get new type of data corruption. It's no more only '`'` and '@'. Randomly bytes are corrupted...

Hope you can solve it.

Go Up