LedBasic — это интерпретируемый BASIC-подобный язык и виртуальная машина (VM) для создания анимаций на адресных светодиодных лентах. Программы пишутся в текстовом виде, компилируются в байт-код прямо на контроллере и выполняются неблокирующим образом — параллельно с остальным кодом Arduino.
Она позволяет писать анимации для светодиодов в виде простого текста (скриптов), компилировать их в компактный байт-код и воспроизводить без блокировки основного цикла микроконтроллера.
Основные возможности:
- Неблокирующее выполнение— 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 IDE
Описание функций библиотеки
Функции логически разделены на группы: инициализация, загрузка кода, управление выполнением и настройки.
Инициализация объекта:
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(). Полностью гасит ленту (заливает черным цветом).
~LedBasic() - Деструктор класса. Вызывается при удалении объекта. Автоматически освобождает динамическую память (RAM), если она была выделена под байт-код с помощью malloc.
Подготовка и компиляция скриптов:
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
- Возвращает: текущую установленную скорость в процентах.
Язык скриптов LedBasic
Язык представляет собой классический диалект BASIC с номерами строк.
Типы данных и переменные
- Поддерживается 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 — Команда зарезервирована для изменения глобальной яркости.
Управление логикой (Control Flow)
- 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 — это готовое решение для встраивания скриптовых анимаций в проекты на Arduino, ESP8266 и ESP32. Библиотека предлагает разработчику законченную экосистему:
- Асинхронность: Неблокирующие паузы WAIT и защита от зависаний.
- Гибкость: Полноценный BASIC-подобный язык с циклами, математикой и подпрограммами.
- Удобство: Поддержка HSV-цветов, табличной тригонометрии и редактор кода с эмулятором.
LedBasic позволяет держать сложные эффекты в файловой системе или PROGMEM, вызывая их по требованию, и гарантирует, что даже «кривой» скрипт с бесконечным циклом не повесит ваш контроллер. Это надежный фундамент для вашего светового проекта.
#arduino #platformio #neopixel #ws2812b #apa102 #esp8266 #esp32 #led #basic #cpp #ide #программирование #светодиоды #ардуино #vscode #DIY #виртуальнаяМашина #VM #скрипты #микроконтроллеры #SmartHome #умныйДом #светодиоднаяЛента #эффекты #световыеЭффекты #светодиоднаяАнимация #ArduinoProject #ESP32Project #DIYElectronics #Maker #Hardware