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

Tajuk Pengajaran Sistem Embedded

Berikut ini beberapa tajuk yang dapat diajarkan di kelas sistem embedded.

Embedded:
– mengukur memory usage di stack
– apa yang terjadi kalau stack terlalu kecil pada sebuah task
– apa yang terjadi jika suatu resource diakses bersamaan oleh beberapa buah task

Tools pada pengembangan sistem embedded
– GIT: source control
– Unit Testing

Tajuk advanced:
– keamanan sistem embedded
– kriptografi sederhana
– machine learning & sistem embedded

Tugas Perancangan:
– metodologi desain
– pemodelan sistem
– multi tasking
– benchmark komputasi di PC dan di mikrokontroler
– pengujian algoritma di PC dan mikrokontroler

Praktikum:
– pengolahan sinyal LTI
– kendali LTI
– kendali FSM
– kendali hybrid

 

Istilah Impedansi

ada beberapa pengertian impedansi, yg saya ingat 3:
  • impedansi listrik pada rangkaian listrik, misal resistor + kapasitor + induktor yg dibuat menjadi suatu rangkaian. impedansi ini adalah perbandingan arus & tegangan pada komponen tersebut.
  • impedansi saluran transmisi, misal pada kabel koaksial, kabel twisted pair. impedansi ini adalah perbandinga L dan C pada kabel tersebut. impedansi ini dikenal juga sebagai ‘impedansi karakteristik’
  • impedansi pada gelombang elektromagnetik, ini adalah perbandingan kuat medan listrik & medan magnet. impedansi ini dikenal juga sebagai ‘wave impedance’.

Referensi

 

Definisi Cyber Physical System Secara Bahasa

Berikut ini uraian istilah Cyber Physical System atau “Sistem Fisik Siber” menurut bahasa atau arti kata. Definisi dalam dunia engineering dapat dibaca di artikel “Pengertian Cyber Physical System

Konsep Cyber Physical System
Konsep Cyber Physical System (https://ptolemy.berkeley.edu/projects/cps/)

Definisi “Cyber”:

  • of, relating to, or involving computers or computer networks (such as the Internet)
  • computer : computer network

Referensi: https://www.merriam-webster.com/dictionary/cyber

Definisi “Siber”

  • sistem komputer dan informasi
  • dunia maya
  • berhubungan dengan internet

Referensi: https://kbbi.kemdikbud.go.id/entri/siber

Definisi “Physical”

  • of or relating to natural science
  • having material existence : perceptible especially through the senses and subject to the laws of nature
  • of or relating to the body

Referensi:  https://www.merriam-webster.com/dictionary/physical

Definisi “Fisik”

  • jasmani, badan
  • jasmaniah, badaniah

Sumber: https://kbbi.kemdikbud.go.id/entri/fisik

Definisi “System”

  • a regularly interacting or interdependent group of items forming a unified whole

Referensi: https://www.merriam-webster.com/dictionary/system

Definisi “Sistem”

  • perangkat unsur yang secara teratur saling berkaitan sehingga membentuk suatu totalitas:
  • susunan yang teratur dari pandangan, teori, asas, dan sebagainya
  • metode

Referensi: https://kbbi.kemdikbud.go.id/entri/sistem

Referensi