commit 78920d7f3aa6f8dafa63d84fb3e5e278d60e3ac5 Author: Laura Hausmann Date: Fri Apr 29 00:10:00 2022 +0200 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8126b3a --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +.pio +.idea +.vscode +CMakeLists.txt +CMakeListsPrivate.txt +cmake-build-az-delivery-devkit-v4 +cmake-build-debug + diff --git a/README.md b/README.md new file mode 100644 index 0000000..7fce251 --- /dev/null +++ b/README.md @@ -0,0 +1,12 @@ +# esp32-co2-mhz19b +This project displays the current co2 levels, along with temperature and humidity information, on a HD44780 16x2 display. All of this is powered by an ESP32 devkit, a AHT10 temperature and humidity sensor, and a MH-Z19B NDIR CO2 sensor. + +## Wiring +![Wiring diagram](img/wiring.jpeg) + +The main components here are wired up like this: +- The green, yellow and red LEDs are connected to ground and pins 25, 33 and 32 respectively +- The HD44780 16x2 display is connected to an I2C daughterboard, which itself is connected to +5V, ground, as well as the I2C bus pins of the ESP32, 22 for clock and 21 for data +- The AHT10 temperature and humidity sensor is connected to +3.3V, ground, and the I2C bus (see above) +- The MH-Z19B NDIR CO2 sensor is connected to +5V and ground for the 4 pin cluster, and to pins 16 and 17 (ESP32 HardwareSerial2; MH-Z19B side pins Tx and Rx respectively) +- A button to toggle the backlight is connected between pin 23 and ground diff --git a/img/wiring.jpeg b/img/wiring.jpeg new file mode 100644 index 0000000..7617a35 Binary files /dev/null and b/img/wiring.jpeg differ 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..df78f7c --- /dev/null +++ b/platformio.ini @@ -0,0 +1,19 @@ +; 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:az-delivery-devkit-v4] +platform = espressif32 +board = az-delivery-devkit-v4 +framework = arduino +upload_protocol = esptool +lib_deps = + wifwaf/MH-Z19@^1.5.3 + adafruit/Adafruit AHTX0@^2.0.1 + fmalpartida/LiquidCrystal@^1.5.0 \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..9dcc8b6 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,132 @@ +#include +#include "MHZ19.h" +#include "Adafruit_AHTX0.h" +#include "LiquidCrystal_I2C.h" + +#define RX_PIN 16 // Rx pin which the MHZ19 Tx pin is attached to +#define TX_PIN 17 // Tx pin which the MHZ19 Rx pin is attached to +#define BAUDRATE 9600 // Device to MH-Z19 Serial baudrate (should not be changed) + +MHZ19 myMHZ19; // Constructor for library +Adafruit_AHTX0 aht; +LiquidCrystal_I2C LCD(0x27,2,1,0,4,5,6,7,3,POSITIVE); + +int greenpin = 25; +int yellownpin = 33; +int redpin = 32; + +int backlightState = HIGH; +int backlightUpdate = 0; + +int update_ival = 0; +int override = 0; + +int cal_time = 5; //minutes + +void led(int red, int green, int yellow) +{ + analogWrite(redpin, red); + analogWrite(greenpin, green); + analogWrite(yellownpin, yellow); +} + +void IRAM_ATTR BacklightToggle() { + backlightUpdate = true; +} + +void setup() +{ + Serial.begin(9600); // Device to serial monitor feedback + + Serial2.begin(BAUDRATE, SERIAL_8N1, RX_PIN, TX_PIN); // (Uno example) device to MH-Z19 serial start + myMHZ19.begin(Serial2); // *Serial(Stream) refence must be passed to library begin(). + + myMHZ19.autoCalibration(); // Turn auto calibration ON (OFF autoCalibration(false)) + myMHZ19.setRange(2000); + + Serial.println("MHZ19 init:"); + char myVersion[4]; + myMHZ19.getVersion(myVersion); + Serial.print("\nFirmware Version: "); + for(byte i = 0; i < 4; i++) + { + Serial.print(myVersion[i]); + if(i == 1) + Serial.print("."); + } + Serial.println(""); + + Serial.print("Range: "); + Serial.println(myMHZ19.getRange()); + Serial.print("Background CO2: "); + Serial.println(myMHZ19.getBackgroundCO2()); + Serial.print("Temperature Cal: "); + Serial.println(myMHZ19.getTempAdjustment()); + Serial.print("ABC Status: "); myMHZ19.getABC() ? Serial.println("ON") : Serial.println("OFF"); + + if (!aht.begin()) { + Serial.println("Could not find AHT? Check wiring"); + while (true); + } + + LCD.begin(16, 2); + LCD.clear(); + LCD.setBacklight(backlightState); + pinMode(23, INPUT_PULLUP); + attachInterrupt(23, BacklightToggle, FALLING); +} + +void loop() { + if (backlightUpdate) { + backlightState = !backlightState; + backlightUpdate = false; + Serial.printf("Setting backlight to %i \n", backlightState); + LCD.setBacklight(backlightState); + } + + if (update_ival-- > 0) { + delay(1000); + return; + } + + update_ival = 5; //5sec + + sensors_event_t humidity, temp; + aht.getEvent(&humidity, &temp); + LCD.setCursor(0, 0); + LCD.print(temp.temperature, 1); + LCD.print(" C "); + LCD.setCursor(9, 0); + LCD.print(humidity.relative_humidity, 1); + LCD.print("%rH"); + + if (millis() >= (cal_time * 60000) && !override) { + LCD.setCursor(0, 1); + LCD.print(" Ready."); + override = true; + } + + int co2 = myMHZ19.getCO2(false); + if (myMHZ19.errorCode != RESULT_OK) { + Serial.print("Error. Response Code: "); + Serial.println(myMHZ19.errorCode); // Get the Error Code value + return; + } + LCD.setCursor(0, 1); + LCD.print(co2); + LCD.print("ppm "); + + if (co2 < 1000) + led(0, 1, 0); + else if (co2 < 1500) + led(0, 0, 5); + else + led(5, 0, 0); + + if (millis() < (cal_time * 60000)) { + { + LCD.setCursor(8, 1); + LCD.printf("Cal..%2lum", ((cal_time * 60000) - millis()) / 60000); + } + } +} \ No newline at end of file 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