Go Down

Topic: Array di frazionari (Read 6556 times) previous topic - next topic

nid69ita

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  :smiley-mr-green:
my name is IGOR, not AIGOR

Zanco

Code: [Select]
// 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.. ;)

leo72

Non compila perché queste 2 righe sono errate:
Code: [Select]
#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:
Code: [Select]
#define rabbocco 20
#define rabbocco_high 19



Altra cosa...
Code: [Select]
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   ;)

gpb01


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 ;)

Guglielmo
Search is Your friend ... or I am Your enemy !

Zanco

No no,infatti..Ho ringraziato in ogni caso.Volevo solo dire che comunque non funzionava.. ;) 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?

gpb01


... 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 ...  :smiley-roll:

Guglielmo
Search is Your friend ... or I am Your enemy !

Zanco

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

nid69ita

#22
Dec 22, 2013, 11:26 pm Last Edit: Dec 22, 2013, 11:28 pm by nid69ita Reason: 1
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ò.

Code: [Select]
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);

Code: [Select]

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]);
my name is IGOR, not AIGOR

leo72

Sai perché? Mea culpa, non mi ero accorto di una piccola sottigliezza quando si usano le define.
Ecco cosa ti avevo suggerito io:
Code: [Select]
#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.

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..

nid69ita


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()
my name is IGOR, not AIGOR

Zanco

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?

nid69ita


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
my name is IGOR, not AIGOR

Zanco

Code: [Select]
  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

nid69ita

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.
my name is IGOR, not AIGOR

Go Up