Campionamenti valori analogici su array

@docsavage:
esatto, era proprio quello che intendevo

@washe850:

E il K&R cos'è?

Secondo alcuni è "IL" libro. Anche docsavage con la frase "quello che non è scritto nel K&R non serve saperlo" lascia intuire di essere fra questi.

Guarda...

ok si l'ho scaricato e ho guardato un attimo dove parla di cicli for e di array..
chiaramente me lo guardo con un po più di serietà..

ma comunque siamo d'accordo nel dire che:

int anemometro;
int valori[5];
int tempo=1000;

void setup() {
Serial.begin(9600);
}

void loop() {
  anemometro=analogRead(A0);
  for (int i=0;i<6;i++) {
    valori[i]=analogRead(A0);
    Serial.println(valori[i]);
    delay(tempo);
  }
  }

campiona 6 valori nell'array e me li stampa in sequenza sul monitor seriale?

Sono 20 post che lo dico...

int pippo[5];

dichiara un array di CINQUE elementi, numerati da 0 a 4. Convincitene.

Un array da 10 elementi si dimensiona con

int cavolo[10];

contiene 10 elementi, il PRIMO INDICE è 0 e l'ULTIMO INDICE è 9

quindi un array di N elementi ha ULTIMO INDICE N-1 e si dimensiona indicando N

La confusione forse ti deriva dall'uso di altri linguaggi.

se in BASIC dimensioni

dim cavolo(10)

questo ti fornisce un array con ULTIMO INDICE 10 ma con 11 ELEMENTI visto che esiste anche l'elemento 0

in BASIC quando dimensioni l'array fornisci L'INDICE pià alto
in C quando dimensioni l'array fornisci QUANTI elementi contiene

SukkoPera:
Sono 20 post che lo dico...

int pippo[5];

dichiara un array di CINQUE elementi, numerati da 0 a 4. Convincitene.

si questo di averlo capito per bene... in pratica non avevo chiarissimo il conteggio nel for, proprio per via dell'index0.
in pratica quindi nel for sarà presente un numero di ripetizioni pari al numero indicato nella quadra dell'array, nel caso in cui io voglia riempire l'array di tutti i valori, quindi:

int anemometro;
int valori[5];
int tempo=1000;

void setup() {
Serial.begin(9600);
}

void loop() {
  anemometro=analogRead(A0);
  for (int i=0;i<5;i++) {
    valori[i]=analogRead(A0);
    Serial.println(valori[i]);
    delay(tempo);
  }
  }
 
[code]
giusto?

quindi ho riscritto il codice così

int anemometro;
int misure[6];
int tempo=1000;
int tempo2=2000;
int somma;
float media;
void setup() {
  Serial.begin(9600);
}

void loop() {
  
 anemometro= analogRead(A0);
 for (int i=0;i<6;i++){
  Serial.println( );
  Serial.println("inizio sequenza");
  for (int i=0;i<6;i++){
  misure[i]=analogRead(A0);
   Serial.println(misure[i]);
  delay(tempo);
  }
  Serial.println("fine sequenza");
  Serial.println("la media degli ultimi 6 campionamenti è ");
  media=(misure[6]/6);
  Serial.print(media );
  delay(tempo2);
 }
 }

e funziona così:
monitor seriale.
inizio sequenza
valore1 (es 300)
valore2 (es 280)
valore3 (es 300)
valore4 (es 290)
valore5 (es 295)
valore6 (es 285)
fine sequenza
la media degli ultimi 6 campionamenti è 50
e riparte con una nnuova sequenza.
ora ho due tipi di problemi.
il più evidente è che la media non può essere 50, ma un valore intorno a 300.
quindi ho provato, nella riga di codice dove dico
media=(misure[6]/6);
a sostituire misure[6] con misure ma ottengo un valore ancora più basso, tipo 16.
il secondo problema è che questi valori dell'array li ottengo quando l'anemometro è scollegato. se lo collego, tipo adesso ad esempio che non c'è vento e quindi è fermo, ottengo valori che si aggirano intorno all'80, ma non dovrebbero essere 0?

washe850:
quindi ho riscritto il codice così

int anemometro;

int misure[6];
int tempo=1000;
int tempo2=2000;
int somma;
float media;
void setup() {
  Serial.begin(9600);
}

void loop() {
 
anemometro= analogRead(A0);
for (int i=0;i<6;i++){
  Serial.println( );
  Serial.println("inizio sequenza");
  for (int i=0;i<6;i++){
  misure[i]=analogRead(A0);
  Serial.println(misure[i]);
  delay(tempo);
  }
  Serial.println("fine sequenza");
  Serial.println("la media degli ultimi 6 campionamenti è ");
  media=(misure[6]/6);
  Serial.print(media );
  delay(tempo2);
}
}




e funziona così:
monitor seriale.
inizio sequenza
valore1 (es 300)
valore2 (es 280)
valore3 (es 300)
valore4 (es 290)
valore5 (es 295)
valore6 (es 285)
fine sequenza
la media degli ultimi 6 campionamenti è 50
e riparte con una nnuova sequenza.
ora ho due tipi di problemi.
il più evidente è che la media non può essere 50, ma un valore intorno a 300.
quindi ho provato, nella riga di codice dove dico 
media=(misure[6]/6);
a sostituire misure[6] con misure *ma ottengo un valore ancora più basso, tipo 16.*
*il secondo problema è che questi valori dell'array li ottengo quando l'anemometro è scollegato. se lo collego, tipo adesso ad esempio che non c'è vento e quindi è fermo, ottengo valori che si aggirano intorno all'80, ma non dovrebbero essere 0?*
*[/quote]*

PER CORREGGERE
ho provato a sostituire misure[6]
con

misure[i]

ma ottengo una media ancora più bassa.

allora mi sono accorto che stavo tralasciando il fatto che avevo dichiarato anche una variabile

somma

così ho fatto

void loop() {
  
 anemometro= analogRead(A0);
 for (int i=0;i<6;i++){
  Serial.println( );
  Serial.println("inizio sequenza");
  for (int i=0;i<6;i++){
  misure[i]=analogRead(A0);
   Serial.println(misure[i]);
  delay(tempo);
  }
  Serial.println("fine sequenza");
  Serial.println("la media degli ultimi 6 campionamenti è ");
  somma=0;
  somma=somma+(misure[6]);
  media=(somma/6);
  Serial.print(media );
  delay(tempo2);
 }
 }

ma non cambia nulla.
immagino perchè l'istruzione somma=somma+(misure[6]);
non fa fare la somma..

ciao

Ti è già stato detto prima:

int misure[6];

crei un array di 6 elementi: da misure[0] a misure[5].

Quel misure[6] non so proprio cosa possa contenere.

Per ottenere una media si sommano tutti o valori e si divide il risulato pe il numero di valori.
Non è quello che hai scritto tu (o meglio: lo hai scritto nel posto sbagliato).

ciao
pippo72

ciao pippo 72
infatti, ho fatto un altro for per il calcolo somma e adesso funziona e mi da la media corretta

int anemometro;
int misure[6];
int tempo=1000;
int tempo2=2000;
int somma;
float media;
void setup() {
  Serial.begin(9600);
}

void loop() {
  
 anemometro= analogRead(A0);
 for (int i=0;i<6;i++){
  Serial.println( );
  Serial.println("inizio sequenza");
  for (int i=0;i<6;i++){
  misure[i]=analogRead(A0);
   Serial.println(misure[i]);
  delay(tempo);
  }
  Serial.println("fine sequenza");
  Serial.println("la media degli ultimi 6 campionamenti è ");
  somma=0;
  for (int i=0;i<6;i++){
  somma=somma+(misure[i]);
  }
  media=(somma/6);
  Serial.print(media );
  delay(tempo2);
  }
 }

ma comunque perchè se l'anemoemtro non gira non mi dà "0" come misurazione, ma circa 80?

Buongiorno a tutti! eccomi di nuovo. Sinceramente per le ventoline non saprei.. le ho provate con il tester sul banco spinte dalla pistola del compressore e partono entrambe da zero volts fino a 8 volts con il massimo della potenza che il compressore è in grado di fornire.. va bè l'importante in fin dei conti è che funzioni bene quella ventolina che ho installato fuori e che verrà montata sulla pala.

Detto questo, ritornando al programma, ora ho un programma funzionante che mi calcola la media ei valori degli ultimi campionamenti.
Adesso vorrei creare un'ulteriore media delle ultime 4 medie. Quindi un nuovo ciclo for formato da 4 elementi che chiamomedia2[4]
Sostanzialmente, dovrà essere strutturato come il ciclo for che mi è stato suggerito credo sempre da docSavage, in cui l'ultimo elemento dell'array è sempre nuovo ad ogni ciclo, e gli altri 3 sono il risultato della media delle medie precedenti. la struttura dovrà essere qualcosa del genere se non ho capito male:

int anemometro;
int media2[4];
int tempo=1000;
void setup () {
Serial.begin (9600);
}
void loop () {
for (int i=0;i <4;i++) {
Serial.println (valori [i]=media); \\dove la media è l'ultima media calcolata
delay (tempo);
}

delay(un valore);
}

Ora, il mio problema è capire DOVE inserire questo nuovo ciclo for, mi viene da pensare che bisogna metterlo a cascata con l'ultimo, dove viene calcolata la media dei campionamenti.. più o meno così

int anemometro;
int misure[6];
int misure2[4];
int tempo=1000;
int tempo2=2000;
int somma;
float media;
int somma2;
float media2;
void setup() {
  Serial.begin(9600);
}

void loop() {
 
 anemometro= analogRead(A0);
 for (int i=0;i<6;i++){
  Serial.println( );
  Serial.println("inizio sequenza");
  for (int i=0;i<6;i++){
  misure[i]=analogRead(A0);
   Serial.println(misure[i]);
  delay(tempo);
  }
  Serial.println("fine sequenza");
  Serial.println("la media degli ultimi 6 campionamenti è ");
  somma=0;
  for (int i=0;i<6;i++){
  somma=somma+(misure[i]);

  }
for (int i=0;i <3;i++) {
Serial.println (misure2[i]=media);
somma2=0;
somma2=somma2+misure2[i]);
delay (tempo);
}
  media=(somma/6);
  Serial.print(media );
Serial.println("la media delle ultime 4 medie è ");
media2=(somma2/4);
Serial.print(media2);
  delay(tempo2);
  }
 }

potrebbe essere corretto? ora provo a vedere cosa mi dice il compilatore

come non detto non andava per niente bene, e ho modificato in questo modo che si avvicina molto di più al risultato che vorrei ottenere. innanzitutto non avevo necessità che mi visualizzasse i valori dell'array valori2, quindi ho tolto il Serial.print, ed era anche sbagliato il comando di assegnazione dell'array stesso.

int anemometro;
int misure[6];
int misure2[4];
int tempo=1000;
int tempo2=2000;
int somma;
float media;
int somma2;
float media2;
void setup() {
  Serial.begin(9600);
}

void loop() {
 
 anemometro= analogRead(A0);
 for (int i=0;i<6;i++){
  Serial.println( );
  Serial.println("inizio sequenza");
  for (int i=0;i<6;i++){
  misure[i]=analogRead(A0);
   Serial.println(misure[i]);
  delay(tempo);
  }
  Serial.println("fine sequenza");
  Serial.println("la media degli ultimi 6 campionamenti è ");
  somma=0;
  for (int i=0;i<6;i++){
  somma=somma+(misure[i]);
    media=(somma/6);
  Serial.print(media );

  }
for (int i=0;i <3;i++) {
misure2[i]=media;
somma2=0;
somma2=somma2+(misure2[i]);
delay (tempo);
}

Serial.println("la media delle ultime 4 medie è ");
media2=(somma2/4);
Serial.print(media2);
  delay(tempo2);
  }
 }

ancora non è perfetto perchè:
quando mi stampa la media mi da un valore sbagliatissimo tipo:
000.000 000.00 0.0000 00.00 qualcosa del genere;
in secondo luogo non sono sicuro che l'array valori2 sia effettivamente formato dalle medie precedenti, ma anche di come faccia (al quinto ciclo) a tenere in memoria le ultime 3 medie, inserire nel quarto elemento la media corrente e calcolare così la media2.
spero di essere stato abbastanza chiaro.

fatta qualche modifica con alcuni delay e alcuni Serial.print, ma sopratutto, riscritto il ciclo for dell'array valori2 così

for (int i=0;i <3;i++) {
misure2[i]=media;
somma2=0;
somma2=somma2+(misure2[i]);
}
Serial.println();
Serial.print("la media delle ultime 4 medie è ");
media2=(somma2/4);
Serial.print(media2);
  delay(tempo);

vorrei farvi vedere la schermata del monitor seriale. è possibile allegare una foto? c'è l'icona insert an image ma non saprei come indicargli il percorso... ce l'ho sul desktop..

perché preferisco fare una media delle ultime 4 medie? Perché se per caso una improvvisa folata di vento mi fa schizzare una media oltre la soglia limite, non deve bastare per attivare il freno, ma se questa misura oltre limite dura per almeno 3 delle ultime 4 medie, allora si può ritenere altamente probabile che sia il vento sia costantemente oltre limite, e quindi inviare un comando al freno.
Qualcosa del tipo:

switch (media2[4]) 
{ case1: //  3 delle ultime medie su 4
// tipica situazione di vento in crescita mediamente pericoloso
// attivazione freno
// lettura direttamente da analogRead (A0) per attivazione e rilascio freno
break;
case2: //  4 delle ultime 4 medie
// vento forte costante pericoloso
// attivazione freno 
// attivazione bloccaggio definitivo con ingranaggio su ruota dentata o perno
// rilascio freno
// lettura direttamente da analogRead (A0) per l'apertura del bloccaggio definitivo
// e ripartenza dall'inizio
break;
case3: // 1 o 2 delle ultime 4 medie
// vento non pericoloso con qualche folata, tipico del vento in mollata
// non fare nulla
break;
}

Dovrebbe essere tutto qua .. a occhio mi sembra sufficiente.
Naturalmente devo prima implementare:
1 motore passo passo, o dc con vite senza fine, che attiva il freno;
1 motore passo passo che aziona un perno pneumatico per il bloccaggio definitivo

salve Docsavage.
che dire, gli sketch sono ovviamente entrambi validissimi, io naturalmente non conoscendo linguaggio mi sono fatto uno schema mentale diverso, concettualmente mi ero avvicinato alla seconda soluzione proposta, ovviamente non così completa.
il primo sketch che hai proposto fa sostanzialmente quello che farebbe il mio lunghissimo sketch in modo molto più snello ahahah.
rispondendo alle tue domande:
se l'anemometro dovesse smettere di funzionare potrei sostituire,oppure accoppiare l'anemometro con un sensore di numero di giri nel rotore dell'aerogeneratore, o dell'albero motore, visto che sono accoppiati con una coppia conica. l'anemometro comunque è un sensore che sto utilizzando per fare delle prove, per capirci qualcosa e iniziare a programmare. Se ad esempio volessi essere più sicuro potrei usare due sensori di numero di giri posti nello stesso posto, in modo che se si rompesse uno funzionerebbe l'altro e mi darebbe anche un segnale di allarme e manderebbe in blocco il sistema, per esempio.
se il vento sarà davvero molto intenso, avendo un palo alto 14 metri totali, posso ritenere di essere più che sicuro perchè ho tre picchetti cementati a terra (oltre una base di cemento armato per il palo principale), che sostengono il palo in tre punti della sua lunghezza, a 4, a 9 e a 14 metri.
all'aeromotore è applicato un generatore a magneti permanenti, ottenuto dalla modifica di un motore elettrico trifase asincrono, di cui devo ancora tornire il rotore e incollare con resina epossidica i magneti. Non so che potenza potrò ottenere, ma so che già a bassi giri avrò qualcosa. L'unica cosa che so è che era un motore da 1700watt a 1400 rpm a 4 poli. ho visto in rete altri motori simili modificati con magneti in ferrite funzionare egregiamente, spero almeno di ottenere risultati altrettanto soddisfacenti con i magneti al neodimio.
comunque, tornando alla programmazione, sono innegabili i vantaggi di entrambe le soluzioni da te proposte, potrei utilizzarle entrambe..
anche dal mio punto di vista memorizzare misurazioni troppo vecchie non ha molto senso, infatti mi limiterei all'ultimo minuto, o anche meno. In fin dei conti in un minuto potrebbero esserci una o due raffiche forti che metterebbero il sistema in blocco. Ovviamente un freno meccanico inerziale sarebbe automatico e darebbe una risposta ottimale in ogni situazione, ma non è quello che vorrei realizzare.
ma...
visto che ormai sono arrivato fin qua e ho impostato il mio sketch secondo quel filo logico, mi piacerebbe continuare a svilupparlo, se tu volessi continuare a darmi una mano, anche perchè ancora conosco poco linguaggio.
forse risulterà macchinoso e pesante per l'arduino, correggimi se sbaglio, però mi darebbe più soddisfazione e comunque mi serve per imparare qualcosa in più no?
quando avrò tutto pronto molto probabilmente opterò per qualcosa più simile ai tuoi sketch..

docsavage:
Se la moderazione lo consente..........
mi piacerebbe sapere come hai dimensionato aeromotore e riduttore

... un po' off-topic, ma ok :wink:

Guglielmo

docsavage:
Brattain member
e altri simili, quali sono le soglie?

... seeee ... tu vuoi sapere a quanti mila post si raggiungono i vari livelli ? ? ? :smiley: :smiley: :smiley:

Seriamente ... non l'ho mai saputo bene neanche io :-[ ... magari Uwe se lo ricorda ...

Guglielmo

C'è il livello "Spaceballs, may the schwartz be with you" quando arrivi a 1.000.000 di post. :smiley:

L'aeromotore l'ho dimensionato a occhiometro :slight_smile:
Le pale solo alte 1.2m e larghe 0.5m
Rotore da 6 pale tipo savonius, ma in realtà il profilo l'ho fatto con una dima in polistirolo e le pale realizzate in vetroresina.
L'albero di trasmissione è un Tonino che ruota in rapporto 1:1 (ovviamente) dentro il palo.
Alla base c'è un moltiplicatore di giri credo sia 3:1 (non ho contato i denti), recuperato da una coppia conica di fresa per motocoltivatore. Se volete fi faccio vedere tutte le foto.. mi piace pensare che funzionerà ahah

Se mi spieghi come si fa a caricare le foto le carico .. perché mi chiede il percorso ..