Симулятор Arduino Leonardo онлайн: USB HID и Keyboard без платы
Arduino Leonardo — плата, на которой я впервые попробовал USB HID: скетч Keyboard.print открывал блокнот и печатал «Hello» сам. На Uno такого нет — у Uno отдельный USB-чип, а у Leonardo один чип ATmega32U4 держит и скетч, и USB-устройство. Минус — компьютеру ваша плата представляется клавиатурой/мышью, и при глюке скетча клавиатура «сходит с ума»: мышь летает по экрану, в окно вводятся случайные символы. В браузере этот затык безопасен — можно потрогать логику Keyboard.h без потери управления ПК.
Самой платы Leonardo в каталоге симулятора нет — лендинг текстовый с разбором USB HID, библиотек Keyboard.h и Mouse.h, разницей Serial против Serial1, и тем, что переезжает от Uno, а что нет. Для живой сборки и USB-CDC — урок про Serial на ESP32 и Leonardo; для первой прошивки платы — урок про выбор платы и порта.
Leonardo в двух словах
ATmega32U4 — тот же 8-битный AVR, что у Uno, но с одним отличием: USB-контроллер встроен в чип, а не вынесен в отдельный мост (CH340 или 16U2). Из этого — две способности. Первая: плата представляется компьютеру как клавиатура/мышь/джойстик (HID-классы), без драйверов. Вторая: Serial идёт через USB CDC — виртуальный порт, а настоящий UART на пинах 0/1 зовётся Serial1. Это развязка, которая ломает код с Uno: на Leonardo Serial.begin(9600) не означает аппаратный UART, и Serial1.begin(9600) — отдельный вызов для пинов 0/1.
- ATmega32U4: 16 МГц, 32 КБ флеш, 2,5 КБ SRAM — чуть меньше SRAM, чем у Uno (3,5 КБ), и без отдельного USB-моста.
- USB HID: Keyboard.h, Mouse.h, Joystick.h — плата представляется компьютеру клавиатурой/мышью без драйверов.
- Serial против Serial1: первый — виртуальный USB CDC, второй — аппаратный UART на пинах 0/1.
- Автосброс другой: на Leonardo DTR не дёргает RESET так же, как на Uno — при открытии монитора плата не всегда перезапускается, и setup может не пробежать.
- Цена: дороже Uno (наличие HID оправдывает), но часто заменяется Pro Micro — тот же 32U4 в меньшем корпусе.
Стартовый скетч: Keyboard.print в блокнот
#include <Keyboard.h> void setup() { Serial.begin(9600); Keyboard.begin(); delay(5000); // успеть открыть блокнот Keyboard.print("Hello from Leonardo"); Keyboard.write(''); Keyboard.end();} void loop() {}Скетч вставьте в основной симулятор — компилятор поймёт Keyboard.h, и логика сработает: на плате через 5 секунд в окне с фокусом появится строка «Hello from Leonardo». В браузере эмуляции ввода нет: Keyboard.begin/print/write компилируются, но символы никуда не уходят — это честная граница. На живой плате через 5 секунд откройте блокнот, и плата напечатает строку. Полный разбор USB CDC — в уроке про Serial на Leonardo.
Mouse-jiggler: имитация движения мыши
#include <Mouse.h> unsigned long last = 0; void setup() { Mouse.begin();} void loop() { if (millis() - last >= 30000) { last += 30000; Mouse.move(1, 0, 0); // +1 пиксель вправо delay(50); Mouse.move(-1, 0, 0); // обратно }}Mouse-jiggler — самый популярный скетч для Leonardo: курсор сдвигается на пиксель и обратно раз в 30 секунд, и компьютер думает, что пользователь «тут». На работе это лечит блокировку экрана на длинных совещаниях; в логах это обнаруживается, поэтому против корпоративных политик jiggler не используют. В браузере Mouse.move компилируется, но курсор не дёргается: HID-интерфейса нет, это физика железа.
Что переезжает от Uno, а что нет
| Проверка | На Uno | На Leonardo |
|---|---|---|
| Serial.begin — монитор порта | аппаратный UART | USB CDC, виртуальный |
| Serial1.begin — UART на пинах 0/1 | нет (Serial = UART) | да, отдельный интерфейс |
| Keyboard.h, Mouse.h — HID | нет (нужен Hoodloader) | да, из коробки |
| Автосброс при открытии монитора | да, через DTR | не всегда — плата не перезапускается |
| Скетч под ATmega328 | нативно | переписывается под 32U4: пины и таймеры те же, но прерывания таймеров другие |
| Заливка скетча через USB | да, через 16U2/CH340 | да, через 32U4 напрямую |
Скетч под Uno чаще всего собирается на Leonardo без правок — пины 0-13, A0-A5, analogWrite на 3, 5, 6, 9, 10, 11 — те же. Ловушки начинаются там, где код зависит от Serial как UART: на Leonardo Serial — это USB CDC, и после заливки скетча плата может не перезапуститься, потому что DTR не дёргает RESET так же, как у Uno. Поэтому в скетч под Leonardo добавляют while(!Serial) delay(10); — дождаться, пока монитор откроется, перед печатью.
Грабли Leonardo
- Serial против Serial1: на Leonardo Serial — это USB CDC, а не UART. Если код пишет Serial1.begin на Uno, это не скомпилируется; на Leonardo — отдельный интерфейс на пинах 0/1.
- while(!Serial): при открытии монитора Leonardo не перезапускается, и setup может пробежать до того, как монитор готов. Строка while(!Serial) в начале setup — для Leonardo обязательно.
- HID-глюки: при ошибке в скетче Keyboard.press без Keyboard.release клавиша «залипает», и компьютер печатает её бесконечно. Лечится Ctrl+Alt+Del и перепрошивкой.
- Mouse.move без задержки: курсор летает по экрану, и поймать кнопку «Загрузить» в IDE тяжело. Между Mouse.move — delay 50-100 мс.
- Заливка при зависшем HID: если скетч «сошёл с ума» и не даёт загрузить новый, зажмите RESET при подаче USB, отпустите — и в течение 8 секунд загрузите скетч.