Запускаем код для Arduino в браузере
WebAssembly позволяет запускать код на разных языках программирования внутри браузера, и сейчас это не только способ разрабатывать веб-приложения не на JS, но и возможность использовать браузер как кроссплатформенную, легкодоступную песочницу для тестирования. Например, проект Wasmino позволяет эмулировать ядро Arduino в браузере и запускать на нём код прямо из IDE.
Как это работает
В IDE скетчи пишутся на C/C++. Вот простейший пример с сайта Arduino, светодиод на 9 пине плавно разгорается и затухает:
/*
Fade
This example shows how to fade an LED on pin 9 using the analogWrite()
function.
The analogWrite() function uses PWM, so if you want to change the pin you're
using, be sure to use another PWM capable pin. On most Arduino, the PWM pins
are identified with a "~" sign, like ~3, ~5, ~6, ~9, ~10 and ~11.
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/Fade
*/
int led = 9; // the PWM pin the LED is attached to
int brightness = 0; // how bright the LED is
int fadeAmount = 5; // how many points to fade the LED by
// the setup routine runs once when you press reset:
void setup() {
// declare pin 9 to be an output:
pinMode(led, OUTPUT);
}
// the loop routine runs over and over again forever:
void loop() {
// set the brightness of pin 9:
analogWrite(led, brightness);
// change the brightness for next time through the loop:
brightness = brightness + fadeAmount;
// reverse the direction of the fading at the ends of the fade:
if (brightness <= 0 || brightness >= 255) {
fadeAmount = -fadeAmount;
}
// wait for 30 milliseconds to see the dimming effect
delay(30);
}
Скетч при загрузке сохраняется в гист, к которому обращается веб-приложение. Внутри него — настоящее ядро Arduino, скомпилированное под wasm (репозиторий). На сайте в ядро загружается код из гиста и выполняется внутри браузера, позволяя на ходу изменять список и тип подключенных устройств.
Результат примера выше можно посмотреть здесь, нажав на кнопку Run:
Волшебно! Зачем нужна сама плата, если формально можно выполнять код для неё в браузере и на лету видеть результат? На самом деле, конечно, круг кейсов сильно ограничен, да и в интерфейсе можно добавлять только светодиоды и переключатели, без возможности использовать более сложные устройства. С другой стороны, можно как форкнуть репозиторий runtime, так и написать своё приложение с нуля, основываясь только на ядре. Есть и другие ограничения, разберём их ниже.
Как попробовать
Обязательно потребуется Arduino IDE, веб-редактор Arduino Create не подойдёт. Для загрузки гистов также потребуется авторизация в GitHub.
Идём на страницу релизов, в самом свежем копируем ссылку на package_wasmino_index.json (сейчас это https://github.com/wasmino/wasmino-core/releases/download/v0.0.1/package_wasmino_index.json) и вставляем в поле «Additional Boards Manager URLs» в настройках (File > Preferences).
Затем в Tools > Board открываем Boards Manager, находим Wasmino, устанавливаем и выбираем:
С настройкой покончено, теперь остаётся вставить пример выше (прежде чем экспериментировать с другим кодом, изучите ограничения Wasmino) и нажать Upload. При первом запуске в консоли появится ссылка и код для авторизации приложения в GitHub, код активен минуту. После авторизации скетч загружается в гист и в консоли появится ссылка на приложение:
Готово! По умолчанию пины не назначены, поэтому их надо ввести вручную, после чего обновлённой ссылкой можно делиться.
Ограничения
Так как Wasmino работает как абстрактное ядро, его стоит рассматривать как борду с бесконечно быстрым процессором. Из-за этого любые операци кроме delay
и delayMicroseconds
будут происходить мгновенно, что скажется на результате временных функций вроде micros
и millis
. Ввод и вывод происходят только во время паузы, поэтому такой код не сработает:
while (!digitalRead(2)) {} // вкладка в браузере зависнет
вместо этого придётся указать задержку вручную
while (!digitalRead(2)) {
delay(50);
}
Также из-за бесконечно быстрого процессора прерывания происходят только во время delay
и delayMicroseconds
, поэтому рекомендуется использовать noInterrupts
и interrupts
для защиты важных участков, если код предназначается для реального железа.
Кроме того, из-за отсутствия встроенного светодиода, в Wasmino не работает BUILTIN_LED
.
Реализованные функции и классы
(отсюда)
- digitalRead()
- digitalWrite()
- pinMode()
- analogRead()*
- analogWrite()
- delay()
- delayMicroseconds()
- micros()
- millis()
- abs()
- constrain()
- map()
- max()
- min()
- pow()
- sq()
- sqrt()
- cos()
- sin()
- tan()
- bit()
- bitClear()
- bitRead()
- bitSet()
- bitWrite()
- highByte()
- lowByte()
- attachInterrupt()
- detachInterrupt()
- interrupts()
- noInterrupts()
- Serial*
- Stream
* Не реализованы в веб-приложении, но есть в ядре
Нереализованные функции и классы
- analogReference()
- analogReadResolution()
- analogWriteResolution()
- noTone()
- pulseIn()
- pulseInLong()
- shiftIn()
- shiftOut()
- tone()
- isAlpha()
- isAlphaNumeric()
- isAscii()
- isControl()
- isDigit()
- isGraph()
- isHexadecimalDigit()
- isLowerCase()
- isPrintable()
- isPunct()
- isSpace()
- isUpperCase()
- isWhitespace()
- random()
- randomSeed()
- Keyboard
- Mouse
Ядро активно допиливается, можно помочь запилить недостающие фичи.
Заключение
Wasmino — клёвый проект, который стоит поддержать на раннем этапе, если вы работаете с Arduino и хотите видеть полноценную (почти) реализацию борды в браузере. Ядро в текущем пре-релизном виде написано одним человеком, и контрибьюторы ему явно помогут не забросить эту амбициозную идею.
На правах рекламы
Мощные VDS с процессорами AMD EPYC для разработчиков. Частота ядра CPU до 3.4 GHz. Максимальная конфигурация позволит оторваться на полную — 128 ядер CPU, 512 ГБ RAM, 4000 ГБ NVMe.