acquisizione dati multipla

Buon giorno a tutti,

ho visto sul forum ma non ho trovato nulla che fosse mirato per il mio problema. Devo acquisire un segnale analogico proveniente da quattro motori. Da analisi fatte, se la tenasione ( che poi convertita in livello arduino) è compresa in un certo range allora vuol dire che il motore risulta in funzione. Altrimenti il motore è guasto.

Per evitare di fare un confronto su singolo ingresso e quindi occupare molta memoria. Ho creato un array di valori e l'array dei pin analogici. Inizialmente definendola char ma non funzionava, siccome on line mi indica che i pin analogici che vanno da A0 ad A5 corrispondono ai pin 14 a 19. Quando vado a caricare lo sketch mi fa delle letture sballate, come se qualche segnale non lo riuscisse a Allego il codice utilizzato.

/*
 utilizzo l'ingresso A0 per acquisire il segnale tachimetrico,
 devo vedere di impostare 4 ingressi consecutivi oppure impostarli di volta in volta.
 */


int mot[3];
byte pinmot[]={14,15,16,17};

void setup() {
  Serial.begin(9600);
  pinMode(13,OUTPUT);
}
 
void loop() {

for(int i=0;i<3;i++)
   {
    mot[i]=analogRead(pinmot[i]);
     delay(1000);
  Serial.print("il valore del motore ");
  Serial.print(i);
  Serial.print(" è: ");
  Serial.println(mot[i]);
    if ((mot[i]<81) || (mot[i]>737)){
  Serial.print("il motore : ");
  Serial.print(i);
  Serial.print(" è guasto!!! ");
  delay(1000);
  digitalWrite(13,HIGH);
  }
  else {
    digitalWrite(13,LOW);
    delay(1000);
   }
   }
}

ecco come mi compare su monitor seriale:

il valore del motore 0 è: 755
il motore : 0 è guasto!!! il valore del motore 1 è: 607
il valore del motore 2 è: 480
il valore del motore 0 è: 756
il motore : 0 è guasto!!! il valore del motore 1 è: 604
il valore del motore 2 è: 473
il valore del motore 0 è: 755

questo anche se non collego i 4 pin.

Alcune regole ...

... per i pin analogici UTILIZZA in nomi logici A0 ... An che, a seconda della board, vengo assegnati al giusto valore numerico. Per cui: byte pinmot[] ={A0, A1, A2, A3};

... è documentato da qualche parte (mi sembra nel datasheet, ma al momento non ricordo) che, quando si cambia canale di acquisizione, è meglio fare una lettura a vuoto e scartarla. Quindi ... quando passi da un pin all'altro DEVI fare una lettura che butti.

... NON lasciare mai un pin, analogico o digitale che sia, non collegato ... data l'alta impedenza con i digitali avrai valori saltellanti tra LOW e HIGH, mentre con gli analogici letture casuali.

Guglielmo

Ecco cosa intendevo,

impostando questo codice, funziona.

/*
 utilizzo l'ingresso A0,A1,A2,A4, per acquisire il segnale tachimetrico,
 devo vedere di impostare 4 ingressi consecutivi oppure impostarli di volta in volta.
 */
 
void setup() {
  Serial.begin(9600);
  pinMode(13,OUTPUT);
}
 
void loop() {
  int m0 = analogRead(A0);
  Serial.print("il valore del motore 1 è:   ");
  Serial.println(m0);
  delay(2000);
  int m1 = analogRead(A1);
  Serial.print("il valore del motore 2 è:   ");
  Serial.println(m1);
  delay(2000);
  int m2 = analogRead(A2);
  Serial.print("il valore del motore 3 è:   ");
  Serial.println(m2);
  delay(2000);
  int m3 = analogRead(A3);
  Serial.print("il valore del motore 4 è:   ");
  Serial.println(m3);
  delay(2000);
   
 // delay(500);     posso impostare un ritardo

  if ((m0<81) || (m0>737)){
  Serial.println("il motore 1 è guasto!!!");
  digitalWrite(13,HIGH);
  }
  else {
  digitalWrite(13,LOW);
  }  

  if ((m1<81) || (m1>737)){
  Serial.println("il motore 2 è guasto!!!");
  digitalWrite(13,HIGH);
  }
  else {
  digitalWrite(13,LOW);
  }
    if ((m2<81) || (m2>737)){
  Serial.println("il motore 3 è guasto!!!");
  digitalWrite(13,HIGH);
  }
  else {
  digitalWrite(13,LOW);
  }
    if ((m3<81) || (m3>737)){
  Serial.println("il motore 4 è guasto!!!");
  digitalWrite(13,HIGH);
  }
  else {
  digitalWrite(13,LOW);
  }
 
}

Volevo impostare un codice molto più snello ed elegante come il primo post, ma i valori mi escono sballati. Questo sarà un sottocodice usato in un algoritmo in cui verificherò se il pin 13 si è portato a livello alto.
Oppure impostando un array e verificando in uscita con un ciclo for fale array.

spero qualcuno mi possa dare una mano.
Grazie mille a tutti

Non so se è questo che causa l'anomalia ma manca il pinMode seui pin che hai definito per la lettura, prova a mettere nel setup un for (così come hai fatto nel loop) che setti:

pinMode(pinmot[i], INPUT);

e vedi se risolvi.
Detto questo, se non colleghi nulla ai pin analogici e fai un'analogRead il pin ti restituirà valori "casuali" in base alle interferenze che captano

P.S. = Anticipato da Guglielmo

Grazie mille Guglielmo, quindi mi suggerisci a questo punto di impostare il codice come adesso ho scritto?in effetti così funziona perfettamente. Poi a quel punto carico i valori su un array e me lo porto fuori. Da lì mi faccio una verifica di questo array se contiene valori al di fuori del range indicato allora attivo il pin 13 altrimenti lo disattivo.

in effetti quando stacco un pin, mi acquisisce valori sballati!!!

per fabpolli

con analogread non è necessario dichiarare in void che sia un imput. non so se poi sia questo il problema.
Come vedete dal post precedente, se faccio un acquisizione per volta il codice va bene.

Se mi confermate che solo così risolvo allora mi metto l'anima in pace. Però se c'è un modo più elegante ben venga :wink: ahahahah

grazie a tutti!!!

un abbraccio

Quello che suggeriva Guglielmo è una cosa del genere:

for(int i=0;i<3;i++)
{
   int lr = analogRead(pinmot[i]);
   mot[i]=analogRead(pinmot[i]);
}

Non sono sicuro di aver capito correttamente cosa volevi fare ... stavi cercando di avere letture "contemporanee" sugli ingressi analogici ?

Se si, non e' fisicamente possibile, perche' ci sono si sei ingressi, ma sono "multiplexati" internamente verso un singolo convertitore AD ... quindi non e' proprio fisicamente possibile leggerne piu di uno per volta ... inoltre, come ha gia detto anche Guglielmo, la prima lettura va scartata, perche' a causa della commutazione del multiplexer interno risulta imprecisa ...

Grazie mille a tutti, a questo punto vado per la soluzione in cui acquisisco un valore per volta.
Un ultima domanda, adesso sto facendo dei test con arduino uno.
A breve mi arriverà arduino mega. Il concetto vale uguale per entrambi, ovvero hanno un unico multiplexer?

grazie mille a tutti per le delucidazioni

saluti

Comunque acquisisci, essendo il ADC unico sia sulla UNO che sulla MEGA che su altre schede, DEVI, ad ogni cambio di canale, fare una lettura a vuoto e scartare il valore, sia che leggi tramire un for/array (più semplice e pulito) sia che leggi uno ad uno i vari canali.

Guglielmo

Grazie mille Guglielmo,

reputo soddisfatto e chiuso questo thread. Spero possa servire a qualcun'altro

saluti

rlocus

... se volesse usare il for, non sarebbe piu semplice fare due letture consecutive con in mezzo 5 o 10 ms di delay ? ... in questo modo scarta automaticamente la prima, tenendo la struttura semplice e senza incasinarsi troppo ... giusto come idea ...

Etemenanki:
... se volesse usare il for, non sarebbe piu semplice fare due letture consecutive ...

... hai visto il post di fabpolli, #5 ? :wink:

Guglielmo

gpb01:
... hai visto il post di fabpolli, #5 ? :wink:
Guglielmo

... adesso si ... :roll_eyes: