
Hari ini kita akan berbicara tentang topik yang relevan seperti timer dan multitasking di Arduino. Alasan penulisan artikel ini adalah ceramah oleh
Oleg Artamonov @olartamonov untuk siswa
MIREA dalam
Samsung IoT Academy , atau lebih tepatnya, pernyataan Oleg, kutipan (kuliah kedua, 1:13:08):
"Ada, misalnya, tugas yang sebagian besar driver Arduino, terutama pemula, dapat dipatahkan, meminta mereka untuk berkedip dengan lima LED berbeda dengan frekuensi dan periode berbeda, dan sehingga periode lain dapat diubah secara individual untuk setiap LED ..."
Menilai oleh pernyataan Oleg, ia memiliki kesalahpahaman yang sangat tentang Arduino secara umum dan tentang "arduino" pada khususnya. Berkedip dengan lima LED dalam mode yang ditunjukkan olehnya adalah tugas yang benar-benar sepele untuk Arduino, dan untuk
Arduino Mega Server itu bukan tugas sama sekali, tetapi kesalahpahaman yang nyata - multitasking diatur dengan cara biasa, yang dengan mudah mengontrol ratusan entitas yang berbeda (LED, servos, motor langkah, dll.). d.) secara real time.
Mari kita
cari tahu bagaimana mengatur multitasking pada Arduino bersama-sama, dan pada saat yang sama membantu siswa
MIREA menyingkirkan stereotip persepsi yang dipaksakan kepada mereka sehubungan dengan fenomena sosio-budaya dan teknologi pada zaman kita yang disebut
Arduino .
Kuliah oleh Oleg Artamonov
Kita harus memberi penghargaan,
kuliah Oleg sendiri bagus - mereka memberikan banyak informasi yang berguna dan terstruktur dengan baik tentang mikrokontroler, dan saya akan merekomendasikan agar semua orang yang tertarik dengan masalah ini membiasakan diri dengan mereka. Satu-satunya kelemahan dari ceramah-ceramah ini bagi saya nampak seperti techno-snobbery mengenai Arduino, yang bertindak sebagai "anak lelaki cambuk".
Secara khusus, sepanjang semua kuliah, Oleg membuat pernyataan tegas tentang ketidakcocokan Arduino untuk membangun sistem multi-tasking yang kompleks, yang hanya bertentangan dengan kebenaran dan praktik nyata.
Di Arduino, Anda dapat membuat sistem multi-tasking yang menakjubkan di mana puluhan dan ratusan entitas (LED, sensor, aktuator, servos, motor stepper, antarmuka nirkabel dan kabel, dll.) Bekerja secara bersamaan dalam mode multitasking (semu, alami).
Kami tidak akan pergi jauh untuk contoh. Berikut adalah proyek
Winter Garden ("Smart Greenhouse") di mana entitas berikut bekerja secara real time dalam mode multitasking:
Topologi pengendali nRF24 terdistribusi dengan sejumlah besar peralatan yang terhubung dan real-time. Pengguna hanya berurusan dengan "basis", pekerjaan mitra nRF24 sepenuhnya transparan baginya. Dan, ya, ini Arduino.Di "markas":
- 7 servos
- 9 motor stepper
- 6 relay
- 3 sensor kelembaban tanah
- 2 sensor cahaya
- sensor ketinggian air
- Kelembaban dan sensor suhu udara
Pada nRF24 dari bagian jarak jauh:
- 12 sensor kelembaban tanah
- 12 relay
- 3 motor stepper
- 2 sensor cahaya
- sensor ketinggian air
Selain itu, secara real time, nRF24 sendiri beroperasi di antara dua bagian sistem yang terdistribusi dan antarmuka Ethernet dari server dan mesin server, yang menyediakan antarmuka pengguna sistem.
Secara total, secara real time, dalam mode multitasking, setidaknya 60 entitas berfungsi pada Mega 8-bit (dan ini tidak termasuk banyak layanan dari sistem operasi AMS itu sendiri, dengan mereka jumlah entitas akan mendekati seratus). Yang jelas tidak setuju dengan pernyataan bahwa "multitasking nyata tidak mungkin dilakukan pada Arduino dan bermasalah untuk berkedip bahkan dengan lima LED di dalamnya".
Beberapa kata untuk membela Arduino
(Meskipun jelas bahwa Arduino sebagai fenomena sosial-budaya dan teknologi dengan jutaan pasukan penggemar dan ribuan proyek luar biasa tidak membutuhkan perlindungan.)
Saya telah mengatakan berulang kali dan akan mengulangi sekali lagi bahwa Arduino dalam komponen perangkat lunaknya, pada kenyataannya, hanyalah salah satu dari tingkat abstraksi yang mungkin (seperti yang lain) dengan kelebihan dan kekurangannya sendiri. Dan sama sekali tidak ada perbedaan bagi pengguna apa yang "berputar" di dalam sepotong kecil silikon - "murni" Arduino, RTOS, RIOT OS, AMS atau abstraksi matematis lainnya tentang representasi dan pengelolaan sumber daya besi pengontrol.
Penting bagi pengguna untuk menyelesaikan masalahnya - bagi pengontrol untuk menyirami tanaman, menyalakan lampu, mengontrol tirai, dll. Dan masalah utama bukan pada alat yang digunakan dalam pengembangan, tetapi dalam kemampuan untuk menggunakannya dan, norak, dalam imajinasi dan visi rekayasa pengembang sendiri.
Bagaimana cara kerjanya?
Dengan sendirinya, multitasking pada mikrokontroler dapat diatur dengan cara yang berbeda, dalam hal ini kita akan berbicara tentang yang paling sederhana - proses bergiliran dalam kendali dan secara sukarela memberikannya setelah menggunakan kuantum waktu mereka. Metode ini, tentu saja, bukan tanpa cacat yang jelas, tetapi, seperti yang mereka katakan, praktik adalah kriteria kebenaran dan telah membuktikan dirinya dalam kondisi nyata: digunakan baik dalam distribusi standar
Arduino Mega Server dan dalam banyak proyek di
AMS Pro . Dan sistem ini bekerja 24/7 dan telah mengkonfirmasi uptime dalam berbulan-bulan operasi bebas masalah.
Ini merupakan indikasi dari sekitar seratus entitas dari sistem nRF24 terdistribusi, yang dikelola secara mandiri dalam waktu nyata. Perhatikan dua indikator CPU terakhir - bahkan pada Mega 8-bit, beban prosesor adalah nol (artinya, sistem ini benar-benar gratis).Sedikit tentang timer
Untuk mengatur kontrol sistem yang kompleks, tidak cukup hanya mentransfer kontrol antara proses pada gilirannya dan, bersama dengan transfer kontrol otomatis ke AMS, berbagai jenis timer digunakan: siklik, siklik dengan sejumlah pengulangan (batch), tunggal, acak, campuran, dll. Semua ini diatur cara asli Arduino dan tidak menggunakan interupsi atau pemrograman langsung dari pengatur waktu mikrokontroler (tetapi interupsi, tentu saja, digunakan oleh sistem “untuk tujuan yang dimaksudkan”).
Yang lagi secara langsung bertentangan dengan pernyataan: "Akan ada cukup timer besi untuk 3 LED, sejak saat itu, arduinists akan memiliki masalah." Jangan mulai. Semua jenis timer tersedia untuk kami dalam jumlah berapa pun. Dan, jika diinginkan, kita dapat membuat diri kita sendiri lebih baru dan semaunya eksotis.
Kasus utama
Kasus utama untuk jenis organisasi multitasking ini adalah membuat kode yang disebut "non-blocking", yaitu kode yang tidak menggunakan fungsi delay (), yang hanya menjeda program untuk waktu tertentu.
Waktu nyata
Metode yang dijelaskan untuk menerapkan multitasking dapat digambarkan sebagai "soft-realtime", waktu tunda khas dalam sistem adalah 10 ms (tetapi penundaan puncak bisa lebih lama dan tidak standar). Ini memberlakukan batasan yang terkenal pada spektrum penerapan solusi ini, tetapi untuk sebagian besar tugas "rumah tangga" (dan tidak hanya) sangat cocok, lihat contoh di atas.
Jika Anda memerlukan kontrol dalam waktu nyata yang lebih ketat, maka ini memerlukan optimisasi khusus kode untuk tugas tertentu, merestrukturisasi arsitektur atau, dalam kasus yang sangat ekstrim, mengalokasikan pengontrol terpisah untuk fungsi tertentu. Sebagai contoh, menyoroti
pengontrol efek
terpisah untuk strip LED cerdas.
Ini adalah deskripsi teoretis umum tentang pekerjaan multitasking di Arduino secara umum dan di AMS khususnya, sekarang kita beralih ke pertimbangan contoh-contoh praktis.
Pengatur waktu siklus

Pertimbangkan penerapan pengatur waktu siklik yang paling sederhana. Ini adalah timer (dalam terminologi "siklus" AMS), yang diaktifkan pada interval waktu tertentu yang telah ditentukan dan digunakan untuk mengaktifkan proses siklik.
Secara umum, lebih baik untuk merancang penghitung waktu pemrograman sebagai objek, tetapi dalam pengiriman standar Arduino Mega Server penghitung waktu ini diterapkan sebagai fungsi, oleh karena itu, sebagai permulaan, kami akan mempertimbangkannya dalam hipostasis ini.
Menggunakan pengatur waktu siklik sangat sederhana: cukup masukkan kode yang perlu dijalankan secara berkala di antara tanda kurung pernyataan if. Jika Anda perlu menggunakan interval pemicu yang berbeda, maka gunakan saja variabel yang diinginkan, bukan cycle1s. Anda dapat membuat sebanyak mungkin siklus yang berbeda - sistem bahkan pada Mega 8-bit dapat dengan mudah menangani ratusan timer seperti itu (hanya, tentu saja, Anda perlu mengingat bahwa kode yang dipanggil tidak memblokir).
if (cycle1s) {
// , , ,
}
. :
// Cycles
bool cycle1s = false;
bool cycle5s = false;
bool cycle20s = false;
bool cycle30s = false;
bool cycle1m = false;
bool cycle3m = false;
bool cycle5m = false;
.
«Timers»:
/*
Module Timers
part of Arduino Mega Server project
*/
// Cycles
unsigned long timeSec;
unsigned long timer1s;
unsigned long timer5s;
unsigned long timer20s;
unsigned long timer30s;
unsigned long timer1m;
unsigned long timer3m;
unsigned long timer5m;
void timersInit() {
unsigned long uptimeSec = millis() / 1000;
timeSec = uptimeSec;
timer1s = uptimeSec;
timer5s = uptimeSec;
timer20s = uptimeSec;
timer30s = uptimeSec;
timer1m = uptimeSec;
timer3m = uptimeSec;
timer5m = uptimeSec;
}
void timersWorks() {
timeSec = millis() / 1000;
if (timeSec - timer1s >= 1) {
timer1s = timeSec; cycle1s = true;
if (timeSec - timer5s >= 5) {timer5s = timeSec; cycle5s = true;}
if (timeSec - timer20s >= 20) {timer20s = timeSec; cycle20s = true;}
if (timeSec - timer30s >= 30) {timer30s = timeSec; cycle30s = true;}
if (timeSec - timer1m >= 60) {timer1m = timeSec; cycle1m = true;}
if (timeSec - timer3m >= 180) {timer3m = timeSec; cycle3m = true;}
if (timeSec - timer5m >= 300) {timer5m = timeSec; cycle5m = true;}
}
}
void eraseCycles() {
cycle1s = false;
cycle5s = false;
cycle20s = false;
cycle30s = false;
cycle1m = false;
cycle3m = false;
cycle5m = false;
}
. - , . , , .
void loop() {
timersWorks();
//
eraseCycles();
}
, , . myCycle.
, :
/*
myCycle Library
part of Arduino Mega Server project
*/
#ifndef _MYCYCLE_H
#define _MYCYCLE_H
#define MS_500 500
#define MS_01S 1000
#define MS_02S 2000
#define MS_05S 5000
#define MS_10S 10000
#define MS_13S 13000
#define MS_17S 17000
#define MS_20S 20000
#define MS_30S 30000
#define MS_01M 60000
#define MS_03M 180000
#define MS_05M 300000
#define MS_01H 3600000
#define MS_06H 21600000
#define MS_12H 43200000
#define MS_01D 86400000
class myCycle {
private:
bool _go;
bool _active;
unsigned long _start;
unsigned long _period;
public:
myCycle(unsigned long per, bool act);
void reInit(unsigned long per, bool act);
void reStart();
bool check();
bool go();
void clear();
// active
bool active();
void setActive(bool act);
// period
unsigned long period();
void setPeriod(unsigned long per);
}; // class myCycle
#endif // _MYCYCLE_H
:
/*
myCycle Library
part of Arduino Mega Server project
*/
#include "myCycle.h"
#include <Arduino.h>
myCycle::myCycle(unsigned long per, bool act) {
_go = false;
_active = act;
_period = per;
_start = millis();
}
// Methods
void myCycle::reInit(unsigned long per, bool act) {
_go = false;
_active = act;
_period = per;
_start = millis();
}
void myCycle::reStart() {
_start = millis();
}
bool myCycle::check() {
if (millis() - _start >= _period) {
_start = millis();
if (_active) {
_go = true;
}
}
return _go;
}
bool myCycle::go() {
return _go;
}
void myCycle::clear() {
_go = false;
}
// Active
bool myCycle::active() {
return _active;
}
void myCycle::setActive(bool act) {
_active = act;
}
// Period
unsigned long myCycle::period() {
return _period;
}
void myCycle::setPeriod(unsigned long per) {
_period = per;
}
«» : « ».
:
:
#include "myCycle.h"
:
// Cycles
myCycle cycle500(MS_500, true);
myCycle cycle2s(MS_02S, true);
myCycle cycle5s(MS_05S, true);
:
void timersWorks() {
cycle500.check();
cycle2s.check();
cycle5s.check();
}
void eraseCycles() {
cycle500.clear();
cycle2s.clear();
cycle5s.clear();
}
:
void loop() {
timersWorks();
//
if (cycle5s.go()) {
Serial.println(F("cycle5s!"));
}
eraseCycles();
}
, , . , / , , , .
Arduino

, — . , . , AMS .
()
, . , 3 nRF24. 3 .
/ . .
«», - - .
- , , .
, , . , , , 20 , «», «» , . , «» .
, . — Arduino Mega Server .
, , / , « » . .
— , 8- .
, , Arduino - — — , .
, Arduino Mega Server .
, , Arduino , , , Arduino () .
, , .
P.S.,
0.17 Arduino Mega Server Arduino Mega, Due, 101 M0,
. , , .