Documentation
Set up your kit, talk to the board from your own code, and look up what every module sends and understands.
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.
Chrome, Edge, Brave, Opera or Arc. Uploading uses Web Serial, which Firefox, Safari and phone browsers do not have.
Charge-only cables cannot program the board. One that came with a phone or laptop works.
- 1Describe 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.
- 2Put 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.
- 3Plug in the board
USB-C from the board to your computer. No driver needed.
- 4Pick 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.
- 5Upload 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.

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.


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.
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": {…} }
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 Display9 capabilities · 2 ports
Module id st7735_tft · ST7735 TFT Color Display (160x80) · Digital · ST7735S (Sitronix)
What it can do
display_textDisplay text at cursor position with configurable size and color
clear_displayClear the display to black
fill_screenFill entire screen with a color
draw_pixelDraw a single pixel at x,y with color
draw_lineDraw a line between two points
draw_rectDraw a rectangle outline
fill_rectDraw a filled rectangle
draw_circleDraw a circle outline
fill_circleDraw 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 Grid8 capabilities
Module id neopixel_grid · NeoPixel 3x3 LED Grid · Digital · WS2812B (Worldsemi)
What it can do
set_pixelSet a single LED by index (0-8) to RGB color
set_allSet all LEDs to the same RGB color
set_rowSet an entire row to a color
set_columnSet an entire column to a color
clearTurn off all LEDs
showUpdate physical LEDs with current colors
set_brightnessSet global brightness (0-255). Values above 51 are clamped to 51 (20% cap).
get_pixel_colorGet a pixel's color as packed uint32_t (0x00RRGGBB). Extract: r = (color >> 16) & 0xFF, g = (color >> 8) & 0xFF, b = color & 0xFF
Pins
3.3Vsupply
GNDground
Data ALED data (V1.x, RGB)
Data BLED data (V2.x, RGBW)
Orientation Sensor12 capabilities
Module id icm40608_imu · 6-Axis IMU (ICM-40608 or LSM6DSOX) · I2C (0x68) · LSM6DSOX (STMicroelectronics)
What it can do
read_accel_xfloat, gRead X-axis acceleration in g
read_accel_yfloat, gRead Y-axis acceleration in g
read_accel_zfloat, gRead Z-axis acceleration in g
read_gyro_xfloat, deg/sRead X-axis rotation rate in degrees/second
read_gyro_yfloat, deg/sRead Y-axis rotation rate in degrees/second
read_gyro_zfloat, deg/sRead Z-axis rotation rate in degrees/second
read_temperaturefloat, CRead sensor die temperature
get_pitchfloat, degPitch angle (nose up/down) in degrees, -90..+90, from accelerometer
get_rollfloat, degRoll angle (left/right tilt) in degrees, -180..+180, from accelerometer
get_tilt_anglefloat, degTotal tilt from upright in degrees (0 = flat face-up, 180 = flat face-down)
get_orientationstringCoarse 6-way orientation: face_up, face_down, edge_right, edge_left, edge_front, edge_back, unknown
was_shakenboolEdge-triggered shake/tap detector (returns true once per spike >1.8g, then resets)
Pins
3.3Vsupply
GNDground
Data AI²C SDA
Data BI²C SCL
Temperature & Humidity2 capabilities
Module id aht20_sensor · AHT20 Temperature & Humidity Sensor · I2C (0x38) · AHT20 (ASAIR (Guangzhou Aosong Electronics))
What it can do
read_temperaturefloat, CRead temperature in Celsius
read_humidityfloat, %RHRead relative humidity
Pins
3.3Vsupply
GNDground
Data AI²C SDA
Data BI²C SCL
Air Quality4 capabilities
Module id scd40_air_quality · SCD40 Air Quality Sensor (CO2) · I2C (0x62) · SCD40 (Sensirion)
What it can do
read_co2int, ppmRead CO2 concentration in ppm
read_temperaturefloat, CRead temperature in Celsius
read_humidityfloat, %RHRead relative humidity
is_readyboolCheck if first measurement has been received
Pins
3.3Vsupply
GNDground
Data AI²C SDA
Data BI²C SCL
Distance Sensor4 capabilities
Module id vl53l5cx_distance · VL53L5CX 8x8 Distance Sensor · I2C (0x29) · VL53L5CX (STMicroelectronics)
What it can do
get_distanceint, mmGet distance for a specific zone (0-63) in mm
get_min_distanceint, mmGet minimum distance across all 64 zones in mm
get_max_distanceint, mmGet maximum distance across all 64 zones in mm
is_readyboolCheck if sensor has data available
Pins
3.3Vsupply
GNDground
Data AI²C SDA
Data BI²C SCL
Knob14 capabilities · 2 ports
Module id rotary_encoder_knob · Rotary Encoder Knob · Digital · EC11 (generic (Bourns/ALPS-compatible))
What it can do
getPositionint, stepsGet cumulative rotation position as int32_t (increments/decrements with each step)
setPositionvoidSet position to a specific value: setPosition(int32_t pos)
resetPositionvoidReset position counter to zero
getDirectionintGet direction of last rotation: 1=CW, -1=CCW, 0=none
wasRotatedCWboolCheck if knob was rotated clockwise since last check
wasRotatedCCWboolCheck if knob was rotated counter-clockwise since last check
isPressedboolCheck if knob button is currently pressed (press down on knob)
wasPressedboolCheck if knob button was just pressed (edge detection)
updatevoidSample 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.
setAccelerationvoidConfigure acceleration: setAcceleration(bool enabled, int maxMultiplier=5). Enabled by default. Slow turns = 1 step, fast spins = up to maxMultiplier steps per click.
enableRingvoidEnable or disable the LED indicator ring: enableRing(bool enabled). Ring is enabled by default.
setRingColorvoidSet ring indicator color: setRingColor(uint8_t r, uint8_t g, uint8_t b). Default is white (255,255,255).
setRingBrightnessvoidSet ring global brightness: setRingBrightness(uint8_t brightness). 0-255, default ~50.
setRingPositionvoidManually 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
Button3 capabilities
Module id button_module · Button · Digital
What it can do
is_pressedboolCheck if button is currently pressed
was_pressedboolCheck if button was just pressed (edge detection)
was_releasedboolCheck if button was just released (edge detection)
Pins
3.3Vsupply
GNDground
Data Aswitch, active low (pressed = LOW)
Data BRGB indicator LED (V2.0 only)
Speaker8 capabilities · 2 ports
Module id speaker · I2S Speaker (MAX98357A) · Digital · MAX98357A (Analog Devices (Maxim))
What it can do
play_tonePlay a tone at given frequency for a duration (blocking)
play_notePlay a musical note with automatic gap between notes
play_rtttlPlay an RTTTL melody string (non-blocking, plays in background)
restPlay silence for a duration
stopStop any sound immediately
set_volumeSet volume level (0.0 to 1.0)
write_samplesWrite raw 16-bit mono audio samples directly to I2S output (for streaming from microphone)
play_pcmPlay 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
Microphone10 capabilities · 2 ports
Module id microphone · I2S MEMS Microphone (ICS-43434) · Digital · ICS-43434 (TDK InvenSense)
What it can do
get_sound_levelGet current RMS sound level (0-32767)
is_sound_detectedCheck if sound exceeds a threshold
get_peak_amplitudeGet peak amplitude since last read (resets after read)
get_samplesCopy raw audio samples into a buffer
start_recordingStart recording audio into heap buffer (up to 10 seconds)
stop_recordingStop recording audio
is_recordingCheck if currently recording
get_recordingGet pointer to recorded audio buffer for playback
get_recording_lengthGet number of recorded samples
set_channelSelect 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 Motor5 capabilities
Module id dc_motor · DC Motor (H-Bridge) · Digital · DRV8833 (Texas Instruments)
What it can do
forwardRun motor forward at specified speed (0-255)
reverseRun motor in reverse at specified speed (0-255)
stopStop the motor (coast)
brakeBrake the motor (active stop)
set_speedSet motor speed and direction (-255 to +255)
Pins
3.3Vsupply
GNDground
Data AIN1
Data BIN2
Big Screen12 capabilities · 2 ports
Module id st7789_tft · ST7789 TFT Color Display (320x240) · Digital
What it can do
display_textDisplay text at cursor position with configurable size and color
clear_displayClear the display to black
fill_screenFill entire screen with a color
draw_pixelDraw a single pixel at x,y with color
draw_lineDraw a line between two points
draw_rectDraw a rectangle outline
fill_rectDraw a filled rectangle
draw_circleDraw a circle outline
fill_circleDraw a filled circle
draw_round_rectDraw a rounded rectangle, outline or filled
draw_triangleDraw a triangle, outline or filled
draw_ellipseDraw 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 Sensor7 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, uSRead conductance between the prongs in microsiemens
read_rawint, countsRead the raw oversampled reading (HIGH means DRY)
calibrate_dryRecord the current reading as the 0 % point; call with the probe in air
calibrate_wetRecord the current reading as the 100 % point; call with the prongs in water
set_status_colorDrive the on-module status LED
set_status_offTurn the on-module status LED off
Pins
3.3Vsupply
GNDground
Data AI²C SDA
Data BI²C SCL
Camera5 capabilities · 2 ports
Module id ov5640_camera · OV5640 Camera (SPI) · Digital
What it can do
capture_frameCapture one JPEG frame into the driver's buffer
streamStart or stop continuous capture, so frames are always fresh
set_resolutionSet capture resolution, QQVGA through HD
set_qualitySet JPEG quality, 0-63, lower is better
camera_statusReport 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 Card11 capabilities · 2 ports
Module id micro_sd_card · microSD Card (SPI) · Digital
What it can do
write_fileWrite text or bytes to a path, replacing the file
append_lineAppend a line to a file
read_fileRead a file back
list_dirList a directory
findSearch for files by glob
grepSearch inside a file for text
make_dirCreate a directory
delete_fileDelete a file
card_infoCard type, capacity, used and free space
remountMount a card that was inserted after boot
logQueue 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
- Unplug the USB cable from the board, wait a second, plug it back in and try again. This fixes most cases.
- 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.
- Use a data USB-C cable. Many cables are charge-only and cannot program the board.
- Plug straight into the computer, not through a hub.
- Press the board's reset button, then try again.
- On Linux, your user has to be in the
dialoutgroup.
There is no way to upload from my browser
The upload finished but the board stays offline
My code connects but nothing arrives
The connection is refused or closes at once
I send an action and the board ignores it
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].
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.