Documentation

Set up your kit, talk to the board from your own code, and look up what every module sends and understands.

Ask ClaudeAsk ChatGPTOpens your own account with these docs loaded.

Quick start

For parents, schools and learners

You describe what you want to build, Atech picks the modules and writes the firmware, and you upload it to the board from the browser. No soldering and nothing to install.

A desktop Chromium browser

Chrome, Edge, Brave, Opera or Arc. Uploading uses Web Serial, which Firefox, Safari and phone browsers do not have.

A USB-C data cable

Charge-only cables cannot program the board. One that came with a phone or laptop works.

  1. 1
    Describe what to build

    Open atech.dev/editor and type your idea in the prompt box, for example “a button toggles the light grid”. You get a board diagram and generated firmware.

  2. 2
    Put the modules where the diagram shows

    Slide each module into its port and push it in firmly. You can rearrange them in the editor at any time; the firmware is rebuilt for the new layout.

  3. 3
    Plug in the board

    USB-C from the board to your computer. No driver needed.

  4. 4
    Pick WiFi or USB

    On WiFi, open the connection pill and add your WiFi credentials so the board can join your network. On USB, open the pill and click “Connect device via USB” once.

  5. 5
    Upload the code

    Click “Upload Code”. The board restarts, and its events start streaming in the connection pill.

Build with your own agent

For software developers, vibe-coders and companies

You can skip the editor and build with Claude Code, Codex, Cursor, Lovable or any coding agent that can run Python. The open-source Atech SDK gives the agent the module catalogue, each module's API and a bundled compiler that builds and flashes the board offline. No account needed.

1. Install the SDK

pip install atech

2. Give your agent this prompt

Paste it into the agent's chat, then describe what you want to build. It asks which board and modules you have before it writes any code.

Install the Atech Python SDK and use it to build my project:

    pip install atech

It needs Python 3.10 or newer. Then run `atech guide` and read all of it before
anything else: it is the SDK's own manual for coding agents (the workflow, the
rules, what will bite you). `atech guide protocol` covers the wire format.

Atech is a modular electronics platform: pre-built hardware modules snap into
numbered ports on an ESP32 motherboard, with no soldering or wiring. The SDK
ships the module catalog, each module's API, and a bundled compiler that builds
and flashes the board offline.

Before you write any code, ask me:

1. Which Atech board do I have? Run `atech list-boards` to see the boards and
   their ports.
2. Which modules do I own? Run `atech list-modules` to see every module the
   SDK knows about, and ask me which of those I actually have in hand.
3. Which port is each module plugged into?

If I don't have a board yet, or I'm missing a module the build needs, point me
to https://atech.dev/buy and suggest which kit fits what I described.

Then:

- Run `atech new <name> --board <board id>` and describe the build in its
  project.yaml, using only modules I confirmed I own and the ports I confirmed
  they're in. `atech info <module>` shows a module's API.
- Run `atech validate`, then `atech build`, and fix anything they report.
  Tell me first that the first build downloads the ESP32 compiler, about
  2.4 GB, once.
- Run `atech upload` with my board on USB-C (a data cable), then `atech check`
  to see which modules answered, and tell me what to expect it to do.

3. What the agent runs

  • atech guideThe SDK's manual for coding agents. Read first.
  • atech list-modulesEvery module in the catalog, with its API.
  • atech new <name> --board <id>A project.yaml, plus AGENTS.md and CLAUDE.md for the agent.
  • atech validateCheck the project before building.
  • atech buildCompile the project to ESP32 firmware, offline.
  • atech uploadFlash the board over USB-C.
  • atech checkReboot the board and see which modules answered.

The SDK is Python and open source, on PyPI. No board yet? Your agent will point you to a kit that fits.

The board

Every kit uses the same motherboard: an ESP32-S3 with 12 module ports around its edge. The port numbers are printed on the board.

  • Module ports: 1–7, 9–11 and 13–14.
  • 8 is the USB-C socket and 12 is the reset button.
  • Most modules take one port. Double-width modules (Color Display, Knob, Speaker, Microphone, Big Screen, Camera, microSD Card) take two neighbouring ports on the same side: 1–2, 2–3, 3–4, 4–5, 5–6, 9–10, 10–11, 13–14.

The firmware is built for the ports in your project's diagram. If you move a module on the board, move it in the editor too and upload again.

The motherboard seen from above, with ports numbered 1 to 14

Pin layout

Every port is a 6-pin header: 1 is 12V, 2 is 5V, 3 is 3.3V, 4 is ground, and 5 and 6 are the two data lines, D1 and D2. The power pins are shared by every port; the data lines go to the ESP32-S3 pins shown below. Open a map to see it full size.

The 14-port board with each port's six pins drawn out to labels: 12V, 5V, 3.3V, ground, and the D1 and D2 GPIOs
14-port board. Ports 1–6 on the left, 7 at the top, 9–14 on the right. 8 is the USB-C socket, 12 the reset button. A module always plugs in with 12V on its left, so on 7, 9, 10, 11, 13 and 14 the pins run 6 → 1 seen from above.
The 10-port board, front and back, with each port's six pins drawn out to labels: 12V, 5V, 3.3V, ground, and the D1 and D2 GPIOs
10-port board. Ports 1–6 on the front, 7–10 on the back. 10 is where the USB-C module plugs in. A module always plugs in with 12V on its left, so on 4, 5, 6, 7 and 8 the pins run 6 → 1 seen from above.

Events & actions

A running board speaks JSON, and there are only two kinds of message. Events come from the board on their own: a sensor reading, a button press. Actions are commands you send to it: set a colour, play a tone, draw text.

// Event: the board tells you something
{
  "event_type": "sensor",        // sensor | button | state | log
  "key":        "temperature",   // which reading; set by your build's firmware
  "value":      23.4             // number, string, object or bool
}

// Action: you tell the board to do something
{
  "action": "set_color",         // set by your build's firmware
  "value":  { "r": 255, "g": 0, "b": 0 }
}

Which keys and actions exist depends on the modules in your build and the firmware written for them. The module reference lists what each module can do.

Connect from code

There are two ways to reach the board, chosen per project with the WiFi / USB toggle in the editor. The event and action payloads are the same on both; only the wrapper around them differs. Switching transport rebuilds the firmware.

WiFi

The board runs on its own. Control it from another machine, a phone or a deployed web app.

Address
wss://gateway.atech.dev/ws/live/<project id>
From board
{ "type": "device_event", "payload": {…} }
To board
{ "type": "send_to_device", "device_id": "<project id>", "payload": {…} }
USB

Local and offline. The computer the board is plugged into talks straight to it, no cloud.

Port
115200 baud, one JSON object per line
From board
{ "type": "event", "payload": {…} }
To board
{ "action": "…", "value": … }

Your project id is in the editor: open the project's Docs tab and look under Your project.

Over WiFi

const PROJECT_ID = "<your project id>";
const ws = new WebSocket(`wss://gateway.atech.dev/ws/live/${PROJECT_ID}`);

// Every event the board sends
ws.onmessage = (e) => console.log(JSON.parse(e.data));

// Send an action
ws.onopen = () => ws.send(JSON.stringify({
  type: "send_to_device",
  device_id: PROJECT_ID,
  payload: { action: "set_color", value: { r: 255, g: 0, b: 0 } },
}));

Over USB

// Browser, Web Serial API
const port = await navigator.serial.requestPort();
await port.open({ baudRate: 115200 });

const writer = port.writable.getWriter();
const enc = new TextEncoder();
const send = (action) => writer.write(enc.encode(JSON.stringify(action) + "\n"));

// Read the board's events, one JSON object per line
const reader = port.readable.pipeThrough(new TextDecoderStream()).getReader();
(async () => {
  let buf = "";
  while (true) {
    const { value, done } = await reader.read();
    if (done) break;
    buf += value;
    let i;
    while ((i = buf.indexOf("\n")) >= 0) {
      console.log(buf.slice(0, i));
      buf = buf.slice(i + 1);
    }
  }
})();

// Send an action
send({ action: "set_color", value: { r: 255, g: 0, b: 0 } });

Module reference

What each module can do, with the type and unit of every reading, and the pins it uses. Open a module to see its list.

Color Display
9 capabilities · 2 ports

Module id st7735_tft · ST7735 TFT Color Display (160x80) · Digital · ST7735S (Sitronix)

What it can do

  • display_text

    Display text at cursor position with configurable size and color

  • clear_display

    Clear the display to black

  • fill_screen

    Fill entire screen with a color

  • draw_pixel

    Draw a single pixel at x,y with color

  • draw_line

    Draw a line between two points

  • draw_rect

    Draw a rectangle outline

  • fill_rect

    Draw a filled rectangle

  • draw_circle

    Draw a circle outline

  • fill_circle

    Draw a filled circle

Pins

  • 3.3V (first port)

    supply

  • GND (first port)

    ground

  • Data A (first port)

    DC, data/command select

  • Data B (first port)

    CS, chip select

  • 3.3V (second port)

    supply

  • GND (second port)

    ground

  • Data A (second port)

    MOSI, data in

  • Data B (second port)

    SCLK, serial clock

LED Grid
8 capabilities

Module id neopixel_grid · NeoPixel 3x3 LED Grid · Digital · WS2812B (Worldsemi)

What it can do

  • set_pixel

    Set a single LED by index (0-8) to RGB color

  • set_all

    Set all LEDs to the same RGB color

  • set_row

    Set an entire row to a color

  • set_column

    Set an entire column to a color

  • clear

    Turn off all LEDs

  • show

    Update physical LEDs with current colors

  • set_brightness

    Set global brightness (0-255). Values above 51 are clamped to 51 (20% cap).

  • get_pixel_color

    Get a pixel's color as packed uint32_t (0x00RRGGBB). Extract: r = (color >> 16) & 0xFF, g = (color >> 8) & 0xFF, b = color & 0xFF

Pins

  • 3.3V

    supply

  • GND

    ground

  • Data A

    LED data (V1.x, RGB)

  • Data B

    LED data (V2.x, RGBW)

Orientation Sensor
12 capabilities

Module id icm40608_imu · 6-Axis IMU (ICM-40608 or LSM6DSOX) · I2C (0x68) · LSM6DSOX (STMicroelectronics)

What it can do

  • read_accel_xfloat, g

    Read X-axis acceleration in g

  • read_accel_yfloat, g

    Read Y-axis acceleration in g

  • read_accel_zfloat, g

    Read Z-axis acceleration in g

  • read_gyro_xfloat, deg/s

    Read X-axis rotation rate in degrees/second

  • read_gyro_yfloat, deg/s

    Read Y-axis rotation rate in degrees/second

  • read_gyro_zfloat, deg/s

    Read Z-axis rotation rate in degrees/second

  • read_temperaturefloat, C

    Read sensor die temperature

  • get_pitchfloat, deg

    Pitch angle (nose up/down) in degrees, -90..+90, from accelerometer

  • get_rollfloat, deg

    Roll angle (left/right tilt) in degrees, -180..+180, from accelerometer

  • get_tilt_anglefloat, deg

    Total tilt from upright in degrees (0 = flat face-up, 180 = flat face-down)

  • get_orientationstring

    Coarse 6-way orientation: face_up, face_down, edge_right, edge_left, edge_front, edge_back, unknown

  • was_shakenbool

    Edge-triggered shake/tap detector (returns true once per spike >1.8g, then resets)

Pins

  • 3.3V

    supply

  • GND

    ground

  • Data A

    I²C SDA

  • Data B

    I²C SCL

Temperature & Humidity
2 capabilities

Module id aht20_sensor · AHT20 Temperature & Humidity Sensor · I2C (0x38) · AHT20 (ASAIR (Guangzhou Aosong Electronics))

What it can do

  • read_temperaturefloat, C

    Read temperature in Celsius

  • read_humidityfloat, %RH

    Read relative humidity

Pins

  • 3.3V

    supply

  • GND

    ground

  • Data A

    I²C SDA

  • Data B

    I²C SCL

Air Quality
4 capabilities

Module id scd40_air_quality · SCD40 Air Quality Sensor (CO2) · I2C (0x62) · SCD40 (Sensirion)

What it can do

  • read_co2int, ppm

    Read CO2 concentration in ppm

  • read_temperaturefloat, C

    Read temperature in Celsius

  • read_humidityfloat, %RH

    Read relative humidity

  • is_readybool

    Check if first measurement has been received

Pins

  • 3.3V

    supply

  • GND

    ground

  • Data A

    I²C SDA

  • Data B

    I²C SCL

Distance Sensor
4 capabilities

Module id vl53l5cx_distance · VL53L5CX 8x8 Distance Sensor · I2C (0x29) · VL53L5CX (STMicroelectronics)

What it can do

  • get_distanceint, mm

    Get distance for a specific zone (0-63) in mm

  • get_min_distanceint, mm

    Get minimum distance across all 64 zones in mm

  • get_max_distanceint, mm

    Get maximum distance across all 64 zones in mm

  • is_readybool

    Check if sensor has data available

Pins

  • 3.3V

    supply

  • GND

    ground

  • Data A

    I²C SDA

  • Data B

    I²C SCL

Knob
14 capabilities · 2 ports

Module id rotary_encoder_knob · Rotary Encoder Knob · Digital · EC11 (generic (Bourns/ALPS-compatible))

What it can do

  • getPositionint, steps

    Get cumulative rotation position as int32_t (increments/decrements with each step)

  • setPositionvoid

    Set position to a specific value: setPosition(int32_t pos)

  • resetPositionvoid

    Reset position counter to zero

  • getDirectionint

    Get direction of last rotation: 1=CW, -1=CCW, 0=none

  • wasRotatedCWbool

    Check if knob was rotated clockwise since last check

  • wasRotatedCCWbool

    Check if knob was rotated counter-clockwise since last check

  • isPressedbool

    Check if knob button is currently pressed (press down on knob)

  • wasPressedbool

    Check if knob button was just pressed (edge detection)

  • updatevoid

    Sample encoder, poll button, and refresh the ring - MUST call once per loop iteration. Encoder counts in hardware (PCNT); this call reads the count and repaints the ring.

  • setAccelerationvoid

    Configure acceleration: setAcceleration(bool enabled, int maxMultiplier=5). Enabled by default. Slow turns = 1 step, fast spins = up to maxMultiplier steps per click.

  • enableRingvoid

    Enable or disable the LED indicator ring: enableRing(bool enabled). Ring is enabled by default.

  • setRingColorvoid

    Set ring indicator color: setRingColor(uint8_t r, uint8_t g, uint8_t b). Default is white (255,255,255).

  • setRingBrightnessvoid

    Set ring global brightness: setRingBrightness(uint8_t brightness). 0-255, default ~50.

  • setRingPositionvoid

    Manually override ring position: setRingPosition(float pos). 0.0-12.0 maps around the physical ring (CCW from 12 o'clock). Pass negative to re-couple to knob position.

Pins

  • 3.3V (first port)

    supply

  • GND (first port)

    ground

  • Data A (first port)

    encoder CLK (channel A)

  • Data B (first port)

    encoder DT (channel B)

  • 3.3V (second port)

    supply

  • GND (second port)

    ground

  • Data A (second port)

    button switch, active low

  • Data B (second port)

    NeoPixel ring data

Button
3 capabilities

Module id button_module · Button · Digital

What it can do

  • is_pressedbool

    Check if button is currently pressed

  • was_pressedbool

    Check if button was just pressed (edge detection)

  • was_releasedbool

    Check if button was just released (edge detection)

Pins

  • 3.3V

    supply

  • GND

    ground

  • Data A

    switch, active low (pressed = LOW)

  • Data B

    RGB indicator LED (V2.0 only)

Speaker
8 capabilities · 2 ports

Module id speaker · I2S Speaker (MAX98357A) · Digital · MAX98357A (Analog Devices (Maxim))

What it can do

  • play_tone

    Play a tone at given frequency for a duration (blocking)

  • play_note

    Play a musical note with automatic gap between notes

  • play_rtttl

    Play an RTTTL melody string (non-blocking, plays in background)

  • rest

    Play silence for a duration

  • stop

    Stop any sound immediately

  • set_volume

    Set volume level (0.0 to 1.0)

  • write_samples

    Write raw 16-bit mono audio samples directly to I2S output (for streaming from microphone)

  • play_pcm

    Play a base64-encoded chunk of 16-bit mono PCM streamed from the host. The browser/app decodes the MP3, resamples to 16 kHz mono, and sends play_pcm chunks. The firmware just forwards each chunk to the I2S DAC. This is how the device plays MP3/WAV/audio files, with no on-device decoder needed.

Pins

  • 3.3V (first port)

    supply

  • GND (first port)

    ground

  • Data A (first port)

    LRCLK, left/right clock

  • Data B (first port)

    BCLK, bit clock

  • 3.3V (second port)

    supply

  • GND (second port)

    ground

  • Data B (second port)

    DIN, audio data

Microphone
10 capabilities · 2 ports

Module id microphone · I2S MEMS Microphone (ICS-43434) · Digital · ICS-43434 (TDK InvenSense)

What it can do

  • get_sound_level

    Get current RMS sound level (0-32767)

  • is_sound_detected

    Check if sound exceeds a threshold

  • get_peak_amplitude

    Get peak amplitude since last read (resets after read)

  • get_samples

    Copy raw audio samples into a buffer

  • start_recording

    Start recording audio into heap buffer (up to 10 seconds)

  • stop_recording

    Stop recording audio

  • is_recording

    Check if currently recording

  • get_recording

    Get pointer to recorded audio buffer for playback

  • get_recording_length

    Get number of recorded samples

  • set_channel

    Select left or right channel (LR pin)

Pins

  • 3.3V (first port)

    supply

  • GND (first port)

    ground

  • Data A (first port)

    LR, left/right channel select

  • Data B (first port)

    WS, word select

  • 3.3V (second port)

    supply

  • GND (second port)

    ground

  • Data A (second port)

    SCK, serial clock

  • Data B (second port)

    SD, serial data

DC Motor
5 capabilities

Module id dc_motor · DC Motor (H-Bridge) · Digital · DRV8833 (Texas Instruments)

What it can do

  • forward

    Run motor forward at specified speed (0-255)

  • reverse

    Run motor in reverse at specified speed (0-255)

  • stop

    Stop the motor (coast)

  • brake

    Brake the motor (active stop)

  • set_speed

    Set motor speed and direction (-255 to +255)

Pins

  • 3.3V

    supply

  • GND

    ground

  • Data A

    IN1

  • Data B

    IN2

Big Screen
12 capabilities · 2 ports

Module id st7789_tft · ST7789 TFT Color Display (320x240) · Digital

What it can do

  • display_text

    Display text at cursor position with configurable size and color

  • clear_display

    Clear the display to black

  • fill_screen

    Fill entire screen with a color

  • draw_pixel

    Draw a single pixel at x,y with color

  • draw_line

    Draw a line between two points

  • draw_rect

    Draw a rectangle outline

  • fill_rect

    Draw a filled rectangle

  • draw_circle

    Draw a circle outline

  • fill_circle

    Draw a filled circle

  • draw_round_rect

    Draw a rounded rectangle, outline or filled

  • draw_triangle

    Draw a triangle, outline or filled

  • draw_ellipse

    Draw an ellipse, outline or filled

Pins

  • 3.3V (first port)

    supply

  • GND (first port)

    ground

  • Data A (first port)

    DC, data/command select (the panel's RS pin)

  • Data B (first port)

    CS, chip select

  • 3.3V (second port)

    supply

  • GND (second port)

    ground

  • Data A (second port)

    MOSI, data in

  • Data B (second port)

    SCLK, serial clock

Soil Sensor
7 capabilities

Module id soil_sensor · Soil Moisture Sensor (two-prong galvanic probe) · I2C (0x37) · CH32V003

What it can do

  • read_moisturefloat, %

    Read calibrated soil moisture, 0-100 %

  • read_conductancefloat, uS

    Read conductance between the prongs in microsiemens

  • read_rawint, counts

    Read the raw oversampled reading (HIGH means DRY)

  • calibrate_dry

    Record the current reading as the 0 % point; call with the probe in air

  • calibrate_wet

    Record the current reading as the 100 % point; call with the prongs in water

  • set_status_color

    Drive the on-module status LED

  • set_status_off

    Turn the on-module status LED off

Pins

  • 3.3V

    supply

  • GND

    ground

  • Data A

    I²C SDA

  • Data B

    I²C SCL

Camera
5 capabilities · 2 ports

Module id ov5640_camera · OV5640 Camera (SPI) · Digital

What it can do

  • capture_frame

    Capture one JPEG frame into the driver's buffer

  • stream

    Start or stop continuous capture, so frames are always fresh

  • set_resolution

    Set capture resolution, QQVGA through HD

  • set_quality

    Set JPEG quality, 0-63, lower is better

  • camera_status

    Report link and sensor state

Pins

  • 3.3V (first port)

    supply

  • GND (first port)

    ground

  • Data A (first port)

    MISO: module to board

  • Data B (first port)

    MOSI: board to module

  • 3.3V (second port)

    supply

  • GND (second port)

    ground

  • Data A (second port)

    SCLK: serial clock

  • Data B (second port)

    CS: chip select

microSD Card
11 capabilities · 2 ports

Module id micro_sd_card · microSD Card (SPI) · Digital

What it can do

  • write_file

    Write text or bytes to a path, replacing the file

  • append_line

    Append a line to a file

  • read_file

    Read a file back

  • list_dir

    List a directory

  • find

    Search for files by glob

  • grep

    Search inside a file for text

  • make_dir

    Create a directory

  • delete_file

    Delete a file

  • card_info

    Card type, capacity, used and free space

  • remount

    Mount a card that was inserted after boot

  • log

    Queue lines to a file from a background writer, without blocking

Pins

  • 3.3V (first port)

    supply

  • GND (first port)

    ground

  • Data A (first port)

    CS, chip select

  • Data B (first port)

    SCLK, serial clock

  • 3.3V (second port)

    supply

  • GND (second port)

    ground

  • Data A (second port)

    MOSI

  • Data B (second port)

    MISO

Troubleshooting

The board will not connect, or the upload fails

  1. Unplug the USB cable from the board, wait a second, plug it back in and try again. This fixes most cases.
  2. Close anything else that holds the port: another atech.dev tab (only one tab can use the board at a time) or the Arduino IDE Serial Monitor.
  3. Use a data USB-C cable. Many cables are charge-only and cannot program the board.
  4. Plug straight into the computer, not through a hub.
  5. Press the board's reset button, then try again.
  6. On Linux, your user has to be in the dialout group.

There is no way to upload from my browser

Uploading needs the Web Serial API, which only desktop Chromium browsers have. Open the project in Chrome, Edge, Brave, Opera or Arc on a computer.

The upload finished but the board stays offline

After an upload the board restarts and reconnects, which can take up to 60 seconds. If it has not come back by then, unplug and replug it or press its reset button. On WiFi, check the network name and password you entered; the board joins 2.4 GHz networks only.

My code connects but nothing arrives

The board is not online. Open the connection pill in the editor and check that “Receiving frames” is green.

The connection is refused or closes at once

Check the address. It ends in your project id; copy it fresh from the project's Docs tab, under Your project.

I send an action and the board ignores it

The firmware only accepts the actions of the modules in that build. Check that the module is in the build and the action is one its firmware handles.

Get help

Stuck, or found something that does not work as described here? Ask in Discord, where the team and other builders answer, or write to [email protected].

Ask ClaudeAsk ChatGPTOpens your own account with these docs loaded.

Or add Atech to your assistant for good: in Claude (Settings, Connectors) or ChatGPT (Settings, Connectors) add a connector with the address https://atech.dev/mcp. It then answers from these docs every time, nothing to paste.