База знаний · Примеры и обучение

Раздел «Полезное»: 20 готовых заготовок

Диагностика и рабочие приёмы без внешних библиотек: от сканера I2C до многозадачности.

«09. Полезное» — особый раздел: не учебные упражнения, а двадцать готовых заготовок и диагностических скетчей, которые пригождаются в реальных проектах. Всё — на чистом встроенном языке, без единой внешней библиотеки: работает на любой плате сразу.

Диагностика: скетчи-помощники

  • I2C_Scanner — ищет устройства на шине I²C и печатает их адреса: первый вопрос при подключении любого дисплея или датчика («а какой у него адрес?») закрыт.
  • PinButtonTester / PinSnapshot — проверка пинов и снимок их состояний: «живой ли вход?» выясняется за минуту.
  • ResetReason — почему плата перезагрузилась: детектив для загадочных рестартов.
  • PlotterDemoSignals / PlotterAnalogInputs — сигналы для графика: освоить плоттер, даже когда датчиков под рукой нет.

Заготовки: приёмы для взрослых проектов

  • MultiTasking — несколько дел без delay(): каркас почти любого серьёзного устройства.
  • DoAfterDelay / BlinkNTimes — «сделай через N мс» и «мигни N раз» без блокировок.
  • ButtonGestures — короткое, длинное, двойное нажатие одной кнопки: три команды из одной клавиши.
  • MedianFilter / Hysteresis — чистим шумные датчики и лечим «дребезг порога» у автоматики.
  • MenuInMonitor / SerialCommandControl — меню и командное управление через монитор: интерфейс без экрана.
  • RememberSetting — настройка, переживающая выключение питания.
Раздел «09. Полезное» в примерах Trema IDE: 20 готовых заготовок
Двадцать заготовок одним экраном: сканер шины, тестер сервопривода, многозадачность и другие.

Чтобы было понятно, о каком уровне речь, — вот целиком «I2C_Scanner», самый вызываемый скетч раздела. Он опрашивает все 127 адресов шины и говорит, кто отозвался:

#include <Wire.h>  // библиотека шины I2C — она уже внутри ядра

void setup() {
  Wire.begin();
  Serial.begin(9600);
  Serial.println("Ищу устройства на шине I2C...");

  int found = 0;
  for (byte address = 1; address < 127; address++) {
    Wire.beginTransmission(address);
    // endTransmission вернёт 0, если по этому адресу кто-то ответил.
    if (Wire.endTransmission() == 0) {
      Serial.print("Найдено устройство по адресу 0x");
      Serial.println(address, HEX);
      found++;
    }
  }

  if (found == 0) {
    Serial.println("Никто не ответил — проверьте провода SDA и SCL");
  }
}

void loop() {
}

Пять минут гадания «датчик сломан или провода?» сокращаются до одной прошивки.

А это «MultiTasking» — заготовка приёма, а не работа с железом: плата делает два дела сразу, потому что нигде не останавливается.

unsigned long ledTimer = 0;
unsigned long printTimer = 0;
bool ledOn = false;

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  unsigned long now = millis();

  // Дело первое: мигать раз в 200 мс.
  if (now - ledTimer >= 200) {
    ledTimer = now;
    ledOn = !ledOn;
    digitalWrite(LED_BUILTIN, ledOn ? HIGH : LOW);
  }

  // Дело второе: печатать раз в секунду. Оба дела идут «одновременно»,
  // потому что программа нигде не останавливается.
  if (now - printTimer >= 1000) {
    printTimer = now;
    Serial.print("Работаю ");
    Serial.print(now / 1000);
    Serial.println(" с");
  }
}

Третий характерный житель раздела — «RememberSetting»: настройка переживает выключение питания, потому что лежит в постоянной памяти платы.

#include <EEPROM.h>  // память, которая переживает выключение

const int ADDRESS = 0;  // ячейка, где храним настройку
byte brightness = 0;

void setup() {
  Serial.begin(9600);

  // Читаем сохранённое значение при включении.
  brightness = EEPROM.read(ADDRESS);
  Serial.print("Запомненная яркость: ");
  Serial.println(brightness);

  brightness = brightness + 10;
  if (brightness > 250) {
    brightness = 0;
  }

  // update пишет только если значение изменилось — бережёт ресурс памяти.
  EEPROM.update(ADDRESS, brightness);
  Serial.print("Новая яркость сохранена: ");
  Serial.println(brightness);
}

void loop() {
}

Как пользоваться

Как ящиком с инструментами: столкнулись с задачей — загляните, нет ли готового приёма. Шумит датчик — MedianFilter; нужно три действия с одной кнопки — ButtonGestures; не находится дисплей — I2C_Scanner. Копируйте кусками в свои проекты — для того и написано, с русскими комментариями к каждой строке.

Обновлено: 19 июля 2026