#include <ESP32Servo.h>
#include <DHT.h>

/////For CAN////////
#include <mcp_can.h>
#include <SPI.h>
////////////////////
#define DHTTYPE DHT11
#define DHTPIN 4
#define R1 2    //L1
#define R2 5    //L2
#define R3 12   //L3
#define R4 13   //P1
#define R5 14   //P2
#define R6 15   //P3
#define R7 16   //P4
#define R8 17   //P5
#define R9 18   //FRESH TO AQUA
#define R10 19  //AQUA TO PLANT
#define R11 21  //EXIT FAN
#define R12 22  //HUMIDIFIER

#define SM1 36    //P1
#define SM2 39    //P2
#define SM3 34    //P3
#define SM4 35    //P4
#define SM5 32    //P5
///////////////////////
long unsigned int rxId;
unsigned char len = 0;
unsigned char rxBuf[8] = {0};
char msgString[128];                           // Array to store serial string

#define CAN0_INT 23                              // Set INT to GPIO4 for ESP32
MCP_CAN CAN0(33);                                // Set CS to GPIO33 for ESP32

// SPI pins for ESP32
#define SCK_PIN 25
#define MISO_PIN 26
#define MOSI_PIN 27
#define CS_PIN 33
/////////////////////
int A=0,skip=0;
int one[5]={0};

byte i = 0;
byte data[8] = {1, 1, 1, 1, 1, 1, 1, 1};
int c=0;

// Initialize DHT sensor
DHT dht(DHTPIN, DHTTYPE);

void can_set() {
  Serial.begin(115200);

  SPI.begin(SCK_PIN, MISO_PIN, MOSI_PIN, CS_PIN); // Initialize SPI bus with custom pins

  if (CAN0.begin(MCP_ANY, CAN_500KBPS, MCP_16MHZ) == CAN_OK)
    Serial.println("MCP2515 Initialized Successfully!");
  else
    Serial.println("Error Initializing MCP2515...");

  CAN0.setMode(MCP_NORMAL);                    // Change to normal mode to allow messages to be transmitted

  pinMode(CAN0_INT, INPUT_PULLUP);              // Configuring pin for /INT input with pull-up
}


void cancom() {

  byte sndStat;
  byte i;
  int valid=0;
  rxBuf[8] = {0};

    // while (digitalRead(CAN0_INT));
    if (!digitalRead(CAN0_INT)) {                          // If CAN0_INT pin is low, read receive buffer
      CAN0.readMsgBuf(&rxId, &len, rxBuf);                 // Read data: len = data length, buf = data byte(s)

      if ((rxId & 0x40) == 0x40) {            // Determine if message is a remote request frame
        sprintf(msgString, " REMOTE REQUEST FRAME");
        Serial.print(msgString);
        valid=1;
      }

      Serial.println();
  }
if(valid){
    for(int i=0;i<8;i++)
    {
      data[i] = 0;
    }
    float value = analogRead(SM1);
    float moisture_percentage = ( 100.00 - ( ( value/ 4096.00) * 100.00 ));
    data[0]=(int)moisture_percentage;
    // data[0]=12;


    value = analogRead(SM2);
    moisture_percentage = ( 100.00 - ( ( value/ 4096.00) * 100.00 ));
    data[1]=(int)moisture_percentage;
    // data[1]=24;

    value = analogRead(SM3);
    moisture_percentage = ( 100.00 - ( ( value/ 4096.00) * 100.00 ));
    data[2]=(int)moisture_percentage;
    // data[2]=95;

    value = analogRead(SM4);
    moisture_percentage = ( 100.00 - ( ( value/ 4096.00) * 100.00 ));
    data[3]=(int)moisture_percentage;
    // data[3]=63;

    value = analogRead(SM5);
    moisture_percentage = ( 100.00 - ( ( value/ 4096.00) * 100.00 ));
    data[4]=(int)moisture_percentage;
    // data[4]=22;

    float h = dht.readHumidity();
    data[5]=(int)h;
    // data[5]=30;

    float t = dht.readTemperature();
    data[6]=(int)t;
    // data[6]=51;
    data[7] = 0;

  if(skip == 1){
    skip = 0;
    sndStat = CAN0.sendMsgBuf(0x23, 8, data);  // Send data: ID = 0x23, Standard CAN Frame, Data length = 8 bytes, 'data' = array of data bytes to send
    if (sndStat == CAN_OK)
      Serial.println("Message Sent Successfully and received !");
    else
      Serial.println("Error Sending Message...");
  }


   while (digitalRead(CAN0_INT));
    if (!digitalRead(CAN0_INT)) {                          // If CAN0_INT pin is low, read receive buffer

      rxBuf[8] = {0};

      CAN0.readMsgBuf(&rxId, &len, rxBuf);                 // Read data: len = data length, buf = data byte(s)

      if ((rxId & 0x80000000) == 0x80000000)
        sprintf(msgString, "Extended ID: 0x%.8lX  DLC: %1d  Data:", (rxId & 0x1FFFFFFF), len);
      else
        sprintf(msgString, "Standard ID: 0x%.3lX       DLC: %1d  Data:", rxId, len);

      Serial.print(msgString);

      if ((rxId & 0x40) == 0x40) {            // Determine if message is a remote request frame
        sprintf(msgString, " REMOTE REQUEST FRAME");
        Serial.print(msgString);
        skip = 1;
      } else {
        skip=0;
        for (byte i = 0; i < len; i++) {
          sprintf(msgString, " 0x%.2X", rxBuf[i]);
          Serial.print(msgString);
        }
      }
  if(skip){
      Serial.println();

    //LIGHTS

      if(((int)rxBuf[0]==0))
      {
        digitalWrite(R1, HIGH);
        digitalWrite(R2, HIGH);
        digitalWrite(R3, HIGH);
      }

      if(((int)rxBuf[0]==1))
      {
        digitalWrite(R1, LOW);
      }
      else digitalWrite(R1, HIGH);

      if(((int)rxBuf[0]==2))
      {
        digitalWrite(R2, LOW);
      }
      else digitalWrite(R2, HIGH);

      if(((int)rxBuf[0]==3))
      {
        digitalWrite(R3, LOW);
      }
      else digitalWrite(R3, HIGH);

      if(((int)rxBuf[0]==4))
      {
        digitalWrite(R1, LOW);
        digitalWrite(R2, LOW);
        digitalWrite(R3, LOW);
      }

      //Plant 1
      if(((int)rxBuf[1]==1))
      {
        digitalWrite(R4, LOW);
        delay(2000);
        digitalWrite(R4, HIGH);
        delay(3000);
      }
      else digitalWrite(R4, HIGH);

      //Plant 2
      if(((int)rxBuf[2]==1))
      {
        digitalWrite(R5, LOW);
        delay(2000);
        digitalWrite(R5, HIGH);
        delay(3000);
      }
      else digitalWrite(R5, HIGH);

      //Plant 3
      if(((int)rxBuf[3]==1))
      {
        digitalWrite(R6, LOW);
        delay(2000);
        digitalWrite(R6, HIGH);
        delay(3000);
      }
      else digitalWrite(R6, HIGH);

      //Plant 4
      if(((int)rxBuf[4]==1))
      {
        digitalWrite(R7, LOW);
        delay(2000);
        digitalWrite(R7, HIGH);
        delay(3000);
      }
      else digitalWrite(R7, HIGH);

      //Plant 5
      if(((int)rxBuf[5]==1))
      {
        digitalWrite(R8, LOW);
        delay(2000);
        digitalWrite(R8, HIGH);
        delay(3000);
      }
      else digitalWrite(R8, HIGH);

      //Humidifier
      if(((int)rxBuf[6]==1))
      {
        digitalWrite(R11, LOW);
      }
      else digitalWrite(R11, HIGH);

      //Exit Fan
      if(((int)rxBuf[7]==1))
      {
        digitalWrite(R12, LOW);
      }
      else digitalWrite(R12, HIGH);

}
}
}
}

void setup()
{
  can_set();
  dht.begin(); // Initialize DHT sensor
  
  pinMode(R1, OUTPUT);
  pinMode(R2, OUTPUT);
  pinMode(R3, OUTPUT);
  pinMode(R4, OUTPUT);
  pinMode(R5, OUTPUT);
  pinMode(R6, OUTPUT);
  pinMode(R7, OUTPUT);
  pinMode(R8, OUTPUT);
  pinMode(R9, OUTPUT);
  pinMode(R10, OUTPUT);
  pinMode(R11, OUTPUT);
  pinMode(R12, OUTPUT);

  digitalWrite(R1, HIGH);
  digitalWrite(R2, HIGH);
  digitalWrite(R3, HIGH);
  digitalWrite(R4, HIGH);
  digitalWrite(R5, HIGH);
  digitalWrite(R6, HIGH);
  digitalWrite(R7, HIGH);
  digitalWrite(R8, HIGH);
  digitalWrite(R9, HIGH);
  digitalWrite(R10, HIGH);
  digitalWrite(R11, HIGH);
  digitalWrite(R12, HIGH);
}


void loop()
{
  cancom();
}
