TypeScript на микроконтроллерах: революция в embedded разработке

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Когда JavaScript встречает железо: новое слово в embedded

Когда мы говорим "embedded разработка", в голове обычно всплывают ассоциации с Си, голым металлом, ассемблерными вставками и бесконечными дебаггинг-сессиями с осциллографом. А теперь представьте, что вы пишете прошивку для умного датчика температуры, используя TypeScript. Звучит как фантастика? А зря.

Мир встраиваемых систем переживает тихую революцию. Современные микроконтроллеры обзавелись достаточным объемом памяти и тактовой частотой, чтобы выполнять скриптовые языки. А TypeScript с его статической типизацией и богатой экосистемой становится идеальным кандидатом для embedded-проектов, где важна надежность и читаемость кода.

В этой статье мы разберем, как TypeScript проникает в мир embedded, какие инструменты для этого нужны, и напишем реальный код для управления светодиодом через GPIO. Поехали!

Почему TypeScript, а не C или Python?

Классический выбор для embedded — это C. Он быстр, предсказуем и жрет мало памяти. Но у него есть темная сторона: управление памятью вручную, отсутствие нормальной типизации на уровне компилятора и "ад" с макросами. Python (MicroPython) проще, но медленный и динамический — вы узнаете о баге только в рантайме, когда устройство зависнет где-нибудь на полке.

TypeScript предлагает золотую середину:

  • Строгая типизация — компилятор ловит ошибки на этапе сборки. Никаких случайных string вместо number в регистрах микроконтроллера.
  • Современный синтаксис — async/await, дженерики, интерфейсы. Код становится самодокументируемым.
  • Экосистема npm — тысячи библиотек, которые можно адаптировать под железо.
  • Безопасность типов — вы точно знаете, что передаете в функцию setPin(17, HIGH), а не setPin("17", true).

Конечно, TypeScript не заменит C для высоконагруженных систем реального времени. Но для IoT-датчиков, умных лампочек, метеостанций и прототипов — это идеальный выбор.

Инструментарий: что нужно для старта

Чтобы писать на TypeScript под железо, нам понадобится среда выполнения, которая умеет интерпретировать JavaScript на микроконтроллере. Самые популярные варианты:

  • JerryScript — легковесный JS-движок от Samsung. Занимает ~1 МБ Flash.
  • Espruino — специализированная прошивка для STM32 и ESP32. Поддерживает TypeScript через транспиляцию.
  • Moddable SDK — мощный фреймворк для IoT с поддержкой TypeScript "из коробки".

Мы будем использовать Espruino на плате ESP32 (или Raspberry Pi Pico с прошивкой Espruino). Это самый простой способ попробовать TypeScript в embedded без паяльника и даташитов.

Установка и настройка

  1. Скачайте прошивку Espruino для вашей платы с официального сайта.
  2. Прошейте плату через USB (используйте утилиту esptool для ESP32).
  3. Установите Node.js и npm, если еще не установлены.
  4. Установите espruino-cli глобально: npm install -g espruino-cli.
  5. Создайте проект: mkdir my-embedded-ts && cd my-embedded-ts && npm init -y.
  6. Установите TypeScript: npm install --save-dev typescript @types/espruino.

Теперь у вас есть TypeScript-проект, который знает о типах Espruino! Создайте файл tsconfig.json:

{
  "compilerOptions": {
    "target": "ES2015",
    "module": "commonjs",
    "strict": true,
    "outDir": "./dist",
    "rootDir": "./src",
    "types": ["espruino"]
  },
  "include": ["src/**/*"]
}

Пишем первый код: мигаем светодиодом

Классика embedded — "Hello World" в виде мигающего светодиода. Создадим файл src/blink.ts:

import { Pin, setInterval } from 'espruino';

// Интерфейс для конфигурации пина
interface LedConfig {
    pin: number;
    interval: number;
}

// Функция инициализации светодиода
function setupLed(config: LedConfig): Pin {
    const led = new Pin(config.pin);
    led.mode('output');
    return led;
}

// Функция для переключения состояния
function toggleLed(led: Pin): void {
    const currentState = led.read();
    led.write(currentState === 0 ? 1 : 0);
}

// Главная функция приложения
function main(): void {
    const ledConfig: LedConfig = {
        pin: 2,        // GPIO2 на ESP32 — обычно встроенный LED
        interval: 500  // мигаем каждые 500 мс
    };

    const led = setupLed(ledConfig);
    
    console.log('LED initialized on pin', ledConfig.pin);
    
    // Устанавливаем интервал
    setInterval(() => {
        toggleLed(led);
    }, ledConfig.interval);
}

// Запускаем
main();

Теперь скомпилируем TypeScript в JavaScript: npx tsc. В папке dist появится blink.js. Загрузим его на плату:

espruino-cli --board ESP32 --port /dev/ttyUSB0 dist/blink.js

Светодиод на GPIO2 начнет мигать. Поздравляю, вы только что написали embedded-программу на TypeScript!

Работа с датчиками: I2C и TypeScript

Мигать светодиодом — весело, но давайте подключим реальный датчик, например, BME280 (температура, влажность, давление). Работаем через шину I2C. TypeScript с его типизацией идеально подходит для работы с регистрами.

Подключение датчика

Создадим файл src/bme280.ts:

import { I2C, Pin } from 'espruino';

// Типы для данных с датчика
interface SensorData {
    temperature: number;
    humidity: number;
    pressure: number;
}

// Адреса регистров BME280
const REGISTERS = {
    CHIP_ID: 0xD0,
    RESET: 0xE0,
    CTRL_HUM: 0xF2,
    CTRL_MEAS: 0xF4,
    CONFIG: 0xF5,
    PRESS_MSB: 0xF7,
    TEMP_MSB: 0x                

Блоги

Рекомендаций по книгам