Bangun Jam Digital Arduino dengan Mesin Status Terbatas
Komponen dan Perlengkapan
Arduino UNO – 1 unit (setiap Arduino kompatibel dengan LCD Shield dapat digunakan; penulis menggunakan Arduino Mega)
LCD Keypad Shield – 1 unit
Aplikasi dan Layanan Online
YAKINDU Statechart Tools (gratis untuk penggunaan non-komersial)
Eclipse C++ IDE untuk Arduino
Tentang Proyek
Halo, saya akan menunjukkan bagaimana jam digital dapat dibuat dengan YAKINDU Statechart Tools dan dijalankan pada Arduino yang menggunakan LCD Keypad Shield.
Model asli jam digital diambil dari David Harel. Dia telah menerbitkan makalah tentang "perluasan luas formalisme konvensional dari mesin status dan diagram status."
Dalam makalah tersebut, ia menggunakan contoh jam digital untuk penelitiannya. Saya menggunakannya sebagai inspirasi dan membangun kembali jam dengan YAKINDU Statechart Tools (alat untuk membuat model grafis mesin status dan menghasilkan kode C/C++ dengannya) dan menghidupkannya kembali pada Arduino.
Cara Kerja Jam Digital
Mari kita mulai dengan menentukan bagaimana jam digital seharusnya bekerja. Apakah Anda ingat jam digital "ultra keren" yang semua orang miliki pada tahun 90? Jam dengan stopwatch terintegrasi, alarm yang berbeda, dan bunyi setiap jam penuh. Jika tidak, lihat contoh jam digital tahun 90.
Jadi, dasarnya ini adalah jam yang dapat dikonfigurasi dengan berbagai mode. Utamanya, waktu saat ini akan ditampilkan, tetapi ada beberapa fitur lain. Sebagai input, Anda memiliki tombol on/off, tombol mode, dan tombol set. Selain itu, Anda dapat menyalakan dan mematikan lampu.
Dengan tombol mode Anda dapat membedakan antara mode dan mengaktifkan/menonaktifkan fitur jam:
Tampilkan waktu (Jam)
Tampilkan tanggal (Tanggal)
Atur alarm (Alarm 1, Alarm 2)
Aktifkan/nonaktifkan bunyi (Set Chime)
Gunakan stopwatch (Stop Watch)
Dalam menu, Anda dapat menggunakan tombol on/off untuk mengonfigurasi mode. Tombol set memungkinkan Anda untuk mengatur waktu, misalnya untuk jam atau alarm. Stopwatch dapat dikontrol – dimulai dan dihentikan – dengan menggunakan tombol lampu menyala dan lampu mati. Anda juga dapat menggunakan penghitung putaran terintegrasi.
Selain itu, ada bunyi yang berbunyi setiap jam penuh, dan lampu latar belakang yang dapat dikontrol terintegrasi. Pada langkah pertama, saya tidak mencabutnya ke Arduino.
Mesin Status
Saya tidak ingin terlalu detail dalam penjelasan contoh ini. Itu bukan karena terlalu kompleks, hanya sedikit terlalu besar. Saya akan mencoba menjelaskan ide dasar bagaimana cara kerjanya. Eksekusi seharusnya dapat dijelaskan sendiri dengan melihat model atau mengundah dan mensimulasinya. Beberapa bagian dari mesin status digabungkan di sub wilayah, seperti wilayah atur waktu. Dengan ini, keterbacaan mesin status dijamin.
Model dibagi menjadi dua bagian – bagian grafis dan bagian tekstual. Dalam bagian tekstual, peristiwa, variabel, dll. akan didefinisikan. Dalam bagian grafis – diagram status – eksekusi logis model ditentukan. Untuk membuat mesin status yang memenuhi perilaku yang ditentukan, beberapa peristiwa input diperlukan, yang dapat digunakan dalam model: onoff, set, mode, light, dan light_r. Dalam bagian definisi, peristiwa internal digunakan, yang meningkatkan nilai waktu setiap 100 ms:
every 100 ms / time += 1
Berdasarkan langkah 100 ms, waktu saat ini akan dihitung dalam format HH:MM:SS:
Eksekusi dasar dari mesin status sudah didefinisikan di bagian Cara Kerja Jam Digital. Dalam alat, saya menggunakan beberapa elemen pemodelan "khusus" seperti CompositeState, History, Sub-Diagrams, ExitNodes, dll. Deskripsi detail dapat ditemukan dalam Panduan Pengguna.
LCD Keypad Shield
LCD Keypad Shield cukup keren untuk proyek sederhana yang memerlukan layar untuk visualisasi dan beberapa tombol sebagai input – HMI (Antarmuka Manusia-Mesin) yang sederhana dan tipikal. LCD Keypad Shield berisi lima tombol pengguna dan satu lagi untuk reset. Lima tombol semuanya terhubung ke pin A0 Arduino. Setiap tombol terhubung ke pembagi tegangan, yang memungkinkan untuk membedakan antara tombol.
Anda dapat menggunakan analogRead(0) untuk menemukan nilai spesifik, yang tentu dapat bervariasi menurut produsen. Proyek sederhana ini menampilkan nilai saat ini pada LCD:
Dengan ambang batas ini, mungkin untuk membaca tombol:
#define NONE 0 #define SELECT 1 #define LEFT 2 #define DOWN 3 #define UP 4 #define RIGHT 5
static int readButton() { int result = 0; result = analogRead(0); if (result < 50) { return RIGHT; } if (result < 150) { return UP; } if (result < 300) { return DOWN; } if (result < 550) { return LEFT; } if (result < 850) { return SELECT; } return NONE; }
Antarmuka Mesin Status
Kode C++ yang dihasilkan dari mesin status menyediakan antarmuka, yang harus diimplementasikan untuk mengontrol mesin status. Langkah pertama adalah menghubungkan peristiwa input dengan tombol pada Keypad Shield. Saya telah menunjukkan cara membaca tombol, tetapi untuk menghubungkannya ke mesin status, debounce tombol diperlukan – jika tidak, peristiwa akan muncul beberapa kali, yang menghasilkan perilaku yang tidak dapat diprediksi. Konsep debounce perangkat lunak tidak baru. Anda dapat melihat dokumentasi Arduino.
Dalam implementasi saya, saya mendeteksi tepi jatuh (melepaskan tombol). Saya membaca nilai tombol, menunggu 80 ms (dapat hasil lebih baik dengan 80 daripada 50), menyimpan hasilnya dan membaca nilai baru. Jika oldResult bukan NONE (tidak ditekan) dan hasil baru adalah NONE, saya tahu bahwa tombol telah ditekan sebelumnya dan sekarang telah dilepaskan. Kemudian, saya memunculkan peristiwa input yang sesuai dari mesin status.
int oldState = NONE; static void raiseEvents() { int buttonPressed = readButton(); delay(80); oldState = buttonPressed; if (oldState != NONE && readButton() == NONE) { switch (oldState) { case SELECT: { stateMachine->getSCI_Button()->raise_mode(); break; } case LEFT: { stateMachine->getSCI_Button()->raise_set(); break; } case DOWN: { stateMachine->getSCI_Button()->raise_light(); break; } case UP: { stateMachine->getSCI_Button()->raise_light_r(); break; } case RIGHT: { stateMachine->getSCI_Button()->raise_onoff(); break; } default: { break; } } } }
Menyambungkan Semua
Program utama menggunakan tiga bagian:
Mesin Status
Sebuah Timer
Sebuah Pengendali Tampilan (typical lcd.print(...))
DigitalWatch* stateMachine = new DigitalWatch(); CPPTimerInterface* timer_sct = new CPPTimerInterface(); DisplayHandler* displayHandler = new DisplayHandler();
Mesin status menggunakan pengendali tampilan dan mendapatkan timer, yang akan diperbarui untuk mengontrol peristiwa yang diatur waktu. Setelah itu, mesin status diinisialisasi dan dimasukkan.