diff --git a/src/atomizer.h b/src/atomizer.h new file mode 100644 index 0000000..3404755 --- /dev/null +++ b/src/atomizer.h @@ -0,0 +1,39 @@ +#include + +/** + * Simple controller library for an ultrasonic atomizer + * used in atomizers, scent dispensers, etc. + * + * studio derfunke (c) 2022 + */ +class Atomizer { + int pinSwitch; + int pinSensor; + u_int lastToggle; // since last toggle action + + public: + Atomizer(int pin) : pinSwitch(pin) { + } + + bool debug() { + int ldr = analogRead(pinSensor); + Serial.print(ldr); + } + + bool is_on() { + int ldr = analogRead(pinSensor); + return ldr > 300; + } + + u_int elapsed() { + return millis() - lastToggle; + } + + void toggle() { + digitalWrite(pinSwitch, HIGH); + delay(300); + digitalWrite(pinSwitch, LOW); + lastToggle = millis(); + } + +}; // class \ No newline at end of file diff --git a/src/config.h b/src/config.h index 5cad6d6..97627ff 100644 --- a/src/config.h +++ b/src/config.h @@ -1,8 +1,11 @@ // pin configuration -#define PIN_DHT 2 +#define PIN_DHT 16 #define PIN_ATOMIZER 4 -#define MQTT_BROKER "YOUR_MQTT_BROKER_IP_ADDRESS" +// mqtt://interact:c9FjEDUnRgDTalBR@interact.cloud.shiftr.io +#define MQTT_BROKER "interact.cloud.shiftr.io" +#define MQTT_TOKEN "interact" +#define MQTT_PASSWD "c9FjEDUnRgDTalBR" diff --git a/src/main.cpp b/src/main.cpp index c31daef..8865993 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,27 +4,30 @@ #include #include #include -#include // mqtt stuff -#include #include #include #include "credentials.h" #include "config.h" +#include "atomizer.h" +#include "mqtt.h" -DHT dht(2, DHT11); -float h, t, f; -float hif, hic; +DHT dht(PIN_DHT, DHT11); +Atomizer fog(PIN_ATOMIZER); +typedef struct dhtReading { + float humidity, // in % + temperature; // in C +} tDHTReading; + +tDHTReading reading; USquare duty; // function generator for duty cycle Trigger fogOff( &duty, 1.0, ON_ASCENT ); Trigger fogOn( &duty, 0.0, ON_DESCENT ); -WiFiClient espClient; -PubSubClient client(espClient); - +// /////////////////////////////////////////////////////////////// void setup() { Serial.begin(115200); LOG_INIT(); @@ -48,133 +51,70 @@ void setup() { Serial.println("Brace! Brace! trying to continue without wifi..."); } - Serial.println("Initializing mqtt data stream..."); - client.setServer(MQTT_BROKER, 1883); - client.setCallback(callback); + mqtt_init(); Serial.println("Initializing DHT sensor..."); dht.begin(); } -void dht_report_reading() { +void dht_report_reading(tDHTReading &r) { Serial.print(F("Humidity: ")); - Serial.print(h); + Serial.print(r.humidity); Serial.print(F("% Temperature: ")); - Serial.print(t); + Serial.print(r.temperature); Serial.print(F("°C ")); - Serial.print(f); - Serial.print(F("°F Heat index: ")); - Serial.print(hic); - Serial.print(F("°C ")); - Serial.print(hif); - Serial.println(F("°F")); -} - -void callback(char* topic, byte* message, unsigned int length) { - Serial.print("Message arrived on topic: "); - Serial.print(topic); - Serial.print(". Message: "); - String messageTemp; - - for (int i = 0; i < length; i++) { - Serial.print((char)message[i]); - messageTemp += (char)message[i]; - } Serial.println(); - - // // Feel free to add more if statements to control more GPIOs with MQTT - - // // If a message is received on the topic esp32/output, you check if the message is either "on" or "off". - // // Changes the output state according to the message - // if (String(topic) == "esp32/output") { - // Serial.print("Changing output to "); - // if(messageTemp == "on"){ - // Serial.println("on"); - // digitalWrite(ledPin, HIGH); - // } - // else if(messageTemp == "off"){ - // Serial.println("off"); - // digitalWrite(ledPin, LOW); - // } - // } } -void reconnect() { - // Loop until we're reconnected - while (!client.connected()) { - Serial.print("Attempting MQTT connection..."); - // Attempt to connect - if (client.connect("kodama")) { - Serial.println("connected"); - // Subscribe - client.subscribe("esp32/output"); - } else { - Serial.print("failed, rc="); - Serial.print(client.state()); - Serial.println(" try again in 5 seconds"); - // Wait 5 seconds before retrying - delay(5000); - } - } +void mqtt_dispatch_dht_reading(tDHTReading &r) { + broker.publish("kodama/air/temperature", String(r.temperature).c_str() ); + broker.publish("kodama/air/humidity", String(r.humidity).c_str() ); } -// bool dht_read() { //(float &_h, float &_t) { -// bool retval = true; +bool dht_is_valid_reading(tDHTReading &r) { + bool retval = true; -// // Reading temperature or humidity takes about 250 milliseconds! -// // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor) -// h = dht.readHumidity(); -// // Read temperature as Celsius (the default) -// t = dht.readTemperature(); - -// // Check if any reads failed and exit early (to try again). -// if (isnan(h) || isnan(t) ) { -// retval = false; -// } + // Check if any reads failed and exit early (to try again). + if (isnan(r.humidity) || isnan(r.temperature) ) { + retval = false; + } + return retval; +} -// return retval; -// } +bool dht_read(tDHTReading &r) { //(float &_h, float &_t) { + // Reading temperature or humidity takes about 250 milliseconds! + // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor) + r.humidity = dht.readHumidity(); + // Read temperature as Celsius (the default) + r.temperature = dht.readTemperature(); -void atomizer_switch() { - digitalWrite(PIN_ATOMIZER, HIGH); - delay(300); - digitalWrite(PIN_ATOMIZER, LOW); + return dht_is_valid_reading( r ); } void loop() { + mqtt_pump(); - // float t = millis() * 0.001; + float t = millis() * 0.001; // float v = duty.square(t); // Serial.print(t); Serial.print("@ "); Serial.println(v); - // if ( !dht_read() ) { //(h, t) ) { - // LOG("Failed to read from DHT sensor!"); - // LOG_NEW_LINE - // } + if ( !dht_read( reading ) ) { //(h, t) ) { + LOG("Failed to read from DHT sensor!"); + LOG_NEW_LINE + } else { + dht_report_reading( reading ); + mqtt_dispatch_dht_reading( reading ); + } if( fogOff.bang() ) { Serial.print(t); Serial.println(" >>>>>>>>>> FOG OFF!"); - atomizer_switch(); + fog.toggle(); } if( fogOn.bang() ) { Serial.print(t); Serial.println(" <<<<<<<<<< FOG ON!"); - atomizer_switch(); + fog.toggle(); } - // if(v >= 1) { - // // Reading temperature or humidity takes about 250 milliseconds! - // // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor) - // h = dht.readHumidity(); - // // Read temperature as Celsius (the default) - // t = dht.readTemperature(); - - // // Compute heat index in Celsius (isFahreheit = false) - // hic = dht.computeHeatIndex(t, h, false); - // dht_report_reading(); - - // Serial.print(">> "); Serial.print(v); Serial.println(); - // } - - delay(50); + delay(2000); } diff --git a/src/mqtt.cpp b/src/mqtt.cpp new file mode 100644 index 0000000..adca7ff --- /dev/null +++ b/src/mqtt.cpp @@ -0,0 +1,80 @@ +#include "mqtt.h" +#include "config.h" + +WiFiClient espClient; +PubSubClient broker(espClient); + +String byte2str(byte* message, unsigned int length) { + String retval; + + for (int i = 0; i < length; i++) { + Serial.print((char)message[i]); + retval += (char)message[i]; + } + + return retval; +} + +void mqtt_callback(char* _topic, byte* _message, unsigned int _length) { + + String topic = String(_topic); + String payload = byte2str( _message, _length ); + + Serial.print("MQTT << "); + Serial.print(topic); + Serial.print(" ["); + Serial.print(payload); + Serial.print("]"); + Serial.println(); + + + // // Feel free to add more if statements to control more GPIOs with MQTT + + // // If a message is received on the topic esp32/output, you check if the message is either "on" or "off". + // // Changes the output state according to the message + // if (String(topic) == "esp32/output") { + // Serial.print("Changing output to "); + // if(messageTemp == "on"){ + // Serial.println("on"); + // digitalWrite(ledPin, HIGH); + // } + // else if(messageTemp == "off"){ + // Serial.println("off"); + // digitalWrite(ledPin, LOW); + // } + // } +} + +bool mqtt_init() { + Serial.println("Initializing mqtt data stream..."); + broker.setServer(MQTT_BROKER, 1883); + broker.setCallback(mqtt_callback); +} + +void mqtt_reconnect() { + // Loop until we're reconnected + while (!broker.connected()) { + Serial.print("Attempting MQTT connection..."); + // Attempt to connect + if (broker.connect("kodama-AC234", MQTT_TOKEN, MQTT_PASSWD)) { + Serial.println("connected"); + // Subscribe + broker.subscribe("kodama/incoming"); + } else { + Serial.print("failed, rc="); + Serial.print(broker.state()); + Serial.println(" try again in 5 seconds"); + // Wait 5 seconds before retrying + delay(5000); + } + } +} + + +void mqtt_pump() { + if (!broker.connected()) { + mqtt_reconnect(); + } + broker.loop(); +} + diff --git a/src/mqtt.h b/src/mqtt.h new file mode 100644 index 0000000..ca2aed0 --- /dev/null +++ b/src/mqtt.h @@ -0,0 +1,9 @@ +#include // mqtt stuff +#include + +extern PubSubClient broker; + +void mqtt_callback(char* topic, byte* message, unsigned int length); +bool mqtt_init(); +void mqtt_reconnect(); +void mqtt_pump();