#include <SoftwareSerial.h>
#include <Wire.h>
#include <SHT31.h>
#define lsaddress 0x23 // I2C Address 0x23 of Light sensor.
#define shtAddress 0x44
SHT31 sht;
// RS485
#define TempandHumRE 14
#define TempandHumDE 12
#define PHRE 8
#define PHDE 7
const byte phaddress[] = {0x01, 0x03, 0x00, 0x00, 0x00, 0x01, 0x84, 0x0A};
const byte TempandHumaddress[] = {0x01 ,0x03 ,0x00 ,0x00 ,0x00 ,0x02 ,0xC4 ,0x0B};
byte TempandHum_values[20];
SoftwareSerial TempandHum_mod(2, 3);
byte PH_values[11];
SoftwareSerial PH_mod(4, 5);
// Light Sensor pin
uint8_t buf[4] = {0};
uint16_t data, data1;
float Lux;
// Relay pin
const int relayPin1 = 15; // Pump
const int relayPin2 = 2; // Valve 1
const int relayPin3 = 0; // Valve 2
// Water flow sensor
const int flowSensor1 = 4;
const int flowSensor2 = 16;
volatile int NbTopsFan[2] = {0};
int Calc[2] = {0};
void TCA9548A(uint8_t bus) {
Wire.beginTransmission(0x70); // TCA9548A address is 0x70
Wire.write(1 << bus); // send byte to select bus
Wire.endTransmission();
}
void SHT30Sensor() {
sht.begin(); // Initialize the SHT31 sensor without specifying the I2C address
Wire.setClock(100000);
uint16_t stat = sht.readStatus();
Serial.print(stat, HEX);
Serial.println();
}
// void RS485Sensor_TempandHum(){
// TempandHum_mod.begin();
// pinMode(TempandHumRE, OUTPUT);
// pinMode(TempandHumDE, OUTPUT);
// }
// void RS485Sensor_PH(){
// PH_mod.begin();
// pinMode(PHRE, OUTPUT);
// pinMode(PHDE, OUTPUT);
// }
void setup() {
// Start I2C communication with the Multiplexer
Wire.begin();
Serial.begin(115200);
Serial.println("\nESP32");
// Define pin mode of relay
pinMode(relayPin1, OUTPUT);
pinMode(relayPin2, OUTPUT);
pinMode(relayPin3, OUTPUT);
// Define pin mode of flow sensor
pinMode(flowSensor1, INPUT);
pinMode(flowSensor2, INPUT);
// Define interrupt
attachInterrupt(digitalPinToInterrupt(flowSensor1), rpm1, RISING);
attachInterrupt(digitalPinToInterrupt(flowSensor2), rpm2, RISING);
// Define digital write
digitalWrite(relayPin1, LOW);
digitalWrite(relayPin2, LOW);
digitalWrite(relayPin3, LOW);
// Activate the pump
pump(relayPin1);
// Activate the valves
valve(relayPin2);
valve(relayPin3);
// Set multiplexer to channel 1
// TCA9548A(1);
// Set the I2C address of the sensor
// TCA9548A(2);
// SHT30Sensor();
// Set RS485
// RS485Sensor_TempandHum();
// RS485Sensor_PH();
}
void loop() {
waterFlow(flowSensor1, 1);
waterFlow(flowSensor2, 2);
// Set multiplexer to channel 1 and display Light Sensor
// TCA9548A(1);
// lightSensor();
// Set multiplexer to channel 2 and display Temp Sensor
// TCA9548A(2);
// SHT30_sensor();
// Set RS485 sensor
// RS485Sensor_TempandHum();
}
// Function for water pump
void pump(int pumpPin) {
// Select the parameters for the water pump turn signal
static int pumpState = digitalRead(pumpPin);
// Pump working status
digitalWrite(pumpPin, (pumpState == HIGH) ? HIGH : LOW);
}
// Function for water valve
void valve(int valvePin) {
// Select the parameter for the water valve turn signal
static int valveState = digitalRead(valvePin);
// Valve working status
digitalWrite(valvePin, (valveState == HIGH) ? LOW : LOW);
}
void waterFlow(const int sensorPin, const int sensorNum) {
sei();
delay(1000);
cli();
Calc[sensorNum - 1] = (NbTopsFan[sensorNum - 1] * 60 / 7.5);
Serial.print("Water Flow ");
Serial.print(sensorNum);
Serial.print(": ");
Serial.print(Calc[sensorNum - 1], DEC);
Serial.println(" L/hour");
}
void rpm1() {
NbTopsFan[0]++;
}
void rpm2() {
NbTopsFan[1]++;
}
void lightSensor() {
readReg(0x10, buf, 2); // Register Address 0x10
data = buf[0] << 8 | buf[1];
Lux = (((float)data) / 1.2);
Serial.print("Lux: ");
Serial.print(Lux);
Serial.print(" lx");
Serial.print("\n");
delay(500);
}
uint8_t readReg(uint8_t reg, const void* pBuf, size_t size) {
if (pBuf == NULL) {
Serial.println("pBuf ERROR!! : null pointer");
}
uint8_t* _pBuf = (uint8_t*)pBuf; // Convert pointer const void* to uint8_t*
Wire.beginTransmission(lsaddress); // Start communication with device at address
Wire.write(®, 1); // Send register address data to device
if (Wire.endTransmission() != 0) { // End communication and check if successful
return 0;
}
delay(20); // Delay for stability
Wire.requestFrom(lsaddress, (uint8_t)size); // Request data from device to Arduino
for (uint16_t i = 0; i < size; i++) {
_pBuf[i] = Wire.read(); // Read data and store into buffer
}
return size; // Return size of data read to caller
}
void SHT30_sensor(){
sht.read();
Serial.print("Temperature: ");
Serial.print(sht.getTemperature(), 1);
Serial.print(" C");
Serial.print("\t");
Serial.print("Humidity: ");
Serial.print(sht.getHumidity(), 1);
Serial.println(" %");
delay(100);
}
void RS485Sensor_TempandHum(){
static float val1, val2 ;
val1 = ((TempandHum_values[5]*256)+Oxigen()) * 0.1;
val2 = ((TempandHum_values[3]*256)+TempandHum_values[4]) * 0.1;
Serial.print("ความชื้น: ");
Serial.print(val2);
Serial.println(" % ");
delay(2000);
}
byte Oxigen() {
digitalWrite(TempandHumDE, HIGH);
digitalWrite(TempandHumRE, HIGH);
delay(10);
if (TempandHum_mod.write(TempandHumaddress, sizeof(TempandHumaddress)) == 8) {
digitalWrite(TempandHumDE, LOW);
digitalWrite(TempandHumRE, LOW);
for (byte i = 0; i < 11; i++) {
//Serial.print(TempandHum_mod.read(),HEX);
TempandHum_values[i] = TempandHum_mod.read();
Serial.print(TempandHum_values[i], HEX);
Serial.print(" ");
}
Serial.println();
}
return TempandHum_values[6];
}
void RS485Sensor_PH(){
static byte val1, val2, val3;
static int ph, ph2;
val2 = Fphaddress();
delay(250);
ph = val2 / 10;
ph2 = val2 % 10;
Serial.print("PH: ");
Serial.print(ph);
Serial.print(".");
Serial.print(ph2);
Serial.println(" pH");
delay(2000);
}
byte Fphaddress() {
digitalWrite(PHDE, HIGH);
digitalWrite(PHRE, HIGH);
delay(10);
if (PH_mod.write(phaddress, sizeof(phaddress)) == 8) {
digitalWrite(PHDE, LOW);
digitalWrite(PHRE, LOW);
for (byte i = 0; i < 7; i++) {
PH_values[i] = PH_mod.read();
}
}
return PH_values[4];
}