
B3VY LED Badge
A badge design in the shape of the B3VY logo. Created to help promote the B3VY network at Open Sauce Conference 2025.

Atym extends WebAssembly (Wasm) beyond the browser to secure, resource-constrained edge devices. In this project, we combine Atym with Edge Impulse's motion classifier to create a closed-loop inference system: raw sensor data is published, classified, and the prediction is validated -- all on device.
The system runs on both Linux and Zephyr targets and is organized as three independent containers that communicate via Atym Ocre's internal messaging bus:
The data publisher validates predictions in a closed loop, so you can measure accuracy without any external tooling.
Before you can build and deploy containers, you need an Atym account. Head to the Atym Eval Program signup page and fill out the form with your name, email, phone number, industry, and role. Once submitted, Atym will provision your account and send you login credentials via email.
If you've already completed the Run WebAssembly Containers on Raspberry Pi Using Atym getting started guide and have a working Atym setup, skip ahead to Step 4.
Atym provides a preconfigured Dev Container with the full toolchain for building WebAssembly containers. This is the recommended approach.
Prerequisites:
Clone the Atym getting-started repository:
git clone --recursive https://github.com/atym-io/getting-started.git
cd getting-startedWhy
--recursive? This repository includes the Atym SDK as a submodule, which provides the C API definitions needed to build Atym applications.
Open the directory in VS Code:
code .Run Dev Containers: Open Folder in Container... from the Command Palette (Cmd+Shift+P on Mac, Ctrl+Shift+P on Windows/Linux). Select the folder and wait for the container to build. This may take a few minutes the first time.
Once inside the Dev Container, verify the toolchain:
atym versionYou should see output like:
Atym CLI
Version: v1.0.3Then associate the CLI with your Atym account:
atym loginAlternative: If you prefer not to use the Dev Container, you can install the Atym CLI directly on your machine. See the Atym CLI Setup docs for Linux, macOS, and Windows instructions.
You need the Atym Ocre runtime installed on a Linux device (like a Raspberry Pi 4) and registered with your account.
Register the device from your development machine:
atym add device --deviceName "my-rpi" --description "Raspberry Pi 4" --serialNumber "RPI4001"Save the deviceUUID, pskSecret, and tenantUUID from the output -- you'll need them to configure the runtime.
Install the Atym runtime on your Pi. SSH in and download the latest runtime. Check the Atym Quickstart Guide for the most current download link:
wget https://atympublicshare.blob.core.windows.net/runtime/linux/latest/atym-runtime-debian-aarch64.tar.gz
tar -xzf atym-runtime-debian-aarch64.tar.gz
cd atym-runtimeConfigure and start the runtime with your device credentials:
atym config set device/id deviceUUID@tenantID
atym config set device/psk pskSecret
atym config set server/endpoint coapgw.prod.atym.io
atym runtime config set server/port 5684
./bin/atym-runtimeYou should see Client connected successfully when the device connects.
For a more detailed walkthrough of the Raspberry Pi setup (including headless mode, flashing the OS, and troubleshooting), see the Run WebAssembly Containers on Raspberry Pi Using Atym guide.
At this point you should have:
On your development machine (or inside the Dev Container), clone the example repo:
git clone https://github.com/atym-io/atym-samples-ei-motion-classifier.git
cd atym-samples-ei-motion-classifierThe repo includes an Edge Impulse motion classifier model and test dataset in the edge-impulse-sdk and data/testing/ directories, so you can build and deploy immediately without needing an Edge Impulse account.
If you want to use the included model, skip ahead to the build step. To use your own model instead:
edge-impulse-sdk folder..cbor files in the data/testing/ directory.Edge Impulse generates model_metadata.h and model_variables.h in the model-parameters/ directory when you export. These define the raw sample count, input frame size, and labels -- they generally don't require editing.
Before building, make sure you're logged in to your Atym registry:
atym loginThen build and push all three containers:
./build.sh atymThis will:
ei-assets, ei-data, and ei-classifier.data/testing/ and embed them into the assets container at build time.The containers must be deployed in a specific order:
/testing on the device filesystem.Deploy the assets container first because the data container depends on the extracted dataset, and the classifier must be listening before data is published. On Zephyr targets, this order is especially important to populate the filesystem before launching the other containers.
Deploy the assets container:
atym run assets ei-assetsAfter the dataset is extracted, deploy the inference and data containers (this will automatically deploy in the correct order):
./run.shWith all three containers running, you should see output similar to the following.
Data container output:
[DATA] Data publisher start
[DATA] Using sample directory: /testing
[DATA] Found 3 CBOR files
[DATA] Publish window 0 of sample "testing/idle.1.cbor.XXXX.cbor"
[DATA] Comparison for sample 'testing/idle.1.cbor...cbor' window 0:
[DATA] expected='idle' predicted='idle' score=0.97563 -> MATCH
...
[DATA] Test results:
[DATA] Total windows: 25
[DATA] Correct windows: 24
[DATA] Window accuracy: 96.00 %Classifier container output:
[CLS] EI classifier subscriber starting up (closed-loop responder)...
[CLS] Listening for samples on topic 'ei/sample/raw'
[CLS] Publishing results on topic 'ei/result'
[CLS] [0.00241, 0.97563, ...]
[CLS] Published result: label=idle score=0.97563The data publisher streams sample windows from the test dataset, the classifier responds with predicted labels, and the publisher reports overall accuracy.
The three containers communicate via Atym Ocre's messaging bus:
[Assets Container] (extracts CBOR files)
|
v
/testing/ (filesystem)
^
|
[Data Container] -------[ei/sample/raw]-------> [Classifier Container]
(publishes samples) (runs inference)
^
|
[ei/result]
(receives predictions)The assets container extracts dataset files to the /testing directory. The data container reads samples from this directory and publishes them on the ei/sample/raw topic. The classifier container subscribes to this topic, runs inference, and publishes predictions on the ei/result topic. The data container subscribes to ei/result to compare expected and predicted labels.
You can reuse this infrastructure for your own motion classification model.
edge-impulse-sdk/ folder.The model-parameters/ directory contains model_metadata.h and model_variables.h, which define EI_CLASSIFIER_RAW_SAMPLE_COUNT, EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE, and the label count. These are automatically generated and should not need manual editing.
.cbor files in the data/testing/ directory.During the build, the gen_embedded_assets.py script will detect these files and embed them into the assets container automatically.
Run the build script and deployment commands as described in Steps 7 and 8. The CMake build system will automatically discover CBOR files in data/testing/, generate C headers to embed them via gen_embedded_assets.py, and link everything into the final containers.
This example has been tested on both Linux and Zephyr RTOS. If you're porting your own model to a WebAssembly/Zephyr environment, here's what to watch out for.
When exporting from Edge Impulse for Wasm targets, enable "Use xxd instead of INCBIN to link TFLite/ONNX files". Wasm doesn't support INCBIN's binary embedding method. This setting is found in Edge Impulse's Dashboard under Experiments.
The following flags are critical for Wasm compatibility:
-fno-exceptions # Wasm doesn't support C++ exceptions
-DEIDSP_SIGNAL_C_FN_POINTER # Use C function pointers for signal processing
-DEI_C_LINKAGE # Use C linkage for EI functions
-DUSE_CMSIS_NN=OFF # CMSIS-NN optimizations not supported in WASIThese are already configured in the included CMakeLists.txt.
CLOCK_MONOTONIC for timing. If you use your own model, the included patch in ei_classifier_porting.cpp will need to be manually added.By combining Atym Ocre with Edge Impulse's motion classifier, you can build a portable, closed-loop inference system that runs on both Linux and Zephyr devices. Because Atym uses WebAssembly, the same application can be built once and run across multiple hardware architectures with minimal changes, enabling efficient experimentation at the edge.