Buongiorno a tutti, sono alla fine di un progetto ma ho un problema, presumo sullo sketch, tutte le altre funzioni vanno bene, cerco di spiegarlo,
Esp32 s2 mini
display 7789
un pulsante
circuito di carica della batteria
Con il pulsante faccio ON e OFF con autoritenuta, una volta acceso, mi da i dati di un sensore e lo stato della batteria, con lo stesso pulsante scorro nelle varie pagine, se invece tengo premuto spengo, fin qui tutto ok
Se collego il circuito della batteria per caricarla o per alimentarla da powerbank, il display mi segnala che sono alimentato da fonte esterna con la scritta "Chrg" e lo scorrimento dell'icona della batteria, il problema è in questo momento, quando è in questo stato non riesco più a scorrere le pagine e non capisco perchè
se potete darmi un aiuto questo è lo sketch
Grazie infinite
#include <SPI.h>
#include <Wire.h>
#include "SPIFFS.h"
#include <TFT_eSPI.h>
#include "DEFINES.h"
#include <Adafruit_ADS1X15.h>
#include "RunningAverage.h"
#include <Arduino.h>
#include <Pangodream_18650_CL.h>
#include <Adafruit_INA219.h>
#include <TJpg_Decoder.h>
//------------------------------------------------------------------------------------------------
// INIZIALIZE LIBRARY
//------------------------------------------------------------------------------------------------
TFT_eSPI tft = TFT_eSPI();
#define RA_SIZE 16
RunningAverage RA(RA_SIZE);
Adafruit_INA219 ina219; // Declare and instance of INA219
#define I2C_ADDRESS_1 0x48
Adafruit_ADS1115 ads;
Pangodream_18650_CL BL;
char *batteryImages[] = {"/battery_01.jpg", "/battery_02.jpg", "/battery_03.jpg", "/battery_04.jpg", "/battery_05.jpg"};
//-----------------------------Calculate MOD (Maximum Operating Depth)----------------------------
float cal_mod (float percentage, float ppo2 = 1.4) {
return 10 * ( (ppo2 / (percentage / 100)) - 1 );
}
//------------------------------------------------------------------------------------------------
void beep() {
tone(buzzer, 700, 50); // Suono attivo per 50mS
}
//------------------------------------------------------------------------------------------------
int read_sensor(int adc = 0) {
int16_t millivolts = 0;
double currentmv = 0;
millivolts = ads.readADC_Differential_0_1();
millivolts = abs(millivolts);
RA.addValue(millivolts);
currentmv = RA.getAverage();
currentmv = abs(currentmv);
return currentmv;
}
//------------------------------------------------------------------------------------------------
void setup(void) {
Serial.begin(115200);
pinMode(charge,INPUT);
pinMode(pinButton, INPUT_PULLUP);
pinMode(mosfetPin, OUTPUT);
digitalWrite(mosfetPin, LOW);
//pinMode(P_ROSSO, OUTPUT);
// Accendo led rosso
// digitalWrite(P_ROSSO, HIGH);
delay(1000); //tempo ritardo in accensione
digitalWrite(mosfetPin, HIGH);
//Spengo led rosso
//digitalWrite(P_ROSSO, LOW);
Serial.println("STARTED!");
Serial.print("Running: Setup\n");
Serial.println(F("Inizializing FS..."));
if (SPIFFS.begin()){
Serial.println(F("done."));
}else{
Serial.println(F("fail."));
}
File testFile = SPIFFS.open(F("/Datas.txt"), "r");
if (testFile){
Serial.println("Read file content!");
testFile.seek(0, SeekSet);
page = testFile.readString().toInt();
testFile.seek(10, SeekSet);
oxVmax = testFile.readString().toInt();
testFile.close();
}else{
Serial.println("Problem on read file!");
}
// Init
ads.begin(); // ads1115 start
ina219.begin();
RA.clear(); // Clear the Running Avarage
tft.begin();
tft.setSwapBytes(true);
TJpgDec.setJpgScale(1);
TJpgDec.setCallback(tft_output);
ads.setGain(GAIN_SIXTEEN);
multiplier = 0.0078125F;
tft.setRotation(2);
tft.fillScreen(TFT_BLACK);
tft.setTextSize(2);
tft.setTextFont(4);
tft.setTextColor(0x4BC5);
tft.fillRect(5,90,230,50, 0xFFAD); // blocco GIALLO
tft.fillRect(5,87,230,10, 0x07E0 ); // blocco dove vengono scritte le situazioni
tft.fillRect(5,130,230,10, 0x07E0 ); // blocco dove vengono scritte le situazioni
tft.setCursor(70,95);
tft.print("EAN");
tft.setTextColor(TFT_GREEN);
tft.setTextSize(1);
tft.setTextFont(4);
tft.setCursor(30,40);
tft.print("Analizzatore");
tft.setCursor(70,180);
tft.print("Nitrox");
delay(3000);
pinMode(buzzer, OUTPUT);
}
//------------------------------------------------------------------------------------------------
void FILEWriteInt(int p_address, int p_value)
{
File testFile = SPIFFS.open(F("/Datas.txt"), "w");
testFile.seek(p_address, SeekSet);
testFile.print(p_value);
testFile.close();
}
unsigned int FILEReadInt(int p_address)
{
File testFile = SPIFFS.open(F("/Datas.txt"), "r");
testFile.seek(p_address, SeekSet);
int value = testFile.readString().toInt();
testFile.close();
return value;
}
//------------------------------------------------------------------------------------------------
int calibrate(double oxGas) {
Serial.print("calibrating for sampleling gas : ");
Serial.print(oxGas);
Serial.print(" % Oxygen\n");
Serial.print("oxVair: ");
Serial.print(oxVact);
Serial.print(" ");
Serial.print("oxVair: ");
Serial.print(oxVair);
Serial.print(" ");
Serial.print("oxV1atm: ");
Serial.print(oxV1atm);
Serial.print("\n");
// Azzera la media corrente in modo da poter ricominciare da capo
RA.clear();
tft.fillScreen(TFT_BLACK);
tft.setTextSize(1);
tft.setTextFont(4);
tft.setTextColor(TFT_CYAN, TFT_BLACK);
tft.setCursor(10,40);
tft.print(" CALIBRAZIONE");
tft.setCursor(10,70);
tft.print(" AUTOMATICA");
tft.setCursor(50,200);
tft.setTextSize(1);
tft.setTextFont(4);
tft.setTextColor( TFT_GREEN, TFT_BLACK);
tft.print(oxGas);
tft.print(F(" oxygen"));
int bar = 1;
for (int cx = 0; cx <= RA_SIZE; cx++) {
tft.drawRect(10, 119, 210, 27, TFT_WHITE);
tft.fillRect(11, 120, cx*13, 25, TFT_GREEN);
delay(200);
result = read_sensor(0);
delay(50);
}
beep();
result = RA.getAverage();
result = abs(result);
Serial.print("Calibration value o2: ");
Serial.print(result);
Serial.print("\n");
if (result <= milivolt_low_error) {
Serial.print("result <= milivolt_low_error\n");
errorState=1;
return 0;
} else {
tft.fillScreen(TFT_BLACK);
active = 0;
if( oxGas == 20.90 ) {
Serial.print("oxGas == 20.9\n");
// This is the 100% linear value of the milivolts expected
// From the sensor in 1 bar o2 == 100 % oxygen
oxV1atm = 1/0.209 * result * multiplier;
Serial.print("Theoretical linear 100% o2 voltage level: ");
Serial.print(oxV1atm);
Serial.print(" mV \n");
} else if( oxGas == 100.00 ) {
Serial.print("oxGas == 100.0\n");
//Serial.print("Voltage level for 100% o2 : ");
//Serial.print(result * multiplier);
//Serial.print(" mV \n");
FILEWriteInt(10, result);
}
return result;
}
}
//------------------------------------------------------------------------------------------------
void ina219values() {
//Acquisizione dei valori dal sensore
shuntvoltage = ina219.getShuntVoltage_mV(); //Legge la tensione tra V e V +. Questa è la caduta di tensione misurata ai capi del resistore shunt. Il valore è espresso in mV
busvoltage = ina219.getBusVoltage_V(); //Legge la tensione tra GND e V. Questa è la tensione totale vista dal circuito in esame. (Tensione di alimentazione - tensione shunt). Il valore è in Volt.
current_mA = ina219.getCurrent_mA(); //Legge la corrente, ricavata tramite la legge di Ohm dalla tensione shunt misurata. Il valore è in mA.
power_mW = ina219.getPower_mW();
loadvoltage = busvoltage + (shuntvoltage / 1000); //Calcola la tensione sul carico
energy = energy + loadvoltage * current_mA / 3600;
Serial.print("Bus Voltage: "); Serial.print(busvoltage); Serial.println(" V");
Serial.print("Shunt Voltage: "); Serial.print(shuntvoltage); Serial.println(" mV");
Serial.print("Voltage: "); Serial.print(loadvoltage); Serial.println(" V");
Serial.print("Current: "); Serial.print(current_mA); Serial.println(" mA");
Serial.print("Power: "); Serial.print(power_mW); Serial.println(" mW");
Serial.print("");
}
//------------------------------------------------------------------------------------------------
void error(int e) {
beep();
delay(200);
oxVact = read_sensor(0);
oxVact = oxVact * multiplier;
tft.setTextColor(TFT_RED, TFT_BLACK);
tft.setTextSize(3);
tft.setTextFont(4);
tft.setCursor(30,30);
tft.print("X");
tft.setTextColor(TFT_RED, TFT_BLACK);
tft.setTextSize(1);
tft.setTextFont(4);
tft.setCursor(100,40);
tft.print("SENSOR ");
tft.setTextSize(1);
tft.setTextFont(4);
tft.setCursor(100,70);
tft.print("ERROR");
if ( e == 1 ) {
tft.setTextColor(TFT_MAGENTA, TFT_BLACK);
tft.setTextSize(1);
tft.setTextFont(4);
tft.setCursor(40,140);
tft.print("Voltage LOW");
} else if ( e == 2 ) {
tft.setTextColor(TFT_MAGENTA, TFT_BLACK);
tft.setTextSize(1);
tft.setTextFont(4);
tft.setCursor(2,140);
tft.print("Voltage High");
} else {
tft.setTextColor(TFT_MAGENTA, TFT_BLACK);
tft.setTextSize(1);
tft.setTextFont(4);
tft.setCursor(2,140);
tft.print("Unknown Err");
}
tft.setCursor(60, 200);
tft.setTextSize(1);
tft.setTextFont(4);
tft.print(oxVact , 2);
tft.print(" mV ");
if (oxVact > milivolt_low_error && oxVact < milivolt_high_error ) {
errorState = 0;
oxVair = 0;
result_max = 0;
}
}
byte countDigits(int num){
byte count=0;
while(num){
num=num/10;
count++;
}
return count;
}
//------------------------------------------------------------------------------------------------
void batteryMonitor(){
battPcrt = (busvoltage-6.8)/.014+.5;
if(battPcrt>100) battPcrt=100;
if(battPcrt<0) battPcrt=0;
if (digitalRead(charge) == HIGH)
//if (false)
{
for(int i=0; i< ARRAY_SIZE(batteryImages); i++){
drawingBatteryIcon(batteryImages[i]);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.setCursor(150, 4);
tft.setTextSize(1);
tft.setTextFont(2);
tft.print(" Chrg ");
//drawingText("Chrg");
//delay(400);
vTaskDelay(500);
}
}else{
int imgNum = 0;
// int battPcrt = BL.getBatteryChargeLevel();
if(battPcrt >=80){
imgNum = 3;
}else if(battPcrt < 80 && battPcrt >= 50 ){
imgNum = 2;
}else if(battPcrt < 50 && battPcrt >= 20 ){
imgNum = 1;
}else if(battPcrt < 20 ){
imgNum = 0;
}
drawingBatteryIcon(batteryImages[imgNum]);
char buf[10] = {0};
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.setTextSize(1);
tft.setTextFont(2);
sprintf(buf,"%3i %%",battPcrt);
tft.setTextPadding(tft.textWidth("000 %",2));
tft.setTextDatum(TR_DATUM); //se vuoi rimanere allineato a dx
tft.drawString(buf,190,4,2); // cambia x,y (150,3) al bisogno
//tft.print("Never Used Stack Size: ");
//tft.println(uxTaskGetStackHighWaterMark(NULL));
}
}
//------------------------------------------------------------------------------------------------
void drawingBatteryIcon(String filePath){
TJpgDec.drawFsJpg(ICON_POS_X, 0, filePath);
}
void drawingText(String text){
tft.fillRect(ICON_POS_X-70, 0, 20, ICON_HEIGHT, TFT_BLACK);
tft.setTextDatum(5);
tft.setTextSize(1);
//tft.setTextFont(2);
tft.drawString(text, ICON_POS_X-2, STATUS_HEIGHT_BAR/2, 4);
}
bool tft_output(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t* bitmap)
{
if ( y >= tft.height() ) return 0;
tft.pushImage(x, y, w, h, bitmap);
return 1;
}
//------------------------------------------------------------------------------------------------
void header(float result) {
tft.setTextSize(1);
tft.setTextFont(6);
tft.setTextColor(TFT_YELLOW);
tft.setCursor(50, 40);
tft.print(result, 1);
}
//------------------------------------------------------------------------------------------------
void analysing(int x, int cal, int cal100) {
int mod = 0;
oxVact = read_sensor(0);
//Serial.print("Oxygen = ");
if (cal100 > 0 ) {
result = 20.9 + 79.1*(oxVact - cal)/(cal100 - cal);
} else {
result = (float(oxVact)/float(cal) )*20.9;
}
oxVact = oxVact*multiplier;
if (result > 99.9) result = 99.9;
if (oxVact < milivolt_low_error || result <= 0 ) {
tft.fillScreen(TFT_BLACK);
errorState=1;
} else if ( oxVact > milivolt_high_error ) {
tft.fillScreen(TFT_BLACK);
errorState=2;
} else
if (result >= result_max) {
result_max = result;
}
//-------------------------------------------------------PAGINA 0 MAX -------------------------------
if ( page == 0 ) {
batteryMonitor();
tft.setTextSize(1);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.setTextFont(6);
tft.setCursor(70, 40);
tft.print((float) result, 1);
tft.fillRect(70,120,4,100, TFT_BLUE); //linea di divisione
tft.fillRect(170,120,4,100, TFT_BLUE); //linea di divisione
tft.fillRect(2,100,238,4, TFT_MAGENTA); //linea di divisione
tft.fillRect(70,165,100,4, TFT_BLUE); //linea di divisione
tft.setTextSize(1);
tft.setTextFont(4);
tft.setCursor(95, 130);
tft.print("Max");
tft.setCursor(95,180);
tft.print(result_max, 1);
tft.print(" ");
}
//-------------------------------------------------------PAGINA 1 MOD-------------------------------
// MOD Display
if ( page == 1 ) {
batteryMonitor();
tft.setTextSize(1);
tft.setTextFont(6);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.setCursor(70, 40);
tft.print((float) result, 1);
// Print table with MOD 1.4 and 1.6 ppO2
tft.fillRect(70,120,4,100, TFT_BLUE); //linea di divisione verticale
tft.fillRect(140,120,4,100, TFT_BLUE); //linea di divisione verticale
tft.fillRect(210,120,4,100, TFT_BLUE); //linea di divisione verticale
tft.fillRect(2,100,238,4, TFT_MAGENTA); //linea di divisione orrizontale
tft.fillRect(70,165,140,4, TFT_BLUE); //linea di divisione orrizontale
tft.setTextSize(1);
tft.setTextFont(4);
tft.setCursor(90, 130);
tft.print("1.4");
tft.setCursor(160, 130);
tft.print("1.6 ");
tft.setCursor(2, 180);
tft.print("MOD");
tft.setCursor(90, 180);
tft.print(floor(cal_mod(result, 1.4)),0);
tft.print(" ");
tft.setCursor(160, 180);
tft.print(floor(cal_mod(result, 1.6)),0);
tft.print(" ");
}
//-------------------------------------------------------PAGINA 2 RISULTATO IN GRANDE-------------------------------
if ( page == 2 ) {
batteryMonitor();
tft.setTextSize(1);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.setTextSize(2);
tft.setTextColor(TFT_CYAN,TFT_BLACK);
tft.setCursor(20, 90);
tft.setTextFont(6);
tft.print((float) result, 1);
}
//-------------------------------------------------------PAGINA 3 informazione tecniche-------------------------------
// Questa pagina non viene salvata nella EEPROM
if ( page == 3 ) {
tft.fillRect(95,37,3,160, TFT_YELLOW); //linea di divisione verticale
tft.fillRect(2,37,220,3, TFT_YELLOW); //linea di divisione orrizontale
tft.setCursor(5, 10);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.setTextSize(1);
tft.setTextFont(4);
tft.print("INFO");
tft.setCursor(0, 50);
tft.setTextColor(0xfffc41, TFT_BLACK);
tft.setTextSize(1);
tft.setTextFont(4);
tft.print("Cell");
tft.setCursor(120, 50);
tft.print( oxVact , 2);
tft.print(" mV");
tft.setCursor(0, 90);
tft.setTextColor(0xfffc41, TFT_BLACK);
tft.setTextSize(1);
tft.setTextFont(4);
tft.print("Batt");
tft.setCursor(120, 90);
tft.print(busvoltage , 2);
tft.print(" V ");
tft.setCursor(0, 130);
tft.setTextColor(0xfffc41, TFT_BLACK);
tft.setTextSize(1);
tft.setTextFont(4);
tft.print("Batt");
tft.setCursor(120, 130);
tft.print(battPcrt);
tft.print(" % ");
tft.setCursor(0, 170);
if (cal100 > 0 ) {
tft.print("refmix");
tft.setCursor(120, 170);
tft.print("Aria + o2");
} else {
tft.print("refmix");
tft.setCursor(120, 170);
tft.print("Aria ");
}
tft.setTextColor(TFT_SKYBLUE, TFT_BLACK);
tft.setCursor(0, 210);
tft.setTextSize(1);
tft.setTextFont(2);
tft.print("Firmw 1.8");
}
}
//------------------------------------------------------------------------------------------------
void max_clear() {
result_max = 0;
beep();
//battVolt.clear();
active = 0;
}
//------------------------------------------------------------------------------------------------
void ON_OFF(){
if (digitalRead(pinButton) == LOW && t == 0) {
t = millis();
// Debounce software...
delay(50);
// Accendo led rosso
// digitalWrite(P_ROSSO, HIGH);
Serial.println("Inizio sequenza ");
Serial.print(t); Serial.println("...");
tmrLast = millis();
}
if (digitalRead(pinButton) == HIGH && t > 0) {
//Spengo led rosso
// digitalWrite(P_ROSSO, LOW);
t = 0;
Serial.println(" (annullata)");
tmrLast = millis();
}
//tempo ritardo in spegnimento
// Verifico anche il tempo totale
if((t > 0 && millis() - t > 2000) || millis() - tmrLast > INATTIVITA*1000 ) {
digitalWrite(mosfetPin, LOW);
// Simulo lo spegnimento....
// digitalWrite(P_ROSSO, LOW);
Serial.println("*** SPENTO ***");
while (1) { };
}
}
//------------------------------------------------------------------------------------------------
void loop(void) {
ON_OFF();
ina219values();
int current = digitalRead(pinButton);
if (current == LOW && previous == HIGH && (millis() - firstTime) > 200) {
firstTime = millis();
active = 17;
}
millis_held = (millis() - firstTime);
secs_held = millis_held / 1000;
if (millis_held > 2) {
if (current == HIGH && previous == LOW) {
if (millis_held <= 400) {
page++;
if ( page >= 4 ) {
page = 0;
}
if ( page != 3 ) {
FILEWriteInt(0, page);
}
tft.fillScreen(TFT_BLACK);
}
if (millis_held >= 400 && millis_held < 5000 ) {
oxVact = read_sensor(0);
oxVact = oxVact*multiplier;
if ( (oxVact > (oxV1atm - 10) ) && oxVair > 0) {
oxVmax = calibrate(100.00);
}
else {
//max_clear();
oxVair = calibrate(20.90);
}
}
if (millis_held >= 5000 ) {
//Serial.print("Clear 100% o2\n");
// max_clear();
oxVmax=0;
//EEPROMWriteInt(2, 0);
FILEWriteInt(10, 0);
oxVair = calibrate(20.90);
}
}
}
previous = current;
prev_secs_held = secs_held;
if ( errorState > 0 ) {
tft.fillScreen(TFT_BLACK);
while(errorState > 0){
error(errorState);
}
} else {
//calibrazione forzata all'avvio
if (oxVair == 0) {
oxVair = calibrate(20.90);
}
analysing(0, oxVair, oxVmax);
}
active++;
}