SINAU PROGRAMMING
SINAU PROGRAMMING
  • Home
  • Source Code
  • Social
  • CONTROL
    • Internet of Think (IoT)
    • ESP
      • NodeMcu
      • Lora
      • WeMos
      • Esp 32 Dev
      • Node 32s
    • Arduino
    • Raspberry
    • Proteus
  • MATLAB
    • MATLAB PROJECT
    • PLC
      • Omron
      • Mitsubishi
      • Siemens
      • Schneider
      • ArduinoPLC
    • Arduino
    • Basic & Doc
  • Contact Us

CONTROL


Computer Vision

Contact

 Untuk tahap pertama, saya sarankan fokus pada pembacaan suara dan visualisasi gelombang (waveform) terlebih dahulu. Setelah berhasil, baru kita tambahkan filter suara jantung, penguatan sinyal, dan penghitungan BPM.



1. Konsep sistem



INMP441

Menangkap getaran suara melalui mikrofon digital I2S

ESP32

Membaca sampel suara dan mengolahnya menjadi data gelombang

LCD ST77916

Menampilkan gelombang suara secara langsung

LCD ST77916 berukuran 1,53 inci umumnya memiliki resolusi 360 × 360 piksel dan menggunakan antarmuka QSPI, bukan SPI standar. Ini penting karena pemilihan library harus sesuai dengan antarmuka LCD.


2. Library yang diperlukan

Library / Board Package

Fungsi

ESP32 by Espressif Systems

Board package Arduino untuk ESP32

GFX Library for Arduino

Mengendalikan LCD ST77916 dan menggambar gelombang

driver/i2s.h

Membaca suara INMP441 menggunakan I2S

Library grafis yang kita gunakan adalah Arduino_GFX karena menyediakan kelas Arduino_ST77916 dan Arduino_ESP32QSPI.


Untuk instalasi, buka Arduino IDE → Tools → Board → Boards Manager, kemudian instal esp32 by Espressif Systems. Selanjutnya buka Sketch → Include Library → Manage Libraries, cari GFX Library for Arduino dan instal.

driver/i2s.h sudah disediakan oleh board package ESP32, sehingga tidak memerlukan library mikrofon tambahan.

3. Wiring ESP32 ke INMP441

Contoh ini menggunakan ESP32 DevKit V1 / ESP32-WROOM-32. Jika Anda menggunakan ESP32-S3, pin perlu disesuaikan.

Pin INMP441

Pin ESP32

VDD

3V3

GND

GND

SCK

GPIO 26

WS

GPIO 25

SD

GPIO 33

L/R

GND

INMP441 menggunakan komunikasi I2S dengan resolusi data 24-bit. Menghubungkan L/R ke GND memilih kanal kiri. Jangan menghubungkan VDD INMP441 ke 5V.

Tujuan:

  • memastikan I2S bekerja
  • melihat level suara

Program: 

Sintaks:

#include <Arduino.h> #include <driver/i2s.h> #define I2S_WS 25 #define I2S_SCK 26 #define I2S_SD 33 #define SAMPLE_RATE 16000 int32_t samples[256]; void setup() { Serial.begin(115200); i2s_config_t i2s_config = { .mode = (i2s_mode_t) ( I2S_MODE_MASTER | I2S_MODE_RX ), .sample_rate = SAMPLE_RATE, .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT, .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT, .communication_format = I2S_COMM_FORMAT_STAND_I2S, .intr_alloc_flags = 0, .dma_buf_count = 4, .dma_buf_len = 256, .use_apll = false }; i2s_pin_config_t pin_config = { .bck_io_num = I2S_SCK, .ws_io_num = I2S_WS, .data_out_num = -1, .data_in_num = I2S_SD }; i2s_driver_install( I2S_NUM_0, &i2s_config, 0, NULL ); i2s_set_pin( I2S_NUM_0, &pin_config ); Serial.println("INMP441 READY"); } void loop() { size_t bytes_read; i2s_read( I2S_NUM_0, samples, sizeof(samples), &bytes_read, portMAX_DELAY ); int sample_count = bytes_read / sizeof(int32_t); long sum=0; for(int i=0;i<sample_count;i++) { int32_t sample = samples[i] >> 14; sum += abs(sample); } int level = sum/sample_count; Serial.println(level); delay(100); }


4. Wiring ESP32 ke LCD ST77916

Untuk modul LCD ST77916 tipe QSPI 11-pin:

Pin LCD

Pin ESP32

VCC

    3V3

GND            

    GND

SCL / CLK

    GPIO 18

SDA / IO0

    GPIO 23

IO1

    GPIO 19

IO2

    GPIO 21

IO3

    GPIO 22

CS

    GPIO 5

RST

    GPIO 17

BL

    GPIO 16

TE

    Tidak digunakan

Susunan ini merupakan contoh pemetaan GPIO, bukan pin bawaan wajib modul. Pastikan label pada LCD sesuai dan modul menerima suplai 3,3V.

Test LCD Bisa Menggunakan Program Ini :

Sintaks:

#include <Arduino_GFX_Library.h> // ======================= // WARNA RGB565 // ======================= #define BLACK 0x0000 #define WHITE 0xFFFF #define RED 0xF800 #define GREEN 0x07E0 #define BLUE 0x001F #define YELLOW 0xFFE0 // ======================= // PIN LCD ST77916 QSPI // ======================= #define LCD_CS 5 #define LCD_SCK 18 #define LCD_D0 23 // SDA #define LCD_D1 19 // IO1 #define LCD_D2 21 // IO2 #define LCD_D3 22 // IO3 #define LCD_RST 17 #define LCD_BL 16 // ======================= // QSPI BUS // ======================= Arduino_DataBus *bus = new Arduino_ESP32QSPI( LCD_CS, LCD_SCK, LCD_D0, LCD_D1, LCD_D2, LCD_D3 ); // ======================= // LCD DRIVER // ======================= Arduino_GFX *gfx = new Arduino_ST77916( bus, LCD_RST, 0, // rotation false, // inversion 360, 360 ); void lcdReset() { pinMode(LCD_RST, OUTPUT); digitalWrite(LCD_RST,HIGH); delay(100); digitalWrite(LCD_RST,LOW); delay(100); digitalWrite(LCD_RST,HIGH); delay(300); } void setup() { Serial.begin(115200); Serial.println("Start LCD ST77916"); // Backlight pinMode(LCD_BL,OUTPUT); digitalWrite(LCD_BL,HIGH); // Reset LCD lcdReset(); // Init LCD if(!gfx->begin()) { Serial.println("LCD INIT FAILED"); while(1) { delay(1000); } } Serial.println("LCD OK"); // TEST WARNA gfx->fillScreen(RED); delay(1000); gfx->fillScreen(GREEN); delay(1000); gfx->fillScreen(BLUE); delay(1000); gfx->fillScreen(BLACK); // TEST TEXT gfx->setTextColor(WHITE); gfx->setTextSize(3); gfx->setCursor(55,140); gfx->println("ST77916"); gfx->setTextSize(2); gfx->setCursor(90,190); gfx->println("ESP32 TEST"); gfx->drawCircle( 180, 180, 170, YELLOW ); } void loop() { }#include <Arduino_GFX_Library.h>
// ======================= // WARNA RGB565 // ======================= #define BLACK 0x0000 #define WHITE 0xFFFF #define RED 0xF800 #define GREEN 0x07E0 #define BLUE 0x001F #define YELLOW 0xFFE0 // ======================= // PIN LCD ST77916 QSPI // ======================= #define LCD_CS 5 #define LCD_SCK 18 #define LCD_D0 23 // SDA #define LCD_D1 19 // IO1 #define LCD_D2 21 // IO2 #define LCD_D3 22 // IO3 #define LCD_RST 17 #define LCD_BL 16 // ======================= // QSPI BUS // ======================= Arduino_DataBus *bus = new Arduino_ESP32QSPI( LCD_CS, LCD_SCK, LCD_D0, LCD_D1, LCD_D2, LCD_D3 ); // ======================= // LCD DRIVER // ======================= Arduino_GFX *gfx = new Arduino_ST77916( bus, LCD_RST, 0, // rotation false, // inversion 360, 360 ); void lcdReset() { pinMode(LCD_RST, OUTPUT); digitalWrite(LCD_RST,HIGH); delay(100); digitalWrite(LCD_RST,LOW); delay(100); digitalWrite(LCD_RST,HIGH); delay(300); } void setup() { Serial.begin(115200); Serial.println("Start LCD ST77916"); // Backlight pinMode(LCD_BL,OUTPUT); digitalWrite(LCD_BL,HIGH); // Reset LCD lcdReset(); // Init LCD if(!gfx->begin()) { Serial.println("LCD INIT FAILED"); while(1) { delay(1000); } } Serial.println("LCD OK"); // TEST WARNA gfx->fillScreen(RED); delay(1000); gfx->fillScreen(GREEN); delay(1000); gfx->fillScreen(BLUE); delay(1000); gfx->fillScreen(BLACK); // TEST TEXT gfx->setTextColor(WHITE); gfx->setTextSize(3); gfx->setCursor(55,140); gfx->println("ST77916"); gfx->setTextSize(2); gfx->setCursor(90,190); gfx->println("ESP32 TEST"); gfx->drawCircle( 180, 180, 170, YELLOW ); } void loop() { }


5. Program Arduino lengkap

Program berikut membaca mikrofon, menghitung tingkat sinyal RMS, lalu menampilkan grafik bergerak pada LCD. Grafik ini adalah amplitudo suara terhadap waktu, belum gelombang suara mentah atau hasil pengukuran detak jantung.

Kode Program ESP32 + INM441+ LCD LCD ST77916:

#include <Arduino.h>

#include <Arduino_GFX_Library.h>

#include <driver/i2s.h>

#include <math.h>


// ===== LCD ST77916 QSPI =====

#define LCD_CS   5

#define LCD_SCK  18

#define LCD_D0   23

#define LCD_D1   19

#define LCD_D2   21

#define LCD_D3   22

#define LCD_RST  17

#define LCD_BL   16


// ===== INMP441 I2S =====

#define MIC_SCK  26

#define MIC_WS   25

#define MIC_SD   33


#define SAMPLE_RATE 16000

#define SAMPLES     256


#define BLACK 0x0000

#define WHITE 0xFFFF

#define GREEN 0x07E0

#define GRAY  0x4208


Arduino_DataBus *bus = new Arduino_ESP32QSPI(

  LCD_CS, LCD_SCK,

  LCD_D0, LCD_D1, LCD_D2, LCD_D3

);


Arduino_GFX *gfx = new Arduino_ST77916(

  bus, LCD_RST, 0, true, 360, 360

);


int32_t audioBuffer[SAMPLES];


int graphX = 70;

int previousY = 210;

float smoothLevel = 0;


void setupMicrophone() {

  i2s_config_t config = {};


  config.mode = (i2s_mode_t)(

    I2S_MODE_MASTER | I2S_MODE_RX

  );

  config.sample_rate = SAMPLE_RATE;

  config.bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT;

  config.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT;

  config.communication_format = I2S_COMM_FORMAT_STAND_I2S;

  config.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1;

  config.dma_buf_count = 4;

  config.dma_buf_len = SAMPLES;

  config.use_apll = false;


  i2s_pin_config_t pins = {};

  pins.mck_io_num = I2S_PIN_NO_CHANGE;

  pins.bck_io_num = MIC_SCK;

  pins.ws_io_num = MIC_WS;

  pins.data_out_num = I2S_PIN_NO_CHANGE;

  pins.data_in_num = MIC_SD;


  esp_err_t result =

    i2s_driver_install(I2S_NUM_0, &config, 0, NULL);


  if (result != ESP_OK) {

    Serial.println("Gagal mengaktifkan I2S");

    while (true) delay(1000);

  }


  i2s_set_pin(I2S_NUM_0, &pins);

}


void setupDisplay() {

  pinMode(LCD_BL, OUTPUT);

  digitalWrite(LCD_BL, HIGH);


  if (!gfx->begin()) {

    Serial.println("LCD gagal diinisialisasi");

    while (true) delay(1000);

  }


  gfx->fillScreen(BLACK);

  gfx->drawCircle(180, 180, 178, GRAY);


  gfx->setTextColor(WHITE);

  gfx->setTextSize(2);

  gfx->setCursor(100, 75);

  gfx->print("STETOSKOP");


  gfx->setTextSize(1);

  gfx->setCursor(123, 105);

  gfx->print("AUDIO MONITOR");


  gfx->drawFastHLine(70, 210, 220, GRAY);

}


float readSoundLevel() {

  size_t bytesRead = 0;


  esp_err_t result = i2s_read(

    I2S_NUM_0,

    audioBuffer,

    sizeof(audioBuffer),

    &bytesRead,

    pdMS_TO_TICKS(100)

  );


  if (result != ESP_OK || bytesRead == 0) {

    return 0;

  }


  int count = bytesRead / sizeof(int32_t);

  double sum = 0;

  double sumSquare = 0;


  for (int i = 0; i < count; i++) {

    // Konversi slot 32-bit ke sampel sekitar 16-bit

    int32_t sample = audioBuffer[i] >> 16;


    sum += sample;

    sumSquare += (double)sample * sample;

  }


  double mean = sum / count;

  double variance = sumSquare / count - mean * mean;

  double rms = sqrt(fmax(variance, 0.0));


  // dBFS relatif terhadap rentang 16-bit

  float dbFS = 20.0f * log10f((rms + 0.01f) / 32768.0f);


  // Skala visual percobaan, bukan dB SPL

  float level = (dbFS + 70.0f) * (100.0f / 60.0f);


  return constrain(level, 0.0f, 100.0f);

}


void drawGraph(float level) {

  smoothLevel = smoothLevel * 0.7f + level * 0.3f;


  int y = 210 - (int)(smoothLevel * 60.0f / 100.0f);


  // Hapus satu kolom grafik lama

  gfx->drawFastVLine(graphX, 140, 72, BLACK);

  gfx->drawPixel(graphX, 210, GRAY);


  if (graphX > 70) {

    gfx->drawLine(

      graphX - 1, previousY,

      graphX, y,

      GREEN

    );

  } else {

    gfx->drawPixel(graphX, y, GREEN);

  }


  previousY = y;

  graphX++;


  if (graphX >= 290) {

    graphX = 70;

    previousY = y;

  }


  // Tampilkan level suara

  gfx->fillRect(105, 250, 150, 22, BLACK);

  gfx->setTextSize(2);

  gfx->setTextColor(WHITE);

  gfx->setCursor(110, 252);

  gfx->printf("LEVEL %3d", (int)smoothLevel);

}


void setup() {

  Serial.begin(115200);

  delay(500);


  setupDisplay();

  setupMicrophone();


  Serial.println("Stetoskop digital siap");

}


void loop() {

  float level = readSoundLevel();


  drawGraph(level);


  static unsigned long lastPrint = 0;

  if (millis() - lastPrint >= 200) {

    lastPrint = millis();


    Serial.print("Level: ");

    Serial.println(level, 1);

  }

}




Program Arduino dengan Perulangan while untuk Menampilkan Nilai Variabel di LCD

Berdasarkan skema yang Anda berikan, kita akan membuat program Arduino menggunakan perulangan while untuk menampilkan nilai variabel i pada layar LCD. Skema tersebut menunjukkan bahwa:

  • Arduino Nano digunakan sebagai mikrokontroler.
  • LCD 16x2 (LMD044L) terhubung ke pin digital Arduino.
  • Nilai dari variabel i akan ditampilkan pada layar LCD.  

     Pembuatan Program While 1:

     


Berikut adalah langkah-langkah dan kode lengkapnya:


Langkah-Langkah Pembuatan Program:

  1. Pengaturan Pin LCD:

    • LCD 16x2 biasanya terhubung ke pin digital Arduino menggunakan protokol 4-bit atau 8-bit.
    • Dalam contoh ini, asumsikan LCD terhubung menggunakan modus 4-bit , yang lebih umum karena menghemat pin.
  2. Library LCD:

    • Gunakan library LiquidCrystal yang sudah tersedia di Arduino IDE untuk memudahkan pengoperasian LCD.
  3. Perulangan while:

    • Gunakan perulangan while untuk mengubah nilai variabel i dan menampilkan hasilnya pada LCD.
  4. Tampilan pada LCD:

    • Teks yang ditampilkan adalah "nilai dari i = [nilai_i]".

Kode Program Arduino 1:

#include <LiquidCrystal.h>

const int rs = 12, en = 11, d4 = 10, d5 = 9, d6 = 8, d7 = 7;

LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

int i=0;

void setup() {

lcd.begin(16, 2); //LCD 4x20

while (i<10)

{

lcd.setCursor(0,0);lcd.print("value of i =");

lcd.setCursor(13,0); lcd.println(i); delay(500);

i++;

}

}

void loop() {

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

}

Penjelasan Kode:

  1. Library LiquidCrystal:

    • Digunakan untuk mengontrol LCD 16x2. Pastikan library ini telah terinstal di Arduino IDE.
  2. Pengaturan LCD:

    • lcd.begin(16, 2) menginisialisasi LCD dengan ukuran 16 kolom x 2 baris.
    • lcd.setCursor(x, y) digunakan untuk mengatur posisi kursor pada layar LCD. x adalah kolom (0-15), dan y adalah baris (0 atau 1).
  3. Perulangan while:

    • while (i < 10) menjalankan blok kode selama nilai i kurang dari a 10.
    • Setiap iterasi, nilai i ditampilkan pada kolom ke-12 layar LCD (lcd.setCursor(12, 0)).
    • Setelah menampilkan nilai i, i dinkrement dengan i++.

 

Pembuatan Program While 2:

  • Arduino Nano digunakan sebagai mikrokontroler.
  • LCD 16x2 (LMD044L) terhubung ke pin digital Arduino.


Kode Program Arduino 2:

#include <LiquidCrystal.h> // Inisialisasi objek LCD LiquidCrystal lcd(7, 8, 9, 10, 11, 12); // RS, Enable, D4, D5, D6, D7 void setup() { // Inisialisasi komunikasi serial untuk debugging (opsional) Serial.begin(9600); // Inisialisasi LCD lcd.begin(16, 2); // Ukuran LCD 16 kolom x 2 baris // Pesan awal lcd.setCursor(0, 0); // Cursor ke baris pertama, kolom pertama lcd.print("Nilai dari i = "); // Inisialisasi variabel i int i = 0; } void loop() { // Perulangan while untuk menampilkan nilai i while (i <= 4) { // Loop selama i <= 4 // Tampilkan nilai i pada LCD lcd.setCursor(12, 0); // Pindah cursor ke kolom ke-12 (setelah teks "Nilai dari i = ") lcd.print(i); // Delay agar tampilan mudah dibaca delay(1000); // Increment nilai i i++; } // Setelah loop selesai, tampilkan pesan akhir lcd.clear(); // Bersihkan layar LCD lcd.setCursor(0, 0); lcd.print("Selesai!"); delay(2000); // Tahan pesan selama 2 detik // Reset nilai i untuk simulasi ulang (opsional) i = 0; // Delay sebelum simulasi ulang delay(2000); }

Kode Program Arduino 3:

// program kedua bagian kedua
#include <LiquidCrystal.h>

// Inisialisasi objek LCD
LiquidCrystal lcd(7, 8, 9, 10, 11, 12); // RS, Enable, D4, D5, D6, D7

void setup() {
  // Inisialisasi komunikasi serial untuk debugging (opsional)
  Serial.begin(9600);

  // Inisialisasi LCD
  lcd.begin(16, 2); // Ukuran LCD 16 kolom x 2 baris

  // Pesan awal
  lcd.setCursor(0, 0); // Cursor ke baris pertama, kolom pertama
  lcd.print("Nilai dari i = ");

  // Inisialisasi variabel i
  int i = 0;
  while (i <= 4) { // Loop selama i <= 4
    // Tampilkan nilai i pada LCD
    lcd.setCursor(14, 0); // Pindah cursor ke kolom ke-12 (setelah teks "Nilai dari i = ")
    lcd.print(i);

    // Delay agar tampilan mudah dibaca
    delay(1000);

    // Increment nilai i
    i++;
  }

  // Setelah loop selesai, tampilkan pesan akhir
  lcd.clear(); // Bersihkan layar LCD
  lcd.setCursor(0, 0);
  lcd.print("Selesai!");
  delay(2000); // Tahan pesan selama 2 detik

  // Reset nilai i untuk simulasi ulang (opsional)
  i = 0;

  // Delay sebelum simulasi ulang
  delay(2000);
}

void loop() {
  // Perulangan while untuk menampilkan nilai i
 
}

Penjelasan Kode:

  1. Library LiquidCrystal:

    • Digunakan untuk mengontrol LCD 16x2. Pastikan library ini telah terinstal di Arduino IDE.
  2. Pengaturan LCD:

    • lcd.begin(16, 2) menginisialisasi LCD dengan ukuran 16 kolom x 2 baris.
    • lcd.setCursor(x, y) digunakan untuk mengatur posisi kursor pada layar LCD. x adalah kolom (0-15), dan y adalah baris (0 atau 1).
  3. Perulangan while:

    • while (i <= 4) menjalankan blok kode selama nilai i kurang dari atau sama dengan 4.
    • Setiap iterasi, nilai i ditampilkan pada kolom ke-12 layar LCD (lcd.setCursor(12, 0)).
    • Setelah menampilkan nilai i, i dinkrement dengan i++.
  4. Delay:

    • delay(1000) digunakan untuk memberikan jeda 1 detik antar iterasi, sehingga pengguna dapat melihat perubahan nilai i dengan jelas.
  5. Pesan Akhir:

    • Setelah loop selesai, layar LCD dibersihkan dengan lcd.clear(), dan pesan "Selesai!" ditampilkan.
  6. Simulasi Ulang:

    • Untuk demonstrasi, nilai i direset menjadi 0 setelah loop selesai, dan ada delay 2 detik sebelum simulasi dimulai lagi.

Skema Koneksi (Asumsi Modus 4-Bit):

Pin LCD
Fungsi
Pin Arduino
RS
Register Select
Digital 7
Enable
Enable
Digital 8
D4
Data 4
Digital 9
D5
Data 5
Digital 10
D6
Data 6
Digital 11
D7
Data 7
Digital 12
VSS
Ground
GND
VDD
Power
5V
VO
Contrast Adjust
Potensiometer (opsional)
RW
Read/Write
GND (untuk mode write saja)


Output pada LCD:

Nilai dari i = 1-4

Catatan Tambahan:

  • Jika Anda ingin mengganti modus LCD (misalnya 8-bit), ubah parameter dalam lcd.begin() sesuai konfigurasi koneksi.
  • Pastikan potensiometer terhubung ke pin VO LCD untuk mengatur kontras layar jika diperlukan.
  • Jika LCD tidak menampilkan apa pun, pastikan koneksi pin dan arah kabel sudah benar.

Kesimpulan:

Program ini menggunakan perulangan while untuk menampilkan nilai variabel i pada LCD secara bertahap. Dengan struktur while, kita dapat mengendalikan alur eksekusi program dengan fleksibel, sesuai dengan kondisi yang diinginkan. Semoga penjelasan dan kode ini membantu! 😊

Selamat belajar dan praktik!
Jika Anda ingin mempelajari lebih lanjut tentang penggunaan array dalam Arduino, silakan tunggu artikel berikutnya hanya di www.sinauprogramming.com .


Tag: #CProgramming #Perulangan #Looping #ControlStatement #ContinueBreak #BelajarPemrograman

Older Posts Home





POPULAR POSTS

  • Proteus 8.5 Full Version Professional
  • Serial Communication UART Raspberry Pico (SoftSerial)
  • Artificial Neural Network for Identification MATLAB
  • Skema Power Supply Switching SMPS
  • Tutorial ILI9341 TFT SPI LCD touch Screen
  • Cara Install Board ESP32 Ke Arduino IDE
  • Pulse Oxymetry (SPO2) + Raspberry Pi

ABOUT ME

cobabaru

Sinau Programming

SUBSCRIBE & FOLLOW

Training


Contact Form

Name

Email *

Message *

Categories

  • alkes 2
  • Android 4
  • Arduino 35
  • Basic & Doc 12
  • centrifuge 1
  • ESP32 9
  • Internet of Things (IoT) 23
  • LCD TFT SPI 2
  • MATLAB 6
  • Metode kendali 1
  • Modul Charger 1
  • Nextion 4
  • NodeMcu 8
  • oled 1
  • Pattern Recognition 2
  • Pemrograman 2
  • Perbaikan 1
  • PID 2
  • PLC HMI VTSCADA ARDUINO 3
  • PRIVACY POLICY 1
  • Proteus 11
  • Python 1
  • raspberry 5
  • Teknik Elektromedik 2
  • Thingsboard 1
  • Video 5
  • Wemos 4

sinau_programming

Sinau Programming Distributed by Sinau Programming