/*
Demo 4 – Telemetry: Multiple Wireless Transmitters, One Datalogger   
  For Instructable: Arduino Data Logging Shield With Real Time Clock Timestamp ... and Telemetry, Sensor Network
  Link: https://www.instructables.com/Arduino-Data-Logging-Shield-With-Real-Time-Clock-T/
  Youtube video demonstration: https://youtu.be/NPI2uSaAMdw
  By JD_K April 2023

** This is the sketch for the SERVER that RECEIVES data from multiple clients

Uses ARduino, DS1307, microSD card reader module, nRF24L01, etc.
*/


#include "uRTCLib.h"
 uRTCLib rtc;

// ***  Code for the nRF24L01_ based on the RadioHead library - nrf24_reliable_datagram_server
#include <RHReliableDatagram.h>
#include <RH_NRF24.h>
#include <SPI.h>

// SERVER_ADDRESS is the address of this Arduino which is receiving data from multiple clients
#define SERVER_ADDRESS 1

// Singleton instance of the radio driver
RH_NRF24 driver;

// Class to manage message delivery and receipt, using the driver declared above
RHReliableDatagram manager(driver, SERVER_ADDRESS);

uint8_t data[] = "OK";
uint8_t buf[RH_NRF24_MAX_MESSAGE_LEN];


// Library for the microSD card reader
#include <SD.h>
int CSpin = 9;


void setup() {
  Serial.begin(9600);

  // *** uRTCLib code
URTCLIB_WIRE.begin();
  // rtc.set(0, 13, 18, 7, 12, 12, 20);
  //  RTCLib::set(byte second, byte minute, byte hour, byte dayOfWeek, byte dayOfMonth, byte month, byte year)
  

  // *** nRF24L01 code
  if (!manager.init()) 
    Serial.println(F("nRF24L01 init failed"));
  // Defaults after init are 2.402 GHz (channel 2), 2Mbps, 0dBm
// *** End the nRF24L01 code for the set up


  // *** Setup: Initiallizing the SD card Reader
  Serial.println(F("Initializing Card"));
  pinMode(CSpin, OUTPUT); // the "CS_pin" this is toggled high or low when you are reding or writing to the SD card because other devices could be connected via SPI

  //Check if card is ready
  if (!SD.begin(CSpin))
  {
    Serial.println(F("Card Failed"));
delay (100);
    return; //this command will end the whole sketch
  }
   Serial.println(F("Card Ready"));


  //Write Log File Header
  File logFile = SD.open("LOG4.csv", FILE_WRITE);
  if (logFile)
  {
    logFile.println(F(", , , , ,")); // Just a leading blank line, in case there was previous data
    logFile.println(F("Month,Day,Hour,Minutes,Seconds,Sender,Celcius,LDR"));
    logFile.close();
    Serial.println(F("Month,Day,Hour,Minutes,Seconds,Sender,Celcius,LDR"));
  }
  else
  {
    Serial.println(F("Could not open command file to print header."));
    return;
  }
// ***  End the SD card reader code in the setup
}


void loop()
{
  // *** nRF24L01 code in the Loop
if (manager.available())
  {
    // Wait for a message addressed to us from the client
    uint8_t len = sizeof(buf);
    uint8_t from;
    rtc.refresh();   // Accesses time and date from RTC to be later logged in with the data
    if (manager.recvfromAck(buf, &len, &from))
    {
      Serial.print(F("Request from : 0x"));
      Serial.print(from, HEX);
      Serial.print(F(": "));
      Serial.println((char*)buf);

//Prepare a string in CSV format so that it can then be uplaoded to the log file
// This part is from STRINGS for Video from Kevin Durah, 7th Lesson: https://www.youtube.com/watch?v=tCJgnBI1D5o
    char dataToLog[25]; // this is where we store the new string; for 5 integers and the string for the float in the next line, the minimum is 19 elements
    
 if (from == 2) {
    sprintf(dataToLog, "%i,%i,%i,%i,%i,%i,%s,%s", rtc.month(), rtc.day(), rtc.hour(), rtc.minute(), rtc.second(),2, ((char*)buf), " "); //using sprintf() function
// %b is for a byte; others could be %s = a string (if wanting a keyword), %i = integer, %li = long integer, %s = a string again
 } else if (from == 3) {
    sprintf(dataToLog, "%i,%i,%i,%i,%i,%i,%s,%s", rtc.month(), rtc.day(), rtc.hour(), rtc.minute(), rtc.second(),3, " ",((char*)buf)); //using sprintf() function
 }
    Serial.print(F("Data to log: "));
    Serial.println(dataToLog); // print it all out as one string to show that it worked

  //Open a file to write to; Only one file can be open at a time
  File logFile = SD.open("LOG4.csv", FILE_WRITE); //this will open a new file if this does not exist already, or open the existing file of the same name
  if (logFile)
  {
    logFile.println(dataToLog); // logging the data 
    logFile.close();
    uint8_t flush_rx (); //clear buf in case the data is missed next time around
//    Serial.println(dataToLog);
  }
  else
  {
    Serial.println(F("Could not open log file to record date"));
  }
  
      // Send a reply back to the originator client
      if (!manager.sendtoWait(data, sizeof(data), from))
        Serial.println(F("sendtoWait failed"));
    }  
      // *** End of the nRF24L01 code in the Loop
}
}
