ESP-Now data throughput logging on GPS coordinates

224 Views Asked by At

I'm using two ESP32 boards for ESP-Now communication, where one ESP is sending packets and while the other is receiving them while logging this data together with GPS to measure throughput at a certain coordinate for me to get throughput rate while moving and changing rate between sender and receiver.

ESP32 receiver and GPS module is connected to Rpi that is running a script of reading the data from serial com ports, parsing it, and writing it to a file.

import serial
import time
import pandas as pd

# Receiver
esp_com = '/dev/ttyUSB1'
esp_baud = 115200
ser = serial.Serial(port=esp_com, baudrate=esp_baud, timeout=0.1)

# GPS
gps_com = '/dev/ttyUSB0'
gps_baud = 4800
sergps = serial.Serial(port=gps_com, baudrate=gps_baud, timeout=0.1)

# title of the file to write data in
title = 'ESP-NOW LoRa'

# time step at which data is logged
timestep = 1

# create lists
XCV = []

# initial dropped/received packets data
drp = 0
rcv = 0
counter = 0

waiting_for_recv = False

# outputs empty data table
df = pd.DataFrame()

# outputs time in seconds since the timer started
then = time.time()
then1 = time.time()

# clear ESP buffers
ser.flushInput()
ser.flushOutput()

# initial data
RECEIVED = 0
RECEIVED = []
LAT = []
LON = []
T = []
t = 0
gpsdata = ''

# loop
while True:
    try:
        xcv = ser.readline().decode()  # decodes string
        if xcv != '':
            xcv = xcv.split("\r\n")
            for x in xcv:
                if x != '':
                    print(x)
                    XCV.append(x)
                    if 'RECV' in x:
                        RECEIVED = int(x[4:])  # sliced first 4 characters

        while True:
            cvb = sergps.readline()
            if cvb != b'':
                if 'GNGGA' in cvb.decode():
                    gpsdata = cvb.decode()
            else:
                break

        now = time.time()

        if now > then+timestep:
            print(now)
            df.at[counter, 'timestamp'] = now
            df.at[counter, 'received'] = RECEIVED
            drp = 0
            rcv = 0

            RECEIVED = 0
            then = now

            counter += 1

            vbn = gpsdata.split(',')
            if('GNGGA' in vbn[0]) & (vbn[2] != "") & (len(vbn) >= 5):
                print('GPS has a fix')
                tt = vbn[1]
                lat = vbn[2]
                lon = vbn[4]
                lat = int(lat[0:2])+float(lat[2:])/60
                lon = int(lon[0:3])+float(lon[3:])/60
                LAT.append(lat)
                LON.append(lon)
                T.append(t)
                t += 1
                print('LAT: {}, LON: {}'.format(lat, lon))

            else:
                print('GPS does not have a fix')
                LAT.append(0)
                LON.append(0)

            # write data to file every 30 seconds
            if now > then1+30:
                then1 = now
                # print GPS dataframe to columns
                df['lat'] = LAT
                df['lon'] = LON
                df.to_excel(title+'.xlsx')  # writes data to excel file

    except Exception as e:
        print(e)

I ran into a problem, where once GPS has a fix, and starts sending full NMEA messages with coordinates, received/dropped packet data gets lost, and the whole script hangs. I can see in my variables that GPS NMEA data is parsed correctly and when GPS does not have a fix, everything works, but once it starts sending full NMEA messages with coordinates the script breaks.

I can't really figure it out myself why, and I think that the code itself needs optimisation.

1

There are 1 best solutions below

0
On

I see it's been a while, but I have bumped in to this post.

So one issue I see:

while True:
    cvb = sergps.readline()
    if cvb != b'':
         if 'GNGGA' in cvb.decode():
             gpsdata = cvb.decode()
    else:
        break

Here you will stuck in the loop while the ANY data is coming from GPS module. You might want to break also after you get gpsdata.

One other thing here you have boolean values so use and (logical) and not & (bitwise):

vbn = gpsdata.split(',')
    if('GNGGA' in vbn[0]) & (vbn[2] != "") & (len(vbn) >= 5):
        print('GPS has a fix')

Read more here: 'and' (boolean) vs '&' (bitwise)