From 60b5c945b538abe5e9e3707f52de5828861ef347 Mon Sep 17 00:00:00 2001 From: Luis Rodil-Fernandez Date: Sat, 12 Feb 2022 04:44:08 +0100 Subject: [PATCH] needed before anything happens --- .gitignore | 8 + ...s a button digitally with a transistor.png | Bin 0 -> 46858 bytes include/README | 39 ++++ lib/README | 46 +++++ mcukit | 1 + platformio.ini | 28 +++ src/config.h | 8 + src/main.cpp | 180 ++++++++++++++++++ test/README | 11 ++ 9 files changed, 321 insertions(+) create mode 100644 .gitignore create mode 100644 How to press a button digitally with a transistor.png create mode 100644 include/README create mode 100644 lib/README create mode 160000 mcukit create mode 100644 platformio.ini create mode 100644 src/config.h create mode 100644 src/main.cpp create mode 100644 test/README diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b9c2d11 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +.pio +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/launch.json +.vscode/ipch + +src/credentials* +mcukit/* diff --git a/How to press a button digitally with a transistor.png b/How to press a button digitally with a transistor.png new file mode 100644 index 0000000000000000000000000000000000000000..d1174cbd8416ee80ce2eb18dfaf80472dff855d3 GIT binary patch literal 46858 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 literal 0 HcmV?d00001 diff --git a/include/README b/include/README new file mode 100644 index 0000000..194dcd4 --- /dev/null +++ b/include/README @@ -0,0 +1,39 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the usual convention is to give header files names that end with `.h'. +It is most portable to use only letters, digits, dashes, and underscores in +header file names, and at most one dot. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/lib/README b/lib/README new file mode 100644 index 0000000..6debab1 --- /dev/null +++ b/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into executable file. + +The source code of each library should be placed in a an own separate directory +("lib/your_library_name/[here are source files]"). + +For example, see a structure of the following two libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +and a contents of `src/main.c`: +``` +#include +#include + +int main (void) +{ + ... +} + +``` + +PlatformIO Library Dependency Finder will find automatically dependent +libraries scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/mcukit b/mcukit new file mode 160000 index 0000000..e06e54c --- /dev/null +++ b/mcukit @@ -0,0 +1 @@ +Subproject commit e06e54c09a925a7a0285504f98919ea78ce149f6 diff --git a/platformio.ini b/platformio.ini new file mode 100644 index 0000000..588b7cb --- /dev/null +++ b/platformio.ini @@ -0,0 +1,28 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[common] +lib_deps_external = + https://github.com/adafruit/DHT-sensor-library/archive/refs/tags/1.4.3.zip + https://github.com/knolleary/pubsubclient/archive/refs/tags/v2.8.zip + + +[env:lolin32] +platform = espressif32 +board = lolin32 +framework = arduino + +upload_speed = 115200 +monitor_speed = 115200 + +lib_extra_dirs = ./mcukit +lib_deps = ${common.lib_deps_external} + +upload_port = /dev/cu.SLAB_USBtoUART diff --git a/src/config.h b/src/config.h new file mode 100644 index 0000000..5cad6d6 --- /dev/null +++ b/src/config.h @@ -0,0 +1,8 @@ + +// pin configuration + +#define PIN_DHT 2 +#define PIN_ATOMIZER 4 + +#define MQTT_BROKER "YOUR_MQTT_BROKER_IP_ADDRESS" + diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..c31daef --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,180 @@ +#include +#include +#include +#include +#include +#include +#include // mqtt stuff +#include + +#include +#include + +#include "credentials.h" +#include "config.h" + +DHT dht(2, DHT11); +float h, t, f; +float hif, hic; + + +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(); + + pinMode(PIN_ATOMIZER, OUTPUT); + + duty.setFrequency(0.05); + duty.setAmplitude(0.5); + duty.setPhase(0); + duty.setYShift(0.5); + + df_header_print(); + + if( wifi_connect_as_client(WIFI_SSID, WIFI_PASSWORD) ) { + wifi_print_mode(); + wifi_print_ip(); + } else { + Serial.print("Failed to connect to wifi "); + Serial.print( WIFI_SSID ); + Serial.println(); + Serial.println("Brace! Brace! trying to continue without wifi..."); + } + + Serial.println("Initializing mqtt data stream..."); + client.setServer(MQTT_BROKER, 1883); + client.setCallback(callback); + + Serial.println("Initializing DHT sensor..."); + dht.begin(); +} + +void dht_report_reading() { + Serial.print(F("Humidity: ")); + Serial.print(h); + Serial.print(F("% Temperature: ")); + Serial.print(t); + 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); + } + } +} + +// bool dht_read() { //(float &_h, float &_t) { +// 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; +// } + +// return retval; +// } + +void atomizer_switch() { + digitalWrite(PIN_ATOMIZER, HIGH); + delay(300); + digitalWrite(PIN_ATOMIZER, LOW); +} + +void loop() { + + // 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( fogOff.bang() ) { + Serial.print(t); Serial.println(" >>>>>>>>>> FOG OFF!"); + atomizer_switch(); + } + + if( fogOn.bang() ) { + Serial.print(t); Serial.println(" <<<<<<<<<< FOG ON!"); + atomizer_switch(); + } + + // 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); +} diff --git a/test/README b/test/README new file mode 100644 index 0000000..b94d089 --- /dev/null +++ b/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PlatformIO Unit Testing and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PlatformIO Unit Testing: +- https://docs.platformio.org/page/plus/unit-testing.html