Write small scripts in the browser, run them on an ESP32, control LEDs and pins, build a live UI, connect over USB or MQTT, and let the AI assistant help shape code and documentation around the project you are making.
Code, upload, stop, inspect logs, and recover sketches from the board.
Keep projects as revisions with code, chat, specification, and circuit notes together.
Drive LED strips, pins, sensors, environment-aware behavior, browser controls, online data, and Home Assistant entities.
Read the full guide here:
https://madshobye.github.io/Portal/p1_embed/web/guide/guide.html
How to use the interface:
https://madshobye.github.io/Portal/p1_embed/web/guide/first-run.html
To edit and code for xobit use the online editor.
https://madshobye.github.io/Portal/p1_embed/web/?view=coding
If the board does not show up on your computer then you need to install a driver:
Windows CH340/CH341 driver: WCH CH341SER Windows driver
macOS CH340/CH341 driver: WCH CH341SER macOS driver
In this case it is the cu.wchusbserial10
A basic NeoPixel example drives a 144-pixel WS2812B strip from GPIO16 with GPIO18 used as the strip power pin.
Behavior
Powers the strip on at startup.
Runs a simple blue chase across the LEDs.
Leaves a short dim trail behind the moving pixel.
Loops continuously with a steady frame rate.
Hardware
Strip data: GPIO16
Strip power: GPIO18
Strip type: WS2812B NeoPixel-style LED strip
Brightness: fixed at a moderate level
// Basic NeoPixel chase with strip power control.
var stripPin = 16;
var powerPin = 18; // xobit-circuit: IO18 ledStrip
var stripIndex = 0;
var ledCountValue = 50;
var baseBrightness = 50;
var chasePos = 0;
var lastFrameAt = 0;
var frameIntervalMs = 80;
function setup() {
pinMode(powerPin, OUTPUT);
digitalWrite(powerPin, HIGH);
ledConfig(stripIndex, stripPin, ledCountValue, baseBrightness);
ledClear(stripIndex, 1);
}
function loop() {
var now = 0;
var i = 0;
now = millis();
if ((now - lastFrameAt) < frameIntervalMs) {
delay(10);
return;
}
lastFrameAt = now;
ledClear(stripIndex, 0);
ledSet(stripIndex, chasePos, 0, 0, 255);
i = chasePos - 1;
if (i >= 0) {
ledSet(stripIndex, i, 0, 0, 80);
}
i = chasePos - 2;
if (i >= 0) {
ledSet(stripIndex, i, 0, 0, 20);
}
ledShow();
chasePos = chasePos + 1;
if (chasePos >= ledCountValue) {
chasePos = 0;
}
delay(5);
}
NeoPixel Button 5
A NeoPixel strip uses GPIO16 for data and GPIO18 for power. A button on GPIO33 connects directly to ground and uses the internal pull-up.
Behavior
Powers the strip on at startup.
Reads the button on GPIO33 as active-low.
Shows the first 15 pixels green when the button is released.
Shows the first 15 pixels red while the button is pressed.
Leaves the rest of the strip off.
Hardware
Strip data: GPIO16
Strip power: GPIO18
Button input: GPIO13
Strip type: WS2812B NeoPixel-style LED strip
Active pixels: first 15 LEDs only
// Sets the first 15 NeoPixels green or red based on a button on GPIO33 wired directly to ground.
var stripPin = 16;
var powerPin = 18; // xobit-circuit: IO18 ledStrip
var buttonPin = 13; // xobit-circuit: IO33 button
var stripIndex = 0;
var ledCountValue = 15;
var baseBrightness = 50;
var buttonPressed = 0;
var i = 0;
function setup() {
pinMode(powerPin, OUTPUT);
digitalWrite(powerPin, HIGH);
// Read the button.
pinMode(buttonPin, INPUT_PULLUP);
ledConfig(stripIndex, stripPin, ledCountValue, baseBrightness);
ledClear(stripIndex, 1);
}
function loop() {
// Read the button.
buttonPressed = digitalRead(buttonPin) == LOW;
//println(digitalRead(buttonPin) );
ledClear(stripIndex, 0);
i = 0;
while (i < ledCountValue) {
if (buttonPressed) {
ledSet(stripIndex, i, 255, 0, 0);
} else {
ledSet(stripIndex, i, 0, 255, 0);
}
i = i + 1;
}
ledShow();
delay(20);
}