Array di frazionari

@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?

Zanco:
... 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?

Mmmm ... io intato prima di tutto mi accerterei che la sprintf() su Arduino sia implementata per i float perché, se ben ricordo, per ragioni di spazio, NON lo è e allora ... otterrai solo 10 bei punti interrogativi come output ... :roll_eyes:

Guglielmo

Ho scritto il define nel modo corretto ma niente..Mi dava sempre lo stesso errore, l'if non gli andava bene.Allora,dopo aver letto un consiglio di Leo dato sul forum dove diceva che è sempre meglio usare const invece che define ho provato a sostituire..rullo di tamburi..FUNZIONA!!!!Nel senso che compila..Resta da capire la dimensione da dare invece del 1000 e poi questa storia dello sprintf..Dove posso verificare se funziona anche con dei float o meno?
Matteo

Ti confermo cha la sprintf() non capisce il %f (i float) perchè quella parte della libreria per questa MCU è stata tagliata in quanto troppo pesante.
Puoi convertire i numeri usando dtostrf(), oppure sfrutti la Serial.print(), lei accetta i float.
Devi spezzare tutta la frase però.

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);
Serial.print("Ultimi valori letti: ");
Serial.print(rangevalue[1]); Serial.print(",");
Serial.print(rangevalue[2]); Serial.print(","); 
Serial.print(rangevalue[3]); Serial.print(",");
...
Serial.println(rangevalue[10]);

Sai perché? Mea culpa, non mi ero accorto di una piccola sottigliezza quando si usano le define.
Ecco cosa ti avevo suggerito io:

#define rabbocco 20
#define rabbocco_high 19

E' sbagliato!! =( =(
Devi sapere che il compilatore prende ciò che segue una define e lo sostituisce in toto in tutto il testo, senza controllare.
Siccome rabbocco_high viene dopo il primo define, in realtà rabbocco_high diventava 20_high per via del define precedente. Quindi nel testo succedeva di tutto perché rabbocco_high non esisteva più per sostituirlo con 19.... era 20_high, che messo a caso nel testo provocava errori. Di lì il macello.

Comunque proprio per evitare questi problemi, conviene sempre usare le costanti.

Ma riguardo al 1000 che mi dite?Ad ogni modo dtostrf mi sembra di capire che possa dare in output un solo valore alla volta.Sbaglio?Invece con serial.print come faccio a stampare un array?Ho provato a dirgli semplicemente serial.print(array) ma non funziona..

Zanco:
Ma riguardo al 1000 che mi dite?Ad ogni modo dtostrf mi sembra di capire che possa dare in output un solo valore alla volta.Sbaglio?Invece con serial.print come faccio a stampare un array?Ho provato a dirgli semplicemente serial.print(array) ma non funziona..

Per il 1000 direi metti solo 100.
Per l'altro, te l'ho scritto sopra come fare, replay #22. Stampi un valore alla volta con print() e l'ultimo con println()

Però così me li mette uno sotto l'altro,non su una riga..Giusto?Eventualmente tenendo sprintf se il glieli passo tutti come %d mi stampa solo le parti intere pur essendo dei float e quindi permettendomi di calcolare tutto in modo preciso e solo stampare in modo più approssimato o proprio non lo fa perchè sono dei float?

Zanco:
Però così me li mette uno sotto l'altro,non su una riga..Giusto?

Errato. Solo con la println() va a capo, con la print() prosegue sulla stessa riga

  Serial.print("Gli ultimi valori letti sono:");
  
  Serial.print(rangevalue[1]);
  Serial.print(rangevalue[2]);
  Serial.print(rangevalue[3]);
  Serial.print(rangevalue[4]);
  Serial.print(rangevalue[5]);
  Serial.print(rangevalue[6]);
  Serial.print(rangevalue[7]);
  Serial.print(rangevalue[8]);
  Serial.print(rangevalue[9]);
  Serial.println(rangevalue[10]);

Questo è ciò che ho scritto,compila e dunque sono fiducioso sul fatto che possa essere corretto.Per cui ringrazio davvero tutti per l'aiuto.Siete veramente disponibili..
Matteo

Tieni solo conto che scritti così i numeri saranno tutti appiccicati l'uno all'altro. Devi mettere una print con uno spazio o una virgola per separarli.