Кроссплатформенная симуляция Arduino в стиле Tinkercad Circuits: размещение компонентов, проводка, блочное программирование и пошаговый симулятор.
Написано на Flutter. Работает на Windows, Web, Android, iOS.
- Схема — перетаскивайте компоненты из палитры, вращайте, соединяйте пины проводами. Свойства компонентов (сопротивление, свет, положение потенциометра и стика джойстика, параметры датчиков) можно редактировать.
- Подписанные контакты — каждый вывод подписан прямо на компоненте (
VCC,GND,TRIG,ECHO,DATA,SDA,SCL,SIG,A/Cу светодиода). У платы Arduino подписаны все хедеры, включаяGNDи питание. Во время прокладки провода все свободные контакты подсвечиваются оранжевым. - Блочное программирование — программа собирается из блоков, разделена на
setupиloop(пины, задержки, циклы, условия, переменные, Serial, сервопривод, зуммер, LCD, датчики). - Два представления программы — одно и то же блочное дерево:
SketchPrinter— Arduino C++ в редактируемой вкладке Скетч (см. ниже)SketchCompiler— компиляция в байткод встроенной ВМ
- Живая симуляция — модифицированный MNA-солвер считает напряжения в узлах каждый кадр. Горят светодиоды, крутится сервопривод, работает Serial Monitor, датчики (HC-SR04, DHT11) возвращают значения в программу.
- Сохранение/загрузка — через
shared_preferences(слоты) и импорт/экспорт JSON. - Готовые уроки — 12 примеров: Blink, Кнопка+светодиод, Потенциометр+светодиод, Джойстик+сервопривод, Сервопривод, Пьезо-зуммер, LCD 16x2, Ультразвуковой дальномер, DHT11, Машинка-робот 4WD, Механическая рука, Рука из деталей.
- Робототехника — три готовых стенда, которые собираются и программируются обычными блоками:
- Robot Car 4WD — шасси со встроенным драйвером, четырьмя моторами (по своему на каждое колесо) и двумя дальномерами HC-SR04. Наружу выведены
M1A/M1B/EN1…M4A/M4B/EN4(направление + ШИМ-скорость каждого мотора),TRIG/ECHO(перед) иTRIG2/ECHO2(корма),5V/GND. Машинка реально ездит по рабочему полю: границы поля работают стенами, а дальномеры измеряют расстояние до стены по курсу и назад, поэтомуread distanceотвечает «живыми» сантиметрами. - Robot Arm — настраиваемая рука-конструктор: задаёте число звеньев (2–6), а на каждый сустав ставите сервопривод (
J1…J6) или оставляете его в покое. Последний сустав работает челюстями захвата. Угол задаётся блокомservo write. - Детали руки —
Arm Base,Arm Link,Arm Gripperи обычныйServo: рука собирается перетаскиванием, детали прилипают к золотым гнёздам, а сервопривод, вставленный в сустав, поворачивает всё, что прикручено выше него.
- Robot Car 4WD — шасси со встроенным драйвером, четырьмя моторами (по своему на каждое колесо) и двумя дальномерами HC-SR04. Наружу выведены
- Адаптивный UI — на десктопе/web 3 колонки, на телефоне — вкладки.
- Два языка — кнопка RU / EN в тулбаре переводит весь интерфейс (уроки, названия деталей и блоков, подсказки, сообщения); выбор сохраняется между запусками. По умолчанию — русский.
Вкладка Скетч — не превью, а полноценный редактор, и обе стороны связаны: правки кода пересобирают блоки, правки блоков переписывают код.
- Код можно писать руками. Есть подсветка синтаксиса и автокомплит: список
подсказок открывается у каретки,
↑/↓— выбор,Tabили клик — вставка,Esc— закрыть. Без открытого спискаTabпросто ставит отступ. - Код → блоки. Как только набранный скетч становится корректным, блоки пересобираются сами: переключитесь на вкладку Блоки — программа уже там.
- Блоки → код. Любая правка блоков (добавить, удалить, переставить, изменить параметр) сразу переписывает текст.
- Ошибка в коде ничего не ломает. Если строку не удалось разобрать, блоки остаются как были, а сверху появляется баннер с номером строки и причиной. Кнопка пересобрать возвращает текст из блоков.
- Словарь подсказок знает только те конструкции, которые понимает блочный
редактор (пины,
delay,for/while,if, Serial, servo, LCD, датчики), поэтому автокомплит и блоки всегда говорят об одном и том же. - Разбором текста занимается
lib/blocks/sketch_parser.dart— обратная функция кSketchPrinter: печать блоков и чтение текста проверены тестами друг на друге (напечатали → прочитали → напечатали то же самое).
flutter pub get
flutter run -d windows # или chrome, android, iosflutter analyze # 0 проблем
flutter test # widget + engine + i18n тесты (172/172)lib/
blocks/ блоки, каталог, печать и разбор C++
engine/ netlist, solver, vm, simulation_engine, robotics
i18n/ таблицы строк (RU/EN) и контроллер языка
models/ circuit, pins, component specs, project
examples/ готовые уроки
services/ хранение JSON
state/ AppState (ChangeNotifier)
ui/ тема, канвас, виджеты
main.dart
Ядро (models/, engine/) не зависит от Flutter — легко тестируется.
Текст интерфейса живёт только в lib/i18n/strings.dart: виджеты и данные берут
строку по ключу через S.t, поэтому новый язык — это ещё одна таблица.
- Примеры и уроки → выберите урок → Загрузить пример
- Запустить — запустить симуляцию, Остановить — остановить, Сбросить — сбросить
- Вкладки: Блоки, Скетч, Порт, Инспектор
- RU / EN в тулбаре — переключение языка интерфейса
- Нажмите на контакт компонента (точку на его краю) — она подсветится оранжевым, а сверху появится подсказка, от какого контакта идёт провод.
- Нажмите на второй контакт — провод готов. Повторное нажатие на тот же контакт отменяет прокладку.
- То же самое можно делать из вкладки Inspector: у выбранного компонента виден список всех контактов и то, к чему каждый уже подключён; нажатие на контакт в списке начинает провод.
- Пока провод прокладывается, подписанные контакты подсвечиваются, чтобы было видно, куда попадать (у макетной платы контактов слишком много — там подписи не выводятся).
- Провода рисуются поверх компонентов, а на каждом конце провода стоит маркер цвета провода — поэтому всегда видно, к какому именно контакту платы пришёл провод, даже если он подходит к середине корпуса.
- Двойной клик — повернуть компонент на 90°
- Долгое нажатие — удалить компонент
- Перетаскивание — переместить компонент
- Перетаскивание детали руки — тащите деталь к золотому гнезду другой детали и отпустите: она прилипнет (а потянув снова — отцепится)
Обычный модуль из категории INPUT — тот же самый, что и в Tinkercad: пять контактов и стик, который можно наклонять.
| Контакт | Куда подключать | Что там |
|---|---|---|
VCC, GND |
питание платы | питание резистивных делителей |
VRX |
аналоговый вход | напряжение оси X: 0…5 В |
VRY |
аналоговый вход | напряжение оси Y: 0…5 В |
SW |
цифровой вход | кнопка внутри стика, замыкает на GND |
- Наклоните стик пальцем — он поедет за ним, а делители тут же отдадут
напряжение оси:
analogReadпо центру вернёт ~511, в крайнем правом (или верхнем) положении — близко к 1023, в крайнем левом (нижнем) — к нулю. - Клик по отправленному стику возвращает его в центр, как пружина.
- Клик по короткой площадке
SWв углу — нажать кнопку; второй клик отпускает. УSWтот же механизм, что и у обычной кнопки: она замыкает пин наGND, поэтому вход платы нужно подтянуть (pin mode INPUT_PULLUP), как в уроке. - В Inspector у него два ползунка (
X,Y) с процентом и напряжением, кнопка «в центр» и тумблерSW.
Комбинация стика и сервопривода — самый быстрый способ «поиграть» в аналоговый: урок Джойстик и сервопривод читает обе оси и светит светодиодом на нажатие стика.
Машинка и рука — обычные компоненты из палитры (категория ROBOTICS), поэтому
подключаются и программируются теми же блоками, что и всё остальное. Новых
блоков для них не нужно. Детали руки (Arm Base, Arm Link, Arm Gripper)
образуют отдельный мини-конструктор: их перетаскивают, и они прилипают друг к
другу — см. раздел про руку из деталей ниже.
Внутри шасси уже стоят драйвер, четыре мотора — по одному на каждое колесо — и два дальномера (перед и корма). Вы просто подключаете к ним Arduino:
| Контакт машинки | Куда подключать | Зачем |
|---|---|---|
M1A, M1B |
любые цифровые пины | направление переднего левого мотора |
EN1 |
пин с ШИМ (3, 5, 6, 9, 10, 11) | скорость переднего левого мотора |
M2A, M2B, EN2 |
— | передний правый мотор |
M3A, M3B, EN3 |
— | задний левый мотор |
M4A, M4B, EN4 |
— | задний правый мотор |
TRIG, ECHO |
цифровые пины | дальномер на носу |
TRIG2, ECHO2 |
цифровые пины | дальномер на корме |
5V, GND |
питание платы | питание логики |
Каждое колесо — со своим мотором: полный привод, независимые левая и правая
пары (левая — M1+M3, правая — M2+M4), поэтому машинка может и ехать
прямо, и разворачиваться на месте. Направление задаётся парой A/B обычными
digital write, а скорость — analog write на ENx.
Откройте урок Robot car 4WD: avoid the walls и нажмите Run — машинка поедет вперёд и свернёт перед стеной.
- Машинка едет в сторону своего «носа» (он нарисован справа), а
rotationсовпадает с курсом, поэтому провода честно тянутся за ней. - Колёса прокручиваются на экране каждое со своей скоростью, так что видно, какое колесо буксует.
- Стены — это границы рабочего поля: корпус всегда остаётся внутри.
- Оба дальномера отдают расстояние до стены в сантиметрах (7 пикселей = 1 см):
передний — по курсу, задний — назад.
read distance (cm)работает без настроек; чтобы прочитать кормовой датчик, добавьте второй блокread distanceи укажите егоTRIG/ECHO. - Хотите задать расстояние вручную (например, поставить перед ней препятствие) — выключите тумблер Wall sensors в Inspector и двигайте ползунки Distance ahead / Distance behind.
- Во время работы машинку нельзя перетаскивать: её положением управляет физика. Остановите симуляцию, поставьте её на нужное место и направьте двойным кликом — Run запомнит эту точку, а Reset вернёт машинку туда же.
- В Inspector видны скорость каждого из четырёх колёс, курс и показания обоих дальномеров.
Рука — это конструктор. Вы задаёте, сколько в ней звеньев (Segments, 2–6),
и на каждый сустав решаете, вставлять сервопривод или нет:
| Контакт руки | Зачем |
|---|---|
J1 … J6 |
сигнал сервопривода сустава (по одному на сустав), подключайте к пинам с ШИМ |
5V, GND |
питание сервоприводов |
Первый сустав — плечо у основания, каждый следующий — следующее сочленение, а
последний сустав работает челюстями захвата. Углы задаются блоком
servo write:
servo write pin 3, angle 40 // плечо
servo write pin 5, angle 120 // локоть
servo write pin 6, angle 135 // кисть
Откройте урок Robot arm: pick and place — это готовый цикл «взять и перенести».
- Рука нарисована цепочкой звеньев в плоскости экрана: видно все суставы сразу. Больший угол на сервоприводе сильнее «загибает» сустав.
- Сустав, в который не вставили сервопривод, держит угол, выставленный вручную ползунком в Inspector. Так можно «позировать» руку и анимировать один сустав за раз.
- Челюсти открываются пропорционально углу последнего сустава (0° — закрыты, 180° — раскрыты).
- В Inspector для каждого сустава виден либо живой угол с сервопривода, либо его ручная установка.
Руку можно собрать не целиком, а по деталям — как из конструктора:
Arm Base— основание-тумба,Arm Link— звено,Arm Gripper— захват с челюстями,Servo— обычный сервопривод из палитры.- У каждой детали есть золотое гнездо (виден кружок-паз) — точка, куда вставляется следующая деталь.
- Перетащите деталь так, чтобы её пятка попала на гнездо, и отпустите — она прилипнет и останется на месте. Потяните снова — отцепится. Одно гнездо держит одну деталь.
- Сервопривод — единственная деталь, которая гнётся: он поворачивает всё, что
прикручено выше него, на угол из
servo write(связь «вверх по цепочке»). - Сервопривод, вставленный в гнездо самого захвата, работает челюстями: 0° закрывает их, 180° раскрывает широко.
Откройте урок Robot arm: build it out of parts — там собран стенд «тумба → серво → звено → серво → звено → захват → челюсти».
- Кнопка Unbolt в Inspector отсоединяет деталь от родителя.
- Если удалить деталь, всё, что было прикручено выше, не исчезает — оно просто становится свободным и остаётся на месте.
Физика вынесена в lib/engine/robotics.dart и не зависит от Flutter:
RigWiringчитает состояние стенда из netlist (resolveLogicPin+ таблицыruntime), поэтому стенд работает и напрямую, и через макетную плату.CarPhysics— дифференциальный привод: складывает скорости четырёх колёс в линейную и угловую, считает лучи до стены (вперёд и назад) и не даёт корпусу выехать за поле.ArmKinematics— прямая кинематика руки: длина звена зависит от числа сегментов, так что рука любой длины помещается в компонент;ArmAssembly«запекает» позу — раскладывает цепочку деталей по гнёздам и превращает углы сервоприводов вx/y/rotationдеталей.- Машинка и рука шагают по виртуальному времени программы, а не по кадрам:
wait 300— это ровно 300 мс работы моторов (иначе классическая программа «вперёд → подождать → повернуть» почти не двигала бы машинку).
- Виртуальное время в микросекундах;
delay()«перепрыгивает» вперёд. - Кооперативный режим: ВМ работает с бюджетом инструкций за кадр — бесконечный цикл не зависнет.
- Светодиод моделируется как 180 Ом,
INPUT_PULLUP— 40 кОм к 5 В, выходные пины — фиксированное напряжение. - Эмуляция
pulseIn()/DHT11 через связи по электрическим узлам (netlist). - Роботы шагают по виртуальному времени: машинка и рука получают команды из тех же таблиц
runtime, что и обычные компоненты.