Есть классический путь начинающего embedded-разработчика: взять Arduino (плата для прототипирования с микроконтроллером), подключить датчик через I2C, написать 30 строк кода, порадоваться результату. Потом взять микроконтроллер ESP32 — чуть мощнее, Wi-Fi из коробки, уже интереснее. А потом наступает момент, когда задача требует полноценного TCP/IP-стека, SSH-доступа, записи данных в базу, отладки через gdb (GNU Debugger, отладчик в Linux) и еще пяти вещей, для которых на микроконтроллере нужно написать половину ОС.

Вот тут и появляется вопрос: а что если взять одноплатный Linux-компьютер и моделировать на нем также, как на Arduino — паяльник (или готовая разводка), плата-монтажка, модули на штырьках? Вот для таких развлечений отлично подходит наш однопланик Napi-С с штырьками c шагом 2.54мм. Основная идея в том, что на нем легко делать как конечные устройства, так и прототипы для своих теорий. Имея уже на борту сеть и USB, можно с ножек (GPIO) «забирать» интерфейсы (UART, I2C, SPI) и строить свои устройства. Кроме того, имея в ножках второй USB-порт, можно подключить широкий спектр дополнительной периферии (например, второй Ethernet).

Оглавление статьи

  1. Микроконтроллер или Linux-SBC: когда что выбрать для прототипирования

  2. Что такое NAPI-C и почему он со штырьками 2.54 мм

  3. Демонстрационная плата: что и как подключили

  4. Как все выглядит на фото

  5. Учебная плата NapiSci: прототипирование без навесного монтажа

  6. Device Tree Overlay: как включить интерфейс в Linux

  7. I2C: читаем BMP280 (температура, давление, влажность)

  8. SPI2: читаем MAX6675 (термопара, до +1024°C)

  9. GPIO: реле, светодиоды, кнопки

  10. Что в итоге

Микроконтроллер или Linux-SBC: когда что выбрать для прототипирования

Начну с дисклеймера — у обоих подходов в работе с прототипированием есть своя ниша. Микроконтроллер (далее для краткости «МК») незаменим там, где нужен детерминированный real-time отклик, минимальное потребление или ценник $3 за штуку. Linux-платформа выигрывает там, где нужны сеть, файловая система, готовые драйверы для тысяч устройств и возможность отладки мощными инструментами.

Рис. 1. МК vs Linux-SBC: сравнение по ключевым параметрам
Рис. 1. МК vs Linux-SBC: сравнение по ключевым параметрам

Про термин SBC (Single-Board Computer) — одноплатный компьютер. Все компоненты на одной плате: процессор, оперативная память, порты ввода-вывода, сетевой интерфейс. В отличие от обычного ПК, где это отдельные устройства в корпусе. Linux-SBC в контексте статьи просто означает «одноплатник под управлением Linux» в противовес микроконтроллеру, на котором Linux не запускается (или запускается с большими ограничениями). Самый известный пример — Raspberry Pi. Наш NAPI-C — тоже SBC.

Для прототипа, который в итоге должен стать IoT-узлом с выгрузкой данных на сервер, отправкой алертов и удаленным управлением — Linux-платформа сокращает время разработки радикально. Не нужно реализовывать TCP/IP, TLS, MQTT-клиент и файловую систему с нуля. Все это уже есть в ядре и в стандартных пакетах.

Что такое NAPI-C и почему он со штырьками 2.54 мм 

NAPI-C — компактный одноплатный компьютер на процессоре Rockchip RK3308 (ARM Cortex-A35, 4 ядра, до 1.3 ГГц) с предустановленным embedded дистрибутивом NapiLinux предустановленными Telegraf, InfluxDB, mbusd и другими инструментами) или с классическим Armbian\Debian На борту: Ethernet, USB, и главное — GPIO-гребенка с шагом 2.54 мм.

Рис. 2.  Фото NAPI-C — компактного одноплатного компьютера на процессоре Rockchip RK3308
Рис. 2.  Фото NAPI-C — компактного одноплатного компьютера на процессоре Rockchip RK3308

Шаг 2.54 мм — это тот же шаг, что у Arduino, Raspberry Pi и большинства Wemos D1 mini-совместимых модулей. Это значит, что готовые шилды и модули (датчики, реле, дисплеи) встают напрямую — без переходников и без разводки плат.

 Рис. 3. Карта интерфейсов NAPI-C: доступные шины и подключенная периферия
Рис. 3. Карта интерфейсов NAPI-C: доступные шины и подключенная периферия

Доступные интерфейсы:

  • UART — консоль вывода, RS485/RS232, LoRa/Zigbee-модемы

  • I2C — цифровые датчики (BMP280, SHT31, SSD1306 и тысячи других), ЦАП, RTC

  • SPI — датчики температуры, дисплеи, накопители, SD-карты

  • GPIO — реле, светодиоды, кнопки, любая TTL-логика 3.3В

Демонстрационная плата: что и как подключили

Чтобы доказать концепцию живым железом, в NapiLab собрали демонстрационную плату с навесным монтажом. Принцип такой же, как при прототипировании под микроконтроллеры. Это монтажная плата, провода, готовые модули на штырьках. Только вместо Arduino в центре — NAPI-C, вставленный в панельку (чтобы можно было снять и переставить на следующую версию платы).

Состав платы:

  1. UART0 (GPIO2_A0/A1) Стандартная консоль Linux. На плате установлен преобразователь CH340E на USB-C для удобного подключения к ноутбуку.

  2. UART3 (GPIO3_B5/B4) Модуль TTL-RS485. Подключается к Modbus RTU-датчикам. Это тот самый порт, который в предыдущей статье использовался для опроса через Telegraf (ссылка Хабр).

  3. I2C3 (GPIO0_C0 SCL, GPIO0_B7 SDA) Датчик BMP280 — температура, давление, влажность. Подключен не напрямую, а через сменяемую платку в формате Wemos D1 mini. В любой момент можно поменять на другой I2C-модуль, сохранив разводку.

  4. SPI2 (GPIO1_D0 CLK, GPIO1_C6 MISO, GPIO1_C7 MOSI, GPIO1_D1 CS)  Модуль термопары MAX6675K. Измеряет температуру до +1024°C по K-типу. Классика для контроля температуры печей, паяльных станций, промышленных процессов.

  5. GPIO2_B5  Модуль реле (Wemos relay shield). Управляется уровнем TTL 3.3В — один бит в GPIO, и контакты реле замыкаются.

  6. GPIO2_B6, GPIO2_B7, GPIO2_C0  Три светодиода на плате расширения. Для визуальной индикации состояний.

  7. GPIO2_B3  Кнопка с фиксацией. Для чтения входящего сигнала.

    Все модули — в панельках или на штырьках. Снял BMP280, поставил другой I2C-датчик. Снял MAX6675, поставил SPI-дисплей. Разводка остается, меняется только периферия. Именно так и должен работать макет под прототип.

    Видео по проекту:

Как все выглядит на фото

Теперь несколько фото (Рис. 4) собранной платы для иллюстрации нашей статьи. Номера компонентов на фото соответствуют списку в разделе выше. Компонент без номера — платка внешнего питания с кнопкой вкл./выкл., кнопка Reset (слева от компонента №4).

Рис. 4. Фото собранной платы, компонент без номера — платка внешнего питания 
Рис. 4. Фото собранной платы, компонент без номера — платка внешнего питания 

Все элементы на монтажной плате можно «снять» и «одеть». Это мы сделали для того, чтобы, если мы будем делать следующую версию прототипа, перенести эти же элементы на другую версию платы (ведь всегда знаешь, как надо сделать лучше, когда закончил).

Рис. 5. Фото монтажной платы в полуразобранном виде
Рис. 5. Фото монтажной платы в полуразобранном виде
Рис. 6. Фото монтажной платы с обратной стороны
Рис. 6. Фото монтажной платы с обратной стороны

На обратной стороне коммутация элементов выполняется соединительными проводами. Выглядит как лапша у начинающего радиолюбителя, но это не так все страшно, если соблюдать цвета и некоторые приемы при пайке. 

P.S. Этот вариант монтажной платы с таким монтажом проводами интересен как опытный образец для статьи, но в лаборатории мы уже редко его применяем, есть готовая плата для прототипирования NapiSci (о ней ниже), 

Учебная плата NapiSci: прототипирование на PCB

Итак, теперь про NapiSci. Плата, которую мы показали выше, скоммутирована соединительным монтажом — соединения на обратной стороне сделаны вручную, припаянными проводами. Это привычный способ быстро проверить концепцию, но не самый удобный для повторной сборки. Да и любой инженер, работающий с монтажкой на проводах, через пару недель забывает куда какой провод идет. Вообщем, простой, но не самый удобный вариант.

Теперь мы сами используем и предлагаем новую монтажку всем, кто хочет пропустить этап «паяльник и моток проводов» и сразу работать с готовой платформой, — у NapiLab есть готовое решение — учебная плата NapiSci.

Рис. 7. Учебная плата NapiSci
Рис. 7. Учебная плата NapiSci

Идея та же, что у конструкторов на базе Arduino: берешь готовые модули, вставляешь в посадочные места, и система работает. Только в центре не Arduino, а NAPI-C с полноценным Linux. Плата рассчитана на изучение Embedded Linux и прототипирование собственных устройств с датчиками и модулями расширения.

На борту или в виде подключаемых модулей:

  • RTC — модуль часов реального времени, данные не теряются при отключении питания

  • Дисплей SPI — для отображения локальной информации без SSH (здесь стоит на месте №4, если смотреть на фото монтажной платы с соединительными проводами). Скрипт опроса дисплея для NapiSci: https://github.com/lab240/napi-scripts/blob/main/sensors/py/napi_displayonly_demo.py

  • Блок питания 9–36 В — питание от промышленных источников и аккумуляторов

  • Встроенный датчик (опционально)

  • Консоль — модуль USB-UART для отладочного вывода

  • RS485 — для подключения Modbus-датчиков и промышленной периферии

  • Два датчика на шине I2C

  • Светодиоды на GPIO — индикация состояний

  • Магнитное реле на GPIO — коммутация нагрузки

  • Сухое реле на GPIO — гальванически развязанный выход

  • Модуль расширения GPIO — для добавления собственной периферии

Все, что описано далее в этой статье — активация интерфейсов через Device Tree Overlay, работа с I2C, SPI, управление GPIO через gpiod — работает на NapiSci точно так же. Разница только в том, что паяльник для сборки теперь не нужен. 

Device Tree Overlay: как включить интерфейс в Linux

Вот тут главное отличие от Arduino: на микроконтроллере интерфейс работает сразу после инициализации периферии в коде. В Linux интерфейсы (I2C, SPI, UART) описываются в Device Tree — бинарном описании аппаратуры, которое ядро читает при загрузке.

Чтобы включить интерфейс, нужно добавить Device Tree Overlay (DTS-файл с патчем к основному дереву устройств). Звучит сложно, на практике — одна строчка в конфиге. Ниже диаграмма сравнения инициализации интерфейсов в ОС NapiLinux и чистой ARMbian .

Рис. 7. Активация интерфейсов через Device Tree Overlay: NapiLinux и Armbian
Рис. 7. Активация интерфейсов через Device Tree Overlay: NapiLinux и Armbian

В NapiLinux

Открываем /boot/uEnv.txt и добавляем нужные оверлеи:

overlays=rk3308-uart3 rk3308-i2c3-m0 rk3308-spi2-spidev

Сохраняем, перезагружаемся. После перезагрузки появятся устройства:

/dev/i2c-3  ← I2C3 для BMP280
/dev/spidev2.0  ← SPI2 для MAX6675
/dev/ttyS3  ← UART3 для RS485

В Armbian

Для каждого интерфейса создаем DTS-файл и применяем командой:

armbian-add-overlay rk3308-i2c3-m0.dts
armbian-add-overlay rk3308-spi2-spidev.dts

DTS-файлы для стандартных интерфейсов NAPI-C уже готовы и описаны в документации. Самому писать DTS нужно только при нестандартных конфигурациях.

I2C: читаем BMP280 (температура, давление, влажность)

BMP280 — один из самых популярных датчиков в Arduino/ESP32 экосистеме. Bosch выпускает его с 2014 года, и к нему существуют библиотеки под буквально любую платформу. Для Linux есть Python-библиотека от Pimoroni (да, те самые, что делают Hat-шилды для Raspberry Pi).

1.  Убедиться, что устройство видно на шине:

i2cdetect -y 3

BMP280 покажется по адресу 0x76 или 0x77 (зависит от пина SDO). Если адрес виден — датчик подключен правильно.

2.  Установить библиотеку python:

python3 -m pip install pimoroni-bme280

Репозиторий: github.com/pimoroni/bme280-python

3.  Запустить скрипт (шина I2C3, поэтому SMBus(3)):

from smbus2 import SMBus
from bme280 import BME280
bus= SMBus(3)      # I2C3 на NAPI-C
bme280 = BME280(i2c_dev=bus)
while True:
t = bme280.get_temperature()
p = bme280.get_pressure()
h = bme280.get_humidity()
    print(f"{t:05.2f}C  {p:05.2f}hPa  {h:05.2f}%")

Реальный вывод с работающего устройства:

root@napi-armbian:~# python3 bmp280.py
22.00C  965.00hPa  24.76%
22.00C  965.00hPa  24.64%
22.00C  965.00hPa  24.58%

Ключевой момент — номер шины. Это единственное изменение в примере из репозитория.

  • На NAPI-C I2C3 → SMBus(3).

  • На Raspberry Pi обычно SMBus(1).

SPI2: читаем MAX6675 (термопара, до +1024°C)

MAX6675 — специализированный АЦП для термопар типа K. Внутри микросхемы: усилитель холодного спая, 12-битный АЦП, SPI-интерфейс. Диапазон измерений 0..+1024°C с разрешением 0.25°C. Классика для промышленных применений: контроль температуры в печах, паяльных станциях, литьевом производстве.

В Linux SPI-устройства доступны через spidev — символьное устройство /dev/spidev2.0. Читаем напрямую через Python-пакет spidev.

1.  Установить spidev:

apt install python3-dev	# только для Armbian
python3 -m pip install spidev

Репозиторий с примером: github.com/w4r-10rd/max6675-rpi

2.  Скрипт чтения температуры (SPI2, поэтому spi.open(2, 0)):

import spidev, time
 
spi = spidev.SpiDev()
spi.open(2, 0)              # SPI2, CS0
spi.max_speed_hz = 3900000
 
while True:
	t = spi.readbytes(2)
	msb = format(t[0], "#010b")
	lsb = format(t[1], "#010b")
	r_temp  = msb[2:] + lsb[2:]
	t_bytes = "0b" + r_temp[0:13]
	temp	= int(t_bytes, base=2) * 0.25
    print(f"Temperature: {temp:.2f} C")
	time.sleep(2)

Вывод:

root@napi-armbian:~# python3 max6675.py
Temperature: 22.75 C
Temperature: 22.25 C
Temperature: 22.50 C

MAX6675 отдает данные в 16-битном пакете: 12 бит температуры (биты 14..3) и несколько служебных. Скрипт вручную парсит битовое поле. Разрешение 0.25°C — это 2 бита дробной части, отсюда умножение на 0.25.

GPIO: реле, светодиоды, кнопки

GPIO в Linux — тема с историей. Долгое время единственным способом было /sys/class/gpio (sysfs). Потом появился gpiod — современный API с символьными устройствами /dev/gpiochipN. В ядрах 5.x+ sysfs объявлен устаревшим, но работает и сейчас. Покажем оба способа.

Рис. 8. Адресация GPIO: от обозначения в даташите до команды в Linux
Рис. 8. Адресация GPIO: от обозначения в даташите до команды в Linux

Как расшифровать адрес GPIO

В даташите на RK3308 (и в документации NAPI-C) GPIO записываются в нотации GPIOx_Yn, например GPIO2_B5. Расшифровка:

  • x — номер банка GPIO (0..4), соответствует gpiochipX в gpiod

  • Y — группа (A=0, B=8, C=16, D=24)

  • n — номер ножки в группе (0..7)

Для gpiod: номер линии = Y_offset + n. GPIO2_B5 → gpiochip2, линия B(8)+5 = 13.
Для sysfs: номер gpio = x*32 + Y_offset + n. GPIO2_B5 → 2*32+8+5 = 77 → /sys/class/gpio/gpio77.

Управление реле через gpiod (рекомендуется)

Включить реле (GPIO2_B5 = gpiochip2, линия 13):

# gpiod v2+
gpioset -t 0 -c gpiochip2 13=1   # включить
gpioset -t 0 -c gpiochip2 13=0   # выключить
 
# Прочитать текущее состояние
gpioget -a -c gpiochip2 13
"13"=active

В gpiod v1.6.3 команда gpioget сбрасывает состояние GPIO в 0. В v2+ поведение исправлено. NapiLinux поставляется с актуальной версией. Для Armbian\Debian gpiolib2 можно установить из нашего репозитория https://repo.napilab.ru.

Как подключить репоизторий: 

curl -fsSL https://repo.napilab.ru/napilab.gpg | gpg --dearmor | tee /usr/share/keyrings/napilab.gpg > /dev/null
echo "deb [arch=arm64 signed-by=/usr/share/keyrings/napilab.gpg] https://repo.napilab.ru stable main" > /etc/apt/sources.list.d/napilab.list
apt-get update

apt-get purge -y libgpiod2 libgpiod-dev gpiod || true
apt-get install -y mbusd gpiod

Управление светодиодами с миганием

gpiod умеет задавать период переключения прямо из командной строки. Три светодиода с разными частотами:

gpioset -z -t 500ms -c gpiochip2 14=1   # LED1, 2 Гц
gpioset -z -t 200ms -c gpiochip2 15=1   # LED2, 5 Гц
gpioset -z -t 100ms -c gpiochip2 16=1   # LED3, 10 Гц
 
# Процессы работают в фоне
ps ax | grep gpioset

Чтение кнопки через sysfs (универсальный способ)

Sysfs работает без установки дополнительных пакетов:

echo 77 > /sys/class/gpio/export     	# активировать GPIO77 (GPIO2_B5)
cat /sys/class/gpio/gpio77/direction  	# out или in
echo 1 > /sys/class/gpio/gpio77/value 	# установить HIGH
cat /sys/class/gpio/gpio77/value      	# прочитать состояние
echo 77 > /sys/class/gpio/unexport    	# освободить

Сводная таблица GPIO-адресов демо-платы:

GPIO (даташит)

Функция

gpiod

sysfs

GPIO2_B5

Реле

gpiochip2 / 13

gpio77

GPIO2_B6

LED 1

gpiochip2 / 14

gpio78

GPIO2_B7

LED 2

gpiochip2 / 15

gpio79

GPIO2_C0

LED 3

gpiochip2 / 16

gpio80

GPIO2_B3

Кнопка

gpiochip2 / 11

gpio75

Что в итоге

NAPI-C как прототипная платформа закрывает проблему выбора между «я хочу сделать быстро на монтажке» и «мне нужно все это сделать как нормальный сетевой узел». Аналогично модули Wemos D1 mini, тот же подход с навесным монтажом — но получаем полноценный Linux с SSH, Python, gpiod, i2c-tools и spidev.

Главное, что нужно принять к сведению при переходе с МК на Linux-стек:

  1. Интерфейсы включаются через Device Tree Overlay — одна строчка в /boot/uEnv.txt.

  2. I2C работает через /dev/i2c-N, любая Python-библиотека через smbus2.

  3. SPI доступен как /dev/spidevX.Y, читается через пакет spidev.

  4. GPIO управляется через gpiod (gpiochip + номер линии) или sysfs (глобальный номер).

  5. Адресация GPIO: для gpiod — Y_offset+n, для sysfs — x*32+Y_offset+n.

Весь код, что показан в статье, взят из реально работающей демонстрационной платы с фото и видео, которые в статье.  

Хелпы и репозитории

Если будут вопросы по статье, реализациям или требуется дополнительная информация, просьба писать мне на почту или в ЛС. 

Комментарии (5)


  1. nipper
    22.07.2026 10:30

    Это Rock Pi S с новым шильдиком?


  1. SysManOne
    22.07.2026 10:30

    Ох уж эти отсталости с AT-командами на UART. Ну я понимаю, если это для Кулибиных на дачах, но с точки зрения эффективности это - не серьёзно.


  1. yudelex
    22.07.2026 10:30

    Макетка с модулями нормально работала с таким "волосатыми" соединениями?)


  1. SysManOne
    22.07.2026 10:30

    Кстати, куда-то потерялись LoRa и ZigBee .


  1. kpmy
    22.07.2026 10:30

    Готовые оверлеи под всё подряд не напишете, устройств ведь много. Пока читал статью, вспоминал, с чем столкнулся, пока пытался запустить на OrangePi Zero 2W шину CAN через самый популярный модуль c маркетплейсов. В итоге оказалось, что всё действительно "в одну строчку" делается только на Raspberry Pi в самых популярных вариантах (у которых одинаковая GPIO 40 pin колодка).

    Это уже потом я понял, что кесарю кесарево, и разместил там рядом ESP32. Если мне не изменяет память, это и есть способ, которым добавили GPIO на RPi 5, через Pico на плате.

    P.S. Ну и к неймингу вопрос, по-русски Napi-C звучит не очень.