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

De wiki-se.plil.fr
Aller à la navigation Aller à la recherche
Aucun résumé des modifications
 
(28 versions intermédiaires par 4 utilisateurs non affichées)
Ligne 6 : Ligne 6 :


L'idée est bien de refléter l'ensemble de l'état des touches "verrous" du clavier du PC. A chaque changement d'état de ces touches vous associerez un signal lumineux avec les 3 LED multicolores et surtout un signal sonore. Vous êtes tenus de produire des sons et pas seulement des notes. Pour cela vous devrez réussir à stocker (en mémoire flash) des échantillons sonores et à les reproduire sur votre haut-parleur.
L'idée est bien de refléter l'ensemble de l'état des touches "verrous" du clavier du PC. A chaque changement d'état de ces touches vous associerez un signal lumineux avec les 3 LED multicolores et surtout un signal sonore. Vous êtes tenus de produire des sons et pas seulement des notes. Pour cela vous devrez réussir à stocker (en mémoire flash) des échantillons sonores et à les reproduire sur votre haut-parleur.
= Carte =
Photo de la carte et ses composants :
<gallery>
Fichier:Image CARTE COMPOSANTS.jpg
Fichier:Image hp.jpg
Fichier:Image carte avec hp.jpg
</gallery>


= Fichiers =
= Fichiers =
Ligne 78 : Ligne 87 :
=== Prog SE ===
=== Prog SE ===


=== LED ===
==== LED ====


==== Faire clignoter une led ====
===== Faire clignoter une led =====
<syntaxhighlight lang="cddl">
<syntaxhighlight lang="cddl">
#include <avr/io.h>
#include <avr/io.h>
Ligne 121 : Ligne 130 :


     DDRD |= (1 << LED);   
     DDRD |= (1 << LED);   
     PORTD &= ~(1 << LED);              // Configuration de la résistance de tirage
     PORTD &= ~(1 << LED);               


     DDRC &= ~(1 << BUTTON);                // Sortie pour la LED
     DDRC &= ~(1 << BUTTON);                 
     PORTC |= (1 << BUTTON);     
     PORTC |= (1 << BUTTON);     


Ligne 142 : Ligne 151 :


===== Faire parler le HP =====
===== Faire parler le HP =====
''Alimenter le HP et lui fournir une fréquence fixe mais mettre un délai entre 2 sons, pour débuter :''<syntaxhighlight lang="c">
#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#define TONE_FREQUENCY 1000  // 1kHz
#define TONE_DURATION_MS 1000 // 1 second
#define SAMPLE_RATE 8000
#define BUFFER_SIZE SAMPLE_RATE / (1000 / TONE_DURATION_MS)
#define LED    0
#define BUTTON  2
#define SPEAKER 7
int main(void){
    CLKSEL0 = 0b00010101;
    CLKSEL1 = 0b00001111;
    CLKPR = 0b10000000;
    CLKPR = 0;
    TCCR1A = (1 << COM1A0);
    TCCR1B = (1 << WGM12) | (1 << CS10);
    OCR1A = F_CPU / (2 * SAMPLE_RATE) - 1;
    DDRD |= (1 << LED);             
    PORTD &= ~(1 << LED);             
    DDRB |= (1 << SPEAKER);
    PORTB &= ~(1 << SPEAKER);
    while(1) {
        uint16_t i;
        for (i = 0; i < BUFFER_SIZE; i++) {
            PORTB ^= (1 << SPEAKER);
            _delay_us(1000000UL / (2 * TONE_FREQUENCY));
        }
        PORTB &= ~(1 << SPEAKER);
    }
    return 0;
}
</syntaxhighlight>''Fournir un son de test bufferAudio PROGMEM codé en 8bit fourni au HP :''
1) Conversion du fichier aac ou mp3 en fichier codé sous 8bit -> sortie du fichier wav via https://g711.org/
Low Definition 8-bit WAV (8Khz, Mono, 8-Bit PCM)
2) Passer du 8-bit WAV en hexadécimal -> utilisation de la commande linux xxd -i nomDuFichierAudio
A partir de maintenant, nous avons le contenu du fichier audio sous forme hexadécimal et pouvons le stocker et l'utiliser en c
EXEMPLE :<syntaxhighlight lang="c">
const uint8_t audioBuffer[] PROGMEM = {
    0xFF, 0x00, 0x80, 0x7F, 0x00, 0xFF, 0x7F, 0x80, 0x00, 0xFF, 0x80, 0x7F
};
</syntaxhighlight>Premièrement, nous avions décider de prendre un certain son de cloche.
Mais le son étant trop "bas" et de mauvaise qualité. Personne était capable de reconnaître notre son.
Nous sommes donc passé sur un son plus "stridant" et "aigu". Pour avoir un son plus facilement reconnaissable.
Le sample étant trouvé ici sous format wav comme décrit plus haut:
https://samplefocus.com/samples/8-bit-kit-beep
Après l'avoir converti en 8 bits low définition (gain de place) et utilisé xxd nous avons récupérer le contenu du fichier sous format hexadécimal.
Nous l'avons stocké dans un tableau, nous le parcourons allant de 0 à la taille du tableau, et, à chaque tour de boucle, nous donnons au port B (speaker) la valeur courant du bit du tableau. Avec un délai entre chaque pour obtenir le son voulu.<syntaxhighlight lang="c">
      for (uint16_t i = 0; i < sizeof(audioBuffer); i++) {
            uint8_t sample = pgm_read_byte(&audioBuffer[i]);
            PORTB = sample;
            _delay_us(60);
      }
</syntaxhighlight><syntaxhighlight lang="c">
#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#define TONE_FREQUENCY 1000  // 1kHz
#define TONE_DURATION_MS 1000 // 1 second
#define SAMPLE_RATE 8000
#define BUFFER_SIZE SAMPLE_RATE / (1000 / TONE_DURATION_MS)
#define LED    0
#define BUTTON  2
#define SPEAKER 7
const uint8_t audioBuffer[] PROGMEM = {
  0x52, 0x49, 0x46, 0x46, 0x0a, 0x04, 0x00, 0x00, 0x57, 0x41, 0x56, 0x45,
  0x66, 0x6d, 0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,
  0x40, 0x1f, 0x00, 0x00, 0x40, 0x1f, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00,
  0x64, 0x61, 0x74, 0x61, 0xe6, 0x03, 0x00, 0x00, 0x7c, 0x6b, 0x51, 0x3d,
  0x25, 0x16, 0x0d, 0x07, 0x0a, 0x00, 0xc1, 0xff, 0xf1, 0xff, 0xf5, 0xfe,
  0xf7, 0xfd, 0xf9, 0xfc, 0xf9, 0xfb, 0xfa, 0xfa, 0xfb, 0xfa, 0xfb, 0xfa,
  0xfb, 0xfa, 0xfa, 0xfb, 0xf9, 0xfb, 0x33, 0x00, 0x0e, 0x00, 0x0b, 0x00,
  0x0b, 0x03, 0xd6, 0xff, 0xf6, 0xfe, 0xf7, 0xfd, 0xf7, 0xfa, 0x27, 0x00,
  0x0a, 0x03, 0x08, 0x03, 0x07, 0x08, 0xdb, 0xff, 0xf6, 0xfe, 0xf8, 0xfd,
  0xf8, 0xf7, 0x22, 0x00, 0x09, 0x03, 0x08, 0x04, 0x07, 0x0b, 0xe0, 0xff,
  0xf7, 0xfc, 0xf9, 0xfb, 0xfa, 0xf2, 0x1d, 0x00, 0x08, 0x04, 0x07, 0x05,
  0x05, 0x11, 0xe6, 0xfe, 0xf9, 0xfb, 0xfa, 0xfa, 0xfd, 0xec, 0x17, 0x03,
  0x07, 0x05, 0x05, 0x07, 0x02, 0x18, 0xed, 0xfc, 0xfa, 0xfa, 0xfb, 0xf9,
  0xff, 0xe5, 0x10, 0x05, 0x05, 0x07, 0x04, 0x09, 0x00, 0x1f, 0xf3, 0xfa,
  0xfc, 0xf9, 0xfd, 0xf7, 0xff, 0xdf, 0x0b, 0x07, 0x04, 0x07, 0x04, 0x09,
  0x00, 0x22, 0xf8, 0xf7, 0xfe, 0xf7, 0xff, 0xf5, 0xff, 0xd9, 0x09, 0x07,
  0x05, 0x06, 0x05, 0x06, 0x05, 0x07, 0x04, 0x07, 0x04, 0x08, 0x02, 0x0b,
  0x00, 0x2d, 0xfd, 0xf6, 0xfe, 0xf7, 0xfe, 0xf5, 0xff, 0xcf, 0x00, 0x0c,
  0x00, 0x0b, 0x00, 0x0d, 0x00, 0x36, 0xff, 0xf5, 0xff, 0xf5, 0xff, 0xf3,
  0xff, 0xc6, 0x00, 0x0d, 0x00, 0x0b, 0x00, 0x0e, 0x00, 0x3e, 0xff, 0xf2,
  0xff, 0xf4, 0xff, 0xf1, 0xff, 0xbe, 0x00, 0x0e, 0x00, 0x0c, 0x00, 0x0f,
  0x00, 0x45, 0xff, 0xf1, 0xff, 0xf4, 0xff, 0xf1, 0xff, 0xb9, 0x00, 0x0f,
  0x00, 0x0d, 0x00, 0x10, 0x00, 0x4b, 0xff, 0xf1, 0xff, 0xf3, 0xff, 0xf0,
  0xff, 0xb0, 0x00, 0x10, 0x00, 0x0d, 0x00, 0x10, 0x00, 0x55, 0xff, 0xf0,
  0xff, 0xf2, 0xff, 0xef, 0xff, 0xa6, 0x00, 0x11, 0x00, 0x0e, 0x00, 0x11,
  0x00, 0x5e, 0xff, 0xef, 0xff, 0xf2, 0xff, 0xee, 0xff, 0x9d, 0x00, 0x12,
  0x00, 0x0f, 0x00, 0x12, 0x00, 0x68, 0xff, 0xee, 0xff, 0xf1, 0xff, 0xee,
  0xff, 0x95, 0x00, 0x12, 0x00, 0x0f, 0x00, 0x13, 0x00, 0x6e, 0xff, 0xee,
  0xff, 0xf1, 0xff, 0xee, 0xff, 0x8f, 0x00, 0x13, 0x00, 0x0f, 0x00, 0x13,
  0x00, 0x76, 0xff, 0xed, 0xff, 0xf0, 0xff, 0xec, 0xff, 0x83, 0x00, 0x10,
  0x00, 0x0a, 0x02, 0x08, 0x03, 0x08, 0x04, 0x08, 0x03, 0x08, 0x02, 0x0b,
  0x00, 0x44, 0x8b, 0x7a, 0x84, 0x7d, 0x82, 0x7e, 0x82, 0x7f, 0x81, 0x7f,
  0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80
};
int main(void){
    CLKSEL0 = 0b00010101;
    CLKSEL1 = 0b00001111;
    CLKPR = 0b10000000;
    CLKPR = 0;
    TCCR1A = (1 << COM1A0);
    TCCR1B = (1 << WGM12) | (1 << CS10);
    OCR1A = F_CPU / (2 * SAMPLE_RATE) - 1;
    DDRD |= (1 << LED);             
    PORTD &= ~(1 << LED);             
    DDRB |= (1 << SPEAKER);
    PORTB &= ~(1 << SPEAKER);
    while(1) {
 
      for (uint16_t i = 0; i < sizeof(audioBuffer); i++) {
            uint8_t sample = pgm_read_byte(&audioBuffer[i]);
            PORTB = sample;
            _delay_us(60);
      }
     
      _delay_ms(1000);
    }
    return 0;
}
</syntaxhighlight>


=== Prog USB ===
=== Prog USB ===
Le programme qui va sur le microcontrôleur
Le programme qui va sur le microcontrôleur


=== Prog PC ===
==== FAIRE PARLER LE HP EN MEME TEMPS QUE LA LED ====
Le programme qui tourne sur le pc
Nous allons juste reprendres les 2 parties des codes écrits auparavant.
 
Code 1 : le speaker qui parle (cf juste au dessus)
 
Code 2 : la led qui clignote <syntaxhighlight lang="c">
PORTD |= (1 << LED);
_delay_ms(5);
PORTD &= ~(1 << LED);
_delay_ms(5);
</syntaxhighlight>Ce qui nous donne :<syntaxhighlight lang="c">
#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
 
 
#define TONE_FREQUENCY 1000  // 1kHz
#define TONE_DURATION_MS 1000 // 1 second
#define SAMPLE_RATE 8000
#define BUFFER_SIZE SAMPLE_RATE / (1000 / TONE_DURATION_MS)
 
#define LED    0
#define BUTTON  2
#define SPEAKER 7
 
const uint8_t audioBuffer[] PROGMEM = {
  0x52, 0x49, 0x46, 0x46, 0x0a, 0x04, 0x00, 0x00, 0x57, 0x41, 0x56, 0x45,
  ... LE RESTE DE L'HEXA
};
 
 
 
int main(void){
 
    CLKSEL0 = 0b00010101;
    CLKSEL1 = 0b00001111;
    CLKPR = 0b10000000;
    CLKPR = 0;
 
    TCCR1A = (1 << COM1A0);
    TCCR1B = (1 << WGM12) | (1 << CS10);
    OCR1A = F_CPU / (2 * SAMPLE_RATE) - 1;
 
    DDRD |= (1 << LED);             
    PORTD &= ~(1 << LED);             
 
    DDRB |= (1 << SPEAKER);
    PORTB &= ~(1 << SPEAKER);
 
    while(1) {
 
     
      PORTD &= ~(1 << LED);
 
      for (uint16_t i = 0; i < sizeof(audioBuffer); i++) {
 
            uint8_t sample = pgm_read_byte(&audioBuffer[i]);
 
            PORTB = sample;
 
            _delay_us(55);
 
      }
      PORTD |= (1 << LED);
     
      _delay_ms(1000);
 
    }
 
    return 0;
}
 
</syntaxhighlight>Nous avons bien insérer l'allumage de la LED au moment où le speaker parle.
 
==== FAIRE PARLER LE HP ET LA LED EN MEME TEMPS QU'UN APPUI CLAVIER ====
Nous avons précédemment, mis en place différentes fonctionnalités :
 
* Faire clignoter la LED
* Faire clignoter une led en fonction du bouton
* Faire "parler" le HP
* Faire fonctionner le HP en même temps que la LED
 
Le dernier point du projet, objectif du projet, et donc de faire "parler" le HP et la LED en même temps qu'un appui clavier.
 
Pour gérer l'interaction avec le clavier, nous allons utiliser la bibliothèque LUFA.
 
LUFA (Lightweight USB Framework for AVRs) est une bibliothèque logicielle open source conçue pour faciliter le développement d'applications USB pour les microcontrôleurs AVR.
 
En utilisant LUFA, on peux facilement interagir avec des périphériques USB, comme la touche MAJ (Caps Lock). La bibliothèque fournit des fonctions et des structures prêtes à l'emploi pour lire l'état de la touche MAJ et contrôler les LED associées.
 
Nous allons donc implémenter les fonctionnalités développées auparavant au sein de la bibliothèque, plus précisément au moment ou une fonction nous permet de lire l'état des LEDS associés (la led MAJ en l'occurrence).
 
Pour cela, LUFA dispo d'un fichier Keyboard.c, qui permet de lire les états claviers et notamment l'état des LEDS du clavier.
 
Nous allons donc allumé la LED et le HP quand la LED de la touche MAJ est allumée (car la LED s'allume lors de l'appuie MAJ).
 
(if (LEDReport & HID_KEYBOARD_LED_NUMLOCK)<syntaxhighlight lang="c">
void ProcessLEDReport(const uint8_t LEDReport)
{
    uint8_t LEDMask = LEDS_LED2;
 
    if (LEDReport & HID_KEYBOARD_LED_NUMLOCK) {
        PORTD &= ~(1 << LED);
        for (uint16_t i = 0; i < sizeof(audioBuffer); i++) {
 
            uint8_t sample = pgm_read_byte(&audioBuffer[i]);
 
            PORTB = sample;
 
            _delay_us(55);
 
      }
      PORTD |= (1 << LED);
    }
 
    if (LEDReport & HID_KEYBOARD_LED_CAPSLOCK);
 
    if (LEDReport & HID_KEYBOARD_LED_SCROLLLOCK);
}
</syntaxhighlight>
 
=== CONCLUSION ===
Dans ce projet, nous avons proposé d'équiper une carte d'un port USB, d'une horloge, d'une LED, d'un bouton et d'un haut-parleur. L'objectif final était de produire un son et d'allumer la LED lorsqu'un bouton ou la touche CapsLock étaient enfoncés.
 
Cependant, une contre-proposition a été faite pour refléter l'état des touches "verrou" du clavier du PC en associant un signal lumineux avec des LED multicolores et un signal sonore. Pour cela, il a été suggéré de stocker des échantillons sonores en mémoire flash et de les reproduire sur le haut-parleur.
 
Le projet implique l'utilisation d'une carte programmable, en l'occurrence la carte "atmega16u2". Des dépendances et des outils de programmation tels que "avr-gcc", "avr-libc", et "dfu-programmer" sont nécessaires pour la compilation, l'édition des liens et la programmation de la carte.
 
Trois programmes ont été programmés comme preuve de concept et "prise en main" : un programme pour faire clignoter une LED, un programme pour faire clignoter une LED en fonction d'un bouton, et un programme pour produire un son sur le haut-parleur. Le dernier programme utilise un buffer audio stocké en mémoire flash pour reproduire un son.
 
Finalement, la conclusion du projet est que le premier choix de son de cloche n'était pas reconnaissable et de mauvaise qualité. Une nouvelle sélection de son plus "strident" et "aigu" a été effectuée pour améliorer la reconnaissance. Le contenu du fichier audio a été converti en hexadécimal et stocké dans un tableau. Le programme parcourt ensuite ce tableau pour produire le son désiré sur le haut-parleur.
 
Ce projet nous as permis d'acquérir des compétences en électronique, en programmation et en manipulation de signaux audio. Il offre une introduction pratique à la programmation bas niveau et à l'utilisation de composants électroniques pour créer des fonctionnalités interactives.
 
Parmi les points positifs de ce projet, on peut noter la possibilité de développer des compétences en électronique, en programmation et en manipulation de signaux audio. Il offre une introduction pratique à la programmation bas niveau et à l'utilisation de composants électroniques pour créer des fonctionnalités interactives. De plus, la proposition de refléter l'état des touches "verrou" du clavier du PC en associant un signal lumineux avec des LED multicolores et un signal sonore représente une alternative intéressante.
 
Cependant, il est important de souligner quelques points négatifs. Tout d'abord, le premier choix de son de cloche s'est révélé être de mauvaise qualité et peu reconnaissable. Cela a nécessité une nouvelle sélection de son plus "strident" et "aigu" pour améliorer la reconnaissance. De plus, le projet implique l'utilisation de dépendances et d'outils de programmation spécifiques tels que "avr-gcc", "avr-libc" et "dfu-programmer", ce qui peut représenter une barrière pour les débutants ou ceux qui ne sont pas familiers avec ces outils.
 
En conclusion, ce projet offre une opportunité d'apprentissage précieuse, en permettant aux étudiants d'acquérir des compétences pratiques dans différents domaines. Malgré quelques points négatifs liés à la qualité du son et à la nécessité d'utiliser des outils spécifiques, les aspects positifs tels que l'introduction à la programmation bas niveau et l'interaction avec des composants électroniques en font une expérience enrichissante.
 
[[Fichier:VID20230615110227.mp4|vignette|gauche]]

Version actuelle datée du 4 juillet 2023 à 11:57

Proposition de système

Nous voudrions équiper la carte d'un port USB, d'une horloge, d'une LED, d'un bouton et d'un haut-parleur. Le but final serait de, lors d'un appui bouton et/ou CapsLock (à définir ensemble), de faire un son et un allumage de la LED.

Contre-proposition

L'idée est bien de refléter l'ensemble de l'état des touches "verrous" du clavier du PC. A chaque changement d'état de ces touches vous associerez un signal lumineux avec les 3 LED multicolores et surtout un signal sonore. Vous êtes tenus de produire des sons et pas seulement des notes. Pour cela vous devrez réussir à stocker (en mémoire flash) des échantillons sonores et à les reproduire sur votre haut-parleur.

Carte

Photo de la carte et ses composants :

Fichiers

Vous utiliserez le même circuit imprimé que le groupe 5.

Installation

Installation des dépendances :

apt install gcc-avr avr-libc dfu-programmer

Passer du fichier source au fichier exécutable :

Compil : avr-gcc -mmcu=atmega16u2 -DF_CPU=16000000UL -c -Wall -I. -Os main.c -o main.o

Edition des liens (exe) : avr-gcc -mmcu=atmega16u2 -g -lm -Wl,--gc-sections -o main.elf main.o

Transformer le code source en fichiers utilisable pour la carte

avr-objcopy -j .text -j .data -O ihex main.elf main.hex

dfu-programmer atmega16u2 erase

dfu-programmer atmega16u2 flash time.hex

dfu-programmer atmega16u2 reset

Programmation

MAKEFILE

AVR = avr-gcc
AVR_HEX = avr-objcopy

TARGET = atmega16u2
DFU = dfu-programmer

CFLAGS = -mmcu=atmega16u2 -DF_CPU=16000000UL -Wall -I. -Os
CLINKS = -mmcu=atmega16u2 -g -lm -Wl,--gc-sections
CHEXS = -j .text -j .data -O
 
SRC = main.c

OBJ = main.o

ELF = main.elf

HEX = main.hex

push: clean compile link hex erase flash reset

compile: 
    $(AVR) $(CFLAGS) -c $(SRC) -o $(OBJ)

link: 
    $(AVR) $(CLINKS) -o $(ELF) $(OBJ)

hex:
    $(AVR_HEX) $(CHEXS) ihex $(ELF) $(HEX)

erase:
    $(DFU) $(TARGET) erase 

flash:
    $(DFU) $(TARGET) flash $(HEX)

reset:
    $(DFU) $(TARGET) reset

clean:
    rm -f $(OBJ) $(EXEC)

Prog SE

LED

Faire clignoter une led
#include <avr/io.h>
#include <util/delay.h>

#define LED     0
#define BUTTON  2

int main(void){

    DDRD |= (1 << LED);                // Sortie pour la LED
    PORTD &= ~(1 << LED);              // Configuration de la résistance de tirage

    while(1) {
        PORTD |= (1 << LED);
        _delay_ms(5);
        PORTD &= ~(1 << LED); 
        _delay_ms(5);     
    }
}

Boutons

Faire clignoter une led en fonction du bouton
#include <avr/io.h>
#include <util/delay.h>

#define LED     0
#define BUTTON  2

int main(void){

    CLKSEL0 = 0b00010101;
    CLKSEL1 = 0b00001111;
    CLKPR = 0b10000000;
    CLKPR = 0;

    DDRD |= (1 << LED);  
    PORTD &= ~(1 << LED);              

    DDRC &= ~(1 << BUTTON);                
    PORTC |= (1 << BUTTON);    

    while(1) {
        if (!(PINC & (1 << BUTTON)))
        {
            PORTD |= (1 << LED);
            _delay_ms(5);
            PORTD &= ~(1 << LED); 
            _delay_ms(5);     
        }
    }
}

HP

Faire parler le HP

Alimenter le HP et lui fournir une fréquence fixe mais mettre un délai entre 2 sons, pour débuter :

#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h>


#define TONE_FREQUENCY 1000  // 1kHz
#define TONE_DURATION_MS 1000 // 1 second
#define SAMPLE_RATE 8000
#define BUFFER_SIZE SAMPLE_RATE / (1000 / TONE_DURATION_MS)

#define LED     0
#define BUTTON  2
#define SPEAKER 7


int main(void){

    CLKSEL0 = 0b00010101;
    CLKSEL1 = 0b00001111;
    CLKPR = 0b10000000;
    CLKPR = 0;

    TCCR1A = (1 << COM1A0); 
    TCCR1B = (1 << WGM12) | (1 << CS10); 
    OCR1A = F_CPU / (2 * SAMPLE_RATE) - 1;

    DDRD |= (1 << LED);               
    PORTD &= ~(1 << LED);              

    DDRB |= (1 << SPEAKER);
    PORTB &= ~(1 << SPEAKER);

    while(1) {
        uint16_t i;
        for (i = 0; i < BUFFER_SIZE; i++) {
            PORTB ^= (1 << SPEAKER); 
            _delay_us(1000000UL / (2 * TONE_FREQUENCY));
        }

        PORTB &= ~(1 << SPEAKER);
    }

    return 0;
}

Fournir un son de test bufferAudio PROGMEM codé en 8bit fourni au HP :


1) Conversion du fichier aac ou mp3 en fichier codé sous 8bit -> sortie du fichier wav via https://g711.org/

Low Definition 8-bit WAV (8Khz, Mono, 8-Bit PCM)


2) Passer du 8-bit WAV en hexadécimal -> utilisation de la commande linux xxd -i nomDuFichierAudio

A partir de maintenant, nous avons le contenu du fichier audio sous forme hexadécimal et pouvons le stocker et l'utiliser en c


EXEMPLE :

 const uint8_t audioBuffer[] PROGMEM = {
    0xFF, 0x00, 0x80, 0x7F, 0x00, 0xFF, 0x7F, 0x80, 0x00, 0xFF, 0x80, 0x7F
};

Premièrement, nous avions décider de prendre un certain son de cloche.

Mais le son étant trop "bas" et de mauvaise qualité. Personne était capable de reconnaître notre son.

Nous sommes donc passé sur un son plus "stridant" et "aigu". Pour avoir un son plus facilement reconnaissable.

Le sample étant trouvé ici sous format wav comme décrit plus haut:

https://samplefocus.com/samples/8-bit-kit-beep


Après l'avoir converti en 8 bits low définition (gain de place) et utilisé xxd nous avons récupérer le contenu du fichier sous format hexadécimal.

Nous l'avons stocké dans un tableau, nous le parcourons allant de 0 à la taille du tableau, et, à chaque tour de boucle, nous donnons au port B (speaker) la valeur courant du bit du tableau. Avec un délai entre chaque pour obtenir le son voulu.

      for (uint16_t i = 0; i < sizeof(audioBuffer); i++) {

            uint8_t sample = pgm_read_byte(&audioBuffer[i]);

            PORTB = sample;

            _delay_us(60);

      }
#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h>


#define TONE_FREQUENCY 1000  // 1kHz
#define TONE_DURATION_MS 1000 // 1 second
#define SAMPLE_RATE 8000
#define BUFFER_SIZE SAMPLE_RATE / (1000 / TONE_DURATION_MS)

#define LED     0
#define BUTTON  2
#define SPEAKER 7

const uint8_t audioBuffer[] PROGMEM = {
  0x52, 0x49, 0x46, 0x46, 0x0a, 0x04, 0x00, 0x00, 0x57, 0x41, 0x56, 0x45,
  0x66, 0x6d, 0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,
  0x40, 0x1f, 0x00, 0x00, 0x40, 0x1f, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00,
  0x64, 0x61, 0x74, 0x61, 0xe6, 0x03, 0x00, 0x00, 0x7c, 0x6b, 0x51, 0x3d,
  0x25, 0x16, 0x0d, 0x07, 0x0a, 0x00, 0xc1, 0xff, 0xf1, 0xff, 0xf5, 0xfe,
  0xf7, 0xfd, 0xf9, 0xfc, 0xf9, 0xfb, 0xfa, 0xfa, 0xfb, 0xfa, 0xfb, 0xfa,
  0xfb, 0xfa, 0xfa, 0xfb, 0xf9, 0xfb, 0x33, 0x00, 0x0e, 0x00, 0x0b, 0x00,
  0x0b, 0x03, 0xd6, 0xff, 0xf6, 0xfe, 0xf7, 0xfd, 0xf7, 0xfa, 0x27, 0x00,
  0x0a, 0x03, 0x08, 0x03, 0x07, 0x08, 0xdb, 0xff, 0xf6, 0xfe, 0xf8, 0xfd,
  0xf8, 0xf7, 0x22, 0x00, 0x09, 0x03, 0x08, 0x04, 0x07, 0x0b, 0xe0, 0xff,
  0xf7, 0xfc, 0xf9, 0xfb, 0xfa, 0xf2, 0x1d, 0x00, 0x08, 0x04, 0x07, 0x05,
  0x05, 0x11, 0xe6, 0xfe, 0xf9, 0xfb, 0xfa, 0xfa, 0xfd, 0xec, 0x17, 0x03,
  0x07, 0x05, 0x05, 0x07, 0x02, 0x18, 0xed, 0xfc, 0xfa, 0xfa, 0xfb, 0xf9,
  0xff, 0xe5, 0x10, 0x05, 0x05, 0x07, 0x04, 0x09, 0x00, 0x1f, 0xf3, 0xfa,
  0xfc, 0xf9, 0xfd, 0xf7, 0xff, 0xdf, 0x0b, 0x07, 0x04, 0x07, 0x04, 0x09,
  0x00, 0x22, 0xf8, 0xf7, 0xfe, 0xf7, 0xff, 0xf5, 0xff, 0xd9, 0x09, 0x07,
  0x05, 0x06, 0x05, 0x06, 0x05, 0x07, 0x04, 0x07, 0x04, 0x08, 0x02, 0x0b,
  0x00, 0x2d, 0xfd, 0xf6, 0xfe, 0xf7, 0xfe, 0xf5, 0xff, 0xcf, 0x00, 0x0c,
  0x00, 0x0b, 0x00, 0x0d, 0x00, 0x36, 0xff, 0xf5, 0xff, 0xf5, 0xff, 0xf3,
  0xff, 0xc6, 0x00, 0x0d, 0x00, 0x0b, 0x00, 0x0e, 0x00, 0x3e, 0xff, 0xf2,
  0xff, 0xf4, 0xff, 0xf1, 0xff, 0xbe, 0x00, 0x0e, 0x00, 0x0c, 0x00, 0x0f,
  0x00, 0x45, 0xff, 0xf1, 0xff, 0xf4, 0xff, 0xf1, 0xff, 0xb9, 0x00, 0x0f,
  0x00, 0x0d, 0x00, 0x10, 0x00, 0x4b, 0xff, 0xf1, 0xff, 0xf3, 0xff, 0xf0,
  0xff, 0xb0, 0x00, 0x10, 0x00, 0x0d, 0x00, 0x10, 0x00, 0x55, 0xff, 0xf0,
  0xff, 0xf2, 0xff, 0xef, 0xff, 0xa6, 0x00, 0x11, 0x00, 0x0e, 0x00, 0x11,
  0x00, 0x5e, 0xff, 0xef, 0xff, 0xf2, 0xff, 0xee, 0xff, 0x9d, 0x00, 0x12,
  0x00, 0x0f, 0x00, 0x12, 0x00, 0x68, 0xff, 0xee, 0xff, 0xf1, 0xff, 0xee,
  0xff, 0x95, 0x00, 0x12, 0x00, 0x0f, 0x00, 0x13, 0x00, 0x6e, 0xff, 0xee,
  0xff, 0xf1, 0xff, 0xee, 0xff, 0x8f, 0x00, 0x13, 0x00, 0x0f, 0x00, 0x13,
  0x00, 0x76, 0xff, 0xed, 0xff, 0xf0, 0xff, 0xec, 0xff, 0x83, 0x00, 0x10,
  0x00, 0x0a, 0x02, 0x08, 0x03, 0x08, 0x04, 0x08, 0x03, 0x08, 0x02, 0x0b,
  0x00, 0x44, 0x8b, 0x7a, 0x84, 0x7d, 0x82, 0x7e, 0x82, 0x7f, 0x81, 0x7f,
  0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80
};



int main(void){

    CLKSEL0 = 0b00010101;
    CLKSEL1 = 0b00001111;
    CLKPR = 0b10000000;
    CLKPR = 0;

    TCCR1A = (1 << COM1A0); 
    TCCR1B = (1 << WGM12) | (1 << CS10); 
    OCR1A = F_CPU / (2 * SAMPLE_RATE) - 1;

    DDRD |= (1 << LED);               
    PORTD &= ~(1 << LED);              

    DDRB |= (1 << SPEAKER);
    PORTB &= ~(1 << SPEAKER);

    while(1) {
  
      for (uint16_t i = 0; i < sizeof(audioBuffer); i++) {

            uint8_t sample = pgm_read_byte(&audioBuffer[i]);

            PORTB = sample;

            _delay_us(60);

      }
      
      _delay_ms(1000);

    }

    return 0;
}

Prog USB

Le programme qui va sur le microcontrôleur

FAIRE PARLER LE HP EN MEME TEMPS QUE LA LED

Nous allons juste reprendres les 2 parties des codes écrits auparavant.

Code 1 : le speaker qui parle (cf juste au dessus)

Code 2 : la led qui clignote

PORTD |= (1 << LED);
_delay_ms(5);
PORTD &= ~(1 << LED); 
_delay_ms(5);

Ce qui nous donne :

#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h>


#define TONE_FREQUENCY 1000  // 1kHz
#define TONE_DURATION_MS 1000 // 1 second
#define SAMPLE_RATE 8000
#define BUFFER_SIZE SAMPLE_RATE / (1000 / TONE_DURATION_MS)

#define LED     0
#define BUTTON  2
#define SPEAKER 7

const uint8_t audioBuffer[] PROGMEM = {
  0x52, 0x49, 0x46, 0x46, 0x0a, 0x04, 0x00, 0x00, 0x57, 0x41, 0x56, 0x45,
  ... LE RESTE DE L'HEXA
};



int main(void){

    CLKSEL0 = 0b00010101;
    CLKSEL1 = 0b00001111;
    CLKPR = 0b10000000;
    CLKPR = 0;

    TCCR1A = (1 << COM1A0); 
    TCCR1B = (1 << WGM12) | (1 << CS10); 
    OCR1A = F_CPU / (2 * SAMPLE_RATE) - 1;

    DDRD |= (1 << LED);               
    PORTD &= ~(1 << LED);              

    DDRB |= (1 << SPEAKER);
    PORTB &= ~(1 << SPEAKER);

    while(1) {

      
      PORTD &= ~(1 << LED); 
  
      for (uint16_t i = 0; i < sizeof(audioBuffer); i++) {

            uint8_t sample = pgm_read_byte(&audioBuffer[i]);

            PORTB = sample;

            _delay_us(55);

      }
      PORTD |= (1 << LED);
      
      _delay_ms(1000);

    }

    return 0;
}

Nous avons bien insérer l'allumage de la LED au moment où le speaker parle.

FAIRE PARLER LE HP ET LA LED EN MEME TEMPS QU'UN APPUI CLAVIER

Nous avons précédemment, mis en place différentes fonctionnalités :

  • Faire clignoter la LED
  • Faire clignoter une led en fonction du bouton
  • Faire "parler" le HP
  • Faire fonctionner le HP en même temps que la LED

Le dernier point du projet, objectif du projet, et donc de faire "parler" le HP et la LED en même temps qu'un appui clavier.

Pour gérer l'interaction avec le clavier, nous allons utiliser la bibliothèque LUFA.

LUFA (Lightweight USB Framework for AVRs) est une bibliothèque logicielle open source conçue pour faciliter le développement d'applications USB pour les microcontrôleurs AVR.

En utilisant LUFA, on peux facilement interagir avec des périphériques USB, comme la touche MAJ (Caps Lock). La bibliothèque fournit des fonctions et des structures prêtes à l'emploi pour lire l'état de la touche MAJ et contrôler les LED associées.

Nous allons donc implémenter les fonctionnalités développées auparavant au sein de la bibliothèque, plus précisément au moment ou une fonction nous permet de lire l'état des LEDS associés (la led MAJ en l'occurrence).

Pour cela, LUFA dispo d'un fichier Keyboard.c, qui permet de lire les états claviers et notamment l'état des LEDS du clavier.

Nous allons donc allumé la LED et le HP quand la LED de la touche MAJ est allumée (car la LED s'allume lors de l'appuie MAJ).

(if (LEDReport & HID_KEYBOARD_LED_NUMLOCK)

void ProcessLEDReport(const uint8_t LEDReport)
{
    uint8_t LEDMask = LEDS_LED2;

    if (LEDReport & HID_KEYBOARD_LED_NUMLOCK) {
        PORTD &= ~(1 << LED); 
        for (uint16_t i = 0; i < sizeof(audioBuffer); i++) {

            uint8_t sample = pgm_read_byte(&audioBuffer[i]);

            PORTB = sample;

            _delay_us(55);

      }
      PORTD |= (1 << LED);
    }

    if (LEDReport & HID_KEYBOARD_LED_CAPSLOCK);

    if (LEDReport & HID_KEYBOARD_LED_SCROLLLOCK);
}

CONCLUSION

Dans ce projet, nous avons proposé d'équiper une carte d'un port USB, d'une horloge, d'une LED, d'un bouton et d'un haut-parleur. L'objectif final était de produire un son et d'allumer la LED lorsqu'un bouton ou la touche CapsLock étaient enfoncés.

Cependant, une contre-proposition a été faite pour refléter l'état des touches "verrou" du clavier du PC en associant un signal lumineux avec des LED multicolores et un signal sonore. Pour cela, il a été suggéré de stocker des échantillons sonores en mémoire flash et de les reproduire sur le haut-parleur.

Le projet implique l'utilisation d'une carte programmable, en l'occurrence la carte "atmega16u2". Des dépendances et des outils de programmation tels que "avr-gcc", "avr-libc", et "dfu-programmer" sont nécessaires pour la compilation, l'édition des liens et la programmation de la carte.

Trois programmes ont été programmés comme preuve de concept et "prise en main" : un programme pour faire clignoter une LED, un programme pour faire clignoter une LED en fonction d'un bouton, et un programme pour produire un son sur le haut-parleur. Le dernier programme utilise un buffer audio stocké en mémoire flash pour reproduire un son.

Finalement, la conclusion du projet est que le premier choix de son de cloche n'était pas reconnaissable et de mauvaise qualité. Une nouvelle sélection de son plus "strident" et "aigu" a été effectuée pour améliorer la reconnaissance. Le contenu du fichier audio a été converti en hexadécimal et stocké dans un tableau. Le programme parcourt ensuite ce tableau pour produire le son désiré sur le haut-parleur.

Ce projet nous as permis d'acquérir des compétences en électronique, en programmation et en manipulation de signaux audio. Il offre une introduction pratique à la programmation bas niveau et à l'utilisation de composants électroniques pour créer des fonctionnalités interactives.

Parmi les points positifs de ce projet, on peut noter la possibilité de développer des compétences en électronique, en programmation et en manipulation de signaux audio. Il offre une introduction pratique à la programmation bas niveau et à l'utilisation de composants électroniques pour créer des fonctionnalités interactives. De plus, la proposition de refléter l'état des touches "verrou" du clavier du PC en associant un signal lumineux avec des LED multicolores et un signal sonore représente une alternative intéressante.

Cependant, il est important de souligner quelques points négatifs. Tout d'abord, le premier choix de son de cloche s'est révélé être de mauvaise qualité et peu reconnaissable. Cela a nécessité une nouvelle sélection de son plus "strident" et "aigu" pour améliorer la reconnaissance. De plus, le projet implique l'utilisation de dépendances et d'outils de programmation spécifiques tels que "avr-gcc", "avr-libc" et "dfu-programmer", ce qui peut représenter une barrière pour les débutants ou ceux qui ne sont pas familiers avec ces outils.

En conclusion, ce projet offre une opportunité d'apprentissage précieuse, en permettant aux étudiants d'acquérir des compétences pratiques dans différents domaines. Malgré quelques points négatifs liés à la qualité du son et à la nécessité d'utiliser des outils spécifiques, les aspects positifs tels que l'introduction à la programmation bas niveau et l'interaction avec des composants électroniques en font une expérience enrichissante.