# furrtek/precir architecture

> Architecture diagram of the GitHub repository furrtek/precir, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-22). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/furrtek/precir
- Repository: https://github.com/furrtek/precir

## Overview

PrecIR is a collection of tools and transmitter hardware for communicating with infrared electronic shelf labels (ESLs). The Android workflow combines barcode scanning or image/page selection with frame preparation, then sends commands over USB serial to an ESL Blaster; firmware schedules timed infrared transmission to a line-of-sight ESL. The repository also includes standalone transmitter firmware, configurable remote-frame storage, and a special raw-frame firmware variant. The README documents additional command-line and Windows tools, but their implementation paths are absent from the supplied tree. App and firmware source excerpts are partial, so uncertain internal wiring is omitted.

Main entry points: [`PriceHax/app/src/main/java/org/furrtek/pricehax2/MainActivity.java`](https://github.com/furrtek/precir/blob/master/PriceHax/app/src/main/java/org/furrtek/pricehax2/MainActivity.java) (PriceHax UI), [`hardware/esl_blaster/FW03/Src/main.c`](https://github.com/furrtek/precir/blob/master/hardware/esl_blaster/FW03/Src/main.c) (Firmware v3), [`hardware/esl_blaster/FW03S/Src/main.c`](https://github.com/furrtek/precir/blob/master/hardware/esl_blaster/FW03S/Src/main.c) (Raw-frame firmware), [`PriceHax/app/src/main/java/org/furrtek/pricehax2/DMConvert.java`](https://github.com/furrtek/precir/blob/master/PriceHax/app/src/main/java/org/furrtek/pricehax2/DMConvert.java) (Image conversion)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_android["Android client"]
  node_activity["PriceHax UI<br/>[MainActivity.java]"]
  node_camera["Camera preview<br/>[CameraPreview.java]"]
  node_usb["USB serial link<br/>[MainActivity.java]"]
  node_txprogress["Transmit progress<br/>[TXProgress.java]"]
  node_async["Async callbacks"]
end

subgraph group_frame["Frame preparation"]
  node_frame["IR frames<br/>[IRFrame.java]"]
  node_convert["Image conversion<br/>[DMConvert.java]"]
  node_convertparams["Conversion options"]
  node_dmimage["Display image<br/>[DMImage.java]"]
  node_dither["Bitmap dithering<br/>[DitherBitmap.java]"]
  node_dmgen["Display frame generation<br/>[DMGen.java]"]
end

subgraph group_blaster["ESL Blaster"]
  node_blaster{{"ESL Blaster"}}
end

subgraph group_firmware["Firmware variants"]
  node_fw01["Firmware v1<br/>[main.c]"]
  node_fw02["Firmware v2<br/>[main.c]"]
  node_fw03["Firmware v3<br/>[main.c]"]
  node_fw03s["Raw-frame firmware<br/>[main.c]"]
  node_usbcdc["USB CDC interface<br/>[usbd_cdc_if.c]"]
  node_remote["Stored remote frames<br/>[main.h]"]
end

node_user(("Operator"))
node_esl(("Infrared ESL"))
node_serialadapter(("USB-serial adapter"))

node_user -->|"operates"| node_activity
node_activity -->|"starts preview"| node_camera
node_camera -->|"provides frames"| node_activity
node_activity -->|"sets options"| node_convertparams
node_activity -->|"converts image"| node_convert
node_convert -->|"produces image"| node_dmimage
node_convert -->|"uses dithering"| node_dither
node_activity -->|"requests frames"| node_dmgen
node_dmgen -->|"creates"| node_frame
node_activity -->|"builds commands"| node_frame
node_activity -->|"transmits frames"| node_usb
node_usb -->|"USB serial"| node_blaster
node_serialadapter -.->|"serial control"| node_blaster
node_blaster -->|"runs"| node_fw01
node_blaster -->|"runs"| node_fw02
node_blaster -->|"runs"| node_fw03
node_blaster -.->|"runs"| node_fw03s
node_fw03 -->|"receives CDC data"| node_usbcdc
node_fw03s -->|"receives CDC data"| node_usbcdc
node_usbcdc -->|"feeds command loop"| node_fw03
node_fw03 -->|"reads stored frames"| node_remote
node_fw03s -.->|"reads stored frames"| node_remote
node_fw01 -->|"transmits infrared"| node_esl
node_fw02 -->|"transmits infrared"| node_esl
node_fw03 -->|"transmits infrared"| node_esl
node_fw03s -.->|"transmits raw IR"| node_esl
node_activity -->|"updates status"| node_txprogress
node_activity -->|"dispatches callback"| node_async

click node_activity "https://github.com/furrtek/precir/blob/master/PriceHax/app/src/main/java/org/furrtek/pricehax2/MainActivity.java"
click node_camera "https://github.com/furrtek/precir/blob/master/PriceHax/app/src/main/java/org/furrtek/pricehax2/CameraPreview.java"
click node_frame "https://github.com/furrtek/precir/blob/master/PriceHax/app/src/main/java/org/furrtek/pricehax2/IRFrame.java"
click node_convert "https://github.com/furrtek/precir/blob/master/PriceHax/app/src/main/java/org/furrtek/pricehax2/DMConvert.java"
click node_convertparams "https://github.com/furrtek/precir/blob/master/PriceHax/app/src/main/java/org/furrtek/pricehax2/DMConvertParams.java"
click node_dmimage "https://github.com/furrtek/precir/blob/master/PriceHax/app/src/main/java/org/furrtek/pricehax2/DMImage.java"
click node_dither "https://github.com/furrtek/precir/blob/master/PriceHax/app/src/main/java/org/furrtek/pricehax2/DitherBitmap.java"
click node_dmgen "https://github.com/furrtek/precir/blob/master/PriceHax/app/src/main/java/org/furrtek/pricehax2/DMGen.java"
click node_usb "https://github.com/furrtek/precir/blob/master/PriceHax/app/src/main/java/org/furrtek/pricehax2/MainActivity.java"
click node_fw01 "https://github.com/furrtek/precir/blob/master/hardware/esl_blaster/FW01/Src/main.c"
click node_fw02 "https://github.com/furrtek/precir/blob/master/hardware/esl_blaster/FW02/Src/main.c"
click node_fw03 "https://github.com/furrtek/precir/blob/master/hardware/esl_blaster/FW03/Src/main.c"
click node_fw03s "https://github.com/furrtek/precir/blob/master/hardware/esl_blaster/FW03S/Src/main.c"
click node_usbcdc "https://github.com/furrtek/precir/blob/master/hardware/esl_blaster/FW03/Src/usbd_cdc_if.c"
click node_remote "https://github.com/furrtek/precir/blob/master/hardware/esl_blaster/FW03/Inc/main.h"
click node_txprogress "https://github.com/furrtek/precir/blob/master/PriceHax/app/src/main/java/org/furrtek/pricehax2/TXProgress.java"
click node_async "https://github.com/furrtek/precir/blob/master/PriceHax/app/src/main/java/org/furrtek/pricehax2/AsyncResponseTX.java"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_activity,node_camera,node_usb,node_txprogress,node_async toneBlue
class node_frame,node_convert,node_convertparams,node_dmimage,node_dither,node_dmgen toneAmber
class node_blaster toneMint
class node_fw01,node_fw02,node_fw03,node_fw03s,node_usbcdc,node_remote toneRose
class node_user,node_esl,node_serialadapter toneIndigo
```

## Components

### Android client

- [PriceHax UI](https://github.com/furrtek/precir/blob/master/PriceHax/app/src/main/java/org/furrtek/pricehax2/MainActivity.java): `PriceHax/app/src/main/java/org/furrtek/pricehax2/MainActivity.java`
- [Camera preview](https://github.com/furrtek/precir/blob/master/PriceHax/app/src/main/java/org/furrtek/pricehax2/CameraPreview.java): `PriceHax/app/src/main/java/org/furrtek/pricehax2/CameraPreview.java`
- [USB serial link](https://github.com/furrtek/precir/blob/master/PriceHax/app/src/main/java/org/furrtek/pricehax2/MainActivity.java): `PriceHax/app/src/main/java/org/furrtek/pricehax2/MainActivity.java`
- [Transmit progress](https://github.com/furrtek/precir/blob/master/PriceHax/app/src/main/java/org/furrtek/pricehax2/TXProgress.java): `PriceHax/app/src/main/java/org/furrtek/pricehax2/TXProgress.java`
- [Async callbacks](https://github.com/furrtek/precir/blob/master/PriceHax/app/src/main/java/org/furrtek/pricehax2/AsyncResponseTX.java): `PriceHax/app/src/main/java/org/furrtek/pricehax2/AsyncResponseTX.java`

### Frame preparation

- [IR frames](https://github.com/furrtek/precir/blob/master/PriceHax/app/src/main/java/org/furrtek/pricehax2/IRFrame.java): `PriceHax/app/src/main/java/org/furrtek/pricehax2/IRFrame.java`
- [Image conversion](https://github.com/furrtek/precir/blob/master/PriceHax/app/src/main/java/org/furrtek/pricehax2/DMConvert.java): `PriceHax/app/src/main/java/org/furrtek/pricehax2/DMConvert.java`
- [Conversion options](https://github.com/furrtek/precir/blob/master/PriceHax/app/src/main/java/org/furrtek/pricehax2/DMConvertParams.java): `PriceHax/app/src/main/java/org/furrtek/pricehax2/DMConvertParams.java`
- [Display image](https://github.com/furrtek/precir/blob/master/PriceHax/app/src/main/java/org/furrtek/pricehax2/DMImage.java): `PriceHax/app/src/main/java/org/furrtek/pricehax2/DMImage.java`
- [Bitmap dithering](https://github.com/furrtek/precir/blob/master/PriceHax/app/src/main/java/org/furrtek/pricehax2/DitherBitmap.java): `PriceHax/app/src/main/java/org/furrtek/pricehax2/DitherBitmap.java`
- [Display frame generation](https://github.com/furrtek/precir/blob/master/PriceHax/app/src/main/java/org/furrtek/pricehax2/DMGen.java): `PriceHax/app/src/main/java/org/furrtek/pricehax2/DMGen.java`

### ESL Blaster

- **ESL Blaster**

### Firmware variants

- [Firmware v1](https://github.com/furrtek/precir/blob/master/hardware/esl_blaster/FW01/Src/main.c): `hardware/esl_blaster/FW01/Src/main.c`
- [Firmware v2](https://github.com/furrtek/precir/blob/master/hardware/esl_blaster/FW02/Src/main.c): `hardware/esl_blaster/FW02/Src/main.c`
- [Firmware v3](https://github.com/furrtek/precir/blob/master/hardware/esl_blaster/FW03/Src/main.c): `hardware/esl_blaster/FW03/Src/main.c`
- [Raw-frame firmware](https://github.com/furrtek/precir/blob/master/hardware/esl_blaster/FW03S/Src/main.c): `hardware/esl_blaster/FW03S/Src/main.c`
- [USB CDC interface](https://github.com/furrtek/precir/blob/master/hardware/esl_blaster/FW03/Src/usbd_cdc_if.c): `hardware/esl_blaster/FW03/Src/usbd_cdc_if.c`
- [Stored remote frames](https://github.com/furrtek/precir/blob/master/hardware/esl_blaster/FW03/Inc/main.h): `hardware/esl_blaster/FW03/Inc/main.h`

### Other components

- **Operator**
- **Infrared ESL**
- **USB-serial adapter**

## Connections

- Operator → PriceHax UI: operates
- PriceHax UI → Camera preview: starts preview
- Camera preview → PriceHax UI: provides frames
- PriceHax UI → Conversion options: sets options
- PriceHax UI → Image conversion: converts image
- Image conversion → Display image: produces image
- Image conversion → Bitmap dithering: uses dithering
- PriceHax UI → Display frame generation: requests frames
- Display frame generation → IR frames: creates
- PriceHax UI → IR frames: builds commands
- PriceHax UI → USB serial link: transmits frames
- USB serial link → ESL Blaster: USB serial
- USB-serial adapter → ESL Blaster: serial control
- ESL Blaster → Firmware v1: runs
- ESL Blaster → Firmware v2: runs
- ESL Blaster → Firmware v3: runs
- ESL Blaster → Raw-frame firmware: runs
- Firmware v3 → USB CDC interface: receives CDC data
- Raw-frame firmware → USB CDC interface: receives CDC data
- USB CDC interface → Firmware v3: feeds command loop
- Firmware v3 → Stored remote frames: reads stored frames
- Raw-frame firmware → Stored remote frames: reads stored frames
- Firmware v1 → Infrared ESL: transmits infrared
- Firmware v2 → Infrared ESL: transmits infrared
- Firmware v3 → Infrared ESL: transmits infrared
- Raw-frame firmware → Infrared ESL: transmits raw IR
- PriceHax UI → Transmit progress: updates status
- PriceHax UI → Async callbacks: dispatches callback
