Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save whitebrandy/a28f6a8add61ea6207f2672721eab71a to your computer and use it in GitHub Desktop.
Save whitebrandy/a28f6a8add61ea6207f2672721eab71a to your computer and use it in GitHub Desktop.
#include <Arduino.h>
#include <WiFi.h>
#include <Wire.h>
#include <MQTT.h>
#define uS_TO_S_FACTOR 1000000ULL
#define TIME_TO_SLEEP 3600
#define BUTTON_PIN_BITMASK (1ULL << GPIO_NUM_1)
const char* ssid = "XXX";
const char* password = "XXX";
const char* mqtt_server = "IP";
const char* battery_topic = "backdoor/sensor/voltage";
const char* battery_p_topic = "backdoor/sensor/percent";
const char* lock_topic = "backdoor/sensor/lockstatus";
WiFiClient net;
MQTTClient client;
int lockPin = 1;
int lockstatus = -1;
RTC_DATA_ATTR unsigned long lastUpdate = 0;
void(* panic_reset) (void) = 0;
void flickerled(void) {
int count;
int status;
int _delay;
unsigned long start = millis();
unsigned long current;
pinMode(LED_BUILTIN, OUTPUT);
pinMode(lockPin, INPUT);
while(true) {
current = millis();
if ((current - start) > 60000)
break;
status = !digitalRead(lockPin);
if (status == 0)
_delay = 100;
else
_delay = 1000;
for (int i = 0; i < 5; i++) {
digitalWrite(LED_BUILTIN, HIGH);
delay(_delay);
digitalWrite(LED_BUILTIN, LOW);
delay(_delay);
}
digitalWrite(LED_BUILTIN, LOW);
}
}
void initWifi() {
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
int count = 0;
Serial.printf("Connecting to network: %s\n", ssid);
while(WiFi.status() != WL_CONNECTED) {
Serial.print('.');
Serial.print("Still trying to connect to network!");
delay(100);
count++;
if (count == 100)
ESP.restart();
}
Serial.println();
Serial.printf("Got IP address:");
Serial.println(WiFi.localIP());
}
void print_wakeup_reason() {
esp_sleep_wakeup_cause_t wakeup_reason;
wakeup_reason = esp_sleep_get_wakeup_cause();
switch(wakeup_reason)
{
case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Wakeup caused by external signal using RTC_IO"); break;
case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Wakeup caused by external signal using RTC_CNTL"); break;
case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Wakeup caused by timer"); break;
case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Wakeup caused by touchpad"); break;
case ESP_SLEEP_WAKEUP_ULP : Serial.println("Wakeup caused by ULP program"); break;
default : Serial.printf("Wakeup was not caused by deep sleep: %d\n",wakeup_reason); break;
}
}
float get_battery_voltage() {
uint32_t Vbatt = 0;
for(int i = 0; i < 16; i++) {
Vbatt += analogReadMilliVolts(A0); // Read and accumulate ADC voltage
}
float Vbattf = 2 * Vbatt / 16 / 1000.0; // Adjust for 1:2 divider and convert to volts
Serial.println(Vbattf, 3); // Output voltage to 3 decimal places
delay(100);
return Vbattf; // Wait for 1 second
}
int get_battery_percent(float voltage) {
if (voltage > 4)
return 100;
if ((voltage <= 4) && (voltage > 3.95))
return 95;
if ((voltage <= 3.95) && (voltage > 3.9))
return 92;
if ((voltage <= 3.9) && (voltage > 3.8))
return 85;
if ((voltage <= 3.8) && (voltage > 3.7))
return 79;
if ((voltage <= 3.7) && (voltage > 3.6))
return 61;
if ((voltage <= 3.6) && (voltage > 3.5))
return 43;
if ((voltage <= 3.5) && (voltage > 3.4))
return 15;
if ((voltage <= 3.4) && (voltage > 3.3))
return 3;
if (voltage <= 3.3)
return 0;
}
void initMQTT() {
Serial.println("Attempting to connect to MQTT Broker at: ");
Serial.println(mqtt_server);
client.begin(mqtt_server, 1883, net);
int count = 0;
while (!client.connect("BackdoorSensor", "mqtt", "beelink")) {
Serial.print(".");
Serial.print("Backdoor MQTT still pending!");
delay(100);
count++;
if (count == 100)
ESP.restart();
}
Serial.println("Connected!");
}
void SendMQTTMessage(const char *topic, char* val, int qos) {
Serial.printf("Publishing topic:");
Serial.println(topic);
Serial.printf("Publishing value:");
Serial.println(val);
for (int i=0; i < 1; i++) {
client.publish(topic, val, 0, qos);
delay(500);
}
}
void setup() {
Serial.begin(115200);
pinMode(A0, INPUT); // Configure A0 as ADC input
pinMode(lockPin, INPUT); // GPIO1 as lockstatus
char message[4];
float voltage;
int percent;
Serial.print("Flickering LED...");
flickerled();
Serial.print("Flickering LED...");
print_wakeup_reason();
esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
Serial.println("Setup ESP32 to sleep for every " + String(TIME_TO_SLEEP) +
" Seconds");
voltage = get_battery_voltage();
percent = get_battery_percent(voltage);
dtostrf(voltage, 6, 3, message);
// Network part
initWifi();
initMQTT();
Serial.println("Sending Battery Topic - Voltage");
SendMQTTMessage(battery_topic, message, 0);
dtostrf(percent,3,0,message);
Serial.println("Sending Battery Topic - Percent");
SendMQTTMessage(battery_p_topic, message, 0);
lockstatus = !digitalRead(lockPin);
dtostrf(lockstatus,2,0,message);
Serial.println("Sending lock topic");
SendMQTTMessage(lock_topic, message, 1);
if (lockstatus == 0) { //unlocked
esp_sleep_enable_ext1_wakeup(BUTTON_PIN_BITMASK, ESP_EXT1_WAKEUP_ANY_LOW);
Serial.println("Sleeping to wake up on pin GPIO1 HIGH");
} else {
esp_sleep_enable_ext1_wakeup(BUTTON_PIN_BITMASK, ESP_EXT1_WAKEUP_ANY_HIGH);
Serial.println("Sleeping to wake up on pin GPIO1 LOW");
}
Serial.println("Going to sleep now");
//reread lock status. We will update mqtt status on the next run
Serial.flush();
esp_deep_sleep_start();
Serial.println("This will never be printed");
}
void loop() {
#if 0
uint32_t Vbatt = 0;
for(int i = 0; i < 16; i++) {
Vbatt += analogReadMilliVolts(A0); // Read and accumulate ADC voltage
}
float Vbattf = 2 * Vbatt / 16 / 1000.0; // Adjust for 1:2 divider and convert to volts
Serial.println(Vbattf, 3); // Output voltage to 3 decimal places
delay(1000); // Wait for 1 second
#endif
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment