License: Apache 2.0

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.

ParameterTypeDescription
latitudedoubleLatitude in range [-90, 90]
longitudedoubleLongitude in range [-180, 180]
levelintHierarchy 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.

ParameterTypeDescription
bgridStringconst 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.

ParameterTypeDescription
datastd::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)).

ParameterTypeDescription
directoryconst 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.

ParameterTypeDescription
bgridStringconst std::string&Comma-separated indices (1-based)
languageconst 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.

ParameterTypeDescription
wordsconst std::string&Comma-separated words (case-insensitive)
languageconst 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.

ParameterTypeDescription
levelintLevel 1 to 4

Returns: Area in km². Formula: 510,000,000 / 2048^level.

LevelApproximate 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