LedBasic — это интерпретируемый BASIC-подобный язык и виртуальная машина (VM) для создания анимаций на адресных светодиодных лентах. Программы пишутся в текстовом виде, компилируются в байт-код прямо на контроллере и выполняются неблокирующим образом — параллельно с остальным кодом Arduino.
Она позволяет писать анимации для светодиодов в виде простого текста (скриптов), компилировать их в компактный байт-код и воспроизводить без блокировки основного цикла микроконтроллера.
Основные возможности:
Особенности языка LedBasic:
Библиотека на - GitVerse
Библиотека с - Яндекс.Диск
Мануалы и справочники - Яндекс.Диск
Дополнительно:
Online LedBasic IDE
Она позволяет писать анимации для светодиодов в виде простого текста (скриптов), компилировать их в компактный байт-код и воспроизводить без блокировки основного цикла микроконтроллера.
Основные возможности:
- Неблокирующее выполнение— tick() вызывается из loop(), не мешает другим задачам
- Независимость от типа ленты — подключение через коллбэки (совместимо с любой версией NeoPixelBus)
- Полный язык: переменные A–Z, арифметика, условия, циклы, подпрограммы, функции
- Управление скоростью—setSpeed(percent) масштабирует все задержки без изменения скрипта.
- Встроенные LED-функции: SIN8, COS8, PIXEL, RND, ABS, MIN, MAX
- HSV и RGB— SET_HSVс аппаратной конвертацией без float
- Браузерная IDE — редактор, эмулятор, отладчик, экспорт — всё в одном HTML-файл
- Аппаратная независимость (Hardware Agnostic)
LedBasic ничего не знает о железе. Она не использует напрямую FastLED или NeoPixelBus. При создании объекта вы передаете ей коллбэки (функции обратного вызова) для установки цвета пикселя, вывода буфера на ленту и очистки. Это значит, что вы можете использовать абсолютно любую библиотеку для работы со светодиодами. - Асинхронность (Неблокирующая работа)
Внутри используется конечный автомат (State Machine). Команды WAIT или DELAY не вешают микроконтроллер (ESP8266/ESP32). Функция tick() быстро отрабатывает часть инструкций и отдает управление обратно, что позволяет параллельно работать с Wi-Fi, MQTT или веб-сервером. - Встроенная математика и эффекты
Реализованы собственные таблицы синуса и косинуса (sin8, cos8) и конвертер HSV -> RGB. Библиотеке не нужны тяжелые зависимости. - Компиляция на лету и запуск из памяти
Текстовый скрипт компилируется в компактный бинарный байт-код. Скрипты можно хранить в файловой системе (LittleFS) и запускать прямо оттуда. - Защита от зависаний (Watchdog protection)
За один вызов tick() виртуальная машина выполняет не более 1000 инструкций. Если в BASIC-скрипте написан бесконечный цикл GOTO без пауз, микроконтроллер не зависнет и не уйдет в перезагрузку (Watchdog reset).
Особенности языка LedBasic:
- Переменные и математика: 26 переменных (A-Z), поддерживающих 16-битные целые числа. Доступна базовая математика (+, -, *, /, %).
- LED-команды: SET (RGB цвет), SET_HSV (цвет по тону, насыщенности и яркости), FILL (заливка), CLEAR (очистка), BRIGHT (яркость).
- Отрисовка: Команды SHOW (вывести на ленту), WAIT (вывести и ждать), DELAY (просто пауза).
- Математические функции: Встроены быстрые функции для создания эффектов: RND (случайное число), SIN8 и COS8 (табличные синусы/косинусы для плавных волн), MIN, MAX, ABS.
- Управление потоком: Классические FOR...TO...STEP...NEXT, циклы IF...THEN, переходы GOTO и подпрограммы GOSUB...RETURN.
Библиотека на - GitVerse
Библиотека с - Яндекс.Диск
Мануалы и справочники - Яндекс.Диск
Дополнительно:
Online LedBasic IDE
Функции логически разделены на группы: инициализация, загрузка кода, управление выполнением и настройки.
Инициализация объекта:
LedBasic(uint16_t count, LBSetPixel setPixelCb, LBShow showCb, LBClear clearCb)
Конструктор класса. Создает экземпляр виртуальной машины.
Библиотека не привязана к конкретному оборудованию, поэтому при создании объекта вы обязаны передать количество светодиодов и три функции-коллбэка (обычно это лямбда-выражения), которые "объясняют" библиотеке, как управлять вашей лентой.
Подготовка и компиляция скриптов:
bool compileFromText(const char* scriptText)
Компилирует текстовый скрипт на языке BASIC в бинарный байт-код прямо в оперативной памяти (RAM) микроконтроллера.
bool compileBasToBin(const char* basPath, const char* binPath)
Читает текстовый файл BASIC из файловой системы LittleFS, компилирует его построчно и сразу записывает готовый байт-код в другой файл.
bool loadBinFile(const char* path)
Загружает в оперативную память заранее скомпилированный бинарный файл из файловой системы LittleFS.
bool loadBinMemory(const uint8_t* code)
Подключает байт-код напрямую из указателя памяти.
Управление и выполнение:
void play()
Запускает выполнение загруженного скрипта с самой первой строки.
void stop()
Останавливает выполнение скрипта.
void tick()
Главная функция-движок. Ее обязательно нужно поместить внутрь главного цикла loop() вашего скетча, чтобы анимация работала.
bool isRunning() const
Управление скоростью:
Библиотека позволяет "на лету" изменять скорость воспроизведения эффектов, воздействуя на длительность пауз WAIT и DELAY в скриптах, без необходимости переписывать сам код скрипта.
void setSpeed(uint16_t percent)
Устанавливает множитель скорости в процентах (от 1 до 1000).
uint16_t getSpeed() const
Инициализация объекта:
LedBasic(uint16_t count, LBSetPixel setPixelCb, LBShow showCb, LBClear clearCb)
Конструктор класса. Создает экземпляр виртуальной машины.
Библиотека не привязана к конкретному оборудованию, поэтому при создании объекта вы обязаны передать количество светодиодов и три функции-коллбэка (обычно это лямбда-выражения), которые "объясняют" библиотеке, как управлять вашей лентой.
- Аргументы:
- count — общее количество пикселей на вашей ленте.
- setPixelCb — функция вида void(uint16_t pos, uint8_t r, uint8_t g, uint8_t b). Устанавливает цвет конкретного пикселя.
- showCb — функция вида void(). Вызывает обновление ленты (отправку данных из буфера на светодиоды).
- clearCb — функция вида void(). Полностью гасит ленту (заливает черным цветом).
Подготовка и компиляция скриптов:
bool compileFromText(const char* scriptText)
Компилирует текстовый скрипт на языке BASIC в бинарный байт-код прямо в оперативной памяти (RAM) микроконтроллера.
- Аргументы: Строка const char*, содержащая полный текст скрипта (строки должны разделяться символом переноса \n).
- Как работает: Парсит текст, переводит команды в числа (токены), выделяет нужное количество RAM и сохраняет туда байт-код. Строит индекс для быстрых переходов GOTO.
- Возвращает: true при успешной компиляции, false если не хватило памяти.
bool compileBasToBin(const char* basPath, const char* binPath)
Читает текстовый файл BASIC из файловой системы LittleFS, компилирует его построчно и сразу записывает готовый байт-код в другой файл.
- Аргументы:
- basPath — путь к исходному текстовому файлу (например, "/effect.bas").
- binPath — путь, куда сохранить бинарный файл (например, "/effect.bin").
- Особенности: Очень экономит оперативную память, так как не загружает весь текст в RAM. Полезно для предварительной компиляции скриптов.
bool loadBinFile(const char* path)
Загружает в оперативную память заранее скомпилированный бинарный файл из файловой системы LittleFS.
- Аргументы: path — путь к бинарному файлу (например, "/effect.bin").
- Возвращает: true при успехе, false если файл не найден или ошибка чтения.
bool loadBinMemory(const uint8_t* code)
Подключает байт-код напрямую из указателя памяти.
- Аргументы: code — массив uint8_t, содержащий байт-код.
- Особенности: Эта функция не копирует массив в новую память и не вызывает malloc. Она просто сохраняет указатель. Это идеально подходит для хранения жестко зашитых (hardcoded) эффектов во Flash-памяти микроконтроллера с использованием PROGMEM.
Управление и выполнение:
void play()
Запускает выполнение загруженного скрипта с самой первой строки.
- Как работает: Обнуляет все переменные (A-Z), сбрасывает стек вызовов (GOSUB, FOR), переводит виртуальную машину в статус VM_RUNNING. Если скрипт не загружен — функция просто проигнорируется.
void stop()
Останавливает выполнение скрипта.
- Как работает: Переводит машину в статус VM_STOPPED и автоматически вызывает ваш коллбэк clearCb, чтобы выключить все светодиоды на ленте.
void tick()
Главная функция-движок. Ее обязательно нужно поместить внутрь главного цикла loop() вашего скетча, чтобы анимация работала.
- Как работает: За один вызов читает и выполняет порцию инструкций (байт-кода).
- Асинхронность: Если в скрипте встречается команда WAIT 500, функция tick() запоминает время, переводит VM в режим ожидания и сразу же завершает свою работу, отдавая управление основному loop(). При следующих вызовах она будет проверять встроенный таймер (millis()), и продолжит работу только когда время выйдет.
- Безопасность: Чтобы микроконтроллер не завис на конструкции вида 10 GOTO 10, tick() имеет лимит (budget): за один проход она выполняет максимум 1000 инструкций.
bool isRunning() const
- Возвращает: true, если скрипт в данный момент выполняется (включая моменты паузы WAIT/DELAY). Возвращает false, если скрипт остановлен функцией stop() или дошел до конца программы (маркера конца файла).
Управление скоростью:
Библиотека позволяет "на лету" изменять скорость воспроизведения эффектов, воздействуя на длительность пауз WAIT и DELAY в скриптах, без необходимости переписывать сам код скрипта.
void setSpeed(uint16_t percent)
Устанавливает множитель скорости в процентах (от 1 до 1000).
- Аргументы:percent — скорость в процентах.
- 100 — нормальная скорость (по умолчанию, 1 к 1).
- 200 — в 2 раза быстрее (задержка WAIT 100 превратится в 50 мс).
- 50 — в 2 раза медленнее (задержка WAIT 100 превратится в 200 мс).
uint16_t getSpeed() const
- Возвращает: текущую установленную скорость в процентах.
C++:
void setup() {
strip.begin();
// 1. Инициализация (basic создана глобально)
// 2. Компиляция текста из строки
basic.compileFromText("10 SET 0, 255, 0, 0\n20 WAIT 1000\n30 CLEAR\n40 WAIT 1000\n50 GOTO 10\n");
// Можно загрузить из файла: basic.loadBinFile("/blink.bin");
// 3. Запуск программы
basic.play();
}
void loop() {
// 4. Движок программы (не блокирует цикл!)
basic.tick();
// Пример управления на лету:
// Если нажата кнопка, ускорить в 3 раза
if (digitalRead(BTN_PIN) == LOW) {
basic.setSpeed(300);
} else {
basic.setSpeed(100);
}
}
Язык представляет собой классический диалект BASIC с номерами строк.
Типы данных и переменные
Поддерживается приоритет математических операций: +, -, *, /, % (остаток от деления), AND (побитовое И), OR (побитовое ИЛИ).
Встроенные функции:
Типы данных и переменные
- Поддерживается 26 глобальных целочисленных переменных (типа int16_t).
- Имена переменных — одиночные заглавные буквы английского алфавита: от A до Z.
- SET pos, r, g, b — Установить цвет RGB (0-255) для пикселя с индексом pos.
- SET_HSV pos, h, s, v — Установить цвет в формате HSV (Оттенок, Насыщенность, Яркость). Библиотека сама пересчитает это в RGB.
- FILL r, g, b — Залить всю ленту одним цветом.
- CLEAR — Выключить все светодиоды (залить черным).
- SHOW — Отправить данные на ленту (применить изменения).
- WAIT ms — Вызвать SHOW и подождать ms миллисекунд.
- DELAY ms — Просто подождать ms миллисекунд (без обновления ленты).
- BRIGHT val — Команда зарезервирована для изменения глобальной яркости.
- GOTO line — Безусловный переход на строку с номером line.
- GOSUB line ... RETURN — Вызов подпрограммы и возврат (глубина стека до 10 вызовов).
- FOR var = start TO end [STEP step] ... NEXT var — Цикл со счетчиком (глубина вложенности до 8).
- IF условие THEN команда — Условное выполнение. Поддерживаются операторы ==, !=, >, <, >=, <=. Особенность: после THEN может идти только одна команда.
Поддерживается приоритет математических операций: +, -, *, /, % (остаток от деления), AND (побитовое И), OR (побитовое ИЛИ).
Встроенные функции:
- RND(min, max) — Случайное число в диапазоне.
- ABS(x) — Модуль числа.
- MIN(a, b), MAX(a, b) — Минимальное / максимальное значение.
- SIN8(x), COS8(x) — Быстрый синус/косинус (вход 0-255, выход 0-255).
- PIXEL — Возвращает индекс последнего пикселя на ленте (общее количество - 1).
LedBasic IDE v3 — это легковесная, полностью работающая (не без багов конечно, но вполне работает.) в браузере среда разработки (IDE) и эмулятор для написания эффектов адресных светодиодных лент (подобных WS2812b) на Basic подобном языке.
Основные возможности:
Позволяет видеть результат работы кода прямо на экране без подключения реального "железа".
Программа создана не только для развлечения, но и для реального использования в проектах (например, на Arduino или ESP8266/ESP32). Код можно экспортировать в несколько форматов:
Основные возможности:
- Синтаксическая подсветка: Автоматическое окрашивание команд (синий), логики (фиолетовый), математики (желтый), переменных (зеленый) и чисел.
- Автодополнение (Autocomplete): При вводе текста появляются подсказки с шаблонами команд (например, при вводе SET предложит SET_HSV P , C , 255 , 200).
- Анализ ошибок (Линтер): Редактор «на лету» проверяет код. Если допущена ошибка (неизвестная команда, нет номера строки), код подчеркивается красной волнистой линией, а в левом поле появляется значок предупреждения.
- Инструмент «Нумерация»: Так как язык требует номеров строк (10, 20, 30...), этот инструмент позволяет автоматически перенумеровать весь код с заданным шагом.
- Автоформатирование: Кнопка «Формат» автоматически расставляет пробелы вокруг операторов и приводит команды к верхнему регистру для красоты кода.
Позволяет видеть результат работы кода прямо на экране без подключения реального "железа".
- Формы вывода:
Поддерживает 3 режима визуализации:- Полоса (Strip) — классическая прямая лента.
- Кольцо (Ring) — светодиоды по кругу.
- Матрица (Matrix) — прямоугольная 2D-сетка (с настройкой ширины и высоты).
- Настройки: Можно менять количество пикселей (до 1024), масштаб (размер светодиодов).
- Графика: Реалистичное отображение с эффектом "свечения" (Glow) вокруг ярких пикселей.
- Производительность: Показывает реальный FPS работы эмулятора.
- Консоль: Выводит логи компиляции, сообщения об ошибках и статус системы.
- Переменные (Live-мониторинг): В реальном времени показывает текущие значения всех 26 доступных переменных (от A до Z) прямо во время работы анимации! Отличный инструмент для поиска логических ошибок.
- Байт-код: Показывает результат компиляции. Текстовый BASIC переводится в компактные HEX-инструкции, которые можно посмотреть с привязкой к номерам строк.
Программа создана не только для развлечения, но и для реального использования в проектах (например, на Arduino или ESP8266/ESP32). Код можно экспортировать в несколько форматов:
- .bas — исходный текстовый код программы.
- const char* — код в виде C++ строки для вставки прямо в скетч Arduino.
- PROGMEM — код в виде массива символов, хранящегося во флеш-памяти микроконтроллера.
- .bin hex — скомпилированный бинарный байт-код в виде C++ массива (uint8_t), готовый для выполнения на микроконтроллере (самый быстрый и компактный вариант).
- Горячие клавиши: Ctrl+Enter или F5 для запуска кода, Ctrl+S для сохранения.
- Кастомизация UI: Можно изменять высоту нижней панели отладки и ширину левой панели эмулятора перетаскиванием мыши.
- Настройки: Подстройка размера шрифта, размера табуляции (Tab), скорости работы виртуальной машины (setSpeed (%)).
- Локальная работа: Все функции (загрузка, сохранение файлов, компиляция) работают прямо в браузере с использованием HTML5 File API, не требуя сервера.
C++:
// =============================================================
// main_rainbow.cpp — эффект «Радуга со случайными вспышками»
//
// Вся лента показывает полный спектр радуги, равномерно
// распределённый по длине. Радуга медленно вращается.
// Случайные пиксели вспыхивают белым — как искры.
//
// Использует PIXEL — автоматически подстраивается под
// любую длину ленты без изменения скрипта.
//
// Железо: лента WS2812B, ESP8266, DMA-пин GPIO3 (RX)
// =============================================================
#include <Arduino.h>
#include <NeoPixelBus.h>
#include "LedBasic.h"
// --- настройки ---
#define NUM_LEDS 60 // меняй под свою ленту
#define DATA_PIN 3 // DMA: только GPIO3 (RX)
using MyStrip = NeoPixelBus<NeoGrbFeature, NeoEsp8266DmaWs2812xMethod>;
MyStrip strip(NUM_LEDS, DATA_PIN);
LedBasic basic(
NUM_LEDS,
[](uint16_t pos, uint8_t r, uint8_t g, uint8_t b) {
strip.SetPixelColor(pos, RgbColor(r, g, b));
},
[]{ strip.Show(); },
[]{ strip.ClearTo(RgbColor(0, 0, 0)); strip.Show(); }
);
// =============================================================
// Скрипт: радуга + случайные белые вспышки
//
// H — смещение оттенка (анимация вращения)
// P — текущий пиксель
// C — оттенок пикселя P
// S — случайное число для вспышки (0..14)
//
// Каждый пиксель получает оттенок H + P * 256 / PIXEL —
// это равномерно растягивает весь спектр по ленте.
// С вероятностью 1/15 пиксель вспыхивает белым.
// =============================================================
const char* scriptText =
"10 H = 0\n" // начальное смещение оттенка
// --- кадр: рисуем радугу пиксель за пикселем ---
"100 P = 0\n"
"110 C = H + P * 256 / PIXEL\n" // оттенок: смещение + шаг по позиции
"120 SET_HSV P , C , 255 , 170\n"
// с вероятностью 1/15 — белая вспышка поверх
"130 S = RND 0 , 14\n"
"140 IF S == 0 THEN SET P , 255 , 255 , 220\n"
"150 P = P + 1\n"
"160 IF P <= PIXEL THEN GOTO 110\n"
// показать кадр и прокрутить радугу
"170 WAIT 25\n"
"180 H = H + 4\n"
"190 IF H > 255 THEN H = H - 256\n"
"200 GOTO 100\n";
// =============================================================
void setup() {
strip.Begin();
strip.Show();
basic.compileFromText(scriptText);
basic.play();
}
void loop() {
basic.tick();
}
Код:
Радуга:
10 H = 0
20 FOR I = 0 TO PIXEL
30 C = H + I * 256 / PIXEL
40 SET_HSV I , C , 255 , 180
50 NEXT I
60 WAIT 30
70 H = H + 2
80 IF H > 255 THEN H = H - 256
90 GOTO 20
Изменено:

