Menurut foto di artikelnya, mereka mengembangkan board khusus kerjasama antara Texas Instruments dengan Stanford: (Picture of the DSP shield calculating heart rate in bpm) dari [dokumen]
Berikut ini foto DSP Shield yang dikembangkan Stanford: [sumber]
Pada artikel ini diuraikan pembuatan sistem mikrokontroler dengan lampu yang berkedip dengan duty cycle 10%.
Pada mikrokontroler , lampu kedip dapat dibuat dengan delay ataupun dengan finite state machine (FSM). Pada artikel ini dipakai FSM dengan tujuan mendemonstratikan kemampuan FSM sebagai model untuk membuat perangkat lunak mikrokontroler.
Duty cycle yang diinginkan adalah 10%. Untuk itu maka lampu akan menyala selama 1 satuan waktu, dan lampu mati selama 9 satuan waktu. Lampu menyala selama 1 state , sedangkan lampu mati selama 9 state. Untuk itu dibuat 10 state: 1 state lampu menyala, dan 10 state lampu mati.
Pada artikel ini diuraikan membuat sistem mikrokontroler untuk mengendalikan lampu berdasarkan sebuah sakelar. Lampu dinyalakan dengan menekan tombol satu kali. Lampu dimatikan dengan cara menekan tombol agak lama.
Kebutuhan Sistem
Input switch push-button
Output 1 buah LED
Tombol ditekan sekali secara singkat untuk menyalakan lampu
Tombol ditekan dan ditahan selamat 1 detik untuk mematikan lampu
Diagram Blok Sistem secara umum sebagai berikut
Skenario sistem
Untuk memperjelas sistem yang akan dibuat, perlu dibuat dulu beberapa skenario yang dapat terjadi pada sistem ini.
LED mati: ditekan 1x pendek (kurang dari 1 detik) maka LED menyala
LED mati: ditekan 1x panjang (lebih dari 1 detik) -> LED menyala
LED menyala: ditekan & ditahan selama 1 detik -> LED mati
LED menyala: ditekan kurang dari 1 detik -> LED tetap menyala
LED menyala: ditekan & ditahan selama lebih dari 1 detik -> LED mati dalam 1 detik, setelah itu tetap mati
LED menyala: switch ditekan berkali-kali pendek -> LED tetap menyala (frekuensi di bawah batas tertentu)
LED mati: switch ditekan berkali-kali pendek -> LED menyala dan tidak mati (frekuensi di bawah batas tertentu)
Hal-hal yang tidak diperhatikan pada sistem ini:
prosedur mematikan/menyalakan sistem
keadaan baterai habis. Untuk sistem yang menggunakan baterai isi ulang (rechargeable), seharusnya ada mekanisme untuk mencegah baterai betul-betul habis.
Berikut ini Diagram Skenario 1 LED mati: ditekan 1x pendek (kurang dari 1 detik) maka LED menyala
Diagram Skenario 2: LED mati: ditekan 1x panjang (lebih dari 1 detik) -> LED menyala
Diagram skenario 3: LED menyala: ditekan & ditahan selama 1 detik -> LED mati
Skenario 4 LED menyala: ditekan kurang dari 1 detik -> LED tetap menyala
LED menyala: ditekan & ditahan selama lebih dari 1 detik -> LED mati dalam 1 detik, setelah itu tetap mati
Skenario Ekstra 6
Skenario Ekstra 7
Strategi/Algoritma:
Kondisi awal mati
Tunggu ada tombol ditekan. Jika ada , nyalakan lampu.
Tunggu tombol ditekan lama. Jika ada, matikan lampu. Abaikan input lain.
Berikut ini adalah implementasi lampu penyeberangan jalan (“traffic light at a pedestrian crosswalk”) dari Example 3.9 di buku “Introduction to Embedded Systems, a cyber physical systems approch” karangan Lee & Seshia.
Model sistem menggunakan Extended State Machine, sebagai berikut:
Perangkat Keras
Implementasi hardware menggunakan Arduino Nano ATmega328
Pin yang dipakai:
output lampu merah : pin D2 (active high)
output lampu hijau: D3 (active high)
output lampu kuning: pin D4 (active high)
input tombol: pin D11 (active low)
output lampu kedip: pin LED_BUILTIN / D13
Pada model tidak diperlukan lampu kedip, namun pada aplikasi ini ditambahkan lampu kedip sebagai indikasi bahwa sistem berfungsi.
Perangkat Lunak
Model FSM perangkat lunak mengikuti Example 3.9 sebagai berikut:
Perangkat lunak dibuat menggunakan library Arduino. Perangkat lunak terbagi menjadi bagian inisialisasi yang hanya dilakukan sekali di fungsi setup() dan bagian yang dilakukan berulang-ulang di fungsi loop().
Implementasi finite state machine (FSM) ada di fungsi fsm_init() dan fsm(). Fungsi fsm_init() berisi inisialisasi variabel FSM. fungsi fsm() berisi perubahan (reaction) yang terjadi pada FSM. Sesuai dengan penjelasan di Example 3.9, fungsi fsm() ini dipanggil secara setiap 1 detik, dengan cara menambahkan delay dengan fungsi delay().
Membuat fungsi periodik dengan delay() sebenarnya tidak tepat sekali pewaktuannya. Jika diperlukan pewaktuan yang lebih tepat, dapat menggunakan interupsi Timer1.
Penjelasan Perangkat Lunak
Pada sistem ini terdapat 4 buah state. Untuk itu, setiap state didefinisikan menggunakan macro. Penggunaan macro ini untuk membantu memahami kode dengan lebih mudah.
Setiap state diasosiasikan dengan suatu angka tertentu. Angka yang dipakai bebas, asal memperhatikan batas tipe data yang dipakai. Pada program ini tipe data yang dipakai adalah int, sehingga nilainya yang dapat dipakai adalah antara -32,768 sampai dengan 32,767
Bagian selanjutnya adalah definisi untuk pin-pin yang dipakai. Ada 4 pin yang dipakai, sehingga diperlukan 4 buah macro sebagai berikut.
Penggunaan macro ini untuk memudahkan pembacaan source code.
Bagian selanjutnya adalah variabel global
int state ;
int sig_r = 0;
int sig_g = 0;
int sig_y = 0;
int count = 0;
Pada program ini diperlukan beberapa variabel global. Variabel global diperlukan karena fungsi fsm_init() dipanggil di setup(), sedangkan fsm() dipanggil di fungsi loop(), padahal ada variabel FSM diperlukan untuk keduanya.
Software embedded yang baik seharusnya meminimalkan penggunaan variabel global, supaya program lebih rapi.
Fungsi setup()
Selanjutnya adalah fungsi setup() untuk inisialisasi Arduino
fungsi pinMode() dipanggil untuk mengatur konfigurasi pin-pin sebagai input dan output. Pada kode ini, yang dipakai adalah macro dari nomor pin, dengan tujuan memudahkan pembacaan software.
Port serial sebenarnya tidak wajib diaktifkan untuk sistem lampu penyeberangan ini. Pada implementasi ini, port serial dipakai untuk melakukan monitoring dan debugging. Variabel state, input dan output dicetak ke port serial secara teratur untuk mengecek apakah implementasi sudah berjalan sebagaimana mestinya.
Bagian selanjutnya dari fungsi setup() adalah melakukan inisialisasi FSM.
Fungsi activate_output(int r, int g, int y) fungsinya adalah menyalakan lampu output sesuai output dari FSM. Pada penjelasan Example 3.9, output adalah berupa sinyal sigR, sigR dan sigY. Sinyal-sinyal ini hanya ada / aktif ketika diperlukan perubahan lampu yang menyala. Untuk itu perlu fungsi ini untuk mengubah 3 buah sinyal ini menjadi penyalaan lampu yang sesuai.
Fungsi fsm_init()
Fungsi fsm_init() berfungsi memasukkan nilai awal (state) di FSM.
Berikut ini adalah bagian yang diimplementasikan di fungsi fsm_init()
Menurut model FSM, yang perlu dilakukan di awal adalah variabel count diubah menjadi 0, dan state awal adalah RED. Namun pada program ini ditambahkan juga kondisi awal lampu merah menyala, dengan cara memberikan sinyal sigR.
Fungsi loop()
Fungsi loop() dipanggil secara rutin oleh Arduino.
Hal-hal yang dilakukan di fungsi ini adalah:
membaca input dari tombol dengan perintah digitalRead()
membalik nilai input, karena tombol di hardware dibuat active low, sedangkan FSM memerlukan tombol pedestrian yang active_high
memanggil fungsi fsm() untuk menghitung state berikut dari FSM berdasarkan state terkini dan input pada saat itu. Hasilnya adalah state akan diubah, variabel count diubah, dan ada keluaran di variabel output.
memanggil activate_output() untuk melakukan perubahan lampu menyala jika diperlukan
mencetak state,input dan output untuk keperluan debugging / monitoring
membuat delay 1 detik
Fungsi print_state()
Fungsi ini tugasnya adalah mencetak semua variabel sistem untuk melakukan debugging
Fungsi fsm()
Fungsi ini adalah implementasi state chart.
Fungsi ini dirancang untuk tidak menggunakan variabel global, karena variabel global kurang baik dipakai . Semua output menggunakan pointer sebagai metode passing parameter. Pada fungsi ini tidak ada variabel global ataupun variabel jenis static.
Jenis FSM yang dipakai adalah extended state machine, jadi pada FSM ini ada variabel state dan variabel ‘count’.
Pada bagian awal, variabel sig_r,sig_g dan sig_y dinolkan, untuk menandakan bahwa defaultnya tidak ada output apapun.
Pada fungsi fsm() , yang dihitung adalah:
state selanjutnya, di variabel *state
variabel count (*count)
Perhitungan state dan variabel *count dibagi berdasarkan state terkini.
Implementasi STATE_RED
Berikut ini adalah bagian dari state chart yang diimplementasikan untuk case STATE_RED
Dari state RED akan pindah ke state GREEN dengan syarat varioabel count lebih besar atau sama dengan 60. Jika terjadi perpindahan ini, maka variabel count diubah menjadi 0.
Jika tidak terjadi perpindahan state, maka variabel count ditambah dengan 1.
Implementasi STATE_GREEN
Berikut ini adalah bagian dari state chart yang diimplementasikan untuk case STATE_GREEN
Dari state GREEN akan pindah ke state PENDING dengan syarat tombol input pedestrian ditekan, dan variabel count<60. Jika terjadi perpindahan ini, maka variabel count ditambah 1.
Dari state GREEN akan pindah ke state YELLOW dengan syarat tombol input pedestrian ditekan, dan variabel count lebih dari atau sama dengan 60. Jika terjadi perpindahan ini, maka variabel count diubah menjadi 0.
Implementasi STATE_PENDING
Berikut ini adalah bagian dari state chart yang diimplementasikan untuk case STATE_PENDING
Dari state PENDING akan pindah ke state YELLOW dengan syarat variabel count lebih atau sama dengan 60. Jika terjadi perpindahan ini, maka terjadi output sigY dan variabel count diset menjadi 0.
Jika tidak terjadi perpindahan tersebut, maka variabel count ditambah 1
Implementasi STATE_YELLOW
Berikut ini adalah bagian dari state chart yang diimplementasikan untuk case STATE_YELLOW
Dari state YELLOW akan pindah ke state RED dengan syarat count>5. Jika terjadi transisi ini , maka akan ada sinyal sigR dan variabel count dibuat menjadi 0
Jika tidak terjadi pindah ke state RED, maka variabel count ditambah 1.
Komentar
Pada model FSM yang diberikan di Example 3.9, ada kelemahan:
pada initial state tidak diberikan output, sehingga lampu yang menyala tidak terdefinisi. Pada program, hal ini diselesaikan dengan menambahkan sinyal sigR untuk menyalakan lampu merah
Sistem ini memiliki kelemahan dalam pembacaan tombol input. Penekanan tombol perlu dilakukan cukup lama agar terbaca oleh FSM. Hal ini terjadi karena fungsi fsm() dipanggil setiap detik. Jadi pada kondisi worst case, tombol input pedestrian perlu ditekan dan ditahan selama 1 detik. Pada best case cukup ditahan mendekati 0 detik. Rata-rata 0,5 detik.
Untuk mengatasi masalah lambatnya pembacaan tombol, dapat diatas dengan memperkecil perioda pemanggilan fungsi fsm(). Supaya perilaku sistem tidak berubah, maka batas-batas untuk variabel count di FSM perlu diubah. Misal perioda diubah dari 1 detik menjadi 1 milidetik. Maka batasan count<60 di FSM pada STATE_GREEN perlu diubah menjadi count<60000, demikian juga untuk batasan lainnya.
Sebuah drone buatan Iran jatuh di Ukraina. Di dalamnya ternyata terdapat komponen prosesor digital buatan Texas Instruments di Amerika . DSP (Digital Signal Processor) adalah mikroprosesor yang dioptimasi untuk melakukan perhitungan matematis yang sangat cepat.
Kemampuan TMS320F28335 adalah komputasi 150 MIPS , Floating Point Unit, 512 KB flash memory, EMIF (External Memory Interface), 12 bit Analog to Digital Converter.
Berikut ini foto drone buatan Iran tersebut (foto dari sebuah pameran militer):
Tipe drone tersebut: Shahed-191 UAV
Selain prosesor digital, ada juga pompa bahan bakar buatan Polandia
Update:
Ada lagi ditemukan komponen dari kepingan drone Shahed136 .
Pada perang Rusia-Ukraina, pihak Rusia banyak menggunakan guided missile (roket dengan pemandu) sebagai senjata. Pada misil-misil ini ternyata di dalamnya banyak menggunakan komponen buatan Amerika dan negara barat lainnya.
Pengukur ketinggian dengan radio (radio altimeter) yang dipakai di misil Kalibr dan 9M727 Iskander. Modul ini menggunakan chip semikonduktor buatan Altera
Chip TMS320C30GEL dari Texas Instrument dari misil 9M727 Iskander. TMS320C30 adalah prosesor untuk pengolahan sinyal digital dengan kemampuan floating point. Lebih jauh tentang TMS320C30 dapat dibaca di artikel “The TMS320C30 Floating-Point Digital Signal Processor“.
Berikut ini modul pengendali dari misil 9M727 Kalibr berbasis DSP (Digital Signal Processor) dari Texas Instrument. Modul ini dilengkapi dengan sirip pendingin di sekitarnya.
Rumah dengan listrik 5500 VA dapat dipakai sampai berapa watt?
Jawab: P = V x I x cos phi
Dengan
P : daya listrik (dalam watt)
V: tegangan jala-jala listrik (dalam volt)
I: arus listrik (dalam ampere)
cos phi: faktor daya (antara 0 sampai 1)
V x I ini adalah “5500 VA” yang merupakan daya terpasang di rumah
Pada kondisi ideal, faktor daya adalah 1. Maka daya maksimum adalah : 5500 watt
Jika di rumah banyak beban induktif seperti pompa, AC, kulkas, kipas, maka faktor daya biasanya sekitar 0,7. Maka daya maksimum = P = 5500 x 0,7 = 3850 watt.
Tegangan normal di rumah-rumah adalah 220 volt. Namun sering tegangan turun, misal sampai ke 200 volt. Akibat tegangan turun, daya akan lebih kecil lagi.
5500 VA pada tegangan 220 volt, artinya arus = 5500/220 = 25 ampere. Besaran ini sesuai dengan ukuran MCB yang terpasang di panel listrik.
Pada kondisi non ideal: tegangan 220 volt, faktor daya 0,7 , arus maksimum tetap 25 ampere. Maka daya sebagai berikut:
P = P x I x faktor daya = 220 x 25 x 0,7 = 3500 watt
Kesimpulan:
5500 VA memberikan daya maksimum 5500 watt pada kondisi ideal
5500 VA memberikan daya maksimum 3500 watt pada kondisi non ideal (tegangan turun ke 200 volt, faktor daya = 0,7)
Berikut ini contoh MCB dengan kapasitas 25 ampere. MCB ini biasa dipasang untuk membatasi arus sampai 25 ampere, artinya daya (VA) = 5500 VA
Beberapa smartphone model terbaru (tahun 2022) dapat dicharge dengan charger 25 watt. Untuk mendapatkan daya 25 watt tersebut, berapakah arusnya (dalam ampere)?
Jawaban ringkas: arus adalah 3 ampere atau 2,77 ampere.
// CJMCU-8118
#include <WiFi.h> // WiFi control for ESP32
#include <ThingsBoard.h> // ThingsBoard SDK
#include <esp_task_wdt.h>
// WiFi access point
#define WIFI_AP_NAME "APNAME" // ganti dengan WIFI AP
// WiFi password
#define WIFI_PASSWORD "123456" // ganti dengan WIFI AP password
#define TOKEN "zRG1HN8w0PRydh5gV7Il"
#define LED_SENSOR 23
#define ADC_INPUT 34
#define BUILTIN_LED 2
#define WDT_TIMEOUT 60
// ThingsBoard server instance.
#define THINGSBOARD_SERVER "192.168.0.114"
#include <Arduino.h>
#include <Wire.h>
// Initialize ThingsBoard client
WiFiClient espClient;
// Initialize ThingsBoard instance
ThingsBoard tb(espClient);
// the Wifi radio's status
int status = WL_IDLE_STATUS;
// main application loop delay (ms)
int quant = 20;
// Period of sending a temperature/humidity data.
int send_delay = 2000;
// Time passed after telemetry data was sent, milliseconds.
int send_passed = 0;
char mac_str[20]; // storing MAC address string
byte mac_byte[6]; // storing MAC address bytes
int led_counter = 0; //blinking built int led
void setup() {
pinMode(BUILTIN_LED, OUTPUT);
pinMode(LED_SENSOR, OUTPUT);
// put your setup code here, to run once:
Serial.begin(115200);
delay(1000);
Serial.print("Source Code: ");
Serial.println(__FILE__);
//wait for serial connection to open (only necessary on some boards)
while (!Serial);
WiFi.begin(WIFI_AP_NAME, WIFI_PASSWORD);
InitWiFi();
WiFi.macAddress(mac_byte);
sprintf(mac_str, "%02x%02x%02x%02x%02x%02x", mac_byte[0], mac_byte[1], mac_byte[2], mac_byte[3], mac_byte[4], mac_byte[5]);
Serial.print("ESP board MAC address: ");
Serial.println(WiFi.macAddress());
Serial.print("ESP board IP address: ");
Serial.println(WiFi.localIP());
// setup WDT
esp_task_wdt_init(WDT_TIMEOUT, true); //enable panic so ESP32 restarts
esp_task_wdt_add(NULL); //add current thread to WDT watch
}
void loop() {
float temperature = 25;
float pressure = 0;
float humidity = 60; // default humidity
float co2 = 0;
float tvoc = 0;
delay(quant);
send_passed += quant;
// Reconnect to WiFi, if needed
if (WiFi.status() != WL_CONNECTED) {
reconnect();
return;
}
// Reconnect to ThingsBoard, if needed
if (!tb.connected()) {
// Connect to the ThingsBoard
Serial.print("Connecting to: ");
Serial.print(THINGSBOARD_SERVER);
Serial.print(" with token ");
Serial.println(TOKEN);
if (!tb.connect(THINGSBOARD_SERVER, TOKEN)) {
Serial.println("Failed to connect");
return;
}
}
// Check if it is a time to send sensor data
if (send_passed > send_delay) {
int dust;
dust = DustRead();
Serial.print("Sending telemetry data...");
Serial.print("Dust ");
Serial.print(dust);
Serial.println("");
tb.sendTelemetryFloat("dust", dust);
send_passed = 0;
}
// Process messages
tb.loop();
led_counter++; // LED blink at 1 Hz
if (led_counter > 50) {
led_counter = 0;
}
if (led_counter > 25) {
digitalWrite(BUILTIN_LED , LOW);
} else {
digitalWrite(BUILTIN_LED , HIGH);
}
esp_task_wdt_reset(); // WDT reset setelah berhasil mengirim data
}
void I2C_Scan() {
byte error, address;
int nDevices;
Serial.println("I2C Scanning...");
nDevices = 0;
for (address = 1; address < 127; address++ ) {
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0) {
Serial.print("I2C device found at address 0x");
if (address < 16) {
Serial.print("0");
}
Serial.println(address, HEX);
nDevices++;
}
else if (error == 4) {
Serial.print("Unknow error at address 0x");
if (address < 16) {
Serial.print("0");
}
Serial.println(address, HEX);
}
}
if (nDevices == 0) {
Serial.println("No I2C devices found\n");
}
else {
Serial.println("done\n");
}
}
void InitWiFi()
{
Serial.println("Connecting to AP ...");
// attempt to connect to WiFi network
WiFi.begin(WIFI_AP_NAME, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("Connected to AP");
}
void reconnect() {
// Loop until we're reconnected
status = WiFi.status();
if ( status != WL_CONNECTED) {
WiFi.begin(WIFI_AP_NAME, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("Connected to AP");
}
}
int DustRead() {
int sensorValue;
// read the analog in value:
digitalWrite(LED_SENSOR, HIGH);
delayMicroseconds(280);
sensorValue = analogRead(ADC_INPUT); // measurement 280 us after signal start
delayMicroseconds(40); // total signal duration 320 us
digitalWrite(LED_SENSOR, LOW); // turn off LED
// print the results to the Serial Monitor:
Serial.print("sensor = ");
Serial.println(sensorValue);
return sensorValue;
}
Cara mengubah IPAddress menjadi char[] di Arduino – class IPAddress memiliki fungsi toString untuk mengubah ke String – class String memiliki fungsi c_str untuk mengubah ke pointer character