I've been using electronics for a few years now and have decided to make a fancy smart alarm clock with an ESP8266 Wi-Fi module to use for geolocation to set time based on time-zone and maybe integrate AI to make a home assistant. The rest is an arduino uno, adafruit screw shield, voltage splitter (for the ESP's 3.3v architecture), LCD shield, and RTC module for timekeeping. but I keep getting the error ESP not found! and I am struggling with finding the reason. my wiring looks like the picture added, and my code is below as well. Ideas?
#include <Wire.h>
#include <RTClib.h>
#include <LiquidCrystal.h>
#include <WiFiEsp.h> // WiFi library for ESP8266 AT mode
#include <WiFiEspUdp.h> // UDP for NTP
#include <NTPClient.h> // NTP client
#include <ArduinoJson.h> // JSON parsing for API response
// RTC setup
RTC_DS3231 rtc;
// LCD pins (standard for LCD Keypad Shield)
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
// Button pin (analog for keypad)
const int btnPin = A0;
// Alarm settings (change these)
int alarmHour = 8; // 24-hour format
int alarmMinute = 30;
bool alarmSet = true; // Alarm enabled by default
// Variables for time and state
int currentHour, currentMinute, currentSecond;
bool alarming = false;
bool settingTime = false; // For RTC time adjustment mode
const int buzzerPin = 3; // Changed to free pin (avoid conflict with LCD pin 9)
// ESP8266 setup (using hardware Serial on pins 0/1)
char ssid[] = "YOUR_WIFI_SSID"; // Replace with your WiFi SSID
char pass[] = "YOUR_WIFI_PASSWORD"; // Replace with your WiFi password
int wifiStatus = WL_IDLE_STATUS;
// NTP setup (UTC initially)
WiFiEspUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", 0, 60000); // Pool server, 0 offset (UTC), update every 60s
// Variables for location/timezone
String currentTimezone = "";
String currentCity = "";
String currentCountry = "";
long timezoneOffset = 0;
void setup() {
lcd.begin(16, 2);
lcd.print("Alarm Clock");
delay(2000);
lcd.clear();
if (!rtc.begin()) {
lcd.print("RTC not found!");
while (1);
}
// Set initial time if RTC lost power (uncomment and upload once)
// rtc.adjust(DateTime(F("Jul 30 2025"), F("09:43:00")));
pinMode(buzzerPin, OUTPUT);
digitalWrite(buzzerPin, LOW);
// Initialize ESP8266 WiFi on hardware Serial
Serial.begin(115200); // Hardware serial for ESP (test baud 115200)
// Serial.begin(74880); // Uncomment to try boot baud if 115200 fails
delay(1000); // Delay to let ESP stabilize
sendAT("AT+RST"); // Reset ESP before init
delay(3000); // Longer wait for reset
WiFi.init(&Serial);
// To enable debug, edit WiFiEsp library debug.h and set DEBUG_LEVEL to 4, then restart IDE
// Retry loop for initialization (tries 3 times)
int retries = 0;
while (WiFi.status() == WL_NO_SHIELD && retries < 3) {
lcd.print("ESP init retry...");
delay(2000);
sendAT("AT"); // Test AT during retries
retries++;
}
if (WiFi.status() == WL_NO_SHIELD) {
lcd.print("ESP not found!");
while (1);
} else {
lcd.print("ESP detected!");
sendAT("AT"); // Basic test command
delay(3000);
lcd.clear();
}
// Connect to WiFi
while (wifiStatus != WL_CONNECTED) {
lcd.setCursor(0, 1);
lcd.print("Connecting WiFi...");
wifiStatus = WiFi.begin(ssid, pass);
delay(5000);
}
lcd.clear();
lcd.print("WiFi Connected");
// Sync time and timezone on startup
syncTimeAndTimezone();
delay(2000);
lcd.clear();
}
// Function to send AT commands and print responses for debugging
void sendAT(String command) {
Serial.println(command);
lcd.print("Sent: " + command.substring(0, 8)); // Show on LCD (limited space)
delay(3000); // Longer wait for response (increased from 1000)
String response = "";
while (Serial.available()) {
response += (char)Serial.read();
}
if (response.length() > 0) {
lcd.clear();
lcd.print("Resp: " + response.substring(0, 8)); // Show response snippet on LCD
}
delay(2000);
lcd.clear();
}
void loop() {
DateTime now = rtc.now();
currentHour = now.hour();
currentMinute = now.minute();
currentSecond = now.second();
// Display time
lcd.setCursor(0, 0);
lcd.print("Time: ");
if (currentHour < 10) lcd.print("0");
lcd.print(currentHour);
lcd.print(":");
if (currentMinute < 10) lcd.print("0");
lcd.print(currentMinute);
lcd.print(":");
if (currentSecond < 10) lcd.print("0");
lcd.print(currentSecond);
// Display alarm status
lcd.setCursor(0, 1);
lcd.print("Alarm: ");
if (alarmHour < 10) lcd.print("0");
lcd.print(alarmHour);
lcd.print(":");
if (alarmMinute < 10) lcd.print("0");
lcd.print(alarmMinute);
lcd.print(alarmSet ? " ON " : " OFF");
// Check for alarm trigger
if (alarmSet && currentHour == alarmHour && currentMinute == alarmMinute && currentSecond == 0) {
alarming = true;
}
if (alarming) {
tone(buzzerPin, 1000); // Beep at 1kHz
delay(500);
noTone(buzzerPin);
delay(500);
}
// Read buttons (thresholds: right<60, up<200, down<400, left<600, select<800)
int btnValue = analogRead(btnPin);
if (btnValue < 60) { // Right: Stop alarm fully
alarming = false;
alarmSet = false; // Disable after trigger (optional)
} else if (btnValue < 200) { // Up: Increase hour (alarm or current time)
if (settingTime) {
currentHour = (currentHour + 1) % 24;
} else {
alarmHour = (alarmHour + 1) % 24;
}
} else if (btnValue < 400) { // Down: Decrease minute (alarm or current time)
if (settingTime) {
currentMinute = (currentMinute > 0) ? currentMinute - 1 : 59;
} else {
alarmMinute = (alarmMinute > 0) ? alarmMinute - 1 : 59;
}
} else if (btnValue < 600) { // Left: Toggle alarm OR sync time if held
delay(500); // Check for long press
if (analogRead(btnPin) < 600) { // Held: Sync time/timezone
syncTimeAndTimezone();
} else { // Short: Toggle alarm
alarmSet = !alarmSet;
}
} else if (btnValue < 800) { // Select: Toggle time set mode or snooze alarm
if (alarming) {
alarming = false; // Snooze: Add 5 min to alarm
alarmMinute += 5;
if (alarmMinute >= 60) {
alarmMinute -= 60;
alarmHour = (alarmHour + 1) % 24;
}
} else {
settingTime = !settingTime; // Enter/exit RTC time set mode
if (!settingTime) {
// Save adjusted time to RTC
rtc.adjust(DateTime(now.year(), now.month(), now.day(), currentHour, currentMinute, 0));
}
}
}
delay(100); // Basic debounce
}
void syncTimeAndTimezone() {
lcd.clear();
lcd.print("Syncing Time...");
// Get UTC from NTP
timeClient.begin();
if (timeClient.forceUpdate()) { // Force immediate sync
unsigned long utcEpoch = timeClient.getEpochTime();
// Get timezone/location from API
WiFiEspClient client;
if (client.connect("ip-api.com", 80)) {
client.println("GET /json?fields=timezone,offset,city,country HTTP/1.1");
client.println("Host: ip-api.com");
client.println("Connection: close");
client.println();
String response = "";
while (client.connected() || client.available()) {
if (client.available()) {
response += client.readString();
}
}
client.stop();
// Parse JSON (response includes headers; find { start)
int jsonStart = response.indexOf("{");
if (jsonStart != -1) {
String jsonStr = response.substring(jsonStart);
DynamicJsonDocument doc(512);
DeserializationError error = deserializeJson(doc, jsonStr);
if (!error) {
currentTimezone = doc["timezone"].as<String>();
timezoneOffset = doc["offset"];
currentCity = doc["city"].as<String>();
currentCountry = doc["country"].as<String>();
// Adjust to local epoch and set RTC
unsigned long localEpoch = utcEpoch + (timezoneOffset);
rtc.adjust(DateTime(localEpoch));
// Optional: Display location/timezone briefly
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(currentCity + ", " + currentCountry);
lcd.setCursor(0, 1);
lcd.print(currentTimezone);
delay(3000);
lcd.clear();
} else {
lcd.print("JSON Parse Fail");
delay(2000);
}
} else {
lcd.print("API Response Fail");
delay(2000);
}
} else {
lcd.print("API Connect Fail");
delay(2000);
}
} else {
lcd.print("NTP Sync Fail");
delay(2000);
}

