[Projet] ADC échantillonnage BP [1Hz 5Khz]
Répondre à la discussion
Affichage des résultats 1 à 4 sur 4

[Projet] ADC échantillonnage BP [1Hz 5Khz]



  1. #1
    invitef75f7d4f

    Question [Projet] ADC échantillonnage BP [1Hz 5Khz]


    ------

    Bonjour tout le monde,

    Je viens vers vous, car depuis une semaine, je travaille (et comme toujours) mes accéléromètres. Le cahier des charges se définit de plus en plus. Néanmoins, cette semaine ci, ainsi que la semaine passée, je m'attarde sur mon ADC...

    J'ai 4 accéléromètres et je dois récupérer son ADC, pour en analyser son peak-to-peak, l'intégrer (numériquement ?) pour obtenir sa vitesse RMS...

    On m'a demandé de travailler avec les interruptions, donc j'ai réécrit tout mon code.

    Je travaille avec un atmega169 et je simule avec proteus pour le moment, (pas le choix, car ça un cout matériel, donc il ne faut pas se planter... )

    Sachant que je recevrais un signal dont les harmoniques peuvent atteindre 5KHz (je mettrais un filtre anti-aliasing en entrée) avant la patte de l'ADC, je dois échantillonner à 2x la fréquence maximale (Théorème de Shannon-Nyquist). En industrie, on utilise même 2.56 (je ne sais pas d'où ça sort...).

    Si je travaille à 8MHz, je prends un prescaler de /64, ce qui me donne 125KHz, donc je dois rediviser par 12 pour obtenir mes 10Khz. Ca ne fonctionne pas, ma fréquence d'échantillonnage est trop basse pourquoi ?

    De plus je ne retrouve pas 10x le sinus 5KHz dans mon signal 500Hz, comment se fait il ?


    Voici le code que j'ai écrit, d'après, il n'y a pas d'erreurs, mais je reste bloqué depuis un bon petit temps (1 semaine). Il prend 250 échantillons et il affiche tout sur l'USART au final.

    Pour tester mon timer, j'ai mis un oscilloscope virtuel sur la led et j'ai une période de 10*20µ à l'état haut, et le même à l'état bas. Pour moi la fréquence est donc 1/(10*20µ) donc 5KHz. pourquoi ça ne correspond pas à mes calculs?

    Code:
    #include "lcd.h"
    #include "fonctions.h"
    #include <avr/interrupt.h>
    
    //#define  CPUCLK	16000000
    #define  CPUCLK	8000000
    #define  NB_ECH 250
    #include <util/delay.h>
    #include <stdlib.h>
    
    volatile uint16_t resultat_RAM1[],resultat_RAM2[],resultat_RAM3[],resultat_RAM4[];
    
    
    void ActiverADC()
    {
    
    // Digital Input Disable
    DIDR0 = 0xFF;
    // Mode 1.1V
    //ADMUX=(1<<REFS1)|(1<<REFS0);
    
    //Mode VCC externe
    ADMUX= (1<< REFS0);
    
    // Ajouter Prescaler et on rend enable l'ADC (8Mhz/64 = 125Khz) OK
    ADCSRA=(1<<ADEN)|(1<<ADPS2)|(1<<ADPS1);
    
    
    
    // on attend pour que la stabilisation de la tension soit faite.
    _delay_ms(100);
    
    
    }
    
    
    uint16_t mesure_accelerometre(uint8_t voie)
    //int mesure_accelerometre(uint8_t voie)
    {
    	
    	
    
    	// 0xF8 permet d'effacer préalablement les 3 bits et on ajoute la voie qu'on veut. 
        ADMUX = (ADMUX & 0xF8)|voie;  // F8, car maximum 7 accéléromètres 0bxxxxx000
    
    	//On met le microcontroleur en mode sleep ADC
    	MCUCR=16;    
    
    	ADCSRA|=(1<<ADSC); // Je commence ma conversion
    
    
    	// On attend tant que ADIF n'est pas à 1 (conversion terminée)
    	//while(!(ADCSRA & (1<<ADIF))); 
    
    	//On peut utiliser ADSC également
    	 while(ADCSRA & (1<<ADSC));
    
    	//on s'assure de remettre ADIF à 0 (effet inverse)
    	ADCSRA|=(1<<ADIF);
    
    	//return(ADCW);
    
    	volatile uint16_t res;
    	res=ADCL+ADCH*256;
    	return res;	
    
    }
    
    
    
    uint16_t resultat;
    char variable[(NB_ECH/4)];
    
    static int i,j,j1,j2,j3,j4;
    
    			int min1 = 1023;
    			int max1 = 0;
    			int min2 = 1023;
    			int max2 = 0;
    			int min3 = 1023;
    			int max3 = 0;
    			int min4 = 1023;
    			int max4 = 0;
    
    
    ISR(TIMER0_COMP_vect) 
    {
    
    //TCNT0 = 254-12; // compteur à 0
    
    //TIFR0 |= (1 << OCF1A);
    
    DDRB = 0xFF;
    //inverse led
    PORTB ^= (1 << 0);
    				
    
    
    				
    				i++; //cycle ACC 1 2 3 4
    				j++;
    				resultat = 0;
    
    			if(i == 1) 
    			{
    				j1++;
    				
    				
    				resultat = mesure_accelerometre(1);
    				if(resultat < min1) { min1 = resultat; }
    				if(resultat > max1) { max1 = resultat; }
    
    				resultat_RAM1[j1] = resultat;
    			}
    
    				if(i==1) 
    				{ 
    					i=0;  // Futur : on loop, utile si on prend pour les 4 ( if i%4 --> i =0)
    				}	
    
    
    
    		if(j==NB_ECH)
    			{
    			
    				
    				j1=0;
    				j2=0;
    				j3=0;
    				j4=0;
    
    				while(j1<NB_ECH) // on boucle l'accéléromètre 1 sur l'USART
    				{   
    
    					intoa(resultat_RAM1[j1],variable);
    					sendString(variable);
    
    					sendString("\r");
    					j1++;
    					
    
    				}
    			
    			}
    }
    int main()
    {
    	
    
    	ActiverADC();
    	ActiverUsart();
    	sendString("Bienvenue dans l'hyperterminal "); //USART
    	sendString("\r");
    	
    	lcd_init(); 
    	PORTA = 0;
    	PORTB = 0;
    
    	lcd_home();
     
    	lcd_string("      ");
    	_delay_ms(200);
    
    	lcd_clrscr(); //effacer le LCD
    
     	lcd_string("Enregistrement \n dans 200 ms.");
    	_delay_ms(200);
    	lcd_clrscr();
    
    
    			// TIMER 8bits utilisé Timer0
    			// MODE CTC
    			// fréquence nominale CPU 8MHz
    
    
    			// Mode CTC
    			TCCR0A |= (1 << WGM01); 
    			
    			//Prescaler / 64;  [8MHz/64 = 125KHz]
    			TCCR0A |= (1 << CS01) |(1<< CS00);
    
    
    			
    			// Interruption activée overflow.
    			//TIMSK0|=(1<<TOIE0);
    
    
    			TCCR0A |= (1<<FOC0A); // Force le Output Compare
    			TIMSK0 |= (1 << OCIE0A); // interruption lors de la comparaison
    
    
    
    			OCR0A =12;
    
    			//TCNT0 = 254-12; //(8MHZ/64 = 125Khz)/ 12 = 10.4Khz
    			sei();
    			
    			while(1) { 
    			// On attend les interruptions. 
    			}
    	
    }
    Qu'en pensez vous ?

    Sur mon schéma :

    Aref a un condo à la masse à 100nF.
    AVcc est relié à 3.3V directement.

    Mes résultats : je retrouve bien 2x 10Hz dans un 1x 5Hz, mais à 5KHz, il est à 2, 3 X dans 500Hz...

    Je vous remercie sincèrement de l'aide que vous pourrez m'apporter.

    -----

  2. #2
    gcortex

    Re : [Projet] ADC échantillonnage BP [1Hz 5Khz]

    Shannon : > 2 échantillons par période

    Le cas 2,5 c'est pour :
    - réduire le volume de données pour un stockage
    - pouvoir reconstituer le signal sans trop de difficulté

    mais si tu peux en avoir 20 c'est une aubaine !!

  3. #3
    invitef75f7d4f

    Re : [Projet] ADC échantillonnage BP [1Hz 5Khz]

    Je te remercie pour ta réponse. As tu un avis concernant le reste de mon message ? Bien à toi

  4. #4
    gcortex

    Re : [Projet] ADC échantillonnage BP [1Hz 5Khz]

    avec une vraie intégration, tu vas plafonner à coup sûr (offset non nul).
    Il faut faire une pseudo-intégration pour recentrer lentement sur zéro.

    Des fois, il faut décocher la case "clkdiv8" au niveau de la configuration des fusibles

  5. A voir en vidéo sur Futura

Discussions similaires

  1. GENERATEUR ONDE TRIANGULAIRE 0.1Hz
    Par inviteb4687f25 dans le forum Électronique
    Réponses: 5
    Dernier message: 12/10/2011, 13h20
  2. NE 555 à 1Hz ?
    Par invitee17a93f1 dans le forum Électronique
    Réponses: 20
    Dernier message: 29/05/2011, 12h48
  3. VCO 5Hz à 5Khz
    Par invite4ce2896a dans le forum Électronique
    Réponses: 5
    Dernier message: 30/04/2011, 13h51
  4. Créer un recepteur Radio MF 331.5khz
    Par invite60bb953f dans le forum Électronique
    Réponses: 4
    Dernier message: 06/07/2007, 10h34
  5. Horloge 1Hz
    Par invitef062af48 dans le forum Électronique
    Réponses: 27
    Dernier message: 13/02/2007, 20h44
Dans la rubrique Tech de Futura, découvrez nos comparatifs produits sur l'informatique et les technologies : imprimantes laser couleur, casques audio, chaises gamer...