Aller au contenu


Photo
- - - - -

Traitement audio via Arduino


8 réponses à ce sujet

#1 Black Templar

Black Templar

    Membre

  • Membres
  • PipPipPipPipPip
  • 1 430 messages
  • Gender:Male
  • Location:Lille

Posté 06 décembre 2012 - 06:29

Bonjour à tous.

Je suis en train de préparer le mini-projet de fin d'année de mes étudiants, en élec.
Cette année, j'ai envie d'essayer de leurs faire prendre conscience des problématiques liées au passage numérique/analogique. J'aimerais aussi en profiter pour rapprocher l'élec de l'informatique (pour leurs montrer que l'un n'exclut pas l'autre et inversement).

Du coup, je me suis dit pourquoi ne pas faire un projet élec intégrant une Arduino ! Comme ça, il y a de l'élec analogique (partie centrale du projet), de la programmation, et bien sur, l'interface élec analogique/élec numérique.
Et comme il y a pas mal de monde ici qui s'amuse avec Arduino, je me suis dit qu'il pourrait être intéressant de partager ce projet.



Le projet :

Le projet aura donc pour but de récupérer un signal sonore (lecteur MP3), de l'amplifier correctement pour l'envoyer sur l'Arduino (signal entre 0 et 5V).
L'Arduino récupèrera les échantillons grâce au convertisseur analogique-numérique intégré. Je vais essayer d'échantillonner à 40.1kHz histoire de respecter les normes. Une fois les échantillons récupérés, ils seront traités à l'aide d'une bibliothèque (que je n'ai pas encore écrite). En gros, si je pouvais implémenter un passe-bas numérique, un effet écho/réverbère et un effet saturation, ça serait sympa.

Une fois l'échantillon traité, celui-ci est directement envoyé à un port 8bits de l'Arduino. Ainsi, il y aura 8 sorties numériques (1 ou 0) qui encoderont l'échantillon.
Ces 8 sorties passeront dans un réseau R2R (voir ce post) afin de reconstituer le signal analogique.
Ce signal sera passé dans un filtre passe-bas à ~20kHz (passif, actif, 1°ordre, 2° ordre, je ne sais pas encore) puis envoyé à un petit ampli tout simple pour piloter un petit haut-parleur afin d'écouter le rendu.


Voila en gros le projet. J'ai fait un petit schéma de principe pour récapituler tout ça :
principe.png


Pour le moment, je viens de finir le préampli. Il permet d'avoir en sortie un signal de 2V crête (4V crête-crête) centré sur 2.5V.
Ce signal peut donc être envoyé tel quel au CAN de l'arduino.
preampli.png

Le montage à bien entendu été testé et marche parfaitement (j'aurais juste pu poussé un peu plus le gain. De toute manière la Zener protège l'arduino)
preampli.jpg

Mon site internet : http://ferdinandpiette.com/


#2 Black Templar

Black Templar

    Membre

  • Membres
  • PipPipPipPipPip
  • 1 430 messages
  • Gender:Male
  • Location:Lille

Posté 07 décembre 2012 - 11:54

Salut.

Ce soir, je me suis attaqué au DAC, passe-bas et à l'ampli.
J'ai essayé de faire au plus simple, avec un AOP double uniquement.

Voilà le schéma
dac_ampli.png

- C1 et R17 coupent les basses fréquences < ~0.5Hz afin de supprimer la composante continue (R17 est très important sinon, on a un potentiel flottant sur l'entrée non inverseuse de U1:A !)

- R18 et C2 forment un filtre passe bas de fréquence de coupure 1/(pi.R18.C2) dans le cas où R18 = R19 (et oui, on a un coef de deux sur la fréquence car le passe bas et l'ampli s'influencent mutuellement !!)

- Le gain de l'ampli est égal à RV1 / (2.R19) (ici on a un coef de deux à cause du passe bas qui se trouve avant)


- La résistance R20 est indispensable en audio car elle permet de "linéariser" la discontinuité du à la commutation des transistors. Sans ça, si on branche un haut parleur en sortie, on entendra un petit grésillement très désagréable.




Le montage est bien entendu lui aussi fonctionnel, testé et validé.
dac_ampli.jpg

D'ailleurs, je m'améliore en soudure Image IPB C'est pas encore parfait, mais déjà plus précis qu'avant
soudures_dac_ampli.jpg

J'ai testé le montage en faisant générer à mon arduino un sinus de 400Hz (voir le code ici). Rendu impeccable à l'oscillo. J'ai aussi testé avec un HP 8ohm 1W, le son est nickel.
sinus_400Hz.jpg

Enfin, voici tous les composants du projet : L'arduino (méga) en haut, le DAC/passe-bas/ampli au centre et le préampli en bas.
preampli_dac_ampli_arduino.jpg

Il ne reste plus qu'a écrire le programme et les fonctions de traitement audio Image IPB

Mon site internet : http://ferdinandpiette.com/


#3 Jbot

Jbot

    Membre chevronné

  • Membres
  • PipPipPipPip
  • 801 messages
  • Gender:Male
  • Location:Paris

Posté 08 décembre 2012 - 10:22

Ca c'est un bon prof soucieux de faire des projets interessant à ses élèves dis donc ! ^^


Malédiction du Créatif :
Plus vous avez d’idées et moins vous arrivez à les structurer.


#4 Black Templar

Black Templar

    Membre

  • Membres
  • PipPipPipPipPip
  • 1 430 messages
  • Gender:Male
  • Location:Lille

Posté 08 décembre 2012 - 02:57

Ca c'est un bon prof soucieux de faire des projets interessant à ses élèves dis donc ! ^^


Héhé, il faut bien réussir à les intéresser un peu ^^
J'aurais bien voulu avoir des projets de ce style durant ma scolarité...

Bon, pour le moment, j'essaye d'échantillonner un signal à 44.1kHz, de le convertir sur 8 bits et de l'écrire sur un des ports de l'Arduino.
Comme ça, je serais capable de tester toute la chaine du montage en écoutant en sortie le signal d'entrée.

Mais c'est moins simple que ça en à l'air ! Avec Arduino, on ne peut pas dépasser les 15KHz en échantillonnage :/ Du coup, je dois configurer directement l'Atmel.
Pour le moment, j'ai réussi à échantillonner à 44.1kHz et j'ai configurer le convertisseur analogique numérique pour qu'il puisse échantillonner à 77kHz max.

#define FASTADC 1

// defines for setting and clearing register bits
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

int sample;

void setup() {

  
#if FASTADC
  // set prescale to 16
  sbi(ADCSRA,ADPS2) ; // 1
  cbi(ADCSRA,ADPS1) ; // 0
  cbi(ADCSRA,ADPS0) ; // 0
#endif


  // Initialisation du port7 (arduino Mega : pin 42 à 49)
  for(int i = 0; i < 8;  i++) {
	pinMode(42+i,OUTPUT); 
  }
  //pinMode(13,OUTPUT);  
  DDRB = 0xFF;//all outputs
  
  // Configuration du timer1.
  // Interruption à 40kHz
  noInterrupts();
  
  TCCR1A = B00000000;// set entire TCCR0A register to 0
  TCCR1B = B00000000;// same for TCCR0B
  TCNT1  = 0;//initialize counter value to 0
  //OCR1A = 49;// = (16*10^6) / (40000*8) - 1 (must be <256)
  OCR1A = 362;// = (16*10^6) / (44100) - 1 (must be <256) (44077Hz)
  
  TCCR1B |= (1 << WGM12);   // CTC
  //TCCR1B |= (1 << CS11);	// prescale8
  TCCR1B |= (1 << CS10);	// prescale1
  //TIMSK1 |= (1 << OCIE0A);  // timer compare interrupt enable
  TIMSK1 |= (1 << OCIE1A);  // timer compare interrupt enable
  
  interrupts();  
}

// Interruption timer 1
ISR(TIMER1_COMPA_vect){ //40kHz interrupt routine 
  PORTB = PORTB ^ B10000000;
  //sample = analogRead(0);
  //PORTL = sample/4;
}

void loop(){
}



Le code est encore un peu en vrac, mais il est fonctionnel.
Sans code dans l'interruption du timer, je suis bien à 44.1kHz.
Si j'essaye d'échantillonner, je tombe à 41.5kHz
Et si en plus, j'essaye d'écrire sur le port L, je tombe cette fois à 25.5kHz :/ (ce qui veut dire qu'arduino met 60µs à écrire sur un port ? :/ Ce qui risque d'être gênant pour une boucle de 2µs ...)

J'ai encore du boulot pour arriver à quelque chose de correct :/ Je vais essayer d'augmenter encore la vitesse de l'ADC, mais ça dégrade les performances (au dessus de 15kHz) :/



EDIT : J'ai compris ce qui ne va pas avec l'écriture sur le port L : en même temps, je fais une division par 4, c'est ça qui prend du temps ! Ce qui est étrange, c'est que le compilo n'optimise pas cette ligne de code ! Une division par 4 revient à décaler le nombre de 2 bits sur la droite.
En remplaçant PORTL = sample/4; par PORTL = sample>>2; l'écriture sur le port devient instantané.

EDIT 2 : Et voilà, en mettant un prescale à 8 au lieu de 16 sur la clock de l'ADC et en utilisant un décalage de bits à la place de la division, j'arrive à échantillonner à 44.1kHz et à faire sortir le signal numérique sur le port L.
Au niveau du rendu sonore, ça marche bien. J'entend bien le morceau joué par mon lecteur MP3 sur le hautparleur, le signal étant passé entre deux par l'arduino :)
J'espère juste que les fonctions de traitements audio ne seront pas trop chronophages :/

Voilà le code qui marche (toujours en vrac).
#define FASTADC 1

// defines for setting and clearing register bits
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

int sample;

void setup() {
#if FASTADC
  // set ADC prescale to 8
  //*
  cbi(ADCSRA,ADPS2) ; // 0
  sbi(ADCSRA,ADPS1) ; // 1
  sbi(ADCSRA,ADPS0) ; // 1
  //*/ 
#endif


  // Initialisation du port7 (arduino Mega : pin 42 à 49)
  for(int i = 0; i < 8;  i++) {
	pinMode(42+i,OUTPUT); 
  }
  //pinMode(13,OUTPUT);  
  DDRB = 0xFF;//all outputs
  
  // Configuration du timer1.
  // Interruption à 44.1kHz
  noInterrupts();
  
  TCCR1A = 0;// set entire TCCR0A register to 0
  TCCR1B = 0;// same for TCCR0B
  TCNT1  = 0;//initialize counter value to 0
  OCR1A = 362;// = (16*10^6) / (44100) - 1 (must be <256) (44077Hz)
  
  TCCR1B |= (1 << WGM12);   // CTC
  TCCR1B |= (1 << CS10);	// prescale1
  TIMSK1 |= (1 << OCIE1A);  // timer compare interrupt enable
  
  interrupts();  
}

// Interruption timer 1
ISR(TIMER1_COMPA_vect){ //44.1kHz interrupt routine 
  //PORTB = PORTB ^ B10000000; // pour tester la fréquence à l'oscillo
  sample = analogRead(0);
  PORTL = sample>>2;
}

void loop(){
}


Mon site internet : http://ferdinandpiette.com/


#5 Zebrech

Zebrech

    Nouveau membre

  • Membres
  • 1 messages

Posté 02 octobre 2014 - 01:38

Bonjour,

Je suis actuellement en Terminale S-si et ma partie de PPE conciste à faire varier la luminosité de 6 ampoules led, avec chacune un filtre de différente couleur, en fonction de la musique. L'idée est de découper le spectre sonore en 6 et d'assigner un voltage plus ou moins élevé afin de faire varier la luminosité et créer une sorte d'equalizer projeté vers le haut. Ce systeme se mettrait au pied d'un "mur" afin d'offrir un spectacle divertissant aux passants.

Il me faut donc acquérir un signal mp3 par une carte arduino comme présenté très clairement ici dans la première partie et je vous remercie d'avoir fait quelque chose d'aussi clair et précis.

Ensuite ca devient compliqué : il me faut convertir ce signal en spectre audio et le découper en 6. Dans la théorie il me faudrait assigner à chacune des 6 sorties de ma carte arduino une partie du spectre et lui associé un voltage en fonction de la hauteur du spectre puis transmettre cela à l'ampoule correspondante. J'aimerai savoir si cette partie et réalisable ou pas.

Je précise que je dois travaillé en TBT pour des raisons de sécurité et que les ampoules sont toutes à luminosité variable avec un maximum de 12V.



#6 Esteban Bellin

Esteban Bellin

    Nouveau membre

  • Membres
  • 1 messages

Posté 02 décembre 2018 - 05:24

bonjour,

 
je ne sais pas si tu vas pouvoir m'aidé je voudrai savoir:
 
 
 
 
comment fait on pour transformer un message vocal (je dirai quelque chose dans le microphone) en information pour qu'il puisse passer dans une première antenne
 
puis que le message soit reçus par la deuxième antenne
 
puis transformé a nouveaux pour être diffusé par un haut parleur
 
il faudrait que sa marche dans les deux sens un talkie walkie en faite


#7 Path

Path

    Made By Humans

  • Modérateur
  • PipPipPipPipPip
  • 2 504 messages
  • Gender:Male
  • Location:Paris

Posté 02 décembre 2018 - 09:32

Au bout de 4 ans, il y a peu de chance d'avoir une réponse.

Tu as regardé du coté de raspberry avec une carte son ?



#8 cocothebo

cocothebo

    Membre passionné

  • Membres
  • PipPipPip
  • 341 messages
  • Gender:Male

Posté 04 décembre 2018 - 10:28

Bonjour,

 

Je trouve ce genre de question toujours très ambiguë, tu veux faire quoi? le montage qui permet de moduler/demoduler le signal du micro ou tu veux juste faire un "talkie walkie" mais sans se soucier de comment ça marche?

 

Dans le 1er cas, regarde du côté d'un emetteur FM ou AM, les versions basiques sont assez simple à réaliser, l'idée c'est avoir une fréquence "porteuse"(relativement haute fréquence) sur lequel on rajoute notre information (le son du micro), c'est ce qu'on appelle une modulation. Après faut voir comment moduler la porteuse, en FM c'est la fréquence qui varie, en AM c'est l'amplitude du signal. (bien sur on peut même passer en numérique mais c'est plus compliqué)

Pour le montage le plus simple c'est de demander à google il connait bien.

 

Dans le cas 2, il suffit d'utiliser un module tout fait, quitte à passer la en numérique (un ADC pour numériser le son du micro, et coté réception, un dac pour passer du signal numérique à de l'analogique sur le haut parleur). En numérique, n'importe quel type de réseau pourra fonctionner facilement (BT, WIFI, Zigbee etc.)



#9 enum

enum

    Membre

  • Membres
  • 18 messages

Posté 05 mai 2019 - 07:12

Génial ce projet ! Je cherchais justement comment obtenir un signal audio avec de l'embarqué. Vraiment cool !





Répondre à ce sujet



  


1 utilisateur(s) li(sen)t ce sujet

0 members, 1 guests, 0 anonymous users