Skocz do zawartości

Jak sprawdzić ustawioną częstotliwość - Ublox NEO-7M


czarobest

Pomocna odpowiedź

Cześć, tworzę sobie właśnie mały logger maksymalnej prędkości do modeli RC, a pewnie zrobię też sobie program do pomiaru przyśpieszenia samochodu :).  Po kliku godzinach przeszukiwania internetu i uczenia się obsługi modułu udało mi się doprowadzić do działania GPS Ublox NEO-7M wraz z wyświetlaczem OLED 128x64 na I2C. Początkowo okazało się że proste biblioteki niestety chyba zajmują sporo ramu i wyświetlacz nie chciał się zainicjować, w związku z tym użyłem biblioteki NeoGPS, po konfiguracji różnych plików i metodą prób i błędów (bo konsola w arduino IDE pokazywała błędy mimo postępowania zgodnie z instrukcją twórcy biblioteki 🙂 ) działa to chyba dobrze. Mam jednak zagwozdkę czy dobrze ustawiłem odświeżanie modułu GPS, a chciałbym żeby było to 10HZ. Dlatego pytam czy jest jakiś sposób by to sprawdzić? Nie mam niestety jak podłączyć modułu do komputera żeby sprawdzić to w programie Ublox'a,  chyba że da się to zrobić poprzez Arduino?

Miałem pomysł, by wyświetlać milisekundy z gps'a na ekranie, ale właśnie to jest rzecz która nie działa - pokazuje 0. Funkcja z sekundami za to działa, ale ona mi nic nie da 🙂.  Tutaj też przydałaby mi się pomoc, bo chyba funkcja fix.dateTime_ms() powinna działać poprawnie...

Załączam kod, który zrobiłem by testować czy GPS w ogóle działa, może będzie potrzebny :). Wersja Arduino to Nano. Program działa tzn. pokazuje dokładnie odległość, wysokość oraz ilość satelit jednak zamiast milisekund pokazuje 0.

#include <NMEAGPS.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

#include <GPSport.h>

#if !defined( NMEAGPS_PARSE_RMC ) &  \
    !defined( NMEAGPS_PARSE_GGA ) &  \
    !defined( NMEAGPS_PARSE_GLL )
  #error You must uncomment at least one of NMEAGPS_PARSE_RMC, NMEAGPS_PARSE_GGA or NMEAGPS_PARSE_GLL in NMEAGPS_cfg.h!
#endif

#if !defined( GPS_FIX_LOCATION )
  #error You must uncomment GPS_FIX_LOCATION in GPSfix_cfg.h!
#endif

NMEAGPS gps;

// The base location, in degrees * 10,000,000
NeoGPS::Location_t base( 522109790L, 209505030L ); // Warszawa
                         


void setup()
{
   Serial.begin(9600);
  Serial.println( F("Date              Time             Latitude         Longitude\n") );
  Serial.flush();
  
  gpsPort.begin( 9600 );
  gpsPort.print( F("$PMTK251,115200*1F\r\n") ); // set 115200 baud rate
  gpsPort.flush();                              // wait for the command to go out
  delay( 100 );                                  // wait for the GPS device to change speeds
  gpsPort.end();                                // empty the input buffer, too

  gpsPort.begin( 115200 );                      // use the new baud rate
  gpsPort.print( F("$PMTK220,100*2F\r\n") );    // set 10Hz update rate    

  
  
  delay(100);
  
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }

  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0, 0);
  display.println(F("TEST"));
  display.display();

  
} // setup

void loop()
{
  
  while (gps.available( gpsPort )) {
    gps_fix fix = gps.read(); // save the latest

    // When we have a location, calculate how far away we are from the base location.
    if (fix.valid.location) {
      float range = fix.location.DistanceMiles( base );
      int alt = fix.alt.whole;
      int data = fix.dateTime.date;
      int satelity = fix.satellites;
      DEBUG_PORT.print( F("Range: ") );
      DEBUG_PORT.print( range );
      DEBUG_PORT.println( F(" Miles") );
      float rangekm = range * 1.609344;
      display.clearDisplay();
      display.setTextSize(1);
      display.setTextColor(WHITE);
      display.setCursor(0, 0);
      display.println(F("Dystans do Warszawy: "));
      display.println(rangekm);
      display.println(F("Wysokosc: "));
      display.println(alt);
      display.println(F("Milisekundy: "));
      display.println(fix.dateTime_ms());
      display.println(F("Satelity: "));
      display.println(satelity);
      display.display();
      
    } else
      // Waiting...
      DEBUG_PORT.print( '.' );
    }

} // loop

 

 

Link do komentarza
Share on other sites

A nie jest problemem wielokrotne inicjowanie zmiennych fix, alt, data wewnątrz pętli while w funkcji Loop? Wydaje mi się, że arduino, za każdym razem przydzieli nową pamięć na te same zmienne i w końcu pamięć RAM Ci się kończy i pokazuje głupoty. Ja bym wyrzucił deklaracje zmiennych przed while….

Edytowano przez Szałszanin
Link do komentarza
Share on other sites

(edytowany)

Przerabiałem przykład w którym już była zmienna "float range" w środku i jakoś tak z lenistwa robiłem nowe w środku :). Głupot nie pokazywało poza tym zerem przy milisekundach.

Ale generalnie też tak myślałem i w już prawie skończonym loggerze mam wszystkie zmienne zainicjowane przed pętlą. Program mi na razie działa, ale dokładne pomiary zrobię jak będę jechał autem. Na razie wiem, że wysokość jest poprawna, współrzędne również. Jedyny problem mam z tym, że nie wiem czy odświeżanie działa tak jak chcę czyli 10Hz czy tylko na 1Hz.

 

EDIT: Dla pewności i w tym kodzie wrzuciłem wszystko przed pętle, niestety milisekundy to dalej 0. Zamiast tego wrzuciłem pokazanie wartości z funkcji millis() i z tego co widzę rośnie skokowo o mniej więcej 1000 czyli program odświeża się raczej co sekundę. Teraz tylko nie wiem co zrobić by było 10Hz.

 

EDIT2: Teoretycznie użyłem programu ubloxRate z biblioteki NeoGPS, ale dalej jest jak wyżej. Nie wiem na razie o co chodzi ale będę próbował dalej jutro.

 

EDIT3: Po wykonaniu polecenia w konsoli przy uruchomieniu programu ubloxRate widać, że GPS przesyła dane szybciej jednak po odłączeniu go od komputera przywraca się znowu do 1Hz. Coś mogę na to poradzić?

 

EDIT4: Edytuję znowu bo udało mi się zmusić moduł do pracy w wyższej częstotliwości, teraz jednak mam problem, bo program wyświetla dane przez około sekundę po czym się zawiesza (ekran przestaje się aktualizować). Pewnie następuję jakieś przepełnienie tylko nar razie nie wiem jak to rozwiązać.

EDIT5: Ostatecznie program przestał się zawieszać choć zdarza się jeszcze, że widać jakby spowolnienie przy wyświetlaniu milisekund, ale za to nie blokuje się całkowicie. Czyli idzie w dobrym kierunku (chyba 😛

Wrzucam fragmenty, którymi udało mi się zmusić moduł do działania na 10Hz, może komuś się to przyda 🙂 To wszystko jest jako dodatek do kodu powyżej.

#include <Streamers.h>
#include <NeoGPS_cfg.h>
#include <ublox/ubxGPS.h>
#include <NeoTeeStream.h>
#include <GPSport.h>

const unsigned char ubxRate10Hz[] PROGMEM =
  { 0x06,0x08,0x06,0x00,100,0x00,0x01,0x00,0x01,0x00 };

const unsigned char ubxRate5Hz[] PROGMEM =
{ 0x06,0x08,0x06,0x00,200,0x00,0x01,0x00,0x01,0x00 };

void sendUBX( const unsigned char *progmemBytes, size_t len )
{
  gpsPort.write( 0xB5 ); // SYNC1
  gpsPort.write( 0x62 ); // SYNC2

  uint8_t a = 0, b = 0;
  while (len-- > 0) {
    uint8_t c = pgm_read_byte( progmemBytes++ );
    a += c;
    b += a;
    gpsPort.write( c );
  }

  gpsPort.write( a ); // CHECKSUM A
  gpsPort.write( b ); // CHECKSUM B

} // sendUBX


void setup()
{
  gpsPort.begin( 9600 );
  sendUBX( ubxRate10Hz, sizeof(ubxRate10Hz));  //  set 10Hz
  delay(2000);
} 

Plus w konfiguracji pliku NMEAGPS_cfg.h

#define NMEAGPS_PARSE_GGA
//#define NMEAGPS_PARSE_GLL
//#define NMEAGPS_PARSE_GSA
//#define NMEAGPS_PARSE_GSV
//#define NMEAGPS_PARSE_GST
#define NMEAGPS_PARSE_RMC
//#define NMEAGPS_PARSE_VTG
//#define NMEAGPS_PARSE_ZDA

//------------------------------------------------------
// Select which sentence is sent *last* by your GPS device
// in each update interval.  This can be used by your sketch
// to determine when the GPS quiet time begins, and thus
// when you can perform "some" time-consuming operations.

#define LAST_SENTENCE_IN_INTERVAL NMEAGPS::NMEA_RMC

A dodatkowo wrzuciłem wszystko po "while (gps.available( gpsPort )) { " w "if (millis() - last > 20)"  tak jak tutaj:


void loop()
{   
    while (gps.available( gpsPort )) 
    {
    	if (millis() - last > 20)
    	{
   				//tutaj główna część programu, odczyt danych, wyświetlanie
    	} 
    }
}

I po tym wszystkim program nie blokuje się, jak na razie, nawet po kliku minutach pracy.

Edytowano przez czarobest
  • Lubię! 1
Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.