Skip to content
  • There are no suggestions because the search field is empty.

Theory of Operations for the Troverlo Mobile Tag Reader (TTR-MHr1) (Internal)

This article provides an overview of how the Troverlo Mobile Tag Reader operates.

Troverlo Reader General Operation:

Pycom board Overview:

1_theory-of-operations-for-the-troverlo-mobile-tag-reader

2_theory-of-operations-for-the-troverlo-mobile-tag-reader

GPY is FCC certified 3 in 1 module that includes BLE, WiFI and Cat-M1 cellular (IoT). Higher level APIs are used to increase development time and decrease the complexity of the code base. All code can be programmed using micro Python.

 

The documentation for the GPY is located at:

 

The GPY comes equipped with an internal antenna for WiFi and BLE.

 

GPS adapter board Overview:

The GPY does not come with a GPS module so an adapter board is needed. The adapter board carries the GPS. Once again to access the GPS peripheral a high level AP is used to speed up development time.

3_theory-of-operations-for-the-troverlo-mobile-tag-reader

Software General Operation:

Software Flow Chart:

4_theory-of-operations-for-the-troverlo-mobile-tag-reader

User settable parameters (Config.py):

The program has a config.py file which will allow the end user to set some customizable parameters. All user setters are stored in this file. Once a parameter has been changed the code will need to be programmed on the device - these are volatile parameters so any OTA update will change the parameters to the ones set in the OTA update.

 

MAC Filtering:

When the Reader performs a WIFI scan, all scanned access points are saved and sent to the cloud via the cellular network. This can result in unnecessary data being sent over the cellular network. In the config.py file, there is an option that allows the user to turn on this MAC filtering and to set the first 3 bytes of the MAC address of two MAC filters.

 

If the scanned MAC address matches the first 3 bytes of the MAC filter, the scanned access points will be saved and sent to the cloud. If the scanned access point MAC address does not match the first 3 bytes of the MAC filter, the data will be thrown away and not sent to the cloud.

 

Example:

Located in config.py

MAC_filter = 1

 

Located in mac_filter.py

MAC_FILTER.append([0x48, 0x06, 0x2b])

MAC_FILTER.append([0x00, 0x17,0x13])

 

Scanned MAC addresses

0x12, 0x56, 0x45, 0x56, 0x2A, 0x56 - Does not match data will be thrown away

0x48, 0x06, 0x2b, 0x16, 0x2B, 0x46 - Matches MAC filter 1

0x00, 0x17, 0x13, 0x14, 0x6A, 0x26 -  Matches MAC filter 2

 

Cellular Transmission Rate:

The cellular transmission rate of the reader is based on the speed the reader is moving. This is configurable in the config.py file. We have four setable speeds and transmission time associated with each speed. We also have an observation per post field. The purpose of this field is to limit the amount of cellular posts, as these are expensive with processing power, and we want the reader data as accurate as possible.

VERY_SLOW_speed = 8  #in kph

VERY_SLOW_data_speed = 300 #secs

VERY_SLOW_obs_per_post = 1



SLOW_speed = 48  #in kph

SLOW_data_speed = 15  #secs

SLOW_obs_per_post = 2



FAST_speed = 97 #kph

FAST_data_speed = 10  #secs

FAST_obs_per_post = 3



VERY_FAST_data_speed = 5  #secs

VERY_FAST_obs_per_post = 6

 

In this example, if the reader is moving between 48kph and 97kph the SLOW data speed will be active. The reader and associated tag data will be cached every 15s. Once we have two data sets (based on the obs_per_post field) - the data will be sent to the cloud. Note: this happens every 30 seconds.

 

If the reader is moving faster than 97kph, the VERY_FAST data speed will be active and we will have the reader and associated tag data will be cached every 5s. Once we have six data sets - the data will be sent to the cloud. Note: this happens every 30 seconds.

 

Configurable timers:

Watchdog: The watchdog is a special timer that will reset the unit if the program doesn’t periodically “kick” it. So this will happen if the program gets “stuck” The default watchdog timer is 20 minutes but can be configured in the config.py

WATCHDOG_INTERVAL = 1200000 #20 minutes (20*60*1000)

OTA updates: The program will periodically check if there is a software update. This rate of this check can be configured in config.py

OTA_FW_CHECK_INTERVAL = 3600  #60 minutes

Thread check: The program has multiple threads running in parallel. The “main” thread handles the watchdog reset and periodically checks the health of the other threads. If the main thread has determined that a thread is no longer responsive a system reset will be triggered. The rate at which the threads will be monitored is configurable in config.py.

THREAD_CHECK_INTERVAL = 600 #10 minutes

Health Check: The program will periodically spit out “health” information. The rate at which the health format data will be printed can be configured in the config.py . (Note: future generations of this project will push the health data to the cloud)

{
    “Uptime” : uint32_t seconds the unit has been running (zeros upon reset)
    “LTE Link DOWN time” : uint32_t seconds the LTE link has been down
    Power Cyles/Resets : uint32_t number of time the software has restarted the unit - power cycles (no clear, rolls over) / uint32_t the number of times the unit has restarted itself (i.e. watchdog reset)
    “GPosts” : uint32_t successful posts to the server (clears on reset, rolls over)
    “BPosts” : uint32_t unsuccessful posts to the server (clears on reset, rolls over)
    “LTER” : uint32_t number of reconnects to the LTE server (clears on reset, rolls over)
    “BuffData” : uint32_t current number of bytes that has been buffered due to unsuccessful posts
    “GPSStat” : uint32_t number of times the GPS has lost lock (clears on reset, rolls over)
    “TimeS” : timestamp string
    “FirmV” : string of the firmware version
    “HardV” : string of the hardware version
    “ProtV” : string of the protocol version
}
HEALTH_CHECK_INTERVAL = 600 #10 minutes  (In seconds - 600 seconds = 10 minutes)

 

Version:

The hardware and protocol version can be set in the config.py.

#Hardware version

HW_VERSION = '1.0.0'

#Protocol Version

PROTO_VERSION = '1.0.0'

 

The firmware version can be set in the OTA_VERSION. Note this version number is checked by the OTA updater - this should not be changed.

VERSION='1.2'

 

Retransmission parameters:

If a cellular post is unsuccessful, the data is stored to a special directory that holds the data. This can be configured in the config.py file. Before the data is stored the program will check that there is at least the amount of space set with the RETRANSMISSION_MIN_SPACE.

RETRANS_DIR="/flash/retransmit_buffer"

RETRANSMISSION_MIN_SPACE = 512000

 

Active Threads:

In order to keep the reader as real time as possible there are 6 separate threads running in parallel.

LED Thread: The LED thread has the simplest application - control the color of the LED.

The LED will blink these colors based on the operation:

      • Red: No GPS or LTE connection.
      • Blue: LTE connection but not GPS
      • Yellow: GPS connection but no LTE
      • Green: LTE connection and GPS connection are valid

 

WiFi Thread: This thread’s main purpose is to continuously scan for WiFi access points. Once a WiFi scan is complete the list of access points will be added to a log with the associated reader. If the access point has already been added to the log - it will only be overwritten if the RSSI is greater than the last read.

If MAC filtering is enabled - the WiFi access point will only be added to the log if the first three bytes of the MAC address match the first 3 bytes of one of the MAC filters.

 

GPS Thread: The GPS thread’s main purpose is to continuously scan the GPS for coordinates. Every one minute the latest GPS coordinates wll be displayed in the print log

 

JSON Post Thread: The JSON post thread handles the state machine to determine if there is retransmit data to send, and will send the data if the LTE link is up. This thread also handles all the posts to the cellular network.

 

LTE Monitor Thread: This thread monitors the health of the LTE connection.

 

Main Thread: The main thread has the most responsibility. Major functions of this thread are as follows:

  1. Poll the other threads for health. Trigger a reset if a thread is unresponsive.
  2. Manage the watchdog timer
  3. Manage the LTE connection
  4. Initiate a JSON post of the data over cellular network
  5. Poll the OTA update server
  6. Print health information

 

Cellular Transmissions:

 

JSON Format:

The JSON format allows for multiple observations to be sent to the cloud in a single JSON post. The idea behind this is to limit the amount of Cellular POSTs, as these tend to be expensive with processing power.

As discussed in the Cellular Transmission Rate section, the reader will collect all the tag data for the associated data speed and then cache the data. Once the observations per post has eclipsed, the reader will send the data up to the cloud.

FAST_speed = 97 #kph

FAST_data_speed = 10 #secs

FAST_obs_per_post = 3

"readerPackage": [
    {
        "TS": "2021-08-25 15:03:54",
        "MAC": "f0:08:d1:cf:9e:e0",
        "LAT": 37.20198,
        "Long": -121.8313,
        "Alt": 106.2,
        "Sp": 0,
        "Hpe": 0.89,
        "tags": [
            {
                "MAC": "a6:40:a0:6f:46:d0",
                "SSID": "TERROR",
                "Freq": 8,
                "RSSI": -42,
                "TS": "2021-08-25 15:03:42",
                "LAT": 37.20298,
                "Long": -121.8323,
                "Alt": 106.2,
                "Sp": 0,
                "Hpe": 0.89
            }
        ]
    },
    {
        "TS": "2021-08-25 15:03:54",
        "MAC": "f0:08:d1:cf:9e:e0",
        "LAT": 37.20198,
        "Long": -121.8313,
        "Alt": 106.2,
        "Sp": 0,
        "Hpe": 0.89,
        "tags": [
            {
                "MAC": "a6:40:a0:6f:46:d0",
                "SSID": "TERROR",
                "Freq": 8,
                "RSSI": -42,
                "TS": "2021-08-25 15:03:42",
                "LAT": 37.20298,
                "Long": -121.8323,
                "Alt": 106.2,
                "Sp": 0,
                "Hpe": 0.89
            }
        ]
    }
]

 

Retransmissions:

If we lose cellular coverage or if, for any reason, a post is unsuccessful - the data will be stored off, and sent when the LTE link has been restored. We have a finite amount of memory, so if the memory available is less than minimum data threshold, the data will not be stored for retransmission. The minimum data threshold is set in the config.py. By default, the minimum amount of space required is 512kb.

The retransmission index is stored in non-volatile memory so this will persist through power cycles. The retransmission algorithm will look at the oldest data with the least amount of attempts - this is the order the retransmission data will be sent over the LTE network

#min amount of space to leave on file system

RETRANSMISSION_MIN_SPACE = 512000

 

Below is the state machine for the retransmission logic.

5_theory-of-operations-for-the-troverlo-mobile-tag-reader

Cellular Carriers:

The board can work with a variety of carriers. The reader has been tested with Verizon, AT&T and Hologram and US Cellular

One Caveat is depending on geographic location, we have found two different APNs for AT&T:

#my_APN = 'm2m.com.attz'

my_APN = 'm2m64.com.attz'

This is located in line 55 of lt_connection.py.

 

Upon powerup, the reader will detect the SIM card and determine the appropriate network to connect to.

 

OTA Updates:

The Troverlo reader is built in with an OTA updater. Currently the server that runs the OTA updater is managed from FileZilla. All the versions of firmware live in FileZilla.

There is a simple server application whose only job is to check the firmware version and generate a manifest file with the differences between the firmware versions and serve files from the FileZilla.

 

The servers lives on AWS at: 18.217.18.208:8000

 

Here is a test ping of the server:

http://18.217.18.208:8000/manifest.json?current_ver=1.0

 

FileZilla credentials

IP:  18.217.18.208

user:  upload

pw:  Voler123

 

When the Troverlo reader is powered on, the unit will ping the server with the current firmware version , if the firmware version is out of date, a firmware update will begin. The firmware version is defined in OTA_VERSION.py

 

In addition to checking the for OTA updates on power one, the reader will periodically ping the server for a firmware update. The rate of which this happens is defined in the config.py file

 

OTA updates: The program will periodically check if there is a software update. This rate of this check can be configured in config.py

OTA_FW_CHECK_INTERVAL = 3600  #60 minutes

 

Programming the TAG Reader:

Reference Tutorial: Pymakr - Visual Studio Marketplace

Download and Install Microsoft Visual Studio

Use 1.36 based upon an online recommendation on versions to avoid error w serial port

https://code.visualstudio.com/updates/v1_36

Download and install the latest Python  Python Release Python 3.9.6 | Python.org

Install the PyMAKR extension for Visual Studio Pymakr - Visual Studio Marketplace

Verify that that you have the latest dependencies for PyMAKR

NodeJS installed on your system (6.9.5 or higher) https://nodejs.org

Once the extension is installed in the Visual Studio terminal will have the option to select the Pymakr console. Select this - see image below.

 

Open the files - on the toolbar select File - Open folder. Navigate to the troverlo folder that contains the source code and select this file. This will load all project files.

 

Once the pymakr console is selected-make sure the Pycom is plugged into the computer via USB and click ‘shift + C’ to connect the device. There should be a check mark next to the Pymakr Console indicator. See image below. Now you are good to start the program process.

 

Click the upload button to start writing all the files to the device. The terminal will start displaying all the files being written to the device.

 

On the command line - we need to specify the file path. Execute commands:

import sys

sys.path.append(‘/flash/troverlo’)

sys.path.append(‘/flash/troverlo/lib’)

6_theory-of-operations-for-the-troverlo-mobile-tag-reader

Debugging the Reader:

Running the unit on the Pymakr console (explained aboves) will result in the reader being able to display messages during operation. During development of the reader, there have been multiple messages added to the functionality of the reader (GPS scans, WiFi scans, successful posts, etc) These messages give very good insight to how the unit is running.

Messages can be added or subtracted based on the information desired.

 

Updating the OS:

There are two ways to check the reader version. On startup the current version will be displayed in the command line interface or command os.uname().

Example response:

(
    sysname='GPy',
    nodename='GPy',
    release='1.20.2.r2',
    version='v1.11-3a7776d on 2020-11-23',
    machine='GPy with ESP32',
    pybytes='1.6.1'
)

 

PYCOM has all the updates for the reader here: https://pycom.io/downloads/

Chose the latest iteration of the firmware 1.20.r6 is the latest when this document was released. Reload the application firmware.

8_theory-of-operations-for-the-troverlo-mobile-tag-reader

9_theory-of-operations-for-the-troverlo-mobile-tag-reader

NOTE: Please clear the bottom option (Enable PyBytes / SmartConfig support) - it causes problems

10_theory-of-operations-for-the-troverlo-mobile-tag-reader

11_theory-of-operations-for-the-troverlo-mobile-tag-reader

12_theory-of-operations-for-the-troverlo-mobile-tag-reader

13_theory-of-operations-for-the-troverlo-mobile-tag-reader

14_theory-of-operations-for-the-troverlo-mobile-tag-reader

15_theory-of-operations-for-the-troverlo-mobile-tag-reader

16_theory-of-operations-for-the-troverlo-mobile-tag-reader

17_theory-of-operations-for-the-troverlo-mobile-tag-reader

18_theory-of-operations-for-the-troverlo-mobile-tag-reader

Command Line:

There are two ways to set the command line and start an upgrade.

 

Power off the unit and press the BS button on the GPS adapter board. Power on the unit while pressing the button. This will launch the unit in program/CLI mode.

Hit control-z as the system loads in VS…do over and over until it gives you the command line

The unit has some user-settable parameters in the config.py file. To read these values over the command line use command import config and type in the parameter you would like to read.

>>> import config

>>> OTA_SERVER_PORT

8099

>>> import config

>>> VERY_SLOW_data_speed

30

>>> import config

>>> DEBUG_PRINT_AP_LIST

True

A full list of all the parameters can be found in the config.py file.

 

Clearing the FLASH:

Or you can enter on command line

os.fsformat("/flash")

 

How to get config from a device

Lower case import config then next line the config parm from the config.py file

>>> import config

>>> OTA_SERVER_PORT

8099



>>> import config

>>> VERY_SLOW_data_speed

30



>>> import config

>>> DEBUG_PRINT_AP_LIST

True



>>> import config

>>> post_url

'https://troverlodevapi.azurewebsites.net/api/clientapi/V1/groupassetdetections'



>>> import config

>>> os.uname()

(sysname='GPy', nodename='GPy', release='1.20.2.r6', version='v1.11-c5a0a97 on 2021-10-28', machine='GPy with ESP32', pybytes='1.7.1')

Looks like it upgraded and is the latest version. Maybe they improved the process since when I did it.

 

Remove items in buffer (does recursively so takes)

>>> from retransmit import *

>>> import config

>>> rmrf(RETRANS_DIR)

>>> kill_all_threads # stops other threads, sometimes it crashes