micropyGPS crashes my ESP32

All ESP32 boards running MicroPython.
Target audience: MicroPython users with an ESP32 board.
cable134
Posts: 24
Joined: Sun Aug 20, 2017 10:51 pm

micropyGPS crashes my ESP32

Post by cable134 » Sun Apr 15, 2018 11:36 pm

Dear folks,
could you please provide an advice how to handle the following issue?

I've connected Ublox NEO-6M module to my Chinese ESP32 WROOM (like this https://github.com/Nicholas3388/LuaNode )
Then I flashed my ESP32 by latest Loboris firmware. Everything works fine until I tried to get GPS coordinates.
I downloaded the latest micropyGPS library and made a simple test code. Please see it below.

Code: Select all

from machine import UART
from micropyGPS import MicropyGPS
import utime

uart = UART(2, rx=13, tx=12, baudrate=9600, bits=8, parity=None, stop=1, timeout=200, buffer_size=256, lineend='\r\n')
my_gps = MicropyGPS(local_offset=0, location_formatting='ddm')

def test():
    while True:
        len = uart.any()
        if len>0:
            b = uart.read(len)
            for x in b:
                if 10 <= x <= 126:
                    stat = my_gps.update(chr(x))
                    if stat:
                        print(stat)
And this code crashes device. And every time the error is different.
I got Guru Meditation Error: Core 1 panic'ed (InstrFetchProhibited)
or Guru Meditation Error: Core 1 panic'ed (LoadProhibited)
or Task watchdog got triggered. The following tasks did not reset the watchdog in time:
or different uPython errors.

I'd like to catch the problem.
Could someone provide me some ideas what could be the reason of my crashes?


Please see clips from the ./BUILD.sh monitor
https://pastebin.com/fqnJC6BL

Code also attached.
Archive.zip
micropyGPS and test code
(7.67 KiB) Downloaded 5 times
Thank you in advance for any ideas.

User avatar
pythoncoder
Posts: 2706
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: micropyGPS crashes my ESP32

Post by pythoncoder » Mon Apr 16, 2018 7:24 am

I suggest you raise this in the Loboris forum.

It might be instructive to remove the GPS parsing to see if the UART driver is working:

Code: Select all

def test():
    while True:
        len = uart.any()
        if len>0:
            b = uart.read(len)
            for x in b:
                print(b)
Peter Hinch

cable134
Posts: 24
Joined: Sun Aug 20, 2017 10:51 pm

Re: micropyGPS crashes my ESP32

Post by cable134 » Mon Apr 16, 2018 8:28 am

pythoncoder wrote:
Mon Apr 16, 2018 7:24 am
I suggest you raise this in the Loboris forum.

It might be instructive to remove the GPS parsing to see if the UART driver is working:
Thank you for your advice.
I will post it to Lobo's forum.
And I already checked UART. It works fine.

I tested the same code on another ESP32 board.
The result is the same.

Code: Select all

>>> gps_test.test()
GPGGA
GPGSA
GPGSV
GPGSV
GPGSV
GPGLL
GPGGA
GPGSA
GPGSV
Guru Meditation Error: Core  1 panic'ed (IllegalInstruction)
. Exception was unhandled.
Core 1 register dump:
PC      : 0x68747970  PS      : 0x00060b30  A0      : 0x800f61b9  A1      : 0x3ffb7e70
A2      : 0x3ffc83e0  A3      : 0x00000019  A4      : 0x00000008  A5      : 0x00000014
A6      : 0x0000000c  A7      : 0x400ea689  A8      : 0x800ebae4  A9      : 0x3ffb7e50
0x400ea689: mp_obj_new_bool at /Users/johnsmith/src/MicroPython_ESP32_psRAM_LoBo/MicroPython_BUILD/components/micropython/py/obj.h:626
 (inlined by) mp_binary_op at /Users/johnsmith/src/MicroPython_ESP32_psRAM_LoBo/MicroPython_BUILD/components/micropython/py/runtime.c:492

A10     : 0x00000004  A11     : 0x3ffc83e0  A12     : 0x00000001  A13     : 0x3ffc85d0
A14     : 0xfffffffe  A15     : 0x00000001  SAR     : 0x0000001c  EXCCAUSE: 0x00000000
EXCVADDR: 0x00000000  LBEG    : 0x4000c46c  LEND    : 0x4000c477  LCOUNT  : 0x00000000

Backtrace: 0x68747970:0x3ffb7e70 0x400f61b6:0x3ffb7e90 0x400ee022:0x3ffb7f30 0x400e9881:0x3ffb7f60 0x400f699d:0x3ffb7f80 0x400ee022:0x3ffb8020 0x400e9881:0x3ffb8050 0x400e98f1:0x3ffb8070 0x400f6a26:0x3ffb8090 0x400ee022:0x3ffb8130 0x400e9881:0x3ffb8160 0x400e98f1:0x3ffb8180 0x400f6a26:0x3ffb81a0 0x400ee022:0x3ffb8240 0x400e9881:0x3ffb82a0 0x400e98ae:0x3ffb82c0 0x400dd01b:0x3ffb82e0 0x400dd29d:0x3ffb8390 0x400d4854:0x3ffb83d0

#######################

>>> gps_test.test()
GPGSV
GPGLL
Guru Meditation Error: Core  1 panic'ed (LoadProhibited)
. Exception was unhandled.
Core 1 register dump:
PC      : 0x400e20e4  PS      : 0x00060130  A0      : 0x800eb18d  A1      : 0x3ffb7ec0
0x400e20e4: qstr_hash at /Users/johnsmith/src/MicroPython_ESP32_psRAM_LoBo/MicroPython_BUILD/components/micropython/py/qstr.c:245

A2      : 0x0b0c0c0b  A3      : 0x00000716  A4      : 0x3ffb7f50  A5      : 0x00000021
A6      : 0x00000001  A7      : 0x0000001c  A8      : 0x800e20e4  A9      : 0x3ffb7ea0
A10     : 0x00000000  A11     : 0x3f40fb2c  A12     : 0x3ffb7f50  A13     : 0x3ffc7180
A14     : 0x00000000  A15     : 0x0000001c  SAR     : 0x0000001e  EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000000  LBEG    : 0x4000c46c  LEND    : 0x4000c477  LCOUNT  : 0x00000000

Backtrace: 0x400e20e4:0x3ffb7ec0 0x400eb18a:0x3ffb7ee0 0x400ecff7:0x3ffb7f10 0x400ea755:0x3ffb7f40 0x400f6d93:0x3ffb7f80 0x400ee022:0x3ffb8020 0x400e9881:0x3ffb8050 0x400e98f1:0x3ffb8070 0x400f6a26:0x3ffb8090 0x400ee022:0x3ffb8130 0x400e9881:0x3ffb8160 0x400e98f1:0x3ffb8180 0x400f6a26:0x3ffb81a0 0x400ee022:0x3ffb8240 0x400e9881:0x3ffb82a0 0x400e98ae:0x3ffb82c0 0x400dd01b:0x3ffb82e0 0x400dd29d:0x3ffb8390 0x400d4854:0x3ffb83d0
0x400e20e4: qstr_hash at /Users/johnsmith/src/MicroPython_ESP32_psRAM_LoBo/MicroPython_BUILD/components/micropython/py/qstr.c:245

0x400eb18a: mp_map_lookup at /Users/johnsmith/src/MicroPython_ESP32_psRAM_LoBo/MicroPython_BUILD/components/micropython/py/map.c:222


loboris
Posts: 244
Joined: Fri Oct 02, 2015 6:19 pm

Re: micropyGPS crashes my ESP32

Post by loboris » Mon Apr 16, 2018 10:18 am

There is a known issue when running the loops like that from the main thread, I'm working on the solution.

There are two modification needed to solve your issue:

To not get the Task watchdog got triggered message, add a short sleep interval in your loop, best on len=0
To solve the crash problem (Guru Meditation Error) run your test() function in the new thread:

Here is the modified code:

Code: Select all

from machine import UART
from micropyGPS import MicropyGPS
import utime
import _thread

uart = UART(2, rx=13, tx=12, baudrate=9600, bits=8, parity=None, stop=1, timeout=200, buffer_size=256, lineend='\r\n')
my_gps = MicropyGPS(local_offset=0, location_formatting='ddm')

def test():
    while True:
        len = uart.any()
        if len>0:
            b = uart.read(len)
            for x in b:
                if 10 <= x <= 126:
                    stat = my_gps.update(chr(x))
                    if stat:
                        print(stat)
        else:
            utime.sleep_ms(100)

testth=_thread.start_new_thread("GPS", test, ())
With this modified code I've been runing for more than an hour without crash.

I've also run with the function to print the acctual data every 10 seconds:

Code: Select all

from machine import UART
from micropyGPS import MicropyGPS
import utime, gc, _thread

uart = UART(2, rx=25, tx=26, baudrate=9600, bits=8, parity=None, stop=1, timeout=200, buffer_size=256, lineend='\r\n')
my_gps = MicropyGPS(local_offset=0, location_formatting='ddm')

def test():
    n = 0
    mem_free = gc.mem_free()
    tm_last = 0
    while True:
        len = uart.any()
        if len>0:
            b = uart.read(len)
            for x in b:
                if 10 <= x <= 126:
                    stat = my_gps.update(chr(x))
                    if stat:
                        tm = my_gps.timestamp
                        tm_now = (tm[0] * 3600) + (tm[1] * 60) + int(tm[2])
                        if (tm_now - tm_last) >= 10:
                            n += 1
                            tm_last = tm_now
                            print("{} {}:{}:{}".format(my_gps.date_string(), tm[0], tm[1], int(tm[2])))
                            print(my_gps.latitude_string(), my_gps.longitude_string(), "{:.2f}m".format(my_gps.altitude))
                            if (n % 10) == 0:
                                print("Mem free:", gc.mem_free(), mem_free - gc.mem_free())
                                gc.collect()
        else:
            utime.sleep_ms(100)

testth=_thread.start_new_thread("GPS", test, ())
Also runs without crash:

Code: Select all

>>> 00/00/00 10:12:18
45° 48.79463' N 16° 1.47866' E 0.00m
04/16/18 10:12:32
45° 48.79567' N 16° 1.47813' E 140.60m
04/16/18 10:12:42
45° 48.79616' N 16° 1.47784' E 140.80m
04/16/18 10:12:52
45° 48.79547' N 16° 1.47782' E 139.90m

>>> _thread.list()
ID=1073594864, Name: GPS, State: running, Stack=4096, MaxUsed=1952, Type: PYTHON
ID=1073448200, Name: MainThread, State: running, Stack=20480, MaxUsed=3624, Type: MAIN
>>> 04/16/18 10:13:2
45° 48.7928' N 16° 1.47852' E 140.00m
04/16/18 10:13:12
45° 48.7914' N 16° 1.47876' E 140.80m
04/16/18 10:13:22
45° 48.79085' N 16° 1.47869' E 141.10m
04/16/18 10:13:32
45° 48.79142' N 16° 1.47873' E 140.80m
04/16/18 10:13:42
45° 48.79317' N 16° 1.47887' E 138.50m
04/16/18 10:13:52
Tested with Ublox NEO-6M module from inside the building.

cable134
Posts: 24
Joined: Sun Aug 20, 2017 10:51 pm

Re: micropyGPS crashes my ESP32

Post by cable134 » Tue Apr 17, 2018 8:31 am

Dear loboris,
thank you for a quick response and great support.

Your trick works fine.

Now I'm testing my Ublox with the connected antenna. Thus, I have a reals GPS data for my tests.

I get rid of GURU errors.
Just got acouple errors like this:

Code: Select all

##########################################
Task watchdog got triggered. The following tasks did not reset the watchdog in time:
 - IDLE (CPU 1)
Tasks currently running:
CPU 0: IDLE
CPU 1: GPS
Task watchdog got triggered. The following tasks did not reset the watchdog in time:
 - IDLE (CPU 1)
Tasks currently running:
CPU 0: IDLE
CPU 1: GPS
Unhandled exception in thread started by <function test at 0x3ffc7880>
Traceback (most recent call last):
  File "gps_test.py", line 19, in test
  File "micropyGPS.py", line 615, in update
  File "micropyGPS.py", line 290, in gpgll
  File "micropyGPS.py", line 279, in gpgll
IndexError: list index out of range



##########################################
04/17/18 10:59:41
Alt:208.60m
04/17/18 10:59:52
Alt:215.40m
04/17/18 11:0:3
Alt:226.20m
Mem free: 53504 2496
Sats:7/12 Fix:3 Parsed:2702
Unhandled exception in thread started by <function test at 0x3ffc77b0>
Traceback (most recent call last):
  File "gps_test.py", line 18, in test
  File "micropyGPS.py", line 615, in update
  File "micropyGPS.py", line 211, in gprmc
  File "micropyGPS.py", line 198, in gprmc
IndexError: list index out of range
##########################################
I wil try to change sleep interval.
Anyway now it looks like working prototype.

Thank you.

cable134
Posts: 24
Joined: Sun Aug 20, 2017 10:51 pm

Re: micropyGPS crashes my ESP32

Post by cable134 » Sat Apr 21, 2018 5:21 pm

Dear Loboris,

I've done some tests on the latest firmware. (60 commits)

I mentioned that I got a lot of GPS parsing CRC errors.
I think its due to heavy micropyGPS procedures.

If I disable GPS parsing, I will have a good working UART reading code.
Following code works fine even without threading.

Code: Select all

def uart_test():
    while True:
        len = uart.any()
        if len > 0:
            b = uart.readln()
            print('{}'.format(b), end='')

If I add a parsing process like this:

Code: Select all

stat = my_gps.update(x)
I wil have a lot of errors while I'm trying to read data from the UART.
Please see bellow clipping:

Code: Select all

0004:$GPGGA,170529.00,4520.13221,N,04028.35199,E,1,09,2.01,177.2,M,35.8,M,,*5A
0005:None0006:None0007:None0008:2.01|AA?X�P��?17|AA?#hp��?177|AA?�l���?177.|AA?���?177.2|AA?hf���?25|AA?Bh���?25.|AA?�p��?25.8|AA?�0��?5A|AA?�gP��?None|AA?o�p��?|AA?�.00,A,5023.0007:NoneNone|AA?o�
I see that a haavy code from the micropyGPS module done something bad with the UART reading.
Is the any suggested way to avoid such errors while we are reading from the UARTs ?

Thank you in advance.

loboris
Posts: 244
Joined: Fri Oct 02, 2015 6:19 pm

Re: micropyGPS crashes my ESP32

Post by loboris » Sat Apr 21, 2018 6:18 pm

Have you tried the second example from my previous post ?

It contains stat = my_gps.update(x) and runs without any error printing time, coordinates and altitude.

Here it is again:

Code: Select all

from machine import UART
from micropyGPS import MicropyGPS
import utime, gc, _thread

uart = UART(2, rx=25, tx=26, baudrate=9600, bits=8, parity=None, stop=1, timeout=200, buffer_size=256, lineend='\r\n')
my_gps = MicropyGPS(local_offset=0, location_formatting='ddm')

def test():
    n = 0
    mem_free = gc.mem_free()
    tm_last = 0
    while True:
        len = uart.any()
        if len>0:
            b = uart.read(len)
            for x in b:
                if 10 <= x <= 126:
                    stat = my_gps.update(chr(x))
                    if stat:
                        tm = my_gps.timestamp
                        tm_now = (tm[0] * 3600) + (tm[1] * 60) + int(tm[2])
                        if (tm_now - tm_last) >= 10:
                            n += 1
                            tm_last = tm_now
                            print("{} {}:{}:{}".format(my_gps.date_string(), tm[0], tm[1], int(tm[2])))
                            print(my_gps.latitude_string(), my_gps.longitude_string(), "{:.2f}m".format(my_gps.altitude))
                            if (n % 10) == 0:
                                print("Mem free:", gc.mem_free(), mem_free - gc.mem_free())
                                gc.collect()
        else:
            utime.sleep_ms(100)

testth=_thread.start_new_thread("GPS", test, ())
Also runs without crash:

Code: Select all

>>> 00/00/00 10:12:18
45° 48.79463' N 16° 1.47866' E 0.00m
04/16/18 10:12:32
45° 48.79567' N 16° 1.47813' E 140.60m
04/16/18 10:12:42
45° 48.79616' N 16° 1.47784' E 140.80m
04/16/18 10:12:52
45° 48.79547' N 16° 1.47782' E 139.90m

>>> _thread.list()
ID=1073594864, Name: GPS, State: running, Stack=4096, MaxUsed=1952, Type: PYTHON
ID=1073448200, Name: MainThread, State: running, Stack=20480, MaxUsed=3624, Type: MAIN
>>> 04/16/18 10:13:2
45° 48.7928' N 16° 1.47852' E 140.00m
04/16/18 10:13:12
45° 48.7914' N 16° 1.47876' E 140.80m
04/16/18 10:13:22
45° 48.79085' N 16° 1.47869' E 141.10m
04/16/18 10:13:32
45° 48.79142' N 16° 1.47873' E 140.80m
04/16/18 10:13:42
45° 48.79317' N 16° 1.47887' E 138.50m
04/16/18 10:13:52

cable134
Posts: 24
Joined: Sun Aug 20, 2017 10:51 pm

Re: micropyGPS crashes my ESP32

Post by cable134 » Sat Apr 21, 2018 7:40 pm

Just tested your code with a small modification.
I'd like to check what was read from UART.

Code: Select all

from machine import UART
from micropyGPS import MicropyGPS
import utime, gc, _thread

uart = UART(2, rx=13, tx=12, baudrate=9600, bits=8, parity=None, stop=1, timeout=200, buffer_size=256, lineend='\r\n')
my_gps = MicropyGPS(local_offset=0, location_formatting='ddm')

def test():
    n = 0
    mem_free = gc.mem_free()
    tm_last = 0
    while True:
        len = uart.any()
        if len>0:
            b = uart.read(len)

            for z in b:
                print('{}'.format(chr(z)) , end='')

            for x in b:
                if 10 <= x <= 126:
                    stat = my_gps.update(chr(x))
                    if stat:
                        tm = my_gps.timestamp
                        tm_now = (tm[0] * 3600) + (tm[1] * 60) + int(tm[2])
                        if (tm_now - tm_last) >= 10:
                            n += 1
                            tm_last = tm_now
                            print("{} {}:{}:{}".format(my_gps.date_string(), tm[0], tm[1], int(tm[2])))
                            print(my_gps.latitude_string(), my_gps.longitude_string(), "{:.2f}m".format(my_gps.altitude))
                            if (n % 10) == 0:
                                print("Mem free:", gc.mem_free(), mem_free - gc.mem_free())
                                gc.collect()
        else:
            utime.sleep_ms(100)

testth=_thread.start_new_thread("GPS", test, ())
And I got

Code: Select all

$GPGSA,A,3,27,10,21,20,16,15,08,26,13,40,,,2.20,1.33,1.76*0F
$GPGSV,4,1,15,04,06,189,,07,00,314,,08,27,30|AA?Òhðáü?23|AA?DhÐâü?18|AA?,hðâü?01|AA?hãü?232,26,14,201,35,2|AA?Dh0ãü?$GPGSV,4,4,15,30,02,338,17,32,04,161,19,40,28,149,37*4F
$GPGLL,Unhandled exception in thread started by <function test at 0x3ffcbff0>
Traceback (most recent call last):
  File "gps_test.py", line 122, in test
  File "micropyGPS.py", line 615, in update
  File "micropyGPS.py", line 405, in gpgga
  File "micropyGPS.py", line 402, in gpgga
TypeError: can't convert  to float

I connected antenna to Ublox module. So I'm operating with real data.
And I got UART reading errors in few secs.

loboris
Posts: 244
Joined: Fri Oct 02, 2015 6:19 pm

Re: micropyGPS crashes my ESP32

Post by loboris » Sat Apr 21, 2018 9:21 pm

It is obvious that you get some garbage from GPS module ($GPGSV,4,1,15,04,06,189,,07,00,314,,08,27,30|AA?Òhðáü?23|AA?DhÐâü?18|AA?,hðâü?01|AA?h), that is the reason for TypeError: can't convert to float exception.

How are you powering your GPS module, it should be from 3.3V ?
What is the voltage on GPS module Tx pin, it should be 3.3V ?

cable134
Posts: 24
Joined: Sun Aug 20, 2017 10:51 pm

Re: micropyGPS crashes my ESP32

Post by cable134 » Sat Apr 21, 2018 9:41 pm

Thank you.
I understand that garbage in data is the reason.
I'm powering my module from VIN pin (about +4.7V).
Ublox Neo-6M has a voltage regulator onboard.

Anyway, I will certainly check the voltage.

As for me, strange, that I do not have any garbage data if I do not call

Code: Select all

stat = my_gps.update(chr(x))
I will report my voltage check results.
Thank you.

Post Reply