From 3176a487980c639ddd16e7c5b2492f7c5d5a7422 Mon Sep 17 00:00:00 2001 From: Dag Olav Prestegarden Date: Sun, 30 Jun 2019 23:09:17 +0200 Subject: [PATCH] Initial --- .gitignore | 6 ++ .travis.yml | 67 +++++++++++++++++ .vscode/extensions.json | 7 ++ .vscode/settings.json | 6 ++ include/README | 39 ++++++++++ lib/README | 46 ++++++++++++ platformio.ini | 14 ++++ src/config.h | 28 +++++++ src/i2cscanner.cpp | 84 +++++++++++++++++++++ src/main.cpp | 161 ++++++++++++++++++++++++++++++++++++++++ test/README | 11 +++ 11 files changed, 469 insertions(+) create mode 100644 .gitignore create mode 100644 .travis.yml create mode 100644 .vscode/extensions.json create mode 100644 .vscode/settings.json create mode 100644 include/README create mode 100644 lib/README create mode 100644 platformio.ini create mode 100644 src/config.h create mode 100644 src/i2cscanner.cpp create mode 100644 src/main.cpp create mode 100644 test/README diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2de98ab --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +.pio +.pioenvs +.piolibdeps +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/launch.json diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..7c486f1 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,67 @@ +# Continuous Integration (CI) is the practice, in software +# engineering, of merging all developer working copies with a shared mainline +# several times a day < https://docs.platformio.org/page/ci/index.html > +# +# Documentation: +# +# * Travis CI Embedded Builds with PlatformIO +# < https://docs.travis-ci.com/user/integration/platformio/ > +# +# * PlatformIO integration with Travis CI +# < https://docs.platformio.org/page/ci/travis.html > +# +# * User Guide for `platformio ci` command +# < https://docs.platformio.org/page/userguide/cmd_ci.html > +# +# +# Please choose one of the following templates (proposed below) and uncomment +# it (remove "# " before each line) or use own configuration according to the +# Travis CI documentation (see above). +# + + +# +# Template #1: General project. Test it using existing `platformio.ini`. +# + +# language: python +# python: +# - "2.7" +# +# sudo: false +# cache: +# directories: +# - "~/.platformio" +# +# install: +# - pip install -U platformio +# - platformio update +# +# script: +# - platformio run + + +# +# Template #2: The project is intended to be used as a library with examples. +# + +# language: python +# python: +# - "2.7" +# +# sudo: false +# cache: +# directories: +# - "~/.platformio" +# +# env: +# - PLATFORMIO_CI_SRC=path/to/test/file.c +# - PLATFORMIO_CI_SRC=examples/file.ino +# - PLATFORMIO_CI_SRC=path/to/test/directory +# +# install: +# - pip install -U platformio +# - platformio update +# +# script: +# - platformio ci --lib="." --board=ID_1 --board=ID_2 --board=ID_N diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..272828b --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,7 @@ +{ + // See http://go.microsoft.com/fwlink/?LinkId=827846 + // for the documentation about the extensions.json format + "recommendations": [ + "platformio.platformio-ide" + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..f74e87d --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "terminal.integrated.env.windows": { + "PATH": "C:\\Users\\dagolap\\.platformio\\penv\\Scripts;C:\\Users\\dagolap\\.platformio\\penv;C:\\ProgramData\\Oracle\\Java\\javapath;C:\\Windows\\system32;C:\\Windows;C:\\Windows\\System32\\Wbem;C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\;C:\\Program Files (x86)\\NVIDIA Corporation\\PhysX\\Common;C:\\Program Files\\Git\\cmd;C:\\Program Files (x86)\\PuTTY\\;C:\\WINDOWS\\system32;C:\\WINDOWS;C:\\WINDOWS\\System32\\Wbem;C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\;C:\\WINDOWS\\System32\\OpenSSH\\;C:\\ProgramData\\chocolatey\\bin;C:\\Users\\dagolap\\AppData\\Local\\Microsoft\\WindowsApps;C:\\Program Files (x86)\\Atmel\\Flip 3.4.7\\bin;C:\\adb;C:\\Program Files\\NVIDIA Corporation\\NVIDIA NvDLISR;C:\\ProgramData\\chocolatey\\bin;;C:\\Users\\dagolap\\AppData\\Local\\Microsoft\\WindowsApps;C:\\Program Files (x86)\\Atmel\\Flip 3.4.7\\bin;C:\\Program Files (x86)\\Nmap;C:\\Users\\dagolap\\AppData\\Local\\Programs\\Microsoft VS Code\\bin;C:\\ProgramData\\Oracle\\Java\\javapath;C:\\Windows\\system32;C:\\Windows;C:\\Windows\\System32\\Wbem;C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\;C:\\Program Files (x86)\\NVIDIA Corporation\\PhysX\\Common;C:\\Program Files\\Git\\cmd;C:\\Program Files (x86)\\PuTTY\\;C:\\WINDOWS\\system32;C:\\WINDOWS;C:\\WINDOWS\\System32\\Wbem;C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\;C:\\WINDOWS\\System32\\OpenSSH\\;C:\\ProgramData\\chocolatey\\bin;C:\\Users\\dagolap\\AppData\\Local\\Microsoft\\WindowsApps;C:\\Program Files (x86)\\Atmel\\Flip 3.4.7\\bin;C:\\adb;C:\\Program Files\\NVIDIA Corporation\\NVIDIA NvDLISR;C:\\ProgramData\\chocolatey\\bin;;C:\\Users\\dagolap\\AppData\\Local\\Microsoft\\WindowsApps;C:\\Program Files (x86)\\Atmel\\Flip 3.4.7\\bin;C:\\Program Files (x86)\\Nmap;C:\\Users\\dagolap\\AppData\\Local\\Programs\\Microsoft VS Code\\bin", + "PLATFORMIO_CALLER": "vscode" + } +} \ No newline at end of file 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/platformio.ini b/platformio.ini new file mode 100644 index 0000000..4fa4a6d --- /dev/null +++ b/platformio.ini @@ -0,0 +1,14 @@ +; 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 + +[env:d1_mini] +platform = espressif8266 +board = d1_mini +framework = arduino diff --git a/src/config.h b/src/config.h new file mode 100644 index 0000000..af884ba --- /dev/null +++ b/src/config.h @@ -0,0 +1,28 @@ +// +// Config +// +// Device unique stuff +#define NODE_NAME "test" +#define NODE_SLEEP_SECONDS 5 * 60 + +// Features +// #define HAS_SHT30 // Temperatur & Humidity +// #define HAS_BMP180 // Barometer +#define HAS_811 // CO2 + +// Wifi +#define WIFI_SSID "" +#define WIFI_PASS "" +#define WIFI_HOST "lolin-env-sensor-" NODE_NAME + +// MQTT +#define MQTT_SERVER "192.168.1.210" +#define MQTT_USER "" +#define MQTT_PASS "" +#define MQTT_PORT 1883 +#define TOPIC_TEMPERATURE "home/" NODE_NAME "/temperature" +#define TOPIC_HUMIDITY "home/" NODE_NAME "/humidity" + +// Module setup +#define SLEEP_SECONDS NODE_SLEEP_SECONDS +#define SENSOR_DHT_ADDRESS 0x45 diff --git a/src/i2cscanner.cpp b/src/i2cscanner.cpp new file mode 100644 index 0000000..29f5ea2 --- /dev/null +++ b/src/i2cscanner.cpp @@ -0,0 +1,84 @@ + // // -------------------------------------- + // // i2c_scanner + // // + // // Version 1 + // // This program (or code that looks like it) + // // can be found in many places. + // // For example on the Arduino.cc forum. + // // The original author is not know. + // // Version 2, Juni 2012, Using Arduino 1.0.1 + // // Adapted to be as simple as possible by Arduino.cc user Krodal + // // Version 3, Feb 26 2013 + // // V3 by louarnold + // // Version 4, March 3, 2013, Using Arduino 1.0.3 + // // by Arduino.cc user Krodal. + // // Changes by louarnold removed. + // // Scanning addresses changed from 0...127 to 1...119, + // // according to the i2c scanner by Nick Gammon + // // http://www.gammon.com.au/forum/?id=10896 + // // Version 5, March 28, 2013 + // // As version 4, but address scans now to 127. + // // A sensor seems to use address 120. + // // Version 6, November 27, 2015. + // // Added waiting for the Leonardo serial communication. + // // + // // + // // This sketch tests the standard 7-bit addresses + // // Devices with higher bit address might not be seen properly. + // // + + // #include + // #include + + + // void setup() + // { + // Wire.begin(); + + // Serial.begin(9600); + // while (!Serial); // Leonardo: wait for serial monitor + // Serial.println("\nI2C Scanner"); + // } + + + // void loop() + // { + // byte error, address; + // int nDevices; + + // Serial.println("Scanning..."); + + // nDevices = 0; + // for(address = 1; address < 127; address++ ) + // { + // // The i2c_scanner uses the return value of + // // the Write.endTransmisstion to see if + // // a device did acknowledge to the address. + // Wire.beginTransmission(address); + // error = Wire.endTransmission(); + + // if (error == 0) + // { + // Serial.print("I2C device found at address 0x"); + // if (address<16) + // Serial.print("0"); + // Serial.print(address,HEX); + // Serial.println(" !"); + + // nDevices++; + // } + // else if (error==4) + // { + // Serial.print("Unknown error at address 0x"); + // if (address<16) + // Serial.print("0"); + // Serial.println(address,HEX); + // } + // } + // if (nDevices == 0) + // Serial.println("No I2C devices found\n"); + // else + // Serial.println("done\n"); + + // delay(5000); // wait 5 seconds for next scan + // } diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..ae53c14 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,161 @@ +#include "config.h" +#include +#include + +#ifdef HAS_BMP180 +#endif + +#ifdef HAS_811 +#include +#endif + +#ifdef HAS_SHT30 +#include +#endif + +// MQTT-client for HomeAssistant integration +void mqtt_handler(char *topic, uint8_t *payload, unsigned int length) +{ + Serial.printf("%b", payload); +} +WiFiClient wifiClient; +PubSubClient mqttClient(MQTT_SERVER, MQTT_PORT, mqtt_handler, wifiClient); + +#ifdef HAS_SHT30 +void reportSht30Data() +{ + SHT3X sht30(SENSOR_DHT_ADDRESS); + + byte couldRead = sht30.get(); + if (couldRead == 0) + { + float temp = sht30.cTemp; + float hum = sht30.humidity; + char cTemp[3]; + char cHum[3]; + sprintf(cTemp, "%.0f", temp); + sprintf(cHum, "%.0f", hum); + + Serial.printf("Temp: %.2f\n", temp); + Serial.printf("Humidity: %.2f\n", hum); + + mqttClient.publish(TOPIC_TEMPERATURE, cTemp, true); + mqttClient.publish(TOPIC_HUMIDITY, cHum, true); + } + else + { + Serial.printf("Ingen måling... returkode: %d\n", couldRead); + mqttClient.publish(TOPIC_TEMPERATURE, "0", true); + mqttClient.publish(TOPIC_HUMIDITY, "0", true); + } +} +#endif + +#ifdef HAS_811 +Adafruit_CCS811 ccs; + +void setup811() +{ + if (!ccs.begin()) + { + Serial.println("Failed to start sensor! Please check your wiring."); + while (1) + ; + } + + Serial.println("Connecting to 811-sensor"); + while (!ccs.available()) + { + delay(1000); + Serial.print("."); + } + + float temp = ccs.calculateTemperature(); + ccs.setTempOffset(temp - 25.0); +} + +void report811Data() +{ + if (ccs.available()) + { + + float temp = ccs.calculateTemperature(); + if (!ccs.readData()) + { + Serial.print("CO2: "); + Serial.print(ccs.geteCO2()); + Serial.print("ppm, TVOC: "); + Serial.print(ccs.getTVOC()); + Serial.print("ppb Temp:"); + Serial.println(temp); + } + } +} +#endif + +void setup() +{ + // + // Setup + // + Serial.begin(9600); + + Serial.println(""); + Serial.printf("Woke up. I am %s - Hello World!\n", WIFI_HOST); + + // Connect D0 to RST to wake up + pinMode(D0, WAKEUP_PULLUP); + + // Connect to Wifi + Serial.printf("Connecting to %s\n", WIFI_SSID); + WiFi.hostname(WIFI_HOST); + WiFi.begin(WIFI_SSID, WIFI_PASS); + + while (WiFi.status() != WL_CONNECTED) + { + delay(1000); + Serial.print("."); + } + Serial.println(""); + Serial.println("WiFi connected"); + Serial.print("IP address: "); + Serial.println(WiFi.localIP()); + + Serial.printf("Connecting to MQTT %s\n", MQTT_SERVER); + mqttClient.connect(MQTT_SERVER, MQTT_USER, MQTT_PASS); + while (!mqttClient.connected()) + { + delay(1000); + Serial.print("."); + } + Serial.println(""); + +// +// Read data from sensor and send to MQTT (was basically loop()) +// +#ifdef HAS_SHT30 + reportSht30Data(); +#endif + +#ifdef HAS_811 + // report811Data(); + setup811(); +#endif + + mqttClient.disconnect(); + wifiClient.stop(); + + Serial.println("Waiting 10 seconds to allow a flash :)"); + delay(2000); + + Serial.printf("Going to sleep for %d seconds now... Bye bye!\n", SLEEP_SECONDS); + // ESP.deepSleep(SLEEP_SECONDS * 1000000); +} + +void loop() +{ + +#ifdef HAS_811 + report811Data(); +#endif +} \ No newline at end of file diff --git a/test/README b/test/README new file mode 100644 index 0000000..df5066e --- /dev/null +++ b/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PIO 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 PIO Unit Testing: +- https://docs.platformio.org/page/plus/unit-testing.html