Sari la conținut
ELFORUM - Forumul electronistilor

intrebari punctuale.


lutza2

Postări Recomandate

va rog frumos sa-mi spuneti la cat timp sefac citirile cu programul asta ?

 

// send the value of analog input 0:   Serial.println(analogRead(A0));  }  //Wait for a bit to keep serial data from saturating  delay(1);

 

Trimite pe seriala niste valori. Ma intereseaza cu ce frecventa ca sa pot face un grafic cu datele respective.

Link spre comentariu

analogRead() consuma cam 0.1 ms

delay(1) consuma 1 ms

 

serial.print() este implementata asincron dar daca viteza este setata cu serial.begin la 9600 bauds inseamna ca va transmite 1200 caractere de 8bit pe secunda, deci cca 0.8ms pentru un caracter ASCII.

In cazul cel mai nefavorabil, cand analogRead intoarce o valoare 1023, vor fi 4 bytes transmisi (4 caractere ASCII care formeaza numarul 1024 - asa transmite serial.print) deci 4 * 0.8 ms = 3.2ms.

 

Asa ca daca se foloseste o viteza de 9600 bauds pentru comunicatia seriala, in cazul cel mai nevaforabil cand analogRead intoarce o valoare aproape de maxim, durata ar putea fi de cca 4.3 ms.

Dar probabil ca dupa ce se umple buffer-ul de 64bytes al comunicatiei seriale lucrurile devin "interesante".

Dar cine stie, poate ma insel?

 

LE: Dar functia este serial.println() ... deci se mai adauga 2 caractere (new line si cr). Deci inca 1.6 ms la totalul anterior.

Editat de mars01
Link spre comentariu

Multumesc frumos mars. M-ai lamurit ca metoda la care m-am gandit nu e cea buna.

 

Scopul final ar fi sa inregistrez intr-un fisier o ecg cu arduino, am pus ceva pe sectiunea medicala , dar nu prea au fost interesati. Se pare ca nu merge cu excel din office.

 

Primul pas, ca sa nu stau cu fire agatate fu sa generez un semnal de 1Hz pe D9 si sa-l injectez in A0. Programul fu asta, de pe net desigur :

 

________

 

#include <TimerOne.h> const byte PWMDAC1pin = 9; // PWM DACconst byte period = 32; // for 8 bit DACint q,numcamp=5728;float v,t=0,f=5,T=1/f,coeff=T/(float)numcamp; void setup(void){  pinMode(PWMDAC1pin, OUTPUT); Timer1.initialize(period);Serial.begin(9600); } int i;void loop(void){    //sine   for(i=0;i<numcamp;i++)   {   t=float(coeff*i);   v=sin(2*PI*f*t);   q=(int)(512+512*v);   Timer1.pwm(PWMDAC1pin, q);   }Serial.println(analogRead(A0));}

 

 

-----------------

O prima intrebare ar fi : -de ce trebuie declarat pinul D9 cu un nume cand ar putea fi pusa direct cifra 9 in loc de PWMDAC1pin ? E vreun avantaj, viteza, ceva  ?

Editat de lutza2
Link spre comentariu

Doar pentru o mai buna urmarire a programului. In cazul asta este simplu, dar in alte situatii - cand acelasi pin este folosit in mai multe locuri (chiar subrutine) si din varii considerente trebuie schimbat cu altul - o sa fie complicat sa faci modificarile fara sa ratezi ceva. In aceasta situatie iti va da cu virgula mult pana te prinzi ca ai uitat sa faci schimbarea intr-un loc

Link spre comentariu

Si in plus, este util pentru acelasi motiv pentru care se folosesc serverele DNS pe Internet.

Este mai usor sa scrii: www.google.com decat sa scrii in bara de adresa a browser-ului: 216.58.209.196 Cu ambele obtii acelasi efect, intri pe pagina motorului de cautare Google.

Oamenii se descurca mai usor cu nume decat cu cifre.

 

Autorul programului a folosit sintaxa:

const byte PWMDAC1pin = 9; // PWM DAC

Dar acelasi lucru se putea face si asa:

#define PWMDAC1pin   9   //PWM DAC

Si de fiecare data cand compilatorul vede PWMDAC1pin il inlocuieste el in fundal cu cifra 9.

Editat de mars01
Link spre comentariu

Treaba este destul de simpla.

 

1. Preiei semnalul la intrarea unui ADC.

2. Vei face o esantionare a semnalului analogic cu o anumita frecventa numita frecventa de esantionare. Legea lui Nyquist spune ca rata de esantionare trebuie sa fie minim dublul frecventei maxime de esantionat.  Sa presupunem ca frecventa maxima de esantionat este de 100 Hz (aceasta ar insemna cam 6000 bpm - batai pe minut intr-un ECG :) ). In acest caz frecventa de esantionare este de minim 200 Hz. 

3 . Configurezi un timer sa aiba firing rate-ul la 200Hz. In subrutina de intrerupere activata de intreruperea Timer-ului ai o variabila flag care este facuta 1 de fiecare data cand ruleaza aceasta rutina.

4. In bucla pricipala testezi acest flag si cand flag-ul este 1 (deci timer-ul a expirat si a dat intrerupere) atunci faci variabila flag sa aiba valoarea zero pentru a te pregati pentru o urmatoare esantionare. Apoi declansezi o citire a ADC-ului.

5. Valoarea intoarsa o pui intr-un buffer cat mai incapator (un vector) a carui dimensiune depinde de cat RAM liber ai. Sa ai grija sa mai lasi ceva si pentru restul de operatii din program altfel o sa dai de niste erori foarte criptice de iti prinzi urechile.

6. Cand buffer-ul se umple il "versi" intr-un fisier pe un sdcard, sau il trimiti mai departe pe USB sau network. Poti folosi DMA-ul (parca Due are DMA).

7. Si o iei de la capat pana ai terminat cu achizitia de date.

 

Pentru reconstituire, sa zicem ca faci acest lucru cu un DAC comandat tot de Arduino.

Din nou setezi un timer pe exact frecventa de esantionare folosita anterior (deci 200 Hz) si la fiecare expirare a timer-ului citesti valorile in ordine din fisier si le trimiti catre DAC. Eventual poti face si aici buffering, citesti valorile de pe sdcard sau de mai stiu eu unde vrei sa stochezi datele intr-un buffer (vector) al lui Arduino iar valorile trimise catre DAC le iei din acest buffer, in ordine, pe "tactul" dat de intreruperea Timer-ului.

 

Pentru simplitate am presupus ca numarul de biti de achizitie ADC este acelasi cu numarul de biti la DAC. Daca difera atunci mai sunt alte procese de prelucrare a

datelor si nu stiu cat face fata Arduino la genul acesta de procesare de semnale specific pentru un DSP (digital signal processor). 

 

Succes!

 

LE: Cu cat frecventa de esantionare este mai mare cu atat reproducerea semnalului este mai exacta. Intr-un final ceva din informatie se pierde, nu degeaba se agita astia in domeniul audio si folosesc convertoare Sigma Delta pe 24bit, foarte scumpe si cu rate de esantionare de 48KHz. 

Doar ca cu cat creste frecventa de esantionare cu atat trebuie sa cresca si frecventa procesorului pentru a face fata la toate operatiile. Asa ca trebuie sa ajungi la un compromis intre calitatea semnalui si puterea de calcul Arduino.

Editat de mars01
Link spre comentariu

Multumesc frumos pentru suport.

Ca un biban ce sunt am pus serialprint in afara buclei for. Normal ca aveam valori aiurea care semanau vag cu un mic sinus pentru ca nu iesea din for cu aceeasi valoare ci erau mici variatiuni oarecum periodice.

Acum l-am bagat in bucla si e un sinus gras si frumos.

Link spre comentariu

Creează un cont sau autentifică-te pentru a adăuga comentariu

Trebuie să fi un membru pentru a putea lăsa un comentariu.

Creează un cont

Înregistrează-te pentru un nou cont în comunitatea nostră. Este simplu!

Înregistrează un nou cont

Autentificare

Ai deja un cont? Autentifică-te aici.

Autentifică-te acum
×
×
  • Creează nouă...

Informații Importante

Am plasat cookie-uri pe dispozitivul tău pentru a îmbunătății navigarea pe acest site. Poți modifica setările cookie, altfel considerăm că ești de acord să continui.Termeni de Utilizare si Ghidări