/////////////////////////////////////per adafruit in generale:
#include <Adafruit_GFX.h>
/////////////////////////////////////per l'encoder?:
#include <Wire.h>
/////////////////////////////////////per il display grosso:
#include "SPI.h"
#include "Adafruit_ILI9341.h"
/////////////////////////////////////intervallo aggiornamento display
unsigned long previousMillisdisplay = 0; // will store last time the screen was updated
// constants won't change:
const int fps = 250; // intervallo di aggiornaento dello schermo (milliseconds)
unsigned long currentMillis;
/////////////////////////////////////per usare la eeprom:
#include <EEPROMex.h>
int addressFloat; // per immagazzinare la totale.
//#define rotation 3 // rotazione dello schermo: 0=^(up),1=<(left),2=down,3=>(right)
#define rotation 0
/////////////////////////////////////pin encoder
#define outputA 2 //CLK pin
#define outputB 3 //DT pin
#define rstbtn 4 //reset button pin
long counter = 0;
const float pi = 3.14; // Pi value
// const float R = (0.03183098862); //Radius of the wheel from center to edge in mt
const float R = (0.03175); //Radius of the wheel from center to edge in mt
//const float R = (40); //Radius of the wheel from center to edge in mt
const int N = 1000; //no of steps for one rotation
double distance = 0.0;
double distance_prec = 0.0;
double distance_tot = 0.0;
//////////////////////////////////////////// per la batteria:
int flag_lampeggio = 0;
///////////////////////////////////////////// parte per la percentuale della batteria:
unsigned long previousMillis = 0; // immagazzina l'ultima volta che la batteria è stata aggiornata
const long interval = 500; // intervallo di aggiornamento della batteria (millisecondi)
float tensione_batteria_bit;
int percentuale_batteria;
int percentuale_batteria_prec; // per fare il controllo e non printarla a cazzo
// la batteria è a 2.7V e si è spento
// all'85% è carico con max tensione 4.18 V
// il valore sottratto è la correzione per la caduta di tensione data da una gnd diversa della batteria
int batt_min = 656-12; // valore in bit di tensione minima batteria (3.2V)
int batt_max = 861-22; // valore in bit di tensione maxima batteria (4.2V)
///////////////////////////////////////////// parte del long press:
const int SHORT_PRESS_TIME = 1000;
int lastState = LOW; // the previous state from the input pin
int currentState; // the current reading from the input pin
unsigned long pressedTime = 0;
unsigned long releasedTime = 0;
int flag_pulsante = 0;
// For the Adafruit lcd TFT shield, these are the default.
#define TFT_DC 9
#define TFT_CS 10
#define TFT_RST 8
///////////////////////////////////////////////// per la visualizzazione mi serve x_0 e y_0
int x_0 = 0; // valore iniziale di x per iniziare a printare
int y_0 = 50; // valore iniziale di y per iniziare a printare
int X_batt = 160; //coordinata x per qui printa la percentuale della batteria
// Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
// If using the breakout, change pins as desired
//Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_CLK, TFT_RST, TFT_MISO);
void setup() {
Serial.begin(9600);
delay(100); //una volta era 2000 proviamo con 1500 se funziona:
// wait for initializing
tft.begin(); // inizia collegamento con tft display
//////////////////////////////////////////stampa logo
tft.setRotation(rotation); // di allo schermo che è messo verticale, ha voluto cosi...
tft.fillScreen(ILI9341_BLACK); //clear the screen
tft.fillRect(0, 140, 340, 4, ILI9341_WHITE); // per fare la linea
for (int i = 0; i < 10; i++)
{
tft.drawRect(i, i,240-i*2, 320-i*2, ILI9341_BLUE);
yield();
}
tft.setCursor(20, 20);
tft.setTextColor(ILI9341_GREEN); tft.setTextSize(6); // colore e size
tft.print("Or");
tft.setTextColor(ILI9341_WHITE); tft.setTextSize(6); // colore e size
tft.print("na");
tft.setTextColor(ILI9341_RED); tft.setTextSize(6); // colore e size
tft.print("ti");
tft.setCursor((12+20), 90);
tft.setTextColor(ILI9341_WHITE); tft.setTextSize(3); // colore e size
tft.print("AUTOMATION");
tft.setCursor(15, 170);
tft.setTextColor(ILI9341_RED); tft.setTextSize(3); // colore e size
tft.print(" misuratore");
tft.setCursor(20, 195);
tft.print(" Ricci");
tft.setTextColor(ILI9341_RED); tft.setTextSize(2); // colore e size
tft.setCursor(120, 201);
tft.print(" V_1.3");
// Initialize encoder pins
pinMode(outputA, INPUT);
pinMode(outputB, INPUT);
pinMode(rstbtn, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(outputA), readEncoder, FALLING);
delay(2500);
distance_tot = EEPROM.readFloat(addressFloat); //leggi il valore distance_tot
if(isnan(distance_tot))
{
distance_tot = 0;
}
delay(2500);
tft.fillScreen(ILI9341_WHITE);
delay(1000);
tft.fillScreen(ILI9341_BLACK); //clear the screen
printlayout(); // printa il layout di visualizzazione del parziale e totale:
delay(150);
}
void controllobatteria() {
currentMillis = millis();
if (currentMillis - previousMillis >= interval)
{
// save the last time you checked the battery
previousMillis = currentMillis;
tensione_batteria_bit = analogRead(A0);
//////////////////////////////////////////// taglio valori massimi e minimi
if (tensione_batteria_bit < batt_min) // se il valore è minore del valore minimo:
{
tensione_batteria_bit = batt_min; // impostalo al valore minimo
}
else if (tensione_batteria_bit > batt_max) //se il valore è magg del val. massimo:
{
tensione_batteria_bit = batt_max; // impostalo al valore max
}
percentuale_batteria = map(tensione_batteria_bit,batt_min,batt_max,0,100); //porta il valore in percentuale
// if the value has changed:
if ((percentuale_batteria != percentuale_batteria_prec) || (percentuale_batteria < 5 )) // se la perc. batt è cambiata:
{
//Serial.println(percentuale_batteria);
tft.setTextSize(3);
tft.setCursor(X_batt , 0);
tft.setTextColor(ILI9341_BLACK); // imposta colore cancella
tft.print(percentuale_batteria_prec);
tft.print("%");
yield();
percentuale_batteria_prec = percentuale_batteria;
if (percentuale_batteria <= 5)
{
if(flag_lampeggio == 1)
{
flag_lampeggio = 0;
}
else
{
tft.setCursor(X_batt , 0);
tft.setTextColor(ILI9341_RED); // imposta colore rosso
tft.print(percentuale_batteria);
tft.print("%");
flag_lampeggio = 1;
}
}
else if ((percentuale_batteria <= 10) && (percentuale_batteria > 5))
{
tft.setCursor(X_batt , 0);
tft.setTextColor(ILI9341_RED); // imposta colore rosso
tft.print(percentuale_batteria);
tft.print("%");
yield();
}else if ((percentuale_batteria >= 10) && (percentuale_batteria <= 30))
{
tft.setCursor(X_batt , 0);
tft.setTextColor(ILI9341_YELLOW); // imposta colore rosso
tft.print(percentuale_batteria);
tft.print("%");
yield();
}else if (percentuale_batteria > 30)
{
tft.setCursor(X_batt , 0);
tft.setTextColor(ILI9341_GREEN); // imposta colore rosso
tft.print(percentuale_batteria);
tft.print("%");
yield();
}
}
}
}
void readEncoder() {
int bValue = digitalRead(outputB);
if (bValue == HIGH) {
counter++; // Clockwise
}
if (bValue == LOW) {
counter--; // Counterclockwise
}
}
// Get the counter value, disabling interrupts.
// This make sure readEncoder() doesn't change the value
// while we're reading it.
long getCounter() {
long result;
noInterrupts();
result = counter;
interrupts();
return result;
}
void resetCounter() {
noInterrupts();
distance_tot = distance_tot+distance;
counter = 0;
interrupts();
}
////////////////////////////////////////////////////funzione aggiornamento display
// int flag_press=0;
// int flag_longpress=0;
void loop() {
// tft.fillScreen(ILI9341_BLACK); //pulisci il display
distance = ((2*pi*R)/N) * getCounter();
currentState = digitalRead(rstbtn); //leggi lo stato del pulsante
if(lastState == HIGH && currentState == LOW) // button is pressed
{
pressedTime = millis();
flag_pulsante = 1;
}
else if(lastState == LOW && currentState == HIGH) // button is released
{
releasedTime = millis();
long pressDuration = releasedTime - pressedTime;
if( pressDuration < SHORT_PRESS_TIME )
{
//////////////////// short press detected
mem_writer(); // immagazzina nella memoria
resetCounter(); // resetta il counter del metraggio
printlayout(); // reprinta il loadout
flag_pulsante = 0;
}
}
if((flag_pulsante == 1) && ((millis()-pressedTime) >= SHORT_PRESS_TIME))
{
//////////////////////// long press detected
flag_pulsante = 0;
distance_tot = 0;
printlayout();
mem_writer();
}
// save the the last state
lastState = currentState;
////////////////////controlla se la batteria è da aggiornare, e nel caso aggiornala
controllobatteria();
////////////////////controlla il display e aggiornalo
currentMillis = millis();
if (currentMillis - previousMillisdisplay >= fps) {
// save the last time you refreshed the display
previousMillisdisplay = currentMillis;
aggiorna_display();
}
}
///////////////////////////////////////////////////// funzione immagazzina in memoria
void mem_writer()
{
// la variabile d'interesse è: distance_tot
EEPROM.writeFloat(addressFloat,distance_tot); // scrivi nella eeprom nel posto adressfloat
// distance_tot = EEPROM.readFloat(addressFloat); //leggi il valore distance_tot
}
////////////////////////////////////////////////////////funzione prova schermo colori
unsigned long testFillScreen() {
unsigned long start = micros();
yield();
tft.fillScreen(ILI9341_RED);
yield();
tft.fillScreen(ILI9341_GREEN);
yield();
tft.fillScreen(ILI9341_BLUE);
yield();
tft.fillScreen(ILI9341_BLACK);
yield();
return micros() - start;
}
void printlayout()
{
tft.fillScreen(ILI9341_BLACK); //clear the screen
tft.setCursor(0 , 0);
tft.setTextColor(ILI9341_WHITE); tft.setTextSize(3); // colore e size
tft.print("batteria:");
tft.setCursor(0, 20);
tft.fillRect(0, 35, 340, 3, ILI9341_WHITE); // per fare la linea
tft.setTextSize(3);
tft.setCursor(X_batt , 0);
tft.setTextColor(ILI9341_GREEN);
tft.print(percentuale_batteria);
tft.print("%");
tft.setCursor(x_0, y_0);
tft.setTextColor(ILI9341_WHITE); tft.setTextSize(4); // colore e size
tft.print(" parziale");
tft.setTextSize(5);
tft.setCursor(x_0 + 0,y_0 + 40);
tft.setTextColor(ILI9341_RED); // imposta colore rosso
tft.print(distance); // printa distanza in m
tft.setTextColor(ILI9341_WHITE); // reimposta colore white
tft.setCursor(x_0 + 210, y_0 + 40);
tft.print("m"); // "metri"
tft.setTextSize(4);
//tft.setCursor(x_0 + 0, y_0 + 70); // meta 112 oppure metà dei caratteri spaziati di 30 = 105
//tft.print("-------------");
tft.fillRect(x_0 , y_0 + 82, 340, 4, ILI9341_WHITE);
tft.setCursor(x_0 + 0, y_0 + 90);
tft.print(" totale");
tft.setTextSize(5);
tft.setCursor(x_0 + 0, y_0 + 130);
tft.setTextColor(ILI9341_RED); // imposta colore rosso
tft.print(distance_tot); // printa distanza in m
tft.setCursor(x_0 + 210, y_0 + 130);
tft.setTextColor(ILI9341_WHITE); // reimposta colore white
tft.print("m"); // "metri"
}
void aggiorna_display()
{
if (distance_prec != distance) // se la distanza è cambiata:
{
//Serial.println(distance);
tft.setTextSize(5);
tft.setCursor(x_0 + 0,y_0 + 40);
tft.setTextColor(ILI9341_BLACK); // imposta colore cancella
tft.print(distance_prec);
yield();
tft.setCursor(x_0 + 0,y_0 + 40);
tft.setTextColor(ILI9341_RED); // imposta colore rosso
tft.print(distance);
yield();
tft.setCursor(x_0 + 0, y_0 + 130);
tft.setTextColor(ILI9341_BLACK); // imposta colore cancella
tft.print(distance_tot); // cancella il vecchio valore di distance_tot
yield();
distance_tot = distance_tot + (distance-distance_prec);
// scrivi il nuovo valore di distance_tot
tft.setCursor(x_0 + 0, y_0 + 130);
tft.setTextColor(ILI9341_RED); // imposta colore cancella
tft.print(distance_tot);
yield();
distance_prec = distance;
}
}
//delay(500);
///////////////////////////////////////////////////////fine prova display
// funzione printa layout visual. distanza
/* // vecchia funzione:
tft.fillScreen(ILI9341_BLACK); // pulisci lo schermo
unsigned long start = micros();
tft.setCursor(0, 0);
tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1);
tft.println("Hello World!");
tft.setTextColor(ILI9341_YELLOW); tft.setTextSize(2);
tft.println(1234.56);
tft.setTextColor(ILI9341_RED); tft.setTextSize(3);
tft.println(0xDEADBEEF, HEX); // printa deadbeef?
tft.println();
tft.setTextColor(ILI9341_GREEN);
tft.setTextSize(5);
tft.println("Groop");
tft.setTextSize(2);
tft.println("I implore thee,");
tft.setTextSize(1);
tft.println("my foonting turlingdromes.");
tft.println("And hooptiously drangle me");
tft.println("with crinkly bindlewurdles,");
tft.println("Or I will rend thee");
tft.println("in the gobberwarts");
tft.println("with my blurglecruncheon,");
tft.println("see if I don't!");
return micros() - start;
unsigned long testFilledRects(uint16_t color1, uint16_t color2) {
unsigned long start, t = 0;
int n, i, i2,
cx = tft.width() / 2 - 1,
cy = tft.height() / 2 - 1;
tft.fillScreen(ILI9341_BLACK);
n = min(tft.width(), tft.height());
for(i=n; i>0; i-=6) {
i2 = i / 2;
start = micros();
tft.fillRect(cx-i2, cy-i2, i, i, color1);
t += micros() - start;
// Outlines are not included in timing results
tft.drawRect(cx-i2, cy-i2, i, i, color2);
yield();
}
return t;
}
void readAndWriteFloat() {
Serial.println("----------------------------");
Serial.println("writing and retreiving float");
Serial.println("----------------------------");
double input = 1010102.50;
double output = 0.0;
EEPROM.writeFloat(addressFloat,input);
output = EEPROM.readFloat(addressFloat);
Serial.print("adress: ");
Serial.println(addressFloat);
Serial.print("input: ");
Serial.println(input);
Serial.print("output: ");
Serial.println(output);
Serial.println("");
}
*/