Spotted a mistake?
🫑 Retrofit a wired doorbell to add WiFi and make it connected 🔔
Press the doorbell to sound the bell and send a notification if the current time is appropriate
This example shows how to use the ESP32-C3 dev board to do the following:
Serial output from the firmware.
Wire up the hardware accordingly
#ifdef PRODUCTION #define DEBUG DBG_NONE #else #define DEBUG DBG_VERBOSE #endif // Change the debug level accordingly: // DBG_NONE, DBG_ERROR, DBG_WARNING, // DBG_INFO (default), DBG_DEBUG, and DBG_VERBOSE #include "Arduino_DebugUtils.h" #include "src/bell/bell.h" #include "src/ledController/ledController.h" #include "src/sleepManager/sleepManager.h" #include "src/wifiConnector/wifiConnector.h" #include "src/timeManager/timeManager.h" #include "src/webhookClient/webhookClient.h" #include "src/batteryLevel/batteryLevel.h" #include "Secret.h" // Timeout for the bell to ring const int bellTimeout = 30000; // 30 seconds // GMT+8 (8 hours * 60 minutes * 60 seconds) const long timeZoneOffset = 28800; const int startTime = 9; // 9am or 0900h const int endTime = 21; // 9pm or 2100h #define BELL_PIN 7 #define LED 3 #define WAKEUP_INTERRUPT_PIN 4 #define BATTERY_ENABLE_PIN 6 #define BATTERY_MEASUREMENT_PIN 5 // Connect this pin to HIGH if you want to stay awake // E.g. for uploading firmware #define SLEEP_CHECK_PIN 2 Bell bell; LEDController ledController(LED); SleepManager sleepManager(WAKEUP_INTERRUPT_PIN, SLEEP_CHECK_PIN); WiFiConnector wifiConnector(ssid, pass); TimeManager timeManager(timeZoneOffset, startTime, endTime); BatteryLevel batteryLevel(BATTERY_ENABLE_PIN, BATTERY_MEASUREMENT_PIN); WebhookClient webhookClient; void setup() { if (DEBUG != DBG_NONE) { Serial.begin(115200); while (!Serial) { } } Debug.setDebugLevel(DEBUG); Debug.timestampOn(); wifiConnector.connect(); if (wifiConnector.isConnected()) { handleConnectedWiFi(); } else { initializeAndRingBell(); } delay(bellTimeout); // Timeout for the doorbell #ifndef PRODUCTION ledController.init(); #endif } void loop() { #ifndef PRODUCTION ledController.blink(1); #endif if (sleepManager.shouldGoToSleep()) { DEBUG_INFO("Going to sleep"); sleepManager.sleep(); } DEBUG_INFO("Staying awake"); } void handleConnectedWiFi() { DEBUG_INFO("Connected to WiFi SSID "); DEBUG_INFO(wifiConnector.getSSID()); ringBellIfNeeded(); // Send to Zapier in production environment // 100/month Zapier limit #ifdef PRODUCTION sendWebhookToZapier(); #endif wifiConnector.disconnect(); } void ringBellIfNeeded() { DEBUG_DEBUG("Initializing time manager..."); timeManager.init(); DEBUG_DEBUG("Time manager initialized."); if (timeManager.isCurrentTimeInRange()) { initializeAndRingBell(); } else { DEBUG_DEBUG("Not ringing the bell! The time is not right."); } } void sendWebhookToZapier() { WebhookClientConfig config = prepareWebhookConfig(); DEBUG_INFO("Sending webhook to Zapier"); if (!webhookClient.sendWebhook(&config)) { DEBUG_ERROR("Unsuccessful sending to Zapier"); } else { DEBUG_INFO("Successful in sending the webhook to Zapier"); } } void initializeAndRingBell() { DEBUG_DEBUG("Initializing bell..."); bell.init(BELL_PIN); DEBUG_DEBUG("Bell initialized."); String debugMessage = "Bell should ring after the timeout of " + String(bellTimeout / 1000.0) + "s"; DEBUG_DEBUG(debugMessage.c_str()); bell.ring(); } WebhookClientConfig prepareWebhookConfig() { const char* environment = "testing"; #ifdef PRODUCTION const char* environment = "production"; #endif WebhookClientConfig config = { certificateAuthority, server, host, endpoint, batteryLevel.readLevel(), environment }; return config; }
# Description: Makefile for the demo code # Usage: make [PRODUCTION=1] [lint] [compile] [upload] [clean] # With battery: make PRODUCTION=1 # With USB power: make ifeq ($(PRODUCTION),1) BOARD := esp32:esp32:esp32c3 else BOARD := esp32:esp32:esp32c3:CDCOnBoot=cdc endif PORT ?= /dev/cu.usbmodem1410* BUILD = build EXTRA_FLAGS := $(if $(filter 1,$(PRODUCTION)),-DPRODUCTION=1,) .PHONY: default lint display compile upload clean default: lint compile upload clean lint: cpplint --extensions=ino --filter=-legal/copyright,-runtime/int,-readability/todo *.ino display: @echo "BOARD: $(BOARD)" @echo "PORT: $(PORT)" @echo "EXTRA_FLAGS: $(EXTRA_FLAGS)" compile: clean lint display @if [ "$(PRODUCTION)" = "1" ]; then \ echo "Compiling with extra flags..."; \ arduino-cli compile --fqbn $(BOARD) --output-dir $(BUILD) --build-property build.extra_flags=$(EXTRA_FLAGS) ./; \ else \ echo "Compiling..."; \ arduino-cli compile --fqbn $(BOARD) --output-dir $(BUILD) ./; \ fi upload: @if [ -n "$(PORT)" ]; then \ arduino-cli upload --fqbn $(BOARD) --port $(PORT) --input-dir $(BUILD); \ else \ echo "Port $(PORT) is not available. Please check if another serial monitor is using it, or press BOOT-RESET button on board the PCB."; \ fi clean: rm -rf build