Tuesday, September 2, 2025

How to Build an Automatic Station Identification using Arduino and DF Player

 


One of my recent weekend project  is the automatic station identifier using Arduino Nano, DFPlayer and DS1307 RTC module. These three modules were integrated on a compact 2 x 3 inch printed circuit board with the addition of a general-purpose transistor to reliably key the transmitter at pre-programmed intervals.

The code for this project was initially generated with the assistance of ChatGPT. Subsequent  refinements included the incorporation of additional libraries  and code modifications to ensure proper functionality. 

Below is the code.

.......................................................................................................................................................................

#include <Wire.h>

#include "Arduino.h"

#include "SoftwareSerial.h"

#include "DFRobotDFPlayerMini.h"

#include "uRTCLib.h"


uRTCLib rtc(0x68);


SoftwareSerial mySerial(10, 11); // D10 = TX, D11 = RX

DFRobotDFPlayerMini myDFPlayer;


const int busyPin = 7;   // DFPlayer BUSY pin

const int playLed = 5;   // Indicator output (HIGH while playing)


int lastMinute = -1;


void setup() {

  

  delay (1000);  //This is included to allow the reset of arduino.

  pinMode(busyPin, INPUT);   

  pinMode(playLed, OUTPUT);  

  digitalWrite(playLed, LOW);


  Serial.begin(9600);

  mySerial.begin(9600);


#ifdef ARDUINO_ARCH_ESP8266

URTCLIB_WIRE.begin(0, 2); // D3 and D4 on ESP8266


  #else

   URTCLIB_WIRE.begin();

  #endif


//rtc.set(45, 29, 19, 6, 23, 8, 25);

//  RTCLib::set(byte second, byte minute, byte hour, byte dayOfWeek, byte dayOfMonth, byte month, byte year)



  if (!myDFPlayer.begin(mySerial)) {

    Serial.println("Unable to begin DFPlayer Mini");

    while (1);

  }


 myDFPlayer.volume(23);  // set volume (0–30)

  

  }


void loop() {

  


  rtc.refresh();


  // --- Show realtime clock every second ---

  Serial.print(rtc.year());

  Serial.print('/');

  Serial.print(rtc.month());

  Serial.print('/');

  Serial.print(rtc.day());

  Serial.print(" ");

  Serial.print(rtc.hour());

  Serial.print(':');

  Serial.print(rtc.minute());

  Serial.print(':');

  Serial.println(rtc.second());


  // --- Every 30 minutes playback trigger ---

  if (rtc.minute() % 15 == 0 && rtc.minute() != lastMinute && rtc.second() == 0) {

    lastMinute = rtc.minute();

    Serial.println("Playing MP3...");

    myDFPlayer.play(1);   // Play first MP3 file (0001.mp3 on SD card)

  }


  // --- Monitor DFPlayer BUSY line ---

  if (digitalRead(busyPin) == LOW) {

    digitalWrite(playLed, HIGH);  // Playing

  } else {

    digitalWrite(playLed, LOW);   // Idle

  }


  delay(1000);

}

.......................................................................................................................................................................


The program is configured to trigger the DFPlayer module at 15 minute interval throughout the hour. During idle periods, the system continuously outputs real-time clock data via the Arduino serial interface. This feature provides an external monitoring capability and allows RTC calibration when necessary.

When the scheduled event occurs, the Arduino simultaneously initiates audio playback on the DFPlayer and signal digital pin 5 to key the transmitter PTT. The Arduino also monitors the busy pin of the DFPlayer via digital pin 7, enabling the microcontroller to accurately determine the end of the audio playback. This ensures that the transmitter's PTT is released in precise synchronization with the termination of the station identification message.




The video below demonstrates the project in operation, keying an Icom IC-2200H radio transceiver. In the future, I am planning to modify the code to include automated time announcement in addition to the station identification feature.   ---73 de du1vss




Sunday, August 10, 2025

How to build a programmable Buck Converter XY6020L

 




Another find from the Chinese market is this XY6020L DIY programmable buck converter.  I bought mine from Lazada for about 21 USD and the kit comes into two modules. One of the module is the main buck converter unit while the other one serves as the display keypad unit.


 

My programmable buck converter uses a salvaged old PSU aluminum case and  connected the module to a 10amps, 24V switching power supply.


 With this combination, my working DIY power supply is now capable delivering 0 to 24V volts and 0-10Amps of current. The front knob and buttons provides access to adjust the CV and CC and the small back lit LCD provides visual indication of my set points and real-time voltage/current output of the converter.


Why need to buy expensive PSU when you can make one. ---73 de du1vss.













Tuesday, July 8, 2025

Programming my Arduino Industrial Board




 

I 'm excited to start testing my newly acquired Arduino Industrial 101 board for potential R&D in Internet of Things (IOT) applications. Thanks to the help of various AI tools, programming microcontrollers has become much easier and faster, making the learning more efficient.

Upon inspecting the board, I can see that this board has 3 digital pins and 4 analog input channels. For my first project, I 'm using the digital pins 5, 6 and 13 each connected to a differently colored LED. Based on  ChatGPT,'s suggestion, activating these LEDs requires the use of Bridge library, and is recommended the following code as a starting point.

#include <Bridge.h>
#include <YunServer.h>
#include <YunClient.h>

YunServer server;

void setup() {
  Bridge.begin();      // Start Bridge
  server.listenOnLocalhost();
  server.begin();

  pinMode(5, OUTPUT);   // Set pin 5 as output
  pinMode(6, OUTPUT);   // Set pin 6 as output
  pinMode(13, OUTPUT);  // Set pin 13 as output
}

void loop() {
  YunClient client = server.accept();

  if (client) {
    process(client);
    client.stop();
  }

  delay(50);
}

void process(YunClient client) {
  String command = client.readStringUntil('/');

  if (command == "digital") {
    int pin = client.readStringUntil('/').toInt();
    int value = client.readStringUntil('\r').toInt();

    if (pin == 5 || pin == 6 || pin == 13) {
      digitalWrite(pin, value);
      client.print(F("Pin "));
      client.print(pin);
      client.print(F(" set to "));
      client.print(value);
    } else {
      client.print(F("Invalid pin."));
    }
  } else {
    client.print(F("Invalid command."));
  }
}

After compiling the code and programming it to the board, the 3 LEDs can be tested by the following http commands.

Activate pin 5: http://arduino.local/arduino/digital/5/1
Deactivate pin 5: http://arduino.local/arduino/digital/5/0

Activate pin 6: http://arduino.local/arduino/digital/6/1
Deactivate pin6: http://arduino.local/arduino/digital/6/0

Activate pin 13: http://arduino.local/arduino/digital/13/1
Deactivate pin 13: http://arduino.local/arduino/digital/13/0





Using ChatGPT again, I was able to create an HTML interface with 3 buttons corresponding to each LED. With this dashboard, I can now control all the 3 LEDs remotely. Below is the HTML code used to control the LEDs. 


<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Arduino Pin Control</title>
  <style>
    body {
      font-family: Arial, sans-serif;
      text-align: center;
      margin-top: 50px;
    }
    .button {
      display: inline-block;
      width: 140px;
      padding: 15px;
      margin: 10px;
      font-size: 18px;
      border: none;
      border-radius: 10px;
      cursor: pointer;
      background-color: #ccc;
    }
    .button.on {
      background-color: #4CAF50;
      color: white;
    }
  </style>
</head>
<body>

  <h1>Arduino Control Panel</h1>

  <button class="button" id="pin5" onclick="togglePin(5)">Pin 5 OFF</button>
  <button class="button" id="pin6" onclick="togglePin(6)">Pin 6 OFF</button>
  <button class="button" id="pin13" onclick="togglePin(13)">Pin 13 OFF</button>

  <script>
    const arduinoIP = "192.168.8.238";  // ✅ Your Arduino IP
    const pinStates = { 5: 0, 6: 0, 13: 0 };

    function togglePin(pin) {
      // Toggle internal state
      pinStates[pin] = pinStates[pin] ? 0 : 1;

      // Build URL
      const url = `http://${arduinoIP}/arduino/digital/${pin}/${pinStates[pin]}`;

      // Use Image to send GET request (avoids CORS)
      const img = new Image();
      img.src = url;

      // Update button UI
      const btn = document.getElementById(`pin${pin}`);
      if (pinStates[pin]) {
        btn.classList.add("on");
        btn.textContent = `Pin ${pin} ON`;
      } else {
        btn.classList.remove("on");
        btn.textContent = `Pin ${pin} OFF`;
      }
    }
  </script>

</body>
</html> 

Before uploading the code to Arduino, make sure to connect the board to your local WIFI network. Once connected, take note of the IP address assigned to the board, and update your HTML code accordingly to ensure proper communication.   --- 73 de du1vss