SE3Groupe2025-8
Programmation des systèmes embarqués
Carte électronique
Vous trouverez ci-joint les documents du Programmation projet PCB qui nous à permis de nous familiarisé avec les logiciel de conception de carte électronique (CAO), ici KiCad.
Carte réalisée en utilisant le logiciel KiCAD : Fichier:2025 PSE-08-PCB.zip.
Schéma électronique de la carte :
Résultat du routage :
Vue 3D :
Photo de la carte soudée :
Programmation
Description
Ce dépôt regroupe l'ensemble des développements logiciels réalisés pour le programmateur USB basé sur le microcontrôleur ATmega16U2.
Il contient plusieurs programmes de test permettant de valider le fonctionnement de la carte électronique ainsi que le firmware principal du programmateur. Le projet utilise la bibliothèque LUFA afin de créer un périphérique USB HID assurant la communication entre le PC et le microcontrôleur.
Contenu du dépôt
- led.c : test du clignotement des LED.
- bouton_led.c : test des boutons et des LED.
- pc_libusb.c : programme PC utilisant libusb pour communiquer avec le périphérique USB.
- Firmware LUFA : implémentation du programmateur USB ISP.
Fonctionnalités
Le firmware permet :
- l'initialisation de l'interface USB ;
- l'initialisation du bus SPI ;
- la gestion de la ligne RESET de la cible ;
- la communication USB HID ;
- la lecture de la signature du microcontrôleur cible ;
- la lecture de la mémoire Flash ;
- l'écriture de la mémoire Flash.
Architecture générale
PC
↓
libusb
↓
USB
↓
ATmega16U2
↓
SPI
↓
Microcontrôleur cible
↓
Connecteur ISP
Tests réalisés
- Validation du fonctionnement des LED.
- Validation des boutons.
- Passage en mode DFU.
- Détection du bootloader DFU.
- Communication USB via LUFA.
- Communication PC ↔ périphérique avec libusb.
- Lecture de la signature AVR.
- Lecture de la mémoire Flash.
- Écriture de la mémoire Flash.
Bilan
Les différents développements réalisés ont permis de valider la majorité des fonctionnalités matérielles et logicielles du programmateur USB. Les communications USB et SPI ainsi que les principales commandes ISP ont été testées avec succès.
La validation complète du système n'a cependant pas pu être finalisée en raison d'un problème matériel lié au câble adaptateur utilisé pour la programmation de la cible.
Premier système embarqué
Archive GIT
Mon archive GIT pour le projet KiCAD et pour les programmes : https://gitea.plil.fr/saboucad/2025_PSE_08_saboucad_msini.git.
Ajouter un .gitignore pour KiCAD et langage C.
Structure avec matériel (y compris production - gerber, bill of materials) / logiciel / documentation (e.g. documentation technique).
Description du système embarqué
Nous avons choisi de réaliser un orienteur de panneau solaire autonome permettant d'optimiser la puissance électrique produite par un panneau photovoltaïque.
L'objectif du projet est de concevoir un système embarqué capable de mesurer en temps réel les grandeurs électriques fournies par le panneau solaire, puis d'orienter automatiquement celui-ci afin de rechercher la position produisant la puissance maximale.
Le système est constitué de deux parties principales :
- une partie commande basée sur un microcontrôleur ATmega32U4-A ;
- une partie actionnement composée d'un servomoteur permettant de modifier l'orientation du panneau solaire.
Afin d'évaluer les performances du panneau photovoltaïque, deux mesures sont réalisées :
- la tension produite par le panneau ;
- le courant délivré par le panneau.
Ces deux grandeurs sont acquises par les convertisseurs analogique-numérique (ADC) du microcontrôleur. La tension est reliée à l'entrée ADC6 (PF6) tandis que le courant est relié à l'entrée ADC7 (PF7).
À partir de ces mesures, la puissance électrique instantanée est calculée grâce à la relation :
où :
- représente la puissance électrique en watts ;
- représente la tension du panneau en volts ;
- représente le courant fourni par le panneau en ampères.
Le principe retenu consiste à déplacer progressivement le panneau solaire grâce au servomoteur et à comparer la puissance obtenue pour différentes orientations. Lorsque la puissance augmente, le système continue à se déplacer dans la même direction. Dans le cas contraire, le sens de rotation est inversé. Cette méthode permet de rechercher expérimentalement l'orientation offrant la puissance maximale.
Le servomoteur est commandé par un signal PWM généré par l'ATmega32U4-A. Le signal de commande est appliqué sur la broche PD5. La génération du signal PWM permet un positionnement précis du panneau sur une plage angulaire déterminée.
La carte électronique a été entièrement conçue sous KiCad. Elle intègre :
- le microcontrôleur ATmega32U4-A ;
- un quartz externe de 8 MHz ;
- le circuit d'alimentation ;
- les connecteurs de programmation ;
- les connecteurs destinés au servomoteur ;
- les entrées analogiques de mesure de tension et de courant.
Le développement logiciel a été réalisé en langage C à l'aide de la chaîne de compilation avr-gcc. Le chargement du programme dans le microcontrôleur est effectué à l'aide de dfu-programmer via le bootloader USB du composant.
Afin de faciliter le débogage et la validation du système, une liaison série UART a également été mise en place. Celle-ci permet d'afficher les valeurs mesurées (tension, courant, puissance) sur un ordinateur à l'aide d'un adaptateur USB-UART.
L'ensemble de ces éléments constitue un système embarqué complet capable d'acquérir des données électriques, de les traiter localement et d'agir mécaniquement sur l'orientation du panneau solaire afin d'améliorer sa production énergétique.
Carte électronique
Carte réalisée en utilisant le logiciel KiCAD : ma carte électronique.
Schéma électronique de la carte :
Résultat du routage :
Carte 3D:
Photo de la carte soudée :
Vidéo très courte et en basse résolution de la carte en fonctionnement :
Media:2025-PSE-08-systeme-video.mp4
Travail effectué
17/02 : Choix du sujet
Après réflexion sur plusieurs idées de projets, nous avons choisi de réaliser un orienteur de panneau solaire. L'objectif principal est de concevoir un système embarqué capable d'orienter automatiquement un panneau photovoltaïque afin d'améliorer sa production d'énergie.
03/03 : Recherche des composants
Une étude préliminaire a été réalisée afin de sélectionner les différents composants nécessaires au projet. Plusieurs solutions ont été envisagées pour l'optimisation de la puissance du panneau solaire, notamment l'utilisation d'un circuit MPPT dédié. Les principaux composants retenus à cette étape sont le microcontrôleur ATmega32U4-A, un servomoteur SG90 ainsi que des photodiodes destinées aux mesures liées à l'orientation.
10/03 : Début de la schématique
La réalisation de la schématique électronique a débuté sous KiCad. Une première version intégrant le microcontrôleur ATmega32U4-A et le circuit de gestion énergétique a été élaborée. Quelques difficultés liées à l'installation et au téléchargement de certaines bibliothèques sous Ubuntu ont ralenti l'avancement du travail.
24/03 : Réflexion sur la gestion de puissance
Après étude des solutions disponibles, il est apparu qu'aucun composant MPPT autonome n'était réellement adapté à l'architecture retenue. Le choix s'est donc orienté vers l'utilisation d'un convertisseur Buck-Boost permettant d'adapter la tension du panneau solaire. Cette solution offre davantage de flexibilité et permettra ultérieurement d'implémenter une stratégie de recherche du point de puissance maximale.
31/03 : Corrections de la schématique
La schématique a été mise à jour afin de prendre en compte les différentes remarques reçues. Une première implémentation du convertisseur Buck-Boost a été réalisée dans l'attente de la validation du professeur de conversion d'énergie. Les connexions du servomoteur ainsi que celles du microcontrôleur ont également été finalisées.
04/04 : Validation de l'approche Buck-Boost
Une étude plus approfondie du fonctionnement du convertisseur Buck-Boost a été menée. Le principe d'un algorithme MPPT de type Perturb and Observe a été retenu. Cette approche repose uniquement sur la mesure de la tension et du courant produits par le panneau solaire afin de calculer la puissance instantanée et de rechercher le point de fonctionnement optimal.
06/05 - 07/05 - 12/05 : Début de l'assemblage
Les premières opérations de soudure ont été réalisées sur la carte électronique. Cette phase a principalement concerné l'environnement du microcontrôleur ATmega32U4-A ainsi que les composants nécessaires aux premiers tests de fonctionnement, notamment les LED de validation.
18/05 - 19/05 - 26/05 : Finalisation de l'assemblage
La majorité des composants restants a été soudée sur la carte électronique. Cette étape a permis d'obtenir une carte complète et prête à être utilisée pour les futurs tests de programmation, d'acquisition de mesures et de commande du servomoteur.
02/06 : Premiers tests du servomoteur
Les premiers essais de commande du servomoteur ont été réalisés. Un signal PWM a été généré par le microcontrôleur afin de vérifier le bon fonctionnement du moteur et de valider les connexions matérielles. Plusieurs valeurs de rapport cyclique ont été testées afin d'observer les différentes positions du servomoteur.
05/06 : Mise en place de la communication UART
Une liaison série UART a été implémentée afin de faciliter le débogage du système. Un adaptateur USB-UART externe a été utilisé pour permettre l'affichage des informations envoyées par le microcontrôleur sur un ordinateur. Cette étape a permis de vérifier le fonctionnement général du programme et de préparer l'affichage des futures mesures.
Détail de la shématique
Convertisseur Buck-Boost
L'objectif principal de notre projet est d'optimiser l'énergie produite par un panneau photovoltaïque. Pour atteindre cet objectif, il est nécessaire de pouvoir adapter le point de fonctionnement du panneau afin de maximiser la puissance électrique récupérée.
Au début du projet, nous avions envisagé l'utilisation d'un circuit MPPT (Maximum Power Point Tracking) dédié. Après étude des composants disponibles, aucune solution autonome ne répondait réellement aux contraintes de notre architecture. Nous avons donc choisi d'utiliser un convertisseur Buck-Boost piloté par le microcontrôleur.
Le convertisseur Buck-Boost est un convertisseur statique de puissance capable de modifier la tension fournie par une source électrique. Contrairement à un simple convertisseur Buck ou Boost, il possède l'avantage de pouvoir fonctionner aussi bien en mode abaisseur qu'en mode élévateur de tension.
Le schéma de principe repose sur quatre éléments principaux :
- une inductance permettant de stocker temporairement l'énergie ;
- un transistor MOSFET jouant le rôle d'interrupteur commandé ;
- une diode assurant le transfert de l'énergie vers la charge ;
- un condensateur de filtrage limitant les variations de tension en sortie.
Le fonctionnement se décompose en deux phases :
Phase 1 : stockage de l'énergie
Lorsque le transistor est passant, le courant traverse l'inductance. Celle-ci emmagasine progressivement de l'énergie sous forme magnétique. Pendant cette phase, la diode est bloquée et la charge est alimentée par le condensateur.
Phase 2 : restitution de l'énergie
Lorsque le transistor est bloqué, l'énergie stockée dans l'inductance est restituée à la charge à travers la diode. Le condensateur contribue alors à stabiliser la tension de sortie.
Le rapport entre la tension d'entrée et la tension de sortie dépend du rapport cyclique du signal PWM appliqué au transistor :
avec :
- : tension d'entrée ;
- : tension de sortie ;
- Échec de l’analyse (SVG avec PNG en repli (MathML peut être activé via une extension du navigateur) : réponse non valide(« Math extension cannot connect to Restbase. ») du serveur « https://wikimedia.org/api/rest_v1/ » :): {\displaystyle a} : rapport cyclique de la commande PWM.
Cette relation montre que :
- pour un faible rapport cyclique, le convertisseur se comporte principalement comme un abaisseur de tension ;
- pour un rapport cyclique élevé, il se comporte principalement comme un élévateur de tension.
Dans notre projet, la commande du convertisseur sera réalisée par le microcontrôleur ATmega32U4-A. Celui-ci ajustera progressivement le rapport cyclique afin de rechercher le point de fonctionnement produisant la puissance maximale.
La puissance électrique délivrée par le panneau photovoltaïque est donnée par :
où :
- représente la tension du panneau ;
- représente le courant fourni ;
- représente la puissance produite.
L'optimisation ne repose donc pas sur la mesure du rayonnement solaire mais directement sur les grandeurs électriques fournies par le panneau. Cette approche permet d'obtenir une méthode plus robuste et plus directement liée aux performances réelles du système.
Le pont diviseur est composé de deux résistances :
- R1 entre la tension du panneau et l'entrée ADC ;
- R2 entre l'entrée ADC et la masse.
La tension appliquée à l'entrée ADC vaut :
On veut que la tension envoyée à l'ADC reste inférieure à 5 V, même lorsque la tension du panneau est maximale.
En prenant une tension maximale du panneau d'environ 6 V, on choisit :
- R1 = 10 kΩ
- R2 = 47 kΩ
On obtient alors :
Pour une tension maximale du panneau de 6 V :
Échec de l’analyse (SVG avec PNG en repli (MathML peut être activé via une extension du navigateur) : réponse non valide(« Math extension cannot connect to Restbase. ») du serveur « https://wikimedia.org/api/rest_v1/ » :): {\displaystyle V_{ADCmax}=6\times0,824=4,94V}
Cette valeur reste inférieure à 5 V, ce qui permet de protéger l'entrée analogique du microcontrôleur.
Pour retrouver la tension réelle du panneau dans le programme, il faut inverser la relation :
Avec les valeurs retenues :
Ainsi, la chaîne de mesure de tension est composée d'un pont diviseur résistif suivi de l'entrée ADC6 du microcontrôleur.
Les valeurs retenues sont :
- R1 = 10 kΩ
- R2 = 47 kΩ
- Entrée utilisée :
PF6 / ADC6
Mesure du courant
La mesure du courant est indispensable pour déterminer la puissance produite par le panneau photovoltaïque. En effet, la tension seule ne permet pas de connaître la puissance réellement fournie, car un panneau peut avoir une tension correcte tout en délivrant un courant faible.
Dans notre carte, la mesure du courant est reliée à l'entrée analogique :
PF7 / ADC7
Pour mesurer le courant, nous utilisons une résistance de mesure appelée résistance shunt. Cette résistance est placée en série avec la charge. Lorsqu'un courant la traverse, une petite tension apparaît à ses bornes.
Cette tension suit la loi d'Ohm :
Vshunt = Rshunt × I
où :
Vshuntest la tension aux bornes de la résistance shunt ;Rshuntest la valeur de la résistance de mesure ;Iest le courant traversant le circuit.
Le but est de choisir une résistance suffisamment faible pour ne pas trop perturber le fonctionnement du panneau, mais suffisamment grande pour obtenir une tension mesurable par l'ADC.
On estime le courant maximal à environ :
Imax = 1 A
On souhaite obtenir une tension de mesure d'environ :
Vshuntmax = 0.5 V
La résistance shunt théorique vaut donc :
Rshunt = Vshuntmax / Imax
Rshunt = 0.5 / 1
Rshunt = 0.5 Ω
Comme nous ne disposions pas directement d'une résistance de cette valeur, nous avons réalisé une résistance équivalente à partir de quatre résistances de 2 Ω montées en parallèle.
Pour quatre résistances identiques en parallèle, la résistance équivalente vaut :
Req = R / 4
Donc :
Req = 2 / 4 = 0.5 Ω
Cette valeur correspond à la valeur souhaitée pour la résistance shunt.
Pour un courant maximal de 1 A, la tension obtenue aux bornes de la résistance shunt est :
Vshunt = 0.5 × 1 = 0.5 V
Cette tension reste inférieure à la tension maximale admissible par l'entrée analogique du microcontrôleur. Elle peut donc être envoyée directement vers l'entrée PF7 / ADC7.
L'ADC de l'ATmega32U4-A convertit ensuite cette tension en une valeur numérique comprise entre 0 et 1023. En considérant une tension de référence de 5 V, la tension mesurée par l'ADC est :
V_ADC = ADC × 5 / 1023
Le courant peut ensuite être retrouvé dans le programme avec la relation :
I = V_ADC / Rshunt
Comme Rshunt = 0.5 Ω, on obtient :
I = V_ADC / 0.5
ou encore :
I = 2 × V_ADC
Les valeurs retenues pour la mesure du courant sont donc :
- résistance shunt équivalente :
Rshunt = 0.5 Ω - réalisation pratique : quatre résistances de
2 Ωen parallèle - courant maximal considéré :
Imax = 1 A - tension maximale mesurée :
Vshuntmax = 0.5 V - entrée utilisée :
PF7 / ADC7
Cette mesure sera ensuite utilisée avec la mesure de tension afin de calculer la puissance instantanée du panneau :
P = U × I
Programmation
Environnement de développement
La programmation du système embarqué a été réalisée en langage C. Le microcontrôleur utilisé sur la carte est un ATmega32U4-A, cadencé par un quartz externe de 8 MHz.
Le développement a été effectué sous Linux / Ubuntu. Ce choix permet d'utiliser directement les outils de compilation et de programmation AVR en ligne de commande.
Les principaux outils utilisés sont :
avr-gcc: compilateur C pour microcontrôleurs AVR ;avr-objcopy: génération du fichier.hexà partir du fichier compilé ;dfu-programmer: outil utilisé pour flasher le programme dans l'ATmega32U4-A ;make: automatisation de la compilation grâce à unMakefile;minicom: affichage des données envoyées par la liaison série UART ;KiCad: conception de la carte électronique.
Le programme est compilé avec une fréquence processeur définie à :
F_CPU = 8000000UL
Cette valeur est importante car elle est utilisée par les fonctions de temporisation, notamment _delay_ms() et _delay_us(). Elle doit donc correspondre à la fréquence réelle du quartz utilisé sur la carte.
Le programme source est écrit dans un fichier principal main.c. Après compilation, un fichier exécutable intermédiaire est généré, puis converti en fichier .hex. Ce fichier .hex est ensuite envoyé dans la mémoire du microcontrôleur à l'aide de dfu-programmer.
Cette organisation permet de tester progressivement les différentes fonctions du système : commande du servomoteur, communication UART, lecture des entrées analogiques, calcul de puissance puis intégration dans un programme principal.
Test des LED
Avant de tester les fonctionnalités plus avancées du projet, un premier programme de validation a été développé afin de vérifier le bon fonctionnement général de la carte électronique.
L'objectif de ce test est de contrôler plusieurs points :
- alimentation correcte de la carte ;
- bon fonctionnement du microcontrôleur ;
- validation de la chaîne de compilation ;
- validation du chargement du programme via DFU ;
- commande d'une sortie numérique.
Le principe consiste à faire clignoter une LED reliée à une broche du microcontrôleur.
Le programme utilisé est le suivant :
#define F_CPU 8000000UL
#include <avr/io.h>
int main(void)
{
DDRD |= (1 << PD5);
```
while(1)
{
PORTD ^= (1 << PD5);
for(long i = 0; i < 500000; i++);
}
```
}
La broche PD5 est configurée en sortie grâce au registre DDRD.
L'instruction :
PORTD ^= (1 << PD5);
Media:2025-PSE-08-teste-led.mp4
Les essais réalisés ont montré que la LED clignotait correctement après le chargement du programme dans le microcontrôleur. Ce premier test a permis de valider l'ensemble de la chaîne de développement avant de poursuivre avec les essais du servomoteur et des acquisitions analogiques.
Compilation et flash du programme
La compilation du programme est réalisée à l'aide de la chaîne de compilation AVR sous Linux.
Compilation du programme :
make
Effacement, programmation et redémarrage du microcontrôleur :
dfu-programmer atmega32u4 erase
dfu-programmer atmega32u4 flash main.hex
dfu-programmer atmega32u4 reset
Le Makefile utilisé durant le projet est le suivant :
MCU = atmega32u4
F_CPU = 8000000UL
CC = avr-gcc
OBJCOPY = avr-objcopy
CFLAGS = -mmcu=$(MCU) -DF_CPU=$(F_CPU) -Os -Wall
all: main.hex
main.elf: main.c
$(CC) $(CFLAGS) main.c -o main.elf
main.hex: main.elf
$(OBJCOPY) -O ihex -R .eeprom main.elf main.hex
flash: main.hex
dfu-programmer $(MCU) erase
dfu-programmer $(MCU) flash main.hex
dfu-programmer $(MCU) reset
clean:
rm -f main.elf main.hex
Cette procédure a été utilisée tout au long du projet afin de tester progressivement les différentes fonctionnalités développées.
Test du servomoteur
Avant d'intégrer le servomoteur dans le programme principal, un programme de test a été développé afin de vérifier son bon fonctionnement.
Le servomoteur utilisé est un SG90.
Le branchement a été réalisé à l'aide du connecteur J2 de la carte :
- J2-1 : GND du servomoteur
- J2-2 : +5 V du servomoteur
- J2-3 : Signal PWM du servomoteur
Le signal de commande est relié à la broche PD5 de l'ATmega32U4-A.
Le programme de test utilisé est le suivant :
#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
int main(void)
{
DDRD |= (1 << PD5);
```
while(1)
{
PORTD |= (1 << PD5);
_delay_us(1500);
PORTD &= ~(1 << PD5);
_delay_ms(18);
_delay_us(500);
}
```
}
Le principe est de générer périodiquement une impulsion de largeur 1500 µs sur la broche PD5. Cette largeur correspond à la position centrale du servomoteur.
Media:2025-PSE-08-test-servo.mp4
Les essais réalisés ont permis de vérifier :
- le bon câblage du connecteur J2 ;
- le fonctionnement du servomoteur ;
- la génération correcte du signal PWM par le microcontrôleur.
Les tests ont montré que le servomoteur répond correctement aux commandes envoyées par l'ATmega32U4-A. Cette étape a validé la partie actionneur du projet avant l'intégration des fonctions de mesure et de calcul de puissance.
Communication UART
Avant de développer l'algorithme d'orientation du panneau solaire, il était nécessaire de pouvoir visualiser les valeurs mesurées par le microcontrôleur. L'objectif était d'afficher sur un ordinateur les mesures de tension, de courant puis de puissance produite par le panneau photovoltaïque.
Pour cela, nous avons choisi d'utiliser une communication série UART. Cette solution permet d'envoyer des caractères depuis l'ATmega32U4-A vers un terminal sur ordinateur afin d'observer en temps réel les données calculées par le programme.
Comme notre carte ne possède pas de convertisseur USB-Série intégré, nous avons utilisé un adaptateur USB-TTL externe.
L'adaptateur est relié au connecteur UART de la carte selon le câblage suivant :
- TX de la carte → RX de l'adaptateur ;
- RX de la carte → TX de l'adaptateur ;
- GND de la carte → GND de l'adaptateur.
L'objectif du programme suivant était de lire une entrée analogique, ici ADC6, puis d'envoyer la valeur mesurée par UART afin de l'afficher sur l'ordinateur.
#define F_CPU 8000000UL
#define BAUD 9600
#define UBRR_VALUE ((F_CPU / (16UL * BAUD)) - 1)
#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>
void uart_init(void) {
UBRR1H = 0;
UBRR1L = UBRR_VALUE;
UCSR1B = (1 << TXEN1);
UCSR1C = (1 << UCSZ11) | (1 << UCSZ10);
}
void uart_putchar(char c) {
while (!(UCSR1A & (1 << UDRE1)));
UDR1 = c;
}
int uart_putchar_stream(char c, FILE *f) {
(void)f;
uart_putchar(c);
return 0;
}
void adc_init(void) {
ADMUX = (1 << REFS0);
ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1);
DIDR0 = (1 << ADC6D);
}
uint16_t adc_read(uint8_t channel) {
ADMUX = (ADMUX & 0xE0) | (channel & 0x1F);
ADCSRA |= (1 << ADSC);
while (ADCSRA & (1 << ADSC));
return ADC;
}
int main(void) {
uart_init();
adc_init();
```
static FILE uart_out = FDEV_SETUP_STREAM(uart_putchar_stream, NULL, _FDEV_SETUP_WRITE);
stdout = &uart_out;
printf("=== Panneau Solaire Monitor ===\r\n");
while (1) {
uint16_t raw = adc_read(6);
uint32_t mv = ((uint32_t)raw * 5000UL) / 1023UL;
printf("ADC: %4u LSB | Tension: %lu.%03lu V\r\n",
raw, mv / 1000, mv % 1000);
_delay_ms(1000);
}
```
}
Dans ce programme, l'UART est configurée à une vitesse de 9600 bauds. La fonction uart_putchar() permet d'envoyer un caractère, puis FDEV_SETUP_STREAM permet d'utiliser directement la fonction printf() pour afficher des messages complets.
La partie ADC permet de lire la tension présente sur l'entrée ADC6. La valeur brute comprise entre 0 et 1023 est ensuite convertie en millivolts avec la relation :
mv = ADC × 5000 / 1023
En théorie, le terminal devait afficher une ligne du type :
ADC: 512 LSB | Tension: 2.502 V
En pratique, malgré plusieurs essais de configuration, les caractères reçus sur le terminal n'étaient pas exploitables. La communication UART n'a donc pas permis d'afficher correctement les valeurs du panneau solaire.
Ces essais ont tout de même permis de mettre en place la structure logicielle nécessaire pour l'envoi série et de préparer la future visualisation des mesures de tension, de courant et de puissance.
Programme principal
Après avoir testé séparément le servomoteur et les entrées analogiques, j'ai essayé de regrouper ces éléments dans un programme principal.
L'objectif de ce programme était de lire les deux entrées analogiques :
ADC6pour la tension ;ADC7pour le courant.
Ensuite, une grandeur proportionnelle à la puissance est calculée en multipliant les deux valeurs ADC :
puissance = tension_adc × courant_adc
Cette valeur n'est pas encore une puissance réelle en watts, car les conversions physiques complètes ne sont pas encore appliquées. Elle permet cependant d'obtenir une grandeur proportionnelle à la puissance fournie par le panneau.
Le programme devait ensuite modifier l'angle du servomoteur en fonction de cette valeur. Plus la puissance mesurée est faible, plus le changement d'angle est petit. Lorsque la puissance est plus grande, l'angle est modifié plus rapidement.
Le code utilisé est le suivant :
#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <stdint.h>
#define SERVO_PIN PD5
void adc_init(void) {
ADMUX = (1 << REFS0);
ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1);
DIDR0 = (1 << ADC6D) | (1 << ADC7D);
}
uint16_t adc_read(uint8_t channel) {
ADMUX = (ADMUX & 0xE0) | (channel & 0x1F);
_delay_us(10);
ADCSRA |= (1 << ADSC);
while (ADCSRA & (1 << ADSC));
return ADC;
}
void servo_pulse(uint16_t pulse_us) {
PORTD |= (1 << SERVO_PIN);
while (pulse_us--) {
_delay_us(1);
}
PORTD &= ~(1 << SERVO_PIN);
}
void servo_write_angle(uint8_t angle) {
uint16_t pulse_us;
```
pulse_us = 1000 + ((uint32_t)angle * 1000) / 180;
servo_pulse(pulse_us);
uint16_t rest_us = 20000 - pulse_us;
while (rest_us--) {
_delay_us(1);
}
```
}
int main(void) {
DDRD |= (1 << SERVO_PIN);
```
adc_init();
uint8_t angle = 0;
while (1) {
uint16_t tension_adc = adc_read(6);
uint16_t courant_adc = adc_read(7);
uint32_t puissance = (uint32_t)tension_adc * courant_adc;
if (puissance < 100000UL) {
angle += 5;
}
else if (puissance < 300000UL) {
angle += 15;
}
else {
angle += 30;
}
if (angle > 180) {
angle = 0;
}
for (uint8_t i = 0; i < 5; i++) {
servo_write_angle(angle);
}
}
```
}
Dans ce programme, la fonction adc_read() permet de lire une entrée analogique. La fonction servo_write_angle() transforme un angle compris entre 0° et 180° en une impulsion comprise entre environ 1000 µs et 2000 µs, ce qui correspond à la plage classique de commande d'un servomoteur.
En pratique, le servomoteur tournait bien, mais il se déplaçait toujours avec la même intensité apparente. Le comportement obtenu ne dépendait donc pas clairement des valeurs mesurées par le panneau.
Ce problème peut s'expliquer par plusieurs raisons :
- les valeurs de
tension_adcetcourant_adcn'étaient peut-être pas suffisamment différentes pour changer de seuil ; - les seuils
100000et300000ont été choisis de manière arbitraire ; - la valeur
angleest toujours incrémentée, donc le servomoteur finit toujours par parcourir la même plage ; - le programme ne compare pas encore la puissance actuelle avec la puissance précédente ;
- l'algorithme MPPT de type Perturb and Observe n'est pas encore réellement implémenté.
Ce code constitue donc une première tentative d'intégration entre les mesures analogiques et la commande du servomoteur. Il permet de valider l'idée générale, mais il devra être amélioré pour que le mouvement du servomoteur dépende réellement de l'évolution de la puissance mesurée.
Bilan
Au cours des différentes séances, j'ai conçu une carte électronique complète autour d'un microcontrôleur ATmega32U4-A. La schématique et le routage ont été réalisés sous KiCad puis la carte a été fabriquée et assemblée manuellement.
La partie matérielle a été validée avec succès. L'environnement du microcontrôleur, l'alimentation, les connecteurs, les LED de test, le servomoteur ainsi que les circuits de mesure de tension et de courant ont été intégrés sur la carte.
Du côté logiciel, j'ai réussi à :
- compiler et programmer le microcontrôleur à l'aide d'avr-gcc et dfu-programmer ;
- valider le fonctionnement de la carte grâce au clignotement des LED ;
- commander un servomoteur SG90 à partir de la broche PD5 ;
- mettre en place les fonctions de lecture des convertisseurs analogique-numérique ADC6 et ADC7 ;
- développer une première version du calcul de puissance à partir des mesures de tension et de courant.
J'ai également étudié le principe du suivi du point de puissance maximale (MPPT). Après analyse des solutions disponibles, le choix s'est porté sur l'utilisation d'un convertisseur Buck-Boost piloté par le microcontrôleur plutôt que sur un circuit MPPT dédié.
Certaines fonctionnalités n'ont cependant pas pu être entièrement finalisées. La communication UART a été mise en place mais les valeurs attendues n'ont pas pu être affichées correctement sur l'ordinateur malgré plusieurs essais de configuration. De plus, l'algorithme d'orientation automatique du panneau solaire reste perfectible. Le servomoteur peut être commandé, mais son mouvement ne dépend pas encore de manière optimale de la puissance réellement produite par le panneau.' Malgré ces limitations, les principaux objectifs pédagogiques du projet ont été atteints. Ce travail j4ai d'aborder l'ensemble des étapes d'un projet de système embarqué : étude préliminaire, choix des composants, conception électronique, routage PCB, assemblage, programmation, tests et validation.
Eventuellement la vidéo brève du fonctionnement du système :