Pages: [1] 2   Go Down
Author Topic: chiarimenti su operatore di comparazione == [Risolto]  (Read 1276 times)
0 Members and 1 Guest are viewing this topic.
Serrata (RC)
Offline Offline
Newbie
*
Karma: 1
Posts: 17
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Salve a tutti

Sto cercando di realizzare un discriminatore con arduino IDE 1.0.1 scheda Mega 2560

In pratica leggo il valore di una tensione su porta analogica 0 e se il valore è uguale ad es. 3.21  accende un led " VERDE" lo stesso succede se raggiunge  3.22 V. accende " ROSSO" a 3.23 si accende il led "Giallo"
Questa variazione la simulo con un potenziometro posto con gli estremi tra + 5V e GND.
La tensione che viene instradata sulla porta 0 verificata con multimetro digitale è ad es. 3.21 ma il led "in questo caso verde " non ne vuol sapere di accendersi l'operatore di comparazione == non fa' il suo dovere
qualcuno sa dirmi perche' . Se invece uso l'operatore <= allora mi funziona ma il problema e' che io voglio che solo se = alla tensione che voglio io devono  accendersi il rispettivi led
Grazie  allego lo sketch


Code:
#define inputPin1 0 //definisco i pin utilizzati di arduino pin analog 0

int valore1 = 0;


int numletture = 10;
float valorex= 0;// variabile di appoggio x comparazione
float media1 = 0;// variabile x media


float gradino = 0.00486;// fattore di conversione per gradino 0.0049 * 1023= 5V

void setup() {

  // put your setup code here, to run once:

  pinMode(11,OUTPUT);//inizializzo pin 11 come uscita digitale
  pinMode(12,OUTPUT);
  pinMode(10,OUTPUT);
  Serial.begin(115200);// inizializzo la seriale software

}

void loop()  // put your main code here, to run repeatedly:
{
  for (int k=0; k < 10; k++){  // Ciclo for per 10 letture

    valore1 = analogRead(inputPin1);//Leggo da analog input 0
    delay(10);

    media1 = (valore1) + media1;// aggiungo lettura su variabile media1

  }

  media1 = (media1 / 10);// infine divido x 10 per la media letture
  media1=(media1*gradino);//converto in volt
  valorex=media1;//valorex variabile di appoggio per discriminatore

  if (valorex == 3.21 )
  {
    Led41();//se valore x = 3.21 V accendi led verde
  }
  if (valorex == 3.22 )

  {
    Led42();////se valore x = 3.22 V accendi led Rosso
  }

  if  (valorex == 3.23) {
    Led43();// //se valore x = 3.2 V accendi led Giallo
  }


 
  Serial.print("PORTA ANALOGICA 0 =") ;// Stampo le medie lette da analog 0
  Serial.print(media1);
  Serial.println();// aggiungo linefeed
  media1=0; //Azzero le medie per le prossime letture
 


}
void Led41(){
  digitalWrite(10,HIGH);
  delay(20);
  digitalWrite(10,LOW);
  }
void Led42(){
  digitalWrite(11,HIGH);
  delay(20);
  digitalWrite(11,LOW);
  }
void Led43(){
  digitalWrite(12,HIGH);
  delay(20);
  digitalWrite(12,LOW);
  }
« Last Edit: October 16, 2012, 06:27:15 am by latofra » Logged

Offline Offline
God Member
*****
Karma: 8
Posts: 691
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

mah,,,    per accendere 3 led   io metterei 3 if
visto che hai un multimetro  porti la tensione a i valori che ti interessano con il voltmetro  e leggi  la lettura  con analogRead e prendi nota dei tre valori

poi fai i tre if

se non hai un potenziometro lineare  10 giri  la vedo dura trovare il valore preciso
Logged


Le cose si possono considerare facili in due casi: quando le si conosce bene o quando non le si conosce affatto...

Serrata (RC)
Offline Offline
Newbie
*
Karma: 1
Posts: 17
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Grazie per la risposta

Ho provato anche i tre if come da te consigliato ma non cambia la sostanza
per quanto riguarda il potenziometro nessun problema ho gia' verificato con multimetro oscilloscopio Tektronics 213 DMM e' uno strumento preciso e riesco ad trimmare abbastanza preciso ma non riesco ad accendere i led anche spostando da un estremo all'altro cioe' da 0 a 4.99 Volt. Se utilizzo l'operatore <= tutto ok per me' e' un mistero .

Logged

Offline Offline
Jr. Member
**
Karma: 2
Posts: 98
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

proprio perchè ti va con il <= (sempre se non ci sono altri problemi che al momento non vedo) è sempre più probabile il fatto che non prendi il valore preciso...prova a fare una cosa con range tipo
Code:
if ((valorex >= 3.20 ) && (valorex <= 3.21))
invece di
Code:
if (valorex == 3.21 )
giusto per fare un esempio

poi io partirei da range abbastanza larghi così da vedere se il concetto in se funziona e piano piano lì restringi più che puoi (fino a che funziona praticamente)
Logged

Serrata (RC)
Offline Offline
Newbie
*
Karma: 1
Posts: 17
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok vado  per tentativi e restringo  il campo

grazie

Provo e faccio sapere
Logged

Serrata (RC)
Offline Offline
Newbie
*
Karma: 1
Posts: 17
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Perfetto funziona grazie per il suggerimento grandioso ale92 in effetti le finestre erano troppo strette nel mio skecth .
Scusa come faccio a mettere risolto sul mio Post .
Grazie
Logged

BZ (I)
Offline Offline
Brattain Member
*****
Karma: 251
Posts: 21272
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I valori possibili sono:
ADC= 658 valore calcolato= 3.19788002
ADC= 659 valore calcolato= 3.20274019
ADC= 660 valore calcolato= 3.20760011
ADC= 661 valore calcolato= 3.21246004
ADC= 662 valore calcolato= 3.21732020
ADC= 663 valore calcolato= 3.22218012
ADC= 664 valore calcolato= 3.22704005
ADC= 665 valore calcolato= 3.23190021
ADC= 666 valore calcolato= 3.23676013
ADC= 667 valore calcolato= 3.24162006
ADC= 668 valore calcolato= 3.24648022
ADC= 669 valore calcolato= 3.25134015

Spiegami dove trovi una corrispondenza ai valori 3.21 ; 3.22  o 3.23
Il == funziona correttamente, Il ragionamento su cui si basa il programma é sbagliato.

Suggerimenti:
* non controllare le tensioni calcolate ma i valori ADC letti
* la lettura non é mai cosí stabile che Ti legge i valori 661, 663 o 663 fissi.

Ciao Uwe
Logged

Serrata (RC)
Offline Offline
Newbie
*
Karma: 1
Posts: 17
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Grazie Uwe

Avevo provato anche a ragionare in termini dei numeri che mi riporta l'ADC ma non ne ero venuto a capo .
Potrebbe essere il mio ragionamento sbagliato ma bene o male con un potis dovrebbe primo o dopo lampeggiare qualcosa o no.Anche perche' l'oscillazione è di uno o due valori in piu' o in meno.
In definitiva se io misuro 3.21 e mi dopo la mia conversione vedo 3.21 perche' l'operatore di ccomparazione non funge?



Logged

BZ (I)
Offline Offline
Brattain Member
*****
Karma: 251
Posts: 21272
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Grazie Uwe

Avevo provato anche a ragionare in termini dei numeri che mi riporta l'ADC ma non ne ero venuto a capo .
Potrebbe essere il mio ragionamento sbagliato ma bene o male con un potis dovrebbe primo o dopo lampeggiare qualcosa o no.Anche perche' l'oscillazione è di uno o due valori in piu' o in meno.
In definitiva se io misuro 3.21 e mi dopo la mia conversione vedo 3.21 perche' l'operatore di ccomparazione non funge?

No, non avresti mai visto accendere un LED, perché se fai un confronto con 3,21 la tensione calcolata deve essere 3,210000 e non 3,21 e qualcosa.

Se usi dei Float non puoi usare il == ma devi sempre definire un valore sopre a uno sotto il quale la condizione é valida. Percui:

if ((valorex >=3,205) && (valorex <3,215))

Ti da un  controllo se il valore é di 3,21 (arrotondato).

Ciao Uwe

Logged

Offline Offline
God Member
*****
Karma: 8
Posts: 691
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Grazie per la risposta

Ho provato anche i tre if come da te consigliato ma non cambia la sostanza
per quanto riguarda il potenziometro nessun problema ho gia' verificato con multimetro oscilloscopio Tektronics 213 DMM e' uno strumento preciso e riesco ad trimmare abbastanza preciso ma non riesco ad accendere i led anche spostando da un estremo all'altro cioe' da 0 a 4.99 Volt. Se utilizzo l'operatore <= tutto ok per me' e' un mistero .



questo li fa accendere   (mettere nel void loop  e assicurarsi che i pin siano settato come output e messi LOW nel setup)

map(analogRead(A0), 0, 1023, 0, 500);

if  (analogRead(A0) >= 321 && analogRead(A0) < 322) digitalWrite (10, HIGH);
if  (analogRead(A0) >= 322 && analogRead(A0) < 323) digitalWrite (11, HIGH);
if  (analogRead(A0) >= 323 && analogRead(A0) < 324) digitalWrite (12, HIGH);


e se metti anche queste righe si spengono se il  potenziometro fa segnare una tensione diversa


if  (analogRead(A0) <  321 && analogRead(A0) >=322) digitalWrite (10, LOW);
if  (analogRead(A0) <  322 && analogRead(A0) >=323) digitalWrite (11, LOW);
if  (analogRead(A0) <  323 && analogRead(A0) >=324) digitalWrite (12, LOW);


IMHO  fare ==  su un analogRed   è gia una specie di controsenso
ci va sempre l'accoppiata    >=  <   


« Last Edit: October 16, 2012, 02:14:27 am by gingardu » Logged


Le cose si possono considerare facili in due casi: quando le si conosce bene o quando non le si conosce affatto...

Rome (Italy)
Offline Offline
Tesla Member
***
Karma: 120
Posts: 9179
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Se usi dei Float non puoi usare il == ma devi sempre definire un valore sopre a uno sotto il quale la condizione é valida.

Confermo, per via di come sono rappresentati i float è praticamente impossibile prevedere un valore esatto su cui eseguire un confronto "==", è sempre necessario prevedere una certa isteresi utilizzando una soglia minore e una superiore.
Aggiungo pure che su Arduino non è molto saggio utilizzare i float quando non è indispensabile (usa una mcu da solo 8 bit senza nessun supporto hardware per i float),meglio lavorare sempre con valori interi preventivamente moltiplicati x10,x100,x1000, etc, a seconda del numero di decimali desiderati.
Logged

0
Offline Offline
Shannon Member
****
Karma: 130
Posts: 10449
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

In definitiva se io misuro 3.21 e mi dopo la mia conversione vedo 3.21 perche' l'operatore di ccomparazione non funge?

perchè la println "taglia" alla seconda cifra decimale, ma in realtà ce ne possono essere di più. Sul reference trovi quale println usare per visualizzare un numero arbitrario di valori dopo la virgola
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Serrata (RC)
Offline Offline
Newbie
*
Karma: 1
Posts: 17
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Grazie a tutti per i preziosi consigli ho capito che beccare il giusto valore dopo la virgola e' un impresa titanica molto meglio prevedere delle finestre .I vostri consigli mi hanno spiegato in pratica come fare .
Per me il topic e' chiuso . Alla prossima
Logged

0
Offline Offline
Shannon Member
****
Karma: 130
Posts: 10449
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I valori possibili sono:
ADC= 658 valore calcolato= 3.19788002
ADC= 659 valore calcolato= 3.20274019
ADC= 660 valore calcolato= 3.20760011
ADC= 661 valore calcolato= 3.21246004
ADC= 662 valore calcolato= 3.21732020
ADC= 663 valore calcolato= 3.22218012
ADC= 664 valore calcolato= 3.22704005
ADC= 665 valore calcolato= 3.23190021
ADC= 666 valore calcolato= 3.23676013
ADC= 667 valore calcolato= 3.24162006
ADC= 668 valore calcolato= 3.24648022
ADC= 669 valore calcolato= 3.25134015

una precisazione; questi valori sono validi se calcolati con i float (vedi infinitesimale del calcolatore) e utilizzando la stessa logica che usa il chip.
Per fare un esempio, sempre con i float, avevo problemi che simulazioni fisiche su due sistemi differenti, nonostante gli stessi valori iniziali, avevano delle diversità dopo pochi step di esecuzione; per risolvere è bastato dare come direttiva al compilatore il parametro "strictfp" (questo in java, ma se ben ricordo c'è qualcosa di simile anche in C), in pratica disattivi tutte le ottimizzazioni non standard sul calcolo dei valori float, che sono diverse da CPU a CPU.
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Rome (Italy)
Offline Offline
Tesla Member
***
Karma: 120
Posts: 9179
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

che sono diverse da CPU a CPU.

Non da cpu a cpu, parliamo di micro senza fpu, ma da compilatore a compilatore e relative implementazioni su micro specifici dello stesso.
Di solito sul manuale del compilatore c'è sempre una sezione dedicata ai float dove viene descritta l'implementazione utilizzata, quella più diffusa è la IEEE 754, e le eventuali divergenze dallo standard utilizzato.
Logged

Pages: [1] 2   Go Up
Jump to: