#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "DHTesp.h"
/*
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include "FS.h"
#include "SD.h"
#include "SPI.h"
const char* ssid = "ESP_RinduDendam";
const char* password = "test123";
*/
//multiplexer
#define COM 35
#define S0 26
#define S1 25
#define S2 33
#define S3 32
const uint8_t controlPins[4] = {S0, S1, S2, S3};
const int channels[16][4] = {
{0, 0, 0, 0}, //channel 0 (moist sensor 8)
{1, 0, 0, 0}, //channel 1 (moist sensor 7)
{0, 1, 0, 0}, //channel 2 (moist sensor 6)
{1, 1, 0, 0}, //channel 3 (moist sensor 5)
{0, 0, 1, 0}, //channel 4 (moist sensor 4)
{1, 0, 1, 0}, //channel 5 (moist sensor 3)
{0, 1, 1, 0}, //channel 6 (moist sensor 2)
{1, 1, 1, 0}, //channel 7 (moist sensor 1)
{0, 0, 0, 1}, //channel 8 (relay selenoid 8)
{1, 0, 0, 1}, //channel 9 (relay selenoid 7)
{0, 1, 0, 1}, //channel 10 (relay selenoid 6)
{1, 1, 0, 1}, //channel 11 (relay selenoid 5)
{0, 0, 1, 1}, //channel 12 (relay selenoid 4)
{1, 0, 1, 1}, //channel 13 (relay selenoid 3)
{0, 1, 1, 1}, //channel 14 (relay selenoid 2)
{1, 1, 1, 1} //channel 15 (relay selenoid 1)
};
//end multiplexer
//shift register output
#define DS 21
#define STCP 22
#define SHCP 23
//mini sd card
#define sdSCK 14
#define sdDO 12
#define sdDI 13
#define sdCS 15
#define sonicECHO 18
#define sonicTRG 19
#define dhtSDA 27
int stateNutrientTank = 0;
int calibrateMoistSensor[8][2] = {
{1680, 3620},
{1680, 3620},
{1680, 3620},
{1680, 3620},
{1680, 3620},
{1680, 3620},
{1680, 3620},
{1680, 3620}
};
DHTesp dhtSensor;
int stateMoistSensor[8];
bool stateRelayWater = false;
bool stateRelayNutrient = false;
bool nutrientTankReady = false;
int nutrientTankLevel = 0;
const int tankMax = 200;
const int tankMin = 0;
//byte data = 0;
//shift register
const int numRegPin = 16;
bool registers[numRegPin];
const int waterPumpPin = 9;
const int nutrientPumpPin = 8;
/*
AsyncWebServer server(80);
void initMicroSD() {
if (!SD.begin()) {
Serial.println("init failed!");
return;
}
uint8_t cardType = SD.cardType();
if (cardType == CARD_NONE) {
Serial.println("no SD card");
}
Serial.println("SD card type: ");
if (cardType == CARD_MMC) {
Serial.println("MMC");
}
else if (cardType == CARD_SD) {
Serial.println("SDSC");
}
else if (cardType == CARD_SDHC) {
Serial.println("SDHC");
}
else {
Serial.println("UNKNOWN");
}
uint64_t cardSize = SD.cardSize() / (1024 * 1024);
Serial.println("SD card size : %11uMB\n", cardSize);
}
void initWiFi() {
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.print("Connectin to WiFi network");
while (WiFi.status() != WL_CONNECTED) {
Serial.println(".");
delay(2000);
}
Serial.println(WiFi.localIP());
}
*/
float readMux(int channel) {
for (int i = 0; i < 4; i ++) {
digitalWrite(controlPins[i], channels[channel][i]);
}
delay(10);
return analogRead(COM);
}
void clearRegister() {
for (int i = numRegPin - 1; i >= 0; i--) {
registers[i] = LOW;
}
}
void setRegister(int pin, int val) {
registers[pin] = val;
}
void writeRegister() {
digitalWrite(STCP, LOW);
for (int i = numRegPin - 1; i >= 0; i--) {
digitalWrite(SHCP, LOW);
digitalWrite(DS, registers[i]);
digitalWrite(SHCP, HIGH);
}
digitalWrite(STCP, HIGH);
}
void taskMoistSensor(void *parameter) {
while (1) {
for (int i = 0; i < 8; i++) {
int min = calibrateMoistSensor[i][0];
int max = calibrateMoistSensor[i][1];
stateMoistSensor[i] = map(readMux(i), max, min, 0, 100);
Serial.println("Sensor " + String(i) + " : " + String(stateMoistSensor[i]));
}
Serial.println("...");
vTaskDelay(1000);
}
}
void taskDHTSensor(void *parameter) {
while (1) {
TempAndHumidity dhtData = dhtSensor.getTempAndHumidity();
Serial.println("Temp: " + String(dhtData.temperature, 2) + "°C");
Serial.println("Humidity: " + String(dhtData.humidity, 1) + "%");
Serial.println("---");
vTaskDelay(1000);
}
}
void taskSonicSensor(void *parameter) {
while (1) {
digitalWrite(sonicTRG, HIGH);
delay(10);
digitalWrite(sonicTRG, LOW);
int distance = pulseIn(sonicECHO, HIGH) * 0.17418;
Serial.println("distance :" + String(distance));
nutrientTankLevel = map(distance, 3000, 0, 0, 100);
Serial.println("tankLevel :" + String(nutrientTankLevel) + "%");
if (nutrientTankLevel > 90) { //water level full
nutrientTankReady = true; //after button ready pushed
stateRelayNutrient = true;
stateRelayWater = false;
} else if (nutrientTankLevel < 10) {
stateRelayWater = true;
stateRelayNutrient = false;
nutrientTankReady = false;
} else {}
vTaskDelay(1000);
}
}
void taskRelay(void *parameter) {
while (1) {
bool stateFieldWet = true;
for (int i = 0; i < 8; i++) {
if (nutrientTankReady == true) {
if (stateMoistSensor[i] < 50) {
setRegister(i, HIGH);
stateFieldWet = false;
} else if (stateMoistSensor[i] > 90) {
setRegister(i, LOW);
} else {}
} else if (stateRelayWater == true) {
setRegister(i, LOW);
} else {}
}
if (stateRelayWater == true) {
setRegister(8, HIGH);
setRegister(9, LOW);
} else {
setRegister(8, LOW);
}
if (nutrientTankReady == true && stateFieldWet == false) {
setRegister(9, HIGH);
setRegister(8, LOW);
} else {
setRegister(9, LOW);
}
writeRegister();
vTaskDelay(1000);
}
}
void setup() {
Serial.begin(115200);
Serial.println("System Online ...");
pinMode(S0, OUTPUT);
pinMode(S1, OUTPUT);
pinMode(S2, OUTPUT);
pinMode(S3, OUTPUT);
pinMode(DS, OUTPUT);
pinMode(STCP, OUTPUT);
pinMode(SHCP, OUTPUT);
pinMode(sonicECHO, INPUT);
pinMode(sonicTRG, OUTPUT);
pinMode(dhtSDA, INPUT);
digitalWrite(S0, LOW);
digitalWrite(S1, LOW);
digitalWrite(S2, LOW);
digitalWrite(S3, LOW);
dhtSensor.setup(dhtSDA, DHTesp::DHT22);
clearRegister();
/*
initMicroSD();
initWiFi();
server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
request->send(SD, "index.html", "text/html");
});
server.serveStatic("/", SD, "/");
server.begin();
*/
xTaskCreatePinnedToCore(
&taskMoistSensor, //fnction
"moistSensor", //task name
1000, //Stack size in bytes
NULL, //parameter
0, //priority
NULL, //Task handle
0 //core where task to run
);
xTaskCreatePinnedToCore(
&taskSonicSensor,
"sonicSensor",
1000,
NULL,
0,
NULL,
0
);
xTaskCreatePinnedToCore(
&taskRelay,
"taskRelay",
1000,
NULL,
0,
NULL,
1
);
xTaskCreatePinnedToCore(
&taskDHTSensor,
"taskDHTSensor",
1000,
NULL,
0,
NULL,
1
);
}
void loop() {
// put your main code here, to run repeatedly:
delay(10); // this speeds up the simulation
}