ESP32
BGrid for ESP32
A highly optimized C++ library designed for the ESP32 and Arduino ecosystem. It focuses on low memory usage and zero heap allocations in hot paths, making it ideal for IoT devices, LoRa trackers, and off-grid communication systems.
Features
- Zero External Dependencies: Self-contained implementation with no third-party libraries required.
- Low Memory Footprint: Small vectors and simple parsing; fits easily in constrained environments.
- Zero Heap Allocations: Hot encoding/decoding paths avoid dynamic memory allocation.
- BIP39 Word Support: Encode and decode grid indices as human-readable words in 9 languages.
- Compile-Time Embedding: Pre-generate word headers to avoid runtime filesystem access on embedded targets.
- Cross-Platform: Primary target is ESP32/Arduino, with desktop support for testing and development.
Installation
Copy the bgrid-esp32 folder into your Arduino libraries directory. Examples will appear under File > Examples > BGrid.
Arduino/
└── libraries/
└── bgrid-esp32/
├── src/
│ ├── BGrid.h
│ ├── BGrid.cpp
│ └── bip39-wordlist/
└── examples/
Alternatively, clone from source:
git clone https://github.com/bgrid-maps/bgrid-esp32.git
Quick Start
#include <BGrid.h>
void setup() {
Serial.begin(115200);
BGrid bgrid;
// Encode coordinates to BGrid indices
double lat = 40.7128; // New York City
double lon = -74.0060;
std::string idx = bgrid.ddToBGrid(lat, lon, 3);
Serial.println(idx.c_str()); // "531,1563,1600"
// Decode back to coordinates
auto dd = bgrid.bGridToDD(idx);
Serial.print(dd.first, 6); // latitude
Serial.print(", ");
Serial.println(dd.second, 6); // longitude
}
void loop() {}
API Reference
Constructor
BGrid();
Creates a new BGrid instance with no word lists loaded.
ddToBGrid
std::string ddToBGrid(double latitude, double longitude, int level) const;
Converts decimal degree coordinates to a BGrid index string.
| Parameter | Type | Description |
|---|---|---|
latitude | double | Latitude in range [-90, 90] |
longitude | double | Longitude in range [-180, 180] |
level | int | Hierarchy depth, 1 to 4 |
Returns: Comma-separated 1-based indices (e.g. "531,1563,1600").
Coordinates are clamped to valid ranges. Normalization maps the position into [0,1) before computing indices through alternating split factors (odd levels: 64×32, even levels: 32×64).
bGridToDD
std::pair<double, double> bGridToDD(const std::string& bgridString) const;
Converts a BGrid index string back to the center point of the corresponding cell.
| Parameter | Type | Description |
|---|---|---|
bgridString | const std::string& | Comma-separated indices (1-based) |
Returns: std::pair<double, double> — {latitude, longitude} of cell center.
Throws: std::invalid_argument if any index is outside [1, 2048].
embedWords
void embedWords(const std::map<std::string, std::vector<std::string>>& data);
Loads pre-generated BIP39 word lists into memory. This is the recommended method for Arduino/ESP32 targets, where runtime file I/O is not available.
| Parameter | Type | Description |
|---|---|---|
data | std::map<std::string, std::vector<std::string>> | Map of language tag → 2048 words |
Use the bundled Python tool to generate the header:
python3 tools/generate_words_header.py
This produces src/BGridWords.h, which can then be included in your sketch:
#include <BGrid.h>
#include "BGridWords.h"
BGrid bgrid;
bgrid.embedWords(BGRID_EMBEDDED_WORDS);
loadLanguages (Desktop only)
void loadLanguages(const std::string& directory);
Loads BIP39 word lists from JSON files at runtime. Only available on desktop builds (guarded by #if !defined(ARDUINO)).
| Parameter | Type | Description |
|---|---|---|
directory | const std::string& | Path to folder containing bip39-*.json |
Throws: std::runtime_error if files are missing or invalid (each must contain exactly 2048 words).
encodeToWords
std::string encodeToWords(const std::string& bgridString, const std::string& language) const;
Converts BGrid indices to human-readable BIP39 words.
| Parameter | Type | Description |
|---|---|---|
bgridString | const std::string& | Comma-separated indices (1-based) |
language | const std::string& | ISO language tag (e.g. "en", "es") |
Returns: Comma-separated words (e.g. "little,airport,dog").
Throws: std::runtime_error if language is not loaded; std::out_of_range if indices are outside [1, 2048].
decodeFromWords
std::string decodeFromWords(const std::string& words, const std::string& language) const;
Converts BIP39 words back to BGrid indices.
| Parameter | Type | Description |
|---|---|---|
words | const std::string& | Comma-separated words (case-insensitive) |
language | const std::string& | ISO language tag |
Returns: Comma-separated 1-based indices.
Accepts flexible delimiters: comma, space, tab, newline. Matching is case-insensitive.
getCellArea
double getCellArea(int level) const;
Returns the approximate area of a cell at the given hierarchy level.
| Parameter | Type | Description |
|---|---|---|
level | int | Level 1 to 4 |
Returns: Area in km². Formula: 510,000,000 / 2048^level.
| Level | Approximate Area |
|---|---|
| 1 | ~249,023 km² |
| 2 | ~121.6 km² |
| 3 | ~0.059 km² |
| 4 | ~0.000029 km² |
BIP39 Word Support
The library supports 9 languages for BIP39 word encoding:
en, es, fr, it, pt, zh, ja, ko, cs
Each word list contains exactly 2048 entries, matching the BGrid index range [1, 2048].
Resources
- Source Code: GitHub Repository