« SE3Groupe2025-3 » : différence entre les versions
| Ligne 213 : | Ligne 213 : | ||
Mon archive GIT pour le projet KiCAD et pour les programmes : [https://gitea.plil.fr/stazani/2025_PSE_B3_stazani_lkachour.git]. | Mon archive GIT pour le projet KiCAD et pour les programmes : [https://gitea.plil.fr/stazani/2025_PSE_B3_stazani_lkachour.git]. | ||
== Historique des | == Historique des séances == | ||
Version actuelle datée du 18 juin 2026 à 06:43
Programmation des systèmes embarqués
L'objectif est de concevoir et programmer une carte qui mesure le niveau sonore ambiant pour l'afficher visuellement.
Pour cela, on utilise 7 LED qui font office d'indicateur de niveau. Le principe est simple : le nombre de LED allumées dépend directement du volume capté.
Chaque LED est associée à un seuil sonore. Plus le bruit augmente, plus on franchit de paliers, et donc plus on allume de LED.
On passe ainsi d'une seule LED allumée pour un bruit léger, jusqu'aux 7 LED allumées en même temps lors d'un pic sonore.
Les LEDs s'ont d'ailleurs vertes oranges et rouges et s'allument du vert au rouge de manière croissante avec les seuils sonores.
Carte électronique
Projet KiCAD rechargé avec un nom correct : Fichier:2025-PSE-3-Prog.zip
Début de correction, projet trop embryonnaire pour mériter une correction, terminez le schéma : Fichier:2025-PSE-3-Prog-rex.zip
Version finale du projet avec le routage : Fichier:2025-PSE-3-Prog-Corrige.zip
Carte réalisée en utilisant le logiciel KiCAD : Fichier:2025-PSE-B3-PROG.zip.
Schéma électronique de la carte :
Résultat du routage :
Photo de la carte soudée :
La carte avait bien été détecté en lsusb lorsque M.Redon l'a fait mais lors de la prochaine scéance plus rien. Pour y remédier nous avons d'abord pensé à un faux contact et avons ressoudé les éléments mal soudés. Nous n'avons tout de même pas réussit à la detecter lors de la dernière scéance. Nous allons quand même écrire le code nécéssaire même si il n'est pas possible pour nous de le tester afin de savoir si il marche correctement.
Programmation
1) blink.c
#include <avr/io.h>
#include <util/delay.h>
#define BLINK_DELAY 250 // en ms
// (PD0 = LED7, PD1-PD6 = LED1-LED6)
int main()
{
// on def les led en sortie :
DDRD |= (1 << 0);
DDRD |= (1 << 1);
DDRD |= (1 << 2);
DDRD |= (1 << 3);
DDRD |= (1 << 4);
DDRD |= (1 << 5);
DDRD |= (1 << 6);
for (int i = 0; i < 50; i++)
{
// on allume les leds
PORTD |= (1 << 0);
PORTD |= (1 << 1);
PORTD |= (1 << 2);
PORTD |= (1 << 3);
PORTD |= (1 << 4);
PORTD |= (1 << 5);
PORTD |= (1 << 6);
_delay_ms(BLINK_DELAY);
// led off
PORTD &= ~(1 << 0); // AND + NOT
PORTD &= ~(1 << 1);
PORTD &= ~(1 << 2);
PORTD &= ~(1 << 3);
PORTD &= ~(1 << 4);
PORTD &= ~(1 << 5);
PORTD &= ~(1 << 6);
_delay_ms(BLINK_DELAY);
}
return 0;
}
1) led_if_noise.c
#define F_CPU 8000000UL // On utilise le quartz de 8MHz de la carte
#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>
// Sensibilité de notre micro
// Définie de manière un peu arbitraire pour l'instant (à affiner en testant la carte en vrai)
#define SEUIL_BRUIT 15
void ADC_Init(void) {
// On pose la référence de tension pour l'ADC (AVCC)
// pour lire ADC13 (qui correspond à PB6 sur notre schéma)
// il faut activer le bit MUX5 (qui est dans ADCSRB)
// et mettre MUX[4:0] à 5 (00101).
ADMUX = (1 << REFS0) | 5;
ADCSRB = (1 << MUX5);
// On active le convertisseur (ADEN).
// La puce tourne à 8 MHz, ce qui est beaucoup trop rapide pour lire un signal analogique correctement.
// On divise donc sa vitesse par 128 (les bits ADPS) pour laisser le temps à l'ADC de bien "écouter" le signal.
ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);
}
uint16_t ADC_Read(void) {
// conversion ADC
ADCSRA |= (1 << ADSC);
// en attendant fin de la conversion (le bit ADSC repasse à 0 quand c'est fini)
while (ADCSRA & (1 << ADSC));
// On retourne le résultat (valeur sur 10 bits, de 0 à 1023)
return ADC;
}
int main(void) {
// LED1 est branchée sur la broche PD1
// On configure donc PD1 en sortie
DDRD |= (1 << PD1);
// Initialisation du convertisseur
ADC_Init();
while (1) {
uint16_t valeur_micro = ADC_Read();
// Quand il n'y a aucun bruit (silence total), le circuit nous renvoie la valeur du milieu : 512.
// Quand il y a du bruit, la valeur oscille autour de ce milieu (elle peut monter à 600 ou descendre à 400 par exemple).
// Le volume réel, c'est simplement l'écart entre la valeur lue et ce "point zéro" de 512.
// La fonction abs() sert juste à toujours avoir un écart positif, même si la valeur descend.
int16_t amplitude = abs((int16_t)valeur_micro - 512);
// Si l'écart dépasse notre seuil (donc on parle normalement au lieu de chuchoter)
if (amplitude > SEUIL_BRUIT) {
PORTD |= (1 << PD1);
_delay_ms(50);
} else {
// Sinon (silence ou simple chuchotement), on éteint la LED1
PORTD &= ~(1 << PD1);
}
}
return 0;
}
1) Justification du code
a) ADMUX
Le tableau nous dit que pour utiliser l'alimentation de la carte (AVCC) comme référence pour nos mesures (ce qui est notre cas puisque notre point de repos est à VBUS/2), il faut mettre REFS1 à 0 et REFS0 à 1.
b) Prescaler
Dans la datasheet du microcontrôleur (Section 24.4), on s'est rendu compte que l'ADC a besoin d'une fréquence d'horloge comprise entre 50 et 200 kHz pour faire des mesures précises. Le souci, c'est que notre carte tourne avec un quartz à 8 MHz, ce qui est beaucoup trop rapide ! Donc on utilise le prescaler. En divisant notre horloge par 128, on a 62,5 kHz (8 MHz / 128), ce qui reste dans la plage recommandée par Atmel. Pour coder ça, on s'est appuyées sur le tableau 24-5 de la doc : il suffit de passer les trois bits ADPS2, ADPS1 et ADPS0 à 1 dans le registre ADCSRA. Et bien sûr, et d'activer l'ADC en mettant le bit ADEN à 1 dans ce même registre.
1) final.c
Ce code est censé marcher de manière à allumer les leds en fonction du niveau sonore, de manière croissante.
#define F_CPU 8000000UL // Quartz 8MHz
#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>
void ADC_Init(void) {
// Config de l'ADC vue avant (AVCC, canal 13, prescaler 128)
ADMUX = (1 << REFS0) | 5;
ADCSRB = (1 << MUX5);
ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);
}
uint16_t ADC_Read(void) {
ADCSRA |= (1 << ADSC);
while (ADCSRA & (1 << ADSC));
return ADC;
}
int main(void) {
// D'après le schéma, LED1 à LED6 sont sur PD1 à PD6.
// On met donc toutes ces broches du Port D en sortie
DDRD |= (1 << PD1) | (1 << PD2) | (1 << PD3) | (1 << PD4) | (1 << PD5) | (1 << PD6) | (1 << PD0);
ADC_Init();
while (1) {
uint16_t valeur_micro = ADC_Read();
int16_t amplitude = abs((int16_t)valeur_micro - 512);
// On éteint d'abord toutes les LEDs pour remettre l'affichage à zéro à chaque tour
PORTD &= ~((1 << PD1) | (1 << PD2) | (1 << PD3) | (1 << PD4) | (1 << PD5) | (1 << PD6) | (1 << PD0));
// On allume les LEDs en cascade selon la force du bruit
if (amplitude > 15) PORTD |= (1 << PD1); // Bruit léger -> LED1
if (amplitude > 30) PORTD |= (1 << PD2); // Voix normale -> LED2
if (amplitude > 50) PORTD |= (1 << PD3); // Voix un peu forte -> LED3
if (amplitude > 80) PORTD |= (1 << PD4); // ... -> LED4
if (amplitude > 120) PORTD |= (1 << PD5); // ... -> LED5
if (amplitude > 180) PORTD |= (1 << PD6); // Gros bruit/cri -> LED6
if (amplitude > 250) PORTD |= (1 << PD0); // Saturé (Max) -> LED7 (qui est sur PD0)
// Petit délai (10ms au lieu de 50ms) pour que les LEDs s'actualisent vite
// et que l'effet visuel soit fluide au rythme de la voix.
_delay_ms(10);
}
return 0;
}
Archive GIT
Mon archive GIT pour le projet KiCAD et pour les programmes : [1].
Historique des séances
On a commencé par chercher une idée de projet et voir ce qu’on pouvait faire comme système embarqué. On a aussi commencé à mettre en place le projet, avec l’organisation du Git et les premières idées pour la carte.
On a commencé à réfléchir au schéma électronique, surtout sur les composants principaux, les LED et les broches qu’on allait utiliser.
On a commencé la réalisation du schéma électronique sur KiCad.
On a placé les premiers composants et on a commencé à faire les connexions. Le but était surtout de poser les bases de la carte et de voir comment relier les différents éléments entre eux.
On a continué le schéma électronique.
On a avancé sur les connexions et on a vérifié que les broches utilisées étaient cohérentes avec ce qu’on voulait faire. On a aussi commencé à faire attention aux LED et à leur branchement, pour pouvoir les tester après.
On a corrigé le schéma électronique.
On a regardé les erreurs possibles dans KiCad, comme les connexions oubliées ou les signaux mal reliés. On a aussi corrigé certaines parties du schéma pour que la carte soit plus propre avant de passer à la suite.
On a fini la réalisation du schéma électronique.
On a fait les dernières corrections et vérifications pour avoir un schéma utilisable. À la fin de cette séance, la partie schéma était quasiment terminée et prête pour la partie matérielle.
Séance non renseignée.
On a repris le projet et on a préparé la partie matérielle.
On a vérifié la carte et les composants avant de commencer vraiment la soudure. Le but était de s’assurer qu’on pouvait assembler la carte correctement et qu’il ne manquait pas d’éléments importants.
On a commencé la soudure des composants sur la carte.
On n’a pas eu beaucoup accès aux fers à souder donc on n’a pas pu avancer autant que prévu, mais on a quand même commencé l’assemblage. Cette séance nous a permis de passer du schéma KiCad à la carte réelle.
On a continué la soudure sur la carte.
On a soudé d’autres composants et on a essayé de faire attention au sens des composants, surtout les LED. On a aussi regardé les soudures pour éviter les faux contacts ou les courts-circuits.
On a corrigé la soudure de la carte.
On s’est rendu compte qu’une LED avait été soudée à l’envers, donc elle ne pouvait pas fonctionner correctement. On l’a donc dessoudée puis ressoudée dans le bon sens. Ça nous a permis de mieux comprendre l’importance de la polarité des LED.
On a commencé les tests des LED et le début de la programmation.
Le but était de vérifier si les LED s’allumaient correctement après la soudure. On a surtout travaillé sur la LED reliée à la broche 26.
On a aussi commencé à faire un programme simple pour configurer la broche en sortie et faire clignoter la LED. Cette séance a permis de faire le lien entre la carte électronique et le programme en C.
On a terminé les dernières soudures de la carte et on a continué la programmation.
On a fait les tests finaux pour vérifier que les LED fonctionnaient bien. Le programme permettait d’allumer et d’éteindre la LED avec un délai, pour voir si la broche 26 était bien commandée.
Cette séance nous a permis de finaliser la partie matérielle et de valider les premiers tests du logiciel.
