{"id":47702820,"url":"https://github.com/finfinack/alphaloc","last_synced_at":"2026-04-02T17:43:37.964Z","repository":{"id":337001492,"uuid":"1131384262","full_name":"finfinack/alphaloc","owner":"finfinack","description":"ESP32 application to receive a GPS/GNSS location and send it to a Sony Alpha camera.","archived":false,"fork":false,"pushed_at":"2026-02-07T08:09:57.000Z","size":381,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-07T17:35:42.559Z","etag":null,"topics":["esp32","gps","sony-alpha-cameras"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/finfinack.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-09T23:12:08.000Z","updated_at":"2026-02-07T08:10:00.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/finfinack/alphaloc","commit_stats":null,"previous_names":["finfinack/alphaloc"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/finfinack/alphaloc","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/finfinack%2Falphaloc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/finfinack%2Falphaloc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/finfinack%2Falphaloc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/finfinack%2Falphaloc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/finfinack","download_url":"https://codeload.github.com/finfinack/alphaloc/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/finfinack%2Falphaloc/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31312375,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-02T12:59:32.332Z","status":"ssl_error","status_checked_at":"2026-04-02T12:54:48.875Z","response_time":89,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["esp32","gps","sony-alpha-cameras"],"created_at":"2026-04-02T17:43:37.447Z","updated_at":"2026-04-02T17:43:37.958Z","avatar_url":"https://github.com/finfinack.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# AlphaLoc\n\nAlphaLoc is an ESP32 application that allows embedding GPS location data directly into Sony Alpha camera photos via Bluetooth Low Energy (BLE). It acts as a bridge between a standard GPS module and your Sony camera, providing real-time geolocation tagging.\n\n## Features\n\n- **Automatic Geotagging**: Sends GPS coordinates (Latitude, Longitude, Altitude, Time) to the camera.\n- **BLE Connection**: Emulates a smartphone location provider for Sony cameras.\n- **Dual Configuration**: Configurable via a Web Interface (WiFi) or BLE characteristics.\n- **Status Indicators**: NeoPixel (RGB LED) feedback for Camera connection, GPS fix, Battery, and WiFi status.\n- **Low Power**: Supports disabling external peripherals (like Stemma QT) to save power.\n\n## Hardware Support\n\nThe project is set up for **PlatformIO** and currently supports:\n\n| Board | Environment | Pinout |\n|-------|-------------|--------|\n| [**DFRobot Beetle ESP32-C6**](https://wiki.dfrobot.com/SKU_DFR1117_Beetle_ESP32_C6) | `esp32c6` | GPS TX: 5, GPS RX: 4, NeoPixel: 6 |\n| [**Adafruit Feather ESP32-S3**](https://learn.adafruit.com/adafruit-esp32-s3-feather/overview)| `esp32s3` | GPS TX: 38, GPS RX: 39, NeoPixel: 6 |\n\nYou can easily adapt it to other ESP32 boards by modifying `platformio.ini`.\n\n### Parts List\n\nThe following is a parts list of what I ended up with.\n\n- [Adafruit ESP32-S3 Feather](https://www.adafruit.com/product/5885), [Overview](https://learn.adafruit.com/adafruit-esp32-s3-feather/overview)\n- [Adafruit Ultimate GPS featherwing](https://learn.adafruit.com/adafruit-ultimate-gps-featherwing)\n- [SparkFun RGB LED Breakout - WS2812B](https://www.sparkfun.com/sparkfun-rgb-led-breakout-ws2812b.html)\n- [Adafruit WiFi Antenna with w.FL / MHF3 / IPEX3 Connector](https://www.adafruit.com/product/5445)\n    - This is optional if you don't have an ESP32 with a PCB antenna.\n- Mini sliding switch (8.5mm x 3.7mm, 3 pin, slider 4mm tall)\n- The antenna of a GY-GPS6MV2\n- 2x Panasonic NCR18650GA Battery (3450mAh)\n- Wires, electrical tape and whatnot\n\n### Models\n\n- [**Holder**](model/holder.3mf): Holder for the batteries, ESP32, optional wifi antenna, ...\n- [**Cover**](model/cover.3mf): Cover with a press fit for the holder and room for the LED board.\n- [**Cover Large**](model/cover_large.3mf): Same as cover but taller and with room for a larger, external GPS antenna.\n\n## Usage\n\n### 1. Initial Setup\n\n1. Connect your GPS module (e.g., GY-GPS6MV2 or an Adafruit Ultimate GPS Featherwing) to the defined TX/RX pins.\n\n2. Flash the firmware using PlatformIO.\n\n   ```bash\n   pio run -e esp32c6 -t upload\n   ```\n\n3. Power on the device.\n\n### 2. Pairing with Camera\n\n1. On your Sony Alpha camera, go to **Network** -\u003e **Bluetooth Settings**.\n2. Enable **Bluetooth Function**.\n3. Select **Pairing**.\n4. The camera should discover \"AlphaLoc\". Select it to pair.\n5. Once paired, go to **Location Info. Link Set.** and enable it.\n6. The camera should now show the GPS icon (solid when receiving data).\n\n### 3. LED Status Codes\n\nThe NeoPixel LED provides a visual \"heartbeat\" every 5 seconds. It flashes multiple colors in sequence to report the status of different subsystems:\n\n**Sequence:** [Camera Status] -\u003e [GPS Status] -\u003e [Battery Status] -\u003e [WiFi Status] -\u003e [Sleep]\n\n1.  **First Flash: Camera Connection**\n    *   🟢 **Green**: Connected to camera and bonded.\n    *   🔵 **Blue**: Connected to camera but not bonded yet.\n    *   🔴 **Red**: Not connected.\n2.  **Second Flash: GPS Fix**\n    *   🟢 **Green**: Valid 3D GPS Fix acquired.\n    *   🟣 **Violet**: *Fake* GPS fix (injected when `ALPHALOC_FAKE_GPS=1`).\n    *   🔴 **Red**: No fix (searching for satellites).\n3.  **Third Flash: Battery Level (Optional)**\n    *   🟢 **Green**: \u003e 50%\n    *   🟡 **Yellow**: \u003e 30%\n    *   🔴 **Red**: \u003c= 30%\n4.  **Fourth Flash: WiFi/Config (Optional)**\n    *   Only appears during the startup \"Config Window\" (first 5 minutes).\n    *   🔵 **Blue**: Web server is active.\n    *   ⚫ **(Off)**: Config window closed, WiFi disabled to save power.\n\n**Example**:\n*   🔴-🔴-🟢-🔵: No camera, no GPS, battery good, config mode active (just turned on).\n*   🔵-🟢-🟡-⚫: Camera connected (not bonded yet), GPS fixed, battery medium, normal operation (config closed).\n*   🟢-🟢-🔴-⚫: Camera connected (bonded), GPS fixed, battery low, normal operation (config closed).\n*   🔵-🟣-🟢-⚫: Camera connected (not bonded yet), fake GPS fixed, battery good, normal operation (config closed).\n\n### 4. Configuration\n\n\u003e **⚠️ SECURITY WARNING**: The BLE configuration service is **DISABLED by default** for security reasons. When enabled, it allows **UNAUTHENTICATED access** to device settings including WiFi passwords. Only enable it (`ALPHALOC_BLE_CONFIG=1`) in trusted environments or for initial setup, then rebuild with it disabled.\n\nOn startup, AlphaLoc enters a **Configuration Window** (default 5 minutes). During this time, you can change settings via WiFi (if `ALPHALOC_WIFI_WEB=1`) or BLE (if `ALPHALOC_BLE_CONFIG=1`).\n\n\u003cimg width=\"300\" height=\"450\" alt=\"web\" src=\"https://github.com/user-attachments/assets/bd50c0e7-f0e7-41f6-8e6a-0d7c2ba5bdf6\" /\u003e\n\n#### Configuration Parameters\n\n| Parameter | Description | Default |\n|-----------|-------------|---------|\n| **Camera Name Prefix** | Filter which cameras to connect to. Useful if you have multiple Sonys. | `SonyA7` |\n| **Camera MAC Prefix** | Connect only to a specific MAC address prefix. Empty matches any. | (Empty) |\n| **TZ Offset** | Timezone offset in minutes (e.g., `60` for UTC+1). | `60` |\n| **DST Offset** | Daylight Savings Time offset in minutes. | `60` |\n| **WiFi SSID/Pass** | Credentials for connecting to your home WiFi. | `WiFi` / `changeme` |\n| **AP SSID/Pass** | Credentials for the hotspot created by AlphaLoc. | `AlphaLoc` / `alphaloc1234` |\n| **Max GPS Age** | How long (seconds) to reuse old coordinates if GPS signal is lost. | `300` |\n\n#### Method A: WiFi Web Interface\n\nAlphaLoc tries to connect to the configured WiFi as a client:\n\n- **Default SSID**: `WiFi`\n- **Default Password**: `changeme`\n- **IP**: assigned via DHCP\n\nIf it can't connect to the WiFi, it starts an access point itself:\n\n- **SSID**: `AlphaLoc`\n- **Password**: `alphaloc1234`\n- **IP**: `192.168.4.1` (direct link to webserver: http://192.168.4.1/)\n\nTo enable this, set the build flag (`ALPHALOC_WIFI_WEB=1` in `platformio.ini`).\n\n#### Method B: BLE Configuration\n\nYou can use a generic BLE app (like nRF Connect) to write to the configuration service.\n\n**Service UUID**: `B1F0B4D5-797B-5A9E-5B4F-4A1F01007EA1`\n\n| Characteristic Name | UUID (Base `B1F0...`) | R/W | Type (Over BLE) | Description |\n| ------------------- | --------------------- | --- | --------------- | ----------- |\n| Camera Name Prefix  | `...02007EA1`         | R/W | String          | Camera name identifier |\n| Camera MAC Prefix   | `...03007EA1`         | R/W | String          | MAC address filter |\n| Timezone Offset     | `...04007EA1`         | R/W | String (Int)    | Minutes from UTC |\n| DST Offset          | `...05007EA1`         | R/W | String (Int)    | Daylight Savings offset (minutes) |\n| Wifi SSID           | `...07007EA1`         | R/W | String          | Station SSID |\n| Wifi Password       | `...08007EA1`         | R/W | String          | Station Password |\n| AP SSID             | `...09007EA1`         | R/W | String          | Access Point SSID |\n| AP Password         | `...0A007EA1`         | R/W | String          | Access Point Password |\n| Max GPS Age         | `...0B007EA1`         | R/W | String (Int)    | Max age of GPS lock in seconds |\n| GPS Lock            | `...0C007EA1`         | R   | String (0/1)    | 1 when GPS lock is valid |\n| GPS Satellites      | `...0D007EA1`         | R   | String (Int)    | Satellites in view (from GGA) |\n| GPS Constellations  | `...0E007EA1`         | R   | String (Int)    | Bitmask: 1=GPS, 2=GLONASS |\n| Camera Connected    | `...0F007EA1`         | R   | String (0/1)    | BLE camera link active |\n| Camera Bonded       | `...10007EA1`         | R   | String (0/1)    | Link bonded (after pairing) |\n\n#### Build-Time Secrets (Recommended)\n\nIf you want to keep WiFi credentials and camera filters out of git, place them in `platformio.secrets.ini` and keep the file ignored. The build merges these flags into every environment via `platformio.ini`.\n\nExample `platformio.secrets.ini` with all supported defaults:\n\n```ini\n[secrets]\nbuild_flags =\n  -DALPHALOC_DEFAULT_WIFI_SSID=\"\\\"MyWifi\\\"\"\n  -DALPHALOC_DEFAULT_WIFI_PASS=\"\\\"MyPass\\\"\"\n  -DALPHALOC_DEFAULT_AP_SSID=\"\\\"AlphaLoc\\\"\"\n  -DALPHALOC_DEFAULT_AP_PASS=\"\\\"AlphaLocPass\\\"\"\n  -DALPHALOC_DEFAULT_CAMERA_NAME_PREFIX=\"\\\"SonyA7\\\"\"\n  -DALPHALOC_DEFAULT_CAMERA_MAC_PREFIX=\"\\\"AA:BB:CC\\\"\"\n```\n\nThese values are used as defaults on first boot (or after a factory reset) and can still be changed later via the WiFi or BLE config UIs.\n\n## BLE Client Details (Camera Link)\n\nAlphaLoc acts as a BLE client to Sony cameras\n\n### Advertisement Filters\n\n- **Manufacturer data**: company ID `0x012D`, product ID `0x0003`\n- **Optional name prefix filter**: `camera_name_prefix` (if set)\n- **Optional MAC prefix filter**: `camera_mac_prefix` (if set)\n\n### Services and Identifiers\n\nAlphaLoc looks for two Sony services (UUIDs are built from 16-bit IDs using the Sony base UUID):\n\n```\nSony base UUID (constructed):\n  00000000-0000-8000-ffff-ffff-ffff-ffff\n  with 16-bit words inserted at positions:\n    first = 0xDD00 / 0xFF00\n    second = 0xDD00 / 0xFF00\n```\n\nIt accepts either 128-bit UUIDs or 16-bit UUIDs:\n\n- **Location Service**: `0xDD00`\n- **Remote Service**: `0xFF00`\n\n### Characteristic Discovery\n\nWithin those services, AlphaLoc searches for:\n\n**Location Service (DD00)**\n\n- `0xDD21`: Flags read to determine if TZ/DST are required\n- `0xDD30`: Lock location (0x00 - Off, 0x01 - On)\n- `0xDD31`: Enable location updates (0x00 - Off, 0x01 - On)\n- `0xDD11`: Location write characteristic; used for sending GPS payloads\n\nData is a 95 byte buffer\n\n| Offset    | Description                                                  | Remark                                           |\n|-----------|--------------------------------------------------------------|--------------------------------------------------|\n| [0:1]     | Payload Length (exclude these two bytes)                     | 0x5D = 93 bytes                                  |\n| [2:4]     | Fixed Data                                                   | 0x0802FC                                         |\n| [5]       | Flag of transmitting timezone offset and DST offset required | 0x03 for transmit and 0x00 for do not transmit   |\n| [6:10]    | Fixed Data                                                   | 0x0000101010                                     |\n| [11:14]   | Latitude (multiplied by 10000000)                            | 0x0BF79E5E = 200777310 / 10000000 = 20.077731    |\n| [15:18]   | Longitude (multiplied by 10000000) \t                       | 0x41C385A7 = 1103332775 / 10000000 = 110.3332775 |\n| [19:20]   | \tUTC Year                                                   | 0x07E4 = 2020                                    |\n| [21]      | \tUTC Month                                                  | 0x0B = 11                                        |\n| [22]      | \tUTC Day                                                    | 0x05 = 5                                         |\n| [23]      | \tUTC Hour                                                   | 0x04 = 4                                         |\n| [24]      | \tUTC Minute                                                 | 0x02 = 2                                         |\n| [25]      | \tUTC Second                                                 | 0x2A = 42                                        |\n| [26:90]   | \tZeros  \t                                                   | 0x00                                             |\n| *[91:92]  | \tDifference between UTC and current timezone in minutes     | 0x01E0 = 480min = 8h (UTC+8)                     |\n| *[93:94]  | \tDifference for DST in current timezone in minutes          |                                                  |\n\n**Remote Service (FF00)**\n\n- `0xFF02` (notification characteristic; CCCD `0x2902`)\n\n### Connection/Discovery Flow (simplified)\n\n```\nADV (Sony) --\u003e connect\n  |\n  +--\u003e discover DD00 (Location Service)\n  |      +--\u003e find DD11, DD21, DD30, DD31\n  |      +--\u003e read DD21 flag byte\n  |      +--\u003e enable location writes on DD11\n  |\n  +--\u003e discover FF00 (Remote Service)\n         +--\u003e find FF02\n         +--\u003e find/guess CCCD (0x2902)\n         +--\u003e enable notifications\n```\n\n### Sending Location\n\nOnce services and characteristics are resolved:\n- Builds a Sony-compatible location payload\n- Writes to `DD11`\n- Enables FF02 notifications after first location write (if required)\n\n## Configuration Options\n\n- **Camera Name Prefix**: Limits connection to cameras starting with this name (Default: \"SonyA7\").\n- **Timezone/DST**: Offset in minutes for timestamp correction.\n- **Max GPS Age**: How long to keep sending the last known location if GPS signal is lost.\n\n## Building\n\nThis project uses the Espressif IoT Development Framework (ESP-IDF) within PlatformIO.\nCheck `platformio.ini` for build flags and pin definitions.\n\n```ini\n; Example Override\nbuild_flags =\n  -DGPS_UART_TX_PIN=5\n  -DGPS_UART_RX_PIN=4\n```\n\n### Build Environments\n\nThe `platformio.ini` file defines several build environments for different purposes:\n\n*   **`env:esp32c6`**: The standard production build for the ESP32-C6. Logging is disabled for performance.\n*   **`env:esp32c6-debug`**: A debugging environment.\n    *   Enables verbose logging (`ALPHALOC_VERBOSE=1`).\n    *   **Enables Fake GPS (`ALPHALOC_FAKE_GPS=1`)**: Simulates a stationary location (Munich) for testing without a GPS module or satellite lock.\n*   **`env:esp32c6-debug-gps`**: Debugging environment using *real* GPS data but with verbose logging enabled.\n*   **`env:esp32s3`**: The standard production build for the ESP32-S3. Logging is disabled for performance.\n*   **`env:esp32s3-debug`**: A debugging environment.\n    *   Enables verbose logging (`ALPHALOC_VERBOSE=1`).\n    *   **Enables Fake GPS (`ALPHALOC_FAKE_GPS=1`)**: Simulates a stationary location (Munich) for testing without a GPS module or satellite lock.\n*   **`env:esp32s3-debug-gps`**: Debugging environment using *real* GPS data but with verbose logging enabled.\n\n### Build Flags\n\nYou can customize the firmware behavior using these compilation flags in `platformio.ini`:\n\n| Flag | Description | Default |\n|------|-------------|---------|\n| `ALPHALOC_WIFI_WEB` | Enable internal settings web server. Set to `0` to remove WiFi stack and save power/flash. | `1` |\n| `ALPHALOC_BLE_CONFIG` | **Enable BLE configuration service.** Note: This allows reading and writing the config via BLE unauthenticated! | `0` (DISABLED) |\n| `ALPHALOC_VERBOSE` | Enable extensive debug logging to serial UART. | `0` |\n| `ALPHALOC_FAKE_GPS` | Ignore UART GPS and output a static test location. | `0` |\n| `ALPHALOC_NEOPIXEL_PIN`| GPIO pin number for the WS2812B NeoPixel. | (Board dependent) |\n| `ALPHALOC_BATTERY_MONITOR` | Enable MAX17048 / LC709203F battery monitor over I2C. | `0` |\n| `ALPHALOC_BATTERY_SDA_PIN` | I2C SDA pin for battery monitor. | (Board dependent) |\n| `ALPHALOC_BATTERY_SCL_PIN` | I2C SCL pin for battery monitor. | (Board dependent) |\n| `ALPHALOC_BATTERY_I2C_POWER_PIN` | Optional power-enable pin for I2C battery monitor. | (Unset) |\n| `GPS_UART_TX_PIN` | TX Pin for GPS Serial (Connects to GPS RX). | (Board dependent) |\n| `GPS_UART_RX_PIN` | RX Pin for GPS Serial (Connects to GPS TX). | (Board dependent) |\n| `DALPHALOC_FACTORY_RESET` | If set to `1`, wipes NVS settings on boot. Dangerous. | Undefined |\n\n**Security Best Practices:**\n- Keep `ALPHALOC_BLE_CONFIG=0` in production builds\n- Only enable BLE config for initial setup in controlled environments\n- Use WiFi config (`ALPHALOC_WIFI_WEB=1`) with strong AP password instead\n- Change default WiFi credentials immediately after first boot\n\n## References\n\nThere is a bunch of work done by others before me which greatly helped figuring out how the BLE protocol works with the Sony Alpha cameras. I'm sure I'm forgetting a bunch but to at least name a few:\n\n- https://github.com/dzwiedziu-nkg/esp32-a7iv-rc\n- https://github.com/ekutner/camera-gps-link\n- https://github.com/whc2001/ILCE7M3ExternalGps\n- And many more (search GitHub for one of the unique identifiers such as the service UUIDs).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffinfinack%2Falphaloc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffinfinack%2Falphaloc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffinfinack%2Falphaloc/lists"}