meshtastic / firmware

Meshtastic device firmware
https://meshtastic.org
GNU General Public License v3.0
3.63k stars 907 forks source link

Meshtastic turns on UBX protocol (and turns NEMA off) some other sketches don't work with UBX #334

Closed bigal488 closed 3 years ago

bigal488 commented 4 years ago

Describe the bug After running Meshtastic, other sketches that use GPS on the TBeam will fail to read data from the GPS.

To Reproduce A known working T-Beam v1.1 2021212 successfully running ttgo-tbeam-ttn-tracker. It acquires a GPS lock within 30 seconds of boot. TTNTracker1

Flashed Meshtastic (firmware-tbeam-EU865-0.9.1.bin). GPS fix within a few minutes. All good so far. meshtastic1

Then flashed the same ttgo-tbeam-ttn-tracker using the Arduino IDE. No GPS. Waited. Still no GPS. The red GPS led is flashing to show theres a hardware lock but no sats showing in the sofware. TTNTracker-NoGPS

Flashed firmware-tbeam-EU865-0.9.1.bin again - GPS fix within a few minutes, then flashed a test sketch to see raw GPS output from the T-Beam Serial1 and theres no serial comms - no output using: Serial1.begin(9600, SERIAL_8N1, 34, 12);

I suspect that Meshtastic has changed some parameters in the GPS NVRam which means it is now not standard. However resetting the GPS by shorting the GPS battery did not resolve the issue,

Device info: TBEAM v1.1 20201212 NEO 6M GPS

bigal488 commented 4 years ago

We now have three t-beams that used to have working GPS with no GPS after flashing Meshtastic and then other SW. A further 6 that came from LilyGO with Meshtastic pre-installed have no GPS (out of the box)

kizniche commented 4 years ago

I can confirm both my 0.7 and 1.0 devices are unable to use the GPS after using meshtastic and then going back to ttn-tracker.

bigal488 commented 4 years ago

I can confirm both my 0.7 and 1.0 devices are unable to use the GPS after using meshtastic and then going back to ttn-tracker.

Hope the Meshtastic devs can offer a solution as I now have 9 T-beam shaped paperweights!

geeksville commented 4 years ago

Meshtastic turns on UBX protocol (because it saves power and provides better control on the rate of updates). That setting is saved inside of the Ublox GPS.

I'm assuming based on this report that the ttn code only uses NMEA protocol (which was true when I was adding code to that project). You'll need to add something to your sketch to turn UBX off and NMEA back on. Alternatively if it would help I could add a feature to meshtastic to leave NMEA also on (though we don't need it) but probably can't do that until I fix some meshtastic bugs first.

geeksville commented 4 years ago

(and I understand you are frustrated - but it isn't really feasible for a project like this to consider/support all the other projects out there that might run on a board. I'll try to help, but IMO not super helpful to say meshtastic broke your boards ;-) )

geeksville commented 4 years ago

This issue has been mentioned on Meshtastic. There might be relevant details there:

https://meshtastic.discourse.group/t/t-beam-neo-6-nmea-output-has-stopped-working/1093/17

kizniche commented 4 years ago

@geeksville Thank you for the detailed responses. I'll investigate how to change the mode and see if I can integrate it into ttn-tracker.

geeksville commented 4 years ago

The ublox datasheet will have a better description but I think all you'll need to do is hand-craft a packet that forces the radio to factory reset. (UBX_CLASS_CFG / UBX_CFG_CFG in their docs). It might even be possible to find in googles (I haven't checked) someone has already figured out what that sequence of bytes (with the header and CRC) is.

bigal488 commented 4 years ago

(and I understand you are frustrated - but it isn't really feasible for a project like this to consider/support all the other projects out there that might run on a board. I'll try to help, but IMO not super helpful to say meshtastic broke your boards ;-) )

I apologise for that. From my perspective 6 boards arrived from LilyGo/AliExpress with meshtastic pre-installed and the gps on all hasnt worked from the get go (as supplied). I'm sure you can appreciate that that this difficult and we still haven't been able to find a resolution.

Testing with meshtastic in order to resolve has caused more boards (that were working) to fail to be able to use the gps...

geeksville commented 4 years ago

I understand and I'm sorry for that. I'll add some support (in the next couple of weeks if the awesome @kizniche can't do his great idea) for helping you out - but I was never planning on "other projects might be missing some GPS init code and therefore might not work after meshtastic has configured the GPS how it required"

bigal488 commented 4 years ago

Many thanks. One question. With the affected devices we're not seeing any raw output at all from the gps serial port at 9600 8N1 even when the gps lock led is flashing. Is it possible that Meshtastic has changed the Ublox hardware baud therefore explaining the lack of serial Comms?

Andy1968T commented 4 years ago

If you need to revert back to factory setting to just receive NMEA 9600 GPS strings for the use with other programs like TinyGPS++ for Arduino Follow this thread. It will get your GPS going as a one way GPS constant streaming NMEA again.
https://meshtastic.discourse.group/t/gps-does-not-work-in-my-application-after-installing-mestastic/1090

geeksville commented 4 years ago

@bigal488 no - the baud rate is still 9600 baud. I bet what you are seeing is that the UBX protocol is bidirectional (as opposed to NEMA which just emits ascii at a certain rate). The host needs to send the GPS a command to ask for the latest solution (this is important when trying to (eventually) get sub second level timing - so we can keep the mesh mostly asleep - including receivers). If the host isn't asking for stuff the device probably isn't talking.

(There is an auto-pvt mode which we don't use that does have periodic unprompted transmissions from the GPS)

smack815 commented 4 years ago

@geeksville Why don't you make it a board type that just sets the GPS back to NEMA and does nothing else. That way it could be deployed by the App as an upgrade... and if you keep enough boot loader logic they could re-deploy meshtastic again if they change their mind via the app.

eriktheV-king commented 4 years ago

Hello I've modified a LilyGO sketch with SparkFun libraries to help you out to reset U-blox NEO GPS devices on TTGO T-beam T22- V1.0 and 1.1 This sketch will bring back U-blox GPS N6M & N8M factory settings so that NMEA 9600 over the GPS serial output is enabled. You can download this sketch on my GitHub: https://github.com/eriktheV-king/TTGO_T-beam_GPS-reset It worked fine for my 5 T-beams... good luck !

geeksville commented 4 years ago

thanks Erik, everyone happy with this solution if so I'll add a link in the README to erick's sketch for those that want to switch to a different project.

geeksville commented 4 years ago

@bigal488 did @eriktheV-king's awesome sketch work for you? Eric would you mind (if it is handy) putting a bin somewhere with this prebuilt? (you could even add it as a pull-request in this repo as images/ttgo-tbeam-uninstaller.bin?)

bigal488 commented 4 years ago

We ended up using UCenter and the passthru sketch to reset our T-beams. I just tried @eriktheV-king's sketch and it appears to have worked....just editing this because, on further testing, I'm still getting no NMEA output from the GPS running a simple Sketch. Will test further and report back.

bigal488 commented 4 years ago

Unfortunately, @eriktheV-king's sketch does not seem to be working. it gets as far as State 3 and then I get the following panic: GPS protocol version: Guru Meditation Error: Core 1 panic'ed (LoadStoreError). Exception was unhandled. Just checking libraries etc. now to make sure its nothing in my set up....

eriktheV-king commented 4 years ago

Sorry to hear that, Bigal

Did you use T-beam V1.0 or T-beam V1.1 to test my sketch? On 1.0 t-beams, it panics in step 3, but after restoring factory defaults in the GPS. On my 1.1 t-beams, it was running normally.

See hereunder:

My sketch wakes up the T-beam's power chip as in the original LilyGO example, but in the loop I used example code that came with the SparkFun library. So I didn't actually change much, just combined the necessary lines from both and greyed out the unnecessary. In State 1, it polls the U-blox to see if its UART runs on 9600 or 38400 baud, then sets speed to 38400. I left the line of code setting UBX output (could have left that out, too), then save the config. In State 2, GPS UART comes back at 38400, then hard resets, then issues a factory restore which restores NMEA output and 9600 baud.

As a test, it polls the Ublox for the protocol version, then keeps outputting cordinates on the T22-V1.1 On polling the GPS protocol version after u-blox factory restore, the V1.0 t-beam often restarted due to a 'guru meditation error' in State 3. But it effectively does restore factory settings in your GPS before that, in State 2! It worked fine with 5 of my Meshtastic T-beams I explictely reset this way.

Testing is easy: when I loaded the original sketch from LilyGO , all 'unbricked' t-beam GPS'es work fine. Within a few seconds they start outputting good cordinates, and within 20 seconds the gps LED shows a fix, too. I also successfully tested Luckynrslevin's sketch.

I then tried your group's ttn-tracker sketch , and get a fix and cordinates on the T-beam screen right away, too.

kizniche commented 4 years ago

It works, but I think it should have some parts removed. Since the v1.0 restarts the sketch, you should remove the baud rate change. I found that it would often have changed the baud from 9600 by the time I unplugged or reflashed the next firmware and the GPS was unreachable. Additionally, I would add a wait until serial is open to begin the sketch, preventing loops while the user isn't monitoring serial. The original sketch I posted is the minimal amount of code to revert to NMEA without having to reset or change the baud rate. This is the method I would suggest be used unless there's a significant need to actually perform soft and hard resets.

kizniche commented 4 years ago

On a slightly different note, I wouldn't mind moving to use the Sparkfun library with UBX in ttn-tracker, but I have not been able to generate a sketch that successfully prints GPS data while in UBX mode. I've tried many different code configurations, all variants of the sketch I link to above that uses NMEA, but setting UBX and calling the get functions. The GPS lights work as though it's acquired satelites/lock, but any get functions I call return 0. @geeksville, could you or anyone else familiar with the Sparkfun library please help me figure out the issue (I've been testing with a T-Beam v1.0)? Here's what I'm working with:

//https://github.com/sparkfun/SparkFun_Ublox_Arduino_Library
//http://librarymanager/All#SparkFun_Ublox_GPS
#include <SparkFun_Ublox_Arduino_Library.h>
SFE_UBLOX_GPS myGPS;

// Select your board version
//#define T_BEAM_V07  // AKA Rev0 (first board released)
#define T_BEAM_V10  // AKA Rev1 (second board released)

#if defined(T_BEAM_V07)
#define GPS_RX_PIN      12
#define GPS_TX_PIN      15
#elif defined(T_BEAM_V10)
#include <Wire.h>
#include "axp20x.h"
AXP20X_Class axp;
#define I2C_SDA         21
#define I2C_SCL         22
#define GPS_RX_PIN      34
#define GPS_TX_PIN      12
#endif

void setup() {
  Serial.begin(115200);
  while (!Serial);  // Wait for user to open the terminal
  Serial.println("Connected to Serial");

#if defined(T_BEAM_V10)
  Wire.begin(I2C_SDA, I2C_SCL);
  if (!axp.begin(Wire, AXP192_SLAVE_ADDRESS)) {
      Serial.println("AXP192 Begin PASS");
  } else {
      Serial.println("AXP192 Begin FAIL");
  }
  axp.setPowerOutPut(AXP192_LDO3, AXP202_ON); // GPS main power
#endif

  Serial1.begin(9600, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN);

  while(1) {
    if (myGPS.begin(Serial1)) {
      myGPS.setUART1Output(COM_TYPE_UBX);
      myGPS.saveConfiguration();
      Serial.println("GPS serial connected and output set to UBX");
      break;
    }
    delay(1000);
  }
}

void loop() {
  long latitude = myGPS.getLatitude();
  Serial.print(F("Lat: "));
  Serial.print(latitude);

  long longitude = myGPS.getLongitude();
  Serial.print(F(" Lon: "));
  Serial.println(longitude);
  delay(1000);
}
geeksville commented 4 years ago

Hi @kizniche yes, I had the same problem. I think there are two things at play:

1) the neo6m (used on most of the tbeams, though some have 8ms) doesn't support the auto-pvt mode that the sparkfun lib defaults to using. Therefore you have to call checkUblox() occasionally from loop. And better to pass in zero to getLatitude(0) so that the loop call won't stall if the GPS doesn't yet have a solution. Here's a snippet from meshtastic:

        // if using i2c or serial look too see if any chars are ready
        ublox.checkUblox(); // See if new data is available. Process bytes as they come in.

        // If we don't have a fix (a quick check), don't try waiting for a solution)
        // Hmmm my fix type reading returns zeros for fix, which doesn't seem correct, because it is still sptting out positions
        // turn off for now
        uint16_t maxWait = i2cAddress ? 300 : 0; // If using i2c we must poll with wait
        fixtype = ublox.getFixType(maxWait);
        DEBUG_MSG("GPS fix type %d\n", fixtype);

        // DEBUG_MSG("sec %d\n", ublox.getSecond());
        // DEBUG_MSG("lat %d\n", ublox.getLatitude());

        // any fix that has time

        if (ublox.getT(maxWait)) {
            /* Convert to unix time
            The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of seconds that have elapsed since January
            1, 1970 (midnight UTC/GMT), not counting leap seconds (in ISO 8601: 1970-01-01T00:00:00Z).
            */
            struct tm t;
            t.tm_sec = ublox.getSecond(0);
            t.tm_min = ublox.getMinute(0);
            t.tm_hour = ublox.getHour(0);
            t.tm_mday = ublox.getDay(0);
            t.tm_mon = ublox.getMonth(0) - 1;
            t.tm_year = ublox.getYear(0) - 1900;
            t.tm_isdst = false;
            perhapsSetRTC(t);
        }

        latitude = ublox.getLatitude(0);
        longitude = ublox.getLongitude(0);
        altitude = ublox.getAltitude(0) / 1000; // in mm convert to meters
        dop = ublox.getPDOP(0); // PDOP (an accuracy metric) is reported in 10^2 units so we have to scale down when we use it
        heading = ublox.getHeading(0);
        numSatellites = ublox.getSIV(0);

2) The sparkfun ubx library didn't originally support the neo6m. I added that support in my fork (https://github.com/meshtastic/SparkFun_Ublox_Arduino_Library). Someone else took that code and submitted a PR upstream (alas - I haven't checked if that change has been merged). Someday I'll reupdate my fork from the master repo and see if I can go back to just using vanilla version of the lib or figure out what other PRs need to get sent in.

geeksville commented 4 years ago

(btw - the power savings of using the ubx protocol can be substantial, because it allows you to change the GPS settings to only try to look for a solution once per second - rather than the higher rate it defaults to. Also you can put the GPS to sleep via the protocol and only turn it on (in my case) once every minute most of the time)

eriktheV-king commented 4 years ago

It works, but I think it should have some parts removed. The original sketch I posted is the minimal amount of code to revert to NMEA

Hello Kyle Thanks for the advice. I tried your minimal code and it works too. So I chose to provide 2 sketches on my GitHub , one with the minimal code (T22-GPS-reset-v3) and in desperate cases a factory reset sketch (T22-GPS-restoreFactory-v2)

eriktheV-king commented 4 years ago

@bigal488 did @eriktheV-king's awesome sketch work for you? Eric would you mind (if it is handy) putting a bin somewhere with this prebuilt? (you could even add it as a pull-request in this repo as images/ttgo-tbeam-uninstaller.bin?)

I'll try to brew a .bin file tomorrow !

geeksville commented 4 years ago

@eriktheV-king any luck building that bin? It would be great if you could add it to this project in some directory so we could point users at it if needed...

mc-hamster commented 3 years ago

Closing this ticket.

There's a toggle available in the python api to reset this parameter.