Hackster is hosting Impact Spotlights: Industrial Automation. Watch the stream live on Thursday!Hackster is hosting Impact Spotlights: Industrial Automation. Stream on Thursday!
Francesco_grRiccardoFiaschiFederico_GonellaMatteo GerbaudoArresio_Eneppe
Created April 10, 2021

Turbo Termo GF | Vallauri

Turbo Termo is a project that analyze the temperature and humidity behavior of a room and detects the presence of people in it.

IntermediateFull instructions provided20 hours43
Turbo Termo GF | Vallauri

Things used in this project

Hardware components

LOLIN D1 mini
×1
SHT30 Shield
×1
Micro SD Card Shield
×1
Relay Shield
×1
Tripler Base
×1

Software apps and online services

Arduino IDE
Arduino IDE
SolidWorks
Google Sheets
Google Sheets

Hand tools and fabrication machines

3D Printer (generic)
3D Printer (generic)

Story

Read more

Custom parts and enclosures

TurboTermoGF_Case

TurboTermoGF_Case

TurboTermoGF_Case_Cover

Schematics

Turbo Termo GF_Demo Sketch

Turbo Termo GF_Wemos assembly

Code

TurboTermoGF_Code.ino

Arduino
// Librerie
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <WEMOS_SHT3X.h>

#include <WiFiClientSecure.h>


SHT3X sht30(0x45);

float T = 0;
float H = 0;

int ist = 0.5;
int statorele = 0;

//Programmazione dell'arrey
//temperature corrispondenti
//ore:             0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20  21  22  23
int tLun [24] = { 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 20, 20, 20, 20, 19, 19, 18, 18, 18, 19, 19, 20, 20, 19};
int tMar [24] = { 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 20, 20, 20, 20, 19, 19, 18, 18, 18, 19, 19, 20, 20, 19};
int tMer [24] = { 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 20, 20, 20, 20, 19, 19, 18, 18, 18, 19, 19, 20, 20, 19};
int tGio [24] = { 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 20, 20, 20, 20, 19, 19, 18, 18, 18, 19, 19, 20, 20, 19};
int tVen [24] = { 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 20, 20, 20, 20, 19, 19, 18, 18, 18, 19, 19, 20, 20, 19};
int tSab [24] = { 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 20, 20, 20, 20, 19, 19, 18, 18, 18, 19, 19, 20, 20, 19};
int tDom [24] = { 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 20, 20, 20, 20, 19, 19, 18, 18, 18, 19, 19, 20, 20, 19};




// SD
#include <SPI.h>
#include <SD.h>

// WeMos Micro SD Shield V1.0.0: D8
// LOLIN Micro SD Shield V1.2.0: D4 (Default)
const int chipSelect = D8;




// Data e ora
#include <NTPClient.h>
#include <WiFiUdp.h>

WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org");

//Giorni della settimana
String weekDays[7] = {"Domenica", "Lunedi", "Martedi", "Mercoledi", "Giovedi", "Venerdi", "Sabato"};

//Mesi
String months[12] = {"Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"};


// Blynk
char auth[] = "Pa5AECkRbfKGiFYRSG9zCVmYiWhkJO_U";


// Credenziali del WI-FI
// Inserisci la password in "" per far funzionare la connessione.
const char* ssid = "";
const char* password = "";

float latit = 44.700415; //latitudine della casa
float longit = 7.857863; //longitudine della casa

const char* host = "script.google.com";
const int httpsPort = 443;

int value;
int valuerele = 0;

WiFiClientSecure client;
WidgetMap myMap(V0);
WidgetLED led1(V100);
SimpleTimer timer;


const char* fingerprint = "46 B2 C3 44 9C 59 09 8B 01 B6 F8 BD 4C FB 00 74 91 2F EF F6";
String GAS_ID = "";     //spreadsheet id


BLYNK_WRITE(V10) { //Comando manuale della caldaia
  valuerele = param.asInt();
}


BLYNK_WRITE(V0) { //Gestione del GPS
  float latitude = param[0].asFloat();
  float longitude = param[1].asFloat();
  float altitude = param[2].asFloat();
  float speed = param[3].asFloat();
  float dislat = (latit - latitude);
  float dislong = (longit - longitude);
  float dist = sqrt(pow(dislat, 2) + pow(dislong, 2));
  if (dist < 0.000244) {
    value = 1;
    led1.on();
  }
  else {
    value = 0;
    led1.off();
  }
}


void setup() {

  Serial.begin(115200);

  Blynk.virtualWrite(V1, 1, 44.700415, 7.857863, "Casa"); //Punto sulla mappa dell'abitazione


  // Connetti al Wi-Fi
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi..");
  }
  // Scrivi l'IP della scheda
  Serial.println(WiFi.localIP());

  client.setInsecure();
  Blynk.begin(auth, ssid, password);


  timer.setInterval(5000L, Misura_temperatura);


  pinMode(D3, OUTPUT);
  pinMode(LED_BUILTIN, OUTPUT);

  timeClient.begin(); //Assegnazione dell'ora
  // Configurazione del tempo secondo la fascia oraria
  // GMT +1 = 3600
  // GMT +8 = 28800
  // GMT -1 = -3600
  // GMT 0 = 0
  timeClient.setTimeOffset(7200); //Ora legale italiana
  
  
}


void loop() {

  Blynk.run();
  timer.run();
  // esegue timer


  digitalWrite(LED_BUILTIN, HIGH);   // Accendi il led

  //Lettura dati sht30
  float T = sht30.cTemp;
  float H = sht30.humidity;


  bool oldRetCode;
  timeClient.update();

  // Impostazione della data completa
  unsigned long epochTime = timeClient.getEpochTime();
  struct tm *ptm = gmtime ((time_t *)&epochTime);
  int monthDay = ptm->tm_mday;
  int currentMonth = ptm->tm_mon + 1;
  int currentYear = ptm->tm_year + 1900;
  String currentDate = String(currentYear) + "-" + String(currentMonth) + "-" + String(monthDay);
  int weekDay = timeClient.getDay();
  int currentHour = timeClient.getHours(); //su google sheet sarebbe la fascia oraria
  
  // Controllo automatico e manuale della caldaia
  if (valuerele == 1){
    digitalWrite (D3, HIGH);
  }
  else {
    if (value == 1){
      int tempcontrol = 0;

      switch (weekDay) {

        case 0:
          tempcontrol = tDom[currentHour];
          if (T < (tempcontrol - ist)) {
            digitalWrite(D3, HIGH);
            statorele = 1;
          }

          if (T > (tempcontrol + ist)) {
            digitalWrite(D3, LOW);
            statorele = 0;
          }
          break;


        case 1:
          tempcontrol = tLun[currentHour];
          if (T < (tempcontrol - ist)) {
            digitalWrite(D3, HIGH);
            statorele = 1;
          }

          if (T > (tempcontrol + ist)) {
            digitalWrite(D3, LOW);
            statorele = 0;
          }
          break;


        case 2:
          if (T < (tempcontrol - ist)) {
            digitalWrite(D3, HIGH);
            statorele = 1;
          }

          if (T > (tempcontrol + ist)) {
            digitalWrite(D3, LOW);
            statorele = 0;
          }
          break;


        case 3:
          if (T < (tempcontrol - ist)) {
            digitalWrite(D3, HIGH);
            statorele = 1;
          }

          if (T > (tempcontrol + ist)) {
            digitalWrite(D3, LOW);
            statorele = 0;
          }
          break;


        case 4:
          if (T < (tempcontrol - ist)) {
            digitalWrite(D3, HIGH);
            statorele = 1;
          }

          if (T > (tempcontrol + ist)) {
            digitalWrite(D3, LOW);
            statorele = 0;
          }
          break;


        case 5:
          if (T < (tempcontrol - ist)) {
            digitalWrite(D3, HIGH);
            statorele = 1;
          }

          if (T > (tempcontrol + ist)) {
            digitalWrite(D3, LOW);
            statorele = 0;
          }
          break;


        case 6:
          tempcontrol = tSab[currentHour];
          if (T < (tempcontrol - ist)) {
            digitalWrite(D3, HIGH);
            statorele = 1;
          }

          if (T > (tempcontrol + ist)) {
            digitalWrite(D3, LOW);
            statorele = 0;
          }
          break;
      }


      if (statorele == 1) {
        digitalWrite(D3, HIGH);
        statorele = 1;
      }

      if (statorele == 0) {
        digitalWrite(D3, LOW);
        statorele = 0;
      }

    }
  }

  //Scrittura su scheda SD
  File dataFile = SD.open("backup TurboTermoGF.csv", FILE_WRITE);
  // se il file  disponibile scrivi
  if (dataFile) {
    dataFile.print(currentDate); // data completa es. 11-05-2021
    dataFile.print(",");
    dataFile.print(timeClient.getFormattedTime()); // ora completa es.15:40:26
    dataFile.print(",");
    dataFile.print(T);
    dataFile.print(",");
    dataFile.println(H);
    dataFile.print(",");
    dataFile.println(valuerele);
    dataFile.close();
  }

  // se il file non viene aperto segnala un errore
  else {
    Serial.println("error opening datalog.csv");
  }

  //Invio dati a Google Sheet
  sendData(T, H, valuerele);


  delay (10000);

}

// Funzionamento e invio dati a google sheet
void sendData(float T, float H, int value) {

  Serial.print("connecting to ");
  Serial.println(host);

  if (!client.connect(host, httpsPort)) {
    Serial.println("connection failed");
    return;
  }

  if (client.verify(fingerprint, host)) {
    Serial.println("certificate matches");
  } else {
    Serial.println("certificate doesn't match");
  }


  String string_temperature =  String(T, DEC);
  String string_humidity =  String(H, DEC);
  String string_presenza =  String(value, DEC);
  //Scrive e invia una stringa di dati a google sheet
  String url = "/macros/s/" + GAS_ID + "/exec?temperature=" + string_temperature + "&humidity=" + string_humidity + "&presenza=" + string_presenza;
  Serial.print("requesting URL: ");
  Serial.println(url);

  client.print(String("GET ") + url + " HTTP/1.1\r\n" + 
               "Host: " + host + "\r\n" +
               "User-Agent: BuildFailureDetectorESP8266\r\n" +
               "Connection: close\r\n\r\n");

  Serial.println("request sent");
  while (client.connected()) {
    String line = client.readStringUntil('\n');
    if (line == "\r") {
      Serial.println("headers received");
      break;
    }
  }


  String line = client.readStringUntil('\n');
  if (line.startsWith("{\"state\":\"success\"")) {
    Serial.println("esp8266/Arduino CI successfull!");
  } else {
    Serial.println("esp8266/Arduino CI has failed");
  }
  Serial.println("reply was:");
  Serial.println("==========");
  Serial.println(line);
  Serial.println("==========");
  Serial.println("closing connection");

}

// misura e invio dei dati di temperatura e umidita a Blynk
void Misura_temperatura() {

  float temperature, humidity;
  if (sht30.get() == 0) {
    temperature = sht30.cTemp;
    humidity = sht30.humidity;
  }
  else
  {
    Serial.println("Error!");
  }

  Blynk.virtualWrite(V11, temperature);  // invia al pin virtuale 11 il valore della temperatura
  Blynk.virtualWrite(V12, temperature);  // invia al pin virtuale 12 il valore per il grafico della temperatura
  Blynk.virtualWrite(V13, humidity);    // invia al pin virtuale 13 il valore dell'umidit
  Blynk.virtualWrite(V14, humidity);    // invia al pin virtuale 14 il valore per il grafico della temperatura


  // SD
  while (!Serial) {
    ; 
  }

  Serial.print("Initializing SD card...");

  // controlla se la sd  presente e pu essere utilizzata
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");

    return;
  }
  Serial.println("card initialized.");

}

Turbo Termo GF_Editor script code.txt

JavaScript
function doGet(e) { 
  Logger.log( JSON.stringify(e) );
  var result = 'Ok';
  if (e.parameter == 'undefined') {
    result = 'No Parameters';
  }
  else {
    var sheet_id = 'Spreadsheet ID'; 	// Insert spreadsheet ID
    var sheet = SpreadsheetApp.openById(sheet_id).getActiveSheet();
    var newRow = sheet.getLastRow() + 1;						
    var rowData = [];
    var Curr_Date = new Date();
    rowData[0] = Curr_Date; // Date in column A
    var Curr_Time = Utilities.formatDate(Curr_Date, "Europe/Rome", 'HH:mm:ss');
    rowData[1] = Curr_Time; // Time in column B
    var Curr_Time = Utilities.formatDate(Curr_Date, "Europe/Rome", 'HH');
    rowData[2] = Curr_Time; // Time in column B
    for (var param in e.parameter) {
      Logger.log('In for loop, param=' + param);
      var value = stripQuotes(e.parameter[param]);
      Logger.log(param + ':' + e.parameter[param]);
      switch (param) {
        case 'temperature':
          rowData[4] = value/1; // Temperature in column E
          result = 'Temperature Written on column E'; 
          break;
        case 'humidity':
          rowData[5] = value/1; // Humidity in column F
          result += 'Humidity Written on column F'; 
          break;
         case 'presenza':
          rowData[6] = value; // presenza in column G
          result += 'presenza Written on column G'; 
          break;
        default:
          result = "unsupported parameter";
      }
    }
    Logger.log(JSON.stringify(rowData));
    var newRange = sheet.getRange(newRow, 1, 1, rowData.length);
    newRange.setValues([rowData]);
  }
  return ContentService.createTextOutput(result);
}
function stripQuotes( value ) {
  return value.replace(/^["']|['"]$/g, "");
}

Credits

Francesco_gr
1 project • 1 follower
Contact
RiccardoFiaschi
1 project • 1 follower
Contact
Federico_Gonella
2 projects • 1 follower
Contact
Matteo Gerbaudo
1 project • 1 follower
Contact
Arresio_Eneppe
1 project • 1 follower
Contact

Comments

Please log in or sign up to comment.