Lampu On Off Dengan 1 Sakelar

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.

  1. LED mati: ditekan 1x pendek (kurang dari 1 detik) maka LED menyala
  2. LED mati: ditekan 1x panjang (lebih dari 1 detik) -> LED menyala
  3. LED menyala: ditekan & ditahan selama 1 detik -> LED mati
  4. LED menyala: ditekan kurang dari 1 detik -> LED tetap menyala
  5. LED menyala: ditekan & ditahan selama lebih dari 1 detik -> LED mati dalam 1 detik, setelah itu tetap mati
  6. LED menyala: switch ditekan berkali-kali pendek -> LED tetap menyala (frekuensi di bawah batas tertentu)
  7. 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:

  1. Kondisi awal mati
  2. Tunggu ada tombol ditekan. Jika ada , nyalakan lampu.
  3. Tunggu tombol ditekan lama. Jika ada, matikan lampu. Abaikan input lain.
  4. Kembali ke (2)

Model State Chart

Sketsa state chart

State diagram sistem versi final

Implementasi Perangkat Keras

Implementasi Perangkat Lunak

Kode implementasi dapat dilihat di https://github.com/waskita/embedded/blob/master/on-off-switch/nano-on-off/nano-on-off.ino

Pengujian

 

 

 

 

Contoh Implementasi Finite State Machine Dengan Mikrokontroler

Berikut ini beberapa contoh implementasi FSM dengan mikrokontroler. Urutan contoh ini mulai dari yang paling mudah, sampai yang paling sulit.

  1. Lampu kedip berbasis FSM dengan delay. Pada contoh ini dibuat lampu kedip dengan duty cycle 50%
  2. Lampu kedip berbasis FSM dengan interupsi Timer 1
  3. Lampu kedip berbasis FSM dengan FreeRTOS
  4. Lampu kedip duty cycle 10% dengan model FSM biasa
  5. Lampu kedip duty cycle 10% dengan model Extended State Machine
  6. Lampu on-off (toggle) dengan input switch
  7. Lampu on-off (toggle) dengan fitur debounce dan model extended state machine
  8. Lampu on-off (toggle) dengan fitur debounce dan model cascade composition
  9. Lampu on off (tekan lama) dengan extended state machine
  10. Lampu on-off (tekan ganda)
  11. Lampu on-off dengan 2 tombol
  12. Lampu lalu lintas jalan dengan extended state machine. Contoh ini adalah implementasi Example 3.9 di buku Lee & Seshia “Introduction to Embedded Systems”.
  13. Lampu lalu lintas untuk kendaraan dan penyeberang jalan dengan model extended state machine.  Contoh ini adalah implementasi Example 5.9 di buku Lee & Seshia “Introduction to Embedded Systems”.
  14. Lampu geser dengan arsitektur event triggered
  15. Lampu geser dengan arsitektur time triggered
  16. Kendali pintu otomatis dengan supervisory control

Unit Test untuk C/C++

Berikut ini beberapa library unit test untuk bahasa pemrograman C atau C++

Unity Unit Test

CppUTest

Google Test

 

Aplikasi Untuk Menggambar Rangkaian Elektronika

Berikut ini beberapa aplikasi untuk menggambar rangkaian elektronika.

Falstadt

Alamat situs: https://www.falstad.com/circuit/

Aplikasi ini hanya ada versi online.

Aplikasi ini dapat dipakai untuk menggambar rangkaian dan animasi simulasi rangkaian.

Logicly

Alamat website: https://logic.ly/

Aplikasi ini berbayar. Ada versi demonya di https://logic.ly/demo

Aplikasi ini hanya ada versi online.

Aplikasi ini dapat dipakai untuk menggambar rangkaian dan animasi simulasi rangkaian.

Logisim

Alamat website: http://www.cburch.com/logisim/

Aplikasi ini diinstall di desktop.

Komponen Elektronika di Persenjataan Rusia

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.

Rudal jelajah Iskander
Rudal jelajah Iskander [sumber]

Maket rudal jelajah 3m-54 Kalibr

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“.

Chip MAX1480 buatan MAXIM dari rudal jelajah 9M727. MAX1480 fungsinya adalah “Complete, Isolated RS-485/RS-422 Data Interface

Cypress semiconductor dari onboard computer

Berikut ini modul pengendali dari misil 9M727 Kalibr berbasis DSP (Digital Signal Processor) dari Texas Instrument. Modul ini dilengkapi dengan sirip pendingin di sekitarnya.

Sumber:

 

Membuat Filter Digital dari Fungsi Transfer Dengan Transformasi Bilinear

Pada tulisan ini akan diuraikan bagaimana membuat filter digital dalam bahasa C dari persamaan filter dalam transformasi Laplace. Contoh ini diadaptasi dari Example 8.4 di buku  “Lizhe Tan, Digital Signal Processing, Fundamentals and Applications” halaman 324.

Misal diketahui suatu filter dalam domain s (Laplace) dengan persamaan sebagai berikut:

\(H(s)=\frac{10}{s+10} \)

Untuk mengubah ke bentuk digital, kita perlu tentukan perioda sampling. Misal dipilih perioda sampling T=0.01 detik

Persamaan transformasi s ke z sebagai berikut

\( s=\frac{2(z -1) }{Tz + 1} \)

H(s) diubah ke H(z) dengan cara  substitusi s pada H(s). T=0.01 dimasukkan ke persamaan transformasi. Maka didapat persamaan berikut:

\( H(z)=\frac{10}{\frac{200(z-1)}{z+1}+10 } \)
\( H(z)=\frac{0.05}{\frac{z-1}{z+1}+0.05 } \)
\( H(z)=\frac{0.05(z+1)}{z-1+0.05(z+1) } \)
\( H(z)=\frac{0.05z+0.05}{1.05z – 0.95 } \)
\( H(z)=\frac{(0.05z+0.05)/1.05z}{(1.05z – 0.95)/1.05z } \)

Didapatkan H(z) dengan bentuk standar.

\( H(z)=\frac{0.0476+0.0476z^{-1}}{1 – 0.9048 z^{-1} } \)

Selanjutnya terapkan teknik di Bab 6 (Example 6.5) untuk mengubah persamaan dalam domain (z) ke domain waktu (n).

Akan didapat persamaan difference dalam n sebagai berikut:

y(n)=0.0476 x(n) + 0.0476 x(n-1) + 0.9048 y(n-1)

 

Simulasi

Tahap selanjutnya adalah simulasi persamaan difference tersebut dengan input fungsi step.

Tahap simulasi ini penting untuk mengecek apakah filter digital yang dihasilkan memiliki perilaku yang sama dengan filter analog di awal. Jika hasilnya berbeda, ada kemungkinan salah perhitungan atau salah koding.

Simulasi dapat dilakukan dengan bahasa pemrograman apa saja, misal C, C++, Matlab, Python, dan sebagainya.

Simulasi di bawah ini dibuat dengan bahasa Python. GUI yang dipakai adalah Jupyter Notebook

import matplotlib
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.ticker import AutoMinorLocator
from matplotlib import gridspec
import matplotlib.ticker as ticker

%matplotlib inline
t=-1 # start time at -1
xn=0
xn1=0
yn1=0
period=0.01

times=np.linspace(-1, 10, 111).reshape(111, 1)
xs=[]
ys=[]
ts=[]
for counter in range(0,200):
    if t<0:
        xn=0        
    else:
        xn=1    
    t=t+period
    xs.append(xn)                    
    y=0.04676 * xn + 0.0476 * xn1 + 0.9048 * yn1
    ys.append(y)
    ts.append(t)
    yn1=y
    xn1=xn
fig = plt.figure(figsize=(8,4))
gs = gridspec.GridSpec(1,1)
ax1 = fig.add_subplot(gs[0])
ax1.plot(ts,xs,"g-",label="input x")
ax1.plot(ts,ys,"r-",label="output y")
ax1.plot(1/10,.632,"bo",label="output y")
ax1.set_xlabel("waktu",family="serif",  fontsize=12)
ax1.set_ylabel("value",family="serif",  fontsize=12)
ax1.legend(loc='best')
fig.tight_layout()
plt.grid(True)
fig.savefig("blt-step.jpg", format="jpg",dpi=65)

Berikut ini output sistem (merah) terhadap input step (warna hijau).

time constant = 1/10

Titik biru adalah t = time constant, dengan value = 63.2%. Posisi titik biru ini pada grafik merah, sehingga dapat disimpulkan respon sistem ini cocok dengan yang diharapkan.

Selanjutnya adalah memberi sinyal sinusoidal dengan frekuensi = frekuensi cut-off ke filter tersebut . Menurut teori, amplitudo pada steady state adalah 0.707 x amplitudo maksimum.

Berikut ini kode untuk memberikan sinyal sinusoida.

t=-1 # start time at -1
xn=0
xn1=0
yn1=0
period=0.01

times=np.linspace(-1, 10, 111).reshape(111, 1)
xs=[]
ys=[]
ts=[]
w=10
for counter in range(0,200):    
    t=t+period
    xn=math.sin(w*t)
    xs.append(xn)                    
    y=0.04676 * xn + 0.0476 * xn1 + 0.9048 * yn1
    ys.append(y)
    ts.append(t)
    yn1=y
    xn1=xn

Berikut ini kode untuk menampilkan grafik sinyal

fig = plt.figure(figsize=(8,4))
gs = gridspec.GridSpec(1,1)
ax1 = fig.add_subplot(gs[0])
ax1.plot(ts,xs,"g-",label="input x")
ax1.plot(ts,ys,"r-",label="output y")
ax1.set_xlabel("waktu",family="serif",  fontsize=12)
ax1.set_ylabel("value",family="serif",  fontsize=12)
ax1.legend(loc='best')
fig.tight_layout()
plt.grid(True)
fig.savefig("blt-sinusoidal.jpg", format="jpg",dpi=65)

Grafik tersebut menunjukkan amplitudo output (merah) ada di sekitar 0.7 dari amplitudo sinyal input (hijau). Terjadi pergeseran fasa sekitar 45 derajat.

Implementasi Bahasa C di Windows

Tahap selanjutnya adalah membuat implementasi filter dengan bahasa C.

Compiler yang digunakan adalah CodeBlocks

Berikut ini kode filter digital dalam bahasa C.

Output program ini adalah file win10-filter.csv

#include <stdio.h>
#include <stdlib.h>

// inisialisasi filter digital

void filter_init(float *xn1,float *yn1)
{
    *yn1=0;
    *xn1=0;
}

// hitung output filter digital filter digital
// delayed variabel diberikan sebagai parameter
float filter_run(float *xn,float *xn1,float *yn1)
{
    float y;
    y=0.04676 * *xn + 0.0476 * *xn1 + 0.9048 * *yn1;
    *yn1=y;
    *xn1=*xn;
    return y;
}

int main()
{
    FILE * fp;
    float y,xn,xn1,yn1;
    int i;
    float t;
    float period;
    t=-1;
    period=0.01;

    fp = fopen ("win10-filter.csv", "w+");
    filter_init(&xn1,&yn1);

    for (i=0; i<200; i++)
    {
        t=t+period;
        if(t<0)
        {
            xn=0;
        }
        else
        {
            xn=1;
        }
        y=filter_run(&xn,&xn1,&yn1);
        fprintf(fp,"%f,%f,%f\n",t,xn,y);
    }
    fclose(fp);
    return 0;
}

Berikut ini grafik dari file csv dengan Excel

Bentuk grafik sesuai dengan grafik di Python. Nilai output csv dapat dibandingkan dengan simulasi di Python. Hasilnya sesuai.

Implementasi Bahasa C di ATmega328

Implementasi filter di ATmega328 diperlukan jika kita membuat filter digital atau membuat simulator plant untuk Hardware In the Loop (HIL)

under construction

Implementasi Bahasa C di ESP32

Implementasi filter di ESP32diperlukan jika kita membuat filter digital atau membuat simulator plant untuk Hardware In the Loop (HIL)

under construction

Catatan

Referensi

  • Lizhe Tan, Digital Signal Processing, Fundamentals and Applications 3rd edition, Academic Press 2019
  • Matlab FIR Filter https://os.mbed.com/handbook/Matlab-FIR-Filter

Kendali Lampu di ThingsBoard Dengan Remote Procedure Call

Pada tulisan ini diuraikan cara mengendalikan lampu secara wireless dengan ThingsBoard. Mikroprosesor yang dipakai adalah ESP32. Metode yang dipakai adalah RPC (Remote Procedure Call)

 

ESP32 di breadboard dengan 3 buah LED biruBerikut ini kode firmware untuk ESP32. Inspirasi kode dari “ESP32 Pico Kit GPIO Control and DHT22 sensor monitor using ThingBoard Arduino SDK

Parameter yang perlu disesuaikan:

  • WIFI_AP_NAME adalah nama access point
  • WIFI_PASSWORD adalah password WiFi yang dipakai
  • TOKEN adalah kode token dari perangkat. Diambil dari ThingsBoard
#include <WiFi.h>           // WiFi control for ESP32
#include <ThingsBoard.h>    // ThingsBoard SDK

// 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        "WIFI_AP_NAME        "
// WiFi password
#define WIFI_PASSWORD       "WIFI_PASSWORD       "

// See https://thingsboard.io/docs/getting-started-guides/helloworld/
// to understand how to obtain an access token
#define TOKEN               "yd8R3K3GE61Drm7TtvgF"
// ThingsBoard server instance.
#define THINGSBOARD_SERVER  "192.168.0.90"

#define ONBOARD_LED 22
// 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;

// Array with LEDs that should be controlled from ThingsBoard, one by one
uint8_t leds_control[] = { 12, 13, 27 };

// Main application loop delay
int quant = 20;

// Initial period of LED cycling.
int led_delay = 1000;
// Period of sending a temperature/humidity data.
int send_delay = 2000;

// Time passed after LED was turned ON, milliseconds.
int led_passed = 0;
// Time passed after temperature/humidity data was sent, milliseconds.
int send_passed = 0;

// Set to true if application is subscribed for the RPC messages.
bool subscribed = false;
// LED number that is currenlty ON.
//int current_led = 0;

// Processes function for RPC call "setGpioStatus"
// RPC_Data is a JSON variant, that can be queried using operator[]
// See https://arduinojson.org/v5/api/jsonvariant/subscript/ for more details
RPC_Response processSetGpioState(const RPC_Data &data)
{
  Serial.println("Received the set GPIO RPC method");
  int pin = data["pin"];
  bool enabled = data["enabled"];
  if (pin < COUNT_OF(leds_control)) {
    Serial.print("Setting LED ");
    Serial.print(pin);
    Serial.print(" to state ");
    Serial.println(enabled);
    digitalWrite(leds_control[pin], enabled);
  }
  return RPC_Response(data["pin"], (bool)data["enabled"]);
}

// RPC handlers
RPC_Callback callbacks[] = {
  { "setGpioStatus",    processSetGpioState },
};

// Setup an application
void setup() {
  // Initialize serial for debugging
  Serial.begin(SERIAL_DEBUG_BAUD);
  WiFi.begin(WIFI_AP_NAME, WIFI_PASSWORD);
  InitWiFi();

  for (size_t i = 0; i < COUNT_OF(leds_control); ++i) {
    pinMode(leds_control[i], OUTPUT);
  }
  pinMode(ONBOARD_LED, OUTPUT); \

// LED check
  digitalWrite(leds_control[0], HIGH);
  delay(500);
  digitalWrite(leds_control[1], HIGH);
  delay(500);
  digitalWrite(leds_control[2], HIGH);
  delay(500);
  digitalWrite(leds_control[0], LOW);
  delay(500);
  digitalWrite(leds_control[1], LOW);
  delay(500);
  digitalWrite(leds_control[2], LOW);
  delay(500);
}

// Main application loop
void loop() {
  delay(quant);
  led_passed += quant;
  send_passed += quant;
  // Reconnect to WiFi, if needed
  if (WiFi.status() != WL_CONNECTED) {
    reconnect();
    return;
  }
  // Reconnect to ThingsBoard, if needed
  if (!tb.connected()) {
    subscribed = false;
    // 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;
    }
  }
  // Subscribe for RPC, if needed
  if (!subscribed) {
    Serial.println("Subscribing for RPC...");
    // Perform a subscription. All consequent data processing will happen in
    // callbacks as denoted by callbacks[] array.
    if (!tb.RPC_Subscribe(callbacks, COUNT_OF(callbacks))) {
      Serial.println("Failed to subscribe for RPC");
      return;
    }
    Serial.println("Subscribe done");
    subscribed = true;
  }

  if (send_passed > send_delay) {
    send_passed = 0;
  }
  // Process messages
  tb.loop();


  static int blink_counter = 0;
  if (blink_counter < 50) {
    digitalWrite(ONBOARD_LED, LOW);
  } else {
    digitalWrite(ONBOARD_LED, HIGH);
  }
  blink_counter++;
  if (blink_counter >= 100) {
    blink_counter = 0;
  }
}

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");
  }
}

Berikut ini software PHP untuk mengendalikan LED dari Windows/Ubuntu

 

<?php

// kendali LED dengan REST API
// Create a new cURL resource
// Setup request to send json via POST
// login untuk mendapatkan JWT

$url = 'http://192.168.0.90:8080/api/auth/login';
$body_array = array();
$body_array["username"] = "[email protected]";
$body_array["password"] = "tenant";
$body = json_encode($body_array);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json', 'Accept: application/json'));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);
print_r($result);

$result_array = json_decode($result, true);
print_r($result_array);
$token = $result_array["token"];
printf("token %s\n", $result_array["token"]);

// sekarang kirim command pakai token

function SetGpio($led_index, $value, $token) {
    $url = 'http://192.168.0.90:8080/api/rpc/twoway/e048cf90-cacc-11ec-84b1-a3192844351e';
    $params = array();
    $params["pin"] = $led_index;
    $params["enabled"] = $value;
    $body_array = array();
    $body_array["method"] = "setGpioStatus";
    $body_array["params"] = $params;
    $body_array["persistent"] = false;
    $body_array["timeout"] = 5000;
    $body = json_encode($body_array);
    $header = array();
    $header[] = 'Content-Type:application/json';
    $header[] = 'Accept: application/json';
    $header[] = 'X-Authorization: Bearer ' . $token;

    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $result = curl_exec($ch);
    curl_close($ch);
    print_r($result);
}

while (1) {
    SetGpio(0, 1, $token);
    usleep(50000);
    SetGpio(0, 0, $token);
    usleep(50000);
    SetGpio(1, 1, $token);
    usleep(50000);
    SetGpio(1, 0, $token);
    usleep(50000);
    SetGpio(2, 1, $token);
    usleep(50000);
    SetGpio(2, 0, $token);
    usleep(50000);
}

Sensor HTU21D Temperatur & Kelembaban

Referensi:

Contoh Program untuk ESP32

 

// library: https://github.com/adafruit/Adafruit_HTU21DF_Library
#define I2C_SDA 15
#define I2C_SCL 13

#include <Wire.h>
#include "Adafruit_HTU21DF.h"

// Connect Vin to 3-5VDC
// Connect GND to ground
// Connect SCL to I2C clock pin (13)
// Connect SDA to I2C data pin (15)

Adafruit_HTU21DF htu = Adafruit_HTU21DF();

void setup() {
  Serial.begin(115200);
  Serial.println("HTU21D-F test");
  Wire.begin(I2C_SDA, I2C_SCL);
  if (!htu.begin()) {
    Serial.println("Couldn't find sensor!");
    while (1);
  }
}

void loop() {
  float temp = htu.readTemperature();
  float rel_hum = htu.readHumidity();
  Serial.print("Temp: "); Serial.print(temp); Serial.print(" C");
  Serial.print("\t\t");
  Serial.print("Humidity: "); Serial.print(rel_hum); Serial.println(" \%");
  delay(500);
}

Sensor Temperatur MCP9808

Contoh kode ESP32 untuk menghubungkan MCP9808 ke ThingsBoard. Kode ini menggunakan library MCP9808 dari Adafruit

// CJMCU-9808
// Adafruit MCP9808 Library https://github.com/adafruit/Adafruit_MCP9808_Library

#include <WiFi.h>           // WiFi control for ESP32
#include <ThingsBoard.h>    // ThingsBoard SDK
#include <Wire.h>
#include "Adafruit_MCP9808.h"
#include <Arduino.h>
#include <Wire.h>

Adafruit_MCP9808 tempsensor = Adafruit_MCP9808();

// WiFi access point
#define WIFI_AP_NAME        "WIFI_AP_NAME"
// WiFi password
#define WIFI_PASSWORD       "WIFI_PASSWORD"
#define TOKEN               "THINGSBOARD_TOKEN"

#define BUILTIN_LED 22
// ThingsBoard server instance.
#define THINGSBOARD_SERVER  "192.168.0.90"

#define I2C_SDA 15
#define I2C_SCL 13

// 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);
  // put your setup code here, to run once:
  Serial.begin(115200);
  delay(1000);

  //wait for serial connection to open (only necessary on some boards)
  while (!Serial);

  Wire.begin(I2C_SDA, I2C_SCL);

  I2C_Scan() ; // just for verifying

  if (!tempsensor.begin(0x18)) {
    Serial.println("Couldn't find MCP9808! Check your connections and verify the address is correct.");
    while (1);
  }
  tempsensor.setResolution(3);

  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());
}

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) {
//    Serial.println("wake up MCP9808.... "); // wake up MCP9808 - power consumption ~200 mikro Ampere
    tempsensor.wake();   // wake up, ready to read!

    // Read and print out the temperature, also shows the resolution mode used for reading.
    //    Serial.print("Resolution in mode: ");
    //    Serial.println (tempsensor.getResolution());
    float c = tempsensor.readTempC();
    //    Serial.print("Temp: ");
    //    Serial.print(c, 4);
    //    Serial.print("*C\t and ");
    //    Serial.println("Shutdown MCP9808.... ");
    tempsensor.shutdown_wake(1); // shutdown MSP9808 - power consumption ~0.1 mikro Ampere, stops temperature sampling
//    Serial.println("");

    Serial.print("Sending telemetry data...");
    Serial.print("Temp ");
    Serial.print(c);
    Serial.println(" ");
    tb.sendTelemetryFloat("temperature", c);
    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 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");
  }
}

update: ditambah dengan watch dog timer

// CJMCU-9808
// Adafruit MCP9808 Library https://github.com/adafruit/Adafruit_MCP9808_Library

#include <WiFi.h>           // WiFi control for ESP32
#include <ThingsBoard.h>    // ThingsBoard SDK
#include <Wire.h>
#include "Adafruit_MCP9808.h"
#include <Arduino.h>
#include <Wire.h>
#include <esp_task_wdt.h>

Adafruit_MCP9808 tempsensor = Adafruit_MCP9808();

#define WDT_TIMEOUT 60
#define WIFI_AP_NAME        "abc" // WiFi access point
#define WIFI_PASSWORD       "123"
#define TOKEN               "jiowre43278feowjk4"

#define BUILTIN_LED 22
// ThingsBoard server instance.
#define THINGSBOARD_SERVER  "192.168.0.114"

#define I2C_SDA 15
#define I2C_SCL 13

// 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);
  // put your setup code here, to run once:
  Serial.begin(115200);
  delay(1000);
  Serial.print(__FILE__);
  //wait for serial connection to open (only necessary on some boards)
  while (!Serial);

  Wire.begin(I2C_SDA, I2C_SCL);

  I2C_Scan() ; // just for verifying

  if (!tempsensor.begin(0x18)) {
    Serial.println("Couldn't find MCP9808! Check your connections and verify the address is correct.");
    while (1);
  }
  tempsensor.setResolution(3);

  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();
    sleep(5); // wait to reconnect
  }

  // 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) {
    //    Serial.println("wake up MCP9808.... "); // wake up MCP9808 - power consumption ~200 mikro Ampere
    tempsensor.wake();   // wake up, ready to read!

    // Read and print out the temperature, also shows the resolution mode used for reading.
    //    Serial.print("Resolution in mode: ");
    //    Serial.println (tempsensor.getResolution());
    float c = tempsensor.readTempC();
    //    Serial.print("Temp: ");
    //    Serial.print(c, 4);
    //    Serial.print("*C\t and ");
    //    Serial.println("Shutdown MCP9808.... ");
    tempsensor.shutdown_wake(1); // shutdown MSP9808 - power consumption ~0.1 mikro Ampere, stops temperature sampling
    //    Serial.println("");

    Serial.print("Sending telemetry data...");
    Serial.print("Temp ");
    Serial.print(c);
    Serial.println(" ");
    tb.sendTelemetryFloat("temperature", c);
    send_passed = 0;
    esp_task_wdt_reset(); // WDT reset setelah berhasil mengirim data
  }

  // 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 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");
  }
}

Referensi:

Proteksi Firmware pada Mikrokontroler ATmega328

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.

Referensi

Stabilizer 10 kVA Bisa Untuk Berapa Watt?

Ada pertanyaan:

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

 

 

 

 

Socomec Countis E13X Energy Meter

 

Foto

 

Referensi