Frekuensi DAC MCP4725 pada ESP32 C3

Pada percobaan ini diukur frekuensi & perioda konversi DAC tipe MCP4725 pada modul ESP32 C3 Luatos.

Rangkaian yang diuji

 

Kode Program

#include <Wire.h>
#include <Adafruit_MCP4725.h>
#include <Wire.h>

#define I2C_SDA 2
#define I2C_SCL 3

Adafruit_MCP4725 dac;

void setup(void) {
  int address = 0;
  int hasil;
  uint32_t speed = 1000000L;
  int status;
  speed = 3000000L;
  status = Wire.begin(I2C_SDA, I2C_SCL, speed);
  Serial.begin(115200);
  Serial.print("Hello! Wire Init status:");
  Serial.println(status);
  Serial.println(speed);

  address = 0x60;
  dac.begin(address);
  Serial.println("Search I2C");
  SearchI2C();
  Serial.println("Generating a triangle wave");
}
int start_sawtooth = 0;
int current_time;
int duration;
int time_begin;
int time_now;
uint32_t counter;

void loop(void) {
  dac.setVoltage(0, false);
  dac.setVoltage(4095, false);
  counter = counter + 1;
  if (counter >= 10000) {
    float period;
    int time_now = millis();
    counter = 0;
    duration = time_now - time_begin;
    period = duration / 10000.0 / 2;
    Serial.print("period (ms): ");
    Serial.println(period);
    //  prepare next round
    time_begin = time_now;
  }
}

void SearchI2C() {
  byte error, address;
  int nDevices;

  Serial.println("Scanning...");

  nDevices = 0;
  for (address = 1; address < 127; address++) {
    //    Serial.println(address, HEX);
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the 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.print(address, HEX);
      Serial.println("  !");

      nDevices++;
    } else if (error == 4) {
      Serial.print("Unknown 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");
}

Kode ada di https://github.com/waskita/embedded/tree/master/esp32-c3-mcp4725

Pengukuran

Pengukuran dilakukan dengan frekuensi clock I2C dari 100 kHz sampai 3 Mhz. Semua menghasilkan angka yang sama.

Sinyal keluaran MCP4725 diukur dengan osiloskop.

Didapat frekuensi sinyal output adalah 3,080 kHz. Jadi frekuensi update DAC adalah 6,16 kHz

period (ms): 0.17
period (ms): 0.16
period (ms): 0.16
period (ms): 0.16

Pengukuran perioda menghasilkan angka 0,16 ms

Kesimpulan

Frekuensi update DAC adalah 6,16 kHz

Perioda 0,16 ms

Referensi

Pengukuran Frekuensi ADC pada Arduino Nano ATmega328

Pengukuran Frekuensi ADC internal pada Arduino Nano ATmega328

berikut ini kode yang dipakai untuk pengukuran

int counter;  // how many iterations
int time_begin = 0;
int time_end = 0;
int duration;

int sensorPin = A0;   // select the input pin for the potentiometer
int ledPin = 13;      // select the pin for the LED

void setup() {
  Serial.begin(115200);
  counter = 0;
  pinMode(2, OUTPUT);
  Serial.println("start benchmark");
}
//---------------------------------------------------
void loop() {
  int value;  // angka yang ditulis
  value = 0;  // minimum value
  analogRead(sensorPin);
  PORTD=0; // langsung akses port supaya lebih cepat
  analogRead(sensorPin);
  PORTD=255;
  counter = counter + 1;
  if (counter >= 10000) {
    float period;
    int time_now = millis();
    counter = 0;
    duration = time_now - time_begin;
    period = duration / 10000.0 /2;
    Serial.print("period (ms): ");
    Serial.println(period);
    //  prepare next round
    time_begin = time_now;
  }
}

Hasil Pengukuran

Pengukuran output pada pin D2 dengan osiloskop menghasilkan sinyal berikut

Dari data port serial, didapatkan angka perioda 0,11 ms

start benchmark
period (ms): 0.11
period (ms): 0.11
period (ms): 0.11
period (ms): 0.11
period (ms): 0.11

Dengan osiloskop didapatkan sinyal kotak dengan frekuensi 4,45532 kHz . Artinya frekuensi ADC adalah dua kalinya, yaitu 8,91064 kHz

Angka 8900 Hz ini sesuai dengan pengukuran di artikel lain: https://chisight.wordpress.com/2016/03/25/speeding-up-the-adc-on-an-arduino-atmega-328p/

Kesimpulan

Frekuensi ADC adalah 8,91064 kHz

Frekuensi ini jauh di bawah kecepatan teoritis. Kemungkinan kelambatan karena library yang dipakai.

Referensi

  • Open Music Labs : ATmega ADC
  • https://www.ee-diary.com/2022/08/programming-atmega328p-adc-in-c.html#
  • https://chisight.wordpress.com/2016/03/25/speeding-up-the-adc-on-an-arduino-atmega-328p/
  • Kode di https://github.com/waskita/embedded/tree/master/nano-adc

Frekuensi DAC MCP4725 pada Arduino Nano ATmega328

Pada percobaan ini diukur frekuensi & perioda konversi DAC (Digital to Analog Converter) tipe MCP4725  pada modul Arduino Nano dengan prosesor ATmega328.

Rangkaian sistem adalah sebagai berikut

 

Kode yang dipakai untuk pengujian adalah sebagai berikut:

// idea from https://learn.sparkfun.com/tutorials/mcp4725-digital-to-analog-converter-hookup-guide/all
#define MCP4725_ADDR 0x60
#include <Wire.h>  //Include the Wire library to talk I2C

int counter;  // how many iterations
int time_begin = 0;
int time_end = 0;
int duration;
void setup() {
  Wire.begin();
  Serial.begin(115200);
  counter = 0;
  Serial.println("start benchmark");
}
//---------------------------------------------------
void loop() {
  int value;  // angka yang ditulis
  value = 0;  // minimum value
  Wire.beginTransmission(MCP4725_ADDR);
  Wire.write(64);                 // cmd to update the DAC
  Wire.write(value >> 4);         // the 8 most significant bits...
  Wire.write((value & 15) << 4);  // the 4 least significant bits...
  Wire.endTransmission();

  value = 4095;  // maximum value
  Wire.beginTransmission(MCP4725_ADDR);
  Wire.write(64);                 // cmd to update the DAC
  Wire.write(value >> 4);         // the 8 most significant bits...
  Wire.write((value & 15) << 4);  // the 4 least significant bits...
  Wire.endTransmission();

  counter = counter + 1;
  if (counter >= 10000) {
    float  period;
    int time_now = millis();
      counter = 0;
    duration = time_now - time_begin;
    period = duration / 10000.0 / 2.0 ;
    Serial.print("period (ms): ");
    Serial.println(period);
    //  prepare next round
    time_begin = time_now;
  }
}

I2C 100 kHz

ATmega328 menggunakan 2 frekuensi I2C: 100 kHz dan 400 kHz. Percoban pertama menggunakan kecepatan default adalah 100 kHz.

Sinyal yang dihasilkan pada output MCP4725 adalah sebagai berikut:

Tampilan pada serial monitor adalah sebagai berikut:

start benchmark
period (ms): 0.43
period (ms): 0.43
period (ms): 0.43
period (ms): 0.43
period (ms): 0.43
period (ms): 0.43

Pengukuran dengan osiloskop menunjukkan sinyal persegi dengan frekuensi 1,166 kHz

Jumlah transisi adalah 2x frekuensi ini, jadi frekuensi konversi adalah 1,166 x 2 = 2,332 kHz

I2C 400 kHz

Pada pengukuran ini, kecepatan I2C dinaikkan menjadi 400 kHz. Caranya menggunakan fungsi Wire.setClock()

Perioda menjadi 0,15 ms

start benchmark
period (ms): 0.15
period (ms): 0.15
period (ms): 0.15
period (ms): 0.15
period (ms): 0.15

Output DAC diukur dengan osiloskop, dengan hasil sebagai berikut

Frekuensi output adalah 3,41733 kHz, sehingga frekuensi DAC adalah 2x 3,417 = 6,834 kHz

Kesimpulan

Dengan clock I2C 100 kHz, didapatkan

  • Perioda konversi ADC adalah 0,43 ms
  • frekuensi konversi ADC adalah 2,332 kHz

Dengan clock I2C 400 kHz, didapatkan

  • Perioda konversi ADC adalah 0,15 ms
  • frekuensi konversi ADC adalah 6,384 kHz

Referensi

ADC dan DAC Populer

Berikut ini ADC yang populer dipakai

  • ADC internal di ATMega328
  • ADC internal di ESP32
  • VS1003
  • ADS1115
  • PCF8591
  • AD7705
  • HX711
  • ADC0804
  • ADS1256
  • ADS1232
  • MCP3008
  • MCP3201

Parameter yang perlu dibandingkan:

  • resolusi (bit)
  • tegangan input maksimum
  • sumber tegangan referensi (internal atau external)
  • tegangan minimum yang dapat diukur
  • jenis ADC (SAR, flash, dsb)
  • kebutuhan daya
  • frekuensi maksimum sampling
  • protokol komunikasi ke mikrokontroler

DAC yang populer dipakai:

  • DAC internal ESP32
  • VS1003
  • PCF8591
  • DAC0800
  • MCP4725

Parameter yang perlu dibandingkan:

  • resolusi (bit)
  • tegangan output maksimum
  • sumber tegangan referensi (internal atau external)
  • tegangan minimum yang dapat diukur
  • jenis ADC (SAR, flash, dsb)
  • kebutuhan daya
  • frekuensi maksimum sampling
  • protokol komunikasi ke mikrokontroler

Literatur

Maxim ADC App Notes, berisi:

  • AN1041: Understanding Integrating ADC
  • AN810: Understanding Flash ADCs
  • AN2102: Migrating from Integrating ADC Architectures to Sigma Delta

 

Perancangan dan Implementasi Low Pass Filter Digital Dengan ESP32

Perancangan Filter

Perancangan filter menggunakan tools dari https://fiiir.com/

Parameter yang digunakan:

  • Sampling rate: 20000 Hz
  • Cut off frequency 800 Hz
  • Transition bandwidth 1800 Hz
  • Window type : Blackman

Berikut ini karakteristik filter yang dapat dilihat di laman yang sama

Kode dalam bahasa Python untuk menghitung parameter filter dan konvolusinya juga dihasilkan dari laman yang sama, sebagai berikut:

from __future__ import print_function
from __future__ import division

import numpy as np

# Example code, computes the coefficients of a low-pass windowed-sinc filter.

# Configuration.
fS = 20000 # Sampling rate.
fL = 800 # Cutoff frequency.
N = 53 # Filter length, must be odd.

# Compute sinc filter.
h = np.sinc(2 * fL / fS * (np.arange(N) - (N - 1) / 2))

# Apply window.
h *= np.blackman(N)

# Normalize to get unity gain.
h /= np.sum(h)

print(h)

# Applying the filter to a signal s can be as simple as writing
# s = np.convolve(s, h)

Parameter filter yang dihasilkan adalah sebagai berikut  (sebagai Python array)

[-4.29317419e-20 -4.18549678e-21 -1.79819385e-05 -8.38178513e-05
 -2.28616892e-04 -4.79528638e-04 -8.51847897e-04 -1.33864303e-03
 -1.89910369e-03 -2.44776137e-03 -2.84740649e-03 -2.90866942e-03
 -2.39870072e-03 -1.06016948e-03  1.35995551e-03  5.07437980e-03
  1.02166209e-02  1.68050560e-02  2.47160945e-02  3.36720917e-02
  4.32479500e-02  5.28978134e-02  6.20002342e-02  6.99171799e-02
  7.60597872e-02  7.99523091e-02  8.12855501e-02  7.99523091e-02
  7.60597872e-02  6.99171799e-02  6.20002342e-02  5.28978134e-02
  4.32479500e-02  3.36720917e-02  2.47160945e-02  1.68050560e-02
  1.02166209e-02  5.07437980e-03  1.35995551e-03 -1.06016948e-03
 -2.39870072e-03 -2.90866942e-03 -2.84740649e-03 -2.44776137e-03
 -1.89910369e-03 -1.33864303e-03 -8.51847897e-04 -4.79528638e-04
 -2.28616892e-04 -8.38178513e-05 -1.79819385e-05 -4.18549678e-21
 -4.29317419e-20]

Simulasi dengan Python di Desktop

Berikut ini kode untuk simulasi filter tersebut di Jupyter Notebook dengan bahasa Python.

from __future__ import print_function
from __future__ import division

import numpy as np
import math
import matplotlib.pyplot as plt

# Example code, computes the coefficients of a low-pass windowed-sinc filter.

# Configuration.
fS = 20000 # Sampling rate.
fL = 800 # Cutoff frequency.
N = 53 # Filter length, must be odd.

# Compute sinc filter.
h = np.sinc(2 * fL / fS * (np.arange(N) - (N - 1) / 2))

# Apply window.
h *= np.blackman(N)

# Normalize to get unity gain.
h /= np.sum(h)

print(h)

# Applying the filter to a signal s can be as simple as writing
# s = np.convolve(s, h)

x = np.linspace(0,1, 20001)

# filter digital
signal_frequency=8000 # diubah-ubah sesuai keperluan
y=np.sin(x*2*math.pi * signal_frequency)
# Applying the filter to a signal s can be as simple as writing
y_out = np.convolve(y, h)
plt.figure(figsize=(16,6))
plt.plot(x, y_out[0:20001],label="output")
plt.plot(x, y[0:20001],label="input")
plt.title("signal:{} Hz".format(signal_frequency))
plt.legend()
plt.axis('tight')
plt.xlim([0, 0.01])
plt.savefig("simulasi-signal-{}.jpg".format(signal_frequency))

Hasil simulasi untuk frekuensi 8 Hz

Hasil simulasi untuk frekuensi 80 HzHasil simulasi untuk frekuensi 800 Hz

Hasil simulasi untuk frekuensi 8000 Hz

Simulasi dengan C di Desktop

Pada percobaan ini filter disimulasikan di Desktop PC untuk mengecek ketepatan perhitungan dibandingkan dengan versi Python.

Kode untuk simulasi C sebagai berikut:

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

int main()
{

#define ORDE_FILTER 53
int i,j,k;
FILE * fp;
char filename[100];
printf("Hello world!\n");
// simulasi 1 detik saja

float signal_frequency=8; // frekuensi input signal
float filter_coefficients[]= {-4.29317419e-20, -4.18549678e-21, -1.79819385e-05, -8.38178513e-05,
-2.28616892e-04, -4.79528638e-04, -8.51847897e-04, -1.33864303e-03,
-1.89910369e-03, -2.44776137e-03, -2.84740649e-03, -2.90866942e-03,
-2.39870072e-03, -1.06016948e-03, 1.35995551e-03, 5.07437980e-03,
1.02166209e-02, 1.68050560e-02, 2.47160945e-02, 3.36720917e-02,
4.32479500e-02, 5.28978134e-02, 6.20002342e-02, 6.99171799e-02,
7.60597872e-02, 7.99523091e-02, 8.12855501e-02, 7.99523091e-02,
7.60597872e-02, 6.99171799e-02, 6.20002342e-02, 5.28978134e-02,
4.32479500e-02, 3.36720917e-02, 2.47160945e-02, 1.68050560e-02,
1.02166209e-02, 5.07437980e-03, 1.35995551e-03, -1.06016948e-03,
-2.39870072e-03, -2.90866942e-03, -2.84740649e-03, -2.44776137e-03,
-1.89910369e-03, -1.33864303e-03, -8.51847897e-04, -4.79528638e-04,
-2.28616892e-04, -8.38178513e-05, -1.79819385e-05, -4.18549678e-21,
-4.29317419e-20
};
int orde_filter=ORDE_FILTER;
float y_history[ORDE_FILTER];
signal_frequency=8000;
sprintf(filename,"simulasi-%d.csv",(int)signal_frequency);
fp = fopen (filename, "w");
fprintf(fp,"time,y,y_out\n");

// zeros y_history
for (i=0; i<orde_filter; i++)
{
y_history[i]=0;
}
for (i=0; i<20000; i++)
{
printf(".");
float t,y;
t=(float)i/(float)20000; // time axis
y=sin(2 * M_PI *signal_frequency* t);
// fprintf(fp,"%f,%f\n",t,y);

// hitung history signal
for (j=orde_filter-1; j>=1; j--)
{
int src=j-1;
int dst=j;
y_history[dst]=y_history[src];
// printf("%d %d\n",src,dst);
}
y_history[0]=y;

// hitung konvolusi
float y_out=0;
for (k=0; k<orde_filter; k++)
{
// fprintf(fp,"%5.3f ",y_history[k]);
y_out=y_out+y_history[k]*filter_coefficients[k];
}
// fprintf(fp,"\n");
fprintf(fp,"%f,%f,%f\n",t,y,y_out);
}
fclose(fp);
return 0;
}



// https://www.tutorialspoint.com/c_standard_library/c_function_fprintf.htm

Output kode C tersebut berupa file *.csv

Visualisasi data di file *.csv dilakukan menggunakan Jupyter Notebook dengan kode sebagai berikut:

import pandas as pd
import math
import matplotlib.pyplot as plt

name="simulasi-8"
name="simulasi-80"
name="simulasi-800"
name="simulasi-8000"
df = pd.read_csv('../filter-simulasi-c/{}.csv'.format(name))

plt.figure(figsize=(16,6))
plt.plot(df["time"], df["y"],marker='o',label="input")
plt.plot(df["time"], df["y_out"],marker='o',label="output")
plt.legend()
plt.axis('tight')
plt.xlim([0, 0.001])
plt.savefig("visualisasi-{}.jpg".format(name))

Tampilan Visualisasi untuk sinyal 8 Hz

nampak sinyal 8 Hz tidak teredam

Tampilan Visualisasi untuk sinyal 80 Hz

sinyal 80 Hz nampak teredam sedikit sekali dan ada lag

Tampilan Visualisasi untuk sinyal 800 Hz

nampak sinyal 800 Hz teredam sekitar 50%

Tampilan Visualisasi untuk sinyal 8000 Hz

nampak sinyal 8000 Hz teredam hampir semuanya

Simulasi dengan C di ESP32

pada percobaan ini kode dijalankan di ESP32 namun input adalah simulasi bukan dari generator sinyal. Output direkam ke port serial, bukan ke osiloskop.

Kode ESP32 adalah sebagai berikut

#define ORDE_FILTER 53

void setup() {

  Serial.begin(115200);

  //

  int i, j, k;

  char filename[100];

  // simulasi 1 detik saja

  float signal_frequency = 8;  // frekuensi input signal

  float filter_coefficients[] = { -4.29317419e-20, -4.18549678e-21, -1.79819385e-05, -8.38178513e-05,

                                  -2.28616892e-04, -4.79528638e-04, -8.51847897e-04, -1.33864303e-03,

                                  -1.89910369e-03, -2.44776137e-03, -2.84740649e-03, -2.90866942e-03,

                                  -2.39870072e-03, -1.06016948e-03, 1.35995551e-03, 5.07437980e-03,

                                  1.02166209e-02, 1.68050560e-02, 2.47160945e-02, 3.36720917e-02,

                                  4.32479500e-02, 5.28978134e-02, 6.20002342e-02, 6.99171799e-02,

                                  7.60597872e-02, 7.99523091e-02, 8.12855501e-02, 7.99523091e-02,

                                  7.60597872e-02, 6.99171799e-02, 6.20002342e-02, 5.28978134e-02,

                                  4.32479500e-02, 3.36720917e-02, 2.47160945e-02, 1.68050560e-02,

                                  1.02166209e-02, 5.07437980e-03, 1.35995551e-03, -1.06016948e-03,

                                  -2.39870072e-03, -2.90866942e-03, -2.84740649e-03, -2.44776137e-03,

                                  -1.89910369e-03, -1.33864303e-03, -8.51847897e-04, -4.79528638e-04,

                                  -2.28616892e-04, -8.38178513e-05, -1.79819385e-05, -4.18549678e-21,

                                  -4.29317419e-20 };

  int orde_filter = ORDE_FILTER;

  float y_history[ORDE_FILTER];

  signal_frequency = 800;

//  signal_frequency = 80;

//  signal_frequency = 8;

  sprintf(filename, "simulasi-%d.csv", (int)signal_frequency);

  printf("time,y,y_out\n");

  // zeros y_history

  for (i = 0; i < orde_filter; i++) {

    y_history[i] = 0;

  }

  for (i = 0; i < 20000; i++) {

    float t, y;

    t = (float)i / (float)20000;  //  time axis

    y = sin(2 * M_PI * signal_frequency * t);

    //        fprintf(fp,"%f,%f\n",t,y);

    // hitung history signal

    for (j = orde_filter - 1; j >= 1; j--) {

      int src = j - 1;

      int dst = j;

      y_history[dst] = y_history[src];

      //            printf("%d %d\n",src,dst);

    }
  y_history[0] = y;
    // hitung konvolusi
    float y_out = 0;
    for (k = 0; k < orde_filter; k++) {
      y_out = y_out + y_history[k] * filter_coefficients[k];
    }

    //        fprintf(fp,"\n");

    printf("%f,%f,%f\n", t, y, y_out);

  }

}

void loop() {

  // put your main code here, to run repeatedly:

}

Output dari ESP32 direkam dengan software RealTerm ke sebuah file *.txt

File *.txt tersebut dirapikan dan disimpan sebagai *.csv

File *.csv ini kemudian divisualisasikan dengan Jupyter Notebook

Kode visualisasi sebagai berikut

# graph simulasi C filter
import pandas as pd
import math
import matplotlib.pyplot as plt

name="esp32-8.csv"
name="esp32-80.csv"
#name="esp32-800.csv"
#name="esp32-8000.csv"
df = pd.read_csv('{}'.format(name))

plt.figure(figsize=(16,6))
plt.plot(df["time"], df["y"],label="input")
plt.plot(df["time"], df["y_out"],label="output")
plt.legend()
plt.axis('tight')
plt.xlim([0, 0.1])
plt.title(name)
plt.savefig("visualisasi-{}.jpg".format(name))

Sinyal 8 Hz:

Sinyal 80 Hz

Sinyal 800 Hz

Sinyal 8000 Hz

Kesimpulan: output dari software LPF di ESP32 sama dengan output dari software C di Desktop

Profiling di ESP32

Pada percobaan ini waktu yang diperlukan untuk menghitung filter diukur di ESP32.

Pewaktuan menggunakan fungsi millis(). Fungsi millis() tidak 100% akurat. Untuk lebih tepat perlu interupsi timer, atau dengan osiloskop.

Kode profiling:

#define ORDE_FILTER 53
float buffer[100];
void setup() {
  int buffer_index = 0;
  int durasi;
  Serial.begin(115200);
  //
  long int i;
  int j, k;
  char filename[100];
  // simulasi 1 detik saja

  float signal_frequency = 8;  // frekuensi input signal
  float filter_coefficients[] = { -4.29317419e-20, -4.18549678e-21, -1.79819385e-05, -8.38178513e-05,
                                  -2.28616892e-04, -4.79528638e-04, -8.51847897e-04, -1.33864303e-03,
                                  -1.89910369e-03, -2.44776137e-03, -2.84740649e-03, -2.90866942e-03,
                                  -2.39870072e-03, -1.06016948e-03, 1.35995551e-03, 5.07437980e-03,
                                  1.02166209e-02, 1.68050560e-02, 2.47160945e-02, 3.36720917e-02,
                                  4.32479500e-02, 5.28978134e-02, 6.20002342e-02, 6.99171799e-02,
                                  7.60597872e-02, 7.99523091e-02, 8.12855501e-02, 7.99523091e-02,
                                  7.60597872e-02, 6.99171799e-02, 6.20002342e-02, 5.28978134e-02,
                                  4.32479500e-02, 3.36720917e-02, 2.47160945e-02, 1.68050560e-02,
                                  1.02166209e-02, 5.07437980e-03, 1.35995551e-03, -1.06016948e-03,
                                  -2.39870072e-03, -2.90866942e-03, -2.84740649e-03, -2.44776137e-03,
                                  -1.89910369e-03, -1.33864303e-03, -8.51847897e-04, -4.79528638e-04,
                                  -2.28616892e-04, -8.38178513e-05, -1.79819385e-05, -4.18549678e-21,
                                  -4.29317419e-20 };
  int orde_filter = ORDE_FILTER;
  float y_history[ORDE_FILTER];
  signal_frequency = 800;
  //  signal_frequency = 80;
  //  signal_frequency = 8;
  printf(“time,y,y_out\n”);

  // zeros y_history
  for (i = 0; i < orde_filter; i++) {
    y_history[i] = 0;
  }
  int time_start = millis();

  for (i = 0; i < 1000000L; i++) {
    float t, y;
    t = (float)i / (float)20000;  //  time axis
    y = sin(2 * M_PI * signal_frequency * t);
    //        fprintf(fp,”%f,%f\n”,t,y);

    // hitung history signal
    for (j = orde_filter – 1; j >= 1; j–) {
      int src = j – 1;
      int dst = j;
      y_history[dst] = y_history[src];
      //            printf(“%d %d\n”,src,dst);
    }
    y_history[0] = y;

    // hitung konvolusi
    float y_out = 0;
    for (k = 0; k < orde_filter; k++) {
      y_out = y_out + y_history[k] * filter_coefficients[k];
    }
    //        fprintf(fp,”\n”);
    //    Serial.print(“.”);
    buffer[buffer_index] = y_out;
    buffer_index++;
    if (buffer_index>100){
      buffer_index=0;
    }
  }
  int time_end = millis();
  durasi = time_end – time_start;
  Serial.println(“durasi”);
  Serial.println(durasi);
}

void loop() {
  // put your main code here, to run repeatedly:
}

Hasil profiling: kode memerlukan 16479 ms untuk menjalankan 1000000 kali perhitungan. jadi setiap perhitungan memerlukan 16.479 us

Konversi DAC di ESP32 memerlukan sekitar 20 us (pesimis), jadi jika kode sekuensial maka didapatkan perioda 36.479 us, atau frekuensi = 27413 Hz.

Frekuensi filter yang dirancang adalah 20000 Hz, jadi masih di bawah batas 27413 Hz.

Pengujian Dengan Sinyal Sesungguhnya

Pada percobaan ini kode dijalankan di ESP32 dengan input dari generator sinyal dan output diamati di osiloskop

Berikut ini implementasi rangkaian:

Implementasi filter digital dengan ESP32, MCP3008 dan level converter
Implementasi filter digital dengan ESP32, MCP3008 dan level converter

Implementasi software dapat dilihat di https://github.com/waskita/embedded/tree/master/esp32_mcp3008_baker_adc_dac_filter-timer

Sinual input didapat dari  generator sinyal GW Instek AFG-2012

Pengukuran output menggunakan osiloskop GW Instek-1152A-U

Berikut ini pengukuran pada frekuensi cut off = 100 Hz jauh di bawah frekuensi cut off.

Berikut ini pengukuran pada frekuensi cut off = 800 Hz. Amplitudo sinyal output sekitar 50% sinyal input.

Berikut ini pengukuran pada frekuensi 1600 Hz, jauh di atas cut off. Amplitudo sinyal output kecil sekali hampir tidak ada.

Berikut ini pengukuran pada frekuensi input 19200 Hz. Terjadi aliasing karena pada sistem ini tidak ada filter anti aliasing.

Referensi

Sensor Debu ZH03A

Sensor debu ZH03A dibuat oleh perusahaan Zhengzhou Winsen Electronics Technology Co., Ltd

Sensor debu ini dapat mengukur kadar debu pada ukuran PM1.0, PM2.5 dan PM10

Berikut ini foto sensor tersebut.

 

Foto tampak depan

Foto tampak samping

Tampak samping

Foto tampak atas

 

Referensi

Cara Membuat Tegangan -10 volt Sampai +10 volt

Permasalahan

Saya mau kontrol variabel dari tegangan negatif (-10) hingga (+10) DC menggunakan mikrokontroler (0 ~ 3,3 VDC). Rangkaian apa yang saya butuhkan?

Jawaban:

Untuk membangkitkan tegangan analog anda bisa pakai DAC (Digital to Analog Converter). Ada mikrokontroler yang sudah ada DACnya, misal ESP32. Kalau belum ada, bisa pakai DAC tambahan seperti MCP4725 . Jadi di sini kita sudah dapat tegangan analog 0 ~ 3,3 volt. Kemudian tegangan ini dikurangi dengan 1,65 volt dengan rangkaian penjumlah op-amp dan sumber tegangan -1,65 volt. Di sini kita dapat tegangan analog -1,65 V ~ 1,65V. Tegangan ini kemudian dikalikan dengan op-amp non inverting supaya menghasilkan rentang -10V ~ +10V.

3500 VA Berapa Watt

3500 VA artinya 3500 volt-ampere, yang mengindikasikan ukuran daya aparent (volt-ampere) dari perangkat atau sistem. Volt-ampere (VA) adalah hasil kali dari tegangan (volt) dan arus (ampere) yang mengalir dalam suatu rangkaian listrik.

Namun, penting untuk memahami bahwa daya tampak (VA) tidak sama dengan daya aktif (watt) yang sebenarnya digunakan oleh perangkat atau sistem. Faktor daya (power factor) digunakan untuk menggambarkan perbandingan antara daya aktif (watt) dan daya aparent (VA). Faktor daya dapat berkisar antara 0 hingga 1.

Jika kita asumsikan faktor daya adalah 1 (cos φ = 1), maka 3500 VA juga setara dengan 3500 watt (W), artinya perangkat atau sistem menggunakan atau menghasilkan daya sebesar 3500 watt. Namun, jika faktor daya lebih rendah dari 1, daya yang sebenarnya akan lebih rendah dari 3500 watt.

Jadi, 3500 VA berarti ukuran daya aparent (volt-ampere) dari perangkat atau sistem, tetapi untuk mengetahui daya aktif (watt) yang sebenarnya, Anda perlu mengetahui berapa sebenarnya faktor daya yang berlaku pada sistem anda.

Rumah dengan kapasitas daya 3500 VA biasanya menggunakan MCB (mini circuit breaker) dengan batas arus 16 ampere. Jadi sebenarnya dayanya adalah 2200 x 16 = 3520 VA, namun untuk mudahnya dibulatkan ke 3500 VA.

MCB merek Schneider dengan batas arus 16 ampere dengan latar belakang hitam tampak depan
MCB merek Schneider dengan batas arus 16 ampere

7700 VA Berapa Watt

Untuk mengkonversi volt-ampere (VA) menjadi watt (W), Anda perlu mengetahui faktor daya (power factor) dari perangkat atau sistem yang sedang Anda ukur. Faktor daya menggambarkan sejauh mana daya yang disalurkan oleh perangkat berkontribusi pada melakukan kerja yang berguna.

Faktor daya dapat bernilai 0 (minimum) sampai 1 (maksimum)

Jika di rumah/pabrik banyak menggunakan motor AC, maka faktor daya dapat turun sampai ke 0,7

Jika di rumah/pabrik banyak menggunakan komputer, biasanya faktor daya di sekitar 0,9

Angka 7700 VA ini biasanya hasil kali dari 220 volt x 35 ampere, artinya rumah dengan listrik 1 fasa dan MCB (mini circuit breaker) berkapasitas 35 ampere.

Namun, jika asumsi kita adalah faktor daya 1 (cos φ = 1), maka 7700 VA juga setara dengan 7700 watt (W). Ini berarti daya yang dikonsumsi atau dihasilkan oleh perangkat atau sistem adalah 7700 watt. Namun, jika faktor daya kurang dari 1, daya sebenarnya akan lebih rendah daripada VA tersebut.

Perlu diperhatikan bahwa faktor daya pada umumnya berbeda untuk berbagai perangkat dan sistem.

Induktor

Induktor adalah suatu komponen elektronik yang terdiri dari kumparan kawat atau kabel yang dililitkan pada suatu inti, biasanya terbuat dari bahan ferromagnetik atau bahan non-magnetik. Induktor sering juga disebut sebagai koil.

Secara bahasa, istilah induktor menurut KBBI adalah “peranti listrik berbentuk kumparan yang digunakan pada rangkaian listrik”

Induktor dapat menyimpan energi listrik dalam bentuk medan magnetik yang terbentuk ketika arus listrik mengalir melalui kumparan. Ketika arus listrik berubah atau dihentikan, medan magnetik akan memberikan arus listrik balik atau back EMF (Electromotive Force) yang berusaha mempertahankan besarnya arus agar konstan.

Contoh induktor kecil
Contoh induktor kecil

Bahan inti induktor dapat dibuat dari berbagai bahan misalnya:

  • Induktor kumparan udara: induktor ini terdiri dari kawat yang dililitkan pada inti udara tanpa adanya inti magnetik tambahan.

  • Induktor kumparan ferromagnetik: induktor ini memiliki inti yang terbuat dari bahan ferromagnetik seperti besi, nikel, atau kobalt.

  • Induktor kumparan non-magnetik: induktor ini memiliki inti yang terbuat dari bahan non-magnetik seperti plastik, keramik, atau kaca.

Berikut ini contoh induktor dengan inti udara

Induktor dengan inti udara
Induktor dengan inti udara

Bentuk induktor ada bermacam-macam, misalnya:

  • Induktor Silinder.
  • Induktor Toroid

Induktor Berbentuk Silinder

Induktor silinder adalah jenis induktor yang memiliki bentuk silinder atau tabung. Induktor ini biasanya terdiri dari inti silinder yang terbuat dari bahan feromagnetik seperti besi atau ferit, dan lilitan kawat tembaga yang dililitkan secara rapat di sekitar inti.

Berikut ini induktor berbentuk silinder [sumber]

Induktor berbentuk silinder
Induktor berbentuk silinder

Induktor silinder biasanya digunakan untuk aplikasi frekuensi rendah hingga menengah, seperti pada regulator daya, filter, dan pengkondisi sinyal. Keuntungan dari penggunaan induktor silinder adalah dapat menampung arus listrik yang cukup besar, dan karena bentuk silindernya, maka induktor ini dapat meminimalkan kebocoran medan magnetiknya.

Namun, kekurangan dari induktor silinder adalah memiliki induktansi yang rendah dibandingkan dengan bentuk inti lainnya, seperti bentuk toroid. Selain itu, induktor silinder juga kurang efektif dalam menahan interferensi elektromagnetik jika dibandingkan dengan induktor dengan bentuk inti khusus yang dirancang untuk menangani interferensi tersebut.

Secara keseluruhan, induktor silinder cocok untuk digunakan pada aplikasi frekuensi rendah hingga menengah yang membutuhkan induktor dengan bentuk yang kompak dan mampu menampung arus listrik yang cukup besar.

Induktor Berbentuk Toroid

Induktor toroid adalah jenis induktor yang memiliki bentuk donut atau cincin. Induktor ini terdiri dari inti toroid yang terbuat dari bahan ferit atau besi, dan lilitan kawat tembaga yang dililitkan rapat di sekitar inti.

Keuntungan dari induktor toroid adalah bentuknya yang dapat meminimalkan kebocoran medan magnetik dan interferensi elektromagnetik. Hal ini disebabkan oleh sifat geometris inti toroid yang memungkinkan medan magnetik yang dihasilkan oleh lilitan kawat dapat ditekan ke dalam inti dan tidak tersebar ke lingkungan sekitarnya.

Selain itu, induktor toroid juga memiliki induktansi yang relatif tinggi dibandingkan dengan bentuk inti lainnya dengan ukuran yang sama. Induktor toroid biasanya digunakan pada aplikasi frekuensi tinggi seperti pada rangkaian RF (Radio Frequency), pemrosesan sinyal, filter, dan dalam sirkuit daya.

Namun, kekurangan dari induktor toroid adalah sulit untuk dililitkan secara manual karena bentuknya yang khusus, sehingga seringkali dibutuhkan mesin khusus untuk melilitkannya. Selain itu, induktor toroid juga cenderung lebih mahal dibandingkan dengan bentuk inti lainnya.

Berikut ini contoh induktor toroid [sumber].

Penutup

Induktor sering digunakan dalam rangkaian elektronik untuk memfilter sinyal, atau menghasilkan osilasi. Misalnya, induktor dapat digunakan dalam rangkaian daya switching, regulator tegangan, sirkuit filter, dan banyak lagi aplikasi lainnya.

Referensi

Fiting Lampu

Fiting lampu adalah tempat memasang bola lampu listrik yang menghubungkan kabel listrik dengan lampu. Istilah ini juga dipakai untuk alat pembagi aliran listrik tiga arah atau lebih dari satu titik lampu.

fiting lampu tempat memasang bola lampu listrik yang menghubungkan kabel listrik dengan lampu
    n alat untuk membagi aliran listrik tiga arah atau lebih dari satu titik lampu
Fiting lampu

Fiting lampu atau yang sering disebut sebagai soket lampu, adalah komponen elektronik yang digunakan untuk menghubungkan lampu dengan sumber daya listrik. Fitting lampu dirancang untuk memastikan lampu terpasang dengan aman dan mudah diganti jika rusak atau ingin diganti dengan jenis lampu yang berbeda.

Fitting lampu biasanya terdiri dari dua bagian yaitu bagian atas yang terhubung dengan kabel listrik dan bagian bawah yang terhubung dengan lampu. Setiap jenis lampu memiliki fitting yang berbeda-beda, dan untuk memasang lampu yang tepat, Anda harus menggunakan fitting yang sesuai dengan jenis lampu tersebut.

Beberapa jenis fitting lampu yang umum digunakan di antaranya Edison screw (E27/E14), bayonet (B22), GU10, dan wedge. Masing-masing jenis fitting ini memiliki desain dan ukuran yang berbeda-beda, sehingga Anda harus memilih fitting yang cocok dengan jenis lampu yang akan dipasang. Selain itu, ada juga fitting lampu yang dirancang khusus untuk lampu neon, lampu fluoro, dan lampu LED.

Fitting lampu juga memiliki peran penting dalam menjaga keamanan listrik di rumah atau bangunan Anda. Jika fitting lampu rusak atau tidak dipasang dengan benar, dapat menyebabkan kebocoran listrik, korsleting atau bahkan kebakaran. Oleh karena itu, penting untuk memilih fitting lampu yang berkualitas baik dan memastikan bahwa pasangannya benar-benar terpasang dengan kuat dan aman.

Jenis Fiting Lampu

Berikut ini beberapa macam jenis fiting lampu

  1. Edison Screw (E10s ,E11s ,E12s ,E14s ,E17s ,E26s ,E26d ,E27s ,E39s ,E39d ,E40s) – jenis fitting yang umum digunakan pada lampu pijar atau lampu CFL.
  2. Bi Pin (G4/G5.3/G9/GU5.3) – jenis fitting yang digunakan untuk lampu halogen atau LED dengan desain pin.
  3. Fitting bayonet (B22) – jenis fitting yang umum digunakan pada lampu pijar atau lampu CFL.
  4. Fiting lampu Fluorescent  untuk lampu jenis fluorescent
  5. Fitting wedge – jenis fitting yang umum digunakan pada lampu kecil, seperti lampu senter atau lampu malam.

Referensi

Motor Arus Searah (DC)

Motor arus searah (DC) adalah jenis motor listrik yang mengubah energi listrik searah menjadi energi mekanik dalam bentuk putaran. Motor jenis ini umumnya menggunakan medan magnet yang dihasilkan oleh arus listrik yang mengalir melalui kumparan untuk menggerakkan bagian motor yang berputar. Hampir semua jenis motor DC memiliki mekanisme di dalamnya untuk secara periodik mengubah arah aliran listrik di sebagian motor. Mekanisme pengubahan ini dapat menggunakan teknik elektromekanik ataupun elektronik.

Motor DC adalah jenis motor listrik pertama yang banyak digunakan karena dapat pada awal adanya motor, listrik yang ada adalah dipasok oleh sistem distribusi tenaga listrik arus searah.

Kecepatan motor DC dapat dikontrol dalam rentang yang cukup luas. Pengendalian kecepatan dapat dilakukan dengan mengubah tegangan catu daya, ataupun dengan mengubah kekuatan arus pada gulungan medan.

Motor DC kecil sering digunakan pada peralatan seperti alat-alat, mainan, dan peralatan rumah tangga. Motor DC yang lebih besar saat ini digunakan dalam penggerak kendaraan listrik, lift dan alat angkat, serta dalam penggerak pabrik penggilingan baja.

Motor DC populer dipakai jika sumber listrik yang tersedia adalah DC. Kemajuan teknologi elektronika daya memungkinkan untuk menghasilkan arus AC dari arus DC dengan mudah. Hal ini menjadikan motor DC mulai dapat digantikan dengan motor arus bolak-balik (AC).

Bagaimana cara kerja motor Arus Searah?

 

Cara kerja motor arus searah
Cara kerja motor arus searah

Cara kerja motor listrik arus searah dengan rotor dua kutub (angker) dan stator magnet permanen. “N” (North = Utara) dan “S” (South = Selatan)  menunjukkan polaritas pada permukaan sumbu bagian dalam magnet; permukaan luar memiliki polaritas yang berlawanan. Tanda + dan – menunjukkan di mana arus DC diterapkan ke komutator yang menyuplai arus ke kumparan jangkar. Arus listrik masuk ke rotor melalui sikat (brush). Sikat berputar bersamaan dengan rotor. Setiap 180 derajat, terjadi pergantian kutub pada rotor sehingga rotor dapat tetap berputar.

Apa saja jenis-jenis motor Arus Searah?

  • Motor arus searah dengan sikat. Pada motor jenis ini, pembalikan polaritas dilakukan secara elektromekanik menggunakan sikat yang terhubung ke cincin belah pada rotor.
  • Motor arus searah tanpa sikat / BLDC (Brushless Direct Current). Pada motor jenis ini, pembalikan polaritas dilakukan secara elektronik menggunakan sakelar semikonduktor seperti transistor BJT (Bipolar Junction Transistor) ataupun MOSFET (Metal Oxyde Semiconductor Field Effect Transistor).

Berikut ini contoh motor BLDC pada floppy drive komputer

Motor brushless direct current BLDC dari floppy disc
Motor floppy drive

Bagaimana cara mengendalikan motor Arus Searah dari mikrokontroler?

Motor dapat dikendalikan secara hanya on-off ataupun secara proporsional. Kendali on-off artinya motor hanya diatur untuk menyala dengan kecepatan penuh atau mati sama sekali. Kendali proporsional artinya kecepatan motor dapat diatur dari 0% sampai 100%.

Kendali on-off dapat dilakukan menggunakan relay ataupun transistor.

Kendali proporsional dapat menggunakan penguat analog yang menghasilkan tegangan / arus tertentu, atau pengendali digital dengan modulasi lebar pulsa (PWM = Pulse Width Modulation)

Berikut ini contoh relay elektromekanik

Relay elektromekanik umumnya perlu tegangan / arus agak besar, sehingga perlu rangkaian antar muka khusus pada mikrokontroler.

Berikut ini contoh relay semikonduktor

Modul solid state relay
Modul solid state relay

Berikut ini contoh rangkaian elektronik pengendali motor dengan konfigurasi “Jembatan-H” atau “H-Bridge”. Rangkaian ini dapat mengatur kecepatan dan arah gerakan motor arus searah.

H Bridge
H Bridge

Rangkaian H-Bridge ini dapat dibuat menggunakan transistor terpisah, ataupun menggunakan modul yang sudah jadi seperti Motor driver TLE 5205-2Motor Driver BTS7960B dan Motor driver TB6612FNG, L293 dan L298.

Referensi