The story of my user (and current headache)

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);
  }

1 Like

Post the verbose error log in code tags. Also, take a photo of a hand-drawn wiring diagram. What you posted is not useful.

2 Likes

Welcome to the forum

You mention both an ESP8266 and a Uno but have posted only one sketch

Is it an ESP-01 or an ESP-01S

1 Like

Nvm, missed read.

using the ESP8266 (pictured below) for geolocation, the uno is the board I am using

an ESP-01

I may have to use a whole different wifi module, turns out the ones I use are really finnicky.

From you picture it looks like you have all 8 pins connected to the Uno but there ar no pins defined in your code. What is CH_EN, Reset, GPIO-0 and 2 set to?

I think they are standardized to be connected to 3.3v (according to my sources)

Not what I asked.
If CH_EN and Reset are not set to HIGH and GPIOs disconnected if you are not using them, then the module will either never work or you may have sporadic operation.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.