#include #include #include #include #include "DHT.h" #include #include #define Version "0.3.3" #define LED_PIN 5 #define LED_COUNT 9 const uint8_t ledMap[LED_COUNT] = { 3, 0, 1, 8, 2, 5, 4, 7, 6 }; //2DO: //Pomiar światła bh1750 i fotorezystor // obsługa nie zamontowania -wyświetlacza, bt1750, DHT22 #define NUMPIXELS 10 //docelowo 9-10 #define DHTTYPE DHT22 #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 32 #define OLED_RESET -1 #define SCREEN_ADDRESS 0x3C //PINS #define BTN_DIMM 34 //GPIO34 D34 #define BTN_RST 35 //GPIO35 D35 #define BTN_HYGRSTT 36 //GPIO36 VP #define BTN_SPEED 39 //GPIO35 VN #define PIN_SPEED_1 32 //GPIO32 D32 #define PIN_SPEED_2 14 //GPIO36 D14 #define DHTPIN 4 //GPIO04 D4 #define LED_WHT_TANK 25 //GPIO26 D26 #define LED_RED_TANK 26 //GPIO25 D25 #define NEOPIXEL 27 //GPIO04 D27 #define IN_PHOTOTRA 12 #define WTR_LVL 33 //GPIO33 D33 #define DIMM_MAX_VALUE 3 // docelowo 4, tylko na testy //NEO PIXEL ARDESES: #define NEOPXL_MULTIPLIER 25 // ARDESES: #define ADR_NEOPXL_SPEED_1 1 #define ADR_NEOPXL_SPEED_2 0 #define ADR_NEOPXL_FILTER 3 #define ADR_NEOPXL_L1 2 #define ADR_NEOPXL_L2 5 #define ADR_NEOPXL_L3 4 #define ADR_NEOPXL_L4 7 #define ADR_NEOPXL_L5 6 #define ADR_NEOPXL_WATERLVL 8 #define ADR_NEOPXL_TANK #define NON_ACTIVE_LED_DIVIDER 8 Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); Adafruit_NeoPixel pixels(NUMPIXELS, NEOPIXEL, NEO_GRB + NEO_KHZ800); DHT dht(DHTPIN, DHTTYPE); BH1750 lightMeter; //MAIN VALUES VARIABLES int8_t resetVal = 0; int8_t fanSpeedVal = 1; int8_t hygrostatVal = 55; int8_t dimmStep = 1; int8_t dimmVal = 1; int8_t waterLvlVal = 0; int8_t photoVal = 0; float temp = 0.0; float hum = 0.0; float lux = 0.0; //NEOPIXELS VARIABLES int8_t neoPixelSwitch = 1; int8_t neoPixelRed = 10; int8_t neoPixelGreen = 10; int8_t neoPixelBlue = 10; int8_t neoPixelSpeed_1 = 1; int8_t neoPixelSpeed_2 = 1; int8_t neoPixelFilter = 1; int8_t neoPixelLvl_1 = 1; int8_t neoPixelLvl_2 = 1; int8_t neoPixelLvl_3 = 1; int8_t neoPixelLvl_4 = 1; int8_t neoPixelLvl_5 = 1; int8_t neoPixelWaterLvlR = 1; int8_t neoPixelWaterLvlG = 1; int8_t neoPixelWaterLvlB = 1; int8_t neoPixelTank = 1; void IRAM_ATTR dimmButtonFcn() { dimmStep++; if (dimmStep > DIMM_MAX_VALUE) { dimmStep = 0; } } void IRAM_ATTR speedButtonFcn() { fanSpeedVal++; if (fanSpeedVal >= 3) { fanSpeedVal = 1; } } void IRAM_ATTR hygrostatButtonFcn() { hygrostatVal = hygrostatVal + 5; if (hygrostatVal > 65) { hygrostatVal = 45; } } void setFanSpeed(uint8_t spdInpt) { if (spdInpt == 1) { digitalWrite(PIN_SPEED_2, LOW); delay(300); digitalWrite(PIN_SPEED_1, HIGH); } else if (spdInpt == 2) { digitalWrite(PIN_SPEED_1, LOW); delay(300); digitalWrite(PIN_SPEED_2, HIGH); } else { digitalWrite(PIN_SPEED_1, LOW); delay(300); digitalWrite(PIN_SPEED_2, LOW); } } void rainbowCycle(uint8_t wait) { uint16_t i, j; for (j = 0; j < 256 * 3; j++) { for (i = 0; i < LED_COUNT; i++) { uint8_t physIndex = ledMap[i]; // mapowanie pozycji logicznej na fizyczną pixels.setPixelColor(physIndex, Wheel((i * 256 / LED_COUNT + j) & 255)); } pixels.show(); delay(wait); } } uint32_t Wheel(byte pos) { pos = 255 - pos; uint8_t r, g, b; if (pos < 85) { r = 255 - pos * 3; g = 0; b = pos * 3; } else if (pos < 170) { pos -= 85; r = 0; g = pos * 3; b = 255 - pos * 3; } else { pos -= 170; r = pos * 3; g = 255 - pos * 3; b = 0; } r = r * 30 / 100; // Ogranicz jasność do 30% g = g * 30 / 100; b = b * 30 / 100; return pixels.Color(r, g, b); } void setup() { Serial.begin(9600); if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) { Serial.println(F("SSD1306 allocation failed")); } display.setTextSize(1); display.setTextColor(SSD1306_WHITE); display.clearDisplay(); display.setCursor(0, 0); display.println("Version:"); display.setCursor(60, 0); display.println(Version); display.display(); // delay(500); pinMode(BTN_RST, INPUT); pinMode(BTN_DIMM, INPUT); pinMode(BTN_SPEED, INPUT); pinMode(BTN_HYGRSTT, INPUT); pinMode(PIN_SPEED_1, OUTPUT); pinMode(PIN_SPEED_2, OUTPUT); pinMode(LED_RED_TANK, OUTPUT); pinMode(LED_WHT_TANK, OUTPUT); pinMode(IN_PHOTOTRA, INPUT_PULLDOWN); pinMode(WTR_LVL, INPUT); attachInterrupt(digitalPinToInterrupt(BTN_DIMM), dimmButtonFcn, FALLING); attachInterrupt(digitalPinToInterrupt(BTN_SPEED), speedButtonFcn, FALLING); attachInterrupt(digitalPinToInterrupt(BTN_HYGRSTT), hygrostatButtonFcn, FALLING); Wire.begin(); lightMeter.begin(); dht.begin(); pixels.begin(); if (dimmStep == 0) { dimmVal = 0; } else if (dimmStep == 1) { dimmVal = 1; } else if (dimmStep == 2) { dimmVal = 6; } else if (dimmStep == 3) { dimmVal = 12; } else { dimmVal = 24; } } void loop() { // ################################################### // WYŚWIETLACZ display.clearDisplay(); display.setCursor(90, 0); display.println(Version); display.setCursor(0, 0); display.println("RST:"); display.setCursor(25, 0); display.println(resetVal); display.setCursor(35, 0); display.println("L:"); display.setCursor(47, 0); display.println(lux); display.setCursor(0, 10); display.println("WtrLvl:"); display.setCursor(50, 10); display.println(waterLvlVal); display.setCursor(70, 10); display.println("FanSpd:"); display.setCursor(115, 10); display.println(fanSpeedVal); // display.setCursor(0, 10); // display.println("FanSpd:"); // display.setCursor(50, 10); // display.println(fanSpeedVal); // // display.setCursor(70, 10); // display.println("Hygst:"); // display.setCursor(115, 10); // display.println(hygrostatVal); display.setCursor(0, 20); display.println("Hum:"); display.setCursor(28, 20); display.println(hum); // display.setCursor(0, 20); // display.println("Ph:"); // display.setCursor(28, 20); // display.println(photoVal); display.setCursor(70, 20); display.println("Dimm:"); display.setCursor(115, 20); display.println(dimmStep); display.display(); display.setCursor(70, 20); display.println("Dimm:"); display.setCursor(115, 20); display.println(dimmStep); display.display(); // DATA HAVEREST lux = lightMeter.readLightLevel(); waterLvlVal = touchRead(WTR_LVL); hum = (dht.readHumidity()); photoVal = analogRead(IN_PHOTOTRA); // ################################################################# // ################################################################# // LOGIKA if (digitalRead(BTN_RST) == HIGH) { unsigned long startTime = millis(); while (digitalRead(BTN_RST) == HIGH && millis() - startTime < 4000) { display.clearDisplay(); display.setCursor(20, 0); display.println("Resetowanie... 4s"); display.display(); delay(100); } if (digitalRead(BTN_RST) == HIGH) { resetVal = 1; display.clearDisplay(); display.setCursor(0, 0); display.println("Zresetowano"); display.display(); delay(500); } } // jeśli nieosiągnieto bliskiej wilgotności - zaświec diody // jeśli osiągnięto bliską wilgotność na 2 biegu zaświeć jedną i przciemnij drugą // jeśli osiągnięto wilgotność przyciemnij diody zależnie od biegu if (hum > hygrostatVal) { setFanSpeed(0); neoPixelSpeed_1 = 1; neoPixelSpeed_2 = 0; if (fanSpeedVal == 2) { neoPixelSpeed_2 = 1; } } else if (hum >= (hygrostatVal - 5) and fanSpeedVal == 2) { setFanSpeed(1); //ustaw predkość 1 zbliża sie do docelowej wartości neoPixelSpeed_1 = NON_ACTIVE_LED_DIVIDER; neoPixelSpeed_2 = 1; } else if (hum < hygrostatVal) { setFanSpeed(fanSpeedVal); neoPixelSpeed_1 = NON_ACTIVE_LED_DIVIDER; if (fanSpeedVal == 1) { neoPixelSpeed_2 = 0; } else { neoPixelSpeed_2 = NON_ACTIVE_LED_DIVIDER; } } if (dimmStep == 0) { dimmVal = 0; } else if (dimmStep == 1) { dimmVal = 1; } else if (dimmStep == 2) { dimmVal = 6; } else if (dimmStep == 3) { dimmVal = 12; } else { dimmVal = 24; } // Ustawianie LED docelowych wartości if (hygrostatVal >= 65) { neoPixelLvl_1 = 1; neoPixelLvl_2 = 1; neoPixelLvl_3 = 1; neoPixelLvl_4 = 1; neoPixelLvl_5 = 1; } else if (hygrostatVal == 60) { neoPixelLvl_1 = 1; neoPixelLvl_2 = 1; neoPixelLvl_3 = 1; neoPixelLvl_4 = 1; neoPixelLvl_5 = 0; } else if (hygrostatVal == 55) { neoPixelLvl_1 = 1; neoPixelLvl_2 = 1; neoPixelLvl_3 = 1; neoPixelLvl_4 = 0; neoPixelLvl_5 = 0; } else if (hygrostatVal == 50) { neoPixelLvl_1 = 1; neoPixelLvl_2 = 1; neoPixelLvl_3 = 0; neoPixelLvl_4 = 0; neoPixelLvl_5 = 0; } else if (hygrostatVal == 45) { neoPixelLvl_1 = 1; neoPixelLvl_2 = 0; neoPixelLvl_3 = 0; neoPixelLvl_4 = 0; neoPixelLvl_5 = 0; } else if (hygrostatVal <= 40) { neoPixelLvl_1 = 0; neoPixelLvl_2 = 0; neoPixelLvl_3 = 0; neoPixelLvl_4 = 0; neoPixelLvl_5 = 0; } else { neoPixelLvl_1 = 1; neoPixelLvl_2 = 0; neoPixelLvl_3 = 1; neoPixelLvl_4 = 0; neoPixelLvl_5 = 1; } // Ustawianie LED osiągniętych wartości if (hum >= 65 && hygrostatVal >= 65 ) { neoPixelLvl_5 = 8; } if (hum >= 60 && hygrostatVal >= 60) { neoPixelLvl_4 = 8; } if (hum >= 55 && hygrostatVal >= 55) { neoPixelLvl_3 = 8; } if (hum >= 50 && hygrostatVal >= 50) { neoPixelLvl_2 = 8; } if (hum >= 45 && hygrostatVal >= 45) { neoPixelLvl_1 = 8; } // wartości zależne od sposobu zasilania PC/Powerbank/Ładowarka //46-47 - sonda nie dotyka wody //26 - ledwo na dnie // 25 jest troche wody // 24-25 połowa zbiornika // 23-24 pełen zbiornik if (waterLvlVal >= 38) { // Empty TANK neoPixelWaterLvlR = 10; neoPixelWaterLvlG = 0; neoPixelWaterLvlB = 0; analogWrite(LED_WHT_TANK, dimmVal * 8); analogWrite(LED_RED_TANK, 0); // tu set fan } if (waterLvlVal < 40 && waterLvlVal >= 25) { //a bit of water TANK neoPixelWaterLvlR = 10; neoPixelWaterLvlG = 10; neoPixelWaterLvlB = 0; analogWrite(LED_WHT_TANK, 0); analogWrite(LED_RED_TANK, dimmVal * 8); } if (waterLvlVal <= 24) { // FULL TANK neoPixelWaterLvlR = neoPixelRed; neoPixelWaterLvlG = neoPixelGreen; neoPixelWaterLvlB = neoPixelBlue; analogWrite(LED_WHT_TANK, 0); analogWrite(LED_RED_TANK, dimmVal * 8); // tu set fan } // if minął czas -> resetVal = 0; if (resetVal == 1) { neoPixelFilter = 0; } else { neoPixelFilter = 1; } delay(100); //NEOPIXELS // ################################################################# // ################################################################# pixels.clear(); //(G,R,B) pixels.setPixelColor(ADR_NEOPXL_SPEED_1, pixels.Color(int((neoPixelGreen * dimmVal * neoPixelSwitch * neoPixelSpeed_1) / NON_ACTIVE_LED_DIVIDER), int((neoPixelRed * dimmVal * neoPixelSwitch * neoPixelSpeed_1) / NON_ACTIVE_LED_DIVIDER), int((neoPixelBlue * dimmVal * neoPixelSwitch * neoPixelSpeed_1) / NON_ACTIVE_LED_DIVIDER))); pixels.setPixelColor(ADR_NEOPXL_SPEED_2, pixels.Color(int((neoPixelGreen * dimmVal * neoPixelSwitch * neoPixelSpeed_2) / NON_ACTIVE_LED_DIVIDER), int((neoPixelRed * dimmVal * neoPixelSwitch * neoPixelSpeed_2) / NON_ACTIVE_LED_DIVIDER), int((neoPixelBlue * dimmVal * neoPixelSwitch * neoPixelSpeed_2) / NON_ACTIVE_LED_DIVIDER))); pixels.setPixelColor(ADR_NEOPXL_FILTER, pixels.Color(neoPixelGreen * dimmVal * neoPixelSwitch * neoPixelFilter, neoPixelRed * dimmVal * neoPixelSwitch * neoPixelFilter, neoPixelBlue * dimmVal * neoPixelSwitch * neoPixelFilter)); pixels.setPixelColor(ADR_NEOPXL_L1, pixels.Color(int(neoPixelGreen * dimmVal * neoPixelSwitch * neoPixelLvl_1/ NON_ACTIVE_LED_DIVIDER), int(neoPixelRed * dimmVal * neoPixelSwitch * neoPixelLvl_1/ NON_ACTIVE_LED_DIVIDER), int(neoPixelBlue * dimmVal * neoPixelSwitch * neoPixelLvl_1 / NON_ACTIVE_LED_DIVIDER))); pixels.setPixelColor(ADR_NEOPXL_L2, pixels.Color(int(neoPixelGreen * dimmVal * neoPixelSwitch * neoPixelLvl_2/ NON_ACTIVE_LED_DIVIDER), int(neoPixelRed * dimmVal * neoPixelSwitch * neoPixelLvl_2/ NON_ACTIVE_LED_DIVIDER), int(neoPixelBlue * dimmVal * neoPixelSwitch * neoPixelLvl_2 / NON_ACTIVE_LED_DIVIDER))); pixels.setPixelColor(ADR_NEOPXL_L3, pixels.Color(int(neoPixelGreen * dimmVal * neoPixelSwitch * neoPixelLvl_3/ NON_ACTIVE_LED_DIVIDER), int(neoPixelRed * dimmVal * neoPixelSwitch * neoPixelLvl_3/ NON_ACTIVE_LED_DIVIDER), int(neoPixelBlue * dimmVal * neoPixelSwitch * neoPixelLvl_3 / NON_ACTIVE_LED_DIVIDER))); pixels.setPixelColor(ADR_NEOPXL_L4, pixels.Color(int(neoPixelGreen * dimmVal * neoPixelSwitch * neoPixelLvl_4/ NON_ACTIVE_LED_DIVIDER), int(neoPixelRed * dimmVal * neoPixelSwitch * neoPixelLvl_4/ NON_ACTIVE_LED_DIVIDER), int(neoPixelBlue * dimmVal * neoPixelSwitch * neoPixelLvl_4 / NON_ACTIVE_LED_DIVIDER))); pixels.setPixelColor(ADR_NEOPXL_L5, pixels.Color(int(neoPixelGreen * dimmVal * neoPixelSwitch * neoPixelLvl_5/ NON_ACTIVE_LED_DIVIDER), int(neoPixelRed * dimmVal * neoPixelSwitch * neoPixelLvl_5/ NON_ACTIVE_LED_DIVIDER), int(neoPixelBlue * dimmVal * neoPixelSwitch * neoPixelLvl_5 / NON_ACTIVE_LED_DIVIDER))); pixels.setPixelColor(ADR_NEOPXL_WATERLVL, pixels.Color(dimmVal * neoPixelSwitch * neoPixelWaterLvlG, dimmVal * neoPixelSwitch * neoPixelWaterLvlR, dimmVal * neoPixelSwitch * neoPixelWaterLvlB)); // pixels.setPixelColor(ADR_NEOPXL_TANK, pixels.Color(neoPixelGreen*dimmVal*neoPixelSwitch*neoPixelTank, neoPixelRed*dimmVal*neoPixelSwitch*neoPixelTank, neoPixelBlue*dimmVal*neoPixelSwitch*neoPixelTank)); pixels.show(); // rainbowCycle(10); // im mniejsza liczba, tym szybsza animacja }