Go Down

Topic: Misuratore Ampere / Volt / Continuità per pista Slot (Read 9901 times) previous topic - next topic

ricki158

Pensavo fosse meglio farlo. Credo comunque sia intrinseco alla libreria.

Standardoil

Sì, ma è input_pullup, e la fa la begin()
tu alla riga dopo la stroi
Prima legge di Nelson (che sono io):
A parità di risultato maggiore è il pensiero, minore il lavoro.
Quindi prima di fare pensa!

Standardoil

Prima legge di Nelson (che sono io):
A parità di risultato maggiore è il pensiero, minore il lavoro.
Quindi prima di fare pensa!

ricki158

Anche togliendo quella riga il problema non cambia comunque.

Si, il pin 14 dell'Arduino Pro Micro che ha chip ATMega32u4

Standardoil

Prima legge di Nelson (che sono io):
A parità di risultato maggiore è il pensiero, minore il lavoro.
Quindi prima di fare pensa!

ricki158

Errore da novizio! Per questo motivo scrivo molto nel forum :D

Grazie mille davvero!!

Adesso risolto anche questo problema volevo cercare un modo per snellire e cancellare le tante funzioni che ho creato per la stampa attraverso l'uso di funzioni parametriche. Vediamo che cosa riesco a fare.

Etemenanki

#246
Jul 10, 2018, 05:50 pm Last Edit: Jul 10, 2018, 05:52 pm by Etemenanki
Te l'avevo detto che qualcuno piu "softwarista" avrebbe probabilmente trovato il problema meglio di me ;)

... snellire e cancellare  ...
Solo come suggerimento ... quando cancelli tutto per passare a finestre completamente diverse, che dovresti comunque riscrivere (tipo, quando fai impostazioni o selezioni), invece di usare le varie funzioni "clear", fai semplicemente il clear dell'intero lcd ... poi al massimo ristampi una sola volta le parti statiche ... in questo modo, sara' un po piu lento durante i passaggi di schermata, ma puoi eliminare tutte le varie funzioni "clear" dedicate (tanto adesso la cancellazione delle scritte durante il funzionamento normale la fai con l'ultimo sistema, dentro alle funzioni di scrittura, giusto ?) ... ;)
"Sopravvivere" e' attualmente l'unico lusso che la maggior parte dei Cittadini italiani,
sia pure a costo di enormi sacrifici, riesce ancora a permettersi.

ricki158

Io per le funzioni "clear" avevo in mente un'altra cosa: tengo la funzione generale e inserisco come argomento il colore, che per le funzioni clear sarà il nero.

ricki158

Buonasera a tutti!

Sotto consiglio di Silente sono passato a scrivere le funzioni inserendo i parametri che mi interessavano, generalizzando in questo modo le funzioni ed utilizzandone una per fare 4 stampe diverse. Che dire, il risultato è strepitoso perché sono passato dalle 1000 righe alle 500.

Oltretutto sono riuscito a capire come dare per parametro un oggetto (in questo caso i display) e sono riuscito a fare le stampe prima su un solo display e poi sull'altro. Devo dire che non cambia molto per quel che riguarda il flickering.

Ho aperto un topic nella sezione software per avere alcune delucidazioni appunto su come inserire alcuni parametri ed ho scoperto altre cose molto utili per far si che i propri codici funzionino :D

Dopo aver fatto tutti questi passi da gigante posso dire di aver completato la parte di stampa sui display e di averla ottimizzata al massimo. Se avete altre idee vi prego parlatemene :D

Visto che non vedevo l'ora di cominciare a misurare qualcosa, ho unito tutto (visto che funziona) al programma principale che svolge le letture e sono riuscito a farlo funzionare facendo qualche aggiustaggio.
Per il momento sto facendo le letture senza nessun tipo di media, così da velocizzare le letture.
Sembra funzionare!

Ho due problemi però:

-1: la variazione dei valori non viene cancellata nella maniera corretta;
-2: la stampa del valore massimo che cambia avviene soltanto nel canale in quel momento selezionato da varSel. La stampa però, perché invece il massimo viene salvato su tutti i canali in maniera diversa. Quindi sostanzialmente quando mi muovo con il tasto che cambia varSel mi si "aggiorna" la stampata del valore massimo.

Allego il codice, vorrei fare un video ma in questo momento non riesco.

ricki158

Buongiorno a tutti!
Dopo un po' di tempo riscrivo su questo topic. Sono riuscito a sistemare il codice e a migliorarlo ancora un pochino su certi aspetti. Adesso funziona tutto a dovere. Ho provato la lettura delle tensioni ed è corretta e abbastanza veloce. La parte di rilevatori di corrente non l'ho ancora finita perché non li abbiamo ancora installati ma ho provato "al banco" gli ACS, 3 su 4 hanno caratteristiche corrette mentre uno solo ha una sensitivity di 0.40 mV/A anziché 0.30 mV/A. Non si sa perché ma rimane lineare nella curva. Vabbé vuol dire che ne terrò conto nel software.
Nel frattempo mi è arrivata la scheda dalla Cina che ho già stagnato (mi son dimenticato di comprare solamente una morsettiera da stampato a 45° da 2 poli sennò sarebbe già finito), ho fatto la plancia del mobiletto e appena posso farò il mobiletto completo con una stampante 3D.
Per il momento funziona tutto e sono molto soddisfatto. Volevo ringraziarvi.

ricki158

Buongiorno a tutti!
Finalmente ho ritrovato un po' di tempo per concludere questo progetto. Purtroppo però ho cantato vittoria troppo presto.

Ho installato tutto sulla scheda come sulla breadboard, ho però scambiato i pin RST CS e D/C dei due display, sempre mantenendoli digitali ma non MOSI, MISO e SCK. Questo per non incrociare i cavi che ho saldato al connettore per i display. Questa è l'unica modifica che ho fatto e naturalmente ho cambiato i #define del codice per quanto riguarda questi pin. Ho quindi provato per la prima volta la scheda arrivata dalla Cina.

I display si accendono ma viene stampato il codice presente nella funzione "setup" di Arduino, mentre il "loop" non parte proprio. Ho fatto un debug semplicemente inserendo un Serial.println("Pippo"); nel loop ma non c'è nessun tipo di comunicazione.

Mi sembra molto strana questa cosa. Ho provato varie schede Arduino funzionanti e mi danno tutte lo stesso problema, se però tengo la scheda "volante" il loop funziona regolarmente dal momento che leggo su seriale "Pippo".

Potrei aver cambiato il pin sul quale porto i 5v del regolatore di tensione rispetto alla breadboard, non ricordo, ma anziché portare la tensione a monte del regolatore la porto a valle. Però mi sembra comunque strano che soltanto il "loop" sia bloccato. Magari devo ponticellare l'alimentazione sulla scheda Arduino. Non ricordo, devo tornare indietro nel topic a rileggere il discorso, è passato un po' di tempo.

Escludo comunque un problema nel software, il problema è della scheda che ho fatto io sicuramente. Bisogna "soltanto" trovare dove! Ed avere un po' di tempo per mettersi sotto e trovarlo.

Per il resto sto disegnando il mobiletto in SolidWorks per farmelo stampare in 3D, viene carino.

Intanto assieme a MightyPegas stiamo vedendo di migliorare un pochino la libreria Adafruit per i convertitori analogico digitali ADC1015 / ADC1115. Praticamente con gli ADC1115 è possibile avere un campionamento più veloce (anche per i 1015) cambiando alcuni #define, li ho inseriti quindi nella libreria .h ma questi #define sono "bloccati" nella libreria .cpp. Vorrei fare qualcosa di "generico", aggiungendo possibilità alla libreria senza riscriverla. Mi spiego meglio magari con il codice.

Questo è il pacco di #define relativi alla velocità di campionamento nel file .h:

Code: [Select]

#define ADS1015_REG_CONFIG_DR_MASK      (0x00E0) 
#define ADS1015_REG_CONFIG_DR_128SPS    (0x0000)  // 128 samples per second
#define ADS1015_REG_CONFIG_DR_250SPS    (0x0020)  // 250 samples per second
#define ADS1015_REG_CONFIG_DR_490SPS    (0x0040)  // 490 samples per second
#define ADS1015_REG_CONFIG_DR_920SPS    (0x0060)  // 920 samples per second
#define ADS1015_REG_CONFIG_DR_1600SPS   (0x0080)  // 1600 samples per second (default)
#define ADS1015_REG_CONFIG_DR_2400SPS   (0x00A0)  // 2400 samples per second
#define ADS1015_REG_CONFIG_DR_3300SPS   (0x00C0)  // 3300 samples per second


Ai quali ho aggiunto:

Code: [Select]

#define ADS1115_REG_CONFIG_DR_MASK      (0x00E0)
#define ADS1115_REG_CONFIG_DR_8SPS      (0x0000)  // 8 samples per second
#define ADS1115_REG_CONFIG_DR_16SPS    (0x0020)  // 16 samples per second
#define ADS1115_REG_CONFIG_DR_32SPS    (0x0040)  // 32 samples per second
#define ADS1115_REG_CONFIG_DR_64SPS    (0x0060)  // 64 samples per second
#define ADS1115_REG_CONFIG_DR_128SPS    (0x0080)  // 128 samples per second (default)
#define ADS1115_REG_CONFIG_DR_250SPS    (0x00A0)  // 250 samples per second
#define ADS1115_REG_CONFIG_DR_475SPS    (0x00C0)  // 475 samples per second
#define ADS1115_REG_CONFIG_DR_860SPS    (0x00E0)  // 860 samples per second


E fin qui tutto ok.
Nel file .cpp però tutte le funzioni hanno più o meno questa morfologia:

Code: [Select]

/**************************************************************************/
/*!
    @brief  Gets a single-ended ADC reading from the specified channel
*/
/**************************************************************************/
uint16_t Adafruit_ADS1015::readADC_SingleEnded(uint8_t channel) {
  if (channel > 3)
  {
    return 0;
  }
 
  // Start with default values
  uint16_t config = ADS1015_REG_CONFIG_CQUE_NONE    | // Disable the comparator (default val)
                    ADS1015_REG_CONFIG_CLAT_NONLAT  | // Non-latching (default val)
                    ADS1015_REG_CONFIG_CPOL_ACTVLOW | // Alert/Rdy active low   (default val)
                    ADS1015_REG_CONFIG_CMODE_TRAD   | // Traditional comparator (default val)
                    ADS1015_REG_CONFIG_DR_1600SPS   | // 1600 samples per second (default)
                    ADS1015_REG_CONFIG_MODE_SINGLE;   // Single-shot mode (default)

  // Set PGA/voltage range
  config |= m_gain;

  // Set single-ended input channel
  switch (channel)
  {
    case (0):
      config |= ADS1015_REG_CONFIG_MUX_SINGLE_0;
      break;
    case (1):
      config |= ADS1015_REG_CONFIG_MUX_SINGLE_1;
      break;
    case (2):
      config |= ADS1015_REG_CONFIG_MUX_SINGLE_2;
      break;
    case (3):
      config |= ADS1015_REG_CONFIG_MUX_SINGLE_3;
      break;
  }

  // Set 'start single-conversion' bit
  config |= ADS1015_REG_CONFIG_OS_SINGLE;

  // Write config register to the ADC
  writeRegister(m_i2cAddress, ADS1015_REG_POINTER_CONFIG, config);

  // Wait for the conversion to complete
  delay(m_conversionDelay);

  // Read the conversion results
  // Shift 12-bit results right 4 bits for the ADS1015
  return readRegister(m_i2cAddress, ADS1015_REG_POINTER_CONVERT) >> m_bitShift; 
}


Quello che vorrei fare è impostare anziché ADS1015_REG_CONFIG_DR_1600SPS la velocità che voglio io senza per forza scrivere ADS1115_REG_CONFIG_DR_860SPS nel file .cpp, rendendo valida questa libreria solo in questo caso specifico e non in "generale".

Conseguentemente ho la possibilità di variare anche il tempo di delay che aspetto per la conversione. La differenza sostanzialmente tra usare l 1015 e il 1115 è che nel primo ho un delay di 1 mS mentre nel secondo ho un delay di 8 mS. Ma con 860 SPS posso scendere a 2 mS. Anche qui, vorrei riuscire a capire come fare affinché il delay si regoli automaticamente in base alla velocità di campionamento scelta. Anche perché così ad occhio, la libreria è scritta per valori di default, mentre se cambio valori devo farlo sia per la velocità di campionamento sia per il delay.

Chiedo informazioni su come fare poiché di librerie ne so veramente poco, ed ho anche poca immaginazione derivante da poca pratica :D . Allego lo zip della libreria con il file .h al quale ho aggiunto le velocità per il 1115.

Grazie ragazzi!

ricki158

Buongiorno a tutti!

L'Arduino continua a non far girare il "loop" e non ne so il motivo.
I 5v li porto al pin Vcc dell'Arduino Pro Micro (schema elettrico in allegato), cioè a valle del regolatore di tensione interno, esattamente come sulla breadboard, mi ritrovo però circa la stessa tensione (circa 0.1 - 0.2 V in meno) sul pin RAW che è quello in entrata al regolatore di tensione e che è alimentato dalla presa USB, che però non collego!
Sui pin digitali ed analogici mi ritrovo la tensione di alimentazione oppure delle tensioni da 1.20 V.

Non so proprio che pesci pigliare e come risolvere questo problema.
Come mai il "loop" non gira?

Ho proprio bisogno di un vostro aiuto!

Riccardo

Etemenanki

Le tensioni di cui parli le trovi sia con la scheda inserita nell'altra, sia con la scheda disinserita ? ... non e' che usi per sbaglio uno dei pin di comunicazione per qualcos'altro ? (non controllare solo come hardware, anche nel software) ...
"Sopravvivere" e' attualmente l'unico lusso che la maggior parte dei Cittadini italiani,
sia pure a costo di enormi sacrifici, riesce ancora a permettersi.

MightyPegas

Allora…
Ti rispondo qui nel thread perché è una cosa di interesse generale…

Ho letto delle tue ultime peripezie per quanto riguarda la grafica, l'aggiornamento dei dati e il flickering e ho guardato il source.
Da subito ho visto che, pur ottenendo il risultato voluto, sbagliavi il sistema per cancellare il contenuto precedente.
Il sistema più veloce è la fillRect che, a seconda del chip della scheda, utilizza sistemi ottimizzati per scrivere sullo schermo. Nel tuo caso purtroppo il chip non ha di queste facilitazioni, ma la fillRect rimane comunque più veloce perché non deve comporre i caratteri leggendo dalla PGM_MEM e fare una marea di moltiplicazioni per rapportare al textSize, il tutto poi in aggiunta ad un'altra conversione float->ASCII.

Poi… andando a curiosare sulla libreria gfx (io ne usavo un'altra) ho trovato questo:

Code: [Select]

    // NOTE: THERE IS NO 'BACKGROUND' COLOR OPTION ON CUSTOM FONTS.
    // THIS IS ON PURPOSE AND BY DESIGN.  The background color feature
    // has typically been used with the 'classic' font to overwrite old
    // screen contents with new data.  This ONLY works because the
    // characters are a uniform size; it's not a sensible thing to do with
    // proportionally-spaced fonts with glyphs of varying sizes (and that
    // may overlap).  To replace previously-drawn text when using a custom
    // font, use the getTextBounds() function to determine the smallest
    // rectangle encompassing a string, erase the area with fillRect(),
    // then draw new text.  This WILL infortunately 'blink' the text, but
    // is unavoidable.  Drawing 'background' pixels will NOT fix this,
    // only creates a new set of problems.  Have an idea to work around
    // this (a canvas object type for MCUs that can afford the RAM and
    // displays supporting setAddrWindow() and pushColors()), but haven't
    // implemented this yet.


In pratica usando la fonte interna della libreria a dimensione fissa (quella che usi tu se non sbaglio) la libreria già di suo cancella il contenuto precedente in quanto scrive sia il colore in primo piano (il carattere) che lo sfondo. Naturalmente se il nuovo testo risulta più corto del precedente sulla destra ti potranno rimanere uno o più caratteri.
Ad esempio
scrivi "12.34"
e poi allo stesso punto scrivi "0.00"
sullo schermo avrai "0.004"

Ma questo è un problema facilmente risolvibile in diverse maniere.
Il sistema più semplice sarebbe stato tramite la sprintf che (anche se un po' lenta) con gli opportuni parametri avrebbe provveduto a tutto, ma purtroppo la sua implementazione in AVR GCC non supporta i float (e double).
Si deve ricorrere quindi alla dtostrf che trasforma un float/double in stringa (ma senza le opzioni di allineamento della sprintf).
In pratica devi stabilire a priori il numero di cifre max (nel caso dei volt ad es. 6 caratteri: 1 per il segno, 2 per i volt, 1 per il punto e 2 decimali).
Poi con la dtostrf trasformi il float in ascii dentro un buffer e conti i caratteri del risultato
Poi o posti il testo all'interno del buffer a dx e riempi a sx con gli spazi, oppure scrivi sullo schermo n spazi (la differenza tra il num. max di cifre e quelle che hai), calcoli le nuove coordinate e fai la print.

Quando cambi schermata (ad es. dai volt agli ampere) con la fillRect cancelli le aree interessate e scrivi i nuovi valori.

E ti liberi di una marea di codice :)

Uso quello che ho e quello che non ho lo invento!

ricki158

Quindi il "riempiere un rettangolo" è più veloce del "coloro solo i pixel accesi in quel rettangolo" ?
Comunque la libreria di suo non cancella il testo precedente, per questo ho fatto funzioni generiche parametriche che chiamo inserendo il colore e da dove prendere i valori, così posso cancellare facilmente i caratteri.
Al momento l'unica cosa che varia velocemente e che ha un certo flickering sono i volt e gli ampere che aggiorno il più velocemente possibile. Per il resto non ho problemi. Vorrei cercare di risolvere questi problemi imprevisti, dopodiché potrei pensare ad un'ultima ottimizzazione delle stampate, così da migliorare ancor di più la visualizzazione. Grazie intanto!

Go Up