MojoScale
Start here

MojoScale Studio Guide

MojoScale Studio is a browser IDE for ESP32-class firmware. Write constrained Python, use the built-in docs, lint before deployment, save versioned scripts, and flash the correct firmware from the web UI.

Fastest path

Use this order for a normal Studio project.

Create a Studio projectOpen Studio, click New Project, then choose a name, chip, flash size, and BLE option.
Write constrained PythonUse supported modules such as system, gpio, camera, cv, display, network, and storage modules shown in the docs panel.
Use the right-side docsOpen a module in the documentation panel to see functions, arguments, keyword arguments, return shapes, and examples.
Fix lint and syntax errorsThe editor shows parse and lint problems before the board is flashed. Save also runs checks.
Save the projectSave stores the current script and creates a version snapshot so the project can be reopened later.
Flash from the browserClick Flash, connect the board, and let Studio fetch the correct firmware, filesystem, script, and optional AI model.
Users write Python for product behavior. Firmware-native modules handle the board work underneath.
Project setup

Create the project with the right target.

The project target tells Studio which firmware artifacts to use. For now, ESP32-S3 is the supported chip, with 8MB and 16MB flash targets, and BLE can be included or excluded.

NameThe project name shown on the console. Use something descriptive, such as `gesture-camera-test` or `oled-status-panel`.
ChipThe board family. ESP32-S3 is currently the supported Studio target.
Flash sizeChoose the actual board flash size. A firmware image built for 16MB will not boot correctly on an 8MB board.
BLE optionUse the no-BLE build unless the script needs BLE APIs. BLE increases firmware size and memory pressure.
Editor

Write focused Python, not desktop Python.

Studio supports a constrained Python syntax that maps cleanly to the device runtime. Keep scripts small, explicit, and event-driven. Avoid assuming that every desktop Python feature or package exists on the board.

Imports are explicitOnly modules present in the Studio docs can be imported.
Callbacks are named functionsFor timed events, define a top-level function and pass its name where required by the API.
Native work stays nativeCamera capture, display drawing, networking, storage, and AI model execution are implemented in firmware modules.
Keep scripts readableMost projects should be tens of lines, not hundreds. Put behavior in small functions.

Small example

main.py
import system
def tick():
    print(system.heap())
system.schedule("tick", 1000, 1000, -1, tick)
Right-side docs

Use the documentation panel while you write.

The right panel is not just static help text. It is generated from the same module stubs used by linting, autocomplete, and transpilation. When an API changes, docs and checks should move together.

Select a moduleOpen a module such as system, camera, cv, gpio, i2c, ssd1306, color_detector, or motion_detector.
Read the module summaryStart with what the module is for and the sample snippets at the top.
Check method signaturesLook at positional arguments, keyword arguments, return values, and common usage notes.
Copy the shape, not blindlyUse examples as patterns, then adjust pins, camera presets, intervals, and model names for your project.
If the docs panel does not show a module or method, treat it as unsupported until the firmware and Studio stubs are updated.
Lint and save

Fix errors before the board is touched.

Studio checks syntax, supported imports, supported method calls, callback forms, and AI model usage. Save runs lint and stores the code only when the project is in a usable state.

Syntax errorsBroken indentation, missing parentheses, and invalid Python are shown before transpilation.
Unsupported modulesImports not present in the Studio module stubs are blocked.
Unsupported methodsThe linter rejects methods that are not part of the available firmware API.
Invalid model loadsOnly one AI model can be loaded in a script, and the model name must exist in the catalog.
Flashing

Flash firmware, script, and optional model from one modal.

Click Flash in the IDE. Studio uses the project settings to select firmware, then writes the bootloader, partition table, app image, filesystem image, current script, and an AI model when the script needs one.

Use Chrome or Edge because Web Serial is required.
Connect the ESP32-S3 board with a data-capable USB cable.
Verify the project flash size matches the board flash size.
Keep the flashing modal open until all files are written and verified.
If a model is selected in code, Studio flashes that model into the model partition.
AI models

Let the script declare the model it needs.

A script can load one model at a time. Studio checks the model catalog and uses the selected model name to fetch the correct `.espdl` artifact for flashing.

camera + model sketch
import camera
import cv
camera.begin("xiao_s3_sense")
cv.load("hand_detect")
result = cv.detect_camera()
When stuck

Debug in this order.

Fix editor errors firstDo not flash while syntax or lint errors are visible.
Check project targetMake sure chip, flash size, and BLE option match the board and firmware bundle.
Try a tiny scriptUse a one-line print or system heap example to separate firmware issues from app logic.
Open the serial monitorUse device logs to see boot messages, script runtime errors, and module failures.