Ciao sto facendo un volmetro amperometro con INA219 e un display tft ma due cose che non so come fare, e se siano possibili, prima cosa, è possibile leggere sul display A. o mA a secondo di quello che sta misurando e se sì come?
Seconda cosa, è possibile che se no ho niente collegato i numeri sul display stiano fermi a zero e non oscillano a -0 o 0
Anche qui come
Grazie
Hai già uno sketch su cui stai lavorando?
Sì certo ecco
/*
ST7789 240x240 IPS (without CS pin) connections (only 6 wires required):
#01 GND -> GND
#02 VCC -> VCC (3.3V only!)
#03 SCL -> D13/PA5/SCK
#04 SDA -> D11/PA7/MOSI
#05 RES -> D9 /PA0 or any digital
#06 DC -> D10/PA1 or any digital
#07 BLK -> NC
*/
#include <SPI.h>
#include <Adafruit_GFX.h>
#if (__STM32F1__) // bluepill
#define TFT_DC PA1
#define TFT_RST PA0
//#include <Arduino_ST7789_STM.h>
#else
#define TFT_CS 10 // define chip select pin ST7789 TFT module
#define TFT_DC 9 // define data/command pin ST7789 TFT module
#define TFT_RST 8 // define reset pin, or set to -1 and connect to Arduino RESET pin
#include <Arduino_ST7789_Fast.h>
#endif
#define SCR_WD 240
#define SCR_HT 240
Arduino_ST7789 lcd = Arduino_ST7789(TFT_DC, TFT_RST);
#include "PropFont.h"
#include "bold13x20digtop_font.h"
#include "term9x14_font.h"
PropFont font;
// needed for PropFont library initialization, define your drawPixel and fillRect
void customPixel(int x, int y, int c) { lcd.drawPixel(x, y, c); }
void customRect(int x, int y, int w, int h, int c) { lcd.fillRect(x, y, w, h, c); }
#include <Wire.h>
//#include <Wire.h>
#include <Adafruit_INA219.h> // https://github.com/adafruit/Adafruit_INA219
Adafruit_INA219 sensor219; // Declare and instance of INA219
//-----------------------------------------------------------------------------
unsigned long ms = 0;
#define buton 2
#define buton2 4
boolean isAcquisire = false, isStopped = false;
unsigned long oldmillis = 0;
bool avviato, s, spenta;
unsigned long intervallo = 0;
boolean picco = false;
unsigned long prevmillis2 = 0;
unsigned int sample; // , Vmin = 614;// Vmin del pacco 3S
float vin = 0.0;
float watt = 0.0;
float amps = 0.0;
float t;
int PinBatt = A0;
int ValPinBatt;
float Vpin_perc;
float Vbatt;
float calc_res;
float R3 = 20000; //modificare questi valori con i valori realmente utilizzati.
float R4 = 10000;
void setup()
{
Serial.begin(9600);
//pinMode(BUTTON, INPUT_PULLUP);
Serial.println("CLEARDATA");
Serial.println("LABEL,Time,Timer,t (s),ADC,Volt,Ampere,Watt");
delay(5000);
Wire.begin();
Wire.setClock(400000); // faster
lcd.init(SCR_WD, SCR_HT);
font.init(customPixel, customRect, SCR_WD, SCR_HT); // custom drawPixel and fillRect function and screen width and height values
font.setFont(Term9x14);
font.setScale(1);
//bool status = bme.begin(0x76);
sensor219.begin();
pinMode(buton2, INPUT); // pin di ricezione segnale torcia spenta era (INPUT_PULLUP)
pinMode (PinBatt, INPUT);
calc_res = (R3 + R4) / R4;
//pinMode(buton, INPUT);
//digitalWrite(buton, HIGH);
} // end setup
const uint16_t lnCol = RGBto565(255,150,255);
const uint16_t ln2Col = RGBto565(180,180,180);
const uint16_t labCol = RGBto565(250,250,250);
const uint16_t v1Col = RGBto565(100,250,100);
const uint16_t v2Col = RGBto565(255,250,100);
const uint16_t v3Col = RGBto565(120,255,255);
const uint16_t v4Col = RGBto565(255,120,120);
const uint16_t v5Col = RGBto565(150,150,255);
const uint16_t v1aCol = RGBto565(150,150,255);
const uint16_t v2aCol = RGBto565(250,150,250);
int xe=0,mode=1,lastMode=-1;
void drawField(int x, int y, int w, int h, char *label, uint16_t col=lnCol)
{
lcd.drawRect(x,y+7,w,h-7,col);
font.setFont(Term9x14);
font.setScale(1);
font.setColor(labCol,BLACK);
int wl = font.strWidth(label);
font.printStr(x+(w-wl)/2,y,label);
}
void showVal(float v, int x, int y, int w, char *unit, uint16_t col)
{
font.setFont(Bold13x20);
font.setSpacing(3);
font.setScale(1,2);
font.setDigitMinWd(font.charWidth('0'));
font.setColor(col,BLACK);
char txt[10];
dtostrf(v,w,2,txt);
xe = font.printStr(x,y,txt);
font.printStr(xe+2,y,unit);
}
void constData()
{
drawField( 0, 0,120-5,120-3," Ah ");
drawField(120+5, 0,120-5,120-3," Ampere ");
drawField( 0,120+2,120-5,120-3," Power ");
drawField(120+5,120+2,120-5,120-3," ADC ");
font.setColor(v3Col,BLACK);
font.printStr(48,240-27,"hPa");
}
void varData()
{
/*showVal(sensor219.getBusVoltage_V(), 18,43, 4,"V",v1Col);
showVal((sensor219.getCurrent_mA())/1000., 30+120,43, 4,"A",v2Col);
showVal(watt, 14,122+43, 6,"W",v3Col);
showVal(Vbatt, 21+120,122+43, 5,"V",v4Col);*/
showVal(sensor219.getBusVoltage_V(), 10, 0+24, 4, "Ah", v1Col);
showVal((sensor219.getCurrent_mA())/1000, 10+120, 0+24, 4, "A", v2Col);
showVal(watt, 10, 82+24, 4, "W", v3Col);
showVal(Vbatt, 10+120, 82+24, 4, "V", v4Col);
showVal(analogRead (A0), 10, 160+24, 4, "V", v5Col);
font.setFont(Term9x14);
//font.printStr(xe+2,120+44+12,"m");
}
void constBoth()
{
drawField( 0, 0, 120-5, 80-3, " Ah ");
drawField(120+5, 0, 120-5, 80-3, " Ampere ");
drawField( 0, 80+2, 120-5, 80-3, " Power ");
drawField(120+5, 80+2, 120-5, 80-3, " ADC ");
drawField( 0, 160, 240, 80-3, " Battery Voltage ",ln2Col);
font.setFont(Term9x14);
int wv=font.strWidth("88.8");
//font.setColor(v1Col); font.printStr(18+wv,0+24,"'$");
wv=font.strWidth("999999.999");
//font.setColor(v5Col); font.printStr(22+wv,162+25+14,"VOLT");
wv=font.strWidth("888.8");
int wv2=font.strWidth("888.88");
// setInfoFont();
font.setScale(1,2);
font.setColor(v1Col); font.printStr(28+8+wv+10,24+12,"Ah");
font.setColor(v2Col); font.printStr(32+120+wv+10,24+12,"A");
font.setColor(v3Col); font.printStr(28+10+wv+10,105+12,"W");
font.setColor(v5Col); font.printStr(21+wv+100,158+20+14,"volt");
}
void varBoth()
{
showVal(0.0000 , 18, 0+24, 4, "Ah", v1Col);
showVal((sensor219.getCurrent_mA())/1000, 18+120, 0+24, 4, "A", v2Col);
showVal(watt, 18, 82+24, 4, "W", v3Col);
showVal(Vbatt, 18+120, 82+24, 4, "ADC", v4Col);
showVal(sensor219.getBusVoltage_V(), 50, 160+24, 6, "V", v5Col);
font.setFont(Term9x14);
//font.printStr(xe+2,82+22+14,"m");
}
void loop()
{
vin = sensor219.getBusVoltage_V();
amps = (sensor219.getCurrent_mA())/1000.;
watt = vin * amps; // Calculate the Power
ValPinBatt = analogRead(PinBatt);
Vpin_perc = map (ValPinBatt, 0, 1023, 0, 500);
Vbatt = Vpin_perc * calc_res / 100/3 ;
if(mode!=lastMode) {
lastMode=mode;
lcd.fillScreen(BLACK);
if(mode) constBoth(); else constData();
}
if(millis()-ms>1000) {
ms = millis();
if(mode) varBoth(); else varData();
}
//int st = checkButton();
// if(st>0) { if(++mode>1) mode=0; }
//if( digitalRead(2) == HIGH) return; togli le // a inizio per gestire anche pin 2
if ( digitalRead(buton2) == LOW )
{ picco = false;
if (isAcquisire == false) oldmillis = millis();
if (isStopped == false) isAcquisire = true;
}
else
{ if (picco == false) {
picco = true;
prevmillis2 = millis();
}
if (picco == true)
{ if (millis() - prevmillis2 > 450)
{ picco = false;
if (isAcquisire == true)
{ Serial.println("Acquisizione terminata"); // segnala che l'acquisizione è terminata
isStopped = true;
isAcquisire = false;
}
}
}
}
if (isAcquisire == true)
digitalWrite(LED_BUILTIN, HIGH);
else
digitalWrite(LED_BUILTIN, LOW);
if (isAcquisire == true)
{ if (millis() - oldmillis > intervallo)
{ oldmillis = millis();
intervallo = 10000;
sample = analogRead(0); // leggi Vbatt
Serial.print("DATA,TIME,TIMER,");
Serial.print(t/3600); // invia t alla seriale
Serial.print(",");
Serial.print("");
ValPinBatt = analogRead(PinBatt);
Vpin_perc = map (ValPinBatt, 0, 1023, 0, 500);
Vbatt = Vpin_perc * calc_res / 100/3 ;
Serial.print(Vbatt);
Serial.print(","); // invia il separatore alla seriale
Serial.print(vin);
Serial.print(",");
Serial.print(amps);
Serial.print(",");
Serial.println(watt);
t += 10; // incrementa t di 10 unità
} // ----- FINE CICLO -----
}
} // end main loop
Allora... non ho capito tutto, però vedo che leggi la corrente con sensor219.getCurrent_mA() quindi leggi sempre mA. Poi dividi per 1000 e ottieni sempre A. E visualizzi sempre A.
Quand'è che vorresti visualizzare mA?
Per il -0 / 0 su che valori hai questo "difetto"?
Credo sia un problema di arrotondamenti... forse risolvi con un controllo tipo "se minore di 1 visualizza 0".
I valori che mi escono showVal(0.0000 , 18, 0+24, 4, "Ah", v1Col);
showVal((sensor219.getCurrent_mA())/1000, 18+120, 0+24, 4, "A", v2Col);
showVal(watt, 18, 82+24, 4, "W", v3Col);
showVal(Vbatt, 18+120, 82+24, 4, "ADC", v4Col);
showVal(sensor219.getBusVoltage_V(), 50, 160+24, 6, "V", v5Col);
v2 v3 e v5 sono le colonne dove vedo il segno negativo, altra cosa in v1 vorrei avere i calcolo degli Ah, sai dirmi come e dove inserire questo calcolo
Per gli Ah se sai come calcolarli basta che metti la variabile giusta al posto di 0.0000 nella prima showVal.
Non sono bravo con le formule e non ho idea di come funziona il calcolo.
Per gli altri valori, con quanti decimali visualizzi?
fratt:
Per gli Ah se sai come calcolarli basta che metti la variabile giusta al posto di 0.0000 nella prima showVal.
Non sono bravo con le formule e non ho idea di come funziona il calcolo.Per gli altri valori, con quanti decimali visualizzi?
Allora visualizzo con 2 decimali anche se vorrei portarlo a 3 ma non sono riuscito ancora a trovare dove
per la formula di calcolare Ah dovrebbe essere la corrente di scarica per il tempo in ore
Visualizzi una cifra intera, il punto e 2 decimali?
Se è così dovresti cambiare il 2 nella dtostrf, però dovresti aumentare anche il parametro w che passi alla showVal.
fratt:
Visualizzi una cifra intera, il punto e 2 decimali?Se è così dovresti cambiare il 2 nella dtostrf, però dovresti aumentare anche il parametro w che passi alla showVal.
Sto andando aventi anche grazie a te e ti ringrazio, sì vorrei una una cifra intera il punto e 3 decimali, ma cosa importante vorrei poter scegliere ogni colonna (v1, v2, v3, v4, v5) dove vedo i dati sul display quanti decimali (o se averli) mi sai indicare come, grazie
Non avendo il tuo hardware devo andare per tentativi...
Hai provato a mettere 3 al posto di 2 in questa istruzione dtostrf(v,w,2,txt)?
Per poter decidere i decimali diversi per ogni valore bisogna cambiare la funzione showVal aggiungendo un parametro.
Ho provato a mettere 3 al posto di 2 e fa tre decimali, dimmi e spiegami cosa fare
La funzione che mostra i valori è dichiarata così:
void showVal(float v, int x, int y, int w, char *unit, uint16_t col)
Puoi aggiungere un altro parametro per indicare il numero dei decimali
void showVal(float v, int x, int y, int w, byte numdec, char *unit, uint16_t col)
E dentro la funzione invece del 2 o 3 fisso usi il nuovo parametro
dtostrf(v,w,numdec,txt);
Ovviamente devi aggiornare tutte le chiamate a showVal aggiungendo il nuovo parametro nella posizione corretta, ad esempio
showVal((sensor219.getCurrent_mA())/1000., 30+120,43, 4, 2, "A",v2Col);
Fatto funziona, @fratt volevo ringraziarti sei stato gentilissimo, adesso ho un altro step senza aprire un altro topic, INA219 ha un problema sopporta fino a 3,2A vorrei qualche cosa che arrivi a 5/10A ho letto ACS712 ma non è molto preciso, per renderlo più preciso bisogna accoppiarlo ad un ADS1115, hai qualche idea di come si fa
Grazie ancora
Mi fa piacere che hai risolto.
Per l'ACS / ADS non saprei proprio dirti, sull'hardware sono una frana.
E qui è difficile che la cosa sia visibile ad altri... Il titolo non c'entra e la sezione neppure.
Forse conviene che apri un thread nella sezione hardware, così qualcuno che ne capisce può darti delle risposte affidabili.
Grazie @fratt ho aperto un thread su questa sezione, ho i dati sulla seriale ma no sul display, se puoi mi dai un occhio sicuramente ne capisci più di me, grazie ancora
This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.