#include <Wire.h>
#include <RtcDS3231.h>
#include <NimBLEDevice.h>
#include "driver/ledc.h"
RtcDS3231<TwoWire> rtc(Wire);
NimBLEServer* pServer = nullptr;
NimBLECharacteristic* pCharacteristic = nullptr;
const int buzzerPin = 10;
const int ledPin = 2;
const int resolution = 8;
unsigned long previousMillis = 0;
const long interval = 1000;
void setup() {
pinMode(buzzerPin, OUTPUT);
pinMode(ledPin, OUTPUT);
Serial.begin(115200);
Wire.begin(8, 9); // Initialize I2C with GPIO8 as SDA and GPIO9 as SCL
rtc.Begin();
if (!rtc.IsDateTimeValid()) {
Serial.println("RTC lost confidence in the DateTime!");
rtc.SetDateTime(RtcDateTime(__DATE__, __TIME__));
}
if (!rtc.GetIsRunning()) {
Serial.println("RTC was not actively running, starting now");
rtc.SetIsRunning(true);
}
// Set an alarm for 10 seconds from now
RtcDateTime now = rtc.GetDateTime();
RtcDateTime alarmTime = now + 10; // 10 seconds later
DS3231AlarmOne alarm(
alarmTime.Day(),
alarmTime.Hour(),
alarmTime.Minute(),
alarmTime.Second(),
DS3231AlarmOneControl_HoursMinutesSecondsMatch
);
rtc.SetAlarmOne(alarm);
rtc.LatchAlarmsTriggeredFlags(); // Clear any existing alarms
NimBLEDevice::init("ESP32_C3_Audio");
pServer = NimBLEDevice::createServer();
NimBLEService* pService = pServer->createService("12345678-1234-1234-1234-123456789012");
pCharacteristic = pService->createCharacteristic(
"87654321-4321-4321-4321-210987654321",
NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE
);
pService->start();
pServer->getAdvertising()->start();
Serial.println("The device started, now you can pair it with Bluetooth!");
ledc_timer_config_t ledc_timer = {
.speed_mode = LEDC_LOW_SPEED_MODE,
.duty_resolution = (ledc_timer_bit_t)resolution,
.timer_num = LEDC_TIMER_0,
.freq_hz = 1000,
.clk_cfg = LEDC_AUTO_CLK
};
ledc_timer_config(&ledc_timer);
ledc_channel_config_t ledc_channel = {
.gpio_num = buzzerPin,
.speed_mode = LEDC_LOW_SPEED_MODE,
.channel = LEDC_CHANNEL_0,
.intr_type = LEDC_INTR_DISABLE,
.timer_sel = LEDC_TIMER_0,
.duty = 0,
.hpoint = 0
};
ledc_channel_config(&ledc_channel);
}
void loop() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
RtcDateTime now = rtc.GetDateTime();
Serial.print(now.Year());
Serial.print('/');
Serial.print(now.Month());
Serial.print('/');
Serial.print(now.Day());
Serial.print(" ");
Serial.print(now.Hour());
Serial.print(':');
Serial.print(now.Minute());
Serial.print(':');
Serial.print(now.Second());
Serial.println();
}
if (pCharacteristic->getValue().length() > 0) {
String data = pCharacteristic->getValue().c_str();
if (data.length() == 14) {
int year = data.substring(0, 4).toInt();
int month = data.substring(4, 6).toInt();
int day = data.substring(6, 8).toInt();
int hour = data.substring(8, 10).toInt();
int minute = data.substring(10, 12).toInt();
int second = data.substring(12, 14).toInt();
if (year > 2000 && month > 0 && month <= 12 && day > 0 && day <= 31 &&
hour >= 0 && hour < 24 && minute >= 0 && minute < 60 && second >= 0 && second < 60) {
rtc.SetDateTime(RtcDateTime(year, month, day, hour, minute, second));
Serial.println("Time updated via Bluetooth");
} else {
Serial.println("Invalid DateTime format received via Bluetooth");
}
} else {
int freq = data.toInt();
if (freq > 0) {
ledc_set_freq(LEDC_LOW_SPEED_MODE, LEDC_TIMER_0, freq);
digitalWrite(ledPin, HIGH);
delay(100);
digitalWrite(ledPin, LOW);
} else {
Serial.println("Invalid frequency received via Bluetooth");
}
}
pCharacteristic->setValue("");
}
if (rtc.GetAlarmOneTriggered()) {
Serial.println("Alarm One Triggered!");
rtc.LatchAlarmsTriggeredFlags(); // Clear the alarm flag
digitalWrite(buzzerPin, HIGH);
delay(1000); // Buzzer on for 1 second
digitalWrite(buzzerPin, LOW);
}
}