Belajar Elektro

Random post

Belajar Elektro

Powered By Blogger

This is default featured slide 1 title

Go to Blogger edit html and find these sentences.Now replace these sentences with your own descriptions.This theme is Bloggerized by Lasantha Bandara - Premiumbloggertemplates.com.

This is default featured slide 2 title

Go to Blogger edit html and find these sentences.Now replace these sentences with your own descriptions.This theme is Bloggerized by Lasantha Bandara - Premiumbloggertemplates.com.

This is default featured slide 3 title

Go to Blogger edit html and find these sentences.Now replace these sentences with your own descriptions.This theme is Bloggerized by Lasantha Bandara - Premiumbloggertemplates.com.

This is default featured slide 4 title

Go to Blogger edit html and find these sentences.Now replace these sentences with your own descriptions.This theme is Bloggerized by Lasantha Bandara - Premiumbloggertemplates.com.

This is default featured slide 5 title

Go to Blogger edit html and find these sentences.Now replace these sentences with your own descriptions.This theme is Bloggerized by Lasantha Bandara - Premiumbloggertemplates.com.

Thursday, 12 June 2025

KODE UCAPAN TERIMAKASIH

 DIY SWR & POWER METER VHF 500 WATT 2N











KODE PROGRAM UCAPAN TERIMAKASIH :

#include <U8g2lib.h>

#include <Wire.h>

 

U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0);

 

const int buzzerPin = 4;

 

unsigned long lastChange = 0;

unsigned long lastMove = 0;

const unsigned long moveInterval = 150;

 

int stage = 0;

int pupilX = 0;

int pupilDir = 1;

const int maxPupilOffset = 6;

 

unsigned long stageDurations[] = {3000, 2000, 2000, 5000}; // durasi tiap stage

 

int planeX = -40;

int planeY = 28;

 

bool propellerToggle = false;  // animasi baling-baling

 

// Awan Layer 1 (jauh)

const int cloudCount1 = 2;

int cloudX1[cloudCount1] = {130, 200};

int cloudY1[cloudCount1] = {10, 18};

 

// Awan Layer 2 (dekat)

const int cloudCount2 = 2;

int cloudX2[cloudCount2] = {160, 220};

int cloudY2[cloudCount2] = {25, 32};

 

void setup() {

  pinMode(buzzerPin, OUTPUT);

  u8g2.begin();

  u8g2.setFont(u8g2_font_ncenB14_tr);

}

 

void loop() {

  unsigned long now = millis();

 

  // Update animasi mata saat stage 0

  if (stage == 0) {

    if (now - lastMove > moveInterval) {

      pupilX += pupilDir;

      if (pupilX > maxPupilOffset || pupilX < -maxPupilOffset) {

        pupilDir = -pupilDir;

        pupilX += pupilDir * 2;

      }

      lastMove = now;

    }

  }

 

  // Update animasi pesawat & awan saat stage 3

  if (stage == 3 && now - lastMove > moveInterval) {

    planeX += 2;

    if (planeX > 128) planeX = -40;

    lastMove = now;

    propellerToggle = !propellerToggle;

 

    // Gerak awan layer 1 (lebih lambat)

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

      cloudX1[i] -= 1;

      if (cloudX1[i] < -30) cloudX1[i] = 130 + random(20);

    }

 

    // Gerak awan layer 2 (lebih cepat)

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

      cloudX2[i] -= 2;

      if (cloudX2[i] < -30) cloudX2[i] = 130 + random(30);

    }

  }

 

  // Ganti stage tiap interval sesuai durasi masing-masing

  if (now - lastChange > stageDurations[stage]) {

    stage = (stage + 1) % 4;

    lastChange = now;

 

    playCallTone(stage);

  }

 

  u8g2.clearBuffer();

 

  switch (stage) {

    case 0:

      drawRobotHeadWithMouthAndEyes(pupilX);

      break;

 

    case 1:

      drawTextCenteredBold("TERIMAKASIH");

      break;

 

    case 2:

      drawTextTwoLinesBold("ATAS", "ORDERANYA");

      break;

 

    case 3:

      drawPlane(planeX, planeY);

 

      // Gambar awan layer 1 (jauh)

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

        drawCloud(cloudX1[i], cloudY1[i]);

      }

 

      // Gambar awan layer 2 (dekat)

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

        drawCloud(cloudX2[i], cloudY2[i]);

      }

      break;

  }

 

  u8g2.sendBuffer();

}

 

void drawRobotHeadWithMouthAndEyes(int pupilOffsetX) {

  u8g2.drawRFrame(0, 0, 128, 64, 12);

 

  int eyeY = 25;

  int leftEyeX = 40;

  int rightEyeX = 88;

  int eyeWidth = 40;

  int eyeHeight = 28;

 

  u8g2.drawEllipse(leftEyeX, eyeY, eyeWidth / 2, eyeHeight / 2);

  u8g2.drawEllipse(rightEyeX, eyeY, eyeWidth / 2, eyeHeight / 2);

 

  int pupilRadius = 8;

  u8g2.drawDisc(leftEyeX + pupilOffsetX, eyeY, pupilRadius);

  u8g2.drawDisc(rightEyeX + pupilOffsetX, eyeY, pupilRadius);

 

  int mouthX = 32;

  int mouthY = 48;

  int mouthW = 64;

  int mouthH = 12;

  u8g2.drawRBox(mouthX, mouthY, mouthW, mouthH, 5);

  u8g2.drawHLine(mouthX, mouthY + mouthH / 2, mouthW);

}

 

void drawTextCenteredBold(const char* text) {

  u8g2.setFont(u8g2_font_ncenB10_tr);  // font tebal 10 px

  int16_t tw = u8g2.getStrWidth(text);

  u8g2.setCursor((128 - tw) / 2, 30);

  u8g2.print(text);

}

 

void drawTextTwoLinesBold(const char* line1, const char* line2) {

  u8g2.setFont(u8g2_font_ncenB10_tr);

  int16_t tw1 = u8g2.getStrWidth(line1);

  int16_t tw2 = u8g2.getStrWidth(line2);

 

  u8g2.setCursor((128 - tw1) / 2, 20);

  u8g2.print(line1);

 

  u8g2.setCursor((128 - tw2) / 2, 44);

  u8g2.print(line2);

}

 

void drawPlane(int x, int y) {

  // Badan utama

  u8g2.drawBox(x, y, 24, 6);

 

  // Hidung pesawat

  u8g2.drawTriangle(x + 24, y, x + 32, y + 3, x + 24, y + 6);

 

  // Sayap

  u8g2.drawBox(x + 6, y - 6, 6, 6);  // atas

  u8g2.drawBox(x + 6, y + 6, 6, 6);  // bawah

 

  // Ekor horizontal & vertikal

  u8g2.drawBox(x - 4, y + 1, 4, 2); // horizontal

  u8g2.drawBox(x, y - 5, 2, 5);     // vertikal

 

  // Baling-baling animasi

  static bool propellerToggle = false;

  propellerToggle = !propellerToggle;

  if (propellerToggle) {

    u8g2.drawDisc(x + 31, y + 3, 2); // mode bulat

  } else {

    u8g2.drawLine(x + 30, y + 1, x + 32, y + 5); // silang

    u8g2.drawLine(x + 32, y + 1, x + 30, y + 5);

  }

 

  // Asap knalpot

  u8g2.drawTriangle(x - 6, y + 1, x - 4, y - 1, x - 4, y + 5);

}

 

void drawCloud(int x, int y) {

  u8g2.drawCircle(x, y, 6, U8G2_DRAW_ALL);

  u8g2.drawCircle(x + 6, y - 2, 5, U8G2_DRAW_ALL);

  u8g2.drawCircle(x + 12, y, 6, U8G2_DRAW_ALL);

}

 

void playCallTone(int currentStage) {

  int melody0[] = {1000, 1200, 1400, 1200, 1000};

  int melody1[] = {600, 800, 600};

  int melody2[] = {900, 1100, 900};

  int melody3[] = {1300, 1500, 1700};

 

  int duration = 150;

  int* melody;

  int length;

 

  switch (currentStage) {

    case 0:

      melody = melody0;

      length = sizeof(melody0) / sizeof(melody0[0]);

      break;

    case 1:

      melody = melody1;

      length = sizeof(melody1) / sizeof(melody1[0]);

      break;

    case 2:

      melody = melody2;

      length = sizeof(melody2) / sizeof(melody2[0]);

      break;

    case 3:

      melody = melody3;

      length = sizeof(melody3) / sizeof(melody3[0]);

      break;

    default:

      return;

  }

 

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

    tone(buzzerPin, melody[i], duration);

    delay(duration + 50);

  }

  noTone(buzzerPin);

}


KODE SWR & POWER METER 500 WATT GEN2

KODE DENGAN DEBUG :

#include <Wire.h>

#include <Adafruit_GFX.h>

#include <Adafruit_SSD1306.h>

#include <math.h>

 

// Pengaturan OLED

#define SCREEN_WIDTH 128

#define SCREEN_HEIGHT 64

#define OLED_RESET -1

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

 

// Pengaturan pin

#define FWD_PIN A0

#define REF_PIN A1

#define ALARM_PIN 4  // Buzzer pasif

 

// Variabel untuk alarm

unsigned long lastAlarmToggle = 0;

bool alarmState = false;

 

// Fungsi konversi tegangan ke daya (dengan rentang terbaru)

float voltageToPower(float voltage) {

  if (voltage <= 0.2) return 1;

  else if (voltage <= 0.4) return 1 + (voltage - 0.2) * (4.0 / 0.2);               // 1–5W

  else if (voltage <= 0.7) return 5 + (voltage - 0.4) * (15.0 / 0.3);              // 5–20W

  else if (voltage <= 1.1) return 20 + (voltage - 0.7) * (30.0 / 0.4);             // 20–50W

  else if (voltage <= 1.2) return 50 + (voltage - 1.1) * (30.0 / 0.1);             // 50–80W

  else if (voltage <= 1.4) return 80 + (voltage - 1.2) * (20.0 / 0.2);             // 80–100W

  else if (voltage <= 1.8) return 100 + (voltage - 1.4) * (50.0 / 0.4);            // 100–150W

  else if (voltage <= 2.2) return 150 + (voltage - 1.8) * (50.0 / 0.4);            // 150–200W

  else if (voltage <= 2.8) return 200 + (voltage - 2.2) * (100.0 / 0.6);           // 200–300W

  else if (voltage <= 3.8) return 300 + (voltage - 2.8) * (100.0 / 1.0);           // 300–400W

  else if (voltage <= 4.2) return 400 + (voltage - 3.8) * (100.0 / 0.4);           // 400–500W

  else return 500;

}

 

// Fungsi smoothing: rata-rata dari beberapa pembacaan analog

float readAveragedAnalog(int pin, int samples = 10) {

  long total = 0;

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

    total += analogRead(pin);

    delay(2);  // jeda kecil antar pembacaan

  }

  return (float)total / samples;

}

 

void setup() {

  Serial.begin(9600);

  while (!Serial); // Tunggu hingga port serial siap

  Serial.println(F("Inisialisasi dimulai"));

 

  pinMode(ALARM_PIN, OUTPUT);

  noTone(ALARM_PIN);  // Pastikan buzzer mati

 

  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {

    Serial.println(F("OLED gagal!"));

    while (1);

  }

 

  display.clearDisplay();

  display.setTextSize(1);

  display.setTextColor(SSD1306_WHITE);

  display.setCursor(15, 0);

  display.println(F("SWR & POWER METER"));

  display.display();

  delay(2000);

}

 

void loop() {

  float fwdRaw = readAveragedAnalog(FWD_PIN);

  float refRaw = readAveragedAnalog(REF_PIN);

 

  float vFwd = fwdRaw * (5.0 / 1023.0);

  float vRef = refRaw * (5.0 / 1023.0);

 

  float pFwd = voltageToPower(vFwd);

  float pRef = voltageToPower(vRef);

 

  float swr = 1.0;

  if (vFwd > 0.01 && vRef < vFwd) {

    float ratio = vRef / vFwd;

    float sqrtRatio = sqrt(ratio);

    if (sqrtRatio > 0.99) sqrtRatio = 0.99;  // batasi supaya denominator tidak nol

    swr = (1 + sqrtRatio) / (1 - sqrtRatio);

    if (swr > 99) swr = 99;

  }

 

  // Kompensasi SWR agar tidak melonjak drastis pada power besar

  if (pFwd > 20) {  // threshold power 20 watt

    float faktor = 20.0 / pFwd;

    if (faktor < 0.2) faktor = 0.2;  // batas minimal faktor

    swr = 1.0 + (swr - 1.0) * faktor;

  }

 

  float rl = 0;

  if (pFwd > 0.1 && pRef > 0.01) {

    rl = -10.0 * log10(pRef / pFwd);

  } else {

    rl = 99.0;

  }

 

  // Alarm berbunyi jika SWR > 1.5

  if (swr > 1.5) {

    unsigned long currentMillis = millis();

    if (currentMillis - lastAlarmToggle >= 500) { // Alarm berdenyut

      lastAlarmToggle = currentMillis;

      alarmState = !alarmState;

      if (alarmState) {

        tone(ALARM_PIN, 2000);  // Frekuensi 2kHz

      } else {

        noTone(ALARM_PIN);

      }

    }

  } else {

    noTone(ALARM_PIN);

    alarmState = false;

  }

 

  // OLED Tampilkan data

  display.clearDisplay();

 

  display.setCursor(20, 0);

  display.setTextSize(1);

  display.print(F("SWR & POWER METER"));

 

  display.setCursor(0, 12);

  display.setTextSize(1);

  display.print(F("PWR : ")); display.print(pFwd, 1); display.println(F(" W"));

 

  display.setCursor(0, 22);

  display.print(F("REF : ")); display.print(pRef, 1); display.println(F(" W"));

 

  display.setCursor(0, 32);

  display.print(F("SWR : ")); display.println(swr, 2);

 

  display.setCursor(0, 42);

  display.print(F("RL  : ")); display.print(rl, 1); display.println(F(" dB"));

 

  // Bar SWR

  int barWidth = map(swr * 100, 100, 300, 0, 128);

  barWidth = constrain(barWidth, 0, 128);

  display.fillRect(0, 56, barWidth, 6, SSD1306_WHITE);

  display.drawRect(0, 56, 128, 6, SSD1306_WHITE);

 

  display.display();

 

  delay(500);

}

 


Thursday, 8 May 2025

Nano SWR Power Meter VHF


Kode Program dan Wiring

Wiring

Sensor Forward                A0           Tegangan maju (via coupler)

Sensor Reflected             A1           Tegangan pantul (via coupler)

OLED SDA            A4           Data I2C

OLED SCL             A5           Clock I2C

OLED VCC            5V           Power 5V

OLED GND           GND      Ground

Buzzer (+)           D4           Alarm SWR tinggi

Buzzer (–)           GND      Ground

 

Kode Program

#include <Wire.h>

#include <Adafruit_GFX.h>

#include <Adafruit_SSD1306.h>

 

#define PIN_FORWARD A0

#define PIN_REFLECTED A1

#define BUZZER_PIN 4

 

#define SCREEN_WIDTH 128

#define SCREEN_HEIGHT 64

#define OLED_RESET -1

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

 

// Kalibrasi daya

const float forwardScale = 1.28;

const float reflectedScale = 1.28;

 

// Fungsi pembacaan rata-rata analog

float readAverage(int pin, int samples = 10) {

  long total = 0;

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

    total += analogRead(pin);

    delay(2); // delay kecil antar pembacaan

  }

  return (float)total / samples;

}

 

void setup() {

  Serial.begin(9600);

  pinMode(PIN_FORWARD, INPUT);

  pinMode(PIN_REFLECTED, INPUT);

  pinMode(BUZZER_PIN, OUTPUT);

  digitalWrite(BUZZER_PIN, LOW);

 

  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {

    Serial.println(F("OLED tidak ditemukan"));

    while (true);

  }

 

  display.clearDisplay();

  display.display();

}

 

void loop() {

  // Baca tegangan dari coupler dengan rata-rata

  float vForward = readAverage(PIN_FORWARD) * (5.0 / 1023.0);

  float vReflected = readAverage(PIN_REFLECTED) * (5.0 / 1023.0);

 

  // Hitung daya

  float pForward = vForward * forwardScale;

  float pReflected = vReflected * reflectedScale;

 

  // Hitung SWR

  float swr;

  if (pForward == 0) {

    swr = 1.0;

  } else {

    float sqrtR = sqrt(pReflected / pForward);

    if (sqrtR >= 1.0) sqrtR = 0.999;

    swr = (1 + sqrtR) / (1 - sqrtR);

  }

 

  // Alarm jika SWR tinggi

  digitalWrite(BUZZER_PIN, (swr > 1.5) ? HIGH : LOW);

 

  // Tampilan OLED

  display.clearDisplay();

 

  // Judul

  display.setTextSize(2);

  display.setTextColor(SSD1306_WHITE);

  display.setCursor(0, 0);

  display.print("PILIHAN");

  display.setCursor(0, 16);

  display.print("ONLINE");

 

  // Data daya & SWR

  display.setTextSize(1);

  display.setCursor(0, 34);

  display.print("FWD:");

  display.print(pForward, 1);

  display.print("W");

 

  display.setCursor(64, 34);

  display.print("REF:");

  display.print(pReflected, 1);

  display.print("W");

 

  display.setCursor(0, 44);

  display.print("SWR:");

  display.print(swr, 2);

 

  // Bar SWR

  int barWidth = map(constrain(swr, 1, 5) * 10, 10, 50, 10, 120);

  display.drawRect(0, 56, 128, 6, SSD1306_WHITE);

  display.fillRect(0, 56, barWidth, 6, SSD1306_WHITE);

 

  display.display();

  delay(300);

}


 

Saturday, 12 October 2024

DIY Power Meter VHF 200W~2KW








Wa : 0858-7406-4828
 

Nano VNA Modifikasi MDF V2












Wa : 0858-7406-4828
 

DIY FM Transmitter 10 Watt

 













WA : 0858-7406-4828

Wednesday, 21 June 2023

NanoVNA Modifikasi

 NanoVNA Modifikasi

NanoVNA adalah penganalisis jaringan vektor yang mampu mengukur antena, filter, duplekser, dan amplifier, dalam penggunaan umum NanoVNA di gunakan untuk melihat impedensi dari antena dan mengukur SWR dari antena yang akan kita gunakan.

NanoVNA ini kalibrasinya manual dimana beban Load saat kalibrasi akan di anggapnya 50 walau kita menggunakan dummyload 100 ohm atau 75 ohm dimana beban load saat kalibrasi akan menjadi acuan pengukuranya misal kita kalibrasi dengan dummyload 100 ohm maka impedensi 50 ohmnya adalah di 100 ohm jadi pastikan bahwa saat kalibrasi gunakan dummyload yang empedensinya pas 50 ohm agar pengukuran nanti tidak salah atau keliru karena dari pengalaman saya nilai impedensi dummyload bawaan nanoVNA sering tidak sama kalau di ukur ada yang impedensinya 48, 51, 53,54 ohm walau nilai ini masih termasuk kategori nilai toleransi, dibawah ini saya sertakan nilai dummyload bawaan dari 2 jenis nanoVNA dan Rflange




Nah Sekarang masuk ke tahapan modifikasi, apa alasan saya melakukan modifikasi pada nanoVNA Tipe H?  yang pertama adalah konektor bawaanya mudah copot, patah dan kurang kuat karena menggunakan konektor SMA yang di solder langsung pada PCB tanpa penyanggah apapun, kedua adalah karena nanoVNA H ini sangat ringkih dan tidak di lindungi BOX jadi rawan terbentur kena debu dan cairan, yang ke tiga adalah karena kurang nyaman saat di gunakan karena sangat ringan dan mudah tertari-tarik oleh kabel, dan yang ke empat batre bawaan berkapasitas kecil sehingga cepat habis saat di gunakan nah dari empat alasan di atas saya berinisiatif untuk melakukan modifikasi yakni penambahan casing, penggantian konektor ke PL dan Upgrade batre menjadi lebih besar.

Terus banyak yang meragukan ke akuratan NanoVNA ini, Jawaban nya ga usah ragu karena pembacaan nanoVNA ini lumayan detil tinggal kita kalibrasi saja dengan benar karena pengukuran nanoVNA ini berdasarkan hasil kalibrasi di ujung konektornya jadi tidak perlu perbandingan karena patokan kita adalah SWR 1.0 dan Impedensinya 50 Ohm karena nanoVNA akan berpatokan pada nilai kalibrasi tersebut  jadi kuncinya pastikan saat kalibrasi impedensinya harus 50 ohm dan SWR 1.0, Semoga bermanfaat

Sunday, 9 October 2022

Kode program

 //-------------------------

//TEA5767 FM Radio Receiver

//-------------------------

#include <Wire.h>

#include <TEA5767N.h>

#include <LiquidCrystal.h>

//-------------------------------------------

TEA5767N radio = TEA5767N();

LiquidCrystal lcd(3, 4, 5, 6, 7, 8);

//-------------------------------------------

float station[] = {76.8,87.6,97.2,91.8,91,0,98.5,102.6};

int i=0, numStations = *(&station+1)-station;

boolean powerOnOff = false, muteAudio = false;

//===============================================================

void setup()

  pinMode(9,INPUT); pinMode(13,INPUT);

  radio.setStereoNoiseCancellingOn();

  lcd.begin(16, 2);

  lcd.clear();

  attachInterrupt(0, ISR_powerOnOff, RISING);

}

//===============================================================

void loop()

  if(powerOnOff == false)

  {

    lcd.setCursor(0, 0);

    lcd.print("Nopringki, S.Pd");

    lcd.setCursor(0, 1);

    lcd.print("Power OFF");

    radio.setStandByOn();

  }

  if(powerOnOff == true)

  {

    lcd.setCursor(0, 0);

    lcd.print("Power On");

    lcd.setCursor(0, 1);

    lcd.print("Pilih Chanel");

    radio.setStandByOff();

    radio.mute();

  }

  //-------------------------------------------

  while(powerOnOff)

  {

    if(digitalRead(9) == HIGH) changeStation();

    if(digitalRead(13) == HIGH) muteStatus();

  }

}

//===============================================================

void changeStation()

{

  radio.turnTheSoundBackOn();

  radio.selectFrequency(station[i]);

  lcd.clear();

  delay(200);

  if(radio.isStereo()==1) lcd.print("Nopringki Chanel");

  if(radio.isStereo()==0) lcd.print("Nopringki Chanel");

  lcd.setCursor(0, 1);

  lcd.print(radio.readFrequencyInMHz());

  lcd.setCursor(6, 1); lcd.print("MHz");

  lcd.setCursor(10,1);

  lcd.print("SL:"); lcd.print(radio.getSignalLevel()*100/15);

  lcd.setCursor(15,1); lcd.print("%");

  i++;

  if(i == numStations) i = 0;

}

//===============================================================

void ISR_powerOnOff()

{

  powerOnOff = !powerOnOff;

  lcd.clear();

}

//===============================================================

void muteStatus()

{

  delay(200);

  muteAudio = !muteAudio;

  if(muteAudio == true) radio.mute();

  else radio.turnTheSoundBackOn();

}