From 6cdbb8a0a31750f339d093b27cd213909ce5a8e5 Mon Sep 17 00:00:00 2001 From: Phat Nguyen Date: Sat, 17 Feb 2024 17:28:51 +0700 Subject: [PATCH] Fix capitalize folder and file name ignored --- src/Main/BoardDef.cpp | 501 +++++++++++++++++++++ src/Main/BoardDef.h | 88 ++++ src/Main/HardwareWatchdog.cpp | 74 +++ src/Main/HardwareWatchdog.h | 37 ++ src/Main/LedBar.cpp | 126 ++++++ src/Main/LedBar.h | 42 ++ src/Main/PushButton.cpp | 74 +++ src/Main/PushButton.h | 47 ++ src/Main/StatusLed.cpp | 115 +++++ src/Main/StatusLed.h | 45 ++ src/PMS/PMS.cpp | 164 +++++++ src/PMS/PMS.h | 75 +++ src/{pms/pms5003.cpp => PMS/PMS5003.cpp} | 0 src/{pms/pms5003.h => PMS/PMS5003.h} | 0 src/{pms/pms5003t.cpp => PMS/PMS5003T.cpp} | 0 src/{pms/pms5003t.h => PMS/PMS5003T.h} | 0 src/{s8/s8.cpp => S8/S8.cpp} | 0 src/{s8/s8.h => S8/S8.h} | 0 src/S8/mb_crc.cpp | 73 +++ src/S8/mb_crc.h | 8 + src/{sgp41/sgp41.cpp => Sgp41/Sgp41.cpp} | 0 src/{sgp41/sgp41.h => Sgp41/Sgp41.h} | 0 src/{sht/sht.cpp => Sht/Sht.cpp} | 0 src/{sht/sht.h => Sht/Sht.h} | 0 24 files changed, 1469 insertions(+) create mode 100644 src/Main/BoardDef.cpp create mode 100644 src/Main/BoardDef.h create mode 100644 src/Main/HardwareWatchdog.cpp create mode 100644 src/Main/HardwareWatchdog.h create mode 100644 src/Main/LedBar.cpp create mode 100644 src/Main/LedBar.h create mode 100644 src/Main/PushButton.cpp create mode 100644 src/Main/PushButton.h create mode 100644 src/Main/StatusLed.cpp create mode 100644 src/Main/StatusLed.h create mode 100644 src/PMS/PMS.cpp create mode 100644 src/PMS/PMS.h rename src/{pms/pms5003.cpp => PMS/PMS5003.cpp} (100%) rename src/{pms/pms5003.h => PMS/PMS5003.h} (100%) rename src/{pms/pms5003t.cpp => PMS/PMS5003T.cpp} (100%) rename src/{pms/pms5003t.h => PMS/PMS5003T.h} (100%) rename src/{s8/s8.cpp => S8/S8.cpp} (100%) rename src/{s8/s8.h => S8/S8.h} (100%) create mode 100644 src/S8/mb_crc.cpp create mode 100644 src/S8/mb_crc.h rename src/{sgp41/sgp41.cpp => Sgp41/Sgp41.cpp} (100%) rename src/{sgp41/sgp41.h => Sgp41/Sgp41.h} (100%) rename src/{sht/sht.cpp => Sht/Sht.cpp} (100%) rename src/{sht/sht.h => Sht/Sht.h} (100%) diff --git a/src/Main/BoardDef.cpp b/src/Main/BoardDef.cpp new file mode 100644 index 0000000..23fe603 --- /dev/null +++ b/src/Main/BoardDef.cpp @@ -0,0 +1,501 @@ +#include "BoardDef.h" +#if defined(ESP32) +#include "esp32-hal-log.h" +#endif + +const BoardDef bsps[_BOARD_MAX] = { + /** DIY_BASIC */ + [DIY_BASIC] = + { + .SenseAirS8 = + { + .uart_tx_pin = 2, + .uart_rx_pin = 0, +#if defined(ESP8266) + .supported = true, +#else + .supported = false, +#endif + }, + .Pms5003 = + { + .uart_tx_pin = 14, + .uart_rx_pin = 12, +#if defined(ESP8266) + .supported = true, +#else + .supported = false, +#endif + }, + .I2C = + { + .sda_pin = 4, + .scl_pin = 5, +#if defined(ESP8266) + .supported = true, +#else + .supported = false, +#endif + }, + .SW = + { + .pin = -1, /** Not supported */ + .activeLevel = 0, /** Don't care */ + .supported = false, /** Not supported */ + }, + .LED = + { + .pin = -1, + .rgbNum = 0, + .onState = 0, + .supported = false, + .rgbSupported = false, + }, + .OLED = + { +#if defined(ESP8266) + .width = 64, + .height = 48, + .addr = 0x3C, + .supported = true, +#else + .width = 0, + .height = 0, + .addr = 0, + .supported = false, +#endif + }, + .WDG = + { + .resetPin = -1, + .supported = false, + }, + .name = "DIY_BASIC", + }, + /** DIY_PRO_INDOOR_V4_2 */ + [DIY_PRO_INDOOR_V4_2] = + { + .SenseAirS8 = + { + .uart_tx_pin = 2, + .uart_rx_pin = 0, +#if defined(ESP8266) + .supported = true, +#else + .supported = false, +#endif + }, + .Pms5003 = + { + .uart_tx_pin = 14, + .uart_rx_pin = 12, +#if defined(ESP8266) + .supported = true, +#else + .supported = false, +#endif + }, + .I2C = + { + .sda_pin = 4, + .scl_pin = 5, +#if defined(ESP8266) + .supported = true, +#else + .supported = false, +#endif + }, + .SW = + { +#if defined(ESP8266) + .pin = 13, /** D7 */ + .activeLevel = 0, + .supported = true, +#else + .pin = -1, + .activeLevel = 1, + .supported = false, +#endif + }, + .LED = + { + .pin = -1, + .rgbNum = 0, + .onState = 0, + .supported = false, + .rgbSupported = false, + }, + .OLED = + { +#if defined(ESP8266) + .width = 128, + .height = 64, + .addr = 0x3C, + .supported = true, +#else + .width = 0, + .height = 0, + .addr = 0, + .supported = false, +#endif + }, + .WDG = + { + .resetPin = -1, + .supported = false, + }, + .name = "DIY_PRO_INDOOR_V4_2", + }, + /** ONE_INDOOR */ + [ONE_INDOOR] = + { + .SenseAirS8 = + { + .uart_tx_pin = 1, + .uart_rx_pin = 0, +#if defined(ESP8266) + .supported = false, +#else + .supported = true, +#endif + }, + /** Use UART0 don't use define pin number */ + .Pms5003 = + { + .uart_tx_pin = -1, + .uart_rx_pin = -1, +#if defined(ESP8266) + .supported = false, +#else + .supported = true, +#endif + }, + .I2C = + { + .sda_pin = 7, + .scl_pin = 6, +#if defined(ESP8266) + .supported = false, +#else + .supported = true, +#endif + }, + .SW = + { +#if defined(ESP8266) + .pin = -1, + .activeLevel = 1, + .supported = false, +#else + .pin = 9, + .activeLevel = 0, + .supported = true, +#endif + }, + .LED = + { +#if defined(ESP8266) + .pin = -1, + .rgbNum = 0, + .onState = 0, + .supported = false, + .rgbSupported = false, +#else + .pin = 10, + .rgbNum = 11, + .onState = 1, + .supported = true, + .rgbSupported = true, +#endif + }, + .OLED = + { +#if defined(ESP8266) + .width = 0, + .height = 0, + .addr = 0, + .supported = false, +#else + .width = 128, + .height = 64, + .addr = 0x3C, + .supported = true, +#endif + }, + .WDG = + { +#if defined(ESP8266) + .resetPin = -1, + .supported = false, +#else + .resetPin = 2, + .supported = true, +#endif + }, + .name = "ONE_INDOOR", + }, + /** OPEN_AIR_OUTDOOR */ + [OPEN_AIR_OUTDOOR] = { + .SenseAirS8 = + { + .uart_tx_pin = 1, + .uart_rx_pin = 0, +#if defined(ESP8266) + .supported = false, +#else + .supported = true, +#endif + }, + /** Use UART0 don't use define pin number */ + .Pms5003 = + { + .uart_tx_pin = -1, + .uart_rx_pin = -1, +#if defined(ESP8266) + .supported = false, +#else + .supported = true, +#endif + }, + .I2C = + { + .sda_pin = 7, + .scl_pin = 6, +#if defined(ESP8266) + .supported = false, +#else + .supported = true, +#endif + }, + .SW = + { +#if defined(ESP8266) + .pin = -1, + .activeLevel = 1, + .supported = false, +#else + .pin = 9, + .activeLevel = 0, + .supported = true, +#endif + }, + .LED = + { +#if defined(ESP8266) + .pin = -1, + .rgbNum = 0, + .onState = 0, + .supported = false, + .rgbSupported = false, +#else + .pin = 10, + .rgbNum = 0, + .onState = 1, + .supported = true, + .rgbSupported = false, +#endif + }, + .OLED = + { +#if defined(ESP8266) + .width = 0, + .height = 0, + .addr = 0, + .supported = false, +#else + .width = 128, + .height = 64, + .addr = 0x3C, + .supported = true, +#endif + }, + .WDG = + { +#if defined(ESP8266) + .resetPin = -1, + .supported = false, +#else + .resetPin = 2, + .supported = true, +#endif + }, + .name = "OPEN_AIR_OUTDOOR", + }}; + +/** + * @brief Get Board Support Package + * + * @param def Board define @ref BoardType + * @return const BoardDef* + */ +const BoardDef *getBoardDef(BoardType def) { + if (def >= _BOARD_MAX) { + return NULL; + } + return &bsps[def]; +} + +#if defined(ESP8266) +#define bspPrintf(c, ...) \ + if (_debug != nullptr) { \ + _debug->printf("[BSP] " c "\r\n", ##__VA_ARGS__); \ + } +#else +#define bspPrintf(c, ...) log_i(c, ##__VA_ARGS__) +#endif + +/** + * @brief Print list of support Board and sensor + * + * @param _debug Serial debug + */ +void printBoardDef(Stream *_debug) { +#if defined(ESP8266) + if (_debug == NULL) { + return; + } +#endif + + for (int i = 0; i < _BOARD_MAX; i++) { + bspPrintf("Board name: %s", bsps[i].name); + bspPrintf("\tSensor CO2 S8:"); + bspPrintf("\t\tSupported: %d", bsps[i].SenseAirS8.supported); + if (bsps[i].SenseAirS8.supported) { + bspPrintf("\t\tUART Tx: %d", bsps[i].SenseAirS8.uart_tx_pin); + bspPrintf("\t\tUART Rx: %d", bsps[i].SenseAirS8.uart_rx_pin); + } + + bspPrintf("\tSensor PMS5003:"); + bspPrintf("\t\tSupported: %d", bsps[i].Pms5003.supported); + if (bsps[i].Pms5003.supported) { + bspPrintf("\t\tUART Tx: %d", bsps[i].Pms5003.uart_tx_pin); + bspPrintf("\t\tUART Rx: %d", bsps[i].Pms5003.uart_rx_pin); + } + + bspPrintf("\tI2C"); + bspPrintf("\t\tSupported: %d", bsps[i].I2C.supported); + if (bsps[i].I2C.supported) { + bspPrintf("\t\tI2C SCL: %d", bsps[i].I2C.scl_pin); + bspPrintf("\t\tI2C SDA: %d", bsps[i].I2C.sda_pin); + } + + bspPrintf("\tSwitch"); + bspPrintf("\t\tSupported: %d", bsps[i].SW.supported); + if (bsps[i].SW.supported) { + bspPrintf("\t\tPin : %d", bsps[i].SW.pin); + bspPrintf("\t\tActive Level: %d", bsps[i].SW.activeLevel); + } + + bspPrintf("\tLED"); + bspPrintf("\t\tSupported: %d", bsps[i].LED.supported); + if (bsps[i].LED.supported) { + bspPrintf("\t\tPin : %d", bsps[i].LED.pin); + bspPrintf("\t\tRGB : %d", bsps[i].LED.rgbSupported); + if (bsps[i].LED.rgbSupported) { + bspPrintf("\t\tNumber of RGB: %d", bsps[i].LED.rgbNum); + } else { + bspPrintf("\t\tLED state ON: %d (Single LED)", bsps[i].LED.onState); + } + } + + bspPrintf("\tOLED"); + bspPrintf("\t\tSupported: %d", bsps[i].OLED.supported); + if (bsps[i].OLED.supported) { + bspPrintf("\t\tWidth : %d", bsps[i].OLED.width); + bspPrintf("\t\tHeigth : %d", bsps[i].OLED.height); + bspPrintf("\t\tI2C Addr: %d", bsps[i].OLED.addr); + } + + bspPrintf("\tWatchDog"); + bspPrintf("\t\tSupported: %d", bsps[i].WDG.supported); + if (bsps[i].OLED.supported) { + bspPrintf("\t\tReset Pin: %d", bsps[i].WDG.resetPin); + } + } +} + +bool getBoardDef_I2C_Supported(const BoardDef *bsp) { + if (bsp == nullptr) { + return false; + } + return bsp->I2C.supported; +} + +int getBoardDef_I2C_SDA(const BoardDef *bsp) { + if ((bsp == nullptr) || (bsp->I2C.supported == false)) { + return -1; + } + return bsp->I2C.sda_pin; +} + +int getBoardDef_I2C_SCL(const BoardDef *bsp) { + if ((bsp == nullptr) || (bsp->I2C.supported == false)) { + return -1; + } + return bsp->I2C.scl_pin; +} + +bool getBoardDef_SW_Supported(const BoardDef *bsp) { + if (bsp == nullptr) { + return false; + } + return bsp->SW.supported; +} + +int getBoardDef_SW_Pin(const BoardDef *bsp) { + if ((bsp == nullptr) || (bsp->SW.supported == false)) { + return -1; + } + return bsp->SW.supported; +} + +int getBoardDef_SW_ActiveLevel(const BoardDef *bsp) { + if (bsp == nullptr) { + return 0; + } + return bsp->SW.activeLevel; +} + +void AirGradientBspWdgInit(const BoardDef *bsp) { + if (bsp == nullptr) { + return; + } + if (bsp->WDG.supported) { + pinMode(bsp->WDG.resetPin, OUTPUT); + digitalWrite(bsp->WDG.resetPin, LOW); + delay(25); // Delay 25ms + digitalWrite(bsp->WDG.resetPin, HIGH); + } +} + +/** + * @brief Begin reset external watchdog. Must call @ref AirGradientBspWdgFeedEnd + * after 20 ms + * + * @param bsp + */ +void AirGradientBspWdgFeedBegin(const BoardDef *bsp) { + if (bsp == nullptr) { + return; + } + + if (bsp->WDG.supported) { + digitalWrite(bsp->WDG.resetPin, HIGH); + } +} + +/** + * @brief Call this function to finish watchdog feed after call @ref + * AirGradientBspWdgFeedBegin 25 ms + * + * @param bsp + */ +void AirGradientBspWdgFeedEnd(const BoardDef *bsp) { + if (bsp == nullptr) { + return; + } + + if (bsp->WDG.supported) { + digitalWrite(bsp->WDG.resetPin, LOW); + } +} diff --git a/src/Main/BoardDef.h b/src/Main/BoardDef.h new file mode 100644 index 0000000..b445993 --- /dev/null +++ b/src/Main/BoardDef.h @@ -0,0 +1,88 @@ +#ifndef _AIR_GRADIENT_BOARD_DEF_H_ +#define _AIR_GRADIENT_BOARD_DEF_H_ + +#include + +#if defined(ESP8266) +#define AgLog(c, ...) \ + if (this->_debugStream != nullptr) { \ + this->_debugStream->printf("[%s] " c "\r\n", this->TAG, ##__VA_ARGS__); \ + } +#else +#include +#define AgLog(c, ...) log_i(c, ##__VA_ARGS__) +#endif + +/** + * @brief Define Airgradient supported board type + */ +enum BoardType { + DIY_BASIC = 0x00, + DIY_PRO_INDOOR_V4_2 = 0x01, + ONE_INDOOR = 0x02, + OPEN_AIR_OUTDOOR = 0x03, + _BOARD_MAX +}; + +/** + * @brief Board definitions + * + */ +struct BoardDef { + /** Board Support CO2 SenseS8 */ + struct { + const int uart_tx_pin; /** UART tx pin */ + const int uart_rx_pin; /** UART rx pin */ + const bool supported; /** Is BSP supported for this sensor */ + } SenseAirS8; + + /** Board Support Plantower PMS5003 */ + struct { + const int uart_tx_pin; /** UART tx pin */ + const int uart_rx_pin; /** UART rx pin */ + const bool supported; /** Is BSP supported for this sensor */ + } Pms5003; + + /** I2C Bus */ + struct { + const int sda_pin; /** I2C SDA pin */ + const int scl_pin; /** I2C SCL pin */ + const bool supported; /** Is BSP supported I2C communication */ + } I2C; + + /** Switch */ + struct { + const int pin; /** Switch PIN */ + const int activeLevel; /** Switch pressed level */ + const bool supported; + } SW; + + /** LED */ + struct { + const int pin; /** Pin control */ + const int rgbNum; /** Number of RGB LED */ + const int onState; /** Single LED turn on state */ + const bool supported; /** SUpported LED */ + const bool rgbSupported; /** LED is RGB */ + } LED; + + /** OLED */ + struct { + const uint8_t width; /** Display Width */ + const uint8_t height; /** Display height */ + const uint8_t addr; /** OLED I2C address */ + const bool supported; + } OLED; + + /** Watchdog */ + struct { + const uint8_t resetPin; + const bool supported; + } WDG; + const char *name; +}; + +const BoardDef *getBoardDef(BoardType def); +void printBoardDef(Stream *_debug); + +#endif /** _AIR_GRADIENT_BOARD_DEF_H_ */ diff --git a/src/Main/HardwareWatchdog.cpp b/src/Main/HardwareWatchdog.cpp new file mode 100644 index 0000000..37a963c --- /dev/null +++ b/src/Main/HardwareWatchdog.cpp @@ -0,0 +1,74 @@ +#include "HardwareWatchdog.h" + +HardwareWatchdog::HardwareWatchdog(BoardType type) : boardType(type) {} + +#if defined(ESP8266) +void HardwareWatchdog::begin(Stream &debugStream) { + this->_debugStream = &debugStream; + this->begin(); +} +#else +#endif + +/** + * @brief Initialize external watchdog + * + */ +void HardwareWatchdog::begin(void) { + if (this->_isInit) { + return; + } + + /** Get BSP */ + this->bsp = getBoardDef(this->boardType); + if ((this->bsp == nullptr) || (this->bsp->WDG.supported == false)) { + AgLog("Board not supported Watchdog"); + return; + } + + /** Init GPIO and first feed external watchdog */ + pinMode(this->bsp->WDG.resetPin, OUTPUT); + this->_feed(); + + this->_isInit = true; + AgLog("Inittialized"); +} + +/** + * @brief Reset Watchdog + * + */ +void HardwareWatchdog::reset(void) { + if (this->isInitInvalid()) { + return; + } + + this->_feed(); +} + +/** + * @brief Wathdog timeout + * + * @return int Millisecionds + */ +int HardwareWatchdog::getTimeout(void) { return 5 * 1000 * 60; } + +bool HardwareWatchdog::isInitInvalid(void) { + if (this->_isInit == false) { + AgLog("No-initialized"); + return true; + } + return false; +} + +/** + * @brief Reset external watchdog + * + */ +void HardwareWatchdog::_feed(void) { + digitalWrite(this->bsp->WDG.resetPin, HIGH); + delay(25); + digitalWrite(this->bsp->WDG.resetPin, LOW); + + AgLog("Reset"); +} diff --git a/src/Main/HardwareWatchdog.h b/src/Main/HardwareWatchdog.h new file mode 100644 index 0000000..367ff91 --- /dev/null +++ b/src/Main/HardwareWatchdog.h @@ -0,0 +1,37 @@ +#ifndef _HARDWARE_WATCHDOG_H_ +#define _HARDWARE_WATCHDOG_H_ + +#include + +#include "BoardDef.h" + +/** + * @brief The class define how to control external watchdog on ONE-V9 and + * Outdoor + */ +class HardwareWatchdog { +public: + HardwareWatchdog(BoardType type); +#if defined(ESP8266) + void begin(Stream &debugStream); +#else +#endif + void begin(void); + void reset(void); + int getTimeout(void); + +private: + bool _isInit = false; + const BoardDef *bsp; + BoardType boardType; +#if defined(ESP8266) + Stream *_debugStream; + const char *TAG = "HardwareWatchdog"; +#else +#endif + + bool isInitInvalid(void); + void _feed(void); +}; + +#endif /** _HARDWARE_WATCHDOG_H_ */ diff --git a/src/Main/LedBar.cpp b/src/Main/LedBar.cpp new file mode 100644 index 0000000..c6cca1e --- /dev/null +++ b/src/Main/LedBar.cpp @@ -0,0 +1,126 @@ +#include "LedBar.h" + +#include "../Libraries/Adafruit_NeoPixel/Adafruit_NeoPixel.h" + +#define pixel() ((Adafruit_NeoPixel *)this->pixels) + +#if defined(ESP8266) +void LedBar::begin(Stream &debugStream) { + this->_debugStream = &debugStream; + this->begin(); +} +#else +#endif +LedBar::LedBar(BoardType type) : _boardType(type) {} + +/** + * @brief LED bar initialize + * + */ +void LedBar::begin(void) { + if (this->_isBegin) { + return; + } + + /** Get board support package define */ + this->_bsp = getBoardDef(this->_boardType); + if ((this->_bsp == nullptr) || (this->_bsp->LED.supported == false) || + (this->_bsp->LED.rgbNum == 0)) { + AgLog("Board Not supported or LED not available on board"); + return; + } + + /** Init pixels */ + this->pixels = new Adafruit_NeoPixel( + this->_bsp->LED.rgbNum, this->_bsp->LED.pin, NEO_GRB + NEO_KHZ800); + pixel()->begin(); + pixel()->clear(); + + this->_isBegin = true; + + AgLog("Initialize"); +} + +/** + * @brief Set LED color, if LED is on the color update immedietly. Otherwise + * must setOn to show LED color + * + * @param red Color Red (0 - 255) + * @param green Color Green (0 - 255) + * @param blue Color Blue (0 - 255) + * @param ledNum Index of LED from 0 to getNumberOfLeds() - 1 + */ +void LedBar::setColor(uint8_t red, uint8_t green, uint8_t blue, int ledNum) { + if (this->ledNumInvalid(ledNum)) { + return; + } + + pixel()->setPixelColor(ledNum, red, green, blue); +} + +/** + * @brief Set LED brightness apply for all LED bar + * + * @param brightness Brightness (0 - 255) + */ +void LedBar::setBrighness(uint8_t brightness) { + if (this->isBegin() == false) { + return; + } + pixel()->setBrightness(brightness); +} + +/** + * @brief Get number of LED on bar + * + * @return int Number of LED + */ +int LedBar::getNumberOfLeds(void) { + if (this->isBegin() == false) { + return 0; + } + + return this->_bsp->LED.rgbNum; +} + +bool LedBar::isBegin(void) { + if (this->_isBegin) { + return true; + } + AgLog("LED is not initialized"); + return false; +} + +bool LedBar::ledNumInvalid(int ledNum) { + if (this->isBegin() == false) { + return true; + } + + if ((ledNum < 0) || (ledNum >= this->_bsp->LED.rgbNum)) { + AgLog("ledNum invalid: %d", ledNum); + return true; + } + return false; +} + +void LedBar::setColor(uint8_t red, uint8_t green, uint8_t blue) { + for (int ledNum = 0; ledNum < this->_bsp->LED.rgbNum; ledNum++) { + this->setColor(red, green, blue, ledNum); + } +} + +/** + * @brief Call to turn LED on/off base on the setting color + * + */ +void LedBar::show(void) { + if (pixel()->canShow()) { + pixel()->show(); + } +} + +/** + * @brief Set all LED to off color (r,g,b) = (0,0,0) + * + */ +void LedBar::clear(void) { pixel()->clear(); } diff --git a/src/Main/LedBar.h b/src/Main/LedBar.h new file mode 100644 index 0000000..b2431e3 --- /dev/null +++ b/src/Main/LedBar.h @@ -0,0 +1,42 @@ +#ifndef _AIR_GRADIENT_LED_H_ +#define _AIR_GRADIENT_LED_H_ + +#include + +#include "BoardDef.h" + +/** + * @brief The class define how to handle the RGB LED bar + * + */ +class LedBar { +public: +#if defined(ESP8266) + void begin(Stream &debugStream); +#else +#endif + LedBar(BoardType type); + void begin(void); + void setColor(uint8_t red, uint8_t green, uint8_t blue, int ledNum); + void setColor(uint8_t red, uint8_t green, uint8_t blue); + void setBrighness(uint8_t brightness); + int getNumberOfLeds(void); + void show(void); + void clear(void); + +private: + const BoardDef *_bsp; + bool _isBegin = false; + uint8_t _ledState = 0; + BoardType _boardType; + void *pixels = nullptr; +#if defined(ESP8266) + Stream *_debugStream = NULL; + const char *TAG = "LED"; +#else +#endif + bool isBegin(void); + bool ledNumInvalid(int ledNum); +}; + +#endif /** _AIR_GRADIENT_LED_H_ */ diff --git a/src/Main/PushButton.cpp b/src/Main/PushButton.cpp new file mode 100644 index 0000000..d81f81b --- /dev/null +++ b/src/Main/PushButton.cpp @@ -0,0 +1,74 @@ +#include "PushButton.h" + +PushButton::PushButton(BoardType type) : _boardType(type) {} + +#if defined(ESP8266) +void PushButton::begin(Stream &debugStream) { + this->_debugStream = &debugStream; + this->begin(); +} +#else +#endif + +/** + * @brief Initialize PushButton, If PushButton is not initialized the get state + * + */ +void PushButton::begin(void) { + if (this->_isBegin) { + AgLog("Initialized, call end() then try again"); + return; + } + + this->_bsp = getBoardDef(this->_boardType); + if ((this->_bsp == nullptr) || (this->_bsp->SW.supported == false)) { + AgLog("Board not supported or switch not available"); + return; + } + + if (this->_boardType == DIY_PRO_INDOOR_V4_2) { + pinMode(this->_bsp->SW.pin, INPUT_PULLUP); + } else { + pinMode(this->_bsp->SW.pin, INPUT); + } + + this->_isBegin = true; + AgLog("Initialize"); +} + +/** + * @brief Get button state, Alway retrun State::BUTTON_RELEASED if no-initialize + * + * @return PushButton::State + */ +PushButton::State PushButton::getState(void) { + if (this->isBegin() == false) { + return State::BUTTON_RELEASED; + } + + if (digitalRead(this->_bsp->SW.pin) == this->_bsp->SW.activeLevel) { + return State::BUTTON_PRESSED; + } + return State::BUTTON_RELEASED; +} + +/** + * @brief Get PushButton::State as string + * + * @param state Buttons State + * @return String + */ +String PushButton::toString(PushButton::State state) { + if (state == BUTTON_PRESSED) { + return "Presssed"; + } + return "Released"; +} + +bool PushButton::isBegin(void) { + if (this->_isBegin) { + return true; + } + AgLog("Switch not initialized"); + return false; +} diff --git a/src/Main/PushButton.h b/src/Main/PushButton.h new file mode 100644 index 0000000..4b2f6d4 --- /dev/null +++ b/src/Main/PushButton.h @@ -0,0 +1,47 @@ +#ifndef _AIR_GRADIENT_SW_H_ +#define _AIR_GRADIENT_SW_H_ + +#include "BoardDef.h" +#include + +/** + * @brief The class define how to handle the Push button + * + */ +class PushButton { +public: + /** + * @brief Enum button state + */ + enum State { BUTTON_PRESSED, BUTTON_RELEASED }; + +#if defined(ESP8266) + void begin(Stream &debugStream); +#else +#endif + PushButton(BoardType type); + void begin(void); + State getState(void); + String toString(State state); + +private: + /** BSP constant variable */ + const BoardDef *_bsp; + /** Board type */ + BoardType _boardType; + /** Is inititalize flag */ + bool _isBegin = false; + + /** Special variable for ESP8266 */ +#if defined(ESP8266) + Stream *_debugStream = nullptr; + const char *TAG = "PushButton"; +#else +#endif + + /** Method */ + + bool isBegin(void); +}; + +#endif /** _AIR_GRADIENT_SW_H_ */ diff --git a/src/Main/StatusLed.cpp b/src/Main/StatusLed.cpp new file mode 100644 index 0000000..d0451e8 --- /dev/null +++ b/src/Main/StatusLed.cpp @@ -0,0 +1,115 @@ +#include "StatusLed.h" + +StatusLed::StatusLed(BoardType boardType) : boardType(boardType) {} + +#if defined(ESP8266) +void StatusLed::begin(Stream &debugStream) { + this->_debugStream = &debugStream; + this->begin(); +} +#else +#endif + +/** + * @brief Initialized LED + * + */ +void StatusLed::begin(void) { + if (this->_isBegin) { + AgLog("Initialized, call end() then try again"); + return; + } + bsp = getBoardDef(this->boardType); + if ((bsp == nullptr) || (bsp->LED.supported == false)) { + AgLog("Board not support StatusLed"); + return; + } + + pinMode(bsp->LED.pin, OUTPUT); + digitalWrite(bsp->LED.pin, !bsp->LED.onState); + + this->state = LED_OFF; + this->_isBegin = true; + + AgLog("Initialize"); +} + +/** + * @brief Turn LED on + * + */ +void StatusLed::setOn(void) { + if (this->isBegin() == false) { + return; + } + digitalWrite(bsp->LED.pin, bsp->LED.onState); + this->state = LED_ON; + AgLog("Turn ON"); +} + +/** + * @brief Turn LED off + * + */ +void StatusLed::setOff(void) { + if (this->isBegin() == false) { + return; + } + digitalWrite(bsp->LED.pin, !bsp->LED.onState); + this->state = LED_OFF; + AgLog("Turn OFF"); +} + +/** + * @brief Set LED toggle + * + */ +void StatusLed::setToggle(void) { + if (this->state == LED_ON) { + this->setOff(); + } else { + this->setOn(); + } +} + +/** + * @brief Get current LED state + * + * @return StatusLed::State + */ +StatusLed::State StatusLed::getState(void) { return this->state; } + +/** + * @brief Convert LED state to string + * + * @param state LED state + * @return String + */ +String StatusLed::toString(StatusLed::State state) { + if (state == LED_ON) { + return "On"; + } + return "Off"; +} + +bool StatusLed::isBegin(void) { + if (this->_isBegin == false) { + AgLog("Not-Initialized"); + return false; + } + + return true; +} + +void StatusLed::end(void) { + if (_isBegin == false) { + return; + } + +#if defined(ESP8266) + _debugStream = nullptr; +#endif + setOff(); + _isBegin = false; + AgLog("De-initialize"); +} diff --git a/src/Main/StatusLed.h b/src/Main/StatusLed.h new file mode 100644 index 0000000..3890243 --- /dev/null +++ b/src/Main/StatusLed.h @@ -0,0 +1,45 @@ +#ifndef _STATUS_LED_H_ +#define _STATUS_LED_H_ + +#include "BoardDef.h" +#include + +/** + * @brief The class define how to handle the LED + * + */ +class StatusLed { +public: + enum State { + LED_OFF, + LED_ON, + }; + + StatusLed(BoardType boardType); +#if defined(ESP8266) + void begin(Stream &debugStream); +#else +#endif + void begin(void); + void end(void); + void setOn(void); + void setOff(void); + void setToggle(void); + State getState(void); + String toString(StatusLed::State state); + +private: + const BoardDef *bsp = nullptr; + BoardType boardType; + bool _isBegin = false; + State state; +#if defined(ESP8266) + Stream *_debugStream; + const char *TAG = "StatusLed"; +#else +#endif + + bool isBegin(void); +}; + +#endif /** _STATUS_LED_H_ */ diff --git a/src/PMS/PMS.cpp b/src/PMS/PMS.cpp new file mode 100644 index 0000000..be7e919 --- /dev/null +++ b/src/PMS/PMS.cpp @@ -0,0 +1,164 @@ +#include "PMS.h" + +bool PMS::begin(Stream *stream) { + _stream = stream; + + DATA data; + if (readUntil(data, 5000)) { + return true; + } + + return false; +} + +// Standby mode. For low power consumption and prolong the life of the sensor. +void PMS::sleep() { + uint8_t command[] = {0x42, 0x4D, 0xE4, 0x00, 0x00, 0x01, 0x73}; + _stream->write(command, sizeof(command)); +} + +// Operating mode. Stable data should be got at least 30 seconds after the +// sensor wakeup from the sleep mode because of the fan's performance. +void PMS::wakeUp() { + uint8_t command[] = {0x42, 0x4D, 0xE4, 0x00, 0x01, 0x01, 0x74}; + _stream->write(command, sizeof(command)); +} + +// Active mode. Default mode after power up. In this mode sensor would send +// serial data to the host automatically. +void PMS::activeMode() { + uint8_t command[] = {0x42, 0x4D, 0xE1, 0x00, 0x01, 0x01, 0x71}; + _stream->write(command, sizeof(command)); + _mode = MODE_ACTIVE; +} + +// Passive mode. In this mode sensor would send serial data to the host only for +// request. +void PMS::passiveMode() { + uint8_t command[] = {0x42, 0x4D, 0xE1, 0x00, 0x00, 0x01, 0x70}; + _stream->write(command, sizeof(command)); + _mode = MODE_PASSIVE; +} + +// Request read in Passive Mode. +void PMS::requestRead() { + if (_mode == MODE_PASSIVE) { + uint8_t command[] = {0x42, 0x4D, 0xE2, 0x00, 0x00, 0x01, 0x71}; + _stream->write(command, sizeof(command)); + } +} + +// Non-blocking function for parse response. +bool PMS::read(DATA &data) { + _data = &data; + loop(); + + return _status == STATUS_OK; +} + +// Blocking function for parse response. Default timeout is 1s. +bool PMS::readUntil(DATA &data, uint16_t timeout) { + _data = &data; + uint32_t start = millis(); + do { + loop(); + if (_status == STATUS_OK) { + break; + } + + /** Relax task to avoid watchdog reset */ + delay(1); + } while (millis() - start < timeout); + + return _status == STATUS_OK; +} + +void PMS::loop() { + _status = STATUS_WAITING; + if (_stream->available()) { + uint8_t ch = _stream->read(); + + switch (_index) { + case 0: + if (ch != 0x42) { + return; + } + _calculatedChecksum = ch; + break; + + case 1: + if (ch != 0x4D) { + _index = 0; + return; + } + _calculatedChecksum += ch; + break; + + case 2: + _calculatedChecksum += ch; + _frameLen = ch << 8; + break; + + case 3: + _frameLen |= ch; + // Unsupported sensor, different frame length, transmission error e.t.c. + if (_frameLen != 2 * 9 + 2 && _frameLen != 2 * 13 + 2) { + _index = 0; + return; + } + _calculatedChecksum += ch; + break; + + default: + if (_index == _frameLen + 2) { + _checksum = ch << 8; + } else if (_index == _frameLen + 2 + 1) { + _checksum |= ch; + + if (_calculatedChecksum == _checksum) { + _status = STATUS_OK; + + // Standard Particles, CF=1. + _data->PM_SP_UG_1_0 = makeWord(_payload[0], _payload[1]); + _data->PM_SP_UG_2_5 = makeWord(_payload[2], _payload[3]); + _data->PM_SP_UG_10_0 = makeWord(_payload[4], _payload[5]); + + // Atmospheric Environment. + _data->PM_AE_UG_1_0 = makeWord(_payload[6], _payload[7]); + _data->PM_AE_UG_2_5 = makeWord(_payload[8], _payload[9]); + _data->PM_AE_UG_10_0 = makeWord(_payload[10], _payload[11]); + + // Total particles count per 100ml air + _data->PM_RAW_0_3 = makeWord(_payload[12], _payload[13]); + _data->PM_RAW_0_5 = makeWord(_payload[14], _payload[15]); + _data->PM_RAW_1_0 = makeWord(_payload[16], _payload[17]); + _data->PM_RAW_2_5 = makeWord(_payload[18], _payload[19]); + _data->PM_RAW_5_0 = makeWord(_payload[20], _payload[21]); + _data->PM_RAW_10_0 = makeWord(_payload[22], _payload[23]); + + // Formaldehyde concentration (PMSxxxxST units only) + _data->AMB_HCHO = makeWord(_payload[24], _payload[25]) / 1000; + + // Temperature & humidity (PMSxxxxST units only) + _data->AMB_TMP = makeWord(_payload[20], _payload[21]); + _data->AMB_HUM = makeWord(_payload[22], _payload[23]); + } + + _index = 0; + return; + } else { + _calculatedChecksum += ch; + uint8_t payloadIndex = _index - 4; + + // Payload is common to all sensors (first 2x6 bytes). + if (payloadIndex < sizeof(_payload)) { + _payload[payloadIndex] = ch; + } + } + + break; + } + + _index++; + } +} diff --git a/src/PMS/PMS.h b/src/PMS/PMS.h new file mode 100644 index 0000000..f1f32dc --- /dev/null +++ b/src/PMS/PMS.h @@ -0,0 +1,75 @@ +#ifndef _PMS_BASE_H_ +#define _PMS_BASE_H_ + +#include + +/** + * @brief Class define how to handle plantower PMS sensor it's upport for + * PMS5003 and PMS5003T series. The data @ref AMB_TMP and @ref AMB_HUM only + * valid on PMS5003T + */ +class PMS { +public: + static const uint16_t SINGLE_RESPONSE_TIME = 1000; + static const uint16_t TOTAL_RESPONSE_TIME = 1000 * 10; + static const uint16_t STEADY_RESPONSE_TIME = 1000 * 30; + + // static const uint16_t BAUD_RATE = 9600; + + struct DATA { + // Standard Particles, CF=1 + uint16_t PM_SP_UG_1_0; + uint16_t PM_SP_UG_2_5; + uint16_t PM_SP_UG_10_0; + + // Atmospheric environment + uint16_t PM_AE_UG_1_0; + uint16_t PM_AE_UG_2_5; + uint16_t PM_AE_UG_10_0; + + // Raw particles count (number of particles in 0.1l of air + uint16_t PM_RAW_0_3; + uint16_t PM_RAW_0_5; + uint16_t PM_RAW_1_0; + uint16_t PM_RAW_2_5; + uint16_t PM_RAW_5_0; + uint16_t PM_RAW_10_0; + + // Formaldehyde (HCHO) concentration in mg/m^3 - PMSxxxxST units only + uint16_t AMB_HCHO; + + // Temperature & humidity - PMSxxxxST units only + int16_t AMB_TMP; + uint16_t AMB_HUM; + }; + + bool begin(Stream *stream); + void sleep(); + void wakeUp(); + void activeMode(); + void passiveMode(); + + void requestRead(); + bool read(DATA &data); + bool readUntil(DATA &data, uint16_t timeout = SINGLE_RESPONSE_TIME); + +private: + enum STATUS { STATUS_WAITING, STATUS_OK }; + enum MODE { MODE_ACTIVE, MODE_PASSIVE }; + + uint8_t _payload[50]; + Stream *_stream; + DATA *_data; + STATUS _status; + MODE _mode = MODE_ACTIVE; + + uint8_t _index = 0; + uint16_t _frameLen; + uint16_t _checksum; + uint16_t _calculatedChecksum; + + void loop(); + char Char_PM2[10]; +}; + +#endif diff --git a/src/pms/pms5003.cpp b/src/PMS/PMS5003.cpp similarity index 100% rename from src/pms/pms5003.cpp rename to src/PMS/PMS5003.cpp diff --git a/src/pms/pms5003.h b/src/PMS/PMS5003.h similarity index 100% rename from src/pms/pms5003.h rename to src/PMS/PMS5003.h diff --git a/src/pms/pms5003t.cpp b/src/PMS/PMS5003T.cpp similarity index 100% rename from src/pms/pms5003t.cpp rename to src/PMS/PMS5003T.cpp diff --git a/src/pms/pms5003t.h b/src/PMS/PMS5003T.h similarity index 100% rename from src/pms/pms5003t.h rename to src/PMS/PMS5003T.h diff --git a/src/s8/s8.cpp b/src/S8/S8.cpp similarity index 100% rename from src/s8/s8.cpp rename to src/S8/S8.cpp diff --git a/src/s8/s8.h b/src/S8/S8.h similarity index 100% rename from src/s8/s8.h rename to src/S8/S8.h diff --git a/src/S8/mb_crc.cpp b/src/S8/mb_crc.cpp new file mode 100644 index 0000000..462cca1 --- /dev/null +++ b/src/S8/mb_crc.cpp @@ -0,0 +1,73 @@ +#include "mb_crc.h" +#include + +/* ModBus CRC routine extracted from + * https://modbus.org/docs/Modbus_over_serial_line_V1_02.pdf */ + +/* Table of CRC values for high–order byte */ +static const uint8_t auchCRCHi[] = { + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, + 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40}; + +/* Table of CRC values for low–order byte */ +static const uint8_t auchCRCLo[] = { + 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, + 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, + 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, + 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, + 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3, + 0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, + 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, + 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, + 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, + 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26, + 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1, + 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, + 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, + 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, + 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5, + 0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0, + 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, + 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, + 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, + 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C, + 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, + 0x41, 0x81, 0x80, 0x40}; + +uint16_t AgMb16Crc(uint8_t *puchMsg, uint16_t usDataLen) { + /* + puchMsg -> message to calculate CRC upon + usDataLen -> quantity of bytes in message + */ + uint8_t uchCRCHi = 0xFF; /* high byte of CRC initialized */ + uint8_t uchCRCLo = 0xFF; /* low byte of CRC initialized */ + uint16_t uIndex; /* will index into CRC lookup table */ + + while (usDataLen--) /* pass through message buffer */ + { + uIndex = uchCRCLo ^ *puchMsg++; /* calculate the CRC */ + uchCRCLo = uchCRCHi ^ auchCRCHi[uIndex]; + uchCRCHi = auchCRCLo[uIndex]; + } + return (uchCRCHi << 8 | uchCRCLo); +} diff --git a/src/S8/mb_crc.h b/src/S8/mb_crc.h new file mode 100644 index 0000000..b15274b --- /dev/null +++ b/src/S8/mb_crc.h @@ -0,0 +1,8 @@ +#ifndef _AIR_GRADIENT_MODBUS_CRC_H_ +#define _AIR_GRADIENT_MODBUS_CRC_H_ + +#include + +uint16_t AgMb16Crc(uint8_t *buf, uint16_t len); + +#endif /** _AIR_GRADIENT_MODBUS_CRC_H_ */ diff --git a/src/sgp41/sgp41.cpp b/src/Sgp41/Sgp41.cpp similarity index 100% rename from src/sgp41/sgp41.cpp rename to src/Sgp41/Sgp41.cpp diff --git a/src/sgp41/sgp41.h b/src/Sgp41/Sgp41.h similarity index 100% rename from src/sgp41/sgp41.h rename to src/Sgp41/Sgp41.h diff --git a/src/sht/sht.cpp b/src/Sht/Sht.cpp similarity index 100% rename from src/sht/sht.cpp rename to src/Sht/Sht.cpp diff --git a/src/sht/sht.h b/src/Sht/Sht.h similarity index 100% rename from src/sht/sht.h rename to src/Sht/Sht.h