Hendrik Langer
7 years ago
4 changed files with 192 additions and 26 deletions
@ -1,34 +1,176 @@ |
|||||
/**
|
//Define DEBUG to get the Output from DEBUG_PRINTLN
|
||||
* Blink |
#define DEBUG 1 |
||||
* |
|
||||
* Turns on an LED on for one second, |
//Include Basecamp in this sketch
|
||||
* then off for one second, repeatedly. |
#include <Basecamp.hpp> |
||||
* |
#include <Configuration.hpp> |
||||
* https://github.com/platformio/platformio-examples/tree/develop/espressif
|
|
||||
*/ |
#include <U8g2lib.h> |
||||
#include "Arduino.h" |
#ifdef U8X8_HAVE_HW_SPI |
||||
|
#include <SPI.h> |
||||
#ifndef LED_BUILTIN |
#endif |
||||
#define LED_BUILTIN 13 |
#ifdef U8X8_HAVE_HW_I2C |
||||
|
#include <Wire.h> |
||||
#endif |
#endif |
||||
|
|
||||
void setup() |
#include "main.h" |
||||
|
|
||||
|
U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ 15, /* data=*/ 4, /* reset=*/ 16); |
||||
|
|
||||
|
//Create a new Basecamp instance called iot
|
||||
|
Basecamp iot; |
||||
|
|
||||
|
//Variables for the sensor and the battery
|
||||
|
static const int ResetPin = 35; |
||||
|
static const int SensorPin = 32; |
||||
|
static const int BatteryPin = 34; |
||||
|
int sensorValue = 0; |
||||
|
//The batteryLimit defines the point at which the battery is considered empty.
|
||||
|
int batteryLimit = 3300; |
||||
|
|
||||
|
//This is used to control if the ESP should enter sleep mode or not
|
||||
|
bool delaySleep = false; |
||||
|
|
||||
|
//Variables for the mqtt packages and topics
|
||||
|
uint16_t statusPacketIdSub = 0; |
||||
|
String delaySleepTopic; |
||||
|
String statusTopic; |
||||
|
String batteryTopic; |
||||
|
String batteryValueTopic; |
||||
|
|
||||
|
// Reset the configuration to factory defaults (all empty)
|
||||
|
void resetToFactoryDefaults() |
||||
{ |
{ |
||||
// initialize LED digital pin as an output.
|
DEBUG_PRINTLN("Resetting to factory defaults"); |
||||
pinMode(LED_BUILTIN, OUTPUT); |
Configuration config(String{"/basecamp.json"}); |
||||
|
config.load(); |
||||
|
config.reset(); |
||||
|
config.save(); |
||||
} |
} |
||||
|
|
||||
void loop() |
void setup() { |
||||
{ |
//configuration of the battery and sensor pins
|
||||
// turn the LED on (HIGH is the voltage level)
|
pinMode(ResetPin, INPUT_PULLDOWN); |
||||
digitalWrite(LED_BUILTIN, HIGH); |
pinMode(SensorPin, INPUT_PULLDOWN); |
||||
|
pinMode(BatteryPin, INPUT); |
||||
|
|
||||
|
//read the status of the doorsensor as soon as possible to determine the state that triggered it
|
||||
|
sensorValue = digitalRead(SensorPin); |
||||
|
|
||||
|
bool resetPressed = (digitalRead(ResetPin) == HIGH); |
||||
|
if (resetPressed) |
||||
|
{ |
||||
|
resetToFactoryDefaults(); |
||||
|
} |
||||
|
|
||||
|
u8g2.begin(); |
||||
|
delay(50); |
||||
|
u8g2.clearBuffer(); // clear the internal memory
|
||||
|
u8g2.setFont(u8g2_font_ncenB08_tr); // choose a suitable font
|
||||
|
u8g2.drawStr(0,10,"Hello World!"); // write something to the internal memory
|
||||
|
u8g2.sendBuffer(); // transfer internal memory to the display
|
||||
|
|
||||
|
//Initialize Basecamp
|
||||
|
iot.begin(); |
||||
|
|
||||
|
if (resetPressed) { |
||||
|
DEBUG_PRINTLN("**** CONFIG HAS BEEN MANUALLY RESET ****"); |
||||
|
} |
||||
|
|
||||
|
//Configure the MQTT topics
|
||||
|
delaySleepTopic = "esp32-node/cmd/" + iot.hostname + "/delaysleep"; |
||||
|
statusTopic = "esp32-node/stat/" + iot.hostname + "/status"; |
||||
|
batteryTopic = "esp32-node/stat/" + iot.hostname + "/battery"; |
||||
|
batteryValueTopic = "esp32-node/stat/" + iot.hostname + "/batteryvalue"; |
||||
|
|
||||
|
//Set up the Callbacks for the MQTT instance. Refer to the Async MQTT Client documentation
|
||||
|
// TODO: We should do this actually _before_ connecting the mqtt client...
|
||||
|
iot.mqtt.onConnect(onMqttConnect); |
||||
|
iot.mqtt.onPublish(suspendESP); |
||||
|
iot.mqtt.onMessage(onMqttMessage); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
//This function is called when the MQTT-Server is connected
|
||||
|
void onMqttConnect(bool sessionPresent) { |
||||
|
DEBUG_PRINTLN(__func__); |
||||
|
|
||||
|
//Subscribe to the delay topic
|
||||
|
iot.mqtt.subscribe(delaySleepTopic.c_str(), 0); |
||||
|
//Trigger the transmission of the current state.
|
||||
|
transmitStatus(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
//This function transfers the state of the sensor. That includes the door status, battery status and level
|
||||
|
void transmitStatus() { |
||||
|
DEBUG_PRINTLN(__func__); |
||||
|
|
||||
|
if (sensorValue == 0) { |
||||
|
DEBUG_PRINTLN("Door open"); |
||||
|
//Transfer the current state of the sensor to the MQTT broker
|
||||
|
statusPacketIdSub = iot.mqtt.publish(statusTopic.c_str(), 1, true, "open" ); |
||||
|
//Configure the wakeup pin to wake if the door is closed
|
||||
|
esp_sleep_enable_ext0_wakeup((gpio_num_t)SensorPin, 1); |
||||
|
} else { |
||||
|
DEBUG_PRINTLN("Door closed"); |
||||
|
//Transfer the current state of the sensor to the MQTT broker
|
||||
|
statusPacketIdSub = iot.mqtt.publish(statusTopic.c_str(), 1, true, "closed" ); |
||||
|
//Configure the wakeup pin to wake if the door is closed
|
||||
|
esp_sleep_enable_ext0_wakeup((gpio_num_t)SensorPin, 0); |
||||
|
} |
||||
|
|
||||
|
//Read the current analog battery value
|
||||
|
sensorValue = analogRead(BatteryPin); |
||||
|
//sensorC stores the battery value as a char
|
||||
|
char sensorC[6]; |
||||
|
//convert the sensor value to a string
|
||||
|
sprintf(sensorC, "%04i", sensorValue); |
||||
|
//Send the sensor value to the MQTT broker
|
||||
|
iot.mqtt.publish(batteryValueTopic.c_str(), 1, true, sensorC); |
||||
|
//Check the battery level and publish the state
|
||||
|
if (sensorValue < batteryLimit) { |
||||
|
DEBUG_PRINTLN("Battery empty"); |
||||
|
iot.mqtt.publish(batteryTopic.c_str(), 1, true, "empty" ); |
||||
|
} else { |
||||
|
DEBUG_PRINTLN("Battery full"); |
||||
|
iot.mqtt.publish(batteryTopic.c_str(), 1, true, "full" ); |
||||
|
} |
||||
|
DEBUG_PRINTLN("Data published"); |
||||
|
} |
||||
|
|
||||
|
//This topic is called if an MQTT message is received
|
||||
|
void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total) { |
||||
|
DEBUG_PRINTLN(__func__); |
||||
|
|
||||
// wait for a second
|
//Check if the payload eqals "true" and set delaySleep correspondigly
|
||||
delay(1000); |
//Since we only subscribed to one topic, we only have to compare the payload
|
||||
|
if (strcmp(payload, "true") == 0) { |
||||
|
delaySleep = true; |
||||
|
} else { |
||||
|
delaySleep = false; |
||||
|
} |
||||
|
} |
||||
|
|
||||
// turn the LED off by making the voltage LOW
|
void suspendESP(uint16_t packetId) { |
||||
digitalWrite(LED_BUILTIN, LOW); |
DEBUG_PRINTLN(__func__); |
||||
|
|
||||
// wait for a second
|
//Check if the published package is the one of the door sensor
|
||||
delay(1000); |
if (packetId == statusPacketIdSub) { |
||||
|
|
||||
|
if (delaySleep == true) { |
||||
|
DEBUG_PRINTLN("Delaying Sleep"); |
||||
|
return; |
||||
|
} |
||||
|
DEBUG_PRINTLN("Entering deep sleep"); |
||||
|
//properly disconnect from the MQTT broker
|
||||
|
iot.mqtt.disconnect(); |
||||
|
//send the ESP into deep sleep
|
||||
|
esp_deep_sleep_start(); |
||||
|
} |
||||
} |
} |
||||
|
|
||||
|
void loop() |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
@ -0,0 +1,7 @@ |
|||||
|
void resetToFactoryDefaults(); |
||||
|
void setup(); |
||||
|
void onMqttConnect(bool sessionPresent); |
||||
|
void transmitStatus(); |
||||
|
void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total); |
||||
|
void suspendESP(uint16_t packetId); |
||||
|
void loop(); |
Loading…
Reference in new issue