collapse

* Posts Recentes

Emulador NES em ESP32 por dropes
[13 de Março de 2024, 21:19]


Escolher Osciloscópio por jm_araujo
[06 de Fevereiro de 2024, 23:07]


TP4056 - Dúvida por dropes
[31 de Janeiro de 2024, 14:13]


Leitura de dados por Porta Serie por jm_araujo
[22 de Janeiro de 2024, 14:00]


Distancia Cabo por jm_araujo
[08 de Janeiro de 2024, 16:30]


Meu novo robô por josecarlos
[06 de Janeiro de 2024, 16:46]


Laser Engraver - Alguém tem? por almamater
[16 de Dezembro de 2023, 14:23]


Focos LED SMD por almamater
[16 de Dezembro de 2023, 14:12]


I Belive por dropes
[15 de Dezembro de 2023, 13:59]


Carga de corrente eletrónica ZPB30A1 60W por jm_araujo
[11 de Dezembro de 2023, 13:27]

Autor Tópico: GPS GPGGA, NMEA e baudrate  (Lida 5642 vezes)

0 Membros e 1 Visitante estão a ver este tópico.

Offline TMAsantos

  • Mini Robot
  • *
  • Mensagens: 5
GPS GPGGA, NMEA e baudrate
« em: 10 de Julho de 2015, 01:36 »
Boas malta, tenho uma questão que me anda a fazer confusão há algum tempo.

O meu GPS comunica em porta série (UART) com o arduino, por exemplo. Esta comunicação é feita a um baud rate de 38400.

Isto significa que transmito 38400 bits por segundo, logo demoro cerca de 0.026 ms a transmitir 1 bit. Como o NMEA transmite strings e a string do GPGGA tem aproximadamente 64 caracteres ASCII (cada 1 tem 8 bits), demoro cerca de 0.026*8 ms a transmitir 1 carácter e 0.026*8*64 a transmitir todos, o que me dá aproximadamente 13 ms, ignorando o start bit e stop bit.

Estou a fazer a leitura no arduino e a medir o tempo que a leitura demora, utilizando a função "millis()" e obtenho um tempo de aproximadamente 0-2 ms na leitura, o que é muito menos do que estava à espera.

Estou a interpretar mal o protocolo?

Obrigado pela ajuda

PS:
Exemplo de uma strinf GPGGA:
Código: [Seleccione]
$GPGGA,205526.500,3938.8970,N,00984.5289,W,1,5,1.86,84.6,M,50.7,

Offline Njay

  • Mini Robot
  • *
  • Mensagens: 3.598
    • Tróniquices
Re: GPS GPGGA, NMEA e baudrate
« Responder #1 em: 10 de Julho de 2015, 03:00 »
Não sei ao certo como escolheram implementar no Arduino, mas a leitura provavelmente é feita "em background" para um buffer (array, circular) interno da biblioteca, e quando fazes o read dos bytes esse read só está a ler do buffer. A recepção de 1 byte é feita pelo hardware, e depois é gerada uma interrupção, onde o byte *já recebido* apenas é lido de um registo e guardado no buffer, de onde depois o read lê.

Offline TMAsantos

  • Mini Robot
  • *
  • Mensagens: 5
Re: GPS GPGGA, NMEA e baudrate
« Responder #2 em: 10 de Julho de 2015, 12:54 »
Estou a utilizar a biblioteca SoftwareSerial do Arduino.
Utilizo a função read() do objecto. Se calhar está a guardar num buffer interno como dizes, mas há outra questão.
O GPS envia dados com uma frequência de 10Hz. Se eu não respeitar esta frequência na leitura, quando chamo o read(), ele manda-me um caracter que não é o inicio da string, o que me faz achar que ele não os guarda num buffer.

A função millis() pode corromper se no meio de dois millis() tiver um ciclo while a fazer a leitura, sem delays internamente?

Offline Njay

  • Mini Robot
  • *
  • Mensagens: 3.598
    • Tróniquices
Re: GPS GPGGA, NMEA e baudrate
« Responder #3 em: 10 de Julho de 2015, 13:29 »
O buffer tem um limite de tamanho, se não leres dados do buffer a tempo, os que lá estão são sobrepostos por novos bytes a chegar (ou os novos são descartados, não sei como está implementado).

Mete aí o código do teu teste.

Offline TMAsantos

  • Mini Robot
  • *
  • Mensagens: 5
Re: GPS GPGGA, NMEA e baudrate
« Responder #4 em: 10 de Julho de 2015, 14:26 »
Estive a ler melhor a documentação e é verdade, tem um buffer de 64 bytes.

O código não é totalmente meu, retirei à uns tempos de um blog, já não me lembro qual. Só fiz umas ligeiras alterações para medir o tempo.

Código: [Seleccione]
SoftwareSerial GPS(2, 3);

String reads;
int sta;

void setup () {
  Serial.begin(38400);
 
  // connect GPS RX-O to pin 2
  pinMode (2, INPUT);
  // connect GPS TX-I to pin 3
  pinMode (3, OUTPUT);
  GPS.begin(38400);

  // setup NMEA output mode.
  GPS.print("$PGCMD,16,1,1,1,1,1*6B\r\n"); 
 
  sta= millis();
}

void loop() {
  char ch = GPS.read();
  if (ch != -1){
   
    if(ch == '$'){ 
      Serial.println(millis()-sta);
      Serial.println(reads);
      sta= millis();
      reads= "$";
    } else 
    reads+=ch;
   
  }

Entretanto depois criei uma biblioteca em cpp para compactar o código, mas faz basicamente a mesma coisa.

O importante aqui é só mesmo verificar os 13 ms, que neste caso são entre 0 e 2 ms (devido ao buffer).

Offline Njay

  • Mini Robot
  • *
  • Mensagens: 3.598
    • Tróniquices
Re: GPS GPGGA, NMEA e baudrate
« Responder #5 em: 10 de Julho de 2015, 14:33 »
Humm, a coisa ainda não está bem explicada. Seria interessante saber quanto tempo demora isto a executar:

      Serial.println(millis()-sta);
      Serial.println(reads);


p.s. "char ch" é arriscar um bocado, ch devia ser int.
« Última modificação: 10 de Julho de 2015, 14:36 por Njay »

Offline TMAsantos

  • Mini Robot
  • *
  • Mensagens: 5
Re: GPS GPGGA, NMEA e baudrate
« Responder #6 em: 10 de Julho de 2015, 21:38 »
Ser char ou int não é a mesma coisa? Ele depois converte de int para ASCII por ser char.

As linhas que indicaste demoram entre 2 e 3 ms a executar, acabei de medir.


Offline Njay

  • Mini Robot
  • *
  • Mensagens: 3.598
    • Tróniquices
Re: GPS GPGGA, NMEA e baudrate
« Responder #7 em: 10 de Julho de 2015, 21:50 »
Pois, ainda há por aí qualquer coisa incoerente na explicação do curto tempo de leitura, mas se recebes bem as strings é porque o "erro" está na medição ou na configuração.

Se o GPS te enviasse 0xff provavelmente não, char e int não era a mesma coisa. Noutras plataformas poderias ter ainda outro tipo de problema, porque o char nem sempre é signed por omissão.

Offline TMAsantos

  • Mini Robot
  • *
  • Mensagens: 5
Re: GPS GPGGA, NMEA e baudrate
« Responder #8 em: 10 de Julho de 2015, 22:15 »
Fiz esta script rápida, para perceber como é que os dados chegam ao buffer:

Código: [Seleccione]
int aval = GPS.available();
  Serial.println(aval);
  if(aval >=63){
    reads="-";
    for(i=0; i<aval; i++)
      reads+= (char)(GPS.read());
    Serial.println(reads);
  }
  delay(1);

O resultado foi o seguinte:

Código: [Seleccione]
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
59
63
-$GPGGA,210610.100,XXXX.XXXX,N,XXXXX.XXXX,W,1,7,1.68,58.5,M,50.7


Basicamente dá para ver que os dados chegam com uma frequência de 10Hz, como esperado, e enchem logo o buffer (em menos de 2ms). Depois ler é num instante, claro, já está no buffer do Arduino.

Não é estranho ser em menos de 2ms? As contas no meu primeiro post não estão bem feitas?

Offline jm_araujo

  • Mini Robot
  • *
  • Mensagens: 2.943
  • NERD!
Re: GPS GPGGA, NMEA e baudrate
« Responder #9 em: 10 de Julho de 2015, 23:33 »
Isto significa que transmito 38400 bits por segundo, logo demoro cerca de 0.026 ms a transmitir 1 bit. Como o NMEA transmite strings e a string do GPGGA tem aproximadamente 64 caracteres ASCII (cada 1 tem 8 bits), demoro cerca de 0.026*8 ms a transmitir 1 carácter e 0.026*8*64 a transmitir todos, o que me dá aproximadamente 13 ms, ignorando o start bit e stop bit.
Na realidade para enviar um byte de 8 bits via série precisas de mais um start e um stop bit, portanto nas tuas contas deviam ser 0.026*10*64=16.66ms
Assim por alto parece-me que estás a o software serial, que depende de interrupts para ler os dados série, e devem maram-te os millis(), que nem sempre são de fiar.