Eliminare zeri non significativi

Buongiorno
Non avendo l'autorizzazione per creare nuovi argomenti provo a scrivere qua.
Sto realizzando un Voltmetro a 4 cifre ed Amperometro sempre a 4 cifre uno sopra l'altro sotto con un solo Max7219.
Per ora tutto bene ma volevo eliminare gli Zeri di sinistra ma appena ci provo tutto diventa instabile con comportamenti imprevedibili.
Non sono riuscito a trovare nulla sul forum che mi chiarisse questa cosa.
Qualcuno ha affrontato il problema?
Non ho nessun problema a postare il codice.
Non l'ho ancora fatto perché l'altra volta mi hanno sgridato.
La libreria è <LedControl.h>
Grazie in anticipo per i consigli
ms

Mmm ... strano, ma DOVE provavi a creare la nuova discussione? NON di certo nella radice della sezione Italiana, ma in una sotto sezione, come spiegato nel REGOLAMENTO al punto 16.8.

Comunque, ho separato io e creata la nuova discussione.

Probabilmente perché NON l'hai fatto come si deve fare ...

... inserisci e seleziona la parte di codice e premi l'icona <code/> nella barra degli strumenti per contrassegnarla come codice.
Inoltre assicurati di averlo correttamente indentato nell'IDE prima di inserirlo (questo lo si fa premendo ctrlT su un PC o cmd T su un Mac, sempre all'interno del IDE).

Guglielmo

Mi sembrava di aver fatto bene ma non aveva funzionato

#include <LedControl.h>

// Pin collegati al MAX7219
#define DIN_PIN 12
#define CLK_PIN 11
#define CS_PIN 10

// Inizializza l'oggetto LedControl
// Parametri: DIN, CLK, CS, numero di display
LedControl lc = LedControl(DIN_PIN, CLK_PIN, CS_PIN, 1);

// Pin analogici per voltmetro e amperometro
#define VOLT_PIN A0
#define AMP_PIN A1

// Variabili per calcolo tensione e corrente
float voltage = 0.0;
float current = 0.0;
const float VOLT_DIVIDER = 10.0;    // Fattore divisore per il partitore di tensione
const float AMP_CALIBRATION = 0.1;  // Calibrazione sensore corrente

void setup() {
  // Inizializza il MAX7219
  Serial.begin(9600);        //Per monitorare debugg
  analogReadResolution(14);  // Imposta la risoluzione ADC a 14 bit
  lc.shutdown(0, false);     // Accendi il display
  lc.setIntensity(0, 8);     // Imposta la luminosità (0-8)
  lc.clearDisplay(0);        // Cancella il display
}

void loop() {
  // Leggi tensione e corrente
  voltage = analogRead(VOLT_PIN) * (5.0 / 16383.0) * VOLT_DIVIDER;

  current = analogRead(AMP_PIN) * (5.0 / 16383.0) / AMP_CALIBRATION;

  // Mostra i valori

  displayVoltage(voltage);

  displayCurrent(current);

  /*Serial.println(voltage );//monitor seriale */
  delay(200);  // Aggiorna ogni 500 ms
}

void displayVoltage(float value) {
  // Conversione a intero con due decimali
  int val = round(value * 100);  // Usa round() per un arrotondamento preciso
  displayValue(val, 4);          // Mostra sul voltmetro
  Serial.print("Voltage: ");
  Serial.println(value, 2);  // Mostra con 2 decimali per debug
}

void displayCurrent(float value) {
  // Conversione a intero con due decimali
  int val = round(value * 100);  // Usa round() per un arrotondamento preciso
  displayValue(val, 0);          // Mostra sull'amperometro
  Serial.print("Current: ");
  Serial.println(value, 2);  // Mostra con 2 decimali per debug
}

void displayValue(int value, int offset) {
  // Mostra il valore sul display
  bool leadingZero = true;  // Flag per gli zeri iniziali
  for (int i = 0; i < 4; i++) {
    int digit = value % 10;

    value /= 10;
    if (digit == 0 && leadingZero && i > 0) {
      lc.setChar(0, i + offset, ' ', false);  // Mostra uno spazio vuoto
    } else {
      leadingZero = false;                       // Non siamo più in una parte con zeri iniziali
      lc.setDigit(0, i + offset, digit, false);  // Mostra la cifra
    }

    /*Serial.print("i: ");
  Serial.println(i);
   Serial.print("digit: ");
  Serial.println(digit);
   Serial.print("offset: ");
  Serial.println(offset);
  Serial.print("leadingZero: ");
  Serial.println(leadingZero);*/
  }
}

senz'altro sbaglio qualcosa anche nel pubblicare ma devo imparare .
Se le cose già le sapevo non mi sarei iscritto .

E NO, tu NON leggi quanto ti si scrive ... leggi quanto ti ho scritto e correggi il tuo post (quindi NON scrivendo un nuovo post, ma utilizzando il bottone a forma di piccola matita :pencil2: che si trova in basso del tuo post).

Guglielmo

P.S.: Ti ricordo che, purtroppo, fino a quando non sarà sistemato il codice come indicato, nel rispetto del regolamento nessuno ti risponderà (eventuali risposte o tuoi ulteriori post, verrebbero temporaneamente nascosti).

Guarda, senza complicarti la vita, c'è una funzione 'C' che fa di tutto e di più, la sprintf() ... per capire bene il valore dei parametri che si possono passare, guarda la printf() da cui deriva.

Studiatele bene perché spesso permettono di sistemare le stringhe (classiche del 'C') in modo molto semplice e veloce.

Guglielmo

P.S.: NON sono facilissime da capire e richiedono una attenta lettura e studio dei vari parametri ... del resto possono fare parecchie cose e sono abbastanza complesse.

Che board stai usando? Se un Arduino "classico" (Uno,nano,leonardo) meglio se per printf() e simili fai riferimento alla documentazione che trovi qui, perchè ci sono delle limitazioni rispetto all'implementazione classica (non funziona con i float).

Ciao, Ale.

... cosa facilmente ovviabile come scrissi a suo tempo QUI :wink:

Guglielmo

Si, io lo so, ma forse l'OP no.

Ciao, Ale.

1 Like

Per i float a suo tempo risolsi con questo piccolo workaround:

   sprintf(buf, "%d.%02d", int(val), int((val - int(val))*100.0));

... e noi glie lo diciamo :joy:

A parte scherzi, mi sa che l'OP, oltre tutto, sta usano una UNO R4 (almeno dalle sue altre discussioni) ... scheda a 32 bit dove non dovrebbero esserci limitazioni :wink:

Guglielmo

Grazie mille

Ciao
Uso Arduino Uno r4 minima
grazie

Grazie

Grazie
Se ho capito bene devo convertire il numero come stringa e poi manipolarlo.
Giusto?

SBAGLIATO ...
... e non seguire quello che dice docdoc che era per Arduino UNO R3 che era limitato nei float (cosa che non dovrebbe essere con Arduino UNO R4).

La sprintf(), se l'hai studiata, ti permette di creare una stringa con quello che vuoi tu ...
... nel tuo caso il valore numerico di lunghezza fissa (così occupa sempre lo stesso spazio sul display), con il numero di decimali che dici tu e, se non li chiedi espressamente, senza gli zeri iniziali.

Dopo di che ti resta che visualizzare la stringa sul display, il lavoro è già fatto.

Guglielmo

Grazie ci sto lavorando.
Leggo e rileggo e provo a scrivere dei codici per capirne il funzionamento

Decidi ... quante caratteri per la parte intera, quanti per la parte decimale il punto decimale e hai il segno? ... così calcoli la lunghezza totale, dopo di che gli dai la stringa di formattazione, il valore e la funzione ti restituisce la stringa pronta all'uso :wink:

Guglielmo

Grazie mi metto subito all'opera.
Vedo già con questo che se faccio passare un numero a tre cifre gli zeri non ci sono

#include <Arduino.h>
// Numero intero
int numero = 1234;

// Buffer per la stringa risultante
char buffer[10];
void setup() {
  Serial.begin(9600);



  // Converte l'intero in stringa
  sprintf(buffer, "%d", numero);

  // Stampa il risultato
  Serial.print("Il numero convertito in stringa è: ");
  Serial.println(buffer);
}

void loop() {
  Serial.print("Il numero convertito in stringa è: ");
  Serial.println(buffer);
  delay(1000);
}

Se hai un float 'f' che può avere al massimo 2 interi e vuoi 2 decimali mettici il . mettici, per sicurezza il segno aggiungi il terminatore di stringa, se dichiari una stringa 's' di destinazione di 8 caratteri vai sul sicuro e ...

sprintf(s, "%6.2f", f);

... ti dovrebbe dare il valore aspettato.

Guglielmo