////////////////////////////////////////////////////////////////////////////////
// Name:       Node03.ino                                                     //
//             01 = Allereerst wegpoetsen van Ping.                           //
//             02 = Een eerste poging om een temperatuur terug te zenden in   //
//                  plaats van het ontvangen commando. Radio instellingen     //
//                  toegevoegd.                                               //
//             03 = Meerdere sensoren in 1 antwoord proppen, max 32 bytea.    //
//                  Hardware omgebouwd naar schildje voor de Uno.             //
//             04 = 1 Gassensor toegevoegd                                    //
// http://robotigs.nl/robots/includes/parts.php?idpart=344                    //
// Een aangepaste versie van Pong                                             //
// Created by: HARB rboek2@gmail.com July 2020 GPL copyrights                 //
// Platform:   Arduino UNO R3                                                 //
////////////////////////////////////////////////////////////////////////////////
// As outputs the following modules are mounted:                              //
// - Standard Arduino Onboard LED (PWM)                                       //
//           http://robotigs.nl/robotigs/includes/parts_header.php?idpart=185 //
//                                                                            //
// As inputs the following modules are mounted:                               //
// - Temp DS18B20                                                             //
//           http://robotigs.nl/robotigs/includes/parts_header.php?idpart=180 //
//                                                                            //
// For communications and statistics are mounted:                             //
// - Standard Serial Monitor output                                           //
//            http://robotigs.nl/robotigs/includes/parts_header.php?idpart=43 //
// - LoRa NRF24L01+ unit                                                      //
//           http://robotigs.nl/robotigs/includes/parts_header.php?idpart=344 //
////////////////////////////////////////////////////////////////////////////////


  //Define the needed header files for the precompiler, no charge if not used --
  #include <SPI.h>      //Serial Peripheral Interface requiered by software LORA
                       // http://robotigs.nl/robots/includes/parts.php?idpart=28
  //#include <nRF24L01.h>                             //Lijkt nergens voor nodig
  #include <RF24.h>                             // https://github.com/nRF24/RF24
                       //TMRH20 Optimized high speed nRF24L01+ driver class LORA
                      // http://robotigs.nl/robots/includes/parts.php?idpart=344
  #include <printf.h>             //Needed to send to monitor radio.printDetails
  #include <DHT.h>   //Installeer vanuit Lib manager de Adafruit DHT sensor bieb
       //De Lib Manager vraagt zelf om het installeeren van de Adafruit toplayer
             // http://robotigs.nl/robotigs/includes/parts_header.php?idpart=252
  //#include <dht11.h> DHT zou de truc ook moeten kunnen doen.

  //Define PINS ----------------------------------------------------------------
  #define CE_PIN      8       //CE (Chip Enable) is an active-HIGH pin = SS LORA
  #define CSN_PIN     7        //CSN (Chip Select Not) is an active-LOW pin LORA
  #define ledGrePin   5                                             //Groene LED
  #define ledRedPin   6                                               //Rode LED
  #define DHTPIN      4                     //Which DIO input pin connects DHT22
  #define DHTTYPE DHT11       //What sensor is connected (AM2302) (AM2321) DHT22
  #define buzActPin   2                      //Dio pin for annoying sound BUZZER
  #define gasAdcPin  A0                            //ADC pin for gassensor MQGAS

  //Define EEPROM variables ----------------------------------------------------
  //Define DATABASE VARIABLES --------------------------------------------------
  //Define variables -----------------------------------------------------------
  int           ledOnBoardVal  = LOW;       //HIGH-on or LOW-off for LED_BUILTIN
  unsigned long countOk        = 0; //Counters for longterm stabillitytests LORA
  unsigned long countNok       = 0; //Counters for longterm stabillitytests LORA
  unsigned long readCounter    = 0;       //Read sensors if counted down SENSORS
  unsigned long resetCounter   = 400000;           //Reset value if zero SENSORS
  unsigned long hobbyAirTemp   = 0;       //Air temperature degree Celsius DHT22
  unsigned long hobbyAirHum    = 0;              //Air humidity percentage DHT22
  unsigned long hobbyMqGas     = 0;           //Some kind of concentration MQGAS
  int           tmp1           = 0;                       //Can be used anywhere

  //User configuration RF24 radio ----------------------------------------------
  bool         radioNumber     = 0;          //Set radio number 1=Ping or 0=Pong
  bool         role            = 1;   //Send or receive: 1=Ping out, 0=Pong back
  byte         addresses[][6]  = {"1Node","2Node"};
  char         temp[5]         = "-990";       //Wordt gebruikt in antwoord LORA
                                //ALTIJD 1 KARAKTER MEER DAN FEITELIJKE ANTWOORD
  char         humi[4]         = "999";        //Wordt gebruikt in antwoord LORA
  char         gasc[5]         = "1023";       //Wordt gebruikt in antwoord LORA  
  char         answer[32]      = "-23";        //Wordt gebruikt in antwoord LORA
    
  //Initialize OBJECTS ---------------------------------------------------------
  RF24 radio(CE_PIN, CSN_PIN);        //SPI & 10=CE 9=CSN Hardware configuration
  DHT dht(DHTPIN, DHTTYPE);                            //Initialize DHT22 sensor
//END OF PRECOMPILER OPTIONS ---------------------------------------------------


void setup() { //Setup runs once ***********************************************
  Serial.begin(115200);
  Serial.println("LoRa Node setup");
  Serial.println("");
  
  pinMode(CE_PIN, OUTPUT);                       //Dubbelop? kan geen kwaad LORA
  pinMode(CSN_PIN, OUTPUT);                      //Dubbelop? kan geen kwaad LORA
  pinMode(ledRedPin, OUTPUT);                                         //Rode LED
  pinMode(ledGrePin, OUTPUT);                                       //Groene LED
  pinMode(buzActPin, OUTPUT);                 //Set this pin as output to BUZZER

  //Start objects --------------------------------------------------------------
  dht.begin();                                          //Start DHT sensor DHT22
  radio.begin();

  radio.setRetries(4,5);                     //(Delay*250us, Count) ieder max 15
  radio.setPALevel(RF24_PA_MIN);             //RF24_PA_MAX=default, HIGH LOW MIN
  radio.setDataRate(RF24_250KBPS);    //Langzaamste van 3 mogelijke instellingen

  radio.openWritingPipe(addresses[0]);      //addresses[][6] = {"1Node","2Node"}
  radio.openReadingPipe(1,addresses[1]);    //addresses[][6] = {"1Node","2Node"}

  printf_begin();        //Needed to print the radio.printDetails() to a monitor
  radio.printDetails();               //Set of data about the transceiver status
  Serial.println("Radio will start listening");
  radio.startListening();                  // Start the radio listening for data

  //Test hardware and software -------------------------------------------------
  testLEDs();                 //PWM fade in and fade out for 3in1 + on board LED
  Serial.println("");
  Serial.println("Setup done, Node is running");
  beep(1);                        //Create a test beep with KY-012 active BUZZER
} //End of setup ---------------------------------------------------------------






void loop() { //KEEP ON RUNNING THIS LOOP FOREVER  *****************************
  pongback();                //Pong receives timestamp and returns own timestamp
  readSensors();         //Read sensors at timed intervals only and publish data
} //End of void loop() ----------------------- KEEP ON RUNNING THIS LOOP FOREVER





void readSensors() { //Read sensors at timed intervals only ********************
  if (readCounter == 0){       //Only perform measurements if counted down TIMER
    digitalWrite(ledGrePin, HIGH);       //Groene HIGH=aan, LOW=uit activity LED
    readCounter = resetCounter;                        //RESET the counter TIMER
    hobbyAirTemp = 10 * dht.readTemperature();  //Read temperature Celsius DHT22
    dtostrf(hobbyAirTemp, 4, 0, temp);                  //Make suitable for LoRa
    hobbyAirHum = dht.readHumidity();     //Reading takes 250 milliseconds DHT22
    dtostrf(hobbyAirHum, 3, 0, humi);                   //Make suitable for LoRa
    hobbyMqGas = analogRead (gasAdcPin);
    dtostrf(hobbyMqGas, 4, 0, gasc);                   //Make suitable for LoRa
        
    Serial.print("Temperatuur:");
    Serial.print(hobbyAirTemp);
    Serial.print("  Luchtvochtigheid:");
    Serial.print(hobbyAirHum);
    Serial.print("  Gaswaarde:");
    Serial.println(hobbyMqGas);
                
    answer[0] = temp[0];
    answer[1] = temp[1];
    answer[2] = temp[2];
    answer[3] = temp[3];
    answer[4] = ' ';
    answer[5] = humi[0];
    answer[6] = humi[1];
    answer[7] = humi[2];
    answer[8] = ' ';
    answer[9] = gasc[0];
    answer[10] = gasc[1];
    answer[11] = gasc[2];
    answer[12] = gasc[3];
    answer[13] = ' ';
    digitalWrite(ledGrePin, LOW);         //Groene HIGH=on, LOW=off activity LED

    Serial.println(answer);
  }else{                                //Meaning counter was not yet zero TIMER
    readCounter--;                        //Decrement of the timer counter TIMER
  } //End of if (moistureCnt1 == 0)Perform measurements if counted down    TIMER
} //Exit readSensors -----------------------------------------------------------







void pongback(void) { //Pong receives timestamp and returns own timestamp ******
  unsigned long got_time;                      //Variable for receivuing payload
  
  if (radio.available()){ 
    while (radio.available()) {                                   // While there is data ready
      radio.read( &got_time, sizeof(unsigned long) );             // Get the payload
    }
    radio.stopListening();                                        // First, stop listening so we can talk  
    radio.write(&answer, sizeof(answer));
    radio.startListening();                                       // Now, resume listening so we catch the next packets.
    countOk++;                           //One more succesfull communication
    Serial.print(countOk);
    Serial.print(" antwoord verzonden [");
    Serial.print(answer);  
    Serial.println("]");
  }//End of if (radio.available())
} //Exit pongback --------------------------------------------------------------




void toggle_ledOnBoard(void){ //Toggles the LED_BUILTIN on-board LED on or off *
  ledOnBoardVal = !ledOnBoardVal;                                 //Toggle value
  digitalWrite(LED_BUILTIN, ledOnBoardVal);     //Set Arduino boards onboard LED
} //Exit toggle_ledOnBoard -----------------------------------------------------



void testLEDs(void){ //PWM fade in and fade out for 3in1 + on board LED ********
  tmp1 = 0;                      //Brightness of any color, just to test PWM LED

  while (tmp1<255){
    analogWrite(ledRedPin, tmp1);             //Set LED to desired PWM value RED
    tmp1++;
    delay (2);
  }
  while (tmp1>0){
    analogWrite(ledRedPin, tmp1);             //Set LED to desired PWM value RED
    tmp1--;
    delay (2);
  }
  analogWrite(ledRedPin, 0);            //Set LED to desired PWM value = off RED


  

  while (tmp1<255){
    analogWrite(ledGrePin, tmp1);           //Set LED to desired PWM value GREEN
    tmp1++;
    delay (2);
  }
  while (tmp1>0){
    analogWrite(ledGrePin, tmp1);           //Set LED to desired PWM value GREEN
    tmp1--;
    delay (2 );
  }
  analogWrite(ledGrePin, 0);          //Set LED to desired PWM value = off GREEN
} //Exit test_LEDs -------------------------------------------------------------





void beep(uint8_t ms) {      //Create a beep (x5ms) with KY-012 active BUZZER **
  digitalWrite(buzActPin,HIGH);                                 //Turn on BUZZER
  while (ms > 0){                     //Timer of the duration of the beep BUZZER
    delay(5);                                         //Wait milliseconds BUZZER
    ms--;                              //Countdown untill we reached zero BUZZER
  }                 //Timer of the duration has been counted down to zero BUZZER
  digitalWrite(buzActPin,LOW);                  //Turn annoying sound off BUZZER
} //Exit beep ------------------------------------------------------------------





void disable_jtag(void) { //Disable jtag to free port C, enabled by default ****
#if defined(JTD)                           //Not all AVR controller include jtag
  MCUCR |= ( 1 << JTD );                                //Write twice to disable
  MCUCR |= ( 1 << JTD );                                       //So stutter once
#endif                                            //End of conditional compiling
} //Exit jtag_disable ----------------------------------------------------------





////////////////////////////////////////////////////////////////////////////////
// PIN ALLOCATIONS TABLE ARDUINO UNO                                          //
// Board -Atmel- PIN - IDE - Function          - Connection               ALT //
//                                                                            //
// CONNECTIONS RAILS TOP LEFT: DIGITAL PWM<~> ******************************* //
// SCL   -  28 - PC5 -19/A5- ADC5/SCL/PCINT13  -                           NC //
// SDA   -  27 - PC4 -18/A4- ADC4/SDA/PCINT12  -                           NC //
// AREF  -  21 - REF -     - AREF              -                              //
// GND   -  22 - GND -     - GND               -                              //
// 13    -  19 - PB5 -  13 - SCK/PCINT5        - SC   LoRa groen BUILT_IN SPI //
// 12    -  18 - PB4 -  12 - MISO/PCINT4       - MISO LoRa paars          SPI //
// ~11   -  17 - PB3 -  11 - MOSI/OC2A/PCINT3  - MOSI Lora blauw      PWM SPI //
// ~10   -  16 - PB2 -  10 - SS/OC1B/PCINT2    -                      PWM SPI //
// ~9    -  15 - PB1 -   9 - OC1A/PCINT1       -                          PWM //
// 8     -  14 - PB0 -   8 - PCINT0/CLK0/ICP1  - CE LoRa geel             DIO //
//                                                                            //
// CONNECTIONS RAILS TOP RIGHT: DIGITAL PWM<~> ****************************** //
// 7     -  13 - PD7 -   7 - PCINT23/AIN1      - CSN LoRa roze            DIO //
// ~6    -  12 - PD6 -   6 - PCINT22/OCA0/AIN0 - LED rood                 PWM //
// ~5    -  11 - PD5 -   5 - PCINT21/OC0B/T1   - LED groen                PWM //
// 4     -   6 - PD4 -   4 - PCINT20/XCK/T0    - DHT22 wit                INT //
// ~3    -   5 - PD3 -   3 - PCINT19/OC2B/INT1 -                          PWM //
// ~2    -   4 - PD2 -   2 - PCINT18/INT0      - Buzzer bruin             INT //
// TX->1 -   3 - PD1 -   1 - PCINT17/TXD       - Serial monitor           TXD //
// RX<-0 -   2 - PD0 -   0 - PCINT16/RCD       - Serial Monitor           RCD //
//                                                                            //
// CONNECTIONS RAILS BOTTOM LEFT: POWER ************************************* //
// 5V    -   7 - VCC -     - VCC               -                          VCC //
// RES   -   1 - RES -     - PCINT14/RESET     -                          RES //
// 3.3V  -     -     -     -                   -                              //
// 5V    -     -     -     -                   -                              //
// GND   -     -     -     -                   -                              //
// GND   -     -     -     -                   -                              //
// Vin   -     -     -     -                   -                              //
//                                                                            //
// CONNECTIONS RAILS BOTTOM RIGHT: ANALOG IN ******************************** //
// A0    -  23 - PC0 -A0/14- ADC0/PCINT8       -                          ADC //
// A1    -  24 - PC1 -A1/15- ADC1/PCINT9       -                          ADC //
// A2    -  25 - PC2 -A2/16- ADC2/PCINT10      -                          ADC //
// A3    -  26 - PC3 -A3/17- ADC3/PCINT12      -                          ADC //
// A4    -  27 - PC4 -A4/18- ADC4/SDA/PCINT12  -                          TWI //
// A5    -  28 - PC5 -A5/19- ADC5/SCL/PCINT13  -                          TWI //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////




////////////////////////////////////////////////////////////////////////////////
// EEPROM MEMORY MAP:                                                         //
// Start End  Number Description                                              //
// 0000  0000    1        Never use this memory location to be AVR compatible //
////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////
// FUSES (can always be altered 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=0)         //
// 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  //
////////////////////////////////////////////////////////////////////////////////
//345678911234567892123456789312345678941234567895123456789612345678971234567898