#include <string.h>
#include <time.h>
#include <WiFi.h>

int flag1 = 0; // variabile di ausilio per pulsante
int cicli = 0; // contatore cicli di lettura

// ----- ultrasuoni
#define trigPin 0 // define TrigPin
#define echoPin 4 // define EchoPin.
#define MAX_DISTANCE 700 // Maximum sensor distance is rated at 400-500cm.
float timeOut = MAX_DISTANCE * 60; //Sensore
int soundVelocity = 340; // define sound speed=340m/s
float get_s =0;

// -------- Led Lampeggiante --------- //
int ll=0; // Contatore dei cicli on/off
int lamp = 0; // Stato attuale

// -------- Start Server di WiFi --------- //
char ssid[] = "UNISER-WIFI"; // SSID di rete
char password[] = "XXXXXX"; // Password di Reete
WiFiClient wclient; // Istanza alla classe WiFi

//---------- Orologio
const char* ntpServer = "pool.ntp.org"; // ntp Server
const long gmtOffset_sec = 3600; // Variabili Ausiliarie
const int daylightOffset_sec = 3600; // Variabili ausiliarie
char start_time[9]; // Variabili ausiliarie
char end_time[9]; // Variabili ausiliarie

//---------- salvataggio in rete

const uint16_t port = 10000; // Soket tcp/ip Port
const char * host = "192.168.1.34"; // Ip del vostro Server Python
char uscita[5000]; // buffer
int cicli_tot=0; // Contatore ausiliario

//---------------------------

// the setup function runs once when you press reset or power the board
void setup() {
 
Serial.begin(9600); // inizializzazione della seriale di monitor
 
// inizializzazione dei led
pinMode(27, OUTPUT); // blinking Led
pinMode(14, OUTPUT); // led di segnalazione attività di campionamento
pinMode(26, OUTPUT); // led connessione HiFi

digitalWrite(27, LOW); //spegnimento led (condizione Iniziale)
digitalWrite(14, LOW); //spegnimento led (condizione Iniziale)
digitalWrite(26, LOW); //spegnimento led (condizione Iniziale)

//Inizializzazione degli imput
pinMode(34, INPUT); //Pulsante e/o sensore
//Inizializzazione del sonar
pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin, INPUT); // Sets the echoPin as an Input
 
//inizializzazione WiFi
initWiFi(ssid, password);

//inizializzazione Orologio
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);

Serial.println("Setup terminato"); //messaggio di fine configurazione
}


// the loop function runs over and over again forever
void loop() {

ll = lampeggia(27,ll,&lamp,100000);

if(digitalRead(34) == LOW) //controllo se il pulsante è premuto
{
flag1 = 1;
digitalWrite(14, HIGH); // turn the LED on
struct tm timeinfo;
if(!getLocalTime(&timeinfo))
{
Serial.println("Failed to obtain time");
}
char locTime[9];
sprintf(start_time, "%02d:%02d:%02d", timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec); //memorizza l'orario di inizio in start_time
}


if( flag1 == 1) // se il pulsante è stato premuto inizio le misurazioni
{
if(cicli <= 250)
{
get_s = getSonar();
delay(20); // Wait 3sec between pings (about 20 pings/sec).
 
if (get_s > 0) // sono riuscito a fare la misura
{
Serial.print("Distance (mm): "); // Serial print log
Serial.print(get_s); // Serial print log
Serial.print(" "); // Serial print log
Serial.print(cicli); // Serial print log
Serial.print("\n"); // Serial print log
String str = String(get_s);

char *p = const_cast<char*>(str.c_str()); //conversione della stringa per puter usare la funzione strcat()

int j; // inizio ciclo di sostituzione del punto con la virgola
int lenv = strlen(p);
for (j = 0; j < lenv; j++)
{
if (p[j] == '.')
{
p[j] = ',';
j = lenv; // or `break;`
}
} // fine di sostituzione del punto con la virgola
 
strcat(uscita, p); //aggiungo la misura al buffer di uscita
strcat(uscita,";"); // aggiungo il ; qule separatore per il formato csv
}
else // NON sono riuscito a fare la misura
{
Serial.println(" out of range ");
}
cicli++;
}
else
{
//Serial.println(uscita);
flag1 = 0;
Serial.print("\n");
//-------- calcolo dell'ora di fine rilevazione
struct tm timeinfo;
if(!getLocalTime(&timeinfo)){
Serial.println("Failed to obtain time");
}
char locTime[9];
sprintf(end_time, "%02d:%02d:%02d", timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec);
// ---- fine del calcolo dell'ora di fine rilevazione

strcat(uscita, start_time); // inserisco le due letture nel buffer
strcat(uscita,";");
strcat(uscita,end_time );
strcat(uscita,";");

Serial.println("start_time= ");
Serial.println(start_time); //stampo gli orari nel monitor di distema
Serial.println("end_time= ");
Serial.println(end_time);

if(!wclient.connect(host, port)) //controllo se il server è disponibile
{
Serial.println("Connection to host failed");
}
else
{
wclient.print(uscita); //invio i dati al server
wclient.stop();
Serial.println("\nend");
}
digitalWrite(14, LOW); // l'acquisizione è terminata spengo il the LED on
cicli = 0; // azzero i cicli
uscita[0] = '\0'; //pulisco il buffer
}
}
}


// funzione di acquisizione dal sensore
float getSonar()
{
unsigned long pingTime;
float distance;
// make trigPin output high level lasting for 10μs to triger HC_SR04
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Wait HC-SR04 returning to the high level and measure out this waitting time
pingTime = pulseIn(echoPin, HIGH, timeOut);
// calculate the qdistance according to the time
distance = (float)pingTime * soundVelocity / 2 / 10000;
return distance; // return the distance value
}

// funzione di inizializzazione delle wifi
void initWiFi(char *ssid,char *password)
{
if (WiFi.status() != WL_CONNECTED)
{
Serial.println("Starting wifi");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);int VoltsValue=0;
Serial.print(".");
}
// Serial.println("");
digitalWrite(26, HIGH);
Serial.println("WiFi connected");
}
}

//Funzione del led lampeggiante
int lampeggia(int led, int k2, int *lamp, int periodo)
{
k2++;

if (k2 == periodo and *lamp == 0)
{
digitalWrite(led, HIGH); // turn the LED on
*lamp=1;
k2 = 0;
}
if (k2 == (periodo+1) and *lamp == 1)
{
digitalWrite(led, LOW); // turn the LED on
*lamp=0;
k2 = 0;
}
return k2;
}