Array di frazionari

Ciao!Premetto che ho cercato risposta in più di un post senza trovarla.Ho bisogno di costruire un array di numeri frazionari, provenienti da un sensore, per poi farne la media e confrontarla con un valore soglia.Detto ciò, qui tra le istruzioni di Arduino trovo solo indicazioni per costruire un array di numeri interi.Dunque la sola cosa che mi viene in mente di fare è moltiplicare per 1000 ogni valore letto prima di salvarlo nell'array in modo che almeno le prime tre cifre decimali di ogni lettura vengano salvate, per poi dividere per 1000 la media così da riportarmi al valore corretto di lettura ma mi sembra davvero un trucco di basso livello.Voi cosa mi consigliate di fare?Come posso risolvere il problema?
Grazie.
Matteo

Ma chi l'ha detto che non puoi fare array di altri tipi ??? :astonished: :astonished: :astonished:

Esempio:

float myArray[5] = {0.15, 1.17, 12.15, 45.12, 10.5};

Solo stai attento alla precisione dei float (e dei double che, su Arduino, sono identici ai float) che sono a 32 bit. Vedi QUI ed in particolare alla frase :

"Floats have only 6-7 decimal digits of precision. That means the total number of digits, not the number to the right of the decimal point. Unlike other platforms, where you can get more precision by using a double (e.g. up to 15 digits), on the Arduino, double is the same size as float."

Guglielmo

Zanco:
.Detto ciò, qui tra le istruzioni di Arduino trovo solo indicazioni per costruire un array di numeri interi.

Probabilmente gli esempi sono solo per interi però non è certo un problema realizzare un array float basta scrivere "float pippo[n]" ove n è il numero totale di elementi.
In tutti i casi è sempre meglio lavorare con gli interi ove possibile, ovvero fino a che non devi fare calcoli trigonometrici, esponenziali, logaritmi, mi sembra strano che un sensore ti fornisce un float, normalmente forniscono solo valori interi, l'eventuale conversione in float è a carico del software utente.

gpb01:
Ma chi l'ha detto che non puoi fare array di altri tipi ??? :astonished: :astonished: :astonished:

Abbiamo risposto assieme :slight_smile:

Zanco:
...ma mi sembra davvero un trucco di basso livello.

Come detto da @astro e @guglielmo puoi usare array di float.
Però usare valori moltiplicati non è un trucco così stupido, anzi. In alcuni casi, ove applicabile perchè non necessari numeri grossi o con molti decimali, eviti di usare i float e la matematica tra float che per una cpu o mcu può essere un pò pesante. Ripeto, ove applicabile.

Grazie mille.In effetti mi funziona con float.Però non riesco a compilare il mio sketch.. =( Mi da un errore del tipo "error: expected primary-expression before '=' token" e non capisco il perché.Me lo da su un'intestazione di un ciclo if per cui proprio non ne trovo il senso..

Vado a naso.
Hai messo = invece di == ?

Il bello è proprio che ho messo > e non =..Per questo proprio mi è incomprensibile..

Zanco:
Il bello è proprio che ho messo > e non =..Per questo proprio mi è incomprensibile..

Sotto Natale mandiamo tutti le nostre sfere di cristallo a Babbo Natale perché servono a lui :slight_smile:
Senza vedere il codice è impossibile dire dove sta il problema.

Questo è tutto il codice..Non so se sia giusto postarlo qui così ma non so come fare altrimenti..

// Codice sorgente per rabbocco automatico in sump

#include <Time.h>           // Libreria per gestire l'orario (è residuo della mia intenzione di collegare a breve anche luci eccetera)

#include <TimeAlarms.h>     // Altra libreria per gestire l'orario


// Definisco le variabili del sensore a ultrasuoni

int arraysize = 10;                                      // Valori dell'array 10 letture

float rangevalue[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};    // Inizializzo l'array

long pulse;                                              // Tempo trascorso tra invio del segnale e lettura

long pulseiter;                                          // Pulse all'interno del ciclo while

long r;                                                  // Distanza misurata


const float v = 0.03434;                                 // Velocità del suono in centimetri al microsecondo

float modE;                                              // Variabile della media letta dal sensore a ultrasuoni

float modEiter;                                          // Variabile modE ridefinita all'interno del ciclo while

const int ledPin = 13;                                   // Definisco il pin che il sensore a ultrasuoni attiva (qui collego il relè della pompa)

const int triggerPort = 7;                               // Definisco il pin da cui mandare l'impulso

const int echoPort = 8;                                  // Definisco il pin da cui leggere il segnale degli ultrasuoni

#define rabbocco = 20;                                   // Valore inferiore di soglia a sump piena

#define rabbocco_high = 19;                              // Valore superiore di soglia a sump piena (distanza minore dal sensore per evitare di farlo attaccare ad ogni secondo:gli concedo uno scarto di un centimetro)

void setup() {

              Serial.begin(9600);                       // Apro una connessione seriale (nel caso poi collegassi uno schermo o anche solo per visualizzare i dati sul pc)

              delay(500);                               // Attendo apertura connessione

              pinMode( triggerPort, OUTPUT );           // Definisco il trigger come pin da cui inviare il segnale

              pinMode( echoPort, INPUT );               // Definisco l'echo come pin da cui ricevere il segnale
              
              pinMode(ledPin, OUTPUT);                  // Definisco il pin del relè della pompa come pin di out
               
             }

void loop() { 

              for(int i = 0; i < arraysize; i++) {    

                                                   digitalWrite( triggerPort, LOW );   // Porta bassa l'uscita del trigger
 
                                                   digitalWrite( triggerPort, HIGH );  // Invio un impulso di 10 microsecondi al trigger

                                                   delayMicroseconds( 10 );

                                                   digitalWrite( triggerPort, LOW );
 
                                                   pulse = pulseIn( echoPort, HIGH );
 
                                                   r = v * pulse / 2;

                                                   rangevalue[i] = r;                  // Vado a tarare il sensore ad ultrasuoni (58 è un numero a caso in quanto il sensore è ancora in viaggio ma quando arriverà farò un test per sapere l'uscita per ogni cm)

                                                   modE += rangevalue[i];

                                                   delay(10);                          // Tempo che attende prima della nuova lettura

                                                 }
                                                 
char Valori[1000];

sprintf(Valori,  "Ultimi valori letti: %f,%f,%f,%f,%f,%f,%f,%f,%f,%f", rangevalue[1], rangevalue[2], rangevalue[3], rangevalue[4], rangevalue[5], rangevalue[6], rangevalue[7], rangevalue[8], rangevalue[9], rangevalue[10]); 

Serial.print(Valori);   // Stampo i valori letti nel caso in cui ci fosse una connessione attiva
      
modE = modE/10;

Serial.print("La media dei valori letti è: ");

Serial.print(modE);

delay(1000);



// Dichiaro quando accendere la pompa di rabbocco

if(modE > rabbocco) {                                // Se il valore modE è maggiore del valore scelto per l'acqua in sump                    

modEiter = modE;

   while (modEiter>rabbocco_high) {

      digitalWrite(ledPin, HIGH);                    // Attivo relè pompa
      
          digitalWrite( triggerPort, LOW );          // Porta bassa l'uscita del trigger
 
          digitalWrite( triggerPort, HIGH );         // Invio un impulso di 10 microsecondi al trigger

          delayMicroseconds( 10 );

          digitalWrite( triggerPort, LOW );
 
          pulseiter = pulseIn( echoPort, HIGH );
 
          modEiter = v * pulseiter / 2;
      
      delay (500);

    }
  
   digitalWrite(ledPin, LOW);     // Raggiunto il livello spegni la pompa
  
}

    else {                        // Se modE è minore di rabbocco

    digitalWrite(ledPin, LOW);    // Spegni la pompa

    }

}

Di errori ce ne sono tanti, a partire dal fatto che cerchi di assegnare ad un array un valore senza specificare l'indice.
Mi pare di capire che stai usano un normale sonar per acquisire delle distanze, che diavolo ci devi fare con i float visto che il valore misurato è un periodo, numero intero, e al limite lo converti in una distanza in mm, sempre un numero intero.

@Zanzo DEVI mettere il codice negli appositi tag, altrimenti alcune parti diventano illeggibili (ad esempio le quadre)

il codice va nei tag code: [ code] codice [/ code] senza spazi, li ho messi per farti capire.

// Codice sorgente per rabbocco automatico in sump

#include <Time.h>           // Libreria per gestire l'orario (è residuo della mia intenzione di collegare a breve anche luci eccetera)

#include <TimeAlarms.h>     // Altra libreria per gestire l'orario


// Definisco le variabili del sensore a ultrasuoni

int arraysize = 10;                                      // Valori dell'array 10 letture

float rangevalue[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};    // Inizializzo l'array

long pulse;                                              // Tempo trascorso tra invio del segnale e lettura

long pulseiter;                                          // Pulse all'interno del ciclo while

long r;                                                  // Distanza misurata


const float v = 0.03434;                                 // Velocità del suono in centimetri al microsecondo

float modE;                                              // Variabile della media letta dal sensore a ultrasuoni

float modEiter;                                          // Variabile modE ridefinita all'interno del ciclo while

const int ledPin = 13;                                   // Definisco il pin che il sensore a ultrasuoni attiva (qui collego il relè della pompa)

const int triggerPort = 7;                               // Definisco il pin da cui mandare l'impulso

const int echoPort = 8;                                  // Definisco il pin da cui leggere il segnale degli ultrasuoni

#define rabbocco = 20;                                   // Valore inferiore di soglia a sump piena

#define rabbocco_high = 19;                              // Valore superiore di soglia a sump piena (distanza minore dal sensore per evitare di farlo attaccare ad ogni secondo:gli concedo uno scarto di un centimetro)

void setup() {

              Serial.begin(9600);                       // Apro una connessione seriale (nel caso poi collegassi uno schermo o anche solo per visualizzare i dati sul pc)

              delay(500);                               // Attendo apertura connessione

              pinMode( triggerPort, OUTPUT );           // Definisco il trigger come pin da cui inviare il segnale

              pinMode( echoPort, INPUT );               // Definisco l'echo come pin da cui ricevere il segnale
              
              pinMode(ledPin, OUTPUT);                  // Definisco il pin del relè della pompa come pin di out
               
             }

void loop() { 

              for(int i = 0; i < arraysize; i++) {    

                                                   digitalWrite( triggerPort, LOW );   // Porta bassa l'uscita del trigger
 
                                                   digitalWrite( triggerPort, HIGH );  // Invio un impulso di 10 microsecondi al trigger

                                                   delayMicroseconds( 10 );

                                                   digitalWrite( triggerPort, LOW );
 
                                                   pulse = pulseIn( echoPort, HIGH );
 
                                                   r = v * pulse / 2;

                                                   rangevalue[i] = r;                  // Vado a tarare il sensore ad ultrasuoni (58 è un numero a caso in quanto il sensore è ancora in viaggio ma quando arriverà farò un test per sapere l'uscita per ogni cm)

                                                   modE += rangevalue[i];

                                                   delay(10);                          // Tempo che attende prima della nuova lettura

                                                 }
                                                 
char Valori[1000];

sprintf(Valori,  "Ultimi valori letti: %f,%f,%f,%f,%f,%f,%f,%f,%f,%f", rangevalue[1], rangevalue[2], rangevalue[3], rangevalue[4], rangevalue[5], rangevalue[6], rangevalue[7], rangevalue[8], rangevalue[9], rangevalue[10]); 

Serial.print(Valori);   // Stampo i valori letti nel caso in cui ci fosse una connessione attiva
      
modE = modE/10;

Serial.print("La media dei valori letti è: ");

Serial.print(modE);

delay(1000);



// Dichiaro quando accendere la pompa di rabbocco

if(modE > rabbocco) {                                // Se il valore modE è maggiore del valore scelto per l'acqua in sump                    

modEiter = modE;

   while (modEiter>rabbocco_high) {

      digitalWrite(ledPin, HIGH);                    // Attivo relè pompa
      
          digitalWrite( triggerPort, LOW );          // Porta bassa l'uscita del trigger
 
          digitalWrite( triggerPort, HIGH );         // Invio un impulso di 10 microsecondi al trigger

          delayMicroseconds( 10 );

          digitalWrite( triggerPort, LOW );
 
          pulseiter = pulseIn( echoPort, HIGH );
 
          modEiter = v * pulseiter / 2;
      
      delay (500);

    }
  
   digitalWrite(ledPin, LOW);     // Raggiunto il livello spegni la pompa
  
}

    else {                        // Se modE è minore di rabbocco

    digitalWrite(ledPin, LOW);    // Spegni la pompa

    }

}

Ora dovrebbe essere corretto.Il punto è che comunque, convertendo il tempo di ritorno dell'onda in spazio per mezzo della velocità del suono il valore non mi viene certo intero a meno di una probabilità su infinite.Per questo li definisco come float..Al di là di ciò che, fatto solo per avere una maggiore accuratezza, comunque dubito essere il problema, non riesco a compilare questo codice senza capirne il motivo..Dimmi quali sono questi errori così posso correggerli..

Nessuno mi sa aiutare?

Zanco, due cose ...
.. uno, inizializza correttamente i float come float, NON così :

float rangevalue[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};    // Inizializzo l'array

ma così :

float rangevalue[] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};    // Inizializzo l'array

... e solo una formalità, ma a volte ... ti evita problemi.

... due, usa l'apposita funzione (Tools -> Auto Format) dell'IDE per riformattare il sorgete che così è ILLEGIBILE (... ma chi ti ha suggerito di incolonnarti SOTTO le parenti graffe a scrivere ??? :astonished: :astonished: :astonished:) e ripostalo ben formattato.

Guglielmo

Ti suggerirei di non mettere una riga vuoto sotto ogni istruzione. Il codice diventa lunghissimo da leggere.
Mi ricorda quando nei temi a scuola scrivevo più grosso per far sembrare il tema più lungo :grin:

// Codice sorgente per rabbocco automatico in sump

#include <Time.h>           // Libreria per gestire l'orario (è residuo della mia intenzione di collegare a breve anche luci eccetera)

#include <TimeAlarms.h>     // Altra libreria per gestire l'orario


// Definisco le variabili del sensore a ultrasuoni

int arraysize = 10;                                      // Valori dell'array 10 letture

float rangevalue[] = { 
  0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};                         // Inizializzo l'array

long pulse;                                              // Tempo trascorso tra invio del segnale e lettura

long pulseiter;                                          // Pulse all'interno del ciclo while

long r;                                                  // Distanza misurata


const float v = 0.03434;                                 // Velocità del suono in centimetri al microsecondo

float modE;                                              // Variabile della media letta dal sensore a ultrasuoni

float modEiter;                                          // Variabile modE ridefinita all'interno del ciclo while

const int ledPin = 13;                                   // Definisco il pin che il sensore a ultrasuoni attiva (qui collego il relè della pompa)

const int triggerPort = 7;                               // Definisco il pin da cui mandare l'impulso

const int echoPort = 8;                                  // Definisco il pin da cui leggere il segnale degli ultrasuoni

#define rabbocco = 20;                                   // Valore inferiore di soglia a sump piena

#define rabbocco_high = 19;                              // Valore superiore di soglia a sump piena (distanza minore dal sensore per evitare di farlo attaccare ad ogni secondo:gli concedo uno scarto di un centimetro)

void setup() {

  Serial.begin(9600);                       // Apro una connessione seriale (nel caso poi collegassi uno schermo o anche solo per visualizzare i dati sul pc)

  delay(500);                               // Attendo apertura connessione

  pinMode( triggerPort, OUTPUT );           // Definisco il trigger come pin da cui inviare il segnale

  pinMode( echoPort, INPUT );               // Definisco l'echo come pin da cui ricevere il segnale

  pinMode(ledPin, OUTPUT);                  // Definisco il pin del relè della pompa come pin di out

}

void loop() { 

  for(int i = 0; i < arraysize; i++) {    

    digitalWrite( triggerPort, LOW );   // Porta bassa l'uscita del trigger

    digitalWrite( triggerPort, HIGH );  // Invio un impulso di 10 microsecondi al trigger

    delayMicroseconds( 10 );

    digitalWrite( triggerPort, LOW );

    pulse = pulseIn( echoPort, HIGH );

    r = v * pulse / 2;

    rangevalue[i] = r;                  // Vado a tarare il sensore ad ultrasuoni (58 è un numero a caso in quanto il sensore è ancora in viaggio ma quando arriverà farò un test per sapere l'uscita per ogni cm)

    modE += rangevalue[i];

    delay(10);                          // Tempo che attende prima della nuova lettura

  }

  char Valori[1000];

  sprintf(Valori,  "Ultimi valori letti: %f,%f,%f,%f,%f,%f,%f,%f,%f,%f", rangevalue[1], rangevalue[2], rangevalue[3], rangevalue[4], rangevalue[5], rangevalue[6], rangevalue[7], rangevalue[8], rangevalue[9], rangevalue[10]); 

  Serial.print(Valori);   // Stampo i valori letti nel caso in cui ci fosse una connessione attiva

  modE = modE/10;

  Serial.print("La media dei valori letti è: ");

  Serial.print(modE);

  delay(1000);



  // Dichiaro quando accendere la pompa di rabbocco

  if(modE > rabbocco) {                                // Se il valore modE è maggiore del valore scelto per l'acqua in sump                    

    modEiter = modE;

    while (modEiter>rabbocco_high) {

      digitalWrite(ledPin, HIGH);                    // Attivo relè pompa

      digitalWrite( triggerPort, LOW );          // Porta bassa l'uscita del trigger

      digitalWrite( triggerPort, HIGH );         // Invio un impulso di 10 microsecondi al trigger

      delayMicroseconds( 10 );

      digitalWrite( triggerPort, LOW );

      pulseiter = pulseIn( echoPort, HIGH );

      modEiter = v * pulseiter / 2;

      delay (500);

    }

    digitalWrite(ledPin, LOW);     // Raggiunto il livello spegni la pompa

  }

  else {                        // Se modE è minore di rabbocco

    digitalWrite(ledPin, LOW);    // Spegni la pompa

  }

}

Ho fatto quanto mi è stato detto ma certo questo non cambia nulla.Quelle sono solamente formalità..Infatti non compila..Ad ogni modo grazie dei consigli.Sono sempre ben accetti.. :wink:

Non compila perché queste 2 righe sono errate:

#define rabbocco = 20;  
#define rabbocco_high = 19;

Le define NON si fanno con l'uguale né la virgola ma scrivendo direttamente il valore da sostituire:

#define rabbocco 20
#define rabbocco_high 19

Altra cosa...

char Valori[1000];

Spero tu stia scherzando... usare 1000 byte di RAM su una CPU che di suo ne ha solo 2048... e dove in quell'altro singolo K che avanza ci devono stare tutte le altre variabili (ogni float prende 4 posti), gli array dinamici che hai dichiarato nonché le stringhe di testo che usi per le Serial è farsi del vero harakiri :wink:

Zanco:
Ho fatto quanto mi è stato detto ma certo questo non cambia nulla.Quelle sono solamente formalità..Infatti non compila.

Ovvio ... ti è stato detto che erano formalità, sia per evitare possibili errori, sia ... per rendere leggibile il codice , tanto è vero che, come esso è diventato più leggibile, Leo ti ha già individuato una seri di errori !

Perdona, ma non molti sono disposti a dedicare del tempo a qualche cosa scritta in modo illeggibile ... per questo delle semplici "formalità" sono comunque importanti :wink:

Guglielmo

No no,infatti..Ho ringraziato in ogni caso.Volevo solo dire che comunque non funzionava.. :wink: Siete davvero disponibili!!Grazie mille..Ora correggo e provo a vedere se funziona.Riguardo al 1000 è un valore che ho messo pressochè a caso perchè se lasciavo le parentesi vuote è sbagliato e volevo solo vedere se funzionava il codice per poi chiedere consiglio a voi sul valore..Che valore dovrei mettere?