Web FastLED
Arduino + FastLED projects in browser: edit sketch, run it, watch LED matrix.
Or drop .zip / .ino / .h file anywhere on page. F1 — help.
Arduino + FastLED projects in browser: edit sketch, run it, watch LED matrix.
Or drop .zip / .ino / .h file anywhere on page. F1 — help.
Board sets pins (A0…, Serial1-3 on Mega), EEPROM size and defines (ARDUINO_AVR_NANO / ARDUINO_AVR_MEGA2560).
Sketch is compiled by clang (LLVM) in browser and runs as WebAssembly in real time. As with avr-gcc, -fpermissive conversions get cast and warning.
Unlike AVR: int is 32 bit, double is 64 bit, RAM / flash limits are not checked yet.
How strip index maps to X / Y — as GyverMatrix MATRIX_TYPE, CONNECTION_ANGLE, STRIP_DIRECTION. Wiring is taken from sketch on load anyway.
Dot size — LEDs of 3D view (dots and solid), 100% is largest. Cylinder height — 100%: LED pitch is same round and along axis (matrix 24×24 is tall narrow tube); less — lower and wider, more — taller.
Strip color order is used by Real CPU timing: colors are read from data pin as strip reads them. As sketch (default): strip has order that sketch gives in addLeds<…, ORDER> (or its #define COLOR_ORDER), so colors come out as sketch means them. Fixed order (GRB for WS2812, WS2812B, SK6812; RGB for many WS2811) shows what that strip would show: wrong order in sketch swaps colors, as on real strip.
LED gives light proportional to its value (PWM); monitor does not. LED-like converts, so dim colors look as on real LEDs; Raw (slider left) shows values as they are; right of LED-like dim colors get brighter still, up to +200%; default +100%, double click returns it.
Brightness is taken from brightest channel of LED, others keep their proportion, so lifted colors stay saturated.
Contrast darkens dark and middle tones, full brightness stays: 0% — no change (default, double click returns it), 100% — strongest; dim picture gets darker with it. Raw ignores both.
Encoding (UTF-8 / Windows-1251) and line endings (CRLF / LF) of each file are kept on save. Keep session — open project is stored in browser and restored next time.
Site opened once: editor and emulator start without internet (also from iOS home screen). Make offline downloads checked parts in advance; compilers and library are otherwise kept only once used.
| Web FastLED | ae485 — editor, emulator, real build, debugger; MIT license (LICENSE) |
| FastLED 3.7.8 | Daniel Garcia, Mark Kriegsman and contributors — MIT license |
| Arduino AVR core 1.8.6 | Arduino and contributors, with SPI, Wire, SoftwareSerial, EEPROM libraries — LGPL 2.1 |
| LLVM / Clang 21 | LLVM project — Apache 2.0 with LLVM exception; YoWASP build for WebAssembly (whitequark) — ISC license |
| GCC 7.3.0, Binutils 2.26 | Free Software Foundation; avr-gcc of Arduino toolchain (Atmel 3.6.1 patches), built for WebAssembly — GPL 3 (runtime library exception for libgcc) |
| avr-libc 2.0.0 | avr-libc developers, with Arduino patch (malloc margin) — modified BSD license |
| Bootloaders | Optiboot (Peter Knight, Bill Westfield), ATmegaBOOT (Arduino), stk500v2 (Peter Fleury, Mark Sproul) of AVR core — GPL 2; go into “.hex with bootloader” |
| avr8js 0.21 | Uri Shaked and contributors — AVR emulator of Real CPU timing, MIT license |
| CodeMirror 6 | Marijn Haverbeke and contributors — editor, MIT license |
| Color themes | palettes of Visual Studio Code themes (Microsoft, Monokai, Solarized by Ethan Schoonover) — MIT license |
| Library samples | GyverMatrixOS (AlexGyver), Soulmate sketches — their authors |
Pins used by running sketch, as if wires were connected to board.
INPUT_PULLUP — button to GND: press = LOW (GyverMatrix: D3 is mode button, pinMode(dpin, INPUT_PULLUP)).
INPUT — button to 5V: press = HIGH, released pin floats (random). analogRead pins get slider instead of noise.
Hold Press; Shift+click keeps it pressed.
Start sketch: its pins appear here.
| Ctrl+O | Load project: local file |
| Ctrl+S | Save project (.zip) |
| F5 | Compile and start / stop |
| F7, Ctrl+R | Compile only |
| Ctrl+U | Upload to board (USB) |
| F10 / F11 / Shift+F11 | Debugger: step over / into / out; F5 — continue |
| F6 | LED window |
| Space | Pause / continue sketch (outside editor) |
| Ctrl+J | Panel: Problems / Output / Serial monitor |
| Ctrl+Shift+M | Problems |
| Ctrl+, | Options |
| F1 | Help |
| Alt+1…9 | Go to tab 1…9 |
| Ctrl+F / Ctrl+H | Find / replace in file |
| Ctrl+Shift+F | Search in all files (box in toolbar) |
| Alt+G | Go to line |
| Ctrl+Z / Ctrl+Y | Undo / redo (each tab has own history) |
| Ctrl+/ | Comment / uncomment lines |
| Ctrl+D | Select next occurrence |
| Ctrl+Shift+[ / ] | Fold / unfold block |
| Alt+↑ / ↓ | Move line up / down |
| Esc | Close top window |
Get W×H (toolbar, after Load) — takes WIDTH and HEIGHT from sketch into LED window (also MATRIX_WIDTH, kMatrixWidth…); if build runs with other size from size box, it is rebuilt with sketch's size.
On project load LED window keeps its size and build gets it instead of sketch's WIDTH / HEIGHT (Options → LED → W×H from sketch on load on: window takes sketch's size); wiring (MATRIX_TYPE, CONNECTION_ANGLE, STRIP_DIRECTION) are taken once; sketch without them gets wiring from its XY(): zigzag if odd rows are reversed there (y & 1, y % 2), else parallel, from bottom left to right; later wiring is set in Options → LED.
Project is .zip with sketch: main .ino plus other .ino, .h, .c, .cpp files (Arduino IDE sketch folder packed into zip). Each file opens in its own tab, main sketch first; tabs can be dragged; × on tab removes file from project (asks first; last file closes project). Changed file is marked with * until project is saved. Single .ino / .h files are added to open project.
Load ▾ opens menu: Local file… (Ctrl+O, or drop file on page) and Library — projects of server folder repo/ (next to index.html), listed in repo/index.json:
{ "items": [
{ "file": "GyverMatrix.zip", "name": "GyverMatrix 24×12", "board": "mega" },
{ "file": "soulmate/fire.c", "name": "Fire (Soulmate)" }
] }
file — path inside repo/: .zip project, .c sketch or .ino; name — text of menu (file name if omitted); board (nano / mega) is optional and is selected on load.
Plain list ["a.zip", "b.c"] works too. Library item always opens as new project. With 10 and more items menu gets filter box.
Save writes whole project back as .zip with same file names, encodings and line endings. Files that are not sketch sources stay in archive untouched.
✓ (F7) only compiles; Start (F5) compiles sketch and runs it; Pause (Space) stops sketch clock; Reset starts same build again from setup(); Catch-up (⏭, also in Options → Build, off by default) — after rebuild of running sketch (new size, profile) it continues from same moment, see “LED window”; off — it starts from beginning. Compiler is clang (LLVM) in browser:
first time it is downloaded (about 26 MB), then comes from browser cache. Sketch, FastLED 3.7.8 and Arduino core run as WebAssembly in real time:
millis() and delay() are real (or scaled by speed).
Conversions that g++ allows with -fpermissive get cast and warning in Problems. Unlike AVR: int is 32 bit, double is 64 bit, RAM / flash limits are not checked (Real CPU timing has exact AVR, see below).
Power limit: sketch that calls FastLED.setMaxPowerInVoltsAndMilliamps() is dimmed by FastLED as a whole when estimated current is over limit, as on real strip
(e.g. 5 V, 1000 mA: white lines on many LEDs come out grey); Output says so after build. Options → Build → Power limit of sketch is off by default: these calls are dropped for build; turn it on to see what real strip does.
Sketch runs in one of two modes, switched by Real CPU timing button (chip with clock, next to LED window button; yellow when on, off by default).
Off: sketch is compiled by clang into WebAssembly and runs as fast as page can; FastLED.show() waits so that frames come every 20 ms of sketch time — 50 fps at 1×.
Speed (dial icon in LED window): 0.1×…10× = 5…500 fps (double click — 1×). Sketch clock (millis(), micros(), delay()) runs at same speed,
so effects that count frames and effects that count time keep their proportions. 3D view, size rebuild, profile build and catch-up work in this mode.
On: sketch is built with avr-gcc as for real board (see “Board binary”) and its .hex runs on emulated ATmega328P (Nano) or ATmega2560 (Mega) at 16 MHz, instruction by instruction:
every delay, interrupt and FastLED.show() takes exactly as long as on board; int is 16 bit, RAM is 2 KB (Nano) or 8 KB (Mega), as on board. LED colors are read from data pin by pulse widths, as strip reads them (color order of strip: Options → LED → Display, GRB for WS2812B);
Serial monitor talks to USART0 (Serial; Mega Serial1…3 run too, their output is not shown), Inputs drive pins and ADC (Mega: A0…A15); Memory and Profile tabs of panel show RAM and CPU time of board.
Speed is 1×, 3D view, size rebuild, profile build and catch-up are off; size box only lays out LEDs read from pin.
If computer cannot keep up with 16 MHz, board clock runs slower than real time; status bar then shows % of real speed.
| Off | On | |
| Program | clang → WebAssembly | avr-gcc → .hex, same as for board |
| Timing | 50 fps × speed | exact, 16 MHz cycles |
int, RAM | 32 bit, no limit | 16 bit, 2 KB (Nano) / 8 KB (Mega) |
| Speed, 3D, size rebuild | yes | no |
| Memory tab, profile | profile build (slower) | RAM / stack of board, CPU time (free) |
| Boards | Nano, Mega | Nano, Mega |
Turning it on or off while sketch runs starts it again in new mode. fps in corner of LED window is frames per second (FastLED.show() calls; in Real CPU timing — frames read from pin).
Breakpoint: click line number (or just left of it): red dot appears left of number; click again removes it. With Real CPU timing on, board stops before that line runs: arrow and highlight show line, status bar says where, panel opens Debug tab — call stack (click goes to place), registers r0…r31, X / Y / Z, SP, PC, SREG (capital letter = flag set), cycles, RAM as hex (address box, links to variables and stack; changed since previous stop in yellow), list of breakpoints (× removes; line without code of its own moves to next one, “no code” — it never stops there).
Then: Step over (F10) — next line, calls are run through; Step into (F11) — into called function of sketch (library code is run through); Step out (Shift+F11) — until function returns; Continue (F5, Space or Pause button) — runs to next breakpoint. Pause while running stops board at once, as breakpoint does. Interrupts (millis timer, Serial) keep running inside steps; their code is passed over. Board time stands while stopped.
Build is optimized as in IDE (-Os, LTO): small functions are put into callers, lines are reordered, some lines have no code — steps can jump a little, as in any debugger of optimized code.
Line that only calls function which optimizer put into caller (case 1: VUSpectrum();) stops at start of that copy; mark stays on breakpoint line. Breakpoint stops only when line really runs: in mode switch, when that mode comes.
Variables by name come later; for now RAM view shows them (globals from address 0x100).
Button with chip and arrow (next to Save) builds sketch for real board with avr-gcc 7.3.0, same compiler, flags and steps as Arduino IDE 2
(Arduino AVR core 1.8.6, FastLED 3.7.8, link-time optimization). Result is byte for byte what IDE gives:
.hex, .hex with bootloader, .elf (with debug info), .eep, or all of them in .zip; Build only shows size report as IDE does.
Compiler runs in browser: first time it is downloaded (about 16 MB), then comes from browser cache; first build of session takes some seconds more.
Whole project is built as saved (its encoding and line ends), with sizes from sketch itself: LED window size box does not apply. Libraries are found by #include, as in IDE:
FastLED, SPI, Wire, SoftwareSerial, EEPROM. Errors are in Problems, log in Output. .c sketch (no .ino) is built as in emulator: its .c files are sketch, COLS / ROWS become WIDTH / HEIGHT, pattern.c gives setup() / loop() (Options → Build).
“With bootloader” file uses bootloader chosen in Upload menu.
Upload (arrow into board, next to board binary button; Ctrl+U) makes real build and writes it to board over USB, as Arduino IDE does (avrdude): through bootloader, STK500v1 for Nano, STK500v2 for Mega 2560; device signature is checked, every page is read back and compared. Needs Web Serial: Chrome, Edge, Opera or new Firefox on computer.
▾ next to it opens menu: Upload to board; Port — Choose port… when none is chosen yet, else its name and Change (browser asks which port; choice is remembered); Release port — closes what page holds on port (Serial monitor) and forgets it, so other programs (Arduino IDE) can take it; Bootloader of Nano (as Processor menu of IDE): ATmega328P — Optiboot, 115200 baud, Nano since 2018 and most new ones; Old Bootloader — 57600 baud, older ones and many clones. Upload tries chosen one first, then other; when other one answers, it becomes chosen.
Serial monitor of board: in Serial Monitor panel choose speed (as in sketch's Serial.begin()) and Connect board; opening port resets board, as in IDE.
While connected, input line sends to board. Upload closes monitor and opens it again after.
Port can be held by one program only: close serial monitor of Arduino IDE (or other terminal) first, or Release port here before using IDE.
Browser talks to board through serial port of operating system, so USB-serial chip of board needs its driver, same as for Arduino IDE (Web Serial does not replace it). Chip is written on board near USB socket; after choosing port, its name is shown in Upload menu (CH340, CH9102, FT232R…).
| CH340 / CH341 most Nano clones | Windows: CH341SER.EXE (WCH); Windows 10 / 11 often install it themselves. macOS: CH34XSER_MAC (macOS 11 and later: allow driver extension in System Settings). Linux: in kernel (ch341). |
| CH9102 / CH343 many boards with USB-C | Windows: CH343SER (WCH; CH340 driver does not serve it). macOS: same CH34XSER_MAC. Linux: usually works as USB CDC (cdc_acm) of kernel, else WCH driver ch343ser_linux. |
| FT232R / FT231X original Nano (old), some clones | Windows: comes by Windows Update, else FTDI VCP drivers. macOS, Linux: built in. |
| CP2102 | Silicon Labs VCP drivers (Windows, macOS); Linux: built in. |
| ATmega16U2 original Mega 2560, Uno | Windows 10 / 11, macOS, Linux: built in (USB CDC); Windows 7 / 8: driver of Arduino IDE. |
Linux: user must be in dialout group (sudo usermod -aG dialout $USER, then log in again); on Ubuntu package brltty grabs CH340 ports — remove it (sudo apt remove brltty).
If port is missing in browser's list: other cable (many are charge-only), other USB socket, check Device Manager (Windows) for unknown device.
Upload with no answer: right board (Nano / Mega) and bootloader, nothing else holds port, try Old Bootloader / ATmega328P.
As in Arduino IDE, all .ino files of sketch folder become one C++ file:
1. #include <Arduino.h> is put first.
2. Main .ino (named as project, or one with setup() and loop()) goes first, then other .ino files in alphabetical order, case ignored (real build: as IDE, upper case first). Tab order does not matter.
3. Prototypes of all functions are inserted before first function definition, so function may be called before it is defined, from any .ino.
4. #line marks keep file names and line numbers in errors.
So global variables and types of one .ino are visible in .ino files that come after it, not before. .h files are not compiled by themselves: they are included where #include says. .c / .cpp files of sketch folder (and src/) are compiled separately, each must include what it needs (Arduino.h, FastLED.h).
Prototypes are not made for functions with default arguments and for templates — declare them yourself.
Controls are in title bar: size (24x12, 24-12, 2412) — Enter or leaving box rebuilds sketch with these WIDTH and HEIGHT (only for this build, code is not changed; with catch-up on running sketch continues from same moment, new size is shown once new build has caught up;
#define NUM_LEDS 256 given as number equal to old WIDTH × HEIGHT follows new size),
speed (see “Speed and Real CPU timing”), fit window to matrix, effects ▾ menu (grid, coordinates under cursor, strip route — line from leds[0] along indexes, green dot at start). Closing window stops sketch.
3D wraps matrix (as window shows it, after rotate / mirror) on figure; ▾ next to it: figure, mode, rotation. Cylinder — matrix is its side: columns go round, rows go down, so running text runs round cylinder. Sphere — as many points as LEDs, spread by golden angle; each point shows LED under its longitude (x) and latitude (y, top row at north pole). Globe — latitude / longitude grid: rows are parallels, columns meridians, LEDs crowd to poles (as on real LED spheres, maps like Earth fit it best). Torus — columns go round ring, rows round tube (middle row on outer side); text runs round it. Disc (polar) — rows are rings from centre outwards, columns are angle clockwise from top: round panels, fire, tunnels, Lotus. Dome (polar) — same on hemisphere facing you, row 0 at pole. Dots — one dot per LED, back side dimmer (dot size and cylinder height: Options → LED → 3D); Solid (WebGL) — lit figure with LEDs as round dots on dark surface. Drag rotates (fling keeps it spinning), wheel / pinch / right+left drag zooms, double click — normal size and front view; fit makes window square around figure at its present size. Rotate on — figure turns by itself when left alone; off — it stays as left.
In toolbar, next to LED window button, in its own group: rebuild with size of size box (same as Enter in it), Real CPU timing (chip with clock: switch, yellow when on), rotate view by 90° clockwise (action: each click adds 90°, angle other than 0° is shown by small number on button), mirror horizontally (switch, highlighted when on), inputs window (blue while open; green dot — sketch reads pins: buttons, pots).
Catch-up (continue from same moment): new build runs fast (no waiting, no frames) from start up to time of old one, replaying inputs (buttons, sliders, Serial input) and same noise of floating pins,
so time-driven things (mode switching by millis()) come to same place; arrays sized by WIDTH / HEIGHT are filled again.
LEDs grow and shrink with window, down to 1 screen pixel per LED; window is never narrower than its title bar. fps in corner — FastLED.show() calls per second.
Wiring (zigzag / parallel, start corner, direction) and colors are in Options → LED.
Project (or single file) of .c files and without .ino is sketch too, in style of Soulmate / soulmatelights editor: often only draw() and globals, sizes as LED_COLS / LED_ROWS or COLS / ROWS.
.c files are compiled as C++, like .ino (joined alphabetically, prototypes added).
On loading, sketch text itself is changed, so editor shows what is compiled (changed files get * mark, Save keeps changes):
1. LED_COLS, COLS → WIDTH; LED_ROWS, ROWS → HEIGHT (Options → Build, on by default). Defines that become #define WIDTH (WIDTH) are commented.
2. If sketch has no setup(), pattern.c from server root is inserted (Options → Build, on by default): its includes, defines and globals go to top of file
(between // ===== pattern.c marks), its functions (XY(), setup(), loop() calling draw() and FastLED.show()) to end. What sketch has itself is commented in pattern
(#define NUM_LEDS (N_LEDS) of sketch takes place of pattern's one, sketch's line is commented).
If sketch still has no setup() at build (option was off on loading), pattern.c is added for build only, errors in it are shown as pattern.c:line; it is read from server again on each build.
Its size (16×16) is what Get W×H finds when sketch has no sizes of its own; size box overrides it as usual.
Problems — errors and warnings, click opens the place; they are also underlined in editor. Output — compiler log.
Search — results of search box in toolbar: all files of project, as you type (Aa — match case, ab — whole word, .* — regular expression); click selects match in its file.
Serial Monitor — Serial.print of sketch; line below sends text to Serial.read(); speed and Connect board — monitor of real board (see “Upload to board”). Ctrl+J shows / hides panel.
Profile — Real CPU timing off: with profile build on, each function of .ino files gets timer: calls per second, Busy (time of function itself, with library calls), Waits (delay(), FastLED.show() pacing inside it),
Total (with called sketch functions), function that calls FastLED.show() is marked ▶; turning it on while sketch runs rebuilds (with catch-up on, continues from same moment); sketch runs slower with it.
Real CPU timing on: share of board CPU time per function (sketch, FastLED, core, interrupts by name), always on, does not slow sketch.
Memory (Real CPU timing) — RAM of board as bar and table: variables (.data, .bss), heap, stack, free RAM between heap and stack; Now and Max / min since start (free RAM is filled with pattern at reset, growing stack and heap overwrite it). Red dot on tab: little reserve left (under 100 B) or stack ran into variables. Flash use of build is shown too.
Pins used by running sketch, as if wires were connected to board. Pin in INPUT_PULLUP mode is button to GND (press = LOW) —
D3 of GyverMatrix is its mode button. INPUT is button to 5V (press = HIGH; released, pin floats). Pins read by analogRead() get slider
(or noise, as unconnected). Outputs show level or PWM, FastLED pin — number of LEDs. Hold Press; Shift+click keeps it pressed.
Site opened once (over https) starts without internet: page and scripts are kept in browser, also on iPhone / iPad home screen. Compilers and library are kept once used; Options → Offline → Make offline downloads checked ones in advance (clang about 26 MB, avr-gcc about 16 MB), Clear files drops them. When site does not answer, red offline is shown in LED window, left of fps. New build on server: page reloads into it by itself.
| Ctrl+O | Загрузить проект: локальный файл |
| Ctrl+S | Сохранить проект (.zip) |
| F5 | Компиляция и запуск / остановка |
| F7, Ctrl+R | Только компиляция |
| Ctrl+U | Залить в плату (USB) |
| F10 / F11 / Shift+F11 | Отладчик: шаг с обходом / с заходом / выход; F5 — продолжить |
| F6 | Окно LED |
| Space | Пауза / продолжить скетч (вне редактора) |
| Ctrl+J | Панель: Problems / Output / Serial monitor |
| Ctrl+Shift+M | Problems |
| Ctrl+, | Options |
| F1 | Справка |
| Alt+1…9 | Вкладка 1…9 |
| Ctrl+F / Ctrl+H | Найти / заменить в файле |
| Ctrl+Shift+F | Поиск по всем файлам (поле в панели инструментов) |
| Alt+G | Перейти к строке |
| Ctrl+Z / Ctrl+Y | Отменить / повторить (у каждой вкладки своя история) |
| Ctrl+/ | Закомментировать / раскомментировать строки |
| Ctrl+D | Выделить следующее вхождение |
| Ctrl+Shift+[ / ] | Свернуть / развернуть блок |
| Alt+↑ / ↓ | Переместить строку вверх / вниз |
| Esc | Закрыть верхнее окно |
Get W×H (панель инструментов, после Load) — берёт WIDTH и HEIGHT из скетча в окно LED (также MATRIX_WIDTH, kMatrixWidth…); если сборка работает с другим размером из поля размера, она пересобирается с размером скетча.
При загрузке проекта окно LED сохраняет свой размер, и сборка получает его вместо WIDTH / HEIGHT скетча (Options → LED → W×H from sketch on load включено: окно берёт размер скетча); схема подключения (MATRIX_TYPE, CONNECTION_ANGLE, STRIP_DIRECTION) берётся один раз; скетч без них получает схему из своей XY(): зигзаг, если там нечётные строки перевёрнуты (y & 1, y % 2), иначе параллельная, от левого нижнего угла вправо; дальше схема задаётся в Options → LED.
Проект — .zip со скетчем: главный .ino и другие файлы .ino, .h, .c, .cpp (папка скетча Arduino IDE, упакованная в zip). Каждый файл открывается в своей вкладке, главный — первым; вкладки можно перетаскивать; × на вкладке удаляет файл из проекта (с подтверждением; последний файл закрывает проект). Изменённый файл помечен *, пока проект не сохранён. Отдельные файлы .ino / .h добавляются в открытый проект.
Load ▾ открывает меню: Local file… (Ctrl+O или перетащить файл на страницу) и Library — проекты папки repo/ на сервере (рядом с index.html), перечисленные в repo/index.json:
{ "items": [
{ "file": "GyverMatrix.zip", "name": "GyverMatrix 24×12", "board": "mega" },
{ "file": "soulmate/fire.c", "name": "Fire (Soulmate)" }
] }
file — путь внутри repo/: проект .zip, скетч .c или .ino; name — текст в меню (если нет — имя файла); board (nano / mega) необязателен и выбирается при загрузке.
Простой список ["a.zip", "b.c"] тоже работает. Пункт библиотеки всегда открывается как новый проект. При 10 и более пунктах в меню появляется поле фильтра.
Save записывает весь проект обратно в .zip с теми же именами файлов, кодировками и концами строк. Файлы, которые не являются исходниками скетча, остаются в архиве нетронутыми.
✓ (F7) только компилирует; Start (F5) компилирует и запускает скетч; Pause (Space) останавливает часы скетча; Reset запускает ту же сборку заново с setup(); Catch-up (⏭, также в Options → Build, по умолчанию выключен) — после пересборки работающего скетча (новый размер, профиль) он продолжает с того же момента, см. «Окно LED»; выключен — начинает сначала. Компилятор — clang (LLVM) в браузере:
в первый раз он скачивается (около 26 МБ), потом берётся из кэша браузера. Скетч, FastLED 3.7.8 и ядро Arduino работают как WebAssembly в реальном времени:
millis() и delay() настоящие (или масштабируются скоростью).
Преобразования, которые g++ разрешает с -fpermissive, получают приведение типа и предупреждение в Problems. В отличие от AVR: int 32 бита, double 64 бита, пределы RAM / флеша не проверяются (в Real CPU timing — точный AVR, см. ниже).
Ограничение мощности: скетч, который вызывает FastLED.setMaxPowerInVoltsAndMilliamps(), FastLED притемняет целиком, когда оценка тока выше предела, как на настоящей ленте
(например, 5 В, 1000 мА: белые линии на многих светодиодах выходят серыми); Output сообщает об этом после сборки. Options → Build → Power limit of sketch по умолчанию выключено: эти вызовы убираются из сборки; включите, чтобы увидеть, что сделает настоящая лента.
Скетч работает в одном из двух режимов, переключаемых кнопкой Real CPU timing (чип с часами рядом с кнопкой окна LED; жёлтая — включено, по умолчанию выключено).
Выключено: скетч компилируется clang в WebAssembly и работает так быстро, как может страница; FastLED.show() ждёт, чтобы кадры шли каждые 20 мс времени скетча — 50 fps при 1×.
Скорость (значок спидометра в окне LED): 0.1×…10× = 5…500 fps (двойной клик — 1×). Часы скетча (millis(), micros(), delay()) идут с той же скоростью,
поэтому эффекты, считающие кадры, и эффекты, считающие время, сохраняют пропорции. 3D, пересборка под размер, профиль-сборка и catch-up работают в этом режиме.
Включено: скетч собирается avr-gcc, как для настоящей платы (см. «Прошивка для платы»), и его .hex исполняется на эмулированном ATmega328P (Nano) или ATmega2560 (Mega) на 16 МГц, команда за командой:
каждая задержка, прерывание и FastLED.show() длятся ровно столько, сколько на плате; int 16 бит, RAM 2 КБ (Nano) или 8 КБ (Mega), как на плате. Цвета светодиодов читаются с пина данных по длительности импульсов, как их читает лента (порядок цветов ленты: Options → LED → Display, GRB для WS2812B);
Serial monitor работает с USART0 (Serial; Serial1…3 у Mega тоже работают, их вывод не показывается), Inputs управляют пинами и АЦП (Mega: A0…A15); вкладки Memory и Profile панели показывают RAM и время процессора платы.
Скорость 1×, 3D, пересборка под размер, профиль-сборка и catch-up отключены; поле размера только раскладывает светодиоды, считанные с пина.
Если компьютер не успевает за 16 МГц, часы платы идут медленнее реального времени; строка состояния тогда показывает % от реальной скорости.
| Выключено | Включено | |
| Программа | clang → WebAssembly | avr-gcc → .hex, как для платы |
| Тайминги | 50 fps × скорость | точные, такты 16 МГц |
int, RAM | 32 бита, без предела | 16 бит, 2 КБ (Nano) / 8 КБ (Mega) |
| Скорость, 3D, пересборка под размер | да | нет |
| Вкладка Memory, профиль | профиль-сборка (медленнее) | RAM / стек платы, время процессора (бесплатно) |
| Платы | Nano, Mega | Nano, Mega |
Включение или выключение во время работы скетча перезапускает его в новом режиме. fps в углу окна LED — кадры в секунду (вызовы FastLED.show(); в Real CPU timing — кадры, считанные с пина).
Точка останова: клик по номеру строки (или чуть левее): слева от номера появляется красная точка; повторный клик убирает. При включённом Real CPU timing плата останавливается перед выполнением этой строки: стрелка и подсветка показывают строку, строка состояния — где, в панели открывается вкладка Debug — стек вызовов (клик переходит к месту), регистры r0…r31, X / Y / Z, SP, PC, SREG (заглавная буква = флаг установлен), такты, RAM в hex (поле адреса, ссылки на переменные и стек; изменившееся с прошлой остановки — жёлтым), список точек останова (× убирает; строка без своего кода переносится на следующую, «no code» — там остановки не будет).
Дальше: Step over (F10) — следующая строка, вызовы выполняются целиком; Step into (F11) — внутрь вызываемой функции скетча (код библиотек выполняется целиком); Step out (Shift+F11) — до возврата из функции; Continue (F5, Space или кнопка паузы) — до следующей точки останова. Пауза во время работы сразу останавливает плату, как точка останова. Прерывания (таймер millis, Serial) внутри шагов продолжают работать, их код проходится без остановки. Пока плата стоит, её время не идёт.
Сборка оптимизирована, как в IDE (-Os, LTO): мелкие функции встраиваются в вызывающие, строки переставляются, у некоторых строк нет своего кода — шаги могут немного прыгать, как в любом отладчике оптимизированного кода.
Строка, которая только вызывает функцию, встроенную оптимизатором в вызывающую (case 1: VUSpectrum();), останавливается на начале этой копии; отметка остаётся на строке точки. Точка срабатывает, только когда строка действительно выполняется: в переключателе режимов — когда дойдёт до этого режима.
Переменные по именам будут позже; пока их видно в окне RAM (глобальные — с адреса 0x100).
Кнопка с чипом и стрелкой (рядом с Save) собирает скетч для настоящей платы avr-gcc 7.3.0 — тем же компилятором, с теми же флагами и шагами, что Arduino IDE 2
(Arduino AVR core 1.8.6, FastLED 3.7.8, оптимизация при компоновке). Результат байт в байт совпадает с IDE:
.hex, .hex с загрузчиком, .elf (с отладочной информацией), .eep или все сразу в .zip; Build only показывает отчёт о размере, как IDE.
Компилятор работает в браузере: в первый раз скачивается (около 16 МБ), потом берётся из кэша браузера; первая сборка за сеанс идёт на несколько секунд дольше.
Проект собирается в том виде, в каком сохраняется (его кодировка и концы строк), с размерами из самого скетча: поле размера окна LED не применяется. Библиотеки находятся по #include, как в IDE:
FastLED, SPI, Wire, SoftwareSerial, EEPROM. Ошибки — в Problems, лог — в Output. Скетч .c (без .ino) собирается как в эмуляторе: его файлы .c и есть скетч, COLS / ROWS становятся WIDTH / HEIGHT, pattern.c даёт setup() / loop() (Options → Build).
Файл «с загрузчиком» использует загрузчик, выбранный в меню Upload.
Upload (стрелка в плату, рядом с кнопкой прошивки; Ctrl+U) делает настоящую сборку и записывает её в плату по USB, как Arduino IDE (avrdude): через загрузчик, STK500v1 для Nano, STK500v2 для Mega 2560; проверяется сигнатура чипа, каждая страница читается обратно и сравнивается. Нужен Web Serial: Chrome, Edge, Opera или новый Firefox на компьютере.
▾ рядом открывает меню: Upload to board; Port — Choose port…, пока порт не выбран, иначе его имя и Change (браузер спрашивает порт; выбор запоминается); Release port — закрывает то, что страница держит на порту (Serial monitor), и забывает его, чтобы порт могли взять другие программы (Arduino IDE); Bootloader для Nano (как меню Processor в IDE): ATmega328P — Optiboot, 115200 бод, Nano с 2018 года и большинство новых; Old Bootloader — 57600 бод, старые и многие клоны. Заливка сначала пробует выбранный, потом другой; если ответил другой, он становится выбранным.
Монитор порта платы: в панели Serial Monitor выберите скорость (как в Serial.begin() скетча) и нажмите Connect board; открытие порта перезагружает плату, как в IDE.
Пока плата подключена, строка ввода отправляет текст на неё. Заливка закрывает монитор и потом открывает снова.
Порт может держать только одна программа: сначала закройте монитор порта Arduino IDE (или другой терминал), или нажмите здесь Release port перед работой в IDE.
Браузер работает с платой через последовательный порт операционной системы, поэтому USB-UART чипу платы нужен его драйвер, как и для Arduino IDE (Web Serial его не заменяет). Чип подписан на плате рядом с USB-разъёмом; после выбора порта его имя видно в меню Upload (CH340, CH9102, FT232R…).
| CH340 / CH341 большинство клонов Nano | Windows: CH341SER.EXE (WCH); Windows 10 / 11 часто ставят его сами. macOS: CH34XSER_MAC (macOS 11 и новее: разрешить расширение драйвера в Системных настройках). Linux: в ядре (ch341). |
| CH9102 / CH343 многие платы с USB-C | Windows: CH343SER (WCH; драйвер CH340 его не обслуживает). macOS: тот же CH34XSER_MAC. Linux: обычно работает как USB CDC (cdc_acm) ядра, иначе драйвер WCH ch343ser_linux. |
| FT232R / FT231X оригинальная Nano (старая), некоторые клоны | Windows: приходит через Windows Update, иначе FTDI VCP drivers. macOS, Linux: встроен. |
| CP2102 | Silicon Labs VCP drivers (Windows, macOS); Linux: встроен. |
| ATmega16U2 оригинальные Mega 2560, Uno | Windows 10 / 11, macOS, Linux: встроен (USB CDC); Windows 7 / 8: драйвер из Arduino IDE. |
Linux: пользователь должен быть в группе dialout (sudo usermod -aG dialout $USER, потом войти заново); в Ubuntu пакет brltty захватывает порты CH340 — удалите его (sudo apt remove brltty).
Если порта нет в списке браузера: другой кабель (многие только для зарядки), другой USB-разъём, проверьте Диспетчер устройств (Windows) на неизвестное устройство.
Если загрузчик не отвечает: правильная плата (Nano / Mega) и загрузчик, порт не занят другой программой, попробуйте Old Bootloader / ATmega328P.
Как в Arduino IDE, все файлы .ino папки скетча становятся одним файлом C++:
1. Первым ставится #include <Arduino.h>.
2. Главный .ino (названный как проект или тот, где setup() и loop()) идёт первым, затем остальные .ino по алфавиту без учёта регистра (в настоящей сборке — как в IDE, заглавные первыми). Порядок вкладок не важен.
3. Прототипы всех функций вставляются перед первым определением функции, поэтому функцию можно вызывать до её определения из любого .ino.
4. Метки #line сохраняют имена файлов и номера строк в ошибках.
Поэтому глобальные переменные и типы одного .ino видны в .ino, идущих после него, но не до. Файлы .h сами не компилируются: они включаются там, где стоит #include. Файлы .c / .cpp папки скетча (и src/) компилируются отдельно, каждый должен подключать то, что ему нужно (Arduino.h, FastLED.h).
Прототипы не создаются для функций с аргументами по умолчанию и для шаблонов — объявите их сами.
Управление в заголовке окна: размер (24x12, 24-12, 2412) — Enter или выход из поля пересобирает скетч с этими WIDTH и HEIGHT (только для этой сборки, код не меняется; при включённом catch-up работающий скетч продолжает с того же момента, новый размер показывается, когда новая сборка догонит;
#define NUM_LEDS 256, заданный числом, равным старому WIDTH × HEIGHT, следует за новым размером),
скорость (см. «Скорость и Real CPU timing»), fit — окно по матрице, меню эффектов ▾ (сетка, координаты под курсором, маршрут ленты — линия от leds[0] по индексам, зелёная точка в начале). Закрытие окна останавливает скетч.
3D натягивает матрицу (как её показывает окно, после поворота / зеркала) на фигуру; ▾ рядом: фигура, режим, вращение. Cylinder — матрица — его бок: столбцы идут по кругу, строки вниз, поэтому бегущая строка бежит вокруг цилиндра. Sphere — столько точек, сколько светодиодов, разложенных по золотому углу; каждая точка показывает светодиод под своей долготой (x) и широтой (y, верхняя строка на северном полюсе). Globe — сетка широт / долгот: строки — параллели, столбцы — меридианы, светодиоды сгущаются к полюсам (как на настоящих LED-сферах, карты вроде Земли ложатся лучше всего). Torus — столбцы идут вокруг кольца, строки вокруг трубки (средняя строка снаружи); текст бежит вокруг. Disc (полярный) — строки — кольца от центра наружу, столбцы — угол по часовой стрелке от верха: круглые панели, огонь, туннели, Lotus. Dome (полярный) — то же на полусфере, обращённой к вам, строка 0 на полюсе. Dots — точка на светодиод, задняя сторона тусклее (размер точки и высота цилиндра: Options → LED → 3D); Solid (WebGL) — освещённая фигура со светодиодами-кружками на тёмной поверхности. Перетаскивание вращает (бросок продолжает вращение), колесо / щипок / правая+левая кнопки — масштаб, двойной клик — обычный размер и вид спереди; fit делает окно квадратным вокруг фигуры текущего размера. Rotate включено — фигура сама вращается, когда её не трогают; выключено — остаётся как оставили.
В панели инструментов рядом с кнопкой окна LED, в своей группе: пересборка с размером из поля (то же, что Enter в нём), Real CPU timing (чип с часами: переключатель, жёлтый, когда включён), поворот вида на 90° по часовой (действие: каждый клик добавляет 90°, угол кроме 0° показан маленьким числом на кнопке), зеркало по горизонтали (переключатель, подсвечен, когда включён), окно inputs (синее, пока открыто; зелёная точка — скетч читает пины: кнопки, потенциометры).
Catch-up (продолжить с того же момента): новая сборка быстро идёт (без ожиданий и кадров) от начала до времени старой, повторяя входы (кнопки, ползунки, ввод Serial) и тот же шум висящих пинов,
поэтому то, что идёт по времени (смена режимов по millis()), приходит в то же место; массивы по WIDTH / HEIGHT заполняются заново.
Светодиоды растут и уменьшаются вместе с окном, до 1 пикселя экрана на светодиод; окно не бывает уже своего заголовка. fps в углу — вызовы FastLED.show() в секунду.
Схема подключения (зигзаг / параллельная, начальный угол, направление) и цвета — в Options → LED.
Проект (или один файл) из файлов .c без .ino — тоже скетч, в стиле Soulmate / редактора soulmatelights: часто только draw() и глобальные переменные, размеры как LED_COLS / LED_ROWS или COLS / ROWS.
Файлы .c компилируются как C++, как .ino (склеиваются по алфавиту, добавляются прототипы).
При загрузке сам текст скетча меняется, чтобы редактор показывал то, что компилируется (изменённые файлы получают *, Save сохраняет изменения):
1. LED_COLS, COLS → WIDTH; LED_ROWS, ROWS → HEIGHT (Options → Build, включено по умолчанию). Define, ставшие #define WIDTH (WIDTH), комментируются.
2. Если в скетче нет setup(), вставляется pattern.c из корня сервера (Options → Build, включено по умолчанию): его include, define и глобальные переменные идут в начало файла
(между метками // ===== pattern.c), его функции (XY(), setup(), loop(), вызывающая draw() и FastLED.show()) — в конец. То, что есть в самом скетче, комментируется в pattern
(#define NUM_LEDS (N_LEDS) скетча встаёт на место такого же в pattern, строка скетча комментируется).
Если при сборке в скетче всё ещё нет setup() (опция была выключена при загрузке), pattern.c добавляется только в сборку, ошибки в нём показываются как pattern.c:строка; он читается с сервера заново при каждой сборке.
Его размер (16×16) находит Get W×H, когда у скетча нет своих размеров; поле размера, как обычно, его переопределяет.
Problems — ошибки и предупреждения, клик открывает место; они также подчёркнуты в редакторе. Output — лог компилятора.
Search — результаты поля поиска в панели инструментов: все файлы проекта, по мере ввода (Aa — учитывать регистр, ab — слово целиком, .* — регулярное выражение); клик выделяет совпадение в его файле.
Serial Monitor — Serial.print скетча; строка внизу отправляет текст в Serial.read(); скорость и Connect board — монитор настоящей платы (см. «Заливка в плату»). Ctrl+J показывает / скрывает панель.
Profile — при выключенном Real CPU timing: с профиль-сборкой каждая функция файлов .ino получает таймер: вызовы в секунду, Busy (время самой функции с вызовами библиотек), Waits (delay(), ожидание кадра в FastLED.show() внутри неё),
Total (с вызванными функциями скетча), функция, вызывающая FastLED.show(), отмечена ▶; включение во время работы скетча пересобирает его (при включённом catch-up — с того же момента); скетч с ней работает медленнее.
При включённом Real CPU timing: доля процессорного времени платы по функциям (скетч, FastLED, ядро, прерывания по именам), всегда включено, скетч не замедляет.
Memory (Real CPU timing) — RAM платы полосой и таблицей: переменные (.data, .bss), куча, стек, свободная RAM между кучей и стеком; «сейчас» и максимум / минимум с начала (свободная RAM при сбросе заполняется узором, растущие стек и куча его затирают). Красная точка на вкладке: мало запаса (меньше 100 Б) или стек наехал на переменные. Показан и расход флеша сборки.
Пины, которые использует работающий скетч, как если бы к плате были подключены провода. Пин в режиме INPUT_PULLUP — кнопка на GND (нажата = LOW) —
D3 в GyverMatrix — кнопка режимов. INPUT — кнопка на 5V (нажата = HIGH; отпущена — пин висит). Пины, читаемые analogRead(), получают ползунок
(или шум, как неподключённые). Выходы показывают уровень или ШИМ, пин FastLED — число светодиодов. Удерживайте Press; Shift+клик оставляет её нажатой.
Сайт, открытый хотя бы раз (по https), запускается без интернета: страница и скрипты хранятся в браузере, в том числе на экране «Домой» iPhone / iPad. Компиляторы и библиотека сохраняются, когда ими воспользовались; Options → Offline → Make offline заранее скачивает отмеченное (clang около 26 МБ, avr-gcc около 16 МБ), Clear files удаляет. Если сайт не отвечает, в окне LED слева от fps горит красное offline. Новая сборка на сервере: страница сама перезагружается в неё.