Skocz do zawartości

TEENSY 4.0 - niestabilne załączanie i wyłączanie GPS z wyświetlacza NEXTION


keram167

Pomocna odpowiedź

Witam Wszystkich !

Próbuję zrobić programowe załączanie i wyłączanie zasilania modułu GPS poprzez ekranowe przyciski na wyświetlaczu Nextion i sterowanego z Teensy 4.0.  Przełączanie przyciskami z poziomu NEXTION-a działa prawidłowo dopóki mam zakomentowaną zakładkę "GPS", tzn. każde naciśnięcie przycisku "GPS ON" na wyświetlaczu NEXTION załącza zasilanie modułu GPS ( sygnalizacja LED-em ) i każde naciśnięcie przycisku "GPS OFF" powoduje jego wyłączenie.

Problem zaczyna się gdy zakładka "GPS" w programie zostaje odkomentowana. Da się załączyć zasilanie GPS-u prawidłowo lecz wyłączenie nie działa już za każdym razem, mimo naprzemiennego naciskania przycisków "GPS ON" i "GPS OFF" . W tym przypadku moduł GPS, jeśli zostanie zasilony, prawidłowo pobiera wszystkie dane i jeśli zostanie wyłączony to się prawidłowo wyłączy. Opcja ON-OFF dla GPS ma na celu oszczędność zużycia akumulatora, który zasila całość. 

I trochę "technikalii" : napięcie sterujące ( zasilające moduł GPS ) 3,3V jest podawane z pinu 21 TEENSY 4.0 poprzez  IRLML2502 ( MOSFET N - takie akurat miałem dostępne), użyte TEENSY 4.0, GPS - GB-1803, NEXTION z serii Intelligent NX8048P050 a software to WIN11 64, Arduino IDE 1.8.19 z nakładką Teensyduino 1.56, uproszczona biblioteka do NEXTION-a, TinyGPSPlus.h ( linki w programie ). GPS podłączony do TEENSY przez Serial4, NEXTION przez Serial2 (sprzętowo), całość polutowana na płytce uniwersalnej. Program mam w 3 zakładkach, są dołączone ale nie wiem czy będzie to czytelne 😔. Poglądowe fotki w załączeniu.

Męczę się z tym już od jakiegoś czasu i chyba dopadła mnie "mgła covidowa", bo nie umiem znaleźć rozwiązania tego problemu. Więc na koniec - cytując klasyka - "pomożecie ? .... 😉" . Z góry dzięki za wsparcie ! 

#include <Nextion.h>                  // biblioteka https://github.com/bborncr/nextion
#define HardwareSerial2
Nextion myNextion(nextion, 115200);   // max 921600

#include <TinyGPSPlus.h>              // biblioteka https://github.com/mikalhart/TinyGPSPlus
#define HardwareSerial4               // GPS GB-1803 podpięty przez HardwareSerial4
TinyGPSPlus gps;                      // GPS
#define pinGPS 21                     // GPS załączanie modułu z pinu 21

float LON_GPS = 18.817930;            // długość geograficzna   : dane z GPS 18.817930
float LAT_GPS = 49.897415;            // szerokość geograficzna : dane z GPS 49.897415
float LON_GEO = 18.4939;              // długość geograficzna   : 18°49′39″E
float LAT_GEO = 49.5408;              // szerokość geograficzna : 49°54′08″N

void setup()
{
  Serial.begin(115200);
  Serial2.begin(115200);               // NEXTION    => Serial 2 (max. 921600)
  Serial4.begin(115200);               // GPS GB1803 => Serial 4
  myNextion.init();                    // inicjalizacja wyświetlacza
  pinMode(pinGPS, OUTPUT);             // ON-OFF GPS
  digitalWrite(pinGPS, LOW);
}
void loop()
{
  BUTTONS();
  GPS();
}
void BUTTONS()
{
  while (Serial2.available() > 0)
  {
   boolean oldGPSButtonOnState = LOW;
   boolean newGPSButtonOnState = LOW;
   boolean oldGPSButtonOffState = LOW;
   boolean newGPSButtonOffState = LOW;
   boolean GPSOut = LOW;
   String message = myNextion.listen();          
   int buttonGPS_ON  = (message == "GPS_ON");                  // (message == "65 0 c 0 ff ff ff")
   int buttonGPS_OFF = (message == "GPS_OFF");                 // (message == "65 0 1d 0 ff ff ff")

// ========== ZAŁĄCZ GPS ========================================================================
  newGPSButtonOnState = buttonGPS_ON;
  if ( newGPSButtonOnState != oldGPSButtonOnState )
   {
    if ( newGPSButtonOnState == HIGH )
    {
      if ( GPSOut == LOW ) 
      {
        digitalWrite(pinGPS, HIGH);
        GPSOut = HIGH;
      }
      else                    
      {
        digitalWrite(pinGPS, LOW);
        GPSOut = LOW;
      }
      if (message != "")                                   
      {
        Serial.println(message);                          
      }
    }
    oldGPSButtonOnState = newGPSButtonOnState;
  }
// ========== WYŁĄCZ GPS ========================================================================

  newGPSButtonOffState = buttonGPS_OFF;
  if ( newGPSButtonOffState != oldGPSButtonOffState )
   {
    if ( newGPSButtonOffState == HIGH )
    {
      if ( GPSOut == LOW ) 
      {
        digitalWrite(pinGPS, LOW);
        GPSOut = LOW;
      }
      else                    
      {
        digitalWrite(pinGPS, HIGH);
        GPSOut = HIGH;
      }
     }
      if (message != "")                                    
      {
       Serial.println(message);                             
      }
    oldGPSButtonOffState = newGPSButtonOffState;
   }
  }
}
void GPS()
{  
  printInt(gps.satellites.value(), gps.satellites.isValid(), 5);
  printFloat(gps.hdop.hdop(), gps.hdop.isValid(), 6, 1);
  printFloat(gps.location.lat(), gps.location.isValid(), 11, 6);
  printFloat(gps.location.lng(), gps.location.isValid(), 12, 6);
  printInt(gps.location.age(), gps.location.isValid(), 5);
  printDateTime(gps.date, gps.time);
  printFloat(gps.altitude.meters(), gps.altitude.isValid(), 7, 2);
  printFloat(gps.course.deg(), gps.course.isValid(), 7, 2);
  printFloat(gps.speed.kmph(), gps.speed.isValid(), 6, 2);

// ========== DANE ======================================================================================================================================
  if (gps.location.isValid())
  {
    myNextion.setComponentText("t1700", "ONLINE");
    myNextion.sendCommand("t1700.pco=65509");                                // zmiana koloru czcionki na żółty na NEXTION
    
    char GPSLatitude[12];
    sprintf(GPSLatitude, "%.6f\xB0", gps.location.lat());
    myNextion.setComponentText("t1703", GPSLatitude);
    
    char GPSLongitude[12];
    sprintf(GPSLongitude, "%.6f\xB0", gps.location.lng());
    myNextion.setComponentText("t1704", GPSLongitude);
  }
  else
  {
    myNextion.setComponentText("t1700", "OFFLINE");
    myNextion.sendCommand("t1700.pco=2047");                                 // niebieski

    char GPSLatitudeStatic[12];
    sprintf(GPSLatitudeStatic, "%.6f\xB0", LAT_GPS);
    myNextion.setComponentText("t1703", GPSLatitudeStatic);
    
    char GPSLongitudeStatic[12];
    sprintf(GPSLongitudeStatic, "%.6f\xB0", LON_GPS);
    myNextion.setComponentText("t1704", GPSLongitudeStatic);
  }
    char geoLatitudeStatic[12];                                              // myNextion.setComponentText("t1705", String (LAT_GEO, 4 ) + "\xB0");
    sprintf(geoLatitudeStatic, "%.4f\xB0", LAT_GEO);
    myNextion.setComponentText("t1705", geoLatitudeStatic);
    
    char geoLongitudeStatic[12];                                             // myNextion.setComponentText("t1706", String (LON_GEO, 4 ) + "\xB0");
    sprintf(geoLongitudeStatic, "%.4f\xB0", LON_GEO);
    myNextion.setComponentText("t1706", geoLongitudeStatic);

    myNextion.setComponentText("t1708", gps.satellites.value());
    myNextion.setComponentText("t1712", String (gps.location.age(), 5));

    char GPSAltitude[7];
    sprintf(GPSAltitude, "%.2f m", gps.altitude.meters());
    myNextion.setComponentText("t1707", GPSAltitude);

    char HDOP[5];
    sprintf(HDOP, "%.1f", gps.hdop.hdop());
    myNextion.setComponentText("t1709", HDOP);
   
    char GPSCourse[7];
    sprintf(GPSCourse, "%.2f", gps.course.deg());
    myNextion.setComponentText("t1710", GPSCourse);

    char GPSSpeed[7];
    sprintf(GPSSpeed, "%.2f km/h", gps.speed.kmph());
    myNextion.setComponentText("t1711", GPSSpeed);
    smartDelay(100);
}

static void smartDelay(unsigned long ms)
{
  unsigned long start = millis();
  do
  {
    while (Serial4.available())
    gps.encode(Serial4.read());
  }
  while (millis() - start < ms);
}

static void printFloat(float val, bool valid, int len, int prec) {}
static void printInt(unsigned long val, bool valid, int len) {}

static void printDateTime(TinyGPSDate &d, TinyGPSTime &t)
{
  if (t.isValid())
  {
    char GPSTime[18];
    sprintf(GPSTime, "%02dh %02dm %02ds (UTC)", t.hour(), t.minute(), t.second());
    myNextion.setComponentText("t1701", GPSTime);
  }
  if (d.isValid())
  {
    char GPSDate[11];
    sprintf(GPSDate, "%02d-%02d-%02d ", d.day(), d.month(), d.year());
    myNextion.setComponentText("t1702", GPSDate);
  }
  printInt(d.age(), d.isValid(), 5);
  smartDelay(50);
}

 

GPS OK.jpg

GPS BŁĄD.jpg

NEXTION GPS ON.jpg

NEXTION GPS OFF.jpg

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

Funkcja BUTTONS() to jakaś niedokończona się wydaje...
Nie bardzo rozumiem logiki funkcji GPS().
Warunek gps.location.isValid() dotyczy sytuacji kiedy gps "złapał fixa", więc jego sprawdzanie do wyłączania zasilania nie ma raczej sensu.

Link do komentarza
Share on other sites

Faktycznie - nie zauważyłem że to trzy osobne fragmenty kodu.

Wg mnie ta funkcja smartdelay to nieporozumienie.

Enkodowanie NMEA przeniósłbym do loop() i jeżeli konieczne są jakieś opóźnienia w wywoływaniu GPS(), to również bym je realizował w głównej pętli.

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Witam Wszystkich !

12 godzin temu, kostuch napisał:

Wg mnie ta funkcja smartdelay to nieporozumienie.

@kostuch możesz podpowiedzieć dlaczego tak uważasz ?

Testowo zakomentowałem w zakładce "GPS"  linię 67, gdzie jest użyte smartdelay i efekt był taki, że całkowicie przestało działać ON-OFF zasilanie dla GPS-a. No i pojawił się "warning" ale to normalne. Po odkomentowaniu w/w linii, wgraniu nie modyfikowanego kodu do TEENSY, moduł GPS prawidłowo pobiera dane (fotka).  Funkcję "smartdelay" nie ja sobie wymyśliłem, ale jest ona użyta w przykładach dołączonych do biblioteki TinyGPSPlus a z których korzystałem.

Pozdrowienia Wszystkim !
 

smartdelay.jpg

GPS OK.jpg

Link do komentarza
Share on other sites

Chodzi mi o to, że blokujesz wykonywanie programu (czyli BUTTONS() nie wykona się do momentu zakończenia opóźnienia przez smartdelay).

Przyciski chcesz sprawdzać nonstop, więc wywołujesz z loop() - ok.

Próbować czytać nowe dane z gps też powinieneś nonstop, więc gps.encode() powinno być w loop().

Wyświetlać dane z gps chcesz co jakiś czas, więc z loop() powinieneś wywoływać GPS() co jakiś czas, ale już bez żadnych opóźnień wewnątrz tej funkcji.

 

Link do komentarza
Share on other sites

Ciekawe, też myślałem że problemem jest odczyt z serial2, ale teensy 4.0 ma niby 4 bajtowy bufor, wiec dla krótkiego komunikatu powinno działać. Ale skoro nie działa, to może problem jest gdzie indziej. Czy serial2 to sprzętowy uart, czy SoftSerial?

Link do komentarza
Share on other sites

Zarówno Serial2 (NEXTION) jak i Serial4(GPS) są sprzętowe. Zmieniałem podłączenie GPS-a na Serial3 ale bez powodzenia. W przypływie "czarnej rozpaczy"  😉 pokusiłem się na zmianę szybkości transmisji na 921600 - to samo, zmieniałem szybkość procka w TEENSY na 600MHz ( obecnie 150MHz ) - bez zmian. "Pobawię" się jeszcze z kodem - to co zasugerował Kolega @kostuch

 

Link do komentarza
Share on other sites

To może jeszcze jeden test - czy jeśli wywołanie GPS() zastąpisz czekaniem (Delay) przez powiedzmy 200ms, to program będzie działał? Wydaje mi się, że dla krótkich komend, czyli "Z" i "W" powinien działać, natomiast dla długich "GPS_ON"/"GPS_OFF" ma prawo mieć problemy. Ale warto byłoby to sprawdzić.

Bo jeśli działa dla "Z" i "W" to raczej problem nie wynika z przepełniania bufora Serial2 i może trzeba poszukać innej przyczyny.

Link do komentarza
Share on other sites

Witam.

Przepraszam, że dopiero teraz się odzywam, ale małe problemy ze zdrówkiem i duże z Zakładem Udręki Społecznej spowodowały, że musiałem trochę odpuścić testy 😔.

@Elvis - zrobiłem inny "myk" niż sugerowałeś a mianowicie mocno wydłużyłem nazwy komend, lecz niestety z takim samym efektem jak przy nazwach krótkich. Przy zakomentowanej w loop() zakładce "GPS" przełączanie odbywa się prawidłowo za każdym, naprzemiennym naciskaniem przycisków ekranowych. Po jej odkomentowaniu przełączanie jest chaotyczne i niejednoznaczne. Więc, jak sugerowałeś w poprzednim poście - przyczyna będzie tkwiła w innym miejscu.

@kostuch- próbuję i walczę dalej ale na razie też nie mam pozytywnych efektów. Muszę się zastanowić, czy jakoś inaczej nie napisać tego kodu... Może testowo, na próbę, wstawię zamiast GPS-a ( z tymi opóźnieniami ) coś innego np. BME280 ...

Pozdrawiam i dużo zdrówka Wszystkim !!!

PRZYCISKI LONG.jpg

Link do komentarza
Share on other sites

@kostuch - sprawdziłem, przetestowałem Twoje propozycje ale efekt końcowy identyczny jak w poprzednich przypadkach.

Sprawdzałem też "przy okazji" z krótkimi i długimi nazwami przypisanymi dla przycisków ale bez efektu. Dlatego, przy dalszym testowaniu, zostanę przy pierwotnym nazewnictwie przycisków tzn. "GPS_ON" oraz "GPS_OFF". 

Pozdrawiam.

Link do komentarza
Share on other sites

Dobry Wszystkim 😀

Już trochę czasu upłynęło, więc chciałem zakończyć ten wątek. Niestety nie udało mi się w sposób satysfakcjonujący zrobić tego sterowania wykorzystując oprogramowanie Teensy więc spróbowałem zaciągnąć do roboty sam wyświetlacz Nextion - seria Intelligent. Wykorzystałem jedno GPIO ze złącza w jakie jest wyposażony ten wyświetlacz, oprogramowałem jako wyjście i to okazało się w 100% skuteczne i spełniające moje założenia tj. wykonanie załączania i wyłączania zasilania modułu GPS za pomocą ekranowych przycisków i zaoszczędzenie ok. 50 mA prądu, w sytuacji gdy GPS jest nie używany. Uproszczeniu uległ też sam kod - usunąłem niepotrzebną już zakładkę "BUTTONS".

@Elvis , @kostuch WIELKIE dzięki za Waszą pomoc, podpowiedzi i poświęcony czas 👍

nextion.jpg

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.