////////////////////////////////////////////////////////////////////////////////
// Official name:     Smelly Party Old                                        //
// Hardware platform: Smelly                                                  //
// Pin connections:   Arduino Mega 2560                                       //
// Created:           April 2016                                              //
// Created by:        HARB rboek2@gmail.com                                   //
// This program reads the TGS sensors and outputS the readings on Serial Mon. //
////////////////////////////////////////////////////////////////////////////////
// FUSES (can always be altered f.e. by using the STK500)                     //
// On-Chip Debug Enabled: off                            (OCDEN=0)            //
// JTAG Interface Enabled: off                           (JTAGEN=0)           //
// Preserve EEPROM mem through the Chip Erase cycle: On  (EESAVE = 0)         //
// Boot Flash section = 2048 words, Boot startaddr=$3800 (BOOTSZ=00)          //
// Boot Reset vector Enabled, default address=$0000      (BOOTSTR=0)          //
// CKOPT fuse (operation dependent of CKSEL fuses        (CKOPT=0)            //
// Brown-out detection level at VCC=2,7V;                (BODLEVEL=1)         //
// Ext. Cr/Res High Freq.; Start-up time: 16K CK + 64 ms (CKSEL=1111 SUT=11)  //
// LOCKBITS (are dangerous to change, since they cannot be reset)             //
// Mode 1: No memory lock features enabled                                    //
// Application Protect Mode 1: No lock on SPM and LPM in Application Section  //
// Boot Loader Protect Mode 1: No lock on SPM and LPM in Boot Loader Section  //
////////////////////////////////////////////////////////////////////////////////
// EEPROM MEMORY MAP:                                                         //
// Start End  Number Description                                              //
// 0000  0000      1 Never use this memory location to be AVR compatible      //
////////////////////////////////////////////////////////////////////////////////
// PIN ALLOCATIONS                                                            //
// Prog=List=Chip                                                             //
// A0  = 97 = PF0 ADC0             = TGS 01 analog input MQ 7             ADC //
// A1  = 96 = PF1 ADC1             = TGS 02 analog input MQ 135           ADC //
// A2  = 95 = PF2 ADC2             = TGS 03 analog input MQ 5             ADC //
// A3  = 94 = PF3 ADC3             =                                      ADC //
// A4  = 93 = PF4 ADC4/TMK         =                                      ADC //
// A14 = 83 = PK6 ADC14/PCINT22    =                                      ADC //
// A15 = 82 = PK7 ADC15/PCINT23    =                                      ADC //
// 0   =  2 = PE0 RXD0/PCINT8      = Serial monitor, also on-board LED    RX0 //
// 1   =  3 = PE1 TXD0             = Serial monitor, also on-board LED    TX0 //
// 2   =  6 = PE4 OC3B/INT4        = Tgs01 Digital alarm signal input     INT //
// 3   =  7 = PE5 OC3C/INT5        = Tgs02 Digital alarm signal input     INT //
// 4   =  1 = PG5 OCOB             = Tgs03 Digital alarm signal input     PWM //
// 5   =  5 = PE5 OC3A/AIN1        = Tgs etc                              PWM //
// 12  = 25 = PB6 OC1B/PCINT6      =                                      PWM //
// 13  = 26 = PB7 OCOA/OC1C/PCINT7 = On board user LED, on=high off=low   PWM //
// 18  = 46 = PD2 TXD1/INT3        =                                      TX1 //
// 19  = 45 = PD2 RXD1/INT2        =                                      RX1 //
// 20  = 44 = PD1 SDA/INT1         =                                      TWI //
// 21  = 43 = PD0 SCL/INT0         =                                      TWI //
// 44  = 40 = PL5 OC5C             =                                      PWM //
// 45  = 39 = PL4 OC5B             =                                      PWM //
// 46  = 38 = PL3 OC5A             =                                      PWM //
// 50  = 22 = PB3 MISO/PCINT3      =                                      SPI //
// 51  = 21 = PB2 MOSI/PCINT2      =                                      SPI //
// 52  = 20 = PB1 SCK/PCINT1       =                                      SPI //
// 53  = 19 = PB1 SS/PCINT0        =                                      SPI //
////////////////////////////////////////////////////////////////////////////////

// SET PRECOMPILER OPTIONS *****************************************************

// Initialse conditional compiling, uncomment to include, comment to exclude ---
// #define RS232 1                 //Include RS232 sections to output debug info
// #ifdef RS232        //Only include this part if the variable has been defined

// Define precompiler variables ------------------------------------------------
#define LED   PB7         //Arduino boards contain an onboard LED, equals pin 13
#define TGS08  A8                  //Define the analog input pin connected to MQ
#define TGS07  A9                  //Define the analog input pin connected to MQ
#define TGS06 A10                  //Define the analog input pin connected to MQ
#define TGS05 A11                  //Define the analog input pin connected to MQ
#define TGS04 A12                  //Define the analog input pin connected to MQ
#define TGS03 A13                  //Define the analog input pin connected to MQ
#define TGS02 A14                  //Define the analog input pin connected to MQ
#define TGS01 A15                  //Define the analog input pin connected to MQ

///Define the needed header files for the precompiler, no charge if not used ---
#include <SPI.h>                            //Needed to communicate with SD card
#include <SD.h>                     //Needed to work with file system on SD card
//#include <stdio.h>
#include <DS1302.h>         //Clock chip, library from Github written by msparks
//#include <IRremote.h>     //Do never use the default by the IDE but replace it
//#include <AFMotor.h>  //Motors shield, Copyright Adafruit Industries LLC, 2009
//#include <TimerOne.h>    //Currently needed for reading wheel speed per second


// Set the appropriate digital I/O pin connections. These are the pin
// assignments for the Arduino as well for as the DS1302 chip. See the DS1302
// datasheet:
//
//   http://datasheets.maximintegrated.com/en/ds/DS1302.pdf
const int kCePin   = 32;  // Chip Enable
const int kIoPin   = 34;  // Input/Output
const int kSclkPin = 36;  // Serial Clock

// Create a DS1302 object.
DS1302 rtc(kCePin, kIoPin, kSclkPin);

String dayAsString(const Time::Day day) {
  switch (day) {
    case Time::kSunday: return "Sunday";
    case Time::kMonday: return "Monday";
    case Time::kTuesday: return "Tuesday";
    case Time::kWednesday: return "Wednesday";
    case Time::kThursday: return "Thursday";
    case Time::kFriday: return "Friday";
    case Time::kSaturday: return "Saturday";
  }
  return "(unknown day)";
}



//DEFINE CONSTANTS AND VARIABLES -----------------------------------------------
// set up variables using the SD utility library functions:
Sd2Card card;
SdVolume volume;
SdFile root;
// change this to match your SD shield or module;
// Arduino Ethernet shield: pin 4
// Adafruit SD shields and modules: pin 10
// Sparkfun SD shield: pin 8
//const int chipSelect = 4;
const int chipSelect =  53;                     //Arduino mega: Chip select = 53
//const int RECV_PIN = 19;     //Connection of the IR remote TV control receiver
//3 COLOR LED breakout, common ground,      connect these pins preferably to PWM
/*-----( Declare Variables )-----*/
unsigned int anaVal01;      //AnalogRead will fill variable with a 10 bit number
unsigned int anaVal02;      //AnalogRead will fill variable with a 10 bit number
unsigned int anaVal03;      //AnalogRead will fill variable with a 10 bit number
unsigned int anaVal04;      //AnalogRead will fill variable with a 10 bit number
unsigned int anaVal05;      //AnalogRead will fill variable with a 10 bit number
unsigned int anaVal06;      //AnalogRead will fill variable with a 10 bit number
unsigned int anaVal07;      //AnalogRead will fill variable with a 10 bit number
unsigned int anaVal08;      //AnalogRead will fill variable with a 10 bit number
String dataLine = "";             //Declare an epmty string that will be written
String timeNow = "";
//END OF PRECOMPILER OPTIONS ---------------------------------------------------

void toggle_led(void) { //Toggles the default on-board LED on or off ***********
  if bit_is_clear(PORTB, LED)                           //Test if the LED is off
    PORTB |= (1 << LED);                           //If LED=off then turn LED on
  else                                                 //Else the LED must be on
    PORTB &= ~(1 << LED);                                //Then turn the LED off
} //Exit toggle_led -- Or fe: state = !state; ----------------------------------


void printTime() {
  Time t = rtc.time();             //Get the current time and date from the chip
  char buf[50]; // Format the time and date and insert into the temporary buffer
  snprintf(buf, sizeof(buf), "%04d-%02d-%02d %02d:%02d:%02d, ",
           t.yr, t.mon, t.date,
           t.hr, t.min, t.sec);
  timeNow = (buf);
}

void setup() { //Setup runs once ***********************************************
  DDRB |= (1 << LED);                            //Set onboard LED-pin as output
  PORTB |= (1 << LED);                               //Initally onboard LED = on
  Serial.begin(9600);   //Nothing more needed for the Serial Monitor to function
  Serial.println("Smelly Gas Sensor brick test");
  Serial.println("Initializing SD card...");
  // we'll use the initialization code from the utility libraries
  // since we're just testing if the card is working!
  if (!card.init(SPI_HALF_SPEED, chipSelect)) {
    Serial.println("initialization failed. Things to check:");
    Serial.println("* is a card inserted?");
    Serial.println("* is your wiring correct?");
    Serial.println("* did you change the chipSelect pin to match your shield or module?");
    return;
  } else {
    Serial.println("Wiring is correct and a card is present.\n");
  }

  // print the type of card
  Serial.print("Card type: ");
  switch (card.type()) {
    case SD_CARD_TYPE_SD1:
      Serial.println("SD1");
      break;
    case SD_CARD_TYPE_SD2:
      Serial.println("SD2");
      break;
    case SD_CARD_TYPE_SDHC:
      Serial.println("SDHC");
      break;
    default:
      Serial.println("Unknown");
  }

  // Now we will try to open the 'volume'/'partition' - it should be FAT16 or FAT32
  if (!volume.init(card)) {
    Serial.println("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card");
    return;
  }
  // print the type and size of the first FAT-type volume
  uint32_t volumesize;
  Serial.print("Volume type is FAT");
  Serial.println(volume.fatType(), DEC);

  volumesize = volume.blocksPerCluster();    // clusters are collectio ns of blocks
  volumesize *= volume.clusterCount();       // we'll have a lot of clusters
  volumesize *= 512;                            // SD card blocks are always 512 bytes
  Serial.print("Volume size (bytes): ");
  Serial.println(volumesize);
  Serial.print("Volume size (Kbytes): ");
  volumesize /= 1024;
  Serial.println(volumesize);
  Serial.print("Volume size (Mbytes): ");
  volumesize /= 1024;
  Serial.println(volumesize);

  Serial.println("\nFiles found on the card (name, date and size in bytes): ");
  root.openRoot(volume);

  // list all files in the card with date and size
  root.ls(LS_R | LS_DATE | LS_SIZE);
  Serial.println();

  if (!SD.begin(53)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");
} //--(End of setup )-----------------------------------------------------------


void loop() { //KEEP ON RUNNING THIS LOOP FOREVER ******************************
  if (SD.exists("DATALOG.TXT")) {
    //Serial.println("DATALOG.TXT exists.");
  } else {
    Serial.println("DATALOG.TXT doesn't exist.");
    // open a new file and immediately close it:
    Serial.println("Creating DATALOG.TXT...");
    Serial.println();
    File myFile = SD.open("DATALOG.TXT", FILE_WRITE);
    myFile.close();
  }

  printTime();
  dataLine = (timeNow);                                //Empty the line to write
  for (int analogPin = 15; analogPin > 7; analogPin--) {
    int sensor = analogRead(analogPin);
    dataLine += String(sensor);
    if (analogPin > 8) {
      dataLine += ",";
    }
  }
  Serial.println(dataLine);                   //Print to the serial port as well
  File dataFile = SD.open("DATALOG.TXT", FILE_WRITE);       //Should create file
  if (dataFile) {                        //If the file is available, write to it
    dataFile.println(dataLine);
    dataFile.close();
  } else {                             //If the file isn't open, pop up an error
    Serial.println("error opening DATALOG.TXT");
  }
  delay(60000);                                            //Wait for 60 seconds
  toggle_led();                     //Toggles the default on-board LED on or off
} //End of void loop()                       //KEEP ON RUNNING THIS LOOP FOREVER
//345678911234567892123456789312345678941234567895123456789612345678971234567898