Go Down

Topic: Acquisizione PWM (Read 1 time) previous topic - next topic

luigirocco86

Mar 11, 2013, 07:16 pm Last Edit: Mar 11, 2013, 10:13 pm by leo72 Reason: 1
Buonasera a tutti,
mi servirebbe una mano per un progetto che sto svolgendo per la tesi di laurea. Sto utilizzando arduino uno per controllare una board che si occupa di controllare la sonda lambda della macchina. Detto questo il mio arduino non deve fare altro che acquisire un segnale analogico, generare un pwm, comunicare via SPI. Il tutto lo gestisco tramite labview, praticamente mando un carattere con il labview e in base a quel carattere l'arduino sceglie cosa fare, esempio "p" (manda un pwm), "s" (comunica via spi).
Ora veniamo al problema. La comunicazione funziona, mando la lettera "p" e con l'oscilloscopio vedo il pwm. Volevo provare anche se funzionava l'acquisizione analogica, e non avendo un generatore, ho "ponticellato" l'uscita che manda il PWM, con l'ingresso analogico, e ho provato a mandare il pwm e contemporaneamente acquisirlo per vederlo poi su pc....vi metto il codice che forse si capisce meglio:


Code: [Select]
#define pwm 6

int vet[]={-2,-2,-2,-2};
int cont=0;
char mess;
int intensita=0;
int analog=0;

void setup(){
       Serial.begin(9600);// imposto la UART per lavorare a 9600
       delay(200);
pinMode(pwm, OUTPUT); // imposto il pin come uscita
Serial.flush();
           }

void loop(){
           while(Serial.available()>0){
           
                   vet[cont]=Serial.read();
                   cont++;
                   delay(60);
                                       }
                                       
                   mess=vet[0];
                   int c=1;
                   while ((vet[c]!=-2) && (c<=3))
                         {
                         intensita = intensita * 10 + (vet[c]-48);
                         c++;
                         }
                   
                   
             if (mess=='p'){analogWrite(pwm,intensita);  
                                analog=analogRead(A0);
                                Serial.print(analog);
                                }
           
             for(int i = 0; i < c; i++) //riporta il vettore allo stato iniziale
                 {
                 vet[i] = -2;
                 }
             
             Serial.flush();
             cont=0;
             intensita=0;
        }


Il problema è che con l'oscilloscopio vedo il pwm, mentre se vado a leggere il valore analogico mi da si dei valori o 1023 o 0 (come dovrebbe essere il pwm), ma me li da un po a caso. Vi posto una foto.
Il problema non è dalla parte labview, perchè ho preso uno degli esempi labview già fatti, che implementano la comunicazione seriale.
A me sembra che prenda pochi punti, quindi a volte salta lo stato basso o alto e da quella forma a punta.....scusate se sono stato poco chiaro ma è un po un macello da spiegare.
Grazie, spero che riusciate a darmi una mano

PaoloP

#1
Mar 11, 2013, 08:50 pm Last Edit: Mar 11, 2013, 08:52 pm by PaoloP Reason: 1
No è giusto.
Il PWM genera solo due valori: ALTO e BASSO.
L'Arduino UNO non ha una uscita analogia ma simula la cosa attraverso un rapido passaggio tra due stati logici.
In base alla durata del segnale ALTO in rapporto a quello BASSO cambi il Duty-Cycle e quindi l'intensità del segnale in uscita. Quindi se hai un buon oscilloscopio quello che vedrai è questo:
Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

luigirocco86

Grazie per la risposta. Quello che vedo con l'oscilloscopio è giusto, il problema è quello che mi ritorna dalla lettura analogica, che sarebbe la foto postata. Come vedi è tutto sballato. Non riesco a capire perchè..

leo72

Non essendo il PWM un segnale analogico, non leggi ad esempio 2,5V ma sempre 0 o 5 V alternati.
L'ADC dell'Arduino ti campiona ed a volte prende il segnale alto, altre il segnale basso.

Per "livellare" un po' il segnale PWM usa un filtro RC sull'uscita del pin PWM, ti puoi aiutare con questo tool online col quale calcolare i valori di R e C idonei. Vedi un po' se risolvi.
http://sim.okawa-denshi.jp/en/PWMtool.php

L'alternativa è l'acquisto dell'Arduino DUE, che ha 2 uscite analogiche vere.

uwefed

Usa come fonte di tensione da leggere dalla entrata analogica un potenziometro da 5kOhm e collegi le parti esterne a massa e a 5V. col cursore puoi avere delle tensioni tra 0 e 5V.  Metti un condensatore da 0,1µF tra entrata analogica e massa.

Il risultato della Tua lettura PWM con l' entrata analogica é veritiero. Misuri in momenti a caso e non sincronizzato con la frequenza PWM.

Ciao Uwe

luigirocco86

Grazie delle risposte ragazzi.
Oggi però ho fatto la prova del 9 e purtroppo non funziona ancora niente. Sono andato in laboratorio, con oscilloscopio e generatore di segnale e ho cercato di acquisire il segnale generato dal generatore, tramite il canale analogico di arduino.
Il segnale è un'onda quadra, con ampiezza di 2,5Vpp, frequenza di 1kHz e dutycycle del 30%. Ho semplicemente fatto un programma che manda un analogRead(A0) e quello che legge me lo manda sulla seriale.
Vi posto le foto di quello che vedo sull'oscilloscopio e quello che invece leggo dalla lettura analogica che poi mi viene inviata sul pc. Perchè succede questo schifo secondo voi????

PaoloP

#6
Mar 12, 2013, 12:15 pm Last Edit: Mar 12, 2013, 12:18 pm by PaoloP Reason: 1
Questa discussione è molto interessante. (http://arduino.cc/forum/index.php/topic,6549.msg51582.html#msg51582)
Guarda anche a pagina 2, ci sono esempi di acquisizione di segnali da 1Khz.

--> https://sites.google.com/site/measuringstuff/the-arduino
Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

luigirocco86

Volevo dirvi che ho risolto, ma ancora non mi è chiaro il tutto.  :P
Dovevo semplicemente aumentare la baudrate a 59600, anche se non riesco a capire perchè con segnali così lenti mi serve una baud rate così alta...mah

PaoloP

Nell'IDE serie 00xx come la 0022 o la 0023 la seriale è sincrona. Nelle nuove versioni 1.0.x e 1.5.x è asincrona.
Tu quale IDE usi per compilare?
Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

luigirocco86


Go Up