#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_ADS1015.h>
#include "FS.h"
#include "SD.h"
#include "SPI.h"
#include "RTClib.h"  

#define RXD2 33
#define TXD2 2

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

#define FC   4

int ledPin7 = 26;
int ledPin8 = 27;

int  buttonState = 0;
const int buttonPin = 32;

Adafruit_ADS1115 ads1(0x48);
Adafruit_ADS1115 ads2(0x49);

float Voltage1 = 0.0;
float Voltage2 = 0.0;
float Voltage3 = 0.0;
float Voltage4 = 0.0;
float Voltage5 = 0.0;
float Voltage6 = 0.0;

RTC_DS3231 rtc; 

char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

static const uint8_t image_data_Saraarray[1024] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc0, 0x01, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x3f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf8, 0x00, 0x00, 0x0f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x03, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x01, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x1f, 0xfc, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x3f, 0xfe, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x7f, 0xff, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0xff, 0xff, 0x80, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0xfc, 0x1f, 0x80, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0xf8, 0x0f, 0x80, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0xf8, 0x07, 0x80, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0xf0, 0x07, 0x80, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0xf0, 0x07, 0x80, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0xf0, 0x07, 0x80, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0xf0, 0x07, 0x80, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0xf0, 0x07, 0x80, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0xf0, 0x07, 0x80, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0xf0, 0x07, 0x80, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0xf0, 0x07, 0x80, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0xf0, 0x07, 0x80, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0xf0, 0x07, 0x80, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0xf0, 0x07, 0x80, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0xf0, 0x07, 0x80, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0xf0, 0x07, 0x80, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0xf0, 0x07, 0x80, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0xf0, 0x07, 0x80, 0x03, 0xf8, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0xf0, 0x07, 0x80, 0x07, 0xf8, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xd8, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x01, 0xe3, 0x80, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf8, 0x00, 0x00, 0x1f, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x7c, 0x00, 0x00, 0x7f, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x3c, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0f, 0x01, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x3f, 0xe1, 0xe0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x7f, 0xf1, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xf8, 0xf9, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xe0, 0x79, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x39, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x39, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};


Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

void setup() {
                                                    

  ads1.begin();
  ads2.begin();  
  Serial.begin(9600);                              // set serial communication baudrate
  Serial2.begin(9600, SERIAL_8N1, RXD2, TXD2);
  pinMode(34, INPUT);
  pinMode(35, INPUT);
  pinMode(13, INPUT);
  pinMode(21, INPUT);
  pinMode(22, INPUT);
  pinMode(15, INPUT);
  pinMode(buttonPin,INPUT);
 
  pinMode(ledPin7, OUTPUT);
  pinMode(ledPin8, OUTPUT);
  pinMode(FC , OUTPUT);  
  digitalWrite(FC , HIGH);    

  Wire.begin(16, 17);                            // Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.clearDisplay();
  display.display();

  display.drawBitmap(0, 0, image_data_Saraarray, 128, 64, 1);
  display.display();
  delay(2000);
  display.clearDisplay();
  display.display();

  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(15, 15);
  display.println("NORVI IIOT-AE04-V");
  display.setCursor(45, 30);
  display.println("HELLO...");
  display.setCursor(25, 45);
  display.println("Test code V1.0");
  display.display();
  delay(2000);
  display.clearDisplay();
  display.display();


 if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    display.setTextSize(1);
    display.setTextColor(WHITE);
    display.setCursor(15,15);
    display.println("Couldn't find RTC");
    display.display();
    delay(2000);
    display.clearDisplay();
    display.display();
 }
 else{
 if (rtc.lostPower()) {
  
    display.setTextSize(1);
    display.setTextColor(WHITE);
    display.setCursor(25, 15);
    display.println("RTC lost power");
    display.setCursor(30, 35);
    display.println("Set the time!");
    Serial.println("RTC lost power, lets set the time!");
    display.display();
    delay(3000);
    display.clearDisplay();
    display.display();
 
    // If the RTC have lost power it will sets the RTC to the date & time this sketch was compiled in the following line
    // set time from computer time
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2021, 3, 30, 11, 55, 0));
  }

  rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); 
  int a=1;
  while(a<6)
 {
  displayTime();   // printing time function for oled
  a=a+1;
}
 }
  display.display();
  delay(2000);

  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0, 5);
  uint8_t cardType = SD.cardType();
  
  if(SD.begin())
{
  Serial.println("Card Mount: success");
  display.println("Card Mount: success");
  display.setCursor(0, 20);
  Serial.print("Card Type: ");
  display.print("Card Type: ");

  display.setCursor(65,20 );
    if(cardType == CARD_MMC){
        Serial.println("MMC");
        display.println("MMC");
    } else if(cardType == CARD_SD){
        Serial.println("SDSC");
        display.println("SDSC");
    } else if(cardType == CARD_SDHC){
        Serial.println("SDHC");
        display.println("SDHC");
    } else {
        Serial.println("Unknown");
        display.println("Unknown");
    }

  display.setCursor(0, 35);
  int cardSize = SD.cardSize() / (1024 * 1024);
  Serial.printf("Card Size: %lluMB\n", cardSize);
  display.println("Card Size:");
  display.setCursor(65,35);
  display.println(cardSize);
}

  if(!SD.begin())
{
  display.setCursor(35, 15);
  Serial.println("NO SD card");  
  display.println("NO SD card");           
}

display.display();
delay(3500);
display.clearDisplay();
display.display();
delay(1000);
}

void loop()
{
  display.clearDisplay();
  update();
  digitalWrite(ledPin7, HIGH);
  update();
  digitalWrite(ledPin7, LOW);
  digitalWrite(ledPin8, HIGH);
  update();
  digitalWrite(ledPin8, LOW);
}

void update()
{
  float adc0;
  float adc1;
  float adc2;
  float adc3;
  float adc4;
  float adc5;
  
  adc0 = ads1.readADC_SingleEnded(0);
  adc1 = ads1.readADC_SingleEnded(1);
  adc2 = ads1.readADC_SingleEnded(2);
  adc3 = ads1.readADC_SingleEnded(3);  
  adc4 = ads2.readADC_SingleEnded(0);
  adc5 = ads2.readADC_SingleEnded(1);

  Voltage1 = (adc0 * 0.1875) / 1000;
  Voltage2 = (adc1 * 0.1875) / 1000;
  Voltage3 = (adc2 * 0.1875) / 1000;
  Voltage4 = (adc3 * 0.1875) / 1000;
  Voltage5 = (adc4 * 0.1875) / 1000;
  Voltage6 = (adc5 * 0.1875) / 1000;
  
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0, 5);
  display.println("V1");
  display.setCursor(0, 15);
  display.println("V2");
  display.setCursor(0, 25);
  display.println("V3");
  display.setCursor(0, 35);
  display.println("V4");
  display.setCursor(0, 45);
  display.println("V5");
  display.setCursor(0, 55);
  display.println("V6");
  
  display.setCursor(75, 0);
  display.println("Inputs");
  display.setCursor(60, 12);
  display.println(digitalRead(34));
  display.setCursor(70, 12);
  display.println(digitalRead(35));
  display.setCursor(80, 12);
  display.println(digitalRead(13));
  display.setCursor(90, 12);
  display.println(digitalRead(21));
  display.setCursor(100, 12);
  display.println(digitalRead(22));
  display.setCursor(110, 12);
  display.println(digitalRead(15));


  display.setCursor(75, 25);
  display.println("T1");
  display.setCursor(78, 35);
  display.println(digitalRead(26));


  display.setCursor(90, 25);
  display.println("T2");
  display.setCursor(93, 35);
  display.println(digitalRead(27));
  
  display.setCursor(55, 45);
  display.println("Button State");
  buttonState = analogRead(buttonPin);
  delay(50);
  display.setCursor(85, 55);
  display.println(analogRead(buttonPin));
  
  display.setCursor(20,5);
  display.println(Voltage1 * 2.5);
  display.setCursor(20,15);
  display.println(Voltage2 * 2.5);
  display.setCursor(20,25);
  display.println(Voltage3 * 2.5);
  display.setCursor(20,35);
  display.println(Voltage4 * 2.5);
  display.setCursor(20,45);
  display.println(Voltage5 * 2.5);
  display.setCursor(20,55);
  display.println(Voltage6 * 2.5);
  display.display();
  display.clearDisplay();
  
                                                // Make FLOW CONTROL pin HIGH
  Serial2.println("RS485 SUCCESS");             // Send RS485 SUCCESS serially
  Serial2.flush();                              // Wait for transmission of data
  digitalWrite(FC, LOW) ;                       // Receiving mode ON
  delay(500);
  
  if (Serial2.available())
  {
    if (Serial2.read() == '5')                  // If 5 available change the LED status
    {
      digitalWrite(ledPin7, HIGH);
      digitalWrite(ledPin8, HIGH);
    }
    else
    {
      digitalWrite(ledPin7, LOW);
      digitalWrite(ledPin8, LOW);
    }
  }
 digitalWrite(FC , HIGH);  
 delay(500);
}

   
void displayTime(void) {
  DateTime now = rtc.now();
  display.setTextSize(1);             
  display.setTextColor(SSD1306_WHITE);       
 
  display.setCursor(10, 15);        
  display.print(now.year(), DEC);
  display.print('/');
  display.print(now.month(), DEC);
  display.print('/');
  display.print(now.day(), DEC);
  display.print(" ");
  display.print(daysOfTheWeek[now.dayOfTheWeek()]);

  display.setTextSize(2);
  display.setCursor(15, 30);  
  display.print(now.hour(), DEC);
  display.print(':');
  display.print(now.minute(), DEC);
  display.print(':');
  display.print(now.second(), DEC);
  display.println();
  delay(1000);
  display.display();
  display.clearDisplay();
}
