[поновлюється] побачив і не зміг втриматися — тепер маю нову цікаву електронну забавку: arduino oplà iot kit. набір включає контролер arduino mkr wifi 1010 і монтажну плату arduino mkr iot carrier з кольоровим екраном, сенсорними кнопками та датчиками температури, вологості й тиску тощо; і все це програмується. попередній власник награвся та виставив на барахольці kijiji, — тож… я поки що відклав конструктор freenove, щоби погратися цим.

набір arduino mkr iot

зміст

tl;dr

я лише зовсім трішечки погрався з arduino oplà iot, — але вже в захваті! надзвичайно класний набір: якісно зроблений, цікавий, чудово інтегрований (багато різних елементів і датчиків), і з великою кількістю якісної документації. на мою думку, це чудовий спосіб погратися і навчитися програмувати! ціна трохи кусається на перший погляд, особливо на amazon’і… але набір вартий чесної ціни на arduino.cc!

підготовка

що в наборі

мені продали коробку б/у, але з усіма компонентами:

оскільки я взяв б/у, все було вже розпаковане, плати з’єднано й у корпусі. на додачу, я отримав два акумулятори формату 18650 на 3000 мАг і простенький зарядний пристрій (треба розібрати й полагодити підпружинений тримач). за ті гроші, що я віддав — це королівський набір.

(повернутися до змісту)

налаштування arduino ide

новий набір oplà iot дає рік безкоштовного доступу до arduino cloud, проте попередній власник цей час вже вибрав. як на мене, то й на краще: не люблю, коли виробники намагаються мене «залочити» на свої хмарні сервіси безкоштовним пончиком. тож питання вибору середовища навіть не постало — arduino ide на лептопі. я вже трохи з ним знайомий, ще з часів збирання «марсохода». версія 1.8.19 (legacy) була в aur, тож швиденько встановилася (команди для arch linux та похідних; для інших дистрибутивів буде інше, для windows чи mac — див. веб-сайт arduino.cc):

> pamac install arduino

далі — завантаження необхідних компонентів ide (core, бібліотеки) для arduino mkr wifi 1010 та arduino mkr iot carrier:

важливо! на linux, перш ніж можна буде залити тестову програму через usb на контролер, треба додати себе до групи uucp (і перезайти в профіль, або зробити su $USER і запускати arduino з консолі):

> sudo usermod -a -G uucp $USER

тепер можна пробувати «залити» найпростіший код для перевірки світлодіода, як пише підказка на офіційному сайті, але це не дуже цікаво… а ще мені конче треба було якнайшвидше перевірити, чи працює екран. тож…

(повернутися до змісту)

перевірка: hello, world

отже, перша, найпростіша програма — класичний «hello, world» (але на український манер):

#include <Arduino_MKRIoTCarrier.h>
MKRIoTCarrier carrier;                          // Об'єкт класу MKRIoTCarrier

void setup() {
  carrier.noCase();                             // Без корпуса (
  carrier.begin();                              // Ініціалізація монтажної плати

  // Перевірка екрана
  carrier.display.setRotation(0);               // Нормальна орієнтація
  carrier.display.fillScreen(ST77XX_RED);       // Червоне тло
  carrier.display.setTextColor(ST77XX_WHITE);   // Білий текст
  carrier.display.setTextSize(4);               // Великий шрифт
  carrier.display.setCursor(40, 110);           // Позиція для виводу (пікс.)
  carrier.display.print("PTN XLO");             // Український Hello, world =)

  // Перевірка зумера
  carrier.Buzzer.sound(500);                    // Частота зумера 500 Гц
  delay(100);                                   // Тривалість 100 мс
  carrier.Buzzer.noSound();                     // Відкл. зумер
}

void loop() {
  // 
  delay(1000);
}

hello, world! по-українському

(повернутися до змісту)

знайомство з arduino mkr iot carrier

екран

екран працює, що далі? найперше, я спробував навчитися вимикати екран, і це окрема цікава історія, що привела до вимірювання енергоспоживання набору arduino mkr iot за допомогою несправного мультиметра та кількох цікавих висновків. функція для вимикання/вмикання підсвітки екрана arduino mkr iot carrier може виглядати приблизно так:

# include <Arduino_MRKoTCarrier.h>
…
// керування підсвіткою екрана (true/false)
void backlight(boolean state) {
  pinMode(TFT_BACKLIGHT, OUTPUT);
  if (state) {
    digitalWrite(TFT_BACKLIGHT, HIGH);
  } else {
    digitalWrite(TFT_BACKLIGHT, LOW);
  }
}

цікаво, що коротка підказка з використання бібліотеки згадує TFT_BLACKLIGHT — ніхто не виправляє, хоча їхній код не працює і люди, ймовірно, перечіпляються через це?

далі — кольори; простенька самописна функція colorTest() виводить кольорову «шахівницю» довільного розміру, заповнюючи клітинки випадковими кольорами:

// випробування кольорів: кольорова гратка divX x divY з автоматичним обрахуванням кольорів
void colorTest(int divX, int divY) {
    int boxX = int(carrier.display.width() / divX);   // Розміри кольорових прямокутничків
    int boxY = int(carrier.display.height() / divY);  // розраховуються з кількості по x, y
    for (int y = 0; y < divY; y++) {
        for (int x = 0; x < divX; x++) {
          // Колір в бібліотеці Adafruit_ST7735 має тип uint16_t: rgb (5, 6, 5 біт) запаковані в 16 біт
          uint16_t color = random(0xFFFF);            // Випадковий колір
          carrier.display.fillRect(x*boxX, y*boxY, boxX, boxY, color);
        }
    }
}

кольори для екрану adafruit st77xx кодуються трохи незвично (ну, якщо не знати, що таке high color): по 5 біт на червоний та синій, 6 біт на зелений, запаковані в 16 біт. генерування випадкового кольору (тобто числа в діапазоні 0x0..0xFFFF) — це просто, але навряд чи дуже корисно. якщо потрібен якийсь конкретний колір, можна підглянути до невеликого переліку визначених кольорів (ST77XX_), або знайти значно довший перелік. але що як треба вивести конкретну тріаду rgb? в глибинах бібліотеки знайшлася функція color565() якраз для цього; з нею можна замість готової функції для малювання гратки написати іншу, котра малюватиме один блок «шахівниці» визначеним кольором:

// Конвертування кольорів RGB до 565: в кольоровій гратці замалювати прямокутник i,j кольором r,g,b)
void colorBlock(int divX, int divY, int i, int j, uint8_t r, uint8_t g, uint8_t b) {
   int boxX = int(carrier.display.width() / divX);      // Розмір блока по горизонталі
   int boxY = int(carrier.display.height() / divY);     // …по вертикалі
   uint16_t color = carrier.display.color565(r, g, b);  // Конвертування кольору rgb -> high color 565 
   carrier.display.fillRect(i*boxX, j*boxY, boxX, boxY, color);
}

тепер головний цикл для малювання «шахівниці» й випадкового перефарбовування «клітинок» може бути такий:

// Головний цикл (обов'язкове)
void loop() {
    int sizeX = 5, sizeY = 5;
    for (int y = 0; y < sizeY; y++) {               // Малюємо шахівницю 5x5
        for (int x = 0; x < sizeX; x++) {           // …випадковими кольорами
            colorBlock(sizeX, sizeY, x, y, random(255), random(255), random(255));
        }
    }
    while (true) {                                  // Перемальовуємо випадкову клітинку
        colorBlock(sizeX, sizeY, random(sizeX), random(sizeY), random(255), random(255), random(255));
        delay(1000);
    } 
}

далі буде…