Jump to content
ELFORUM - Forumul electronistilor

Citiri consecutive de pe ADC la ATmega168


Guest BogyDruid

Recommended Posts

Guest BogyDruid

am si eu o problema la programarea unor intreruperi ADC pe un ATmega168.

 

proiectul este urmatorul:

 

Am un server WEB care la interval de 1 minut trimite o pagina la client. In acea pagina prezint informatia masurata la ADC in felul urmator. In intervalul de 1 minut pana sa fie trimisa pagina, microcontrolerul trebuie sa masoare 200 de esantioane de pe pinul ADC, sa gaseasca maximul si minimul intre ele, sa faca a=max-min si sa returneze un log_10(a). Acest rezultat va fi inclus in pagina care va fi trimisa clientului.

 

Problema este ca folosind intreruperile ADC nu se mai incarca pagina deloc. Imi ramane la Waiting for . Nu cred ca ajunge la chestiile de TCP...

Codul meu arata cam asa:

 

static volatile int counter = 0; //contorstatic int info_read = 0; //variabila ce imi indica faptul ca functia de prelucrare vector de esantioane a avut successtatic int vector[200]; //vectorul ce va contine cele 200 de esantioanestatic int array_need_filled; //variabila ce determina daca incep sau  nu preluarea cele 200 de esantioanestatic int realADCvalue; //variabila ce va contine rezultatul log_10(a) ce va fi mai apoi pus pe pagina WEB//functia de intrerupere ADC, aici umplu vectorul cu valorile masurate pe pinul ADC, incrementez contorul, reinitializez //masurarea pe ADC, cand contorul ajunge la 200 opresc ADCISR(ADC_vect){    vector[counter] = ADCW;    counter = counter + 1;    if (counter < 200)    {        ADCSRA = 0xCB;    }else{             ADCSRA = 0x00;         }}//functia ce prelucreaza cele 200 de esantioane si returneaza o valoare ce va fi scrisa in pagina WEBint realADC(void){    int j=0,a=0;    int max=vector[0],min=vector[0];    for(j=0;j<200;j++)    {      if(vector[j] > max)      {         max = vector[j];      }else{            if(vector[j] < min)            {               min = vector[j];            }         }    }    a=max-min;           info_read = 1; //new line added here    return log10_approx(a);     }int main(void){             //initializez ADCul, ADC ON, ADC Interrupts ON      ADMUX = 0x43;      ADCSRA = 0x8B;      need_array_filled = 1;//am nevoie sa preiau cele 200 de esantioanewhile(1){          //incep preluarea esantioanelor prin activarea masuratorii cu bitul ADSC          if(need_array_filled)            {               counter = 0;               ADCSRA |= 0x40;               need_array_filled = 0;            }               //daca contorul a ajuns la 200 atunci prelucreaza datele si returneaza valoarea            if(counter == 200)            {               realADCvalue = realADC();               }            //daca datele au fost prelucrate atunci e nevoie de urmatoarea masuratoare de 200 de esantioane            if(info_read)            {               need_array_filled = 1;               info_read = 0;            } ...TCP stuff...    }}
Link to comment
  • Replies 5
  • Created
  • Last Reply

Top Posters In This Topic

  • danzup

    2

  • srdjan

    1

Ca sa-ti dai seama daca e de la ADC (poate ...) ai modificat codul ca sa citesti sa zicem doar de 2 ori ADC ul ?Ca sa te putem ajuta .

Link to comment

static volatile int counter = 0; //contorce face volatile aici? nu cumva contoru sta pe loc si iti face bucla infinita la citirea adc-ului?

Link to comment

static volatile int counter = 0; //contorce face volatile aici? nu cumva contoru sta pe loc si iti face bucla infinita la citirea adc-ului?

La ceva asemanator m-am gandit si eu ... dar se pare ca userul asta a abandonat prezenta pe elforum Dar nu la linia care ai zis tu !El face incrementare de contor mai jos in program ( linia de cod mentionata de tine @srdjan numai declara corect o variabila ) !Eu ma refeream la timpul necesar executie citirii care ar putea depasi orice altceva.Ne-ar mai ajuta daca ne-ar spune ce intrerupere foloseste pentru partea de TCP/IP adica care intrerupere e mai prioritara !ca nu rezulta ....
Link to comment
Guest BogyDruid

am citit undeva ca pentru a folosi o variabile (in cazul de fata counter) atat in main() cat si in intrerupere trebuie declarata volatile.dupa mai multe incercari am ajuns la asa ceva:

uint8_t need_array_filled;unsigned int realADCvalue;volatile int contor;static unsigned int valori[200];ISR(ADC_vect){	//valori[contor] = ADCW;	//linie comentata deoarece necomentata provoaca stagnarea programului	if (contor < 200)	{		ADCSRA = 0xCB;		sei();		contor = contor + 1;	}else{			ADCSRA = 0x00;		 }}unsigned int realADC(void){	 int j=0,a=0;	 int max = 1023, min = 130;         // liniile de mai jos comentate deoarece daca in intrerupere am comentat initializarea vectorului valori nu am cu ce lucra aici        // manual am creat un max si min	 /*int max=valori[0],min=valori[0];	 for(j=0;j<200;j++)	 {		if(valori[j] > max)		{			max = valori[j];		}else{				if(valori[j] < min)				{					min = valori[j];				}			}	 }*/	 a=max-min;	 	 	 return log10_approx(a);	}int main(void){        		ADMUX = 0x43;		ADCSRA = 0x8B;                realADCvalue = 0;                need_array_filled = 1;                while(1){                                if(need_array_filled)				{					contor = 0;					ADCSRA |= 0x40;					need_array_filled = 0;				}				if(contor >= 199)				{					realADCvalue = realADC();					}....tcp....                }}
valoarea de care am nevoie ar trebui sa se afle in realADCvalue. in modul cum e prezentat codul de mai sus cu max si min dat de mine primesc un rezultat de 3446 ceea ce nu e corect. am vazut ca acest rezultat difera de la 32000 nu stiu cat la -32000 nu stiu cat in functie de cum declar variabilele globale. e total aiurea.in concluzie de ce nu pot face valori[contor] = ADCW; in intrerupere?? de ce se opreste programu?

Ne-ar mai ajuta daca ne-ar spune ce intrerupere foloseste pentru partea de TCP/IP adica care intrerupere e mai prioritara !

daca intreruperea de tcp era prioritara cred ca nu mai tinea pagina in Waiting for in cazul in care intreruperea de ADC era problematica ci o afisa si in loc de rezultatul dorit baga o eroare sau ceva nu?
Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now



×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.Terms of Use si Guidelines