#include <Wire.h> // Include la libreria Wire per la comunicazione I2C
#include <Adafruit_GFX.h> // Include la libreria Adafruit GFX per le funzioni grafiche
#include <Adafruit_ILI9341.h> // Include la libreria Adafruit ILI9341 per il display TFT
#include <DHT.h> // Include la libreria DHT per il sensore DHT22
#include <Adafruit_Sensor.h> // Include la libreria Adafruit Sensor (necessaria per BMP280)
#include <Adafruit_BMP280.h> // Include la libreria Adafruit BMP280 per il sensore BMP280
#include <SD.h> // Include la libreria SD per la scheda SD
#include <SPI.h> // Include la libreria SPI per la comunicazione con la scheda SD
#include <Fonts/FreeSans9pt7b.h> // Include il font FreeSans
// Definizione dei pin utilizzati per il display
#define TFT_CS 27
#define TFT_DC 26
#define TFT_RST 4
// Definizione dei pin per il sensore BMP280
#define SDA_PIN 21
#define SCL_PIN 22
// Definizione del pin per il sensore DHT22
#define DHT_PIN 32
// Definizione dei pin per la scheda SD
#define SD_CS 5 // Pin CS per la scheda SD
#define SD_MISO 15 // Pin MISO per la scheda SD
#define SD_MOSI 23 // Pin MOSI per la scheda SD
#define SD_SCK 18 // Pin SCK per la scheda SD
// Creazione di un'istanza dell'oggetto DHT
DHT dht(DHT_PIN, DHT22);
// Creazione di un'istanza dell'oggetto BMP280
Adafruit_BMP280 bmp; // I2C è il default
// Variabile di offset per la taratura della pressione
float pressure_offset = 0.0; // Regola questo valore per la taratura
// Crea un oggetto dell'Adafruit_ILI9341 con i pin specificati
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
void setup() {
// Inizializza la comunicazione seriale
Serial.begin(115200);
// Attendi qualche istante per la stabilizzazione della comunicazione seriale
delay(1000);
// Inizializza il bus I2C con i pin definiti
Wire.begin(SDA_PIN, SCL_PIN);
// Inizializza il display TFT
tft.begin();
// Imposta la rotazione del display (0-3), 3 corrisponde a una rotazione di 270 gradi
tft.setRotation(1);
// Colore DARKBLUE per le prime 64 pixel di altezza
for (int y = 0; y < 64; y++) {
tft.drawFastHLine(0, y, tft.width(), 0x0010);
}
// Colori alternati BIANCO e ALICEBLUE per il resto dello schermo
int rowHeight = (tft.height() - 64) / 9; // Altezza di ciascuna delle 9 righe rimanenti
for (int i = 0; i < 8; i++) { // Modificato per escludere l'ultima riga
uint16_t color = (i % 2 == 0) ? 0xFFFF : 0xEFBF;
for (int y = 64 + i * rowHeight; y < 64 + (i + 1) * rowHeight; y++) {
tft.drawFastHLine(0, y, tft.width(), color);
}
}
// Colore BIANCO esteso per l'ultima riga
int lastRowHeight = (tft.height() - 64) - (8 * rowHeight); // Calcola l'altezza rimanente
tft.fillRect(0, 64 + 8 * rowHeight, tft.width(), lastRowHeight, 0xFFFF); // Estendi l'area bianca
// Inizializza il sensore DHT
dht.begin();
// Inizializza il sensore BMP280 con l'indirizzo I2C specificato
if (!bmp.begin(0x76)) { // Specifica l'indirizzo I2C
Serial.println("Errore di inizializzazione BMP280!");
}
// Inizializza la scheda SD
if (!SD.begin(SD_CS)) {
Serial.println("Errore di inizializzazione della scheda SD!");
} else {
Serial.println("Scheda SD inizializzata con successo.");
// Crea o apre il file log.txt
File logFile = SD.open("/log.txt", FILE_WRITE);
if (logFile) {
logFile.println("Log iniziato.");
logFile.close();
} else {
Serial.println("Impossibile aprire il file log.txt.");
}
}
// Imposta il font al nuovo font
tft.setFont(&FreeSans9pt7b);
// Stampa la scritta nella parte scura blu
tft.setTextColor(ILI9341_RED);
tft.setTextSize(1); // Imposta la dimensione del testo (mantieni 1 per usare il font personalizzato)
tft.setCursor(4, 14); // Imposta la posizione del cursore più in alto
// Scrivi "Alpha Flight Computer" nella parte scura blu
tft.print("Alpha Flight Computer");
// Stampa le etichette nelle righe corrispondenti
tft.setTextColor(ILI9341_BLACK);
tft.setTextSize(1); // Imposta la dimensione del testo
const char* labels[] = {
"Latitude",
"Longitude",
"Altitude [m]",
"Speed [km/h]",
"Out Temp.[C]",
"In Temp.[C]",
"Out Hum.[%]",
"Out Press.[hPa]",
"IR [mW/m^2]"
};
for (int i = 0; i < 9; i++) {
int yOffset = 64 + i * rowHeight + rowHeight / 2 + 4; // Centra verticalmente il testo
tft.setCursor(10, yOffset); // Imposta la posizione del cursore
tft.println(labels[i]);
}
}
void loop() {
// Leggi la temperatura dal sensore BMP280
float temperature = bmp.readTemperature();
// Leggi la pressione dal sensore BMP280
float pressure = bmp.readPressure() / 100.0F; // Converti in hPa
// Aggiungi l'offset di taratura alla pressione letta
pressure += pressure_offset;
// Leggi l'umidità dal sensore DHT
float humidity = dht.readHumidity();
// Stampa la temperatura sulla seriale
Serial.print("Temperatura Esterna: ");
Serial.print(temperature);
Serial.println(" °C");
// Stampa la pressione sulla seriale
Serial.print("Pressione: ");
Serial.print(pressure);
Serial.println(" hPa");
// Controlla se la lettura dell'umidità è valida
if (isnan(humidity)) {
Serial.println("Errore nella lettura dell'umidità!");
} else {
// Stampa l'umidità sulla seriale
Serial.print("Umidità esterna: ");
Serial.print(humidity);
Serial.println(" %");
}
// Pulire la parte inferiore dello schermo
int rowHeight = (tft.height() - 64) / 9;
for (int i = 0; i < 9; i++) {
int yOffset = 64 + i * rowHeight;
tft.fillRect(216, yOffset, tft.width() - 216, rowHeight, (i % 2 == 0) ? 0xFFFF : 0xEFBF);
}
// Estendi l'area bianca per l'ultima riga
int lastRowHeight = (tft.height() - 64) - (8 * rowHeight);
tft.fillRect(216, 64 + 8 * rowHeight, tft.width() - 216, lastRowHeight, 0xFFFF); // Estendi l'area bianca
// Visualizzare i valori sul display
tft.setTextSize(1);
tft.setTextColor(ILI9341_BLUE); // Modifica il colore del testo in blu
// Visualizza i valori letti dal sensore accanto alle etichette
tft.setFont(&FreeSans9pt7b);
tft.setCursor(216, 64 + 0 * rowHeight + rowHeight / 2 + 4); // Riga 1
tft.print("0"); // Placeholder, dovresti avere un valore reale per Lat.
tft.setCursor(216, 64 + 1 * rowHeight + rowHeight / 2 + 4); // Riga 2
tft.print("0"); // Placeholder, dovresti avere un valore reale per Long.
tft.setCursor(216, 64 + 2 * rowHeight + rowHeight / 2 + 4); // Riga 3
tft.print("0"); // Placeholder, dovresti avere un valore reale per Alt.
tft.setCursor(216, 64 + 3 * rowHeight + rowHeight / 2 + 4); // Riga 4
tft.print("0"); // Placeholder, dovresti avere un valore reale per Vel.
tft.setCursor(216, 64 + 4 * rowHeight + rowHeight / 2 + 4); // Riga 5
if (isnan(temperature)) {
tft.print("0");
} else {
tft.print(String(temperature, 1)); // Mostra la temperatura con 1 decimale
tft.print(" ");
}
tft.setCursor(216, 64 + 5 * rowHeight + rowHeight / 2 + 4); // Riga 6
tft.print("0"); // Placeholder, dovresti avere un valore reale per In Temp.
tft.setCursor(216, 64 + 6 * rowHeight + rowHeight / 2 + 4); // Riga 7
if (isnan(humidity)) {
tft.print("0");
} else {
tft.print(String(humidity, 1)); // Mostra l'umidità con 1 decimale
tft.print(" ");
}
tft.setCursor(216, 64 + 7 * rowHeight + rowHeight / 2 + 4); // Riga 8
if (isnan(pressure)) {
tft.print("0");
} else {
tft.print(String(pressure, 1)); // Mostra la pressione con 1 decimale
tft.print(" ");
}
tft.setCursor(216, 64 + 8 * rowHeight + rowHeight / 2 + 4); // Riga 9
tft.print("0"); // Placeholder, dovresti avere un valore reale per IR.
// Scrivere i dati nel file log.txt
if (SD.begin(SD_CS)) {
File logFile = SD.open("/log.txt", FILE_WRITE);
if (logFile) {
logFile.print("Temperatura Esterna: ");
logFile.print(temperature);
logFile.println(" °C");
logFile.print("Pressione: ");
logFile.print(pressure);
logFile.println(" hPa");
logFile.print("Umidità esterna: ");
logFile.print(humidity);
logFile.println(" %");
logFile.close();
} else {
Serial.println("Impossibile aprire il file log.txt.");
}
} else {
Serial.println("Errore nell'inizializzazione della scheda SD.");
}
// Attendi 3 secondi prima della prossima lettura
delay(3000);
}