« I2L 2023 Groupe6 » : différence entre les versions

De wiki-se.plil.fr
Aller à la navigation Aller à la recherche
 
(58 versions intermédiaires par 3 utilisateurs non affichées)
Ligne 37 : Ligne 37 :
Vous n'avez pas à écrire de programme PC avec la bibliothèque <code>libusb</code>.
Vous n'avez pas à écrire de programme PC avec la bibliothèque <code>libusb</code>.


Durant les séances des 28 et 29 septembre, il n'a pas été possible de faire fonctionner la démonstration <code>AudioOutput</code> de la bibliothèque LUFA. Après un examen des sources cet exemple n'est utilisable que sur les AVR avec USB matériel de série 4 et supérieur (un ATMega16u2 appartient à la série 2, pour faire fonctionner directement l'exemple un ATMega32u4, au minimu, était nécessaire). La modification de la carte n'étant pas possible dans les délais impartis, d'autres pistes sont suggérées.
Durant les séances des 28 et 29 septembre, il n'a pas été possible de faire fonctionner la démonstration <code>AudioOutput</code> de la bibliothèque LUFA. Après un examen des sources cet exemple n'est utilisable que sur les AVR avec USB matériel de série 4 et supérieur (un ATMega16u2 appartient à la série 2, pour faire fonctionner directement l'exemple un ATMega32u4, au minimum, était nécessaire). La modification de la carte n'étant pas possible dans les délais impartis, d'autres pistes sont suggérées.


Tout d'abord il est possible de faire fonctionner la démonstration <code>AudioOutput</code> dans un mode dégradé. En effet la différence entre un ATMega16u2 et un ATMega32u4 concernant la démonstration est que le premier ne permet que des points d'accès de taille 64 octets aux maximum alors que le second permet de monter à 256 octets. Par ailleurs pour les points d'accès isochrones de a démonstration il semble que le mode "ping-pong" soit nécessaire. Ce mode consiste à utiliser deux tampons pour les transferts USB afin de les accélérer. Le mode "ping-pong" est disponible pour le point d'accès 1 sur les ATMega32u4 et sur les points d'accès 3 et 4 sur les ATMega16u2.
Tout d'abord il est possible de faire fonctionner la démonstration <code>AudioOutput</code> dans un mode dégradé. En effet la différence entre un ATMega16u2 et un ATMega32u4 concernant la démonstration est que le premier ne permet que des points d'accès de taille 64 octets aux maximum alors que le second permet de monter à 256 octets. Par ailleurs pour les points d'accès isochrones de la démonstration il semble que le mode "ping-pong" soit nécessaire. Ce mode consiste à utiliser deux tampons pour les transferts USB afin de les accélérer. Le mode "ping-pong" est disponible pour le point d'accès 1 sur les ATMega32u4 et sur les points d'accès 3 et 4 sur les ATMega16u2.


Une première solution consiste donc à modifier la démonstration pour tourner avec un point d'accès 3 et une taille de 64 octets : [[Média:LUFA_AudioOutput_ATMega16u2.zip]]. Malheureusement avec des points d'accès de 64 octets il n'est pas possible de dépasser une fréquence d'échantillons de 11025Hz pour un fichier audio avec deux canaux et 16 bits par échantillon (la configuration la plus courante). Il est donc possible que le logiciel de lecture des livres audio refuse de coopérer. Voyez ce que vous pouvez faire de ce coté.
Une première solution consiste donc à modifier la démonstration pour tourner avec un point d'accès 3 et une taille de 64 octets : [[Média:LUFA_AudioOutput_ATMega16u2.zip]]. Malheureusement avec des points d'accès de 64 octets il n'est pas possible de dépasser une fréquence d'échantillons de 11025Hz pour un fichier audio avec deux canaux et 16 bits par échantillon (la configuration la plus courante). Il est donc possible que le logiciel de lecture des livres audio refuse de coopérer. Voyez ce que vous pouvez faire de ce coté.
Ligne 52 : Ligne 52 :


= Proposition définitive =
= Proposition définitive =
Selon les 2 solutions proposées , on a choisi la première solution en intégrant le dossier  [[Média:LUFA_AudioOutput_ATMega16u2.zip]] , sauf qu'on peut pas dépasser une fréquence d'échantillons de 11025 Hz et pour ce faire on a choisi comme lecteur de livres audios '''AUDACIOUS'''  qui est un lecteur audio Open Source , il prend en charge plusieurs format audio notamment  le format '''WAV''' qu'on utilise dans notre système embarqué  . Il nous permet de choisir sur quelle carte son on peut diffuser le son dans notre cas  c'est notre carte son et avant de diffuser le son il le convertit en une fréquence d'échantillons de 11khz .
Selon les 2 solutions proposées , on a commencé  par la première solution en intégrant le dossier  [[Média:LUFA_AudioOutput_ATMega16u2.zip]] , sauf qu'on peut pas dépasser une fréquence d'échantillons de 11025 Hz et pour ce faire on a choisi comme lecteur de livres audios '''AUDACIOUS'''  qui est un lecteur audio Open Source , il prend en charge plusieurs format audio notamment  le format '''WAV''' qu'on utilise dans notre système embarqué  . Il nous permet de choisir sur quelle carte son on peut diffuser le son dans notre cas  c'est notre carte son .  


Pour l'interface clavier on a fusionné le dossier '''Keyboard''' de la librairie '''LUFA''' avec notre dossier principal '''AudioOutput''' , ce qui nous permet finalement d'avoir un seul dossier avec 2 interfaces  , l'interface audio pour la diffusion du son  et l 'interface Clavier qui comprend 6 boutons :
Cependant on a choisi la deuxième solution en intégrant le dossier [[Média:LUFA_KeyboardAudioSpecific_ATMega16u2.zip]] , en insérant le module '''snd_aloop''' dans le noyau , on a eu deux nouvelles cartes disponibles  et en utilisant le code du sous-répertoire PC qui permet de faire le lien entre la carte virtuelle et le périphérique USB.


* ''Bouton Pause'' : qui permet de mettre l'audio en mode Pause .
Pour l'interface clavier on a fusionné le dossier '''Keyboard''' de la librairie '''LUFA''' avec notre dossier principal '''AudioOutput''' , ce qui nous permet finalement d'avoir un seul dossier avec 2 interfaces : l'interface audio pour la diffusion du son  et l 'interface Clavier qui comprend 5 boutons :  
* ''Bouton Play'' : qui permet de mettre l'audio en mode Play.
* ''Bouton Avancer'' :qui permet d'avancer vers l'audio suivant .
* ''Bouton Reculer'' : qui permet de retourner vers l'audio précédent.
* ''Bouton moins (-)'' : qui permet de baisser le volume de l'audio.
* ''Bouton plus (+)'' : qui permet d'augmenter le volume de l'audio.


Finalement notre système embarqué nous donne un casque audio qui lit les livres audios avec des boutons de contrôle.
* ''Bouton Pause/ Play'' : qui permet de mettre l'audio en mode Pause ou en mode Play .
* ''Bouton Précédent  :''qui permet d'avancer vers l'audio suivant .
* ''Bouton Suivant'' : qui permet de retourner vers l'audio précédent.
* ''Bouton Avancer'' : qui permet de faire avancer l'audio de quelques secondes.
* ''Bouton Reculer'' : qui permet  faire reculer l'audio de quelques secondes .


= Répartition du travail =
Finalement notre système embarqué nous donne un casque audio qui lit les livres audios avec des boutons de contrôle


= Carte =
= Carte =
[[Fichier:Page1-600px-I2L-2023-CarteSchema-G2.pdf.jpg|thumb|left|400px]]
[[Fichier:Page1-800px-I2L-2023-CarteSchema-G1.pdf.jpg|thumb|right|400px|Page1-800px-I2L-2023-CarteSchema-G1.pdf]]
[[Fichier:Carte du SE.png|thumb|center|600px|les différents composants de la carte]]
<p style="clear: both;" /><p style="clear: both;" />


[[Fichier:Page1-600px-I2L-2023-CarteSchema-G1-v2.pdf.jpg|vignette|gauche|Schéma de la carte du groupe 1]]
== Conception ==
[[Fichier:Page1-600px-I2L-2023-CarteSchema-G2.pdf.jpg|vignette|droite|Schéma de la carte de l'an dernier]]
[[Fichier:Schéma explicatif du SE.png|thumb|right|400px|schéma explicatif du SE]]
On a utilisé la '''snd_aloop''' est un module noyau '''ALSA''' ''(Advanced Linux Sound Architecture)'' qui permet de créer des cartes sonores virtuelles pour diriger ou rediriger le flux audio à l'intérieur du système, permettant de rediriger le flux audio d'une application vers une autre, d'enregistrer le flux audio ou de l'écouter sans avoir besoin de matériel audio supplémentaire.
Ce module nous a généré 2 cartes sons : la première envoie le flux audio récupéré à partir de '''Audacious''' qui est est un lecteur audio open-source pour les systèmes d'exploitation Linux à la deuxième carte son qui , en utilisant l'API classique ALSA elle fait le lien avec le périphérique USB en utilisant le code du sous répertoire '''PC''' en exécutant la commande '''aplay''' pour diffuser le son on utilise la librairie '''LUFA''' qui est compilé avec la constante FROM_ALSA définie dans le code.
<p style="clear: both;" />


Vous pourrez utiliser la carte du groupe 1 avec la carte clavier du groupe 2 de l'an dernier.
= Code =
 
Dans ce code, on a le clavier qui comprend les 5 boutons  de contrôle du casque Audio , quand l'audio est en mode pause la LED est en rouge sinon est en vert : <syntaxhighlight lang="c" line="1">
<p style="clear: both;" />
#include <stdlib.h>


#include "Keyboard.h"
#include <util/delay.h>
#define LEDVOL
#define BOUTON 4
#define BOUTON2 2


[[Fichier:I2L-2023-G6-PhotoEnsemble.jpg|vignette|centre|Photo du dispositif complet]]
#define SW3 3
#define SW4 4
#define SW5 5
#define SW6 6


= Code =
- Dans ce code, nous avons fait deux actions, un bouton qui pour chaque appuie  change de couleur et un autre bouton qui emet un son.<syntaxhighlight lang="c" line="1">
#include <avr/io.h>
#include <util/delay.h>


#define GREEN 0
#define GREEN 0
#define RED 1
#define RED 1
#define BLUE 2
#define BLUE 2
#define BOUTON 4
#define BOUTON2 2
#define SPEAKER


void make_note_delay(int note)
int currentColor = BLUE;
void CreateKeyboardReport(USB_KeyboardReport_Data_t* const ReportData)
{
{
    // attente d'un demi-cycle
 
     switch (note)
int UsedKeyCodes = 0;
    {
// Initialize the LEDs to BLUE at the start
        case 413:
     PORTD &= ~(1 << BLUE);
            _delay_us(1000000 / 413 / 2);
                    PORTD |= (1 << GREEN);
            break;
                    PORTD |= (1 << RED);
        case 440:
 
            _delay_us(1000000 / 440 / 2);
/* Clear the report contents */
            break;
memset(ReportData, 0, sizeof(USB_KeyboardReport_Data_t));
        case 634:
DDRD &= ~((1 << SW3) | (1 << SW5)| (1<<SW6) | (1<<SW4)); // Set Button pins as inputs
            _delay_us(1000000 / 634 / 2);
    PORTD |= (1 << SW3) | (1 << SW5) | (1<<SW6) | (1<<SW4); // Enable pull-up resistors on the Buttons
            break;
DDRC &= ~((1 << BOUTON) | (1 << BOUTON2)); // Set Button pins as inputs
        case 660:
    PORTC |= (1 << BOUTON) | (1 << BOUTON2); // Enable pull-up resistors on the Buttons
            _delay_us(1000000 / 660 / 2);
 
            break;
// next track
        case 743:
if (!(PIND & (1 << SW3)))
            _delay_us(1000000 / 743 / 2);
  ReportData->KeyCode[UsedKeyCodes++] = HID_KEYBOARD_SC_F9;
            break;
if (!(PIND & (1 << SW5)))
        case 792:
  ReportData->KeyCode[UsedKeyCodes++] = HID_KEYBOARD_SC_UP_ARROW;
            _delay_us(1000000 / 792 / 2);
if (!(PIND & (1 << SW6)))
            break;
  ReportData->KeyCode[UsedKeyCodes++] = HID_KEYBOARD_SC_DOWN_ARROW;
        case 825:
 
            _delay_us(1000000 / 825 / 2);
  // space work = pause /play
            break;
if (!(PIND & (1 << SW4))){
         case 1056:
_delay_ms(10);  
            _delay_us(1000000 / 1056 / 2);
if (currentColor == BLUE)
            break;
         currentColor = GREEN;
     }
    else if (currentColor == GREEN)
}
        currentColor = RED;
void play_note(int note, int periode)
    else
{
        currentColor = BLUE;
    for (int i = 0; i < periode; i++)
     ReportData->KeyCode[UsedKeyCodes++] = HID_KEYBOARD_SC_SPACE;
    {
        PORTB = 255;
}
        make_note_delay(note);
if (!(PINC & (1 << BOUTON)))
        PORTB = 0;
  ReportData->KeyCode[UsedKeyCodes++] = HID_KEYBOARD_SC_LEFT_ARROW;
        make_note_delay(note);
if (!(PINC & (1 << BOUTON2))){
    }
ReportData->KeyCode[UsedKeyCodes++] = HID_KEYBOARD_SC_RIGHT_ARROW; // Touche "Alt"
}
 
/* Make sent key uppercase by indicating that the left shift key is pressed */
//ReportData->Modifier = HID_KEYBOARD_MODIFIER_LEFTSHIFT;
 
//ReportData->KeyCode[UsedKeyCodes++] = HID_KEYBOARD_SC_A;
}
}




int main(void){
    DDRD |= (1 << GREEN) | (1 << RED) | (1 << BLUE) ; // Set Green, Red, Blue as outputs
    DDRC &= ~((1 << BOUTON) | (1 << BOUTON2)); // Set Button pins as inputs
    PORTC |= (1 << BOUTON) | (1 << BOUTON2); // Enable pull-up resistors on the Buttons
    CLKSEL0 = 0b00010101;  // sélection de l'horloge externe
    CLKSEL1 = 0b00001111;  // minimum de 8Mhz
    CLKPR = 0b10000000;    // modification du diviseur d'horloge (CLKPCE=1)
    CLKPR = 0;              // 0 pour pas de diviseur (diviseur de 1)


    DDRB = 255;
/** ISR to handle the reloading of the PWM timer with the next sample. */
ISR(TIMER0_COMPA_vect, ISR_BLOCK)
{
uint8_t PrevEndpoint = Endpoint_GetCurrentEndpoint();
 
/* Select the audio stream endpoint */
Endpoint_SelectEndpoint(AUDIO_OUT_EPADDR);


    int currentColor = GREEN; // Start with Green
/* Check if the current endpoint can be read from (contains a packet) and the host is sending data */
if (Endpoint_IsOUTReceived())
{
/* Retrieve the unsigned 8-bit samples */
uint8_t sample = Endpoint_Read_8();


    while(1){
/* Check to see if the bank is now empty */
        if(!(PINC & (1 << BOUTON))) { // If the first button is pressed
if (!(Endpoint_IsReadWriteAllowed()))
            //_delay_ms(10); // Debounce delay
{
            if(!(PINC & (1 << BOUTON))) { // If the button is still pressed after debouncing
/* Acknowledge the packet, clear the bank ready for the next packet */
                // Toggle to the next color
Endpoint_ClearOUT();
                if(currentColor == GREEN) {
}
                    PORTD &= ~(1 << RED);
                    PORTD |= (1 << GREEN);
                    PORTD |= (1 << BLUE);
                    currentColor = RED;
                } else if(currentColor == RED) {
                    PORTD &= ~(1 << BLUE);
                    PORTD |= (1 << GREEN);
                    PORTD |= (1 << RED);
                    currentColor = BLUE;
                } else if(currentColor == BLUE) {
                    PORTD &= ~(1 << GREEN);
                    PORTD |= (1 << RED);
                    PORTD |= (1 << BLUE);
                    currentColor = GREEN;
                }
            }


             while(!(PINC & (1 << BOUTON))); // Wait for the button to be released
PORTB = sample;
/* Set the LED colors based on the currentColor variable */
        if (currentColor == GREEN)
        {
             PORTD &= ~(1 << RED);
            PORTD |= (1 << GREEN);
            PORTD |= (1 << BLUE);
         }
         }
         if (!(PINC & (1 << BOUTON2))) {
         else if (currentColor == RED)
             play_note(792, 198);
        {
             while (!(PINC & (1 << BOUTON2))); // Wait for the button to be released
            PORTD &= ~(1 << GREEN);
             PORTD |= (1 << BLUE);
             PORTD |= (1 << RED);
         }
         }
    }
     
}


    return 0;
Endpoint_SelectEndpoint(PrevEndpoint);
}
}


</syntaxhighlight>


</syntaxhighlight>
== Compilation ==
Les différentes commandes faites pour diffuser le son dans la carte :


== Conception ==
à partir du dossier AudioOutRex :


== Réalisation ==
$ make clean
$ make
$ sudo make dfu
$ cd /PC
$ sudo ./play hw:2,1,0


= Démonstrations =
= Démonstrations =
[[Fichier:Vidéo démonstrative.mp4|thumb|400px|center]]
<p style="clear: both;" /><p style="clear: both;" />
Vidéo explicatif du fonctionnement du casque audio , englobant la diffusion du son et les 5 touches du clavier (play/pause, suivant, précédent, accélérer , décélérer)


= Rendus =
= Rendus =


Projet KiCAD : [[File:I2L-2023-Carte-G6.zip]]
Projet KiCAD : [[File:I2L-2023-Carte-G6.zip]]
 
Programmes :[[Fichier:I2L-2022-Programmes-G6.zip]]
Programmes : [[File:I2L-2022-Programmes-G6.zip]]

Version actuelle datée du 21 décembre 2023 à 16:06

Proposition de système

Objectif:

Créez un petit dispositif portable capable de lire des livres audio sur l'ordinateur. L'utilisateur peut naviguer à travers les livres audio à l'aide des touches et écouter le contenu via le haut-parleur intégré, il aura également 3 LED : une verte qui signifie que l’audio est en mode marche (play), une bleu qui sera allumée quand l’audio est en mode pause (pause) et une rouge indiquant qu'il y a un souci particulier.

Matériels :

  • Microcontrôleur ;
  • LED ;
  • Touches ;
  • Haut-parleur.

Composants nécessaires:

  1. Microcontrôleur ;
  2. Haut-parleur : Intégrer un haut-parleur ou un transducteur piézoélectrique pour la sortie audio ;
  3. Boutons de contrôle : Ajouter des boutons pour la navigation, la lecture/pause.
  4. LED : couleur rouge s’il a un problème , couleur verte si c’est en mode marche (play) et couleur bleu si c’est en mode pause.

Fonctionnalités:

  1. Lecture de livres audio ;
  2. Navigation dans la liste des livres audio et des chapitres ;
  3. Possibilité de mettre en pause, de reprendre la lecture.

Fonctionnalités Supplémentaires :

  1. Réglage du volume et contrôle de la lecture.

Contre-proposition

Votre carte doit se comporter comme un périphérique USB composite, à savoir un périphérique HID clavier et une carte son.

Pour la programmation du périphèrique USB vous utilisez, comme base, les démonstration LUFA :

  • Demos/Device/LowLevel/AudioOutput ;
  • et Demos/Device/LowLevel/Keyboard.

Vous n'avez pas à écrire de programme PC avec la bibliothèque libusb.

Durant les séances des 28 et 29 septembre, il n'a pas été possible de faire fonctionner la démonstration AudioOutput de la bibliothèque LUFA. Après un examen des sources cet exemple n'est utilisable que sur les AVR avec USB matériel de série 4 et supérieur (un ATMega16u2 appartient à la série 2, pour faire fonctionner directement l'exemple un ATMega32u4, au minimum, était nécessaire). La modification de la carte n'étant pas possible dans les délais impartis, d'autres pistes sont suggérées.

Tout d'abord il est possible de faire fonctionner la démonstration AudioOutput dans un mode dégradé. En effet la différence entre un ATMega16u2 et un ATMega32u4 concernant la démonstration est que le premier ne permet que des points d'accès de taille 64 octets aux maximum alors que le second permet de monter à 256 octets. Par ailleurs pour les points d'accès isochrones de la démonstration il semble que le mode "ping-pong" soit nécessaire. Ce mode consiste à utiliser deux tampons pour les transferts USB afin de les accélérer. Le mode "ping-pong" est disponible pour le point d'accès 1 sur les ATMega32u4 et sur les points d'accès 3 et 4 sur les ATMega16u2.

Une première solution consiste donc à modifier la démonstration pour tourner avec un point d'accès 3 et une taille de 64 octets : Média:LUFA_AudioOutput_ATMega16u2.zip. Malheureusement avec des points d'accès de 64 octets il n'est pas possible de dépasser une fréquence d'échantillons de 11025Hz pour un fichier audio avec deux canaux et 16 bits par échantillon (la configuration la plus courante). Il est donc possible que le logiciel de lecture des livres audio refuse de coopérer. Voyez ce que vous pouvez faire de ce coté.

Une seconde solution consiste à abandonner la création d'une carte son USB standard et de créer un périphérique USB spécifique. C'est ce qui a été fait, à base de la démonstration du clavier, dans la démonstration Média:LUFA_KeyboardAudioSpecific_ATMega16u2.zip. Dans cette configuration le périphérique n'est plus reconnu par le noyau comme une carte son. Il faut écrire un programme spécifique pour l'utiliser.

Il est tentant d'écrire un programme lisant un fichier WAV et l'envoyant sur la carte son spécifique. C'est ce qui est réalisé dans le programme du sous-répertoire PC de la précédente démonstration lorsqu'il est compilé avec la constante FROM_WAVFILE définie. Cela fonctionne mais c'est difficile à utiliser dans votre projet : il faudrait inclure ce code dans celui du lecteur de livres audio.

L'autre solution est d'utiliser le module "loopback" du système son ALSA du noyau Linux. Après insertion du module snd_aloop dans le noyau, deux nouvelles cartes sont disponibles. La première est un puits vers lequel il est possible d'envoyer un flux audio. Le flux peut être récupéré sur la seconde carte son par l'API classique d'ALSA. Il est donc possible d'écrire un programme qui fait le lien entre cette carte son virtuelle et le périphérique USB spécifique. C'est ce qui est réalisé dans le programme du sous-répertoire PC de la précédente démonstration lorsqu'il est compilé avec la constante FROM_ALSA définie.

Vous avez donc plusieurs solution pour réaliser votre projet avec le matériel disponible. A vous de jouer.

Proposition définitive

Selon les 2 solutions proposées , on a commencé par la première solution en intégrant le dossier Média:LUFA_AudioOutput_ATMega16u2.zip , sauf qu'on peut pas dépasser une fréquence d'échantillons de 11025 Hz et pour ce faire on a choisi comme lecteur de livres audios AUDACIOUS qui est un lecteur audio Open Source , il prend en charge plusieurs format audio notamment le format WAV qu'on utilise dans notre système embarqué . Il nous permet de choisir sur quelle carte son on peut diffuser le son dans notre cas c'est notre carte son .

Cependant on a choisi la deuxième solution en intégrant le dossier Média:LUFA_KeyboardAudioSpecific_ATMega16u2.zip , en insérant le module snd_aloop dans le noyau , on a eu deux nouvelles cartes disponibles et en utilisant le code du sous-répertoire PC qui permet de faire le lien entre la carte virtuelle et le périphérique USB.

Pour l'interface clavier on a fusionné le dossier Keyboard de la librairie LUFA avec notre dossier principal AudioOutput , ce qui nous permet finalement d'avoir un seul dossier avec 2 interfaces : l'interface audio pour la diffusion du son et l 'interface Clavier qui comprend 5 boutons :

  • Bouton Pause/ Play : qui permet de mettre l'audio en mode Pause ou en mode Play .
  • Bouton Précédent  :qui permet d'avancer vers l'audio suivant .
  • Bouton Suivant : qui permet de retourner vers l'audio précédent.
  • Bouton Avancer : qui permet de faire avancer l'audio de quelques secondes.
  • Bouton Reculer : qui permet faire reculer l'audio de quelques secondes .

Finalement notre système embarqué nous donne un casque audio qui lit les livres audios avec des boutons de contrôle

Carte

Page1-600px-I2L-2023-CarteSchema-G2.pdf.jpg
Page1-800px-I2L-2023-CarteSchema-G1.pdf
les différents composants de la carte

Conception

schéma explicatif du SE

On a utilisé la snd_aloop est un module noyau ALSA (Advanced Linux Sound Architecture) qui permet de créer des cartes sonores virtuelles pour diriger ou rediriger le flux audio à l'intérieur du système, permettant de rediriger le flux audio d'une application vers une autre, d'enregistrer le flux audio ou de l'écouter sans avoir besoin de matériel audio supplémentaire. Ce module nous a généré 2 cartes sons : la première envoie le flux audio récupéré à partir de Audacious qui est est un lecteur audio open-source pour les systèmes d'exploitation Linux à la deuxième carte son qui , en utilisant l'API classique ALSA elle fait le lien avec le périphérique USB en utilisant le code du sous répertoire PC en exécutant la commande aplay pour diffuser le son on utilise la librairie LUFA qui est compilé avec la constante FROM_ALSA définie dans le code.

Code

Dans ce code, on a le clavier qui comprend les 5 boutons de contrôle du casque Audio , quand l'audio est en mode pause la LED est en rouge sinon est en vert :

#include <stdlib.h>

#include "Keyboard.h"
#include <util/delay.h>
#define LEDVOL
#define BOUTON 4
#define BOUTON2 2

#define SW3 3
#define SW4 4
#define SW5 5
#define SW6 6


#define GREEN 0
#define RED 1
#define BLUE 2

int currentColor = BLUE;
void CreateKeyboardReport(USB_KeyboardReport_Data_t* const ReportData)
{

	int UsedKeyCodes = 0;
	 // Initialize the LEDs to BLUE at the start
    PORTD &= ~(1 << BLUE);
                    PORTD |= (1 << GREEN);
                    PORTD |= (1 << RED);

	/* Clear the report contents */
	memset(ReportData, 0, sizeof(USB_KeyboardReport_Data_t));
	DDRD &= ~((1 << SW3) | (1 << SW5)| (1<<SW6) | (1<<SW4)); // Set Button pins as inputs
    PORTD |= (1 << SW3) | (1 << SW5) | (1<<SW6) | (1<<SW4); // Enable pull-up resistors on the Buttons
	DDRC &= ~((1 << BOUTON) | (1 << BOUTON2)); // Set Button pins as inputs
    PORTC |= (1 << BOUTON) | (1 << BOUTON2); // Enable pull-up resistors on the Buttons

	// next track
	if (!(PIND & (1 << SW3)))
	  ReportData->KeyCode[UsedKeyCodes++] = HID_KEYBOARD_SC_F9;
	if (!(PIND & (1 << SW5)))
	  ReportData->KeyCode[UsedKeyCodes++] = HID_KEYBOARD_SC_UP_ARROW;
	if (!(PIND & (1 << SW6)))
	  ReportData->KeyCode[UsedKeyCodes++] = HID_KEYBOARD_SC_DOWN_ARROW;

	  // space work = pause /play
	if (!(PIND & (1 << SW4))){
		_delay_ms(10); 
		if (currentColor == BLUE)
        currentColor = GREEN;
    else if (currentColor == GREEN)
        currentColor = RED;
    else
        currentColor = BLUE;
    ReportData->KeyCode[UsedKeyCodes++] = HID_KEYBOARD_SC_SPACE;
		
	}
	if (!(PINC & (1 << BOUTON)))
	  ReportData->KeyCode[UsedKeyCodes++] = HID_KEYBOARD_SC_LEFT_ARROW;
	if (!(PINC & (1 << BOUTON2))){
	ReportData->KeyCode[UsedKeyCodes++] = HID_KEYBOARD_SC_RIGHT_ARROW;  // Touche "Alt"
 }

	/* Make sent key uppercase by indicating that the left shift key is pressed */
	//ReportData->Modifier = HID_KEYBOARD_MODIFIER_LEFTSHIFT;

	//ReportData->KeyCode[UsedKeyCodes++] = HID_KEYBOARD_SC_A;
}



/** ISR to handle the reloading of the PWM timer with the next sample. */
ISR(TIMER0_COMPA_vect, ISR_BLOCK)
{
	uint8_t PrevEndpoint = Endpoint_GetCurrentEndpoint();

	/* Select the audio stream endpoint */
	Endpoint_SelectEndpoint(AUDIO_OUT_EPADDR);

	/* Check if the current endpoint can be read from (contains a packet) and the host is sending data */
	if (Endpoint_IsOUTReceived())
	{
		/* Retrieve the unsigned 8-bit samples */
		uint8_t sample = Endpoint_Read_8();

		/* Check to see if the bank is now empty */
		if (!(Endpoint_IsReadWriteAllowed()))
		{
			/* Acknowledge the packet, clear the bank ready for the next packet */
			Endpoint_ClearOUT();
		}

		PORTB = sample;
		/* Set the LED colors based on the currentColor variable */
        if (currentColor == GREEN)
        {
            PORTD &= ~(1 << RED);
            PORTD |= (1 << GREEN);
            PORTD |= (1 << BLUE);
        }
        else if (currentColor == RED)
        {
            PORTD &= ~(1 << GREEN);
            PORTD |= (1 << BLUE);
            PORTD |= (1 << RED);
        }
       
	
	}

	Endpoint_SelectEndpoint(PrevEndpoint);
}

Compilation

Les différentes commandes faites pour diffuser le son dans la carte :

à partir du dossier AudioOutRex :

$ make clean
$ make
$ sudo make dfu
$ cd /PC
$ sudo ./play hw:2,1,0

Démonstrations

Vidéo explicatif du fonctionnement du casque audio , englobant la diffusion du son et les 5 touches du clavier (play/pause, suivant, précédent, accélérer , décélérer)

Rendus

Projet KiCAD : Fichier:I2L-2023-Carte-G6.zip Programmes :Fichier:I2L-2022-Programmes-G6.zip