Rohan Barnwal
Published © GPL3+

Arduino Truck Alarm Clock Featuring Realisitic Engine Sound

A custom Arduino-powered Indian truck alarm clock with dual OLED displays, realistic truck startup sounds

IntermediateFull instructions provided1 hour177
Arduino Truck Alarm Clock Featuring Realisitic Engine Sound

Things used in this project

Hardware components

High Accuracy Pi RTC (DS3231)
Seeed Studio High Accuracy Pi RTC (DS3231)
×1
DFPlayer - A Mini MP3 Player
DFRobot DFPlayer - A Mini MP3 Player
×1
0.96" OLED 64x128 Display Module
ElectroPeak 0.96" OLED 64x128 Display Module
×2
Speaker, Piezo
Speaker, Piezo
×1
LED (generic)
LED (generic)
×4
Jumper wires (generic)
Jumper wires (generic)
×1
9V 1A Switching Wall Power Supply
9V 1A Switching Wall Power Supply
×1
Arduino Mega
×1

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Schematics

ujjk_jB1Mba5oUJ.png

Code

Code

Arduino
#include <Wire.h>
#include <U8g2lib.h>
#include "RTClib.h"
#include "DFRobotDFPlayerMini.h"

// 🟢 OLED1 → SCL=22, SDA=24
U8G2_SSD1306_128X64_NONAME_F_SW_I2C oled1(U8G2_R0, 22, 24, U8X8_PIN_NONE);

// 🔵 OLED2 → SCL=23, SDA=25
U8G2_SSD1306_128X64_NONAME_F_SW_I2C oled2(U8G2_R0, 23, 25, U8X8_PIN_NONE);

// RTC
RTC_DS3231 rtc;

// DFPlayer
DFRobotDFPlayerMini df;

// BUSY pin
const int busyPin = 43;
bool lastBusy = HIGH;

// LEDs
int ledPins[] = {34, 36, 38, 40};
bool ledState = false;

// States
int state = 0;
// 0 = idle
// 1 = playing 0001
// 2 = looping
// 3 = stopped

bool startTriggered = false;
bool stopTriggered = false;

// Loop pattern
int loopTracks[] = {2, 4, 4};
int loopIndex = 0;

void setup() {
  Serial.begin(115200);
  Serial1.begin(9600);
  Wire.begin();

  oled1.begin();
  oled2.begin();

  oled1.setBusClock(50000);
  oled2.setBusClock(50000);

  pinMode(busyPin, INPUT);

  for (int i = 0; i < 4; i++) {
    pinMode(ledPins[i], OUTPUT);
  }

  if (!rtc.begin()) {
    Serial.println("RTC NOT FOUND");
    while (1);
  }

  if (!df.begin(Serial1)) {
    Serial.println("DFPlayer NOT FOUND");
    while (1);
  }

  df.volume(30);
}

void loop() {

  DateTime now = rtc.now();
  int h = now.hour();
  int m = now.minute();

  // ---------- OLED ----------
  char hourStr[3], minStr[3];
  sprintf(hourStr, "%02d", h);
  sprintf(minStr, "%02d", m);

  oled1.clearBuffer();
  oled1.setFont(u8g2_font_logisoso32_tr);
  oled1.drawStr((128 - oled1.getStrWidth(hourStr)) / 2, 45, hourStr);
  oled1.sendBuffer();

  oled2.clearBuffer();
  oled2.setFont(u8g2_font_logisoso32_tr);
  oled2.drawStr((128 - oled2.getStrWidth(minStr)) / 2, 45, minStr);
  oled2.sendBuffer();

  // ---------- START @ 12:50 ----------
  if (h == 12 && m == 50 && !startTriggered) {
    Serial.println("START SEQUENCE");

    df.play(1);  // 0001
    state = 1;
    startTriggered = true;
    loopIndex = 0;
  }

  // ---------- STOP @ 12:55 ----------
  if (h == 12 && m == 55 && !stopTriggered) {
    Serial.println("STOP SEQUENCE");

    df.stop();
    delay(200);
    df.play(3);  // 0003

    state = 3;
    stopTriggered = true;
  }

  // reset trigger
  if (!(h == 12 && m == 50)) startTriggered = false;
  if (!(h == 12 && m == 55)) stopTriggered = false;

  // ---------- DFPLAYER ----------
  bool currentBusy = digitalRead(busyPin);

  if (lastBusy == LOW && currentBusy == HIGH) {

    if (state == 1) {
      state = 2;
      df.play(loopTracks[loopIndex]);
    }

    else if (state == 2) {
      loopIndex = (loopIndex + 1) % 3;

      df.play(loopTracks[loopIndex]);

      Serial.print("Loop: ");
      Serial.println(loopTracks[loopIndex]);
    }
  }

  lastBusy = currentBusy;

  // ---------- LED BLINK ----------
  if (state == 2) {
    ledState = !ledState;

    for (int i = 0; i < 4; i++) {
      digitalWrite(ledPins[i], ledState);
    }
  } else {
    for (int i = 0; i < 4; i++) {
      digitalWrite(ledPins[i], LOW);
    }
  }

  delay(200);
}

Credits

Rohan Barnwal
52 projects • 41 followers
Rohan Barnwal - maker, hacker, tech enthusiast. I explore new tech & find innovative solutions. See my projects on hackster.io!

Comments