I like to play with GPS devices, this is not my first implementation, a time ago I made a similar GPS using M5stack Faces, with Grey Core, but the shortage of RAM limited the capabilities on that project.After having moved to the Core S3, with 8MB of PSRAM, created a custom shell and a new GPS receiver I was able to add new features impossible to achieve on the old version. Also, by using a mix of LoRa and ESPNow, I can communicate my position and other relevant data to other devices in the range of the 2 protocols, or receive their position as target for my navigation.
Main GPSBased on M5Stack CoreS3 and Faces philosophy, uses Calculator keyboard with redesigned shell to offer only the relevant buttons. This device is focused on navigation off grid, no predefined maps, but waypoints and point to point navigation for saved tracks. The SD card allow storing points, preference and tracks, which can be reloaded any time.I can have multiple groups of waypoints, and any given time, the Display will show only the points from one group. The web console allows analyzing and export tracks in GPX and KML format, or visualize any waypoint using HERE maps API. The GPS can be controlled using the keyboard and the touch screen, and when not required, the screen can be put in standby, limiting the power consumption
Hardware:
On the main device I used:
- M5Stack Core S3
- GPS Module NEO-6M, connected on pin 18 and 17
- M5Stack Faces Calculator keyboard, connected on I2C bus
- 2000mah battery, which last for the full day.
- Custom PCB with connection to GPS, battery and keyboard to the Core Bus.
- SD Card 32 GB, connected to the CoreS3.
- Custom shell with place for the Battery, keyboard and GPS.
The other devices i'n using on this project are ready to work, eventually just assempling the units like the dashboard or connecting the GPS using grove port on the Dashboard.. Only the tracker made with TTGO Lora v1.0 requires soldering, as I connected a gps received on pins 25 ( RX Serial2) and 33 (TX Serial2). On the Watch, as the battery is 380mAh, I have a spare battery when I plan to have long hiking (many hours).
SoftwareDisplay
The screen is divided into 5 parts:
- Header: 320 x 20 pixels, showing informations about: UTC Time, numer of satellites in view and in use, Dinamic compass enabled, battery status
- Main Page, 200x220 pixels, showing differen visualizations.
- Side bar high, 100x100 pixel, showing the distance travelled, Waypoint selected and distance. If a grid is displayed, also the scale
- Sibe bar low, 100x100 pixels, complementary to the main page, showing the compass or the grid according to what is displayed on main page
- Footer, 320x20 pixels, showing the functions associated to the touch screen correspondent area.
The main page can show the different viualization:
- Grid; showing waypoints, traveled path and remote devices
- Compass + direction of the waypoint.
- Market points; with the respective distance
- Satellites; all satellites received and the signal level
- Altimeter; showing graph and stats about altimetry
- Simple compass, without waypoints direction
- Point information
Icons: every waypoint is visualzed according to the type, using a Xbm 10x10 array.I have prepared 15 different icons, stored on the image_array.h file. To edit an image, I used the tool https://xbm.jazzychad.net/, which generate directly the array from the image I created.
example:
// Home, 10x10px
const unsigned char epd_bitmap_home[] PROGMEM = {
0x78, 0xfc, 0xfc, 0xfc, 0xfe, 0xfd, 0xff, 0xff, 0xfe, 0xfd, 0x26, 0xfd,
0x26, 0xfd, 0x26, 0xfd, 0xe6, 0xfd, 0xfe, 0xfd
};
corresponding to
GPS Parser: running as autonomous task, read any data coming from the Serial1 port and parse the content to extract the relevant data into a data structure. When a full packet is parsed, set a flag to inform the main loop about the new data.
This flag act as trigger to refresh the screen. Depending on the desired visualization (page variable), the content of the screen is prepared and pushed. Having enough memory allowed me to use M5Canvas on almost all components, eliminating any flickering on the screen and allowing easy rotation of images, to offer the map in the point of view of the user while he is moving.
If enabled, the new point is stored in memory, and/or on the database. Also, according to the preferences, the set of information can be sent via ESPnow in broadcast. When a waypoint is selected, the distance and direction is calculated on every update. The current positions and the one 10 seconds before are compared to calculate current speed and direction of movement, allowing to generate a compass and to visualize the real direction of the target compared to the movement direction. If the speed is lower than 3Km/h, it assumes the direction calculated is not reliable, marking the compass state as RED.
If the device receives a position from a LoRa peer (via the bridge), that point is added as a waypoint on any selected list, making that point selectable as target for the navigation and using an icon moking a person.
Basic Navigation
Used when you are walking freely or navigating to a specific point. Every 10 seconds, the current point can be stored, for future usage, like point to point navigation. Up to 4400 points can be stored in memory, or 12 Hours of navigation. On this mode, you can use any of the different visualization proposed, or keep the screen off if you want to only collect the points from the track. When the display is off, the ESP32 will run on the slowest possible speed to save more energy.
When you are heading to a waypoint, the distance and direction is always displayed on the right part of the screen. All the waypoints from the current list (group) are visualized on screen, using different icons according to the waypoint type.
Anytime, by pressing the WP button, we can store the current point as waypoint. The new point will be named using date and time and will be appended to the list of waypoints. As any other waypoint can be selected as destination and will be displayed on the screen.
Point to point navigation.
From any stored track, in memory or on the database, we can set the GPS in point to point navigation mode. On this mode, the current position is compared to all the points in the track, indicating the distance from the nearest point, the direction of the next 10 points and the percentage of the journey already made. We can reply the track on same direction or inverted, like we need to go back to the initial starting point. See the video for the example.
As the GPS check continuously the distance from all the points on the track, this operation can be slow on very long tracks, but is not a problem on average hiking.
Web Console
When required, we can enable a web server on the main GPS to control or export some data. The device will get from the DB the list of known networks and will try to connect to them one by one. If none is available in the range, will start the network as access point. The IP Address assigned, and the network SSID will be displayed on the display This mode allows preparing the device, like storing waypoints for our next journey, visualizing the data using here map, or export the current track in GPX and KML format, if we want to visualize the data in Google Earth or similar tools. It's also available a SQLite console, where we can execute SQL commands, if you have familiarities with that language. You can use to customize the points, delete tracks, clean-up the database, or add new known networks.
This device is meant to mirror the GPS Screen for basic information related to navigation: Distance, Direction, Name of the waypoint, Battery and Satellites status. The idea is to keep the GPS on the pocket during the walking and use a light device to keep an eye on the navigation.
As Hardware, we need only an ESP32 (because ESPNow) and a small display, like M5Atom S3, M5Stack Dial, or on this example a TTGO Watch 2020 V1. Having a watch with strap on the wrist is more convenient when we need the hands free.
The firmware on the watch is based on this software, published by DanGeiger, and I added the functionalities to display the information coming from the GPS and the ESPNow code. When it is not required, the watch is set into standby to save energy, and turned on using the touch display. Communication is unidirectional, probably in the future I can use the watch to send commands to the display, like change waypoint or extract some data, like visualize the elevation on the path.
On this device, I'm using sprites to rotate the compass and the arrow for the direction. When the device is not moving, like on the example, the North is always visualized on the top.
I implemented a simple protocol to exchange position informations. The payload is quite simple and send information only about current position, an integer < 10 as device ID and a string containing the device name. This information is defined on build time on the config.h file
struct position {
float lat;
float lon;
float alt;
uint8_t device_id;
char device_name[25] = "";
};
There is no collision detection, or checksum verification. Each device transmit the position only if device ID matches the second unit from the GPS time. This limit the capabilities to only 10 devices. Eventually, by using 2 digits, I can extend the capabilities to 60 devices, at the price of a lower update frequency, once per minute.
I did not test the maximum range, this varies a lot depending on which Lora chip is used and the antenna. In my side, I configured the protocol for highest error correction, setting coding rate to 4/8, spreading factor to 12, preamble to 16 and Bandwidth is 128Khz. As the payload is small, this setting is not a problem.
ESPNow-Lora BridgeThis device act as bridge, repeating the information between ESPnow and Lora. As expected by the protocol, every 10 seconds send the position via Lora and send back to the main board all information received from remote peers via Lora. The reason of keeping a separated device instead of adding the Lora capabilities to the Main GPS, is because to increase the range of Lora transmission, we may want to use longer antenna, not practical for a handled device, but possible if the repeater is on the bag pack. As Hardware we need a board powered by ESP32 (because ESPNow) and any Lora chip. I tested successfully a TTGO Lora V1.6, which is already complete of what I need, and a M5stack Stamp S3 with Lora RF96 chip. Both devices work perfectly, the Stamp has a bigger battery, while the TTGO, having a SMA connector, can mount bigger antennas. I would have used on the Stamp the LoRaE220 unit, but unfortunately, is not available on 868Mhz, the only frequency allowed in Europe. The software is quite simple, initialize EspNow and Lora chips, and set two callback functions for the respective protocols, acting as pure bridge.
This device, is meant to receive information from remote peers via Lora and visualize position and distance in the screen.
I used a M5Stack Core on this example, but a bigger display would be better, like the Tab5 device, to offer a bigger visualization, and eventually to preload some real maps as BMP images. While the device is meant to be stationary, there is a GPS Unit connected to determine the proper position and visualize the relative position of every device in the range. We have as well an SD card on the device, using the same protocol of the main GPS. The idea is to visualize also the waypoints, to offer some reference on the grid. Using the buttons, I can see the list of device and select one of them to follow the distance and the direction, see the example below walking in my neighborhood.
The software is based on the old GPS for hiking, and offers different visualization, like the grid, the compass and the constellation of satellites connected.
GPS TrackerThis device act as a beacon, sending his position via LoRa, to be received by the main GPS and by the Lora Dashboard.As hardware, we can use any GPS receiver, a microcontroller, and a Lora chip. There are a lot of devices with these requirements on the market, however, not having one on them ready to use, I assembled two trackers: One using a TTGO Lora v1.0 and a GPS receiver GP-02 based on ATGM336H, connected on pins 25 and 33, The second device is using a M5stack Core, a GPS receiver Neo 6M, and the Unit Com.LoraWan, configured to work as Lora and not LoraWan. While it works perfectly, I prefer the first one because more compact. Probaly will try soon a new version with M5Stamp S3 and a custom PCB.
Once assembled the hardware, it's time to build the code and install on the devices.
All the devices are built using Arduino Ide, and ESP32 library version 3.2, except the watch, which requires v2.17. I plan to upgrade the software on it soon.
The code can be downloaded from https://github.com/ecasti-gmail-com/GPS-S3, which contains all the software tested on the different devices.
Some other librariies are required accross all components, like sqlite, Lora, M5GFX, SSD1306 and of course, M5CoreS3.On every device using LoRa chips, it's required to customize the #DEVICEID and device_name, as it's used in the Lora payload.
Main GPS
If you don't have a face keyboard, the device can be used, with limited functionalities, by using only the touch screen. I prefer the keyboard while hiking, as more intuitive witout looking on the screen, however I may extend the touch screen to be used as only imput.If the gps receiver is not connected properly or not working, the screen will remain black until the first NMEA string is received.
The firmware requires 1.7MB, so pay attention on the partition scheme.
It's required to setup an SD card, possibly smalled than 16GB, the one I used is 32GB but not all the SD card with that size works. on the root of the SD card is required to put the GPS from the folder SQLITE on the code. Note: the GPS can work also without but you loose several features.
WiFI setting: Initially, the GPS will start the wifi as Access Point, and will show on the display the IP address.
If you want to connect to your home network, you can add your setting from th web console.Start the webserver, from the preference page, on the screen will be displayed the IP address, and use FF and FF as credential.
From the homepage, on the sql console, write
insert into wifisettings (mode, ssid, pass) values (0,'test1','123445')
replacing test1 and 123456 with your ssid and password
After executed, you can disable and enable again the webserver to use your network.
FutureI would try to implements different devices, more optimized and compacts, and eventually embedding a Lora chip into the main GPS. I know this will limit the size of the antenna, but with a standard antenna I should cover most of the usecases.
On Lora side, I would like to imrpove the protocol, adding acknowledge, eventually encryption and some Checksum to validate the packet. The protocol is far from meshtastic, but also the Lora part is not the primary functionality. I'm quite happy about the GPS performance, I tested several time on long hiking and solved the scope perfectly, helpint to come back to the car or reaching predefined points. Eventually will clean up the code and will implement bi-directional controls from ESPnow, to control from the watch. On the Dashboard side, I would like to have a bigger display, and maybe enabling a webserver, or downloading the map from openmap to show the remote devices position on a complete context.
Comments