Berikut ini antar muka minimalis antara ESP32 dengan sensor lingkungan BMP280
Pin yang dipakai:
VCC di ESP32 dihubungkan ke VCC di BMP280
GND di ESP32 dihubungkan ke GND di BMP280
SCL di ESP32 dihubungkan ke SCL di BMP280
SDA di ESP32 dihubungkan ke SDA di BMP280
Software juga dibuat minimalis
// https://bitbucket.org/christandlg/bmx280mi/src/master/examples/BMx280_I2C/BMx280_I2C.ino
// BMx280_I2C.ino
//
// shows how to use the BMP280 / BMx280 library with the sensor connected using I2C.
//
// Copyright (c) 2018 Gregor Christandl
//
// connect the AS3935 to the Arduino like this:
//
// Arduino - BMP280 / BME280
// 3.3V ---- VCC
// GND ----- GND
// SDA ----- SDA
// SCL ----- SCL
// some BMP280/BME280 modules break out the CSB and SDO pins as well:
// 5V ------ CSB (enables the I2C interface)
// GND ----- SDO (I2C Address 0x76)
// 5V ------ SDO (I2C Address 0x77)
// other pins can be left unconnected.
#include <Arduino.h>
#include <Wire.h>
#define I2C_SDA 15
#define I2C_SCL 13
#include <BMx280I2C.h>
#define I2C_ADDRESS 0x76
//create a BMx280I2C object using the I2C interface with I2C Address 0x76
BMx280I2C bmx280(I2C_ADDRESS);
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
delay(1000);
//wait for serial connection to open (only necessary on some boards)
while (!Serial);
// Wire.begin();
Wire.begin(I2C_SDA, I2C_SCL);
I2C_Scan() ; // just for verifying
//begin() checks the Interface, reads the sensor ID (to differentiate between BMP280 and BME280)
//and reads compensation parameters.
if (!bmx280.begin())
{
Serial.println("begin() failed. check your BMx280 Interface and I2C Address.");
while (1);
}
if (bmx280.isBME280())
Serial.println("sensor is a BME280");
else
Serial.println("sensor is a BMP280");
//reset sensor to default parameters.
bmx280.resetToDefaults();
//by default sensing is disabled and must be enabled by setting a non-zero
//oversampling setting.
//set an oversampling setting for pressure and temperature measurements.
bmx280.writeOversamplingPressure(BMx280MI::OSRS_P_x16);
bmx280.writeOversamplingTemperature(BMx280MI::OSRS_T_x16);
//if sensor is a BME280, set an oversampling setting for humidity measurements.
if (bmx280.isBME280())
bmx280.writeOversamplingHumidity(BMx280MI::OSRS_H_x16);
}
void loop() {
float temperature = 0;
float pressure = 0;
float humidity = 60; // default humidity
float co2 = 0;
float tvoc = 0;
delay(1000);
//start a measurement
if (!bmx280.measure())
{
Serial.println("could not start measurement, is a measurement already running?");
return;
}
//wait for the measurement to finish
do
{
delay(100);
} while (!bmx280.hasValue());
// Serial.print("Pressure: "); Serial.println(bmx280.getPressure());
// Serial.print("Pressure (64 bit): "); Serial.println(bmx280.getPressure64());
// Serial.print("Temperature: "); Serial.println(bmx280.getTemperature());
pressure = bmx280.getPressure();
temperature = bmx280.getTemperature();
//important: measurement data is read from the sensor in function hasValue() only.
//make sure to call get*() functions only after hasValue() has returned true.
if (bmx280.isBME280())
{
// Serial.print("Humidity: ");
// Serial.println(bmx280.getHumidity());
humidity = bmx280.getHumidity();
}
Serial.print("Temp\t");
Serial.print(temperature);
Serial.print("\t");
Serial.print("Humidity\t");
Serial.print(humidity);
Serial.print("\t");
Serial.print("Pressure\t");
Serial.print(pressure);
Serial.print("\t");
Serial.println("");
}
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");
}
}
Pada percobaan ini dilakukan pengiriman data telemetri dari ESP32 ke Thingsboard. Sensor yang dipakai adalah sakelar on-off. Percobaan ini adalah bagian dari pembuatan sistem IoT (Internet of Things) yang terdiri dari beberapa ESP32 dan software ThingsBoard.
Pada percobaan ini , tidak semua komponen ThingsBoard dipakai. Yang dipakai adalah sebagai berikut
Devices: menggunakan ESP32 dan sakelar sebagas sensor
Protokol HTTP sebagai ThingsBoard Transports
ThingsBoard Core
SQL Database
External Systems
Aliran data pada sistem yang dibuat adalah sebagai berikut:
Sakelar bertindak sebagai sensor. Besaran yang dihasilkan oleh sakelar adalah 0 dan 1. ESP32 membaca status sensor setiap interval tertentu, dan kemudian mengirimkannya ke ThingsBoard menggunakan protokol HTTP. Data ini kemudian disimpan di Database.
Data dari database ini dapat ditampilkan menggunakan Dashboard pada Thingsboard, dan juga dapat diambil oleh aplikasi eksternal menggunakan REST API (REpresentational State Transfer Application Program Interface)
Hardware yang dipakai adalah sebagai berikut:
ESP32 Lolin Wemos
2 buah sakelar. Pada percobaan ini digunakan sakelar geser SPDT dan push button.
ESP32 Lolin Wemos
Daftar pin ESP32 yang dipakai adalah sebagai berikut
pin 13 sebagai input digital, diberi nama SW0. Input active low.
pin 15 sebagai input digital, diberi nama SW1. Input active low.
Berikut ini foto rangkaian setelah dirakit
Perangkat lunak yang dipakai
Arduino versi 1.8.19 (Windows)
ThingsBoard versi 3.3.4.1
Ubuntu Linux 20.04.04 LTS
Wireshark versi 3.02
Setting ThingsBoard
[under construction]
Perangkat Lunak ESP32
Perangkat lunak ESP32 dibuat dengan Arduino
Library yang dipakai di Arduino adalah sebagai berikut
// demo switch telemetry to Thingsboard
// adapted from https://thingsboard.io/docs/samples/esp32/gpio-control-pico-kit-dht22-sensor/
#include <WiFi.h> // WiFi control for ESP32
#include <ThingsBoard.h> // ThingsBoard SDK
// onboard LED
#define BUILTIN_LED 22
// switch pin definition
#define SW0 13
#define SW1 15
// Helper macro to calculate array size
// #define COUNT_OF(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
// WiFi access point
#define WIFI_AP_NAME "ACCESS_POINT_NAME"
// WiFi password
#define WIFI_PASSWORD "ACCESS_POINT_PASSWORD"
// See https://thingsboard.io/docs/getting-started-guides/helloworld/
// to understand how to obtain an access token
#define TOKEN "QdqSrxBAjBvxAoJyeoXN"
// ThingsBoard server instance.
#define THINGSBOARD_SERVER "192.168.0.90"
// Baud rate for debug serial
#define SERIAL_DEBUG_BAUD 115200
// 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
// Setup an application
void setup() {
pinMode(SW0, INPUT_PULLUP); // input switch
pinMode(SW1, INPUT_PULLUP);
pinMode(BUILTIN_LED , OUTPUT);
// Initialize serial for debugging
Serial.begin(SERIAL_DEBUG_BAUD);
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());
}
// Main application loop
void loop() {
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 switch data
if (send_passed > send_delay) {
int switch0, switch1;
switch0 = digitalRead(SW0);
switch1 = digitalRead(SW1);
Serial.print("Sending telemetry data...");
Serial.print(" SW0:");
Serial.print(switch0);
Serial.print(" SW1:");
Serial.println(switch1);
tb.sendTelemetryInt("switch00", switch0);
tb.sendTelemetryInt("switch01", switch1);
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);
}
}
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");
}
}
Pengecekan Telemetri
Setelah sistem dirakit dan ESP32 diprogram, perlu dilakukan pengecekan apakah sistem berfungsi dengan baik. Pengecekan pengiriman data telemetri dilakukan dengan cara:
Memantau output dari port serial ESP32
Mengecek data telemetri di server Thingsboard
Berikut ini output dari serial monitor ESP32.
19:45:30.745 -> Connecting to AP ...
19:45:31.225 -> ......Connected to AP
19:45:33.738 -> ESP board MAC address: 3C:71:BF:03:41:4C
19:45:33.738 -> ESP board IP address: 192.168.0.124
19:45:33.773 -> Connecting to: 192.168.0.90 with token QdqSrxBAjBvxAoJyeoXN
19:45:35.798 -> Sending telemetry data... SW0:1 SW1:1
19:45:37.819 -> Sending telemetry data... SW0:1 SW1:1
19:45:39.850 -> Sending telemetry data... SW0:1 SW1:1
Dari output tersebut dapat disimpulkan:
ESP32 berhasil terhubung ke access point
ESP32 berhasil mendapatkan IP address
ESP32 berhasil mengirim data ke ThingsBoard
Untuk mengecek data yang masuk ke server, prosedurnya sebagai berikut:
Login ke ThingsBoard sebagai tenant. username: [email protected], password: tenant (jika belum diganti)
Klik di “Devices”
Klik di “ESP32 Dual Switch”
Klik di “Latest telemetry”
Jika pengiriman data normal, maka status sakelar terakhir akan muncul di Device details, seperti gambar berikut ini.
Angka di kolom “Value” akan sesuai dengan status sakelar. Pada percobaan ini pengiriman data dilakukan dengan interval 2 detik, jadi selambatnya dalam 2 detik status sakelar terakhir akan masuk.
Dashboard di ThingsBoard
Setelah data dicek masuk, kita dapat membuat dashboard di Thingsboard untuk menampilkan data dari sensor. Berikut ini contoh tampilan dashboard.
Pengambilan Data Telemetri Dengan REST API
Data telemetri di server ThingsBoard dapat diambil menggunakan REST API dari aplikasi lain.
Pada percobaan ini data diambil dengan menggunakan software ‘curl’ di Ubuntu Linux.
Berikut ini beberapa kecelakaan yang terjadi karena kegagalan pada sistem mikroprosesor, terutama yang disebabkan kesalahan di perangkat lunak (software).
Toyota Unintended Acceleration
Mobil Toyota melakukan akselerasi sendiri tanpa diperintah oleh pengemudi. Korban total 89 orang. Penyebab: kesalahan pada software ETCS (Electronic Throttle Control) pada mobil Camry,Lexus ES, Tacoma buatan Toyota.
Therac-25 adalah mesin untuk melakukan terapi radiasi pada pasien. Bugs pada software menyebabkan dosis radiasi melebihi batas. Korban 6 orang: 3 pasien meninggal, 3 pasien luka.
Pesawat A400M jatuh karena 3 dari 4 mesin mati. “The key scenario being examined by investigators is that the torque calibration parameter data was accidentally wiped on three engines as the engine software was being installed at Airbus facilities, which would prevent the FADECs from operating”
Software MCAS (Maneuvering Characteristics Augmentation System) menyebabkan 2 buah pesawat Boeing 737 MAX jatuh. Softwarenya sendiri tidak bermasalah, namun proses engineering pada pembuatannya yang bermasalah.
Pada era perang dingin, USSR memiliki sistem pendeteksi (early warning) peluncuran rudal antar benua (ICBM) dari Amerika. Sistem ini gagal bekerja karena terjadi false positive. “the false alarm was eventually traced to the satellite, which picked up the sun’s reflection off the tops of clouds and mistook it for a missile launch. The computer program that was supposed to filter out such information was rewritten.”
Patriot Missile adalah Surface to Air Missile (SAM). Pada perang teluk (Gulf War), Rudal Patriot ini gagal menembak misil Scud yang ditembakkan dari Iraq. Akibatnya 28 orang tentara meninggal dan 100 orang luka.
Pada tulisan ini diuraikan cara kerja rangkaian penggerak relay dengan transistor NPN.
Contoh rangkaian penggerak relay dengan transistor NPN adalah sebagai berikut:
Rangkaian penggerak relay dengan transistor NPN
Komponen utama rangkaian adalah transistor NPN tipe BC337
Input rangkaian adalah terminal dengan tanda OUT, yang merupakan output dari mikroprosesor seperti Arduino. Tegangan input rangkaian ini diasumsikan 0 volt (untuk logika LOW) dan 5 volt ( untuk logika HIGH)
Tegangan supply relay diasumsikan 5 volt DC.
Tipe relay diasumsikan adalah JQC-3F
Emitter pada transistor terhubung ke GND
Cara Kerja Rangkaian
Jika pin OUT berada pada tegangan rendah (LOW) atau 0 volt, maka transistor akan berada pada keadaan OFF, jadi tidak ada arus mengalir antara kolektor (C) dan emiter (E). Dengan demikian maka kumparan relay tidak mendapat arus. Maka kontak pada relay akan berada pada kondisi normalnya.
Jka pin OUT berapa pada tegangan tinggi (HIGH) atau 5 volt, maka transistor akan berada pada keadaan ON/saturasi. Transistor bertindak sebagai sakelar yang sedang ON. Pin kolektor dan emitter dapat dianggap terhubung dengan resistansi yang sangat rendah. Arus akan mengalir dari supply 5V, melalui kumparan relay, kemudian masuk ke terminal kolektor (C) pada transistor, dan keluar di terminal emitter (E) pada transistor, kemudian masuk ke GND.
Fungsi dioda 1N4007 adalah untuk pada waktu transistor dimatikan. Pada waktu transistor dimatikan, masih ada energi yang tersimpan sebagai medan magnet di dalam kumparan relay. Energi ini berusaha mempertahankan arus pada kumparan. Jika tidak ada dioda, maka arus ini akan memaksa untuk mengalir melalui transistor, sehingga dapat merusak transistor. Dengan adanya dioda, arus ini akan mengalir melalui dioda, sehingga energi yang tersimpan pada kumparan relay dapat dibuang pada dioda tersebut.
Perhitungan Arus dan Tegangan
Pada waktu pin OUT pada tegangan rendah, maka praktis tidak ada arus mengalir pada transistor. Sebenarnya ada, namun kecil sekali sehingga dapat diabaikan.
Pada waktu pin OUT pada tegangan tinggi (5 volt), maka akan ada arus mengalir melalui basis transistor. Tegangan antara basis dan emiter transistor antara 0,6 volt sampai dengan 1,2 volt, tergantung tegangan antara terminal C dan E.
Arus pada relay diasumsikan sekitar 70 mA
Tegangan Vbe pada kondisi itu dapat dilihat pada gambar berikut ini. Ambil kurva Vbe(sat)
Penguatan arus transistro BC337 sekitar 100 sampai 630. Untuk aplikasi ini dianggap penguatan arus = 100
Arus pada kolektor (Ic) adalah:
Ic=Ib x hfe = 2 mA x 100 = 200 mA
Besar arus pada Ic maksimum adalah 200 mA , namun bisa kurang dari 200 mA jika transistor dalam keadaan saturasi. Untuk itu mesti melihat perilaku kumparan relay.
Tegangan Vce saturasi dapat dilihat pada grafik berikut ini:
BC337-saturasi
Tegangan Vce saturasi adalah sekitar 0,2 volt
Tegangan nominal relay adalah 5 volt . Daya pada kumparan relay adalah 0.36 watt. Maka resistansi kumparan relay adalah:
Mikrokontroler seperti ATmega328 dapat diproteksi dengan memprogram fuse bit pada mikrokontroler tersebut. Pemrograman fuse bit mesti dilakukan menggunakan ISP (In System Programming) atau High Voltage Programming, jadi tidak dapat menggunakan port USB pada Arduino Nano / UNO.
Namun demikian proteksi ini dapat juga dibypass dengan menggunakan alat khusus.
Apa yang terjadi jika baterai 2Wh dengan voltase 3.7 V dipasang ke alat berdaya 4Wh voltase 3.7?
Jawaban
Perlu diingat dulu bahwa Wh (watt hour / watt jam) adalah satuan energi, bukan daya. Satuan daya adalah watt.
Baterai memiliki kapasitas energi dan kapasitas arus. Dua hal ini akan mempengaruhi alat jika baterai diganti.
Pertama kita bahas dari sisi energi dulu:
Baterai 4 Wh memiliki jumlah energi 2x baterai 2 Wh, jadi baterai 2Wh akan lebih cepat habis. Misal jika pakai baterai 4 Wh alat tahan 10 jam, maka dengan baterai 2 Wh, alat itu hanya tahan kurang lebih 5 jam.
Kedua dari sisi arus.
Biasanya baterai dengan Wh lebih besar memiliki kapasitas arus lebih besar dibandingkan baterai dengan Wh kecil.
Energi 4 Wh setara dengan 1100 mAh. Biasanya kemampuan arus maksimum yang dipakai adalah sebesar angka mAh. Jadi misal baterai dengan kapasitas 1100 mAh, biasanya hanya ditarik arus sampai 1100 mA, atau 1,1 ampere. Jika melebihi angka ini, biasanya efeknya ke arah efisiensi. Baterai 1100 mAh jika ditarik arus melebihi 1100 mA, maka lebih cepat habis.
Baterai 2 Wh setara dengan 550 mAh, batas arus yang normal adalah 550 mA.
Jadi kalau baterai 4 Wh diganti dengan baterai 2 Wh, maka ada kemungkinan arus yg dipakai melebihi kemampuan baterai sehingga baterai lebih cepat habis, atau lebih cepat panas.
misalnya saya beli stabilizer dengan 10 Kva dengan input voltage V = 150-240 volt dan output voltage 110v / 220v. Itu watt aman yg bisa kita pake brp watt ya ?
Jawaban singkat:
Pada kondisi serba ideal, daya maksimum yang dapat dipakai adalah 10 kW = 10000 watt . Dalam prakteknya, stabilizer sebaiknya dipakai hanya pada beban 70% saja (7000 watt). Efisiensi stabilizer juga perlu diperhatikan, misal 90%. Jika beban induktif seperti motor atau pompa, perlu dikalikan lagi dengan faktor daya misalnya 0,8 .
Kondisi serba ideal ini adalah:
beban 3 fasa seimbang, sehingga arus pada setiap fasa sama besarnya. Dalam prakteknya arus pada setiap fasa perlu dihitung / diukur.
faktor daya = 1, dalam prakteknya tergantung sifat beban. Kalau beban induktif dapat dipakai faktor daya=0,8.
Stabilizer dapat dipakai pada 100% beban, dalam prakteknya sekitar 70%
Efisiensi stabilizer 100%, dalam prakteknya sekitar 90%
Contoh kasus
Beban seimbang, beban pompa listrik 3 fasa (induktif). Maka kemampuan maksimum: 10 kW x 0.7 x 0.7 x 0.9 = 4410 watt
Perlu diperhatikan bahwa stabilizer 10 kVA biasanya 3 fasa. Pada stabilizer 3 fasa 10 kVA, arus maksimum di setiap fasa adalah sekitar 15 ampere.
Perhitungannya:
10 kVA / 3 / 220 volt = 15.151 ampere
Jika arus pada suatu fasa melebihi 15 ampere, maka dapat merusak stabilizer tersebut. Untuk amannya, batasi arus pada 70% arus maksimum, jadi dibatasi pada 15 x 70% = 10.5 ampere.
Sebaiknya dipelajari dulu spesifikasi dari stabilizer yang dipakai, misal di artikel ini: https://www.indotara.co.id/catalog/Arakawa%20Catalog%20Full.pdf
Pada pengembangan sistem dengan komunikasi Modbus RTU dengan RS485, kadang-kadang kita perlu memonitor pertukaran data di kabel RS-485 untuk memantau apakah komunikasi data berjalan dengan benar. Pada artikel ini diuraikan secara ringkas pembuatan perangkat untuk memantau dan merekam trafik data di komunikasi RS-485 tersebut.
Berikut ini skema rangkaiannya secara sederhana
Rangkaian ESP32 dengan RS485
Penjelasan cara kerja rangkaian
Komponen utama sistem adalah sebagai berikut
MAX485 berfungsi untuk mengubah level tegangan RS-485 menjadi TTL 5 volt.
Level converter berfungsi mengubah tegangan TTL 5 volt dari MAX485 menjadi TTL dengan tegangan 3 volt.
Mikrokontroler ESP32 berfungsi merekam data serial dan mengirimnya menggunakan kabel USB ke komputer.
Komputer untuk merekam data serial dari ESP32
Power supply 5 volt untuk MAX485
Pin pada MAX485
Berikut ini foto rangkaian dengan breadboard
Alat untuk merekam sinyal Modbus RTU di RS485 dengan mikrokontroler ESP32
Rangkaian ESP32 , MAX485 dan level converter di breadboard
#esp32-freertos-rs485-analyzer
/**
analisis data RS485
*/
#define LED_BUILTIN 22
#define RXD1 17
#define TXD1 5
#define RXD2 18
#define TXD2 23
void setup() {
Serial.begin(115200);
Serial1.begin(9600, SERIAL_8N1, RXD1, TXD1);
Serial2.begin(9600, SERIAL_8N1, RXD2, TXD2);
Serial.println("Serial Txd 0 is on pin: " + String(TX));
Serial.println("Serial Rxd 0 is on pin: " + String(RX));
Serial.println("Serial Txd 1 is on pin: " + String(TXD1));
Serial.println("Serial Rxd 1 is on pin: " + String(RXD1));
Serial.println("Serial Txd 2 is on pin: " + String(TXD2));
Serial.println("Serial Rxd 2 is on pin: " + String(RXD2));
pinMode(LED_BUILTIN, OUTPUT);
if (1)
xTaskCreate(
TaskBlinker, /* Task function. */
"TaskBlinker", /* String with name of task. */
1000, /* Stack size in bytes. */
NULL, /* Parameter passed as input of the task */
1, /* Priority of the task. */
NULL); /* Task handle. */
xTaskCreate(
TaskSerial1, /* Task function. */
"TaskSerial1", /* String with name of task. */
2000, /* Stack size in bytes. */
NULL, /* Parameter passed as input of the task */
1, /* Priority of the task. */
NULL); /* Task handle. */
}
// the loop function runs over and over again forever
void loop() {
delay(10000);
}
void TaskBlinker(void *parameter) {
int counter = 0;
TickType_t xLastWakeTime;
const TickType_t xPeriod = 500 ;
xLastWakeTime = xTaskGetTickCount();
// dht.begin(); // aktifkan sensor DHT22
while (1) {
digitalWrite(LED_BUILTIN, HIGH);
vTaskDelayUntil(&xLastWakeTime, xPeriod);
digitalWrite(LED_BUILTIN, LOW);
vTaskDelayUntil(&xLastWakeTime, xPeriod);
// Serial.print("Counter:");
// Serial.println(counter);
counter++;
}
}
#define BUFFER_MAX 200
void TaskSerial1(void *parameter) {
int interframe_timer_max = 0;
int interframe_timer = 0; // untuk mengukur waktu antar frame
char buffer_data[BUFFER_MAX];
int buffer_idx = 0;
TickType_t xLastWakeTime;
const TickType_t xPeriod = 1 ;
xLastWakeTime = xTaskGetTickCount();
while (1) {
int incomingByte;
if (Serial1.available() > 0) {
interframe_timer = 0;
} else {
interframe_timer++;
}
while (Serial1.available() > 0) {
// read the incoming byte:
incomingByte = Serial1.read();
buffer_data[buffer_idx] = incomingByte ;
buffer_idx++;
if (buffer_idx > BUFFER_MAX) {
buffer_idx = BUFFER_MAX; // buffer overflow protection
}
}
//Serial.print(incomingByte, HEX);
//Serial.print(" ");
if (interframe_timer > interframe_timer_max) {
interframe_timer_max = interframe_timer;
Serial.print("interframe_max ");
Serial.println(interframe_timer_max);
}
if (interframe_timer > 6 && buffer_idx > 0) {
// cetak semua data di buffer
for (int i = 0; i < buffer_idx; i++) {
Serial.print(buffer_data[i], HEX);
Serial.print(" ");
}
Serial.println();
buffer_idx = 0; // empty buffer
}
vTaskDelayUntil(&xLastWakeTime, xPeriod);
}
}
Berikut ini contoh program sederhana untuk membuat LED onboard berkedip di pada ESP32 Lolin32 Lite. Sistem operasi yang digunakan adalah FreeRTOS. IDE menggunakan Arduino. Delay menggunakan delay dari FreeRTOS, dengan fungsi vTaskDelayUntil().
ESP32 Lolin32 Lite (atas) dan ESP32 DevkitC (bawah)
Lampu berkedip dengan frekuensi 1 Hz. Suatu angka (counter) dikirim melalui port serial setiap detik. Kecepatan port serial adalah 115200 bps
#define LED_BUILTIN 22 # Wemos Lolin32 onboard LED di pin 22
void setup() {
Serial.begin(115200);
Serial.println("Start");
pinMode(LED_BUILTIN, OUTPUT);
if (1)
xTaskCreate(
TaskBlinker, /* Task function. */
"TaskBlinker", /* String with name of task. */
1000, /* Stack size in bytes. */
NULL, /* Parameter passed as input of the task */
1, /* Priority of the task. */
NULL); /* Task handle. */
}
// the loop function runs over and over again forever
void loop() {
delay(10000);
}
void TaskBlinker(void *parameter) {
int counter = 0;
TickType_t xLastWakeTime;
const TickType_t xPeriod = 500 ;
xLastWakeTime = xTaskGetTickCount();
while (1) {
digitalWrite(LED_BUILTIN, HIGH);
vTaskDelayUntil(&xLastWakeTime, xPeriod);
digitalWrite(LED_BUILTIN, LOW);
vTaskDelayUntil(&xLastWakeTime, xPeriod);
Serial.print("Counter:");
Serial.println(counter);
counter++;
}
}
Kadang-kadang kita perlu menguji power supply komputer dengan beban yang diketahui betul resistansinya, supaya nantinya daya yang keluar dapat diatur.
Misal: target daya : 100 watt tegangan output power supply: 12 volt R = V*V/P = 12×12/100 = 1,44 ohm resistor putih bisa max disipasi daya 5 watt, jadi perlu 20 buah (20×5 = 100 watt). Misal 20 resistor diparalel supaya menjadi 1,44 ohm, maka ukuran setiap resistor adalah 1,44 x 20 = 28,8 ohm resistor 28,8 ohm tidak ada, misalnya paling dekat adalah 33 ohm. Jika pakai R=33 ohm, maka perlu 33/1.44 = 22,9 buah, dibulatkan 23 buah. Resistansi realnya: 33/23 = 1,434 ohm disipasi daya realnya = V*V/R = 12×12/1,434 = 100.36 watt
Library mbedtls diperlukan di Linux/Windows kalau kita mau melakukan enkripsi data, terutama kalau aplikasi kita akan berkomunikasi secara tersandikan dengan mikrokontroler ESP32. Library kriptografi di Windows yang kompatibel dengan kriptograsi di ESP32 antara lain adalah mbedtls.
Pertama lakukan instalasi library. Pada contoh berikut ini instalasi dilakukan di cygwin.
Jalankan setup cygwin, kemudian pilih package yang bernama ‘mbedtls”.
Pada contoh di atas, yg dipilih adalah library mbedtls dan mbedtls-devel
Selanjutnya library ini mesti ditambahkan ketika proses link di aplikasi kita.
Sebagai contoh, saya menggunakan IDE Codeblocks. Ketika membuat project, pilih compiler “Cygwin GCC”
Selanjutnya pada CodeBlocks, penambahan library dilakukan dengan masuk ke menu Project -> Build Options -> Linker Setting
Tambahkan file library mbedtls. File library dapat dicari di direktori c:\cygwin64\lib
Nama library yang diperlukan adalah “libmbedcrypto.a”
Lampu dipasang berjejer, dari kiri ke kanan. Nama lamput: OUT1,OUT2,OUT3,OUT4
Perilaku yang diharapkan
pada satu saat hanya 1 lampu yang menyala
kondisi awal lampu paling kiri menyala
jika tombol kanan ditekan, lampu yang menyala bergeser ke kanan
jika tombol kiri ditekan, lampu yang menyala bergeser ke kiri
jika lampu yang menyala sudah sampai di paling kanan, penekanan ke kanan akan membuat lampu paling kiri menyala
jika lampu yang menyala sudah sampai di paling kiri , penekanan ke kiri akan membuat lampu paling kanan menyala
Perancangan
Pada artikel ini, solusi yang dibuat memiliki sifat berikut
even triggered, input penekanan tombol menyebabkan terjadinya interupsi yang akan memanggil Finite State Machine (FSM)
FSM bersifat asinkron. Transisi/ reaksi FSM ditrigger oleh penekanan tombol
Perilaku sistem yang diharapkan dapat dimodelkan dengan menggunakan Timing Diagram (diagram waktu).. Untuk sederhananya dimulai dulu dengan kasus lampu hanya digeser ke 1 arah saja.
Diagram waktu lampu geser kanan 1 arah
Model Flowchart (Diagram Alir)
Model State Chart
State chart lampu geser asinkron
Video demo
Hasil
Lampu sudah dapat bergeser kiri kanan sesuai penekanan tombol
Masih terjadi bouncing, yaitu penekanan tombol satu kali menghasilkan pergeseran lampu lebih dari satu. Solusinya mesti ditambahkan fitur debouncing.
Lampiran
Implementasi perangkat lunak
/*
lampu geser dengan input event-triggerred dari interupsi eksternal
FSM dengan model asinkron
*/
#define OUT1 12
#define OUT2 11
#define OUT3 10
#define OUT4 9
#define STATE1 101
#define STATE2 102
#define STATE3 103
#define STATE4 104
#define EVENT_A 201
#define EVENT_B 202
int state = STATE1;
// the setup function runs once when you press reset or power the board
void setup() {
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
pinMode(OUT1, OUTPUT);
pinMode(OUT2, OUTPUT);
pinMode(OUT3, OUTPUT);
pinMode(OUT4, OUTPUT);
pinMode(2, INPUT_PULLUP);
pinMode(3, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(2), Pin2_isr, FALLING );
attachInterrupt(digitalPinToInterrupt(3), Pin3_isr, FALLING );
// initial state
state = STATE1;
digitalWrite(OUT1, HIGH);
}
void Pin2_isr() {
fsm(EVENT_B);
}
void Pin3_isr() {
fsm(EVENT_A);
}
int fsm(int event) {
switch (state) {
case STATE1: {
if (event == EVENT_A) {
state = STATE2;
digitalWrite(OUT1, LOW);
digitalWrite(OUT2, HIGH);
digitalWrite(OUT3, LOW);
digitalWrite(OUT4, LOW);
} else if (event == EVENT_B)
{
state = STATE4;
digitalWrite(OUT1, LOW);
digitalWrite(OUT2, LOW);
digitalWrite(OUT3, LOW);
digitalWrite(OUT4, HIGH);
}
break;
}
case STATE2: {
if (event == EVENT_A) {
state = STATE3;
digitalWrite(OUT1, LOW);
digitalWrite(OUT2, LOW );
digitalWrite(OUT3, HIGH);
digitalWrite(OUT4, LOW);
} else if (event == EVENT_B)
{
state = STATE1;
digitalWrite(OUT1, HIGH);
digitalWrite(OUT2, LOW);
digitalWrite(OUT3, LOW);
digitalWrite(OUT4, LOW);
}
break;
}
case STATE3: {
if (event == EVENT_A) {
state = STATE4;
digitalWrite(OUT1, LOW);
digitalWrite(OUT2, LOW );
digitalWrite(OUT3, LOW);
digitalWrite(OUT4, HIGH);
} else if (event == EVENT_B)
{
state = STATE2;
digitalWrite(OUT1, LOW);
digitalWrite(OUT2, HIGH);
digitalWrite(OUT3, LOW);
digitalWrite(OUT4, LOW);
}
break;
}
case STATE4: {
if (event == EVENT_A) {
state = STATE1;
digitalWrite(OUT1, HIGH);
digitalWrite(OUT2, LOW);
digitalWrite(OUT3, LOW);
digitalWrite(OUT4, LOW);
} else if (event == EVENT_B)
{
state = STATE3;
digitalWrite(OUT1, LOW);
digitalWrite(OUT2, LOW);
digitalWrite(OUT3, HIGH);
digitalWrite(OUT4, LOW);
}
break;
}
default: {
break;
}
}
}
void loop() {
}
Charger 5V 2A Berapa watt? Berapakah daya yang keluar dari charger 5 volt 2 ampere?
Perhitungan daya dapat dilakukan dengan rumus berikut ini:
P=V x I
Dengan
P (daya) dengan satuan watt
V (tegangan) dengan satuan volt
I (arus) dengan satuan ampere
Jadi jawabannya:
P = V x I = 5 x 2 = 10 watt.
Jawaban ini adalah dengan asumsi efisiensi 100%. Pada prakteknya efisiensi charger berkisar antara 80% ~ 95%, jadi daya yang masuk ke charger dari jala-jala listrik 220 V lebih tinggi sedikit dari daya yang keluar (5 volt 2 ampere).
Ilustrasi charger USB 5 volt dengan kemampuan arus bermacam-macam