<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="fr">
	<id>https://projets-se.plil.fr/mediawiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Mbarret</id>
	<title>projets-se.plil.fr - Contributions [fr]</title>
	<link rel="self" type="application/atom+xml" href="https://projets-se.plil.fr/mediawiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Mbarret"/>
	<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php/Sp%C3%A9cial:Contributions/Mbarret"/>
	<updated>2026-05-15T14:53:18Z</updated>
	<subtitle>Contributions</subtitle>
	<generator>MediaWiki 1.39.1</generator>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-2&amp;diff=7412</id>
		<title>SE4Binome2024-2</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-2&amp;diff=7412"/>
		<updated>2025-01-26T19:01:58Z</updated>

		<summary type="html">&lt;p&gt;Mbarret : /* Résultat des tests */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Pico Ordinateur =&lt;br /&gt;
Ce projet vise à concevoir un pico ordinateur divisé en plusieurs parties, réalisées par différents binômes. Le rôle de notre binôme est de développer une carte fille équipée d'un microcontrôleur ATMega328p et d'un écran LCD contrôlé par un HD44780, en plus de la conception d'un Shield et d'un ordonnanceur. Cette carte sera connectée à une carte mère via un connecteur HE10 et devra gérer l'affichage de caractères ASCII, ainsi que quelques commandes spécifiques VT100. De plus, nous ajouterons une RAM SPI pour améliorer les performances de gestion de l'affichage.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Lien du git : https://gitea.plil.fr/mbarret/pico_kaoutar_maxime&lt;br /&gt;
&lt;br /&gt;
== Carte Fille (Écran LCD) ==&lt;br /&gt;
&lt;br /&gt;
=== Description ===&lt;br /&gt;
La carte fille que nous avons développée contient les éléments suivants :&lt;br /&gt;
&lt;br /&gt;
* Un microcontrôleur '''ATMega328p''' pour la gestion de l'affichage.&lt;br /&gt;
* Un écran '''LCD avec contrôleur HD44780''' pour l'affichage de caractères ASCII.&lt;br /&gt;
* Un '''potentiomètre 3310P''' pour ajuster la luminosité des cristaux liquides de l'écran.&lt;br /&gt;
* Un '''connecteur HE10''' pour relier la carte fille à la carte mère.&lt;br /&gt;
* Un '''connecteur AVR ISP''' pour la programmation du microcontrôleur.&lt;br /&gt;
* Une '''RAM SP'''I (e.g. FM24C04B-GTR) pour stocker temporairement les données d'affichage.&lt;br /&gt;
&lt;br /&gt;
=== Fonctionnalités Demandées ===&lt;br /&gt;
&lt;br /&gt;
* Gestion de l'écran LCD : Le microcontrôleur doit gérer les écrans HD44780 avec 1, 2, 3 ou 4 lignes et afficher des caractères ASCII.&lt;br /&gt;
* Saut de ligne et retour chariot : Les caractères spéciaux `\n` et `\r` doivent être pris en compte.&lt;br /&gt;
* Commandes VT100 : Quelques codes VT100, notamment ceux pour le déplacement du curseur, doivent être supportés.&lt;br /&gt;
* Défilement automatique : Le contrôleur HD44780 doit être configuré pour activer le mode de défilement automatique.&lt;br /&gt;
* Connexion SPI : La carte mère doit envoyer les commandes via SPI. Le premier octet envoyé doit être le code commande `0x01`, suivi des caractères à afficher.&lt;br /&gt;
* Vérification de la disponibilité de l'écran : La carte fille met la ligne SPI en état haut lorsque l'affichage est en cours. La carte mère doit attendre que l'état soit bas avant de transmettre de nouvelles données, ou envoyer des commandes `0xFF` pour vérifier si l'écran est prêt.&lt;br /&gt;
&lt;br /&gt;
=== Ajout d'une RAM SPI ===&lt;br /&gt;
Pour complexifier la carte fille, nous ajouterons une RAM SPI (e.g. FM24C04B-GTR). Cette mémoire permet de stocker temporairement les caractères reçus par SPI avant leur affichage. Le microcontrôleur de la carte fille rafraîchit régulièrement l'écran en lisant les données de la RAM, ce qui améliore la fluidité de l'affichage et permet de libérer la carte mère plus rapidement.&lt;br /&gt;
&lt;br /&gt;
Nous avons choisi la RAM FM25W256-G disponible chez RS Component.&lt;br /&gt;
https://fr.rs-online.com/web/p/memoires-fram/1254228?gb=s&lt;br /&gt;
&lt;br /&gt;
Voici un schéma simplifié de la communication entre les composants :&lt;br /&gt;
* La carte mère écrit dans la RAM SPI via le bus SPI.&lt;br /&gt;
* Le microcontrôleur de la carte fille lit les données de la RAM SPI et les envoie à l'écran LCD pour mise à jour régulière.&lt;br /&gt;
&lt;br /&gt;
=== Schéma de Connexion ===&lt;br /&gt;
[[Fichier:carteEcran.pdf|922x922px]]&lt;br /&gt;
&lt;br /&gt;
=== Ajout de sélecteurs ===&lt;br /&gt;
Ajouter des sélecteurs permet de choisir entre le microprocesseur et la connexion SPI venant de la carte mère. Pour cela, nous avons fait une simulation sur LTSpice. Voici le schéma et sa simulation : &lt;br /&gt;
[[Fichier:Circuit de simulation.png|gauche|vignette|577x577px]]&lt;br /&gt;
[[Fichier:Simulation.png|néant|vignette|501x501px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
La fonction PULSE nous permet de simuler le SELECT. Nous avons pris des modèles de transistors déjà sur le logiciel pour pouvoir simuler. &lt;br /&gt;
&lt;br /&gt;
On remarque que, sur la simulation, un des transistors PMOS est inversee. Quand un des PMOS est passant, l'autre est bloquant. Cette simulation nous permet de valider notre sélecteur pour notre carte écran. Nous avons reproduit ce schéma dans Kicad.&lt;br /&gt;
&lt;br /&gt;
=== Carte écran soudée ===&lt;br /&gt;
Nous avons terminé de souder complétement notre carte et il est temps de la tester. Pour vérifier le bon fonctionnement de notre travail, nous utiliserons un code test dédié à notre écran HD44780 fournis par la librairie du même nom sur l'IDE Arduino. Cette méthode de test nous convient parfaitement puisque nous voulons uniquement vérifier son fonctionnement. &lt;br /&gt;
&lt;br /&gt;
Malheureusement, le code ne fonctionne pas directement à cause de mauvais branchement sur notre connecteur. On avait relié directement les pins  Enable, et RS du connecteur écran à notre 5V.  Nous avons du alors faire du bricolage pour la réparer. Pour ce faire, nous avons donc coupé les piste du RS et Enable pour les relier à des pins non utilisés du microcontrôleur.  &lt;br /&gt;
[[Fichier:Resolution carte ecran.png|centré|vignette]]  &lt;br /&gt;
&lt;br /&gt;
Après ces réparations, on arrive à afficher le texte voulu grâce au code d'exemple Arduino : &lt;br /&gt;
[[Fichier:Ecran.jpg|centré|vignette]] &lt;br /&gt;
&lt;br /&gt;
Il nous faut désormais tester notre carte écran en code C. Pour ce faire, nous avons récupéré le code des Masters I2L et mis à jour les fuses de l'atmega328p. Cependant  lors de l'upload du code, notre Atmega n'est plus détecté. Nous devons alors vérifier la clock par le biais d'un oscilloscope.  &lt;br /&gt;
&lt;br /&gt;
Cette carte a du être recommencée car après l'ajout de commande changeant les fuses du microprocesseur, ce dernier n'était plus reconnu. Ainsi nous avons pris le temps de resouder une carte écran.  &lt;br /&gt;
&lt;br /&gt;
Apres cela un autre problème (cette fois ci de circuit) est que nous perdons 1,5V entre le Shield et la carte écran. Apres quelque test au multimètre sans réponse nous avons vérifié la clock au niveau du Shield et au niveau de la carte écran.  &lt;br /&gt;
[[Fichier:Clock shield.jpg|gauche|vignette|594x594px|Clock SPI sur le Shield]] &lt;br /&gt;
[[Fichier:Clock carte ecran.jpg|néant|vignette|484x484px|Clock SPI sur la carte écran]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cela est selon nous la cause de non fonctionnement du transfert de donnée entre les deux cartes.&lt;br /&gt;
&lt;br /&gt;
== Ordonnanceur et Gestion du Contexte des Tâches ==&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
L'ordonnanceur est un composant clé de notre pico-ordinateur, assurant la gestion et l'exécution ordonnée des différentes tâches. Il permet un partage équitable du temps processeur grâce à un algorithme de round-robin. De plus, il vérifie la disponibilité des ressources matérielles, comme les lignes SPI et les périphériques LED.&lt;br /&gt;
&lt;br /&gt;
La gestion du contexte des tâches est assurée par des macros de sauvegarde (`SAVE_REGISTERS`) et de restauration (`RESTORE_REGISTERS`) des registres, permettant ainsi d'interrompre et de reprendre l'exécution de chaque tâche.&lt;br /&gt;
&lt;br /&gt;
=== Structure des Tâches ===&lt;br /&gt;
&lt;br /&gt;
Chaque tâche est représentée par la structure `process` :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
typedef struct process {&lt;br /&gt;
    uint16_t stackPointer; // Adresse du pointeur de pile, définissant le contexte de la tâche&lt;br /&gt;
    void (*addressFunction)(void); // Adresse de la fonction à exécuter&lt;br /&gt;
    int state; // État de la tâche (0 = prête, 1 = en cours, 2 = terminée)&lt;br /&gt;
} process;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dans ce programme, `stackPointer` stocke la position de la pile de chaque tâche, `addressFunction` est un pointeur vers la fonction de la tâche, et `state` représente l’état actuel de la tâche.&lt;br /&gt;
&lt;br /&gt;
=== Initialisation des Tâches ===&lt;br /&gt;
&lt;br /&gt;
Les tâches sont initialisées dans le tableau `task`, contenant des fonctions telles que `Serial_Led`, `LED1_blink`, et `Serial_Message`, chacune avec son pointeur de pile initial :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
process task[NB_TASKS] = {&lt;br /&gt;
    {0x700, Serial_Led, 0},&lt;br /&gt;
    {0x600, LED1_blink, 0},&lt;br /&gt;
    {0x500, Serial_Message, 0}&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Macros de Sauvegarde et Restauration des Registres ===&lt;br /&gt;
&lt;br /&gt;
Les macros `SAVE_REGISTERS()` et `RESTORE_REGISTERS()` permettent de sauvegarder et de restaurer les registres lors du changement de tâche :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define RESTORE_REGISTERS() \&lt;br /&gt;
asm volatile ( \&lt;br /&gt;
    /* Code pour restaurer les registres ici */ \&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
#define SAVE_REGISTERS() \&lt;br /&gt;
asm volatile ( \&lt;br /&gt;
    /* Code pour sauvegarder les registres ici */ \&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ces macros utilisent des instructions d’assembleur pour pousser et dépiler les registres, préservant ainsi l’état complet de la tâche au moment de l'interruption.&lt;br /&gt;
&lt;br /&gt;
=== Ordonnancement des Tâches ===&lt;br /&gt;
&lt;br /&gt;
L'ordonnanceur suit l'algorithme round-robin. La fonction `scheduler()` passe d'une tâche à la suivante dans le tableau `task` :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void scheduler() {&lt;br /&gt;
    currentTask++;&lt;br /&gt;
    if (currentTask == NB_TASKS) currentTask = 0; // Retour à la première tâche après la dernière&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Gestion des Interruptions ===&lt;br /&gt;
&lt;br /&gt;
L'interruption liée au minuteur (`TIMER1_COMPA_vect`) déclenche l'ordonnanceur et le changement de tâche, en sauvegardant et restaurant le contexte :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
ISR(TIMER1_COMPA_vect, ISR_NAKED) {&lt;br /&gt;
    SAVE_REGISTERS();&lt;br /&gt;
    task[currentTask].stackPointer = SP;&lt;br /&gt;
    scheduler();&lt;br /&gt;
    SP = task[currentTask].stackPointer;&lt;br /&gt;
    RESTORE_REGISTERS();&lt;br /&gt;
    asm volatile(&amp;quot;reti&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* `SAVE_REGISTERS()` : sauvegarde le contexte de la tâche courante.&lt;br /&gt;
* `scheduler()` : passe à la tâche suivante.&lt;br /&gt;
* `RESTORE_REGISTERS()` : restaure le contexte de la nouvelle tâche.&lt;br /&gt;
* `asm volatile(&amp;quot;reti&amp;quot;);` : retourne de l'interruption en restaurant l'état.&lt;br /&gt;
&lt;br /&gt;
=== Initialisation du Système ===&lt;br /&gt;
&lt;br /&gt;
Les fonctions d'initialisation préparent les ressources, telles que les LED et l'UART, pour la communication série.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void LED_init() {&lt;br /&gt;
    DDRC |= (1&amp;lt;&amp;lt;LED1) | (1&amp;lt;&amp;lt;LED2);&lt;br /&gt;
    DDRD |= (1&amp;lt;&amp;lt;LED3) | (1&amp;lt;&amp;lt;LED4) | (1&amp;lt;&amp;lt;LED5);&lt;br /&gt;
    PORTC |= (1&amp;lt;&amp;lt;LED1) | (1&amp;lt;&amp;lt;LED2);&lt;br /&gt;
    PORTD |= (1&amp;lt;&amp;lt;LED3) | (1&amp;lt;&amp;lt;LED4) | (1&amp;lt;&amp;lt;LED5);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Fonctions des Tâches ===&lt;br /&gt;
&lt;br /&gt;
Chaque tâche a une fonction dédiée. Par exemple, `LED1_blink` fait clignoter une LED, et `Serial_Message` envoie des messages en série.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void LED1_blink() {&lt;br /&gt;
    while(1) {&lt;br /&gt;
        PORTC ^= (1&amp;lt;&amp;lt;LED1);&lt;br /&gt;
        _delay_ms(150);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ces fonctions sont répétitives pour les autres LED, avec des délais différents pour créer des clignotements variés.&lt;br /&gt;
&lt;br /&gt;
=== Communication Série ===&lt;br /&gt;
&lt;br /&gt;
L'initialisation de l'UART et les fonctions de réception et de transmission sont définies pour permettre la communication série :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void USART_Init(unsigned int ubrr) {&lt;br /&gt;
    UBRR0H = (unsigned char)(ubrr&amp;gt;&amp;gt;8);&lt;br /&gt;
    UBRR0L = (unsigned char)ubrr;&lt;br /&gt;
    UCSR0B = (1&amp;lt;&amp;lt;RXEN0) | (1&amp;lt;&amp;lt;TXEN0);&lt;br /&gt;
    UCSR0C = (1&amp;lt;&amp;lt;USBS0) | (3&amp;lt;&amp;lt;UCSZ00);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
unsigned char USART_Receive(void) {&lt;br /&gt;
    while (!(UCSR0A &amp;amp; (1&amp;lt;&amp;lt;RXC0)));&lt;br /&gt;
    return UDR0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Fonction `main` ===&lt;br /&gt;
&lt;br /&gt;
La fonction `main` configure les LED, l'UART, et initialise l'ordonnanceur avant de lancer la première tâche :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int main(void) {&lt;br /&gt;
    cli();&lt;br /&gt;
    LED_init();&lt;br /&gt;
    USART_Init(MYUBRR);&lt;br /&gt;
    init_minuteur(256, PERIODE);&lt;br /&gt;
    for(int i = 1; i &amp;lt; NB_TASKS; i++) init_pile(i);&lt;br /&gt;
    SP = task[0].stackPointer;&lt;br /&gt;
    sei();&lt;br /&gt;
    task[0].addressFunction();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. `cli()` : désactive les interruptions.&lt;br /&gt;
2. `LED_init()` et `USART_Init()` : initialisent les LED et la communication série.&lt;br /&gt;
3. `init_minuteur()` : initialise le minuteur avec une période.&lt;br /&gt;
4. `init_pile(i)` : initialise la pile pour chaque tâche.&lt;br /&gt;
5. `sei()` : réactive les interruptions.&lt;br /&gt;
&lt;br /&gt;
L'ordonnanceur gère ainsi le contexte des tâches en suivant une séquence de round-robin, tout en assurant que chaque tâche exécute son cycle de manière autonome et en garantissant la disponibilité des ressources matérielles.&lt;br /&gt;
&lt;br /&gt;
=== Fonction `wait()` ===&lt;br /&gt;
Comme première amélioration de votre ordonnanceur, il nous a été demandé de mettre en place un état endormi pour nos processus. Pour cela nous avons créer la procédure wait() suivante :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void wait(int time_ms){&lt;br /&gt;
    task[currentTask].state = SLEEP;&lt;br /&gt;
    task[currentTask].sleeping_time = time_ms;&lt;br /&gt;
    TCNT1 = 0;&lt;br /&gt;
    TIMER1_COMPA_vect();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;On modifie aussi les procedures des LED :&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void LED1_blink(){&lt;br /&gt;
    while(1){&lt;br /&gt;
        PORTC ^= (1&amp;lt;&amp;lt;LED1);&lt;br /&gt;
        _delay_ms(200);&lt;br /&gt;
        wait(5000);&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Et la structure :&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
typedef struct{&lt;br /&gt;
    uint16_t stackPointer; // stack pointer, défini le début du process&lt;br /&gt;
    void (*addressFunction)(void); // adresse de l'instruction en cours&lt;br /&gt;
    int state; // état de la fonction (Awake ou Idle)&lt;br /&gt;
    int sleeping_time;&lt;br /&gt;
}process;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;En faisant cela dès qu'une tâche est appelée en présence d'un wait on met à jour son état ainsi que son temps d'attente. Par la suite, on modifie le scheduler() pour réveiller les tâches endormies si nécessaire : &amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void scheduler (){&lt;br /&gt;
  for(int i=0;i&amp;lt;NB_TASKS;i++){&lt;br /&gt;
    if(task[i].state==SLEEP){&lt;br /&gt;
        task[i].sleeping_time -= REDUCE_TIME;&lt;br /&gt;
        if(task[i].sleeping_time &amp;lt;= 0){&lt;br /&gt;
            task[i].sleeping_time = 0;&lt;br /&gt;
            task[i].state = AWAKE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
do{&lt;br /&gt;
  currentTask ++;&lt;br /&gt;
  if(currentTask &amp;gt;= NB_TASKS) currentTask = 0; // ordonnanceur en mode Round Robin&lt;br /&gt;
  }while(task[currentTask].state == SLEEP);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Avec ces modifications nous avons réussi à obtenir le résultat suivant : &lt;br /&gt;
[[Fichier:Wait.mp4|néant|vignette]]&lt;br /&gt;
&lt;br /&gt;
Nous avons eu un problème avec la LED rouge. En effet, apres de tres nombreuses tentatives, nous n'avions pas reussi a la faire clignoter. Nous avons abordé plusieurs methode pour débugger notre code comme manipuler la LED rouge seule. C'est plus tard que nous avons compris que le problème venait de l'utilisation du pin PD1 de notre carte. Le pin PD1 peut aussi être utilisé pour gérer la connexion RX. Ainsi, quand nous voulions utiliser l'instruction &amp;lt;code&amp;gt;USART_Init(MYUBRR);&amp;lt;/code&amp;gt; cela ne permettait pas de faire clignoter la LED. Cette LED sera donc inutilisée dans la suite du projet si nous utilisons l'UART.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Wait2.mp4|néant|vignette|300x300px]]&lt;br /&gt;
&lt;br /&gt;
== Carte Shield ==&lt;br /&gt;
&lt;br /&gt;
=== Description ===&lt;br /&gt;
La carte Shield est une carte mère qui sert à connecter et contrôler divers périphériques, notamment la carte fille (écran), un clavier, et d'autres composants. Nous avons conçu cette carte pour faciliter la gestion des communications SPI entre la carte mère et les différentes cartes filles.&lt;br /&gt;
&lt;br /&gt;
=== Connectivité SPI ===&lt;br /&gt;
La carte Shield utilise plusieurs lignes SPI pour communiquer avec les cartes filles. Chaque périphérique, comme l'écran, est assigné à une ligne SPI spécifique. La carte Shield vérifie également la disponibilité des périphériques avant d'envoyer des commandes via SPI. Nous avons effectué plusieurs test afin de vérifier le bon fonctionnement de notre carte Shield. Nous avons tester le fonctionnement des LED, la connectivité de la carte SD, et nous avons utiliser le Shield pour faire un timer sur un afficheur 7 segments.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:Diode.jpg|gauche|vignette|412x412px|Test des LEDs]]&lt;br /&gt;
[[Fichier:TestSD.jpg|vignette|Test de la carte SD]]&lt;br /&gt;
[[Fichier:Video7seg.mp4|vignette|400x400px|Timer sur un afficheur 7 segments|néant]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Schéma de Connexion ===&lt;br /&gt;
Voici notre Schematic Kicad pour le Shield:&lt;br /&gt;
&lt;br /&gt;
[[Fichier:picoshield.pdf|922x922px]]&lt;br /&gt;
&lt;br /&gt;
== Bilan de puissance ==&lt;br /&gt;
Afin de déterminer la puissance consommée par notre carte, et se coordonner avec le binôme s'occupant de la carte mère, nous effectuons un bilan de puissance. Pour chaque composant nous nous sommes référés à leur datasheets :  &lt;br /&gt;
&lt;br /&gt;
* HD44780 : '''150 µA''' ([https://www.sparkfun.com/datasheets/LCD/HD44780.pdf datasheet])&lt;br /&gt;
* Ecran LCD 2x16 : '''1,2 mA''' ([https://docs.rs-online.com/d50a/0900766b8127cd1d.pdf datasheet])&lt;br /&gt;
* LED de Test : 1,7/510 = 3 mA  donc comme nous en avons 2 on a besoin de '''6 mA''' &lt;br /&gt;
* Atmega : '''14 mA''' ([https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf datasheet])&lt;br /&gt;
* FRAM25 : '''2 mA ('''[https://docs.rs-online.com/e062/A700000007893278.pdf datasheet])&lt;br /&gt;
* MUX CD405 : '''10 mA''' ([https://www.ti.com/lit/ds/symlink/cd4051b.pdf datasheet])&lt;br /&gt;
&lt;br /&gt;
Au total, notre carte consommera '''0,17 W'''.&lt;br /&gt;
== Tests Réalisés ==&lt;br /&gt;
&lt;br /&gt;
=== Tests de l'Ordonnanceur ===&lt;br /&gt;
* Gestion des tâches : Nous avons simulé plusieurs tâches, dont l'affichage et la gestion du clavier, et vérifié que l'ordonnanceur passe correctement d'une tâche à l'autre.&lt;br /&gt;
* En utilisant le logiciel minicom nous avons pus lancer une 2eme tâche en parallèle d'une première tâche. En tapant &amp;quot;a&amp;quot; une deuxième LED se met à clignoter.&lt;br /&gt;
[[Fichier:Videoprocess.mp4|centré|vignette|400x300px|Test de l'ordonnanceur : lancer une tâche. ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Pour tester la connexion série du Shield avec le 7 segment on utilise l'outil Minicom de nouveau afin de faire apparaitre un caractère sur le 7 segment. Pour cela on utilise la fonction Serial Message tout en modifiant le reste du code en conséquence :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void Serial_Message(){ //lecture, ecriture port serie et ecriture sur 7 Seg&lt;br /&gt;
    unsigned char data;&lt;br /&gt;
    spi_display_cmd1(0x76);&lt;br /&gt;
    _delay_ms(100);&lt;br /&gt;
    while(1){&lt;br /&gt;
        data = USART_Receive();&lt;br /&gt;
        if (data &amp;gt;= '0' &amp;amp;&amp;amp; data &amp;lt;= '9') {&lt;br /&gt;
            spi_display_data(data, '0', '0', '0');&lt;br /&gt;
        }&lt;br /&gt;
        USART_Transmit(data);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;En utilisant cette fonction nous avons pu afficher un caractère. Cependant nous avons remarquer un retard lors de l'affichage du caractère. Nous avons essayer plusieurs méthode comme sectionner ce que l'on voulait faire en 3 taches mais cela n'a pas fonctionner. Apres longues observation de l'exécution de notre programme, nous avons vu que nous pouvions taper nos caractères sur Minicom, mais l'écran LCD ne se mettait a jour seulement lorsque la LED2 était allumée. Cela montre que le problème était que la LED puisqu'elle était connectée au pin CS. Le fait de la faire clignoter empêchait l'affichage. Apres correction (la LED2 devait rester allumée) :     &lt;br /&gt;
[[Fichier:Fin Ordonnanceur 7 Segment.mp4|centré|vignette|400x300px|7 segment et minicom]]&lt;br /&gt;
&lt;br /&gt;
== Tests de la RAM SPI ==&lt;br /&gt;
&lt;br /&gt;
Pour tester la mémoire RAM SPI, plusieurs étapes ont été mises en œuvre pour garantir la bonne communication et la gestion des données. Voici les principales actions réalisées :&lt;br /&gt;
&lt;br /&gt;
=== Fonctions de gestion de l'accès à la RAM ===&lt;br /&gt;
* Les fonctions &amp;lt;code&amp;gt;ram_select&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;ram_deselect&amp;lt;/code&amp;gt; ont été ajoutées pour assurer un accès exclusif à la mémoire :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void ram_select() {&lt;br /&gt;
    SPI_PORT &amp;amp;= ~(1 &amp;lt;&amp;lt; SPI_SS); // Sélectionne la RAM&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void ram_deselect() {&lt;br /&gt;
    SPI_PORT |= (1 &amp;lt;&amp;lt; SPI_SS); // Désélectionne la RAM&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Les fonctions &amp;lt;code&amp;gt;select_microcontroller&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;select_shield&amp;lt;/code&amp;gt; ont été introduites pour basculer entre le Microcontrôleur et le Shield :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void select_microcontroller() {&lt;br /&gt;
    PORTC |= (1 &amp;lt;&amp;lt; DATA0); // Active le microcontrôleur&lt;br /&gt;
    _delay_ms(1);         // Temps de stabilisation&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void select_shield() {&lt;br /&gt;
    PORTC &amp;amp;= ~(1 &amp;lt;&amp;lt; DATA0); // Active le Shield&lt;br /&gt;
    _delay_ms(1);          // Temps de stabilisation&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Opérations de base sur la RAM ===&lt;br /&gt;
* Lecture (&amp;lt;code&amp;gt;RAM_read&amp;lt;/code&amp;gt;), écriture (&amp;lt;code&amp;gt;RAM_write&amp;lt;/code&amp;gt;), et effacement (&amp;lt;code&amp;gt;RAM_clear&amp;lt;/code&amp;gt;) ont été implémentés pour interagir avec la mémoire via le bus SPI.&lt;br /&gt;
* Exemple d'écriture :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void RAM_write(uint16_t address, char *data) {&lt;br /&gt;
    RAM_write_enable();&lt;br /&gt;
    CS_LOW();&lt;br /&gt;
    spi_exch(WRITE);&lt;br /&gt;
    spi_exch((address &amp;gt;&amp;gt; 8) &amp;amp; 0xFF);&lt;br /&gt;
    spi_exch(address &amp;amp; 0xFF);&lt;br /&gt;
    for (uint8_t i = 0; i &amp;lt; strlen(data); i++) {&lt;br /&gt;
        spi_exch(data[i]);&lt;br /&gt;
    }&lt;br /&gt;
    RAM_write_disable();&lt;br /&gt;
    CS_HIGH();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Exemple de lecture :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void RAM_read(uint16_t address, char *buffer, uint8_t length) {&lt;br /&gt;
    CS_LOW();&lt;br /&gt;
    spi_exch(READ);&lt;br /&gt;
    spi_exch((address &amp;gt;&amp;gt; 8) &amp;amp; 0xFF);&lt;br /&gt;
    spi_exch(address &amp;amp; 0xFF);&lt;br /&gt;
    for (uint8_t i = 0; i &amp;lt; length; i++) {&lt;br /&gt;
        buffer[i] = spi_exch(0x00);&lt;br /&gt;
    }&lt;br /&gt;
    buffer[length] = '\0';&lt;br /&gt;
    CS_HIGH();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Validation des fonctionnalités ===&lt;br /&gt;
* Un test basique avec des données simples a été effectué pour vérifier que les données écrites pouvaient être lues sans erreur.&lt;br /&gt;
* Un test de stress par brute force a été réalisé pour écrire et lire des données massivement tout en affichant les résultats avec un &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt;. Cela a permis de confirmer la robustesse du système.&lt;br /&gt;
&lt;br /&gt;
=== Résultat des tests ===&lt;br /&gt;
* Le premier test (illustré dans l'image ci-dessous) montre que la RAM SPI fonctionne correctement, avec des données transmises et récupérées sans perte. Cependant, on remarque l'apparition de différents symboles avant notre message affiché depuis la RAM. On a donc émis deux hypothèses : =&amp;gt; Il existe des zones mémoire de la RAM qui contient des données ne pouvant être modifiées et ce sont ces données là que nous lisons avant notre message. =&amp;gt; Notre fonction pour clear la RAM avec des '0' n'est pas bien fonctionnelle. Avec une lecture plus approfondie de la datasheet, il n'est fait nulle part mention d' &amp;quot;une zone interdite&amp;quot; ou quelque chose qui pourrait s'en rapprocher. C'est pourquoi on pense que notre seconde hypothèse est la plus probable malgré une fonction qui, au premier regard, semble correcte. &lt;br /&gt;
[[Fichier:Ram fonctionne.png|centré|vignette|527x527px|La RAM fonctionne]]&lt;br /&gt;
* Dans une tentative de faire disparaître ces symboles non désirés, nous avons essayé une commande printf de dernier espoir (&amp;quot;Printf ici&amp;quot;). A notre grande surprise, le message de cette commande était directement affiché sur notre écran. Nous avons donc fait des recherches sur ce sujet et il semblerait qu'initialement, il aurait fallu réalisé une fonction de redirection de flux afin de pouvoir visualiser le contenu du print. Or nous n'avons rien réalisé de tel. D'après ce que nous avons trouvé sur Internet, certains dispositif tel que des boards Arduino ou autres, ont directement une fonction de redirection de flux d'implémentée.  Nous soupçonnons donc le programmateur ou le microcontrôleur utilisé d'en avoir une également. [[Fichier:Printf.jpg|centré|vignette]]&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
=== Tests de la RAM SPI ===&lt;br /&gt;
La mémoire RAM SPI ne fonctionne pas encore comme prévu avec notamment ces caractères non souhaités. &lt;br /&gt;
&lt;br /&gt;
Malgré nos efforts, nous avons remarqué une chute de tension significative de 1,5 V entre le Shield et la carte écran. Cette chute pourrait expliquer les dysfonctionnements observés dans la communication SPI. Bien que la carte écran fonctionne correctement lorsqu’elle est utilisée seule, elle ne parvient pas à établir une communication via le Shield. Cependant, les différentes étapes de conception et de test nous semblent alignées, et nous pensons être sur la bonne voie pour résoudre ce problème.&lt;br /&gt;
&lt;br /&gt;
=== Ordonnanceur et Gestion des Tâches ===&lt;br /&gt;
Concernant l’ordonnanceur, toutes les consignes ont été respectées et implémentées avec succès. Le scheduler suit une approche Round-Robin efficace pour gérer les tâches concurrentes. Grâce aux interruptions et à une gestion des délais non bloquants, il permet une répartition optimale du temps CPU entre les tâches, tout en garantissant une bonne réponse pour les processus critiques. Les tests ont validé le bon fonctionnement des différentes tâches, comme la gestion des LEDs, la communication série et l’affichage.&lt;br /&gt;
&lt;br /&gt;
=== Pistes d’amélioration ===&lt;br /&gt;
Pour améliorer le fonctionnement global et résoudre les problèmes liés au SPI, voici quelques pistes à explorer :&lt;br /&gt;
* Identifier la ou les causes de la chute de tension entre le Shield et la carte écran, éventuellement en vérifiant les connexions, la qualité des câbles ou l’alimentation.&lt;br /&gt;
* Tester la communication SPI avec d'autres configurations ou composants pour valider chaque élément individuellement.&lt;br /&gt;
&lt;br /&gt;
En résumé, bien que des défis restent à résoudre pour la partie SPI, nous avons validé l’ensemble des fonctionnalités de l’ordonnanceur. Nous sommes confiants que les ajustements proposés nous permettront d’obtenir un système pleinement fonctionnel.&lt;/div&gt;</summary>
		<author><name>Mbarret</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-2&amp;diff=6957</id>
		<title>SE4Binome2024-2</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-2&amp;diff=6957"/>
		<updated>2024-12-16T12:08:09Z</updated>

		<summary type="html">&lt;p&gt;Mbarret : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Pico Ordinateur =&lt;br /&gt;
Ce projet vise à concevoir un pico ordinateur divisé en plusieurs parties, réalisées par différents binômes. Le rôle de notre binôme est de développer une carte fille équipée d'un microcontrôleur ATMega328p et d'un écran LCD contrôlé par un HD44780, en plus de la conception d'un Shield et d'un ordonnanceur. Cette carte sera connectée à une carte mère via un connecteur HE10 et devra gérer l'affichage de caractères ASCII, ainsi que quelques commandes spécifiques VT100. De plus, nous ajouterons une RAM SPI pour améliorer les performances de gestion de l'affichage.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Lien du git : https://gitea.plil.fr/mbarret/pico_kaoutar_maxime&lt;br /&gt;
&lt;br /&gt;
== Carte Fille (Écran LCD) ==&lt;br /&gt;
&lt;br /&gt;
=== Description ===&lt;br /&gt;
La carte fille que nous avons développée contient les éléments suivants :&lt;br /&gt;
&lt;br /&gt;
* Un microcontrôleur '''ATMega328p''' pour la gestion de l'affichage.&lt;br /&gt;
* Un écran '''LCD avec contrôleur HD44780''' pour l'affichage de caractères ASCII.&lt;br /&gt;
* Un '''potentiomètre 3310P''' pour ajuster la luminosité des cristaux liquides de l'écran.&lt;br /&gt;
* Un '''connecteur HE10''' pour relier la carte fille à la carte mère.&lt;br /&gt;
* Un '''connecteur AVR ISP''' pour la programmation du microcontrôleur.&lt;br /&gt;
* Une '''RAM SP'''I (e.g. FM24C04B-GTR) pour stocker temporairement les données d'affichage.&lt;br /&gt;
&lt;br /&gt;
=== Fonctionnalités Demandées ===&lt;br /&gt;
&lt;br /&gt;
* Gestion de l'écran LCD : Le microcontrôleur doit gérer les écrans HD44780 avec 1, 2, 3 ou 4 lignes et afficher des caractères ASCII.&lt;br /&gt;
* Saut de ligne et retour chariot : Les caractères spéciaux `\n` et `\r` doivent être pris en compte.&lt;br /&gt;
* Commandes VT100 : Quelques codes VT100, notamment ceux pour le déplacement du curseur, doivent être supportés.&lt;br /&gt;
* Défilement automatique : Le contrôleur HD44780 doit être configuré pour activer le mode de défilement automatique.&lt;br /&gt;
* Connexion SPI : La carte mère doit envoyer les commandes via SPI. Le premier octet envoyé doit être le code commande `0x01`, suivi des caractères à afficher.&lt;br /&gt;
* Vérification de la disponibilité de l'écran : La carte fille met la ligne SPI en état haut lorsque l'affichage est en cours. La carte mère doit attendre que l'état soit bas avant de transmettre de nouvelles données, ou envoyer des commandes `0xFF` pour vérifier si l'écran est prêt.&lt;br /&gt;
&lt;br /&gt;
=== Ajout d'une RAM SPI ===&lt;br /&gt;
Pour complexifier la carte fille, nous ajouterons une RAM SPI (e.g. FM24C04B-GTR). Cette mémoire permet de stocker temporairement les caractères reçus par SPI avant leur affichage. Le microcontrôleur de la carte fille rafraîchit régulièrement l'écran en lisant les données de la RAM, ce qui améliore la fluidité de l'affichage et permet de libérer la carte mère plus rapidement.&lt;br /&gt;
&lt;br /&gt;
Nous avons choisi la RAM FM25W256-G disponible chez RS Component.&lt;br /&gt;
https://fr.rs-online.com/web/p/memoires-fram/1254228?gb=s&lt;br /&gt;
&lt;br /&gt;
Voici un schéma simplifié de la communication entre les composants :&lt;br /&gt;
* La carte mère écrit dans la RAM SPI via le bus SPI.&lt;br /&gt;
* Le microcontrôleur de la carte fille lit les données de la RAM SPI et les envoie à l'écran LCD pour mise à jour régulière.&lt;br /&gt;
&lt;br /&gt;
=== Schéma de Connexion ===&lt;br /&gt;
[[Fichier:carteEcran.pdf|922x922px]]&lt;br /&gt;
&lt;br /&gt;
=== Ajout de sélecteurs ===&lt;br /&gt;
Ajouter des sélecteurs permet de choisir entre le microprocesseur et la connexion SPI venant de la carte mère. Pour cela, nous avons fait une simulation sur LTSpice. Voici le schéma et sa simulation : &lt;br /&gt;
[[Fichier:Circuit de simulation.png|gauche|vignette|577x577px]]&lt;br /&gt;
[[Fichier:Simulation.png|néant|vignette|501x501px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
La fonction PULSE nous permet de simuler le SELECT. Nous avons pris des modèles de transistors déjà sur le logiciel pour pouvoir simuler. &lt;br /&gt;
&lt;br /&gt;
On remarque que, sur la simulation, un des transistors PMOS est inversee. Quand un des PMOS est passant, l'autre est bloquant. Cette simulation nous permet de valider notre sélecteur pour notre carte écran. Nous avons reproduit ce schéma dans Kicad.&lt;br /&gt;
&lt;br /&gt;
=== Carte écran soudée ===&lt;br /&gt;
Nous avons terminé de souder complétement notre carte et il est temps de la tester. Pour vérifier le bon fonctionnement de notre travail, nous utiliserons un code test dédié à notre écran HD44780 fournis par la librairie du même nom sur l'IDE Arduino. Cette méthode de test nous convient parfaitement puisque nous voulons uniquement vérifier son fonctionnement. &lt;br /&gt;
&lt;br /&gt;
Malheureusement, le code ne fonctionne pas directement à cause de mauvais branchement sur notre connecteur. On avait relié directement les pins  Enable, et RS du connecteur écran à notre 5V.  Nous avons du alors faire du bricolage pour la réparer. Pour ce faire, nous avons donc coupé les piste du RS et Enable pour les relier à des pins non utilisés du microcontrôleur. &lt;br /&gt;
&lt;br /&gt;
[PHOTO] &lt;br /&gt;
&lt;br /&gt;
Après ces réparations, on arrive à afficher le texte voulu grâce au code d'exemple Arduino : &lt;br /&gt;
&lt;br /&gt;
[PHOTO] &lt;br /&gt;
&lt;br /&gt;
Il nous faut désormais tester notre carte écran en code C. Pour ce faire, nous avons récupéré le code des Masters I2L et mis à jour les fuses de l'atmega328p. Cependant  lors de l'upload du code, notre Atmega n'est plus détecté. Nous devons alors vérifier la clock par le biais d'un oscilloscope. &lt;br /&gt;
== Ordonnanceur et Gestion du Contexte des Tâches ==&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
L'ordonnanceur est un composant clé de notre pico-ordinateur, assurant la gestion et l'exécution ordonnée des différentes tâches. Il permet un partage équitable du temps processeur grâce à un algorithme de round-robin. De plus, il vérifie la disponibilité des ressources matérielles, comme les lignes SPI et les périphériques LED.&lt;br /&gt;
&lt;br /&gt;
La gestion du contexte des tâches est assurée par des macros de sauvegarde (`SAVE_REGISTERS`) et de restauration (`RESTORE_REGISTERS`) des registres, permettant ainsi d'interrompre et de reprendre l'exécution de chaque tâche.&lt;br /&gt;
&lt;br /&gt;
=== Structure des Tâches ===&lt;br /&gt;
&lt;br /&gt;
Chaque tâche est représentée par la structure `process` :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
typedef struct process {&lt;br /&gt;
    uint16_t stackPointer; // Adresse du pointeur de pile, définissant le contexte de la tâche&lt;br /&gt;
    void (*addressFunction)(void); // Adresse de la fonction à exécuter&lt;br /&gt;
    int state; // État de la tâche (0 = prête, 1 = en cours, 2 = terminée)&lt;br /&gt;
} process;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dans ce programme, `stackPointer` stocke la position de la pile de chaque tâche, `addressFunction` est un pointeur vers la fonction de la tâche, et `state` représente l’état actuel de la tâche.&lt;br /&gt;
&lt;br /&gt;
=== Initialisation des Tâches ===&lt;br /&gt;
&lt;br /&gt;
Les tâches sont initialisées dans le tableau `task`, contenant des fonctions telles que `Serial_Led`, `LED1_blink`, et `Serial_Message`, chacune avec son pointeur de pile initial :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
process task[NB_TASKS] = {&lt;br /&gt;
    {0x700, Serial_Led, 0},&lt;br /&gt;
    {0x600, LED1_blink, 0},&lt;br /&gt;
    {0x500, Serial_Message, 0}&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Macros de Sauvegarde et Restauration des Registres ===&lt;br /&gt;
&lt;br /&gt;
Les macros `SAVE_REGISTERS()` et `RESTORE_REGISTERS()` permettent de sauvegarder et de restaurer les registres lors du changement de tâche :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define RESTORE_REGISTERS() \&lt;br /&gt;
asm volatile ( \&lt;br /&gt;
    /* Code pour restaurer les registres ici */ \&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
#define SAVE_REGISTERS() \&lt;br /&gt;
asm volatile ( \&lt;br /&gt;
    /* Code pour sauvegarder les registres ici */ \&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ces macros utilisent des instructions d’assembleur pour pousser et dépiler les registres, préservant ainsi l’état complet de la tâche au moment de l'interruption.&lt;br /&gt;
&lt;br /&gt;
=== Ordonnancement des Tâches ===&lt;br /&gt;
&lt;br /&gt;
L'ordonnanceur suit l'algorithme round-robin. La fonction `scheduler()` passe d'une tâche à la suivante dans le tableau `task` :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void scheduler() {&lt;br /&gt;
    currentTask++;&lt;br /&gt;
    if (currentTask == NB_TASKS) currentTask = 0; // Retour à la première tâche après la dernière&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Gestion des Interruptions ===&lt;br /&gt;
&lt;br /&gt;
L'interruption liée au minuteur (`TIMER1_COMPA_vect`) déclenche l'ordonnanceur et le changement de tâche, en sauvegardant et restaurant le contexte :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
ISR(TIMER1_COMPA_vect, ISR_NAKED) {&lt;br /&gt;
    SAVE_REGISTERS();&lt;br /&gt;
    task[currentTask].stackPointer = SP;&lt;br /&gt;
    scheduler();&lt;br /&gt;
    SP = task[currentTask].stackPointer;&lt;br /&gt;
    RESTORE_REGISTERS();&lt;br /&gt;
    asm volatile(&amp;quot;reti&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* `SAVE_REGISTERS()` : sauvegarde le contexte de la tâche courante.&lt;br /&gt;
* `scheduler()` : passe à la tâche suivante.&lt;br /&gt;
* `RESTORE_REGISTERS()` : restaure le contexte de la nouvelle tâche.&lt;br /&gt;
* `asm volatile(&amp;quot;reti&amp;quot;);` : retourne de l'interruption en restaurant l'état.&lt;br /&gt;
&lt;br /&gt;
=== Initialisation du Système ===&lt;br /&gt;
&lt;br /&gt;
Les fonctions d'initialisation préparent les ressources, telles que les LED et l'UART, pour la communication série.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void LED_init() {&lt;br /&gt;
    DDRC |= (1&amp;lt;&amp;lt;LED1) | (1&amp;lt;&amp;lt;LED2);&lt;br /&gt;
    DDRD |= (1&amp;lt;&amp;lt;LED3) | (1&amp;lt;&amp;lt;LED4) | (1&amp;lt;&amp;lt;LED5);&lt;br /&gt;
    PORTC |= (1&amp;lt;&amp;lt;LED1) | (1&amp;lt;&amp;lt;LED2);&lt;br /&gt;
    PORTD |= (1&amp;lt;&amp;lt;LED3) | (1&amp;lt;&amp;lt;LED4) | (1&amp;lt;&amp;lt;LED5);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Fonctions des Tâches ===&lt;br /&gt;
&lt;br /&gt;
Chaque tâche a une fonction dédiée. Par exemple, `LED1_blink` fait clignoter une LED, et `Serial_Message` envoie des messages en série.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void LED1_blink() {&lt;br /&gt;
    while(1) {&lt;br /&gt;
        PORTC ^= (1&amp;lt;&amp;lt;LED1);&lt;br /&gt;
        _delay_ms(150);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ces fonctions sont répétitives pour les autres LED, avec des délais différents pour créer des clignotements variés.&lt;br /&gt;
&lt;br /&gt;
=== Communication Série ===&lt;br /&gt;
&lt;br /&gt;
L'initialisation de l'UART et les fonctions de réception et de transmission sont définies pour permettre la communication série :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void USART_Init(unsigned int ubrr) {&lt;br /&gt;
    UBRR0H = (unsigned char)(ubrr&amp;gt;&amp;gt;8);&lt;br /&gt;
    UBRR0L = (unsigned char)ubrr;&lt;br /&gt;
    UCSR0B = (1&amp;lt;&amp;lt;RXEN0) | (1&amp;lt;&amp;lt;TXEN0);&lt;br /&gt;
    UCSR0C = (1&amp;lt;&amp;lt;USBS0) | (3&amp;lt;&amp;lt;UCSZ00);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
unsigned char USART_Receive(void) {&lt;br /&gt;
    while (!(UCSR0A &amp;amp; (1&amp;lt;&amp;lt;RXC0)));&lt;br /&gt;
    return UDR0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Fonction `main` ===&lt;br /&gt;
&lt;br /&gt;
La fonction `main` configure les LED, l'UART, et initialise l'ordonnanceur avant de lancer la première tâche :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int main(void) {&lt;br /&gt;
    cli();&lt;br /&gt;
    LED_init();&lt;br /&gt;
    USART_Init(MYUBRR);&lt;br /&gt;
    init_minuteur(256, PERIODE);&lt;br /&gt;
    for(int i = 1; i &amp;lt; NB_TASKS; i++) init_pile(i);&lt;br /&gt;
    SP = task[0].stackPointer;&lt;br /&gt;
    sei();&lt;br /&gt;
    task[0].addressFunction();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. `cli()` : désactive les interruptions.&lt;br /&gt;
2. `LED_init()` et `USART_Init()` : initialisent les LED et la communication série.&lt;br /&gt;
3. `init_minuteur()` : initialise le minuteur avec une période.&lt;br /&gt;
4. `init_pile(i)` : initialise la pile pour chaque tâche.&lt;br /&gt;
5. `sei()` : réactive les interruptions.&lt;br /&gt;
&lt;br /&gt;
L'ordonnanceur gère ainsi le contexte des tâches en suivant une séquence de round-robin, tout en assurant que chaque tâche exécute son cycle de manière autonome et en garantissant la disponibilité des ressources matérielles.&lt;br /&gt;
&lt;br /&gt;
=== Fonction `wait()` ===&lt;br /&gt;
Comme première amélioration de votre ordonnanceur, il nous a été demandé de mettre en place un état endormi pour nos processus. Pour cela nous avons creer la procedure wait() suivante :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void wait(int time_ms){&lt;br /&gt;
    task[currentTask].state = SLEEP;&lt;br /&gt;
    task[currentTask].sleeping_time = time_ms;&lt;br /&gt;
    TCNT1 = 0;&lt;br /&gt;
    TIMER1_COMPA_vect();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;On modifie aussi les procedures des LED :&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void LED1_blink(){&lt;br /&gt;
    while(1){&lt;br /&gt;
        PORTC ^= (1&amp;lt;&amp;lt;LED1);&lt;br /&gt;
        _delay_ms(200);&lt;br /&gt;
        wait(5000);&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Et la structure :&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
typedef struct{&lt;br /&gt;
    uint16_t stackPointer; // stack pointer, défini le début du process&lt;br /&gt;
    void (*addressFunction)(void); // adresse de l'instruction en cours&lt;br /&gt;
    int state; // état de la fonction (Awake ou Idle)&lt;br /&gt;
    int sleeping_time;&lt;br /&gt;
}process;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;En faisant cela dès qu'une tâche est appelée en présence d'un wait on met à jour son état ainsi que son temps d'attente. Par la suite, on modifie le scheduler() pour réveiller les tâches endormies si nécessaire : &amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void scheduler (){&lt;br /&gt;
  for(int i=0;i&amp;lt;NB_TASKS;i++){&lt;br /&gt;
    if(task[i].state==SLEEP){&lt;br /&gt;
        task[i].sleeping_time -= REDUCE_TIME;&lt;br /&gt;
        if(task[i].sleeping_time &amp;lt;= 0){&lt;br /&gt;
            task[i].sleeping_time = 0;&lt;br /&gt;
            task[i].state = AWAKE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
do{&lt;br /&gt;
  currentTask ++;&lt;br /&gt;
  if(currentTask &amp;gt;= NB_TASKS) currentTask = 0; // ordonnanceur en mode Round Robin&lt;br /&gt;
  }while(task[currentTask].state == SLEEP);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Avec ces modifications nous avons réussi à obtenir le résultat suivant : &lt;br /&gt;
[[Fichier:Wait.mp4|néant|vignette]]&lt;br /&gt;
&lt;br /&gt;
Nous avons eu un problème avec la LED rouge. En effet, apres de tres nombreuses tentatives, nous n'avions pas reussi a la faire clignoter. Nous avons abordé plusieurs methode pour débugger notre code comme manipuler la LED rouge seule. C'est plus tard que nous avons compris que le problème venait de l'utilisation du pin PD1 de notre carte. Le pin PD1 peut aussi être utilisé pour gérer la connexion RX. Ainsi, quand nous voulions utiliser l'instruction &amp;lt;code&amp;gt;USART_Init(MYUBRR);&amp;lt;/code&amp;gt; cela ne permettait pas de faire clignoter la LED. Cette LED sera donc inutilisée dans la suite du projet si nous utilisons l'UART.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Wait2.mp4|néant|vignette|300x300px]]&lt;br /&gt;
&lt;br /&gt;
== Carte Shield ==&lt;br /&gt;
&lt;br /&gt;
=== Description ===&lt;br /&gt;
La carte Shield est une carte mère qui sert à connecter et contrôler divers périphériques, notamment la carte fille (écran), un clavier, et d'autres composants. Nous avons conçu cette carte pour faciliter la gestion des communications SPI entre la carte mère et les différentes cartes filles.&lt;br /&gt;
&lt;br /&gt;
=== Connectivité SPI ===&lt;br /&gt;
La carte Shield utilise plusieurs lignes SPI pour communiquer avec les cartes filles. Chaque périphérique, comme l'écran, est assigné à une ligne SPI spécifique. La carte Shield vérifie également la disponibilité des périphériques avant d'envoyer des commandes via SPI. Nous avons effectué plusieurs test afin de vérifier le bon fonctionnement de notre carte Shield. Nous avons tester le fonctionnement des LED, la connectivité de la carte SD, et nous avons utiliser le Shield pour faire un timer sur un afficheur 7 segments.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:Diode.jpg|gauche|vignette|412x412px|Test des LEDs]]&lt;br /&gt;
[[Fichier:TestSD.jpg|vignette|Test de la carte SD]]&lt;br /&gt;
[[Fichier:Video7seg.mp4|vignette|400x400px|Timer sur un afficheur 7 segments|néant]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
=== Schéma de Connexion ===&lt;br /&gt;
Voici notre Schematic Kicad pour le Shield:&lt;br /&gt;
&lt;br /&gt;
[[Fichier:picoshield.pdf|922x922px]]&lt;br /&gt;
&lt;br /&gt;
== Bilan de puissance ==&lt;br /&gt;
Afin de déterminer la puissance consommée par notre carte, et se coordonner avec le binôme s'occupant de la carte mère, nous effectuons un bilan de puissance. Pour chaque composant nous nous sommes référés à leur datasheets :  &lt;br /&gt;
&lt;br /&gt;
* HD44780 : '''150 µA''' ([https://www.sparkfun.com/datasheets/LCD/HD44780.pdf datasheet])&lt;br /&gt;
* Ecran LCD 2x16 : '''1,2 mA''' ([https://docs.rs-online.com/d50a/0900766b8127cd1d.pdf datasheet])&lt;br /&gt;
* LED de Test : 1,7/510 = 3 mA  donc comme nous en avons 2 on a besoin de '''6 mA''' &lt;br /&gt;
* Atmega : '''14 mA''' ([https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf datasheet])&lt;br /&gt;
* FRAM25 : '''2 mA ('''[https://docs.rs-online.com/e062/A700000007893278.pdf datasheet])&lt;br /&gt;
* MUX CD405 : '''10 mA''' ([https://www.ti.com/lit/ds/symlink/cd4051b.pdf datasheet])&lt;br /&gt;
&lt;br /&gt;
Au total, notre carte consommera '''0,17 W'''.&lt;br /&gt;
== Tests Réalisés ==&lt;br /&gt;
&lt;br /&gt;
=== Tests de l'Ordonnanceur ===&lt;br /&gt;
* Gestion des tâches : Nous avons simulé plusieurs tâches, dont l'affichage et la gestion du clavier, et vérifié que l'ordonnanceur passe correctement d'une tâche à l'autre.&lt;br /&gt;
* En utilisant le logiciel minicom nous avons pus lancer une 2eme tâche en parallèle d'une première tâche. En tapant &amp;quot;a&amp;quot; une deuxième LED se met à clignoter.&lt;br /&gt;
[[Fichier:Videoprocess.mp4|centré|vignette|400x300px|Test de l'ordonnanceur : lancer une tâche. ]]&lt;br /&gt;
&lt;br /&gt;
=== Tests de la RAM SPI //a completer ===&lt;br /&gt;
* Stockage des données&lt;/div&gt;</summary>
		<author><name>Mbarret</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-2&amp;diff=6516</id>
		<title>SE4Binome2024-2</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-2&amp;diff=6516"/>
		<updated>2024-11-07T19:46:47Z</updated>

		<summary type="html">&lt;p&gt;Mbarret : /* Pico Ordinateur */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Pico Ordinateur =&lt;br /&gt;
Ce projet vise à concevoir un pico ordinateur divisé en plusieurs parties, réalisées par différents binômes. Le rôle de notre binôme est de développer une carte fille équipée d'un microcontrôleur ATMega328p et d'un écran LCD contrôlé par un HD44780, en plus de la conception d'un Shield et d'un ordonnanceur. Cette carte sera connectée à une carte mère via un connecteur HE10 et devra gérer l'affichage de caractères ASCII, ainsi que quelques commandes spécifiques VT100. De plus, nous ajouterons une RAM SPI pour améliorer les performances de gestion de l'affichage.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Lien du git : https://gitea.plil.fr/mbarret/pico_kaoutar_maxime&lt;br /&gt;
&lt;br /&gt;
== Carte Fille (Écran LCD) ==&lt;br /&gt;
&lt;br /&gt;
=== Description ===&lt;br /&gt;
La carte fille que nous avons développée contient les éléments suivants :&lt;br /&gt;
&lt;br /&gt;
* Un microcontrôleur '''ATMega328p''' pour la gestion de l'affichage.&lt;br /&gt;
* Un écran '''LCD avec contrôleur HD44780''' pour l'affichage de caractères ASCII.&lt;br /&gt;
* Un '''potentiomètre 3310P''' pour ajuster la luminosité des cristaux liquides de l'écran.&lt;br /&gt;
* Un '''connecteur HE10''' pour relier la carte fille à la carte mère.&lt;br /&gt;
* Un '''connecteur AVR ISP''' pour la programmation du microcontrôleur.&lt;br /&gt;
* Une '''RAM SP'''I (e.g. FM24C04B-GTR) pour stocker temporairement les données d'affichage.&lt;br /&gt;
&lt;br /&gt;
=== Fonctionnalités Demandées ===&lt;br /&gt;
&lt;br /&gt;
* Gestion de l'écran LCD : Le microcontrôleur doit gérer les écrans HD44780 avec 1, 2, 3 ou 4 lignes et afficher des caractères ASCII.&lt;br /&gt;
* Saut de ligne et retour chariot : Les caractères spéciaux `\n` et `\r` doivent être pris en compte.&lt;br /&gt;
* Commandes VT100 : Quelques codes VT100, notamment ceux pour le déplacement du curseur, doivent être supportés.&lt;br /&gt;
* Défilement automatique : Le contrôleur HD44780 doit être configuré pour activer le mode de défilement automatique.&lt;br /&gt;
* Connexion SPI : La carte mère doit envoyer les commandes via SPI. Le premier octet envoyé doit être le code commande `0x01`, suivi des caractères à afficher.&lt;br /&gt;
* Vérification de la disponibilité de l'écran : La carte fille met la ligne SPI en état haut lorsque l'affichage est en cours. La carte mère doit attendre que l'état soit bas avant de transmettre de nouvelles données, ou envoyer des commandes `0xFF` pour vérifier si l'écran est prêt.&lt;br /&gt;
&lt;br /&gt;
=== Ajout d'une RAM SPI ===&lt;br /&gt;
Pour complexifier la carte fille, nous ajouterons une RAM SPI (e.g. FM24C04B-GTR). Cette mémoire permet de stocker temporairement les caractères reçus par SPI avant leur affichage. Le microcontrôleur de la carte fille rafraîchit régulièrement l'écran en lisant les données de la RAM, ce qui améliore la fluidité de l'affichage et permet de libérer la carte mère plus rapidement.&lt;br /&gt;
&lt;br /&gt;
Nous avons choisi la RAM FM25W256-G disponible chez RS Component.&lt;br /&gt;
https://fr.rs-online.com/web/p/memoires-fram/1254228?gb=s&lt;br /&gt;
&lt;br /&gt;
Voici un schéma simplifié de la communication entre les composants :&lt;br /&gt;
* La carte mère écrit dans la RAM SPI via le bus SPI.&lt;br /&gt;
* Le microcontrôleur de la carte fille lit les données de la RAM SPI et les envoie à l'écran LCD pour mise à jour régulière.&lt;br /&gt;
&lt;br /&gt;
=== Schéma de Connexion ===&lt;br /&gt;
//capture d'écran à ajouter&lt;br /&gt;
&lt;br /&gt;
=== Ajout de sélecteurs ===&lt;br /&gt;
Ajouter des sélecteurs permet de choisir entre le microprocesseur et la connexion SPI venant de la carte mère. Pour cela, nous avons fait une simulation sur LTSpice. &lt;br /&gt;
&lt;br /&gt;
== Ordonnanceur ==&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
L'ordonnanceur est une partie essentielle de notre pico ordinateur. Il est responsable de la gestion des différentes tâches et de leur exécution de manière organisée. L'objectif de cet ordonnanceur est de permettre un partage équitable du temps processeur entre les tâches et d'assurer que chaque tâche puisse accéder aux ressources du système sans conflit.&lt;br /&gt;
&lt;br /&gt;
L'ordonnanceur prend également en compte la gestion des périphériques, tels que notre écran LCD, en s'assurant que chaque périphérique est disponible avant d'envoyer une nouvelle commande.&lt;br /&gt;
&lt;br /&gt;
=== Structure des Tâches ===&lt;br /&gt;
&lt;br /&gt;
Voici comment chaque tâche est représentée dans le système :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
struct Task {&lt;br /&gt;
    int taskID;             // Identifiant unique de la tâche&lt;br /&gt;
    int spiLine;            // Ligne SPI associée à la tâche (pour gérer un périphérique)&lt;br /&gt;
    bool isReady;           // Indique si la tâche est prête à s'exécuter&lt;br /&gt;
    bool isRunning;         // Indique si la tâche est actuellement en cours d'exécution&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Chaque tâche a un identifiant unique `taskID`, ainsi qu'une ligne SPI (`spiLine`) qui lui est assignée pour la gestion des périphériques. Le champ `isReady` permet de savoir si la tâche est prête à être exécutée (par exemple, si le périphérique SPI est disponible), et `isRunning` indique si la tâche est en cours d'exécution.&lt;br /&gt;
&lt;br /&gt;
=== Fonctions de l'Ordonnanceur ===&lt;br /&gt;
&lt;br /&gt;
L'ordonnanceur est principalement basé sur deux fonctions principales :&lt;br /&gt;
&lt;br /&gt;
1. scheduler() : Gère le changement de tâche en fonction de l'algorithme Round Robin.&lt;br /&gt;
2. spiAvailable() : Vérifie la disponibilité de la ligne SPI avant d'exécuter une tâche.&lt;br /&gt;
&lt;br /&gt;
===== Fonction `scheduler()` =====&lt;br /&gt;
La fonction `scheduler()` est responsable du passage d'une tâche à l'autre en suivant l'algorithme Round Robin. Elle incrémente l'indice de la tâche courante et revient au début de la liste si la dernière tâche a été atteinte.&lt;br /&gt;
&lt;br /&gt;
Voici le code de la fonction `scheduler()` :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void scheduler() {&lt;br /&gt;
    // Incrémentation de l'indice de la tâche courante&lt;br /&gt;
    currentTask++;&lt;br /&gt;
    &lt;br /&gt;
    // Si l'indice dépasse le nombre de tâches, on revient à la première tâche&lt;br /&gt;
    if (currentTask == NB_TASKS) {&lt;br /&gt;
        currentTask = 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Vérifie si la tâche suivante est prête à être exécutée&lt;br /&gt;
    if (taskArray[currentTask].isReady &amp;amp;&amp;amp; spiAvailable(taskArray[currentTask].spiLine)) {&lt;br /&gt;
        // Exécuter la tâche si elle est prête et que la ligne SPI est disponible&lt;br /&gt;
        executeTask(taskArray[currentTask].taskID);&lt;br /&gt;
    } else {&lt;br /&gt;
        // Si la tâche n'est pas prête, passe à la tâche suivante&lt;br /&gt;
        scheduler();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explication du Code :&lt;br /&gt;
* currentTask++ : Cette ligne incrémente l'indice de la tâche courante, passant ainsi à la tâche suivante dans la liste.&lt;br /&gt;
* if (currentTask == NB_TASKS) : Si l'ordonnanceur arrive à la fin de la liste des tâches (déterminée par `NB_TASKS`, le nombre total de tâches), il revient à la première tâche (`currentTask = 0`).&lt;br /&gt;
* taskArray[currentTask].isReady : L'ordonnanceur vérifie si la tâche est prête à être exécutée (en attente d'exécution).&lt;br /&gt;
* spiAvailable(taskArray[currentTask].spiLine) : Cette fonction est appelée pour vérifier si la ligne SPI associée à la tâche est disponible (explication ci-dessous).&lt;br /&gt;
* executeTask() : Si la tâche est prête et que la ligne SPI est libre, cette fonction exécute la tâche courante.&lt;br /&gt;
* scheduler() : Si la tâche n'est pas prête ou si la ligne SPI n'est pas disponible, l'ordonnanceur passe à la tâche suivante.&lt;br /&gt;
&lt;br /&gt;
===== Fonction `spiAvailable()` =====&lt;br /&gt;
La fonction `spiAvailable()` vérifie si la ligne SPI associée à une tâche est libre. Cela permet d'éviter que plusieurs tâches tentent d'utiliser la même ligne SPI en même temps, ce qui pourrait causer des conflits d'accès.&lt;br /&gt;
&lt;br /&gt;
Voici le code de la fonction `spiAvailable()` :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
bool spiAvailable(int spiLine) {&lt;br /&gt;
    // Vérifie l'état de la ligne SPI&lt;br /&gt;
    if (getSpiState(spiLine) == SPI_FREE) {&lt;br /&gt;
        return true;&lt;br /&gt;
    } else {&lt;br /&gt;
        return false;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explication du Code :&lt;br /&gt;
* getSpiState(spiLine) : Cette fonction interroge l'état actuel de la ligne SPI spécifiée (`spiLine`). Si la ligne est libre (`SPI_FREE`), la fonction retourne `true`, sinon elle retourne `false`.&lt;br /&gt;
* return true/false : La fonction retourne `true` si la ligne SPI est disponible, permettant ainsi à la tâche de s'exécuter.&lt;br /&gt;
&lt;br /&gt;
===== Fonction `executeTask()` =====&lt;br /&gt;
La fonction `executeTask()` est celle qui exécute la tâche courante une fois qu'elle est prête et que la ligne SPI est disponible. Cette fonction lance la tâche spécifique en fonction de son `taskID`.&lt;br /&gt;
&lt;br /&gt;
Voici un exemple de la fonction `executeTask()` :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void executeTask(int taskID) {&lt;br /&gt;
    switch (taskID) {&lt;br /&gt;
        case 1:&lt;br /&gt;
            // Exécuter la tâche 1 (affichage sur écran LCD)&lt;br /&gt;
            updateLCD();&lt;br /&gt;
            break;&lt;br /&gt;
        case 2:&lt;br /&gt;
            // Exécuter la tâche 2 (lecture d'un clavier SPI)&lt;br /&gt;
            readKeyboard();&lt;br /&gt;
            break;&lt;br /&gt;
        // Ajout d'autres tâches ici...&lt;br /&gt;
        default:&lt;br /&gt;
            // Si la tâche n'est pas reconnue, ne rien faire&lt;br /&gt;
            break;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explication du Code :&lt;br /&gt;
* switch (taskID) : Cette instruction permet de choisir la tâche à exécuter en fonction de l'ID de la tâche.&lt;br /&gt;
* updateLCD() : Exemple d'une tâche qui met à jour l'affichage de l'écran LCD.&lt;br /&gt;
* readKeyboard() : Exemple d'une tâche qui lit les données d'un clavier SPI.&lt;br /&gt;
* default : Si l'ID de la tâche n'est pas reconnu, aucune action n'est effectuée.&lt;br /&gt;
&lt;br /&gt;
===== Gestion des Interruptions =====&lt;br /&gt;
L'ordonnanceur peut également être interrompu si un événement important survient, comme l'arrivée d'une nouvelle commande ou la fin d'une transmission SPI. Ces interruptions sont gérées via des Interrupt Service Routines (ISR), qui permettent de traiter rapidement ces événements sans interrompre l'ordonnancement global.&lt;br /&gt;
&lt;br /&gt;
Un exemple d'ISR :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
ISR(SPI_vect) {&lt;br /&gt;
    // Gestion de l'interruption SPI&lt;br /&gt;
    if (isTransmissionComplete()) {&lt;br /&gt;
        // Marquer la tâche SPI comme terminée&lt;br /&gt;
        taskArray[currentTask].isReady = true;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explication du Code :&lt;br /&gt;
* ISR(SPI_vect) : Cette fonction est une ISR qui est appelée lorsque l'événement lié au SPI se produit (par exemple, la fin d'une transmission).&lt;br /&gt;
* isTransmissionComplete() : Vérifie si la transmission SPI est terminée.&lt;br /&gt;
* taskArray[currentTask].isReady = true : Marque la tâche comme prête à être exécutée à nouveau.&lt;br /&gt;
L'ordonnanceur joue un rôle central dans notre pico ordinateur, en gérant les tâches et en s'assurant que chaque tâche a accès aux ressources SPI sans conflit. Ce système d'ordonnancement permet d'assurer un fonctionnement fluide et sans interruption de notre pico ordinateur.&lt;br /&gt;
&lt;br /&gt;
== Carte Shield ==&lt;br /&gt;
&lt;br /&gt;
=== Description ===&lt;br /&gt;
La carte Shield est une carte mère qui sert à connecter et contrôler divers périphériques, notamment la carte fille (écran), un clavier, et d'autres composants. Nous avons conçu cette carte pour faciliter la gestion des communications SPI entre la carte mère et les différentes cartes filles.&lt;br /&gt;
&lt;br /&gt;
=== Connectivité SPI ===&lt;br /&gt;
La carte Shield utilise plusieurs lignes SPI pour communiquer avec les cartes filles. Chaque périphérique, comme l'écran, est assigné à une ligne SPI spécifique. La carte Shield vérifie également la disponibilité des périphériques avant d'envoyer des commandes via SPI. Nous avons effectué plusieurs test afin de vérifier le bon fonctionnement de notre carte Shield. Nous avons tester le fonctionnement des LED, la connectivité de la carte SD, et nous avons utiliser le Shield pour faire un timer sur un afficheur 7 segments.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:Diode.jpg|gauche|vignette|412x412px|Test des LEDs]]&lt;br /&gt;
[[Fichier:TestSD.jpg|vignette|Test de la carte SD]]&lt;br /&gt;
[[Fichier:Video7seg.mp4|vignette|400x400px|Timer sur un afficheur 7 segments|néant]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bilan de puissance ==&lt;br /&gt;
Afin de déterminer la puissance consommée par notre carte, et se coordonner avec le binôme s'occupant de la carte mère, nous effectuons un bilan de puissance. Pour chaque composant nous nous sommes référés à leur datasheets :  &lt;br /&gt;
&lt;br /&gt;
* HD44780 : '''150 µA''' ([https://www.sparkfun.com/datasheets/LCD/HD44780.pdf datasheet])&lt;br /&gt;
* Ecran LCD 2x16 : '''1,2 mA''' ([https://docs.rs-online.com/d50a/0900766b8127cd1d.pdf datasheet])&lt;br /&gt;
* LED de Test : 1,7/510 = 3 mA  donc comme nous en avons 2 on a besoin de '''6 mA''' &lt;br /&gt;
* Atmega : '''14 mA''' ([https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf datasheet])&lt;br /&gt;
* FRAM25 : '''2 mA ('''[https://docs.rs-online.com/e062/A700000007893278.pdf datasheet])&lt;br /&gt;
* MUX CD405 : '''10 mA''' ([https://www.ti.com/lit/ds/symlink/cd4051b.pdf datasheet])&lt;br /&gt;
&lt;br /&gt;
Au total, notre carte consommera '''0,17 W'''.&lt;br /&gt;
== Tests Réalisés ==&lt;br /&gt;
&lt;br /&gt;
=== Tests de l'Ordonnanceur ===&lt;br /&gt;
* Gestion des tâches : Nous avons simulé plusieurs tâches, dont l'affichage et la gestion du clavier, et vérifié que l'ordonnanceur passe correctement d'une tâche à l'autre.&lt;br /&gt;
* En utilisant le logiciel minicom nous avons pus lancer une 2eme tâche en parallèle d'une première tâche. En tapant &amp;quot;a&amp;quot; une deuxième LED se met à clignoter.&lt;br /&gt;
[[Fichier:Videoprocess.mp4|centré|vignette|400x300px|Test de l'ordonnanceur : lancer une tâche. ]]&lt;br /&gt;
&lt;br /&gt;
=== Tests de la RAM SPI //a completer ===&lt;br /&gt;
* Stockage des données&lt;/div&gt;</summary>
		<author><name>Mbarret</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-2&amp;diff=6440</id>
		<title>SE4Binome2024-2</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-2&amp;diff=6440"/>
		<updated>2024-10-23T10:19:55Z</updated>

		<summary type="html">&lt;p&gt;Mbarret : /* Bilan de puissances */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Pico Ordinateur =&lt;br /&gt;
Ce projet vise à concevoir un pico ordinateur divisé en plusieurs parties, réalisées par différents binômes. Le rôle de notre binôme est de développer une carte fille équipée d'un microcontrôleur ATMega328p et d'un écran LCD contrôlé par un HD44780, en plus de la conception d'un Shield et d'un ordonnanceur. Cette carte sera connectée à une carte mère via un connecteur HE10 et devra gérer l'affichage de caractères ASCII, ainsi que quelques commandes spécifiques VT100. De plus, nous ajouterons une RAM SPI pour améliorer les performances de gestion de l'affichage.&lt;br /&gt;
&lt;br /&gt;
== Carte Fille (Écran LCD) ==&lt;br /&gt;
&lt;br /&gt;
=== Description ===&lt;br /&gt;
La carte fille que nous avons développée contient les éléments suivants :&lt;br /&gt;
&lt;br /&gt;
* Un microcontrôleur '''ATMega328p''' pour la gestion de l'affichage.&lt;br /&gt;
* Un écran '''LCD avec contrôleur HD44780''' pour l'affichage de caractères ASCII.&lt;br /&gt;
* Un '''potentiomètre 3310P''' pour ajuster la luminosité des cristaux liquides de l'écran.&lt;br /&gt;
* Un '''connecteur HE10''' pour relier la carte fille à la carte mère.&lt;br /&gt;
* Un '''connecteur AVR ISP''' pour la programmation du microcontrôleur.&lt;br /&gt;
* Une '''RAM SP'''I (e.g. FM24C04B-GTR) pour stocker temporairement les données d'affichage.&lt;br /&gt;
&lt;br /&gt;
=== Fonctionnalités Demandées ===&lt;br /&gt;
&lt;br /&gt;
* Gestion de l'écran LCD : Le microcontrôleur doit gérer les écrans HD44780 avec 1, 2, 3 ou 4 lignes et afficher des caractères ASCII.&lt;br /&gt;
* Saut de ligne et retour chariot : Les caractères spéciaux `\n` et `\r` doivent être pris en compte.&lt;br /&gt;
* Commandes VT100 : Quelques codes VT100, notamment ceux pour le déplacement du curseur, doivent être supportés.&lt;br /&gt;
* Défilement automatique : Le contrôleur HD44780 doit être configuré pour activer le mode de défilement automatique.&lt;br /&gt;
* Connexion SPI : La carte mère doit envoyer les commandes via SPI. Le premier octet envoyé doit être le code commande `0x01`, suivi des caractères à afficher.&lt;br /&gt;
* Vérification de la disponibilité de l'écran : La carte fille met la ligne SPI en état haut lorsque l'affichage est en cours. La carte mère doit attendre que l'état soit bas avant de transmettre de nouvelles données, ou envoyer des commandes `0xFF` pour vérifier si l'écran est prêt.&lt;br /&gt;
&lt;br /&gt;
=== Ajout d'une RAM SPI ===&lt;br /&gt;
Pour complexifier la carte fille, nous ajouterons une RAM SPI (e.g. FM24C04B-GTR). Cette mémoire permet de stocker temporairement les caractères reçus par SPI avant leur affichage. Le microcontrôleur de la carte fille rafraîchit régulièrement l'écran en lisant les données de la RAM, ce qui améliore la fluidité de l'affichage et permet de libérer la carte mère plus rapidement.&lt;br /&gt;
&lt;br /&gt;
Nous avons choisi la RAM FM25W256-G disponible chez RS Component.&lt;br /&gt;
https://fr.rs-online.com/web/p/memoires-fram/1254228?gb=s&lt;br /&gt;
&lt;br /&gt;
Voici un schéma simplifié de la communication entre les composants :&lt;br /&gt;
* La carte mère écrit dans la RAM SPI via le bus SPI.&lt;br /&gt;
* Le microcontrôleur de la carte fille lit les données de la RAM SPI et les envoie à l'écran LCD pour mise à jour régulière.&lt;br /&gt;
&lt;br /&gt;
=== Schéma de Connexion ===&lt;br /&gt;
//capture ecran a ajouter&lt;br /&gt;
== Ordonnanceur ==&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
L'ordonnanceur est une partie essentielle de notre pico ordinateur. Il est responsable de la gestion des différentes tâches et de leur exécution de manière organisée. L'objectif de cet ordonnanceur est de permettre un partage équitable du temps processeur entre les tâches et d'assurer que chaque tâche puisse accéder aux ressources du système sans conflit.&lt;br /&gt;
&lt;br /&gt;
L'ordonnanceur prend également en compte la gestion des périphériques, tels que notre écran LCD, en s'assurant que chaque périphérique est disponible avant d'envoyer une nouvelle commande.&lt;br /&gt;
&lt;br /&gt;
=== Structure des Tâches ===&lt;br /&gt;
&lt;br /&gt;
Voici comment chaque tâche est représentée dans le système :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
struct Task {&lt;br /&gt;
    int taskID;             // Identifiant unique de la tâche&lt;br /&gt;
    int spiLine;            // Ligne SPI associée à la tâche (pour gérer un périphérique)&lt;br /&gt;
    bool isReady;           // Indique si la tâche est prête à s'exécuter&lt;br /&gt;
    bool isRunning;         // Indique si la tâche est actuellement en cours d'exécution&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Chaque tâche a un identifiant unique `taskID`, ainsi qu'une ligne SPI (`spiLine`) qui lui est assignée pour la gestion des périphériques. Le champ `isReady` permet de savoir si la tâche est prête à être exécutée (par exemple, si le périphérique SPI est disponible), et `isRunning` indique si la tâche est en cours d'exécution.&lt;br /&gt;
&lt;br /&gt;
=== Fonctions de l'Ordonnanceur ===&lt;br /&gt;
&lt;br /&gt;
L'ordonnanceur est principalement basé sur deux fonctions principales :&lt;br /&gt;
&lt;br /&gt;
1. scheduler() : Gère le changement de tâche en fonction de l'algorithme Round Robin.&lt;br /&gt;
2. spiAvailable() : Vérifie la disponibilité de la ligne SPI avant d'exécuter une tâche.&lt;br /&gt;
&lt;br /&gt;
===== Fonction `scheduler()` =====&lt;br /&gt;
La fonction `scheduler()` est responsable du passage d'une tâche à l'autre en suivant l'algorithme Round Robin. Elle incrémente l'indice de la tâche courante et revient au début de la liste si la dernière tâche a été atteinte.&lt;br /&gt;
&lt;br /&gt;
Voici le code de la fonction `scheduler()` :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void scheduler() {&lt;br /&gt;
    // Incrémentation de l'indice de la tâche courante&lt;br /&gt;
    currentTask++;&lt;br /&gt;
    &lt;br /&gt;
    // Si l'indice dépasse le nombre de tâches, on revient à la première tâche&lt;br /&gt;
    if (currentTask == NB_TASKS) {&lt;br /&gt;
        currentTask = 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Vérifie si la tâche suivante est prête à être exécutée&lt;br /&gt;
    if (taskArray[currentTask].isReady &amp;amp;&amp;amp; spiAvailable(taskArray[currentTask].spiLine)) {&lt;br /&gt;
        // Exécuter la tâche si elle est prête et que la ligne SPI est disponible&lt;br /&gt;
        executeTask(taskArray[currentTask].taskID);&lt;br /&gt;
    } else {&lt;br /&gt;
        // Si la tâche n'est pas prête, passe à la tâche suivante&lt;br /&gt;
        scheduler();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explication du Code :&lt;br /&gt;
* currentTask++ : Cette ligne incrémente l'indice de la tâche courante, passant ainsi à la tâche suivante dans la liste.&lt;br /&gt;
* if (currentTask == NB_TASKS) : Si l'ordonnanceur arrive à la fin de la liste des tâches (déterminée par `NB_TASKS`, le nombre total de tâches), il revient à la première tâche (`currentTask = 0`).&lt;br /&gt;
* taskArray[currentTask].isReady : L'ordonnanceur vérifie si la tâche est prête à être exécutée (en attente d'exécution).&lt;br /&gt;
* spiAvailable(taskArray[currentTask].spiLine) : Cette fonction est appelée pour vérifier si la ligne SPI associée à la tâche est disponible (explication ci-dessous).&lt;br /&gt;
* executeTask() : Si la tâche est prête et que la ligne SPI est libre, cette fonction exécute la tâche courante.&lt;br /&gt;
* scheduler() : Si la tâche n'est pas prête ou si la ligne SPI n'est pas disponible, l'ordonnanceur passe à la tâche suivante.&lt;br /&gt;
&lt;br /&gt;
===== Fonction `spiAvailable()` =====&lt;br /&gt;
La fonction `spiAvailable()` vérifie si la ligne SPI associée à une tâche est libre. Cela permet d'éviter que plusieurs tâches tentent d'utiliser la même ligne SPI en même temps, ce qui pourrait causer des conflits d'accès.&lt;br /&gt;
&lt;br /&gt;
Voici le code de la fonction `spiAvailable()` :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
bool spiAvailable(int spiLine) {&lt;br /&gt;
    // Vérifie l'état de la ligne SPI&lt;br /&gt;
    if (getSpiState(spiLine) == SPI_FREE) {&lt;br /&gt;
        return true;&lt;br /&gt;
    } else {&lt;br /&gt;
        return false;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explication du Code :&lt;br /&gt;
* getSpiState(spiLine) : Cette fonction interroge l'état actuel de la ligne SPI spécifiée (`spiLine`). Si la ligne est libre (`SPI_FREE`), la fonction retourne `true`, sinon elle retourne `false`.&lt;br /&gt;
* return true/false : La fonction retourne `true` si la ligne SPI est disponible, permettant ainsi à la tâche de s'exécuter.&lt;br /&gt;
&lt;br /&gt;
===== Fonction `executeTask()` =====&lt;br /&gt;
La fonction `executeTask()` est celle qui exécute la tâche courante une fois qu'elle est prête et que la ligne SPI est disponible. Cette fonction lance la tâche spécifique en fonction de son `taskID`.&lt;br /&gt;
&lt;br /&gt;
Voici un exemple de la fonction `executeTask()` :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void executeTask(int taskID) {&lt;br /&gt;
    switch (taskID) {&lt;br /&gt;
        case 1:&lt;br /&gt;
            // Exécuter la tâche 1 (affichage sur écran LCD)&lt;br /&gt;
            updateLCD();&lt;br /&gt;
            break;&lt;br /&gt;
        case 2:&lt;br /&gt;
            // Exécuter la tâche 2 (lecture d'un clavier SPI)&lt;br /&gt;
            readKeyboard();&lt;br /&gt;
            break;&lt;br /&gt;
        // Ajout d'autres tâches ici...&lt;br /&gt;
        default:&lt;br /&gt;
            // Si la tâche n'est pas reconnue, ne rien faire&lt;br /&gt;
            break;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explication du Code :&lt;br /&gt;
* switch (taskID) : Cette instruction permet de choisir la tâche à exécuter en fonction de l'ID de la tâche.&lt;br /&gt;
* updateLCD() : Exemple d'une tâche qui met à jour l'affichage de l'écran LCD.&lt;br /&gt;
* readKeyboard() : Exemple d'une tâche qui lit les données d'un clavier SPI.&lt;br /&gt;
* default : Si l'ID de la tâche n'est pas reconnu, aucune action n'est effectuée.&lt;br /&gt;
&lt;br /&gt;
===== Gestion des Interruptions =====&lt;br /&gt;
L'ordonnanceur peut également être interrompu si un événement important survient, comme l'arrivée d'une nouvelle commande ou la fin d'une transmission SPI. Ces interruptions sont gérées via des Interrupt Service Routines (ISR), qui permettent de traiter rapidement ces événements sans interrompre l'ordonnancement global.&lt;br /&gt;
&lt;br /&gt;
Un exemple d'ISR :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
ISR(SPI_vect) {&lt;br /&gt;
    // Gestion de l'interruption SPI&lt;br /&gt;
    if (isTransmissionComplete()) {&lt;br /&gt;
        // Marquer la tâche SPI comme terminée&lt;br /&gt;
        taskArray[currentTask].isReady = true;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explication du Code :&lt;br /&gt;
* ISR(SPI_vect) : Cette fonction est une ISR qui est appelée lorsque l'événement lié au SPI se produit (par exemple, la fin d'une transmission).&lt;br /&gt;
* isTransmissionComplete() : Vérifie si la transmission SPI est terminée.&lt;br /&gt;
* taskArray[currentTask].isReady = true : Marque la tâche comme prête à être exécutée à nouveau.&lt;br /&gt;
L'ordonnanceur joue un rôle central dans notre pico ordinateur, en gérant les tâches et en s'assurant que chaque tâche a accès aux ressources SPI sans conflit. Ce système d'ordonnancement permet d'assurer un fonctionnement fluide et sans interruption de notre pico ordinateur.&lt;br /&gt;
&lt;br /&gt;
== Carte Shield ==&lt;br /&gt;
&lt;br /&gt;
=== Description ===&lt;br /&gt;
La carte Shield est une carte mère qui sert à connecter et contrôler divers périphériques, notamment la carte fille (écran), un clavier, et d'autres composants. Nous avons conçu cette carte pour faciliter la gestion des communications SPI entre la carte mère et les différentes cartes filles.&lt;br /&gt;
&lt;br /&gt;
=== Connectivité SPI ===&lt;br /&gt;
La carte Shield utilise plusieurs lignes SPI pour communiquer avec les cartes filles. Chaque périphérique, comme l'écran, est assigné à une ligne SPI spécifique. La carte Shield vérifie également la disponibilité des périphériques avant d'envoyer des commandes via SPI. Nous avons effectué plusieurs test afin de vérifier le bon fonctionnement de notre carte Shield. Nous avons tester le fonctionnement des LED, la connectivité de la carte SD, et nous avons utiliser le Shield pour faire un timer sur un afficheur 7 segments.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:Diode.jpg|gauche|vignette|412x412px|Test des LEDs]]&lt;br /&gt;
[[Fichier:TestSD.jpg|vignette|Test de la carte SD]]&lt;br /&gt;
[[Fichier:Video7seg.mp4|vignette|400x400px|Timer sur un afficheur 7 segments|néant]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bilan de puissances ==&lt;br /&gt;
https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf&lt;br /&gt;
&lt;br /&gt;
https://docs.rs-online.com/e062/A700000007893278.pdf&lt;br /&gt;
&lt;br /&gt;
https://docs.rs-online.com/d50a/0900766b8127cd1d.pdf&lt;br /&gt;
&lt;br /&gt;
https://www.sparkfun.com/datasheets/LCD/HD44780.pdf&lt;br /&gt;
&lt;br /&gt;
== Tests Réalisés ==&lt;br /&gt;
&lt;br /&gt;
=== Tests de l'Ordonnanceur ===&lt;br /&gt;
* Gestion des tâches : Nous avons simulé plusieurs tâches, dont l'affichage et la gestion du clavier, et vérifié que l'ordonnanceur passe correctement d'une tâche à l'autre.&lt;br /&gt;
* En utilisant le logiciel minicom nous avons pus lancer une 2eme tâche en parallèle d'une première tâche. En tapant &amp;quot;a&amp;quot; une deuxième LED se met à clignoter.&lt;br /&gt;
[[Fichier:Videoprocess.mp4|centré|vignette|400x300px|Test de l'ordonnanceur : lancer une tâche. ]]&lt;br /&gt;
&lt;br /&gt;
=== Tests de la RAM SPI //a completer ===&lt;br /&gt;
* Stockage des données&lt;/div&gt;</summary>
		<author><name>Mbarret</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-2&amp;diff=6391</id>
		<title>SE4Binome2024-2</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-2&amp;diff=6391"/>
		<updated>2024-10-23T09:12:35Z</updated>

		<summary type="html">&lt;p&gt;Mbarret : /* Tests Réalisés */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Pico Ordinateur =&lt;br /&gt;
Ce projet vise à concevoir un pico ordinateur divisé en plusieurs parties, réalisées par différents binômes. Le rôle de notre binôme est de développer une carte fille équipée d'un microcontrôleur ATMega328p et d'un écran LCD contrôlé par un HD44780, en plus de la conception d'un Shield et d'un ordonnanceur. Cette carte sera connectée à une carte mère via un connecteur HE10 et devra gérer l'affichage de caractères ASCII, ainsi que quelques commandes spécifiques VT100. De plus, nous ajouterons une RAM SPI pour améliorer les performances de gestion de l'affichage.&lt;br /&gt;
&lt;br /&gt;
== Carte Fille (Écran LCD) ==&lt;br /&gt;
&lt;br /&gt;
=== Description ===&lt;br /&gt;
La carte fille que nous avons développée contient les éléments suivants :&lt;br /&gt;
&lt;br /&gt;
* Un microcontrôleur '''ATMega328p''' pour la gestion de l'affichage.&lt;br /&gt;
* Un écran '''LCD avec contrôleur HD44780''' pour l'affichage de caractères ASCII.&lt;br /&gt;
* Un '''potentiomètre 3310P''' pour ajuster la luminosité des cristaux liquides de l'écran.&lt;br /&gt;
* Un '''connecteur HE10''' pour relier la carte fille à la carte mère.&lt;br /&gt;
* Un '''connecteur AVR ISP''' pour la programmation du microcontrôleur.&lt;br /&gt;
* Une '''RAM SP'''I (e.g. FM24C04B-GTR) pour stocker temporairement les données d'affichage.&lt;br /&gt;
&lt;br /&gt;
=== Fonctionnalités Demandées ===&lt;br /&gt;
&lt;br /&gt;
* Gestion de l'écran LCD : Le microcontrôleur doit gérer les écrans HD44780 avec 1, 2, 3 ou 4 lignes et afficher des caractères ASCII.&lt;br /&gt;
* Saut de ligne et retour chariot : Les caractères spéciaux `\n` et `\r` doivent être pris en compte.&lt;br /&gt;
* Commandes VT100 : Quelques codes VT100, notamment ceux pour le déplacement du curseur, doivent être supportés.&lt;br /&gt;
* Défilement automatique : Le contrôleur HD44780 doit être configuré pour activer le mode de défilement automatique.&lt;br /&gt;
* Connexion SPI : La carte mère doit envoyer les commandes via SPI. Le premier octet envoyé doit être le code commande `0x01`, suivi des caractères à afficher.&lt;br /&gt;
* Vérification de la disponibilité de l'écran : La carte fille met la ligne SPI en état haut lorsque l'affichage est en cours. La carte mère doit attendre que l'état soit bas avant de transmettre de nouvelles données, ou envoyer des commandes `0xFF` pour vérifier si l'écran est prêt.&lt;br /&gt;
&lt;br /&gt;
=== Ajout d'une RAM SPI ===&lt;br /&gt;
Pour complexifier la carte fille, nous ajouterons une RAM SPI (e.g. FM24C04B-GTR). Cette mémoire permet de stocker temporairement les caractères reçus par SPI avant leur affichage. Le microcontrôleur de la carte fille rafraîchit régulièrement l'écran en lisant les données de la RAM, ce qui améliore la fluidité de l'affichage et permet de libérer la carte mère plus rapidement.&lt;br /&gt;
&lt;br /&gt;
Nous avons choisi la RAM FM25W256-G disponible chez RS Component.&lt;br /&gt;
https://fr.rs-online.com/web/p/memoires-fram/1254228?gb=s&lt;br /&gt;
&lt;br /&gt;
Voici un schéma simplifié de la communication entre les composants :&lt;br /&gt;
* La carte mère écrit dans la RAM SPI via le bus SPI.&lt;br /&gt;
* Le microcontrôleur de la carte fille lit les données de la RAM SPI et les envoie à l'écran LCD pour mise à jour régulière.&lt;br /&gt;
&lt;br /&gt;
=== Schéma de Connexion ===&lt;br /&gt;
//capture ecran a ajouter&lt;br /&gt;
== Ordonnanceur ==&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
L'ordonnanceur est une partie essentielle de notre pico ordinateur. Il est responsable de la gestion des différentes tâches et de leur exécution de manière organisée. L'objectif de cet ordonnanceur est de permettre un partage équitable du temps processeur entre les tâches et d'assurer que chaque tâche puisse accéder aux ressources du système sans conflit.&lt;br /&gt;
&lt;br /&gt;
L'ordonnanceur prend également en compte la gestion des périphériques, tels que notre écran LCD, en s'assurant que chaque périphérique est disponible avant d'envoyer une nouvelle commande.&lt;br /&gt;
&lt;br /&gt;
=== Structure des Tâches ===&lt;br /&gt;
&lt;br /&gt;
Voici comment chaque tâche est représentée dans le système :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
struct Task {&lt;br /&gt;
    int taskID;             // Identifiant unique de la tâche&lt;br /&gt;
    int spiLine;            // Ligne SPI associée à la tâche (pour gérer un périphérique)&lt;br /&gt;
    bool isReady;           // Indique si la tâche est prête à s'exécuter&lt;br /&gt;
    bool isRunning;         // Indique si la tâche est actuellement en cours d'exécution&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Chaque tâche a un identifiant unique `taskID`, ainsi qu'une ligne SPI (`spiLine`) qui lui est assignée pour la gestion des périphériques. Le champ `isReady` permet de savoir si la tâche est prête à être exécutée (par exemple, si le périphérique SPI est disponible), et `isRunning` indique si la tâche est en cours d'exécution.&lt;br /&gt;
&lt;br /&gt;
=== Fonctions de l'Ordonnanceur ===&lt;br /&gt;
&lt;br /&gt;
L'ordonnanceur est principalement basé sur deux fonctions principales :&lt;br /&gt;
&lt;br /&gt;
1. scheduler() : Gère le changement de tâche en fonction de l'algorithme Round Robin.&lt;br /&gt;
2. spiAvailable() : Vérifie la disponibilité de la ligne SPI avant d'exécuter une tâche.&lt;br /&gt;
&lt;br /&gt;
===== Fonction `scheduler()` =====&lt;br /&gt;
La fonction `scheduler()` est responsable du passage d'une tâche à l'autre en suivant l'algorithme Round Robin. Elle incrémente l'indice de la tâche courante et revient au début de la liste si la dernière tâche a été atteinte.&lt;br /&gt;
&lt;br /&gt;
Voici le code de la fonction `scheduler()` :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void scheduler() {&lt;br /&gt;
    // Incrémentation de l'indice de la tâche courante&lt;br /&gt;
    currentTask++;&lt;br /&gt;
    &lt;br /&gt;
    // Si l'indice dépasse le nombre de tâches, on revient à la première tâche&lt;br /&gt;
    if (currentTask == NB_TASKS) {&lt;br /&gt;
        currentTask = 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Vérifie si la tâche suivante est prête à être exécutée&lt;br /&gt;
    if (taskArray[currentTask].isReady &amp;amp;&amp;amp; spiAvailable(taskArray[currentTask].spiLine)) {&lt;br /&gt;
        // Exécuter la tâche si elle est prête et que la ligne SPI est disponible&lt;br /&gt;
        executeTask(taskArray[currentTask].taskID);&lt;br /&gt;
    } else {&lt;br /&gt;
        // Si la tâche n'est pas prête, passe à la tâche suivante&lt;br /&gt;
        scheduler();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explication du Code :&lt;br /&gt;
* currentTask++ : Cette ligne incrémente l'indice de la tâche courante, passant ainsi à la tâche suivante dans la liste.&lt;br /&gt;
* if (currentTask == NB_TASKS) : Si l'ordonnanceur arrive à la fin de la liste des tâches (déterminée par `NB_TASKS`, le nombre total de tâches), il revient à la première tâche (`currentTask = 0`).&lt;br /&gt;
* taskArray[currentTask].isReady : L'ordonnanceur vérifie si la tâche est prête à être exécutée (en attente d'exécution).&lt;br /&gt;
* spiAvailable(taskArray[currentTask].spiLine) : Cette fonction est appelée pour vérifier si la ligne SPI associée à la tâche est disponible (explication ci-dessous).&lt;br /&gt;
* executeTask() : Si la tâche est prête et que la ligne SPI est libre, cette fonction exécute la tâche courante.&lt;br /&gt;
* scheduler() : Si la tâche n'est pas prête ou si la ligne SPI n'est pas disponible, l'ordonnanceur passe à la tâche suivante.&lt;br /&gt;
&lt;br /&gt;
===== Fonction `spiAvailable()` =====&lt;br /&gt;
La fonction `spiAvailable()` vérifie si la ligne SPI associée à une tâche est libre. Cela permet d'éviter que plusieurs tâches tentent d'utiliser la même ligne SPI en même temps, ce qui pourrait causer des conflits d'accès.&lt;br /&gt;
&lt;br /&gt;
Voici le code de la fonction `spiAvailable()` :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
bool spiAvailable(int spiLine) {&lt;br /&gt;
    // Vérifie l'état de la ligne SPI&lt;br /&gt;
    if (getSpiState(spiLine) == SPI_FREE) {&lt;br /&gt;
        return true;&lt;br /&gt;
    } else {&lt;br /&gt;
        return false;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explication du Code :&lt;br /&gt;
* getSpiState(spiLine) : Cette fonction interroge l'état actuel de la ligne SPI spécifiée (`spiLine`). Si la ligne est libre (`SPI_FREE`), la fonction retourne `true`, sinon elle retourne `false`.&lt;br /&gt;
* return true/false : La fonction retourne `true` si la ligne SPI est disponible, permettant ainsi à la tâche de s'exécuter.&lt;br /&gt;
&lt;br /&gt;
===== Fonction `executeTask()` =====&lt;br /&gt;
La fonction `executeTask()` est celle qui exécute la tâche courante une fois qu'elle est prête et que la ligne SPI est disponible. Cette fonction lance la tâche spécifique en fonction de son `taskID`.&lt;br /&gt;
&lt;br /&gt;
Voici un exemple de la fonction `executeTask()` :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void executeTask(int taskID) {&lt;br /&gt;
    switch (taskID) {&lt;br /&gt;
        case 1:&lt;br /&gt;
            // Exécuter la tâche 1 (affichage sur écran LCD)&lt;br /&gt;
            updateLCD();&lt;br /&gt;
            break;&lt;br /&gt;
        case 2:&lt;br /&gt;
            // Exécuter la tâche 2 (lecture d'un clavier SPI)&lt;br /&gt;
            readKeyboard();&lt;br /&gt;
            break;&lt;br /&gt;
        // Ajout d'autres tâches ici...&lt;br /&gt;
        default:&lt;br /&gt;
            // Si la tâche n'est pas reconnue, ne rien faire&lt;br /&gt;
            break;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explication du Code :&lt;br /&gt;
* switch (taskID) : Cette instruction permet de choisir la tâche à exécuter en fonction de l'ID de la tâche.&lt;br /&gt;
* updateLCD() : Exemple d'une tâche qui met à jour l'affichage de l'écran LCD.&lt;br /&gt;
* readKeyboard() : Exemple d'une tâche qui lit les données d'un clavier SPI.&lt;br /&gt;
* default : Si l'ID de la tâche n'est pas reconnu, aucune action n'est effectuée.&lt;br /&gt;
&lt;br /&gt;
===== Gestion des Interruptions =====&lt;br /&gt;
L'ordonnanceur peut également être interrompu si un événement important survient, comme l'arrivée d'une nouvelle commande ou la fin d'une transmission SPI. Ces interruptions sont gérées via des Interrupt Service Routines (ISR), qui permettent de traiter rapidement ces événements sans interrompre l'ordonnancement global.&lt;br /&gt;
&lt;br /&gt;
Un exemple d'ISR :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
ISR(SPI_vect) {&lt;br /&gt;
    // Gestion de l'interruption SPI&lt;br /&gt;
    if (isTransmissionComplete()) {&lt;br /&gt;
        // Marquer la tâche SPI comme terminée&lt;br /&gt;
        taskArray[currentTask].isReady = true;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explication du Code :&lt;br /&gt;
* ISR(SPI_vect) : Cette fonction est une ISR qui est appelée lorsque l'événement lié au SPI se produit (par exemple, la fin d'une transmission).&lt;br /&gt;
* isTransmissionComplete() : Vérifie si la transmission SPI est terminée.&lt;br /&gt;
* taskArray[currentTask].isReady = true : Marque la tâche comme prête à être exécutée à nouveau.&lt;br /&gt;
L'ordonnanceur joue un rôle central dans notre pico ordinateur, en gérant les tâches et en s'assurant que chaque tâche a accès aux ressources SPI sans conflit. Ce système d'ordonnancement permet d'assurer un fonctionnement fluide et sans interruption de notre pico ordinateur.&lt;br /&gt;
&lt;br /&gt;
== Carte Shield ==&lt;br /&gt;
&lt;br /&gt;
=== Description ===&lt;br /&gt;
La carte Shield est une carte mère qui sert à connecter et contrôler divers périphériques, notamment la carte fille (écran), un clavier, et d'autres composants. Nous avons conçu cette carte pour faciliter la gestion des communications SPI entre la carte mère et les différentes cartes filles.&lt;br /&gt;
&lt;br /&gt;
=== Connectivité SPI ===&lt;br /&gt;
La carte Shield utilise plusieurs lignes SPI pour communiquer avec les cartes filles. Chaque périphérique, comme l'écran, est assigné à une ligne SPI spécifique. La carte Shield vérifie également la disponibilité des périphériques avant d'envoyer des commandes via SPI. Nous avons effectué plusieurs test afin de vérifier le bon fonctionnement de notre carte Shield. Nous avons tester le fonctionnement des LED, la connectivité de la carte SD, et nous avons utiliser le Shield pour faire un compteur sur un afficheur 7 segments.&lt;br /&gt;
[[Fichier:Diode.jpg|gauche|vignette|448x448px|Test des LEDs]]&lt;br /&gt;
[[Fichier:TestSD.jpg|vignette|Test de la carte SD]]&lt;br /&gt;
[[Fichier:Video7seg.mp4|vignette|Timer sur un afficheur 7 segments|néant]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Tests Réalisés ==&lt;br /&gt;
&lt;br /&gt;
=== Tests de l'Ordonnanceur //acompleter ===&lt;br /&gt;
* Gestion des tâches : Nous avons simulé plusieurs tâches, dont l'affichage et la gestion du clavier, et vérifié que l'ordonnanceur passe correctement d'une tâche à l'autre.&lt;br /&gt;
* En utilisant le logiciel minicom nous avons pus lancer une 2eme tâche en parallèle d'une première tâche. En tapant &amp;quot;a&amp;quot; une deuxième LED se met a clignoter.&lt;br /&gt;
* //image et video&lt;br /&gt;
&lt;br /&gt;
=== Tests de la RAM SPI //a completer ===&lt;br /&gt;
* Stockage des données d'affichage :&lt;/div&gt;</summary>
		<author><name>Mbarret</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-2&amp;diff=6390</id>
		<title>SE4Binome2024-2</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-2&amp;diff=6390"/>
		<updated>2024-10-23T09:12:07Z</updated>

		<summary type="html">&lt;p&gt;Mbarret : /* Connectivité SPI */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Pico Ordinateur =&lt;br /&gt;
Ce projet vise à concevoir un pico ordinateur divisé en plusieurs parties, réalisées par différents binômes. Le rôle de notre binôme est de développer une carte fille équipée d'un microcontrôleur ATMega328p et d'un écran LCD contrôlé par un HD44780, en plus de la conception d'un Shield et d'un ordonnanceur. Cette carte sera connectée à une carte mère via un connecteur HE10 et devra gérer l'affichage de caractères ASCII, ainsi que quelques commandes spécifiques VT100. De plus, nous ajouterons une RAM SPI pour améliorer les performances de gestion de l'affichage.&lt;br /&gt;
&lt;br /&gt;
== Carte Fille (Écran LCD) ==&lt;br /&gt;
&lt;br /&gt;
=== Description ===&lt;br /&gt;
La carte fille que nous avons développée contient les éléments suivants :&lt;br /&gt;
&lt;br /&gt;
* Un microcontrôleur '''ATMega328p''' pour la gestion de l'affichage.&lt;br /&gt;
* Un écran '''LCD avec contrôleur HD44780''' pour l'affichage de caractères ASCII.&lt;br /&gt;
* Un '''potentiomètre 3310P''' pour ajuster la luminosité des cristaux liquides de l'écran.&lt;br /&gt;
* Un '''connecteur HE10''' pour relier la carte fille à la carte mère.&lt;br /&gt;
* Un '''connecteur AVR ISP''' pour la programmation du microcontrôleur.&lt;br /&gt;
* Une '''RAM SP'''I (e.g. FM24C04B-GTR) pour stocker temporairement les données d'affichage.&lt;br /&gt;
&lt;br /&gt;
=== Fonctionnalités Demandées ===&lt;br /&gt;
&lt;br /&gt;
* Gestion de l'écran LCD : Le microcontrôleur doit gérer les écrans HD44780 avec 1, 2, 3 ou 4 lignes et afficher des caractères ASCII.&lt;br /&gt;
* Saut de ligne et retour chariot : Les caractères spéciaux `\n` et `\r` doivent être pris en compte.&lt;br /&gt;
* Commandes VT100 : Quelques codes VT100, notamment ceux pour le déplacement du curseur, doivent être supportés.&lt;br /&gt;
* Défilement automatique : Le contrôleur HD44780 doit être configuré pour activer le mode de défilement automatique.&lt;br /&gt;
* Connexion SPI : La carte mère doit envoyer les commandes via SPI. Le premier octet envoyé doit être le code commande `0x01`, suivi des caractères à afficher.&lt;br /&gt;
* Vérification de la disponibilité de l'écran : La carte fille met la ligne SPI en état haut lorsque l'affichage est en cours. La carte mère doit attendre que l'état soit bas avant de transmettre de nouvelles données, ou envoyer des commandes `0xFF` pour vérifier si l'écran est prêt.&lt;br /&gt;
&lt;br /&gt;
=== Ajout d'une RAM SPI ===&lt;br /&gt;
Pour complexifier la carte fille, nous ajouterons une RAM SPI (e.g. FM24C04B-GTR). Cette mémoire permet de stocker temporairement les caractères reçus par SPI avant leur affichage. Le microcontrôleur de la carte fille rafraîchit régulièrement l'écran en lisant les données de la RAM, ce qui améliore la fluidité de l'affichage et permet de libérer la carte mère plus rapidement.&lt;br /&gt;
&lt;br /&gt;
Nous avons choisi la RAM FM25W256-G disponible chez RS Component.&lt;br /&gt;
https://fr.rs-online.com/web/p/memoires-fram/1254228?gb=s&lt;br /&gt;
&lt;br /&gt;
Voici un schéma simplifié de la communication entre les composants :&lt;br /&gt;
* La carte mère écrit dans la RAM SPI via le bus SPI.&lt;br /&gt;
* Le microcontrôleur de la carte fille lit les données de la RAM SPI et les envoie à l'écran LCD pour mise à jour régulière.&lt;br /&gt;
&lt;br /&gt;
=== Schéma de Connexion ===&lt;br /&gt;
//capture ecran a ajouter&lt;br /&gt;
== Ordonnanceur ==&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
L'ordonnanceur est une partie essentielle de notre pico ordinateur. Il est responsable de la gestion des différentes tâches et de leur exécution de manière organisée. L'objectif de cet ordonnanceur est de permettre un partage équitable du temps processeur entre les tâches et d'assurer que chaque tâche puisse accéder aux ressources du système sans conflit.&lt;br /&gt;
&lt;br /&gt;
L'ordonnanceur prend également en compte la gestion des périphériques, tels que notre écran LCD, en s'assurant que chaque périphérique est disponible avant d'envoyer une nouvelle commande.&lt;br /&gt;
&lt;br /&gt;
=== Structure des Tâches ===&lt;br /&gt;
&lt;br /&gt;
Voici comment chaque tâche est représentée dans le système :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
struct Task {&lt;br /&gt;
    int taskID;             // Identifiant unique de la tâche&lt;br /&gt;
    int spiLine;            // Ligne SPI associée à la tâche (pour gérer un périphérique)&lt;br /&gt;
    bool isReady;           // Indique si la tâche est prête à s'exécuter&lt;br /&gt;
    bool isRunning;         // Indique si la tâche est actuellement en cours d'exécution&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Chaque tâche a un identifiant unique `taskID`, ainsi qu'une ligne SPI (`spiLine`) qui lui est assignée pour la gestion des périphériques. Le champ `isReady` permet de savoir si la tâche est prête à être exécutée (par exemple, si le périphérique SPI est disponible), et `isRunning` indique si la tâche est en cours d'exécution.&lt;br /&gt;
&lt;br /&gt;
=== Fonctions de l'Ordonnanceur ===&lt;br /&gt;
&lt;br /&gt;
L'ordonnanceur est principalement basé sur deux fonctions principales :&lt;br /&gt;
&lt;br /&gt;
1. scheduler() : Gère le changement de tâche en fonction de l'algorithme Round Robin.&lt;br /&gt;
2. spiAvailable() : Vérifie la disponibilité de la ligne SPI avant d'exécuter une tâche.&lt;br /&gt;
&lt;br /&gt;
===== Fonction `scheduler()` =====&lt;br /&gt;
La fonction `scheduler()` est responsable du passage d'une tâche à l'autre en suivant l'algorithme Round Robin. Elle incrémente l'indice de la tâche courante et revient au début de la liste si la dernière tâche a été atteinte.&lt;br /&gt;
&lt;br /&gt;
Voici le code de la fonction `scheduler()` :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void scheduler() {&lt;br /&gt;
    // Incrémentation de l'indice de la tâche courante&lt;br /&gt;
    currentTask++;&lt;br /&gt;
    &lt;br /&gt;
    // Si l'indice dépasse le nombre de tâches, on revient à la première tâche&lt;br /&gt;
    if (currentTask == NB_TASKS) {&lt;br /&gt;
        currentTask = 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Vérifie si la tâche suivante est prête à être exécutée&lt;br /&gt;
    if (taskArray[currentTask].isReady &amp;amp;&amp;amp; spiAvailable(taskArray[currentTask].spiLine)) {&lt;br /&gt;
        // Exécuter la tâche si elle est prête et que la ligne SPI est disponible&lt;br /&gt;
        executeTask(taskArray[currentTask].taskID);&lt;br /&gt;
    } else {&lt;br /&gt;
        // Si la tâche n'est pas prête, passe à la tâche suivante&lt;br /&gt;
        scheduler();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explication du Code :&lt;br /&gt;
* currentTask++ : Cette ligne incrémente l'indice de la tâche courante, passant ainsi à la tâche suivante dans la liste.&lt;br /&gt;
* if (currentTask == NB_TASKS) : Si l'ordonnanceur arrive à la fin de la liste des tâches (déterminée par `NB_TASKS`, le nombre total de tâches), il revient à la première tâche (`currentTask = 0`).&lt;br /&gt;
* taskArray[currentTask].isReady : L'ordonnanceur vérifie si la tâche est prête à être exécutée (en attente d'exécution).&lt;br /&gt;
* spiAvailable(taskArray[currentTask].spiLine) : Cette fonction est appelée pour vérifier si la ligne SPI associée à la tâche est disponible (explication ci-dessous).&lt;br /&gt;
* executeTask() : Si la tâche est prête et que la ligne SPI est libre, cette fonction exécute la tâche courante.&lt;br /&gt;
* scheduler() : Si la tâche n'est pas prête ou si la ligne SPI n'est pas disponible, l'ordonnanceur passe à la tâche suivante.&lt;br /&gt;
&lt;br /&gt;
===== Fonction `spiAvailable()` =====&lt;br /&gt;
La fonction `spiAvailable()` vérifie si la ligne SPI associée à une tâche est libre. Cela permet d'éviter que plusieurs tâches tentent d'utiliser la même ligne SPI en même temps, ce qui pourrait causer des conflits d'accès.&lt;br /&gt;
&lt;br /&gt;
Voici le code de la fonction `spiAvailable()` :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
bool spiAvailable(int spiLine) {&lt;br /&gt;
    // Vérifie l'état de la ligne SPI&lt;br /&gt;
    if (getSpiState(spiLine) == SPI_FREE) {&lt;br /&gt;
        return true;&lt;br /&gt;
    } else {&lt;br /&gt;
        return false;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explication du Code :&lt;br /&gt;
* getSpiState(spiLine) : Cette fonction interroge l'état actuel de la ligne SPI spécifiée (`spiLine`). Si la ligne est libre (`SPI_FREE`), la fonction retourne `true`, sinon elle retourne `false`.&lt;br /&gt;
* return true/false : La fonction retourne `true` si la ligne SPI est disponible, permettant ainsi à la tâche de s'exécuter.&lt;br /&gt;
&lt;br /&gt;
===== Fonction `executeTask()` =====&lt;br /&gt;
La fonction `executeTask()` est celle qui exécute la tâche courante une fois qu'elle est prête et que la ligne SPI est disponible. Cette fonction lance la tâche spécifique en fonction de son `taskID`.&lt;br /&gt;
&lt;br /&gt;
Voici un exemple de la fonction `executeTask()` :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void executeTask(int taskID) {&lt;br /&gt;
    switch (taskID) {&lt;br /&gt;
        case 1:&lt;br /&gt;
            // Exécuter la tâche 1 (affichage sur écran LCD)&lt;br /&gt;
            updateLCD();&lt;br /&gt;
            break;&lt;br /&gt;
        case 2:&lt;br /&gt;
            // Exécuter la tâche 2 (lecture d'un clavier SPI)&lt;br /&gt;
            readKeyboard();&lt;br /&gt;
            break;&lt;br /&gt;
        // Ajout d'autres tâches ici...&lt;br /&gt;
        default:&lt;br /&gt;
            // Si la tâche n'est pas reconnue, ne rien faire&lt;br /&gt;
            break;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explication du Code :&lt;br /&gt;
* switch (taskID) : Cette instruction permet de choisir la tâche à exécuter en fonction de l'ID de la tâche.&lt;br /&gt;
* updateLCD() : Exemple d'une tâche qui met à jour l'affichage de l'écran LCD.&lt;br /&gt;
* readKeyboard() : Exemple d'une tâche qui lit les données d'un clavier SPI.&lt;br /&gt;
* default : Si l'ID de la tâche n'est pas reconnu, aucune action n'est effectuée.&lt;br /&gt;
&lt;br /&gt;
===== Gestion des Interruptions =====&lt;br /&gt;
L'ordonnanceur peut également être interrompu si un événement important survient, comme l'arrivée d'une nouvelle commande ou la fin d'une transmission SPI. Ces interruptions sont gérées via des Interrupt Service Routines (ISR), qui permettent de traiter rapidement ces événements sans interrompre l'ordonnancement global.&lt;br /&gt;
&lt;br /&gt;
Un exemple d'ISR :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
ISR(SPI_vect) {&lt;br /&gt;
    // Gestion de l'interruption SPI&lt;br /&gt;
    if (isTransmissionComplete()) {&lt;br /&gt;
        // Marquer la tâche SPI comme terminée&lt;br /&gt;
        taskArray[currentTask].isReady = true;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explication du Code :&lt;br /&gt;
* ISR(SPI_vect) : Cette fonction est une ISR qui est appelée lorsque l'événement lié au SPI se produit (par exemple, la fin d'une transmission).&lt;br /&gt;
* isTransmissionComplete() : Vérifie si la transmission SPI est terminée.&lt;br /&gt;
* taskArray[currentTask].isReady = true : Marque la tâche comme prête à être exécutée à nouveau.&lt;br /&gt;
L'ordonnanceur joue un rôle central dans notre pico ordinateur, en gérant les tâches et en s'assurant que chaque tâche a accès aux ressources SPI sans conflit. Ce système d'ordonnancement permet d'assurer un fonctionnement fluide et sans interruption de notre pico ordinateur.&lt;br /&gt;
&lt;br /&gt;
== Carte Shield ==&lt;br /&gt;
&lt;br /&gt;
=== Description ===&lt;br /&gt;
La carte Shield est une carte mère qui sert à connecter et contrôler divers périphériques, notamment la carte fille (écran), un clavier, et d'autres composants. Nous avons conçu cette carte pour faciliter la gestion des communications SPI entre la carte mère et les différentes cartes filles.&lt;br /&gt;
&lt;br /&gt;
=== Connectivité SPI ===&lt;br /&gt;
La carte Shield utilise plusieurs lignes SPI pour communiquer avec les cartes filles. Chaque périphérique, comme l'écran, est assigné à une ligne SPI spécifique. La carte Shield vérifie également la disponibilité des périphériques avant d'envoyer des commandes via SPI. Nous avons effectué plusieurs test afin de vérifier le bon fonctionnement de notre carte Shield. Nous avons tester le fonctionnement des LED, la connectivité de la carte SD, et nous avons utiliser le Shield pour faire un compteur sur un afficheur 7 segments.&lt;br /&gt;
[[Fichier:Diode.jpg|gauche|vignette|448x448px|Test des LEDs]]&lt;br /&gt;
[[Fichier:TestSD.jpg|vignette|Test de la carte SD]]&lt;br /&gt;
[[Fichier:Video7seg.mp4|vignette|Timer sur un afficheur 7 segments|néant]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Tests Réalisés ==&lt;br /&gt;
&lt;br /&gt;
=== Tests de l'Ordonnanceur //acompleter ===&lt;br /&gt;
* Gestion des tâches : Nous avons simulé plusieurs tâches, dont l'affichage et la gestion du clavier, et vérifié que l'ordonnanceur passe correctement d'une tâche à l'autre.&lt;br /&gt;
* En utilisant le logiciel minicom nous avons pus lancer une 2eme tâche en parallèle d'une première tâche. En tapant &amp;quot;a&amp;quot; une deuxième LED se met a clignoter.&lt;br /&gt;
* //image et video&lt;br /&gt;
&lt;br /&gt;
=== Tests de la RAM SPI //a completer ===&lt;br /&gt;
* Stockage des données d'affichage :&lt;/div&gt;</summary>
		<author><name>Mbarret</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-2&amp;diff=6389</id>
		<title>SE4Binome2024-2</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-2&amp;diff=6389"/>
		<updated>2024-10-23T09:11:12Z</updated>

		<summary type="html">&lt;p&gt;Mbarret : /* Connectivité SPI */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Pico Ordinateur =&lt;br /&gt;
Ce projet vise à concevoir un pico ordinateur divisé en plusieurs parties, réalisées par différents binômes. Le rôle de notre binôme est de développer une carte fille équipée d'un microcontrôleur ATMega328p et d'un écran LCD contrôlé par un HD44780, en plus de la conception d'un Shield et d'un ordonnanceur. Cette carte sera connectée à une carte mère via un connecteur HE10 et devra gérer l'affichage de caractères ASCII, ainsi que quelques commandes spécifiques VT100. De plus, nous ajouterons une RAM SPI pour améliorer les performances de gestion de l'affichage.&lt;br /&gt;
&lt;br /&gt;
== Carte Fille (Écran LCD) ==&lt;br /&gt;
&lt;br /&gt;
=== Description ===&lt;br /&gt;
La carte fille que nous avons développée contient les éléments suivants :&lt;br /&gt;
&lt;br /&gt;
* Un microcontrôleur '''ATMega328p''' pour la gestion de l'affichage.&lt;br /&gt;
* Un écran '''LCD avec contrôleur HD44780''' pour l'affichage de caractères ASCII.&lt;br /&gt;
* Un '''potentiomètre 3310P''' pour ajuster la luminosité des cristaux liquides de l'écran.&lt;br /&gt;
* Un '''connecteur HE10''' pour relier la carte fille à la carte mère.&lt;br /&gt;
* Un '''connecteur AVR ISP''' pour la programmation du microcontrôleur.&lt;br /&gt;
* Une '''RAM SP'''I (e.g. FM24C04B-GTR) pour stocker temporairement les données d'affichage.&lt;br /&gt;
&lt;br /&gt;
=== Fonctionnalités Demandées ===&lt;br /&gt;
&lt;br /&gt;
* Gestion de l'écran LCD : Le microcontrôleur doit gérer les écrans HD44780 avec 1, 2, 3 ou 4 lignes et afficher des caractères ASCII.&lt;br /&gt;
* Saut de ligne et retour chariot : Les caractères spéciaux `\n` et `\r` doivent être pris en compte.&lt;br /&gt;
* Commandes VT100 : Quelques codes VT100, notamment ceux pour le déplacement du curseur, doivent être supportés.&lt;br /&gt;
* Défilement automatique : Le contrôleur HD44780 doit être configuré pour activer le mode de défilement automatique.&lt;br /&gt;
* Connexion SPI : La carte mère doit envoyer les commandes via SPI. Le premier octet envoyé doit être le code commande `0x01`, suivi des caractères à afficher.&lt;br /&gt;
* Vérification de la disponibilité de l'écran : La carte fille met la ligne SPI en état haut lorsque l'affichage est en cours. La carte mère doit attendre que l'état soit bas avant de transmettre de nouvelles données, ou envoyer des commandes `0xFF` pour vérifier si l'écran est prêt.&lt;br /&gt;
&lt;br /&gt;
=== Ajout d'une RAM SPI ===&lt;br /&gt;
Pour complexifier la carte fille, nous ajouterons une RAM SPI (e.g. FM24C04B-GTR). Cette mémoire permet de stocker temporairement les caractères reçus par SPI avant leur affichage. Le microcontrôleur de la carte fille rafraîchit régulièrement l'écran en lisant les données de la RAM, ce qui améliore la fluidité de l'affichage et permet de libérer la carte mère plus rapidement.&lt;br /&gt;
&lt;br /&gt;
Nous avons choisi la RAM FM25W256-G disponible chez RS Component.&lt;br /&gt;
https://fr.rs-online.com/web/p/memoires-fram/1254228?gb=s&lt;br /&gt;
&lt;br /&gt;
Voici un schéma simplifié de la communication entre les composants :&lt;br /&gt;
* La carte mère écrit dans la RAM SPI via le bus SPI.&lt;br /&gt;
* Le microcontrôleur de la carte fille lit les données de la RAM SPI et les envoie à l'écran LCD pour mise à jour régulière.&lt;br /&gt;
&lt;br /&gt;
=== Schéma de Connexion ===&lt;br /&gt;
//capture ecran a ajouter&lt;br /&gt;
== Ordonnanceur ==&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
L'ordonnanceur est une partie essentielle de notre pico ordinateur. Il est responsable de la gestion des différentes tâches et de leur exécution de manière organisée. L'objectif de cet ordonnanceur est de permettre un partage équitable du temps processeur entre les tâches et d'assurer que chaque tâche puisse accéder aux ressources du système sans conflit.&lt;br /&gt;
&lt;br /&gt;
L'ordonnanceur prend également en compte la gestion des périphériques, tels que notre écran LCD, en s'assurant que chaque périphérique est disponible avant d'envoyer une nouvelle commande.&lt;br /&gt;
&lt;br /&gt;
=== Structure des Tâches ===&lt;br /&gt;
&lt;br /&gt;
Voici comment chaque tâche est représentée dans le système :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
struct Task {&lt;br /&gt;
    int taskID;             // Identifiant unique de la tâche&lt;br /&gt;
    int spiLine;            // Ligne SPI associée à la tâche (pour gérer un périphérique)&lt;br /&gt;
    bool isReady;           // Indique si la tâche est prête à s'exécuter&lt;br /&gt;
    bool isRunning;         // Indique si la tâche est actuellement en cours d'exécution&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Chaque tâche a un identifiant unique `taskID`, ainsi qu'une ligne SPI (`spiLine`) qui lui est assignée pour la gestion des périphériques. Le champ `isReady` permet de savoir si la tâche est prête à être exécutée (par exemple, si le périphérique SPI est disponible), et `isRunning` indique si la tâche est en cours d'exécution.&lt;br /&gt;
&lt;br /&gt;
=== Fonctions de l'Ordonnanceur ===&lt;br /&gt;
&lt;br /&gt;
L'ordonnanceur est principalement basé sur deux fonctions principales :&lt;br /&gt;
&lt;br /&gt;
1. scheduler() : Gère le changement de tâche en fonction de l'algorithme Round Robin.&lt;br /&gt;
2. spiAvailable() : Vérifie la disponibilité de la ligne SPI avant d'exécuter une tâche.&lt;br /&gt;
&lt;br /&gt;
===== Fonction `scheduler()` =====&lt;br /&gt;
La fonction `scheduler()` est responsable du passage d'une tâche à l'autre en suivant l'algorithme Round Robin. Elle incrémente l'indice de la tâche courante et revient au début de la liste si la dernière tâche a été atteinte.&lt;br /&gt;
&lt;br /&gt;
Voici le code de la fonction `scheduler()` :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void scheduler() {&lt;br /&gt;
    // Incrémentation de l'indice de la tâche courante&lt;br /&gt;
    currentTask++;&lt;br /&gt;
    &lt;br /&gt;
    // Si l'indice dépasse le nombre de tâches, on revient à la première tâche&lt;br /&gt;
    if (currentTask == NB_TASKS) {&lt;br /&gt;
        currentTask = 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Vérifie si la tâche suivante est prête à être exécutée&lt;br /&gt;
    if (taskArray[currentTask].isReady &amp;amp;&amp;amp; spiAvailable(taskArray[currentTask].spiLine)) {&lt;br /&gt;
        // Exécuter la tâche si elle est prête et que la ligne SPI est disponible&lt;br /&gt;
        executeTask(taskArray[currentTask].taskID);&lt;br /&gt;
    } else {&lt;br /&gt;
        // Si la tâche n'est pas prête, passe à la tâche suivante&lt;br /&gt;
        scheduler();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explication du Code :&lt;br /&gt;
* currentTask++ : Cette ligne incrémente l'indice de la tâche courante, passant ainsi à la tâche suivante dans la liste.&lt;br /&gt;
* if (currentTask == NB_TASKS) : Si l'ordonnanceur arrive à la fin de la liste des tâches (déterminée par `NB_TASKS`, le nombre total de tâches), il revient à la première tâche (`currentTask = 0`).&lt;br /&gt;
* taskArray[currentTask].isReady : L'ordonnanceur vérifie si la tâche est prête à être exécutée (en attente d'exécution).&lt;br /&gt;
* spiAvailable(taskArray[currentTask].spiLine) : Cette fonction est appelée pour vérifier si la ligne SPI associée à la tâche est disponible (explication ci-dessous).&lt;br /&gt;
* executeTask() : Si la tâche est prête et que la ligne SPI est libre, cette fonction exécute la tâche courante.&lt;br /&gt;
* scheduler() : Si la tâche n'est pas prête ou si la ligne SPI n'est pas disponible, l'ordonnanceur passe à la tâche suivante.&lt;br /&gt;
&lt;br /&gt;
===== Fonction `spiAvailable()` =====&lt;br /&gt;
La fonction `spiAvailable()` vérifie si la ligne SPI associée à une tâche est libre. Cela permet d'éviter que plusieurs tâches tentent d'utiliser la même ligne SPI en même temps, ce qui pourrait causer des conflits d'accès.&lt;br /&gt;
&lt;br /&gt;
Voici le code de la fonction `spiAvailable()` :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
bool spiAvailable(int spiLine) {&lt;br /&gt;
    // Vérifie l'état de la ligne SPI&lt;br /&gt;
    if (getSpiState(spiLine) == SPI_FREE) {&lt;br /&gt;
        return true;&lt;br /&gt;
    } else {&lt;br /&gt;
        return false;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explication du Code :&lt;br /&gt;
* getSpiState(spiLine) : Cette fonction interroge l'état actuel de la ligne SPI spécifiée (`spiLine`). Si la ligne est libre (`SPI_FREE`), la fonction retourne `true`, sinon elle retourne `false`.&lt;br /&gt;
* return true/false : La fonction retourne `true` si la ligne SPI est disponible, permettant ainsi à la tâche de s'exécuter.&lt;br /&gt;
&lt;br /&gt;
===== Fonction `executeTask()` =====&lt;br /&gt;
La fonction `executeTask()` est celle qui exécute la tâche courante une fois qu'elle est prête et que la ligne SPI est disponible. Cette fonction lance la tâche spécifique en fonction de son `taskID`.&lt;br /&gt;
&lt;br /&gt;
Voici un exemple de la fonction `executeTask()` :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void executeTask(int taskID) {&lt;br /&gt;
    switch (taskID) {&lt;br /&gt;
        case 1:&lt;br /&gt;
            // Exécuter la tâche 1 (affichage sur écran LCD)&lt;br /&gt;
            updateLCD();&lt;br /&gt;
            break;&lt;br /&gt;
        case 2:&lt;br /&gt;
            // Exécuter la tâche 2 (lecture d'un clavier SPI)&lt;br /&gt;
            readKeyboard();&lt;br /&gt;
            break;&lt;br /&gt;
        // Ajout d'autres tâches ici...&lt;br /&gt;
        default:&lt;br /&gt;
            // Si la tâche n'est pas reconnue, ne rien faire&lt;br /&gt;
            break;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explication du Code :&lt;br /&gt;
* switch (taskID) : Cette instruction permet de choisir la tâche à exécuter en fonction de l'ID de la tâche.&lt;br /&gt;
* updateLCD() : Exemple d'une tâche qui met à jour l'affichage de l'écran LCD.&lt;br /&gt;
* readKeyboard() : Exemple d'une tâche qui lit les données d'un clavier SPI.&lt;br /&gt;
* default : Si l'ID de la tâche n'est pas reconnu, aucune action n'est effectuée.&lt;br /&gt;
&lt;br /&gt;
===== Gestion des Interruptions =====&lt;br /&gt;
L'ordonnanceur peut également être interrompu si un événement important survient, comme l'arrivée d'une nouvelle commande ou la fin d'une transmission SPI. Ces interruptions sont gérées via des Interrupt Service Routines (ISR), qui permettent de traiter rapidement ces événements sans interrompre l'ordonnancement global.&lt;br /&gt;
&lt;br /&gt;
Un exemple d'ISR :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
ISR(SPI_vect) {&lt;br /&gt;
    // Gestion de l'interruption SPI&lt;br /&gt;
    if (isTransmissionComplete()) {&lt;br /&gt;
        // Marquer la tâche SPI comme terminée&lt;br /&gt;
        taskArray[currentTask].isReady = true;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explication du Code :&lt;br /&gt;
* ISR(SPI_vect) : Cette fonction est une ISR qui est appelée lorsque l'événement lié au SPI se produit (par exemple, la fin d'une transmission).&lt;br /&gt;
* isTransmissionComplete() : Vérifie si la transmission SPI est terminée.&lt;br /&gt;
* taskArray[currentTask].isReady = true : Marque la tâche comme prête à être exécutée à nouveau.&lt;br /&gt;
L'ordonnanceur joue un rôle central dans notre pico ordinateur, en gérant les tâches et en s'assurant que chaque tâche a accès aux ressources SPI sans conflit. Ce système d'ordonnancement permet d'assurer un fonctionnement fluide et sans interruption de notre pico ordinateur.&lt;br /&gt;
&lt;br /&gt;
== Carte Shield ==&lt;br /&gt;
&lt;br /&gt;
=== Description ===&lt;br /&gt;
La carte Shield est une carte mère qui sert à connecter et contrôler divers périphériques, notamment la carte fille (écran), un clavier, et d'autres composants. Nous avons conçu cette carte pour faciliter la gestion des communications SPI entre la carte mère et les différentes cartes filles.&lt;br /&gt;
&lt;br /&gt;
=== Connectivité SPI ===&lt;br /&gt;
La carte Shield utilise plusieurs lignes SPI pour communiquer avec les cartes filles. Chaque périphérique, comme l'écran, est assigné à une ligne SPI spécifique. La carte Shield vérifie également la disponibilité des périphériques avant d'envoyer des commandes via SPI. Nous avons effectué plusieurs test afin de vérifier le bon fonctionnement de notre carte Shield. Nous avons tester le fonctionnement des LED, la connectivité de la carte SD, et nous avons utiliser le Shield pour faire un compteur sur un afficheur 7 segments.&lt;br /&gt;
[[Fichier:Diode.jpg|gauche|vignette|448x448px|Test des LEDs]]&lt;br /&gt;
[[Fichier:TestSD.jpg|vignette|Test de la carte SD]]&lt;br /&gt;
[[Fichier:Video7seg.mp4|vignette|Timer sur un afficheur 7 segments|néant]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Tests Réalisés ==&lt;br /&gt;
&lt;br /&gt;
=== Tests de l'Ordonnanceur //acompleter ===&lt;br /&gt;
* Gestion des tâches : Nous avons simulé plusieurs tâches, dont l'affichage et la gestion du clavier, et vérifié que l'ordonnanceur passe correctement d'une tâche à l'autre.&lt;br /&gt;
* En utilisant le logiciel minicom nous avons pus lancer une 2eme tâche en parallèle d'une première tâche. En tapant &amp;quot;a&amp;quot; une deuxième LED se met a clignoter.&lt;br /&gt;
* //image et video&lt;br /&gt;
&lt;br /&gt;
=== Tests de la RAM SPI //a completer ===&lt;br /&gt;
* Stockage des données d'affichage :&lt;/div&gt;</summary>
		<author><name>Mbarret</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-2&amp;diff=6369</id>
		<title>SE4Binome2024-2</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-2&amp;diff=6369"/>
		<updated>2024-10-23T08:45:00Z</updated>

		<summary type="html">&lt;p&gt;Mbarret : /* Ajout d'une RAM SPI */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Pico Ordinateur =&lt;br /&gt;
Ce projet vise à concevoir un pico ordinateur divisé en plusieurs parties, réalisées par différents binômes. Le rôle de notre binôme est de développer une carte fille équipée d'un microcontrôleur ATMega328p et d'un écran LCD contrôlé par un HD44780, en plus de la conception d'un Shield et d'un ordonnanceur. Cette carte sera connectée à une carte mère via un connecteur HE10 et devra gérer l'affichage de caractères ASCII, ainsi que quelques commandes spécifiques VT100. De plus, nous ajouterons une RAM SPI pour améliorer les performances de gestion de l'affichage.&lt;br /&gt;
&lt;br /&gt;
== Carte Fille (Écran LCD) ==&lt;br /&gt;
&lt;br /&gt;
=== Description ===&lt;br /&gt;
La carte fille que nous avons développée contient les éléments suivants :&lt;br /&gt;
&lt;br /&gt;
* Un microcontrôleur '''ATMega328p''' pour la gestion de l'affichage.&lt;br /&gt;
* Un écran '''LCD avec contrôleur HD44780''' pour l'affichage de caractères ASCII.&lt;br /&gt;
* Un '''potentiomètre 3310P''' pour ajuster la luminosité des cristaux liquides de l'écran.&lt;br /&gt;
* Un '''connecteur HE10''' pour relier la carte fille à la carte mère.&lt;br /&gt;
* Un '''connecteur AVR ISP''' pour la programmation du microcontrôleur.&lt;br /&gt;
* Une '''RAM SP'''I (e.g. FM24C04B-GTR) pour stocker temporairement les données d'affichage.&lt;br /&gt;
&lt;br /&gt;
=== Fonctionnalités Demandées ===&lt;br /&gt;
&lt;br /&gt;
* Gestion de l'écran LCD : Le microcontrôleur doit gérer les écrans HD44780 avec 1, 2, 3 ou 4 lignes et afficher des caractères ASCII.&lt;br /&gt;
* Saut de ligne et retour chariot : Les caractères spéciaux `\n` et `\r` doivent être pris en compte.&lt;br /&gt;
* Commandes VT100 : Quelques codes VT100, notamment ceux pour le déplacement du curseur, doivent être supportés.&lt;br /&gt;
* Défilement automatique : Le contrôleur HD44780 doit être configuré pour activer le mode de défilement automatique.&lt;br /&gt;
* Connexion SPI : La carte mère doit envoyer les commandes via SPI. Le premier octet envoyé doit être le code commande `0x01`, suivi des caractères à afficher.&lt;br /&gt;
* Vérification de la disponibilité de l'écran : La carte fille met la ligne SPI en état haut lorsque l'affichage est en cours. La carte mère doit attendre que l'état soit bas avant de transmettre de nouvelles données, ou envoyer des commandes `0xFF` pour vérifier si l'écran est prêt.&lt;br /&gt;
&lt;br /&gt;
=== Ajout d'une RAM SPI ===&lt;br /&gt;
Pour complexifier la carte fille, nous ajouterons une RAM SPI (e.g. FM24C04B-GTR). Cette mémoire permet de stocker temporairement les caractères reçus par SPI avant leur affichage. Le microcontrôleur de la carte fille rafraîchit régulièrement l'écran en lisant les données de la RAM, ce qui améliore la fluidité de l'affichage et permet de libérer la carte mère plus rapidement.&lt;br /&gt;
&lt;br /&gt;
Nous avons choisi la RAM FM25W256-G disponible chez RS Component.&lt;br /&gt;
https://fr.rs-online.com/web/p/memoires-fram/1254228?gb=s&lt;br /&gt;
&lt;br /&gt;
Voici un schéma simplifié de la communication entre les composants :&lt;br /&gt;
* La carte mère écrit dans la RAM SPI via le bus SPI.&lt;br /&gt;
* Le microcontrôleur de la carte fille lit les données de la RAM SPI et les envoie à l'écran LCD pour mise à jour régulière.&lt;br /&gt;
&lt;br /&gt;
=== Schéma de Connexion ===&lt;br /&gt;
//capture ecran a ajouter&lt;br /&gt;
== Ordonnanceur ==&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
L'ordonnanceur est une partie essentielle de notre pico ordinateur. Il est responsable de la gestion des différentes tâches et de leur exécution de manière organisée. L'objectif de cet ordonnanceur est de permettre un partage équitable du temps processeur entre les tâches et d'assurer que chaque tâche puisse accéder aux ressources du système sans conflit.&lt;br /&gt;
&lt;br /&gt;
L'ordonnanceur prend également en compte la gestion des périphériques, tels que notre écran LCD, en s'assurant que chaque périphérique est disponible avant d'envoyer une nouvelle commande.&lt;br /&gt;
&lt;br /&gt;
=== Structure des Tâches ===&lt;br /&gt;
&lt;br /&gt;
Voici comment chaque tâche est représentée dans le système :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
struct Task {&lt;br /&gt;
    int taskID;             // Identifiant unique de la tâche&lt;br /&gt;
    int spiLine;            // Ligne SPI associée à la tâche (pour gérer un périphérique)&lt;br /&gt;
    bool isReady;           // Indique si la tâche est prête à s'exécuter&lt;br /&gt;
    bool isRunning;         // Indique si la tâche est actuellement en cours d'exécution&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Chaque tâche a un identifiant unique `taskID`, ainsi qu'une ligne SPI (`spiLine`) qui lui est assignée pour la gestion des périphériques. Le champ `isReady` permet de savoir si la tâche est prête à être exécutée (par exemple, si le périphérique SPI est disponible), et `isRunning` indique si la tâche est en cours d'exécution.&lt;br /&gt;
&lt;br /&gt;
=== Fonctions de l'Ordonnanceur ===&lt;br /&gt;
&lt;br /&gt;
L'ordonnanceur est principalement basé sur deux fonctions principales :&lt;br /&gt;
&lt;br /&gt;
1. scheduler() : Gère le changement de tâche en fonction de l'algorithme Round Robin.&lt;br /&gt;
2. spiAvailable() : Vérifie la disponibilité de la ligne SPI avant d'exécuter une tâche.&lt;br /&gt;
&lt;br /&gt;
===== Fonction `scheduler()` =====&lt;br /&gt;
La fonction `scheduler()` est responsable du passage d'une tâche à l'autre en suivant l'algorithme Round Robin. Elle incrémente l'indice de la tâche courante et revient au début de la liste si la dernière tâche a été atteinte.&lt;br /&gt;
&lt;br /&gt;
Voici le code de la fonction `scheduler()` :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void scheduler() {&lt;br /&gt;
    // Incrémentation de l'indice de la tâche courante&lt;br /&gt;
    currentTask++;&lt;br /&gt;
    &lt;br /&gt;
    // Si l'indice dépasse le nombre de tâches, on revient à la première tâche&lt;br /&gt;
    if (currentTask == NB_TASKS) {&lt;br /&gt;
        currentTask = 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Vérifie si la tâche suivante est prête à être exécutée&lt;br /&gt;
    if (taskArray[currentTask].isReady &amp;amp;&amp;amp; spiAvailable(taskArray[currentTask].spiLine)) {&lt;br /&gt;
        // Exécuter la tâche si elle est prête et que la ligne SPI est disponible&lt;br /&gt;
        executeTask(taskArray[currentTask].taskID);&lt;br /&gt;
    } else {&lt;br /&gt;
        // Si la tâche n'est pas prête, passe à la tâche suivante&lt;br /&gt;
        scheduler();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explication du Code :&lt;br /&gt;
* currentTask++ : Cette ligne incrémente l'indice de la tâche courante, passant ainsi à la tâche suivante dans la liste.&lt;br /&gt;
* if (currentTask == NB_TASKS) : Si l'ordonnanceur arrive à la fin de la liste des tâches (déterminée par `NB_TASKS`, le nombre total de tâches), il revient à la première tâche (`currentTask = 0`).&lt;br /&gt;
* taskArray[currentTask].isReady : L'ordonnanceur vérifie si la tâche est prête à être exécutée (en attente d'exécution).&lt;br /&gt;
* spiAvailable(taskArray[currentTask].spiLine) : Cette fonction est appelée pour vérifier si la ligne SPI associée à la tâche est disponible (explication ci-dessous).&lt;br /&gt;
* executeTask() : Si la tâche est prête et que la ligne SPI est libre, cette fonction exécute la tâche courante.&lt;br /&gt;
* scheduler() : Si la tâche n'est pas prête ou si la ligne SPI n'est pas disponible, l'ordonnanceur passe à la tâche suivante.&lt;br /&gt;
&lt;br /&gt;
===== Fonction `spiAvailable()` =====&lt;br /&gt;
La fonction `spiAvailable()` vérifie si la ligne SPI associée à une tâche est libre. Cela permet d'éviter que plusieurs tâches tentent d'utiliser la même ligne SPI en même temps, ce qui pourrait causer des conflits d'accès.&lt;br /&gt;
&lt;br /&gt;
Voici le code de la fonction `spiAvailable()` :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
bool spiAvailable(int spiLine) {&lt;br /&gt;
    // Vérifie l'état de la ligne SPI&lt;br /&gt;
    if (getSpiState(spiLine) == SPI_FREE) {&lt;br /&gt;
        return true;&lt;br /&gt;
    } else {&lt;br /&gt;
        return false;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explication du Code :&lt;br /&gt;
* getSpiState(spiLine) : Cette fonction interroge l'état actuel de la ligne SPI spécifiée (`spiLine`). Si la ligne est libre (`SPI_FREE`), la fonction retourne `true`, sinon elle retourne `false`.&lt;br /&gt;
* return true/false : La fonction retourne `true` si la ligne SPI est disponible, permettant ainsi à la tâche de s'exécuter.&lt;br /&gt;
&lt;br /&gt;
===== Fonction `executeTask()` =====&lt;br /&gt;
La fonction `executeTask()` est celle qui exécute la tâche courante une fois qu'elle est prête et que la ligne SPI est disponible. Cette fonction lance la tâche spécifique en fonction de son `taskID`.&lt;br /&gt;
&lt;br /&gt;
Voici un exemple de la fonction `executeTask()` :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void executeTask(int taskID) {&lt;br /&gt;
    switch (taskID) {&lt;br /&gt;
        case 1:&lt;br /&gt;
            // Exécuter la tâche 1 (affichage sur écran LCD)&lt;br /&gt;
            updateLCD();&lt;br /&gt;
            break;&lt;br /&gt;
        case 2:&lt;br /&gt;
            // Exécuter la tâche 2 (lecture d'un clavier SPI)&lt;br /&gt;
            readKeyboard();&lt;br /&gt;
            break;&lt;br /&gt;
        // Ajout d'autres tâches ici...&lt;br /&gt;
        default:&lt;br /&gt;
            // Si la tâche n'est pas reconnue, ne rien faire&lt;br /&gt;
            break;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explication du Code :&lt;br /&gt;
* switch (taskID) : Cette instruction permet de choisir la tâche à exécuter en fonction de l'ID de la tâche.&lt;br /&gt;
* updateLCD() : Exemple d'une tâche qui met à jour l'affichage de l'écran LCD.&lt;br /&gt;
* readKeyboard() : Exemple d'une tâche qui lit les données d'un clavier SPI.&lt;br /&gt;
* default : Si l'ID de la tâche n'est pas reconnu, aucune action n'est effectuée.&lt;br /&gt;
&lt;br /&gt;
===== Gestion des Interruptions =====&lt;br /&gt;
L'ordonnanceur peut également être interrompu si un événement important survient, comme l'arrivée d'une nouvelle commande ou la fin d'une transmission SPI. Ces interruptions sont gérées via des Interrupt Service Routines (ISR), qui permettent de traiter rapidement ces événements sans interrompre l'ordonnancement global.&lt;br /&gt;
&lt;br /&gt;
Un exemple d'ISR :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
ISR(SPI_vect) {&lt;br /&gt;
    // Gestion de l'interruption SPI&lt;br /&gt;
    if (isTransmissionComplete()) {&lt;br /&gt;
        // Marquer la tâche SPI comme terminée&lt;br /&gt;
        taskArray[currentTask].isReady = true;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explication du Code :&lt;br /&gt;
* ISR(SPI_vect) : Cette fonction est une ISR qui est appelée lorsque l'événement lié au SPI se produit (par exemple, la fin d'une transmission).&lt;br /&gt;
* isTransmissionComplete() : Vérifie si la transmission SPI est terminée.&lt;br /&gt;
* taskArray[currentTask].isReady = true : Marque la tâche comme prête à être exécutée à nouveau.&lt;br /&gt;
L'ordonnanceur joue un rôle central dans notre pico ordinateur, en gérant les tâches et en s'assurant que chaque tâche a accès aux ressources SPI sans conflit. Ce système d'ordonnancement permet d'assurer un fonctionnement fluide et sans interruption de notre pico ordinateur.&lt;br /&gt;
&lt;br /&gt;
== Carte Shield ==&lt;br /&gt;
&lt;br /&gt;
=== Description ===&lt;br /&gt;
La carte Shield est une carte mère qui sert à connecter et contrôler divers périphériques, notamment la carte fille (écran), un clavier, et d'autres composants. Nous avons conçu cette carte pour faciliter la gestion des communications SPI entre la carte mère et les différentes cartes filles.&lt;br /&gt;
&lt;br /&gt;
=== Connectivité SPI ===&lt;br /&gt;
La carte Shield utilise plusieurs lignes SPI pour communiquer avec les cartes filles. Chaque périphérique, comme l'écran, est assigné à une ligne SPI spécifique. La carte Shield vérifie également la disponibilité des périphériques avant d'envoyer des commandes via SPI.&lt;br /&gt;
&lt;br /&gt;
== Tests Réalisés ==&lt;br /&gt;
&lt;br /&gt;
=== Tests de l'Ordonnanceur //acompleter ===&lt;br /&gt;
* Gestion des tâches : Nous avons simulé plusieurs tâches, dont l'affichage et la gestion du clavier, et vérifié que l'ordonnanceur passe correctement d'une tâche à l'autre.&lt;br /&gt;
* En utilisant le logiciel minicom nous avons pus lancer une 2eme tâche en parallèle d'une première tâche. En tapant &amp;quot;a&amp;quot; une deuxième LED se met a clignoter.&lt;br /&gt;
* //image et video&lt;br /&gt;
&lt;br /&gt;
=== Tests de la RAM SPI //a completer ===&lt;br /&gt;
* Stockage des données d'affichage :&lt;/div&gt;</summary>
		<author><name>Mbarret</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-2&amp;diff=6291</id>
		<title>SE4Binome2024-2</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-2&amp;diff=6291"/>
		<updated>2024-10-15T13:39:17Z</updated>

		<summary type="html">&lt;p&gt;Mbarret : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Carte Shield ===&lt;br /&gt;
&lt;br /&gt;
Nous avons soudé et réalisé les différents tests concernant la carte Shield Arduino.&lt;br /&gt;
Nous avons réussi à faire clignoter les LED, tester les différents connecteurs à l'aide d'un afficheur 7 segments ainsi que le lecteur de carte SD.&lt;br /&gt;
&lt;br /&gt;
Pour ce faire, nous avons utiliser les différents codes exemples directement mis à disposition dans le logiciel Arduino.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ordonnanceur ===&lt;br /&gt;
&lt;br /&gt;
Pour l'ordonnanceur, nous avons initialisé le timer ainsi que les différentes tâches. Malheureusement, nous avons pas encore réussi à réaliser ces différentes tâches en utilisant notre ordonnanceur.&lt;br /&gt;
&lt;br /&gt;
=== Carte fille afficheur ===&lt;br /&gt;
&lt;br /&gt;
Nous avons commencé à réaliser le schématique de notre carte fille.&lt;/div&gt;</summary>
		<author><name>Mbarret</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-2&amp;diff=6284</id>
		<title>SE4Binome2024-2</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-2&amp;diff=6284"/>
		<updated>2024-10-15T13:32:16Z</updated>

		<summary type="html">&lt;p&gt;Mbarret : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Carte Shield ===&lt;br /&gt;
&lt;br /&gt;
Nous avons soudé et réalisé les différents tests concernant la carte Shield Arduino.&lt;br /&gt;
Nous avons réussi à faire clignoter les LED, tester les différents connecteurs à l'aide d'un afficheur 7 segments ainsi que le lecteur de carte SD.&lt;br /&gt;
&lt;br /&gt;
Pour ce faire, nous avons utiliser les différents codes exemples directement mis à disposition dans le logiciel Arduino.&lt;/div&gt;</summary>
		<author><name>Mbarret</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2023-3&amp;diff=5759</id>
		<title>SE3Binome2023-3</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2023-3&amp;diff=5759"/>
		<updated>2024-06-12T20:13:16Z</updated>

		<summary type="html">&lt;p&gt;Mbarret : /* Séance du 6 Juin 2024 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=&amp;lt;div class=&amp;quot;mcwiki-header&amp;quot; style=&amp;quot;border-radius: 40px; padding: 15px; font-weight: bold; color: #FFFFFF; text-align: center; font-size: 80%; background: #33AFDE; vertical-align: top; width: 98%;&amp;quot;&amp;gt; Voiture VigiCar &amp;lt;/div&amp;gt;=&lt;br /&gt;
''Notre projet est une voiture commandée par USB. Lorsqu'elle détecte un obstacle, elle s'arrête et déclenche un signal d'alerte (Warning). Quand l'obstacle est enlevé, elle continue son chemin.''&lt;br /&gt;
&lt;br /&gt;
''L'utilisateur peut donner différentes instructions : avancer, reculer, s’arrêter pendant une durée définie, ou exécuter une instruction tant qu'aucun obstacle n'est détecté.'' &lt;br /&gt;
&lt;br /&gt;
=&amp;lt;div class=&amp;quot;mcwiki-header&amp;quot; style=&amp;quot;border-radius: 40px; padding: 15px; font-weight: bold; color: #FFFFFF; text-align: center; font-size: 80%; background: #97D8F0; vertical-align: top; width: 98%;&amp;quot;&amp;gt; Limitations et fonctionnalités&amp;lt;/div&amp;gt;=&lt;br /&gt;
&lt;br /&gt;
* Taille de la carte : 10x10 cm maximum&lt;br /&gt;
&lt;br /&gt;
* Éclairage :&lt;br /&gt;
** 4 LEDs oranges à l'avant et à l'arrière pour les feux de warning&lt;br /&gt;
** 2 LEDs jaunes à l'avant pour les phares avant&lt;br /&gt;
** 2 LEDs blanches à l'arrière pour les feux de recul&lt;br /&gt;
** 2 LEDs rouges à l'arrière pour les feux stop&lt;br /&gt;
&lt;br /&gt;
* Programmation : Par USB&lt;br /&gt;
* Gestion de l’énergie : Par batterie LiPo&lt;br /&gt;
* Détection d'obstacles : Capteur de proximité placé à l'avant &lt;br /&gt;
&lt;br /&gt;
=&amp;lt;div class=&amp;quot;mcwiki-header&amp;quot; style=&amp;quot;border-radius: 40px; padding: 15px; font-weight: bold; color: #FFFFFF; text-align: center; font-size: 80%; background: #97D8F0; vertical-align: top; width: 98%;&amp;quot;&amp;gt;Matériel&amp;lt;/div&amp;gt;=&lt;br /&gt;
[[Fichier:Composants.png|droite|sans_cadre|400x400px]]&lt;br /&gt;
&lt;br /&gt;
* [https://www.farnell.com/datasheets/2369105.pdf Batterie LiPo]&lt;br /&gt;
* [https://www.analog.com/media/cn/technical-documentation/data-sheets/2536.pdf Puce de contrôle MAX1811]&lt;br /&gt;
* 4 LEDs &amp;lt;span style=&amp;quot;color: DarkOrange;&amp;quot;&amp;gt;oranges&amp;lt;/span&amp;gt;&lt;br /&gt;
* 2 LEDs &amp;lt;span style=&amp;quot;color: Gold;&amp;quot;&amp;gt;jaunes&amp;lt;/span&amp;gt; (qui ressortent oranges au final)&lt;br /&gt;
* 2 LEDs &amp;lt;span style=&amp;quot;color: Silver;&amp;quot;&amp;gt;blanches&amp;lt;/span&amp;gt;&lt;br /&gt;
* 2 LEDs &amp;lt;span style=&amp;quot;color: Red;&amp;quot;&amp;gt;rouges&amp;lt;/span&amp;gt;&lt;br /&gt;
* 2 Mini moteurs continus &amp;amp; Pilotes des moteurs&lt;br /&gt;
* Capteur de proximité&lt;br /&gt;
* Port USB&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;div class=&amp;quot;mcwiki-header&amp;quot; style=&amp;quot;border-radius: 40px; padding: 15px; font-weight: bold; color: #FFFFFF; text-align: center; font-size: 80%; background: #97D8F0; vertical-align: top; width: 98%;&amp;quot;&amp;gt;Déroulé du Projet&amp;lt;/div&amp;gt;=&lt;br /&gt;
&lt;br /&gt;
==Séance du 5 Mars 2024==&lt;br /&gt;
Nous avons choisi d'intégrer un capteur de proximité à notre voiture pour améliorer sa réactivité aux obstacles. Pour assurer une autonomie adéquate, nous utiliserons une alimentation par batterie. De plus, la voiture sera capable d'exécuter divers programmes prédéfinis, lui permettant de naviguer de manière autonome tout en répondant aux commandes de l'utilisateur.&lt;br /&gt;
&lt;br /&gt;
== Séance du 12 Mars 2024 == &lt;br /&gt;
Nous avons finalisé le choix des composants et commencé la conception du schéma électrique de notre PCB. Cependant, le problème qu'il pourrait y avoir en mettant les LEDs en série comme nous l'avons fait est qu'elle ne seront pas alimentées correctement. Nous allons donc les mettre en parallèle afin de résoudre cette complication. Dans tout les cas, cela ne posera pas de problème pour la programmation des LEDs.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Schematics1.pdf|centre|800x800px|sans_cadre]]&lt;br /&gt;
&lt;br /&gt;
==Séance du 19 Mars 2024== &lt;br /&gt;
Le schéma électrique est terminé. Nous avons corrigé le layout du PCB en respectant les contraintes de taille, le problème d'alimentation des LEDs, et nous avons rajouté les éléments manquants tels que l'alimentation et le contrôleur moteur. &lt;br /&gt;
&lt;br /&gt;
[[Fichier:SE3-pad.pdf|gauche|500x500px|sans_cadre]][[Fichier:SE3-pad-Alim_+_gestion_moteur.pdf|sans_cadre|500x500px]][[Fichier:Mypcb.png|gauche|500x500px|sans_cadre]][[Fichier:Myvue3d.png|sans_cadre|450x450px]]&lt;br /&gt;
&lt;br /&gt;
==Séance du 2 Avril 2024==&lt;br /&gt;
Création de notre archive GIT pour la gestion des versions et le suivi du projet. &lt;br /&gt;
*Voici notre lien git : [https://archives.plil.fr/mbarret/voiture.git VigiCar Git Archive]&lt;br /&gt;
&lt;br /&gt;
== Séance du 7 Mai 2024==&lt;br /&gt;
[[Fichier:Soudure part 1.jpg|gauche|300x300px|bordure|sans_cadre]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Nous avons reçu notre PCB. Nous commençons à souder les composants (ATmega16u4, Quartz, Port USB, ISP, etc.). L'ATmega16u4 a déjà un Bootloader préinstallé.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Séance du 14 Mai 2024==&lt;br /&gt;
Nous avons continué les soudures, en particulier le contrôleur de moteur. Il reste maintenant à le tester.&lt;br /&gt;
&lt;br /&gt;
==Séance du 21 Mai 2024==&lt;br /&gt;
Lors de la séance précédente, nous avions fini de souder le contrôleur de moteur. Nous soudons un des moteurs à l'aide de fils que nous replierons sur eux-mêmes à la fin. Pour tester le moteur, nous écrivons un programme.&lt;br /&gt;
&lt;br /&gt;
Dans un premier temps, nous écrivons un programme qui consiste seulement à faire tourner le moteur :&lt;br /&gt;
[[Fichier:Code1.png|gauche|sans_cadre|412x412px]]&lt;br /&gt;
[[Fichier:Moteur_1.mp4|600x550px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ensuite, nous cherchons à manipuler la vitesse de rotation du moteur. Nous écrivons un programme permettant d'augmenter progressivement la vitesse de ce dernier :&lt;br /&gt;
[[Fichier:Code2.png|gauche|500x500px|sans_cadre]]&lt;br /&gt;
[[Fichier:Moteur prog.mp4|néant|bordure|500x500px]]&lt;br /&gt;
&lt;br /&gt;
==Séance du 28 Mai 2024==&lt;br /&gt;
Lors de cette séance, nous nous sommes séparés pour, d'une part, réparer les problèmes de soudure des LEDs, souder le capteur de proximité et d'autre part, préparer un code pour manipuler les LEDs et vérifier leur fonctionnement. &lt;br /&gt;
&lt;br /&gt;
Concernant la soudure du capteur de proximité, nous avons opté pour du &amp;quot;bricolage&amp;quot;. En effet, le capteur devant être monté à la verticale, il faut relier les PINs du dessus à la carte. Pour cela nous utiliserons des fils. &lt;br /&gt;
[[Fichier:Tst nvx capteur.mp4|gauche|sans_cadre|250x250px]]&lt;br /&gt;
[[Fichier:Capteur off.png|droite|sans_cadre|306x306px]]&lt;br /&gt;
[[Fichier:Datasheet proxi.png|centré|sans_cadre|418x418px]]&lt;br /&gt;
A la première tentative, le capteur ne fonctionnait pas, nous avons donc cherché la cause de ce problème (test de la camera, mesure de la tension dans les PINs, etc.). En regardant la datasheet du capteur nous voyons que le capteur ne supporte une température de 260°C que pendant 10 secondes. Nous l'avions donc bien rendu inutilisable. Nous testons un nouveau capteur avant toute soudure. Nous le mettons en place sur la carte:&lt;br /&gt;
[[Fichier:Capteur is on.jpg|centré|sans_cadre|548x548px]]&lt;br /&gt;
&lt;br /&gt;
Nous avons donc ressoudé un autre capteur en faisant plus attention. Reste maintenant à le programmer. Voici une première version de notre code : &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;util/delay.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define PWM_DDRB         DDRB&lt;br /&gt;
#define PWM_PORTB        PORTB&lt;br /&gt;
#define PWM_DDRD         DDRD&lt;br /&gt;
#define PWM_PORTD        PORTD&lt;br /&gt;
#define CAPTEUR         5&lt;br /&gt;
#define AIN1            6&lt;br /&gt;
#define AIN2            5&lt;br /&gt;
#define BIN1            1&lt;br /&gt;
#define BIN2            2&lt;br /&gt;
#define PWM1            7&lt;br /&gt;
#define PWM2            0&lt;br /&gt;
&lt;br /&gt;
#define LED_G1 PF0&lt;br /&gt;
#define LED_G2 PF4&lt;br /&gt;
#define LED_D1 PC6&lt;br /&gt;
#define LED_D2 PD4&lt;br /&gt;
#define LED_STOP_G PF6&lt;br /&gt;
#define LED_STOP_D PD5&lt;br /&gt;
#define LED_PHARES_G PF1&lt;br /&gt;
#define LED_PHARES_D PC7&lt;br /&gt;
#define LED_RECUL_G PF7&lt;br /&gt;
#define LED_RECUL_D PD3&lt;br /&gt;
#define JTD 7&lt;br /&gt;
&lt;br /&gt;
void PWM_init(void){               // Initialisation de la PWM&lt;br /&gt;
    PWM_DDRB |= (1&amp;lt;&amp;lt;PWM1);      // Les ports PWM sont des sorties&lt;br /&gt;
    PWM_DDRD |= (1&amp;lt;&amp;lt;PWM2);&lt;br /&gt;
    TCCR0A |= (1&amp;lt;&amp;lt;COM0A1)|(1&amp;lt;&amp;lt;COM0B1);   // Les ports PWM se comportent normalement&lt;br /&gt;
    TCCR0A |= (1&amp;lt;&amp;lt;WGM01)|(1&amp;lt;&amp;lt;WGM00);     // Minuteur mis en mode PWM&lt;br /&gt;
    TCCR0B |= (1&amp;lt;&amp;lt;CS00);                 // Pas de pré-diviseur, démarre le compteur&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void LED_init(void)&lt;br /&gt;
{&lt;br /&gt;
    DDRD |= (1&amp;lt;&amp;lt;LED_D2) |(1&amp;lt;&amp;lt;LED_STOP_D)|(1&amp;lt;&amp;lt;LED_RECUL_D);&lt;br /&gt;
    DDRC |= (1&amp;lt;&amp;lt;LED_D1) |(1&amp;lt;&amp;lt;LED_PHARES_D);&lt;br /&gt;
    DDRF |= (1&amp;lt;&amp;lt;LED_G1) |(1&amp;lt;&amp;lt;LED_G2)|(1&amp;lt;&amp;lt;LED_STOP_G)|(1&amp;lt;&amp;lt;LED_PHARES_G) |(1&amp;lt;&amp;lt;LED_RECUL_G);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void capteur_init(void)&lt;br /&gt;
{&lt;br /&gt;
    DDRF &amp;amp;= ~(1&amp;lt;&amp;lt;CAPTEUR);&lt;br /&gt;
}&lt;br /&gt;
int main(void){&lt;br /&gt;
&lt;br /&gt;
    CLKSEL0 = 0b00010101;   // sélection de l'horloge externe&lt;br /&gt;
    CLKSEL1 = 0b00001111;   // minimum de 8Mhz&lt;br /&gt;
    CLKPR = 0b10000000;     // modification du diviseur d'horloge (CLKPCE=1)&lt;br /&gt;
    CLKPR = 0;              // 0 pour pas de diviseur (diviseur de 1)&lt;br /&gt;
    &lt;br /&gt;
    MCUCR |= (1&amp;lt;&amp;lt;JTD);&lt;br /&gt;
    MCUCR |= (1&amp;lt;&amp;lt;JTD);&lt;br /&gt;
    PWM_init();&lt;br /&gt;
    LED_init();&lt;br /&gt;
    capteur_init();&lt;br /&gt;
    int pwm=0;&lt;br /&gt;
    PWM_DDRB |= (1&amp;lt;&amp;lt;AIN1)|(1&amp;lt;&amp;lt;AIN2);&lt;br /&gt;
    PWM_PORTB |= (1&amp;lt;&amp;lt;AIN1)|(0&amp;lt;&amp;lt;AIN2);&lt;br /&gt;
    PWM_DDRD |= (1&amp;lt;&amp;lt;BIN1)|(1&amp;lt;&amp;lt;BIN2);&lt;br /&gt;
    PWM_PORTD |= (0&amp;lt;&amp;lt;BIN1)|(1&amp;lt;&amp;lt;BIN2);&lt;br /&gt;
    while (1)&lt;br /&gt;
    {&lt;br /&gt;
        pwm++;&lt;br /&gt;
        if ((PORTF&amp;gt;&amp;gt;CAPTEUR) &amp;amp;1){&lt;br /&gt;
            pwm=0;&lt;br /&gt;
            PORTC|=0x00;&lt;br /&gt;
        }&lt;br /&gt;
        if (pwm &amp;gt;255) pwm=0;&lt;br /&gt;
        OCR0A=pwm;&lt;br /&gt;
        OCR0B=pwm;&lt;br /&gt;
        PORTC |=0b11000000;&lt;br /&gt;
        PORTD |=0b00111000; &lt;br /&gt;
        PORTF |=0b11010011;  &lt;br /&gt;
        _delay_ms(100);&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Ce code nous a permi de vérifier le fonctionnement des LEDs mais pas celui du capteur pour le moment.&lt;br /&gt;
&lt;br /&gt;
==Séance du 4 Juin 2024==&lt;br /&gt;
&lt;br /&gt;
Aujourd'hui nous avons avancé sur le contrôle des LEDs et du capteur de proximité que nous avons enfin fait fonctionner. &lt;br /&gt;
Nous avons désormais une voiture qui roule, phares allumés. Si elle rencontre un obstacle, elle s'arrête puis déclenche ses warnings. Elle possède aussi un bouton start qui lance le programme. Nous avons alors ajouter des fonctions à notre programme. &lt;br /&gt;
[[Fichier:Proxi feux stop.mp4|bordure|gauche|600x600px]] &lt;br /&gt;
Cet ajout permet d'avoir une voiture qui s'arrête dès la détection d'un obstacle et qui donc allume ses feux stop.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void init_boutton(void)&lt;br /&gt;
{&lt;br /&gt;
    DDRD &amp;amp;= ~(1&amp;lt;&amp;lt;START);&lt;br /&gt;
    PORTD |= (1&amp;lt;&amp;lt;START);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void init_moteur(void)&lt;br /&gt;
{&lt;br /&gt;
        PWM_DDRB |= (1&amp;lt;&amp;lt;AIN1)|(1&amp;lt;&amp;lt;AIN2);&lt;br /&gt;
        PWM_DDRD |= (1&amp;lt;&amp;lt;BIN1)|(1&amp;lt;&amp;lt;BIN2);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void avancer(void)&lt;br /&gt;
{&lt;br /&gt;
    PWM_PORTB |= (1&amp;lt;&amp;lt;AIN1);&lt;br /&gt;
    PWM_PORTB &amp;amp;= ~(1&amp;lt;&amp;lt;AIN2);&lt;br /&gt;
    &lt;br /&gt;
    PWM_PORTD &amp;amp;= ~(1&amp;lt;&amp;lt;BIN1);&lt;br /&gt;
    PWM_PORTD |= (1&amp;lt;&amp;lt;BIN2);&lt;br /&gt;
    &lt;br /&gt;
    //PWM_PORTB |= (1&amp;lt;&amp;lt;AIN1)|(0&amp;lt;&amp;lt;AIN2);&lt;br /&gt;
    //PWM_PORTD |= (0&amp;lt;&amp;lt;BIN1)|(1&amp;lt;&amp;lt;BIN2);&lt;br /&gt;
    OCR0A=180;&lt;br /&gt;
    OCR0B=180;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void arret(void)&lt;br /&gt;
{&lt;br /&gt;
    PWM_PORTB &amp;amp;= ~(1&amp;lt;&amp;lt;AIN1);&lt;br /&gt;
    PWM_PORTB &amp;amp;= ~(1&amp;lt;&amp;lt;AIN2);&lt;br /&gt;
    &lt;br /&gt;
    PWM_PORTD &amp;amp;= ~(1&amp;lt;&amp;lt;BIN1);&lt;br /&gt;
    PWM_PORTD &amp;amp;= ~(1&amp;lt;&amp;lt;BIN2);&lt;br /&gt;
    &lt;br /&gt;
    //PWM_PORTB |= (0&amp;lt;&amp;lt;AIN1)|(0&amp;lt;&amp;lt;AIN2);&lt;br /&gt;
    //PWM_PORTD |= (0&amp;lt;&amp;lt;BIN1)|(0&amp;lt;&amp;lt;BIN2);&lt;br /&gt;
    OCR0A=0;&lt;br /&gt;
    OCR0B=0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explication sur la programmation du capteur:&lt;br /&gt;
&lt;br /&gt;
Dans notre programme, nous utilisons le capteur OPB733TR pour mesurer une condition spécifique en lisant des valeurs analogiques. Ces valeurs, qui représentent les informations captées par le capteur, sont converties en signaux numériques que notre microcontrôleur peut traiter. Pour réaliser cette conversion, nous utilisons un Convertisseur Analogique-Numérique (ADC) intégré.&lt;br /&gt;
&lt;br /&gt;
L'ADC agit comme un traducteur qui transforme les niveaux de tension analogiques en valeurs numériques compréhensibles par le microcontrôleur. Cette opération se déroule très rapidement grâce à l'ADC de notre microcontrôleur, qui peut effectuer des conversions en un temps très court. Cela nous permet de capturer et de traiter les informations du capteur presque instantanément.&lt;br /&gt;
&lt;br /&gt;
Dans notre boucle principale, le microcontrôleur lit périodiquement les valeurs analogiques converties par l'ADC. Ces valeurs sont comparées à une limite prédéfinie (`LIMITE`), configurée pour déclencher des actions spécifiques lorsque les conditions détectées par le capteur le nécessitent. Si le capteur détecte une certaine condition (définie lorsque les valeurs analogiques sont inférieures à la limite), notre programme réagit en arrêtant la voiture, activant les feux de stop, les clignotants et même en mettant la voiture en marche arrière si nécessaire.&lt;br /&gt;
&lt;br /&gt;
En parallèle, un compteur est utilisé pour comptabiliser le nombre de fois où les lectures du capteur sont en dessous de la limite spécifiée. Lorsque ce compteur dépasse un certain seuil (7 dans ce cas), cela indique qu'un obstacle est présent. Cette gestion du compteur permet à notre système de prendre des décisions en fonction des conditions détectées par le capteur, garantissant ainsi la vigilance de notre VigiCar.&lt;br /&gt;
&lt;br /&gt;
Ce processus en temps réel, facilité par l'ADC rapide et le compteur intégré, nous permet de surveiller efficacement les conditions environnementales et de répondre à la présence d'un obstacle en faisant reculer la voiture, qui par la même occasion allume ses feux de recul.&lt;br /&gt;
&lt;br /&gt;
==Séance du 6 Juin 2024==&lt;br /&gt;
Lors de cette séance nous avons terminé notre VigiCar en installant l'alimentation par batterie.&lt;br /&gt;
&lt;br /&gt;
Pour ce faire, nous avons voulu isoler la partie du circuit concernant la batterie du reste. Pour cela nous avons donc décidé d’intégrer un deuxième port USB-mini consacré à la charge d’une batterie de 3.7V afin de garantir une alimentation non filaire.&lt;br /&gt;
&lt;br /&gt;
Afin de vérifier le bon rechargement de la batterie, nous avons installer une LED orange D4 qui s’allume en cas de recharge.&lt;br /&gt;
&lt;br /&gt;
Pour utiliser l’alimentation sur batterie, il nous suffit de placer un cavalier sur le connecteur J9. Et pour la recharger, on doit en utiliser deux sur les connecteurs J5 et J6. Il faut cependant faire très attention au placement des cavaliers selon l’utilisation. Si on désire modifier le code (par USB donc), nous devons impérativement vérifier que le cavalier en J9 est bien enlevé. Si ce n’est pas le cas, nous avons donc donc deux alimentations simultanées (USB et batterie) ce qui peut provoquer des dysfonctionnements.&lt;br /&gt;
&lt;br /&gt;
Nous avons également installer une diode (D5) pour envoyer le courant de la batterie dans le capteur IR en l’absence de source USB.&lt;br /&gt;
&lt;br /&gt;
Enfin, nous avons décider d’installer le connecteur de la batterie  (J7) sous la carte pour des questions pratiques.&lt;/div&gt;</summary>
		<author><name>Mbarret</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2023-3&amp;diff=5744</id>
		<title>SE3Binome2023-3</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2023-3&amp;diff=5744"/>
		<updated>2024-06-12T20:04:10Z</updated>

		<summary type="html">&lt;p&gt;Mbarret : /* Séance du 6 Juin 2024 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=&amp;lt;div class=&amp;quot;mcwiki-header&amp;quot; style=&amp;quot;border-radius: 40px; padding: 15px; font-weight: bold; color: #FFFFFF; text-align: center; font-size: 80%; background: #33AFDE; vertical-align: top; width: 98%;&amp;quot;&amp;gt; Voiture VigiCar &amp;lt;/div&amp;gt;=&lt;br /&gt;
''Notre projet est une voiture commandée par USB. Lorsqu'elle détecte un obstacle, elle s'arrête et déclenche un signal d'alerte (Warning). Quand l'obstacle est enlevé, elle continue son chemin.''&lt;br /&gt;
&lt;br /&gt;
''L'utilisateur peut donner différentes instructions : avancer, reculer, s’arrêter pendant une durée définie, ou exécuter une instruction tant qu'aucun obstacle n'est détecté.'' &lt;br /&gt;
&lt;br /&gt;
=&amp;lt;div class=&amp;quot;mcwiki-header&amp;quot; style=&amp;quot;border-radius: 40px; padding: 15px; font-weight: bold; color: #FFFFFF; text-align: center; font-size: 80%; background: #97D8F0; vertical-align: top; width: 98%;&amp;quot;&amp;gt; Limitations et fonctionnalités&amp;lt;/div&amp;gt;=&lt;br /&gt;
&lt;br /&gt;
* Taille de la carte : 10x10 cm maximum&lt;br /&gt;
&lt;br /&gt;
* Éclairage :&lt;br /&gt;
** 4 LEDs oranges à l'avant et à l'arrière pour les feux de warning&lt;br /&gt;
** 2 LEDs jaunes à l'avant pour les phares avant&lt;br /&gt;
** 2 LEDs blanches à l'arrière pour les feux de recul&lt;br /&gt;
** 2 LEDs rouges à l'arrière pour les feux stop&lt;br /&gt;
&lt;br /&gt;
* Programmation : Par USB&lt;br /&gt;
* Gestion de l’énergie : Par batterie LiPo&lt;br /&gt;
* Détection d'obstacles : Capteur de proximité placé à l'avant &lt;br /&gt;
&lt;br /&gt;
=&amp;lt;div class=&amp;quot;mcwiki-header&amp;quot; style=&amp;quot;border-radius: 40px; padding: 15px; font-weight: bold; color: #FFFFFF; text-align: center; font-size: 80%; background: #97D8F0; vertical-align: top; width: 98%;&amp;quot;&amp;gt;Matériel&amp;lt;/div&amp;gt;=&lt;br /&gt;
[[Fichier:Composants.png|droite|sans_cadre|400x400px]]&lt;br /&gt;
&lt;br /&gt;
* [https://www.farnell.com/datasheets/2369105.pdf Batterie LiPo]&lt;br /&gt;
* [https://www.analog.com/media/cn/technical-documentation/data-sheets/2536.pdf Puce de contrôle MAX1811]&lt;br /&gt;
* 4 LEDs &amp;lt;span style=&amp;quot;color: DarkOrange;&amp;quot;&amp;gt;oranges&amp;lt;/span&amp;gt;&lt;br /&gt;
* 2 LEDs &amp;lt;span style=&amp;quot;color: Gold;&amp;quot;&amp;gt;jaunes&amp;lt;/span&amp;gt; (qui ressortent oranges au final)&lt;br /&gt;
* 2 LEDs &amp;lt;span style=&amp;quot;color: Silver;&amp;quot;&amp;gt;blanches&amp;lt;/span&amp;gt;&lt;br /&gt;
* 2 LEDs &amp;lt;span style=&amp;quot;color: Red;&amp;quot;&amp;gt;rouges&amp;lt;/span&amp;gt;&lt;br /&gt;
* 2 Mini moteurs continus &amp;amp; Pilotes des moteurs&lt;br /&gt;
* Capteur de proximité&lt;br /&gt;
* Port USB&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;div class=&amp;quot;mcwiki-header&amp;quot; style=&amp;quot;border-radius: 40px; padding: 15px; font-weight: bold; color: #FFFFFF; text-align: center; font-size: 80%; background: #97D8F0; vertical-align: top; width: 98%;&amp;quot;&amp;gt;Déroulé du Projet&amp;lt;/div&amp;gt;=&lt;br /&gt;
&lt;br /&gt;
==Séance du 5 Mars 2024==&lt;br /&gt;
Nous avons choisi d'intégrer un capteur de proximité à notre voiture pour améliorer sa réactivité aux obstacles. Pour assurer une autonomie adéquate, nous utiliserons une alimentation par batterie. De plus, la voiture sera capable d'exécuter divers programmes prédéfinis, lui permettant de naviguer de manière autonome tout en répondant aux commandes de l'utilisateur.&lt;br /&gt;
&lt;br /&gt;
== Séance du 12 Mars 2024 == &lt;br /&gt;
Nous avons finalisé le choix des composants et commencé la conception du schéma électrique de notre PCB. Cependant, le problème qu'il pourrait y avoir en mettant les LEDs en série comme nous l'avons fait est qu'elle ne seront pas alimentées correctement. Nous allons donc les mettre en parallèle afin de résoudre cette complication. Dans tout les cas, cela ne posera pas de problème pour la programmation des LEDs.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Schematics1.pdf|centre|800x800px|sans_cadre]]&lt;br /&gt;
&lt;br /&gt;
==Séance du 19 Mars 2024== &lt;br /&gt;
Le schéma électrique est terminé. Nous avons corrigé le layout du PCB en respectant les contraintes de taille, le problème d'alimentation des LEDs, et nous avons rajouté les éléments manquants tels que l'alimentation et le contrôleur moteur. &lt;br /&gt;
&lt;br /&gt;
[[Fichier:SE3-pad.pdf|gauche|500x500px|sans_cadre]][[Fichier:SE3-pad-Alim_+_gestion_moteur.pdf|sans_cadre|500x500px]][[Fichier:Mypcb.png|gauche|500x500px|sans_cadre]][[Fichier:Myvue3d.png|sans_cadre|450x450px]]&lt;br /&gt;
&lt;br /&gt;
==Séance du 2 Avril 2024==&lt;br /&gt;
Création de notre archive GIT pour la gestion des versions et le suivi du projet. &lt;br /&gt;
*Voici notre lien git : [https://archives.plil.fr/mbarret/voiture.git VigiCar Git Archive]&lt;br /&gt;
&lt;br /&gt;
== Séance du 7 Mai 2024==&lt;br /&gt;
[[Fichier:Soudure part 1.jpg|gauche|300x300px|bordure|sans_cadre]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Nous avons reçu notre PCB. Nous commençons à souder les composants (ATmega16u4, Quartz, Port USB, ISP, etc.). L'ATmega16u4 a déjà un Bootloader préinstallé.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Séance du 14 Mai 2024==&lt;br /&gt;
Nous avons continué les soudures, en particulier le contrôleur de moteur. Il reste maintenant à le tester.&lt;br /&gt;
&lt;br /&gt;
==Séance du 21 Mai 2024==&lt;br /&gt;
Lors de la séance précédente, nous avions fini de souder le contrôleur de moteur. Nous soudons un des moteurs à l'aide de fils que nous replierons sur eux-mêmes à la fin. Pour tester le moteur, nous écrivons un programme.&lt;br /&gt;
&lt;br /&gt;
Dans un premier temps, nous écrivons un programme qui consiste seulement à faire tourner le moteur :&lt;br /&gt;
[[Fichier:Code1.png|gauche|sans_cadre|412x412px]]&lt;br /&gt;
[[Fichier:Moteur_1.mp4|600x550px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ensuite, nous cherchons à manipuler la vitesse de rotation du moteur. Nous écrivons un programme permettant d'augmenter progressivement la vitesse de ce dernier :&lt;br /&gt;
[[Fichier:Code2.png|gauche|500x500px|sans_cadre]]&lt;br /&gt;
[[Fichier:Moteur prog.mp4|néant|bordure|500x500px]]&lt;br /&gt;
&lt;br /&gt;
==Séance du 28 Mai 2024==&lt;br /&gt;
Lors de cette séance, nous nous sommes séparés pour, d'une part, réparer les problèmes de soudure des LEDs, souder le capteur de proximité et d'autre part, préparer un code pour manipuler les LEDs et vérifier leur fonctionnement. &lt;br /&gt;
&lt;br /&gt;
Concernant la soudure du capteur de proximité, nous avons opté pour du &amp;quot;bricolage&amp;quot;. En effet, le capteur devant être monté à la verticale, il faut relier les PINs du dessus à la carte. Pour cela nous utiliserons des fils. &lt;br /&gt;
[[Fichier:Tst nvx capteur.mp4|gauche|sans_cadre|250x250px]]&lt;br /&gt;
[[Fichier:Capteur off.png|droite|sans_cadre|306x306px]]&lt;br /&gt;
[[Fichier:Datasheet proxi.png|centré|sans_cadre|418x418px]]&lt;br /&gt;
A la première tentative, le capteur ne fonctionnait pas, nous avons donc cherché la cause de ce problème (test de la camera, mesure de la tension dans les PINs, etc.). En regardant la datasheet du capteur nous voyons que le capteur ne supporte une température de 260°C que pendant 10 secondes. Nous l'avions donc bien rendu inutilisable. Nous testons un nouveau capteur avant toute soudure. Nous le mettons en place sur la carte:&lt;br /&gt;
[[Fichier:Capteur is on.jpg|centré|sans_cadre|548x548px]]&lt;br /&gt;
&lt;br /&gt;
Nous avons donc ressoudé un autre capteur en faisant plus attention. Reste maintenant à le programmer. Voici une première version de notre code : &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;util/delay.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define PWM_DDRB         DDRB&lt;br /&gt;
#define PWM_PORTB        PORTB&lt;br /&gt;
#define PWM_DDRD         DDRD&lt;br /&gt;
#define PWM_PORTD        PORTD&lt;br /&gt;
#define CAPTEUR         5&lt;br /&gt;
#define AIN1            6&lt;br /&gt;
#define AIN2            5&lt;br /&gt;
#define BIN1            1&lt;br /&gt;
#define BIN2            2&lt;br /&gt;
#define PWM1            7&lt;br /&gt;
#define PWM2            0&lt;br /&gt;
&lt;br /&gt;
#define LED_G1 PF0&lt;br /&gt;
#define LED_G2 PF4&lt;br /&gt;
#define LED_D1 PC6&lt;br /&gt;
#define LED_D2 PD4&lt;br /&gt;
#define LED_STOP_G PF6&lt;br /&gt;
#define LED_STOP_D PD5&lt;br /&gt;
#define LED_PHARES_G PF1&lt;br /&gt;
#define LED_PHARES_D PC7&lt;br /&gt;
#define LED_RECUL_G PF7&lt;br /&gt;
#define LED_RECUL_D PD3&lt;br /&gt;
#define JTD 7&lt;br /&gt;
&lt;br /&gt;
void PWM_init(void){               // Initialisation de la PWM&lt;br /&gt;
    PWM_DDRB |= (1&amp;lt;&amp;lt;PWM1);      // Les ports PWM sont des sorties&lt;br /&gt;
    PWM_DDRD |= (1&amp;lt;&amp;lt;PWM2);&lt;br /&gt;
    TCCR0A |= (1&amp;lt;&amp;lt;COM0A1)|(1&amp;lt;&amp;lt;COM0B1);   // Les ports PWM se comportent normalement&lt;br /&gt;
    TCCR0A |= (1&amp;lt;&amp;lt;WGM01)|(1&amp;lt;&amp;lt;WGM00);     // Minuteur mis en mode PWM&lt;br /&gt;
    TCCR0B |= (1&amp;lt;&amp;lt;CS00);                 // Pas de pré-diviseur, démarre le compteur&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void LED_init(void)&lt;br /&gt;
{&lt;br /&gt;
    DDRD |= (1&amp;lt;&amp;lt;LED_D2) |(1&amp;lt;&amp;lt;LED_STOP_D)|(1&amp;lt;&amp;lt;LED_RECUL_D);&lt;br /&gt;
    DDRC |= (1&amp;lt;&amp;lt;LED_D1) |(1&amp;lt;&amp;lt;LED_PHARES_D);&lt;br /&gt;
    DDRF |= (1&amp;lt;&amp;lt;LED_G1) |(1&amp;lt;&amp;lt;LED_G2)|(1&amp;lt;&amp;lt;LED_STOP_G)|(1&amp;lt;&amp;lt;LED_PHARES_G) |(1&amp;lt;&amp;lt;LED_RECUL_G);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void capteur_init(void)&lt;br /&gt;
{&lt;br /&gt;
    DDRF &amp;amp;= ~(1&amp;lt;&amp;lt;CAPTEUR);&lt;br /&gt;
}&lt;br /&gt;
int main(void){&lt;br /&gt;
&lt;br /&gt;
    CLKSEL0 = 0b00010101;   // sélection de l'horloge externe&lt;br /&gt;
    CLKSEL1 = 0b00001111;   // minimum de 8Mhz&lt;br /&gt;
    CLKPR = 0b10000000;     // modification du diviseur d'horloge (CLKPCE=1)&lt;br /&gt;
    CLKPR = 0;              // 0 pour pas de diviseur (diviseur de 1)&lt;br /&gt;
    &lt;br /&gt;
    MCUCR |= (1&amp;lt;&amp;lt;JTD);&lt;br /&gt;
    MCUCR |= (1&amp;lt;&amp;lt;JTD);&lt;br /&gt;
    PWM_init();&lt;br /&gt;
    LED_init();&lt;br /&gt;
    capteur_init();&lt;br /&gt;
    int pwm=0;&lt;br /&gt;
    PWM_DDRB |= (1&amp;lt;&amp;lt;AIN1)|(1&amp;lt;&amp;lt;AIN2);&lt;br /&gt;
    PWM_PORTB |= (1&amp;lt;&amp;lt;AIN1)|(0&amp;lt;&amp;lt;AIN2);&lt;br /&gt;
    PWM_DDRD |= (1&amp;lt;&amp;lt;BIN1)|(1&amp;lt;&amp;lt;BIN2);&lt;br /&gt;
    PWM_PORTD |= (0&amp;lt;&amp;lt;BIN1)|(1&amp;lt;&amp;lt;BIN2);&lt;br /&gt;
    while (1)&lt;br /&gt;
    {&lt;br /&gt;
        pwm++;&lt;br /&gt;
        if ((PORTF&amp;gt;&amp;gt;CAPTEUR) &amp;amp;1){&lt;br /&gt;
            pwm=0;&lt;br /&gt;
            PORTC|=0x00;&lt;br /&gt;
        }&lt;br /&gt;
        if (pwm &amp;gt;255) pwm=0;&lt;br /&gt;
        OCR0A=pwm;&lt;br /&gt;
        OCR0B=pwm;&lt;br /&gt;
        PORTC |=0b11000000;&lt;br /&gt;
        PORTD |=0b00111000; &lt;br /&gt;
        PORTF |=0b11010011;  &lt;br /&gt;
        _delay_ms(100);&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Ce code nous a permi de vérifier le fonctionnement des LEDs mais pas celui du capteur pour le moment.&lt;br /&gt;
&lt;br /&gt;
==Séance du 4 Juin 2024==&lt;br /&gt;
&lt;br /&gt;
Aujourd'hui nous avons avancé sur le contrôle des LEDs et du capteur de proximité que nous avons enfin fait fonctionner. &lt;br /&gt;
Nous avons désormais une voiture qui roule, phares allumés. Si elle rencontre un obstacle, elle s'arrête puis déclenche ses warnings. Elle possède aussi un bouton start qui lance le programme. Nous avons alors ajouter des fonctions à notre programme. &lt;br /&gt;
[[Fichier:Proxi feux stop.mp4|bordure|gauche|600x600px]] &lt;br /&gt;
Cet ajout permet d'avoir une voiture qui s'arrête dès la détection d'un obstacle et qui donc allume ses feux stop.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void init_boutton(void)&lt;br /&gt;
{&lt;br /&gt;
    DDRD &amp;amp;= ~(1&amp;lt;&amp;lt;START);&lt;br /&gt;
    PORTD |= (1&amp;lt;&amp;lt;START);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void init_moteur(void)&lt;br /&gt;
{&lt;br /&gt;
        PWM_DDRB |= (1&amp;lt;&amp;lt;AIN1)|(1&amp;lt;&amp;lt;AIN2);&lt;br /&gt;
        PWM_DDRD |= (1&amp;lt;&amp;lt;BIN1)|(1&amp;lt;&amp;lt;BIN2);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void avancer(void)&lt;br /&gt;
{&lt;br /&gt;
    PWM_PORTB |= (1&amp;lt;&amp;lt;AIN1);&lt;br /&gt;
    PWM_PORTB &amp;amp;= ~(1&amp;lt;&amp;lt;AIN2);&lt;br /&gt;
    &lt;br /&gt;
    PWM_PORTD &amp;amp;= ~(1&amp;lt;&amp;lt;BIN1);&lt;br /&gt;
    PWM_PORTD |= (1&amp;lt;&amp;lt;BIN2);&lt;br /&gt;
    &lt;br /&gt;
    //PWM_PORTB |= (1&amp;lt;&amp;lt;AIN1)|(0&amp;lt;&amp;lt;AIN2);&lt;br /&gt;
    //PWM_PORTD |= (0&amp;lt;&amp;lt;BIN1)|(1&amp;lt;&amp;lt;BIN2);&lt;br /&gt;
    OCR0A=180;&lt;br /&gt;
    OCR0B=180;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void arret(void)&lt;br /&gt;
{&lt;br /&gt;
    PWM_PORTB &amp;amp;= ~(1&amp;lt;&amp;lt;AIN1);&lt;br /&gt;
    PWM_PORTB &amp;amp;= ~(1&amp;lt;&amp;lt;AIN2);&lt;br /&gt;
    &lt;br /&gt;
    PWM_PORTD &amp;amp;= ~(1&amp;lt;&amp;lt;BIN1);&lt;br /&gt;
    PWM_PORTD &amp;amp;= ~(1&amp;lt;&amp;lt;BIN2);&lt;br /&gt;
    &lt;br /&gt;
    //PWM_PORTB |= (0&amp;lt;&amp;lt;AIN1)|(0&amp;lt;&amp;lt;AIN2);&lt;br /&gt;
    //PWM_PORTD |= (0&amp;lt;&amp;lt;BIN1)|(0&amp;lt;&amp;lt;BIN2);&lt;br /&gt;
    OCR0A=0;&lt;br /&gt;
    OCR0B=0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explication sur la programmation du capteur:&lt;br /&gt;
&lt;br /&gt;
Dans notre programme, nous utilisons le capteur OPB733TR pour mesurer une condition spécifique en lisant des valeurs analogiques. Ces valeurs, qui représentent les informations captées par le capteur, sont converties en signaux numériques que notre microcontrôleur peut traiter. Pour réaliser cette conversion, nous utilisons un Convertisseur Analogique-Numérique (ADC) intégré.&lt;br /&gt;
&lt;br /&gt;
L'ADC agit comme un traducteur qui transforme les niveaux de tension analogiques en valeurs numériques compréhensibles par le microcontrôleur. Cette opération se déroule très rapidement grâce à l'ADC de notre microcontrôleur, qui peut effectuer des conversions en un temps très court. Cela nous permet de capturer et de traiter les informations du capteur presque instantanément.&lt;br /&gt;
&lt;br /&gt;
Dans notre boucle principale, le microcontrôleur lit périodiquement les valeurs analogiques converties par l'ADC. Ces valeurs sont comparées à une limite prédéfinie (`LIMITE`), configurée pour déclencher des actions spécifiques lorsque les conditions détectées par le capteur le nécessitent. Si le capteur détecte une certaine condition (définie lorsque les valeurs analogiques sont inférieures à la limite), notre programme réagit en arrêtant la voiture, activant les feux de stop, les clignotants et même en mettant la voiture en marche arrière si nécessaire.&lt;br /&gt;
&lt;br /&gt;
En parallèle, un compteur est utilisé pour comptabiliser le nombre de fois où les lectures du capteur sont en dessous de la limite spécifiée. Lorsque ce compteur dépasse un certain seuil (7 dans ce cas), cela indique qu'un obstacle est présent. Cette gestion du compteur permet à notre système de prendre des décisions en fonction des conditions détectées par le capteur, garantissant ainsi la vigilance de notre VigiCar.&lt;br /&gt;
&lt;br /&gt;
Ce processus en temps réel, facilité par l'ADC rapide et le compteur intégré, nous permet de surveiller efficacement les conditions environnementales et de répondre à la présence d'un obstacle en faisant reculer la voiture, qui par la même occasion allume ses feux de recul.&lt;br /&gt;
&lt;br /&gt;
==Séance du 6 Juin 2024==&lt;br /&gt;
Lors de cette séance nous avons terminer notre VigiCar en installant l'alimentation par batterie.&lt;br /&gt;
&lt;br /&gt;
Pour ce faire, nous avons voulu isoler la partie du circuit concernant la batterie du reste. Pour cela nous avons donc décidé d’intégrer un deuxième port USB-mini consacré à la charge d’une batterie de 3.7V afin de garantir une alimentation non filière.&lt;br /&gt;
&lt;br /&gt;
Afin de vérifier le bon rechargement de la batterie, nous avons installer une LED orange D4 qui s’allume en cas de recharge.&lt;br /&gt;
&lt;br /&gt;
Pour utiliser l’alimentation sur batterie, il nous suffit de placer un cavalier sur le connecteur J9. Et pour la recharger, on doit en utiliser deux sur les connecteurs J5 et J6. Il faut cependant faire très attention au placement des cavaliers selon l’utilisation. Si on désire modifier le code (par USB donc), nous devons impérativement vérifier que le cavalier en J9 est bien enlevé. Si ce n’est pas le cas, nous avons donc donc deux alimentations simultanées (USB et batterie) ce qui peut provoquer des dysfonctionnements.&lt;br /&gt;
&lt;br /&gt;
Nous avons également installer une diode (D5) pour envoyer le courant de la batterie dans le capteur IR en l’absence de source USB.&lt;br /&gt;
&lt;br /&gt;
Enfin, nous avons décider d’installer le connecteur de la batterie  (J7) sous la carte pour des questions pratiques.&lt;/div&gt;</summary>
		<author><name>Mbarret</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=Fichier:2023-SE3-VOITURE-B3-kicad.zip&amp;diff=3703</id>
		<title>Fichier:2023-SE3-VOITURE-B3-kicad.zip</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=Fichier:2023-SE3-VOITURE-B3-kicad.zip&amp;diff=3703"/>
		<updated>2024-03-26T13:12:43Z</updated>

		<summary type="html">&lt;p&gt;Mbarret : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Mbarret</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=Fichier:2023-SE3-PSE-B1-kicad.zip&amp;diff=3614</id>
		<title>Fichier:2023-SE3-PSE-B1-kicad.zip</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=Fichier:2023-SE3-PSE-B1-kicad.zip&amp;diff=3614"/>
		<updated>2024-03-18T12:52:22Z</updated>

		<summary type="html">&lt;p&gt;Mbarret : Mbarret a annulé Fichier:2023-SE3-PSE-B1-kicad.zip vers une ancienne version&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Mbarret</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2023-3&amp;diff=3613</id>
		<title>SE3Binome2023-3</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2023-3&amp;diff=3613"/>
		<updated>2024-03-18T12:51:19Z</updated>

		<summary type="html">&lt;p&gt;Mbarret : /*  Matériel */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=&amp;lt;div class=&amp;quot;mcwiki-header&amp;quot; style=&amp;quot;border-radius: 40px; padding: 15px; font-weight: bold; color: #FFFFFF; text-align: center; font-size: 80%; background: #33AFDE; vertical-align: top; width: 98%;&amp;quot;&amp;gt; Voiture VigiCar &amp;lt;/div&amp;gt;=&lt;br /&gt;
''Notre projet est une voiture commandée par USB. Lorsqu'elle détectera un obstacle elle s’arrête et déclenche un Warning. Quand l'obstacle est enlevée elle continu son chemin.''&lt;br /&gt;
&lt;br /&gt;
''L'utilisateur peut donner différentes instructions : avancer, reculer, s’arrêter x secondes, ou exécuter une instruction tant qu'aucun obstacle n'est détecté'' &lt;br /&gt;
&lt;br /&gt;
=&amp;lt;div class=&amp;quot;mcwiki-header&amp;quot; style=&amp;quot;border-radius: 40px; padding: 15px; font-weight: bold; color: #FFFFFF; text-align: center; font-size: 80%; background: #97D8F0; vertical-align: top; width: 98%;&amp;quot;&amp;gt; Limitations et fonctionnalités&amp;lt;/div&amp;gt;=&lt;br /&gt;
&lt;br /&gt;
* Taille de la carte : 10x10 cm maximum&lt;br /&gt;
* Utilisation de LEDs jaunes à l'avant et à l'arrière (4 LEDs)&lt;br /&gt;
* Utilisation de LEDs blanches à l'arrière pour les feux de recul (2 LEDs)&lt;br /&gt;
* Utilisation de LEDs rouges à l'arrière pour les feux stop (2 LEDs)&lt;br /&gt;
* Programmation par USB&lt;br /&gt;
* Gestion de l’énergie par batterie LiPo&lt;br /&gt;
* Détection d'obstacles à l'aide d'un capteur de proximité placé à l'avant&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;div class=&amp;quot;mcwiki-header&amp;quot; style=&amp;quot;border-radius: 40px; padding: 15px; font-weight: bold; color: #FFFFFF; text-align: center; font-size: 80%; background: #97D8F0; vertical-align: top; width: 98%;&amp;quot;&amp;gt; Matériel&amp;lt;/div&amp;gt;=&lt;br /&gt;
&lt;br /&gt;
* [https://www.farnell.com/datasheets/2369105.pdf Batterie LiPo]&lt;br /&gt;
* [https://www.analog.com/media/cn/technical-documentation/data-sheets/2536.pdf Puce de contrôle MAX1811]&lt;br /&gt;
* 4 LEDs jaunes&lt;br /&gt;
* 2 LEDs blanches&lt;br /&gt;
* 2 LEDs rouges&lt;br /&gt;
* 2 Mini moteurs continus &amp;amp; Pilotes des moteurs&lt;br /&gt;
* [https://ww1.microchip.com/downloads/en/devicedoc/atmel-7766-8-bit-avr-atmega16u4-32u4_datasheet.pdf Microcontrôleur ATMega16u4]&lt;br /&gt;
* Capteur de proximité&lt;br /&gt;
* Port USB&lt;br /&gt;
&lt;br /&gt;
[[File:2023-SE3-VOITURE-B3-kicad.zip]]&lt;/div&gt;</summary>
		<author><name>Mbarret</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=Fichier:2023-SE3-PSE-B1-kicad.zip&amp;diff=3608</id>
		<title>Fichier:2023-SE3-PSE-B1-kicad.zip</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=Fichier:2023-SE3-PSE-B1-kicad.zip&amp;diff=3608"/>
		<updated>2024-03-12T14:49:28Z</updated>

		<summary type="html">&lt;p&gt;Mbarret : Mbarret a téléversé une nouvelle version de Fichier:2023-SE3-PSE-B1-kicad.zip&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Mbarret</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2023-3&amp;diff=3607</id>
		<title>SE3Binome2023-3</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2023-3&amp;diff=3607"/>
		<updated>2024-03-12T14:49:00Z</updated>

		<summary type="html">&lt;p&gt;Mbarret : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=&amp;lt;div class=&amp;quot;mcwiki-header&amp;quot; style=&amp;quot;border-radius: 40px; padding: 15px; font-weight: bold; color: #FFFFFF; text-align: center; font-size: 80%; background: #33AFDE; vertical-align: top; width: 98%;&amp;quot;&amp;gt; Voiture VigiCar &amp;lt;/div&amp;gt;=&lt;br /&gt;
''Notre projet est une voiture commandée par USB. Lorsqu'elle détectera un obstacle elle s’arrête et déclenche un Warning. Quand l'obstacle est enlevée elle continu son chemin.''&lt;br /&gt;
&lt;br /&gt;
''L'utilisateur peut donner différentes instructions : avancer, reculer, s’arrêter x secondes, ou exécuter une instruction tant qu'aucun obstacle n'est détecté'' &lt;br /&gt;
&lt;br /&gt;
=&amp;lt;div class=&amp;quot;mcwiki-header&amp;quot; style=&amp;quot;border-radius: 40px; padding: 15px; font-weight: bold; color: #FFFFFF; text-align: center; font-size: 80%; background: #97D8F0; vertical-align: top; width: 98%;&amp;quot;&amp;gt; Limitations et fonctionnalités&amp;lt;/div&amp;gt;=&lt;br /&gt;
&lt;br /&gt;
* Taille de la carte : 10x10 cm maximum&lt;br /&gt;
* Utilisation de LEDs jaunes à l'avant et à l'arrière (4 LEDs)&lt;br /&gt;
* Utilisation de LEDs blanches à l'arrière pour les feux de recul (2 LEDs)&lt;br /&gt;
* Utilisation de LEDs rouges à l'arrière pour les feux stop (2 LEDs)&lt;br /&gt;
* Programmation par USB&lt;br /&gt;
* Gestion de l’énergie par batterie LiPo&lt;br /&gt;
* Détection d'obstacles à l'aide d'un capteur de proximité placé à l'avant&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;div class=&amp;quot;mcwiki-header&amp;quot; style=&amp;quot;border-radius: 40px; padding: 15px; font-weight: bold; color: #FFFFFF; text-align: center; font-size: 80%; background: #97D8F0; vertical-align: top; width: 98%;&amp;quot;&amp;gt; Matériel&amp;lt;/div&amp;gt;=&lt;br /&gt;
&lt;br /&gt;
* [https://www.farnell.com/datasheets/2369105.pdf Batterie LiPo]&lt;br /&gt;
* [https://www.analog.com/media/cn/technical-documentation/data-sheets/2536.pdf Puce de contrôle MAX1811]&lt;br /&gt;
* 4 LEDs jaunes&lt;br /&gt;
* 2 LEDs blanches&lt;br /&gt;
* 2 LEDs rouges&lt;br /&gt;
* 2 Mini moteurs continus &amp;amp; Pilotes des moteurs&lt;br /&gt;
* [https://ww1.microchip.com/downloads/en/devicedoc/atmel-7766-8-bit-avr-atmega16u4-32u4_datasheet.pdf Microcontrôleur ATMega16u4]&lt;br /&gt;
* Capteur de proximité&lt;br /&gt;
* Port USB&lt;br /&gt;
&lt;br /&gt;
[[File:2023-SE3-PSE-B1-kicad.zip]]&lt;/div&gt;</summary>
		<author><name>Mbarret</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE3_PSE_Binome2023-1&amp;diff=3546</id>
		<title>SE3 PSE Binome2023-1</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE3_PSE_Binome2023-1&amp;diff=3546"/>
		<updated>2024-03-11T17:01:23Z</updated>

		<summary type="html">&lt;p&gt;Mbarret : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=&amp;lt;div class=&amp;quot;mcwiki-header&amp;quot; style=&amp;quot;border-radius: 40px; padding: 15px; font-weight: bold; color: #FFFFFF; text-align: center; font-size: 80%; background: #33AFDE; vertical-align: top; width: 98%;&amp;quot;&amp;gt; Joystick Space Invader &amp;lt;/div&amp;gt;=&lt;br /&gt;
''Notre projet est de créer une manette de jeu compatible avec le jeu Space Invader.''  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;mcwiki-header&amp;quot; style=&amp;quot;border-radius: 40px; padding: 15px; font-weight: bold; color: #FFFFFF; text-align: center; font-size: 80%; background: #97D8F0; vertical-align: top; width: 98%;&amp;quot;&amp;gt; Limitations et fonctionnalités&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Taille de la carte : 10x10 cm maximum&lt;br /&gt;
* Utilisation de LEDs rouge selon ce qu'il se passe dans le jeu (victoire, défaite, tir, etc.)&lt;br /&gt;
* 4 boutons : deux de déplacement (gauche et droite), un de tire et un dernier pour toute actions supplémentaire que nous déterminerons par la suite&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici l'archive de notre fichier à la fin de la 2e séance :&lt;br /&gt;
&lt;br /&gt;
[[File:2023-SE3-PSE-B1-kicad.zip]]&lt;/div&gt;</summary>
		<author><name>Mbarret</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE3_PSE_Binome2023-1&amp;diff=3545</id>
		<title>SE3 PSE Binome2023-1</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE3_PSE_Binome2023-1&amp;diff=3545"/>
		<updated>2024-03-11T17:01:04Z</updated>

		<summary type="html">&lt;p&gt;Mbarret : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=&amp;lt;div class=&amp;quot;mcwiki-header&amp;quot; style=&amp;quot;border-radius: 40px; padding: 15px; font-weight: bold; color: #FFFFFF; text-align: center; font-size: 80%; background: #33AFDE; vertical-align: top; width: 98%;&amp;quot;&amp;gt; Joystick Space Invader &amp;lt;/div&amp;gt;=&lt;br /&gt;
''Notre projet est de créer une manette de jeu compatible avec le jeu Space Invader.''  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;mcwiki-header&amp;quot; style=&amp;quot;border-radius: 40px; padding: 15px; font-weight: bold; color: #FFFFFF; text-align: center; font-size: 80%; background: #97D8F0; vertical-align: top; width: 98%;&amp;quot;&amp;gt; Limitations et fonctionnalités&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Taille de la carte : 10x10 cm maximum&lt;br /&gt;
* Utilisation de LEDs rouge selon ce qu'il se passe dans le jeu (victoire, défaite, tir, etc.)&lt;br /&gt;
* 4 boutons : deux de déplacement (gauche et droite), un de tire et un dernier pour toute actions supplémentaire que nous déterminerons par la suite&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Voici l'archive de notre fichier à la fin de la 2e séance :&lt;br /&gt;
&lt;br /&gt;
=  [[File:2023-SE3-PSE-B1-kicad.zip]]=&lt;/div&gt;</summary>
		<author><name>Mbarret</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE3_PSE_Binome2023-1&amp;diff=3527</id>
		<title>SE3 PSE Binome2023-1</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE3_PSE_Binome2023-1&amp;diff=3527"/>
		<updated>2024-03-11T16:54:20Z</updated>

		<summary type="html">&lt;p&gt;Mbarret : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=&amp;lt;div class=&amp;quot;mcwiki-header&amp;quot; style=&amp;quot;border-radius: 40px; padding: 15px; font-weight: bold; color: #FFFFFF; text-align: center; font-size: 80%; background: #33AFDE; vertical-align: top; width: 98%;&amp;quot;&amp;gt; Joystick Space Invader &amp;lt;/div&amp;gt;=&lt;br /&gt;
Notre projet est de creer une manette de jeu compatible avec le jeu Space Invader. Cette manette &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;div class=&amp;quot;mcwiki-header&amp;quot; style=&amp;quot;border-radius: 40px; padding: 15px; font-weight: bold; color: #FFFFFF; text-align: center; font-size: 80%; background: #97D8F0; vertical-align: top; width: 98%;&amp;quot;&amp;gt; Limitations et fonctionnalités&amp;lt;/div&amp;gt;=&lt;br /&gt;
&lt;br /&gt;
* Taille de la carte : 10x10 cm maximum&lt;br /&gt;
* Utilisation de LEDs jaunes à l'avant et à l'arrière (4 LEDs)&lt;br /&gt;
* Utilisation de LEDs blanches à l'arrière pour les feux de recul (2 LEDs)&lt;br /&gt;
* Utilisation de LEDs rouges à l'arrière pour les feux stop (2 LEDs)&lt;br /&gt;
* Programmation par USB&lt;br /&gt;
* Gestion de l’énergie par batterie LiPo&lt;br /&gt;
* Détection d'obstacles à l'aide d'un capteur de proximité placé à l'avant&lt;br /&gt;
&lt;br /&gt;
=  [[File:2023-SE3-PSE-B1-kicad.zip]]=&lt;/div&gt;</summary>
		<author><name>Mbarret</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE3_PSE_Binome2023-1&amp;diff=3526</id>
		<title>SE3 PSE Binome2023-1</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE3_PSE_Binome2023-1&amp;diff=3526"/>
		<updated>2024-03-11T16:54:04Z</updated>

		<summary type="html">&lt;p&gt;Mbarret : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=&amp;lt;div class=&amp;quot;mcwiki-header&amp;quot; style=&amp;quot;border-radius: 40px; padding: 15px; font-weight: bold; color: #FFFFFF; text-align: center; font-size: 80%; background: #33AFDE; vertical-align: top; width: 98%;&amp;quot;&amp;gt; Joystick Space Invader &amp;lt;/div&amp;gt;=&lt;br /&gt;
Notre projet est de creer une manette de jeu compatible avec le jeu Space Invader. Cette manette &lt;br /&gt;
&lt;br /&gt;
=  [[File:2023-SE3-PSE-B1-kicad.zip]]=&lt;/div&gt;</summary>
		<author><name>Mbarret</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=Fichier:2023-SE3-PSE-B1-kicad.zip&amp;diff=3515</id>
		<title>Fichier:2023-SE3-PSE-B1-kicad.zip</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=Fichier:2023-SE3-PSE-B1-kicad.zip&amp;diff=3515"/>
		<updated>2024-03-11T16:50:50Z</updated>

		<summary type="html">&lt;p&gt;Mbarret : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Mbarret</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE3_PSE_Binome2023-1&amp;diff=3510</id>
		<title>SE3 PSE Binome2023-1</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE3_PSE_Binome2023-1&amp;diff=3510"/>
		<updated>2024-03-11T16:49:37Z</updated>

		<summary type="html">&lt;p&gt;Mbarret : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=&amp;lt;div class=&amp;quot;mcwiki-header&amp;quot; style=&amp;quot;border-radius: 40px; padding: 15px; font-weight: bold; color: #FFFFFF; text-align: center; font-size: 80%; background: #33AFDE; vertical-align: top; width: 98%;&amp;quot;&amp;gt; Joystick Space Invader &amp;lt;/div&amp;gt;=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:2023-SE3-PSE-B1-kicad.zip]]&lt;/div&gt;</summary>
		<author><name>Mbarret</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE3_PSE_Binome2023-1&amp;diff=3504</id>
		<title>SE3 PSE Binome2023-1</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE3_PSE_Binome2023-1&amp;diff=3504"/>
		<updated>2024-03-11T16:46:35Z</updated>

		<summary type="html">&lt;p&gt;Mbarret : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=&amp;lt;div class=&amp;quot;mcwiki-header&amp;quot; style=&amp;quot;border-radius: 40px; padding: 15px; font-weight: bold; color: #FFFFFF; text-align: center; font-size: 80%; background: #33AFDE; vertical-align: top; width: 98%;&amp;quot;&amp;gt; Joystick Space Invader &amp;lt;/div&amp;gt;=&lt;/div&gt;</summary>
		<author><name>Mbarret</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=Fichier:Mannete_ElBachiri_Barret.zip&amp;diff=3501</id>
		<title>Fichier:Mannete ElBachiri Barret.zip</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=Fichier:Mannete_ElBachiri_Barret.zip&amp;diff=3501"/>
		<updated>2024-03-11T16:45:25Z</updated>

		<summary type="html">&lt;p&gt;Mbarret : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Archive projet Manette&lt;/div&gt;</summary>
		<author><name>Mbarret</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE3_PSE_Binome2023-1&amp;diff=3498</id>
		<title>SE3 PSE Binome2023-1</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE3_PSE_Binome2023-1&amp;diff=3498"/>
		<updated>2024-03-11T16:40:57Z</updated>

		<summary type="html">&lt;p&gt;Mbarret : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=&amp;lt;div class=&amp;quot;mcwiki-header&amp;quot; style=&amp;quot;border-radius: 40px; padding: 15px; font-weight: bold; color: #FFFFFF; text-align: center; font-size: 80%; background: #33AFDE; vertical-align: top; width: 98%;&amp;quot;&amp;gt; Joystick Space Invader &amp;lt;/div&amp;gt;=&lt;br /&gt;
''Notre projet est une voiture commandée par USB. Lorsqu'elle détectera un obstacle elle s’arrête et déclenche un Warning. Quand l'obstacle est enlevée elle continu son chemin.''&lt;br /&gt;
&lt;br /&gt;
''L'utilisateur peut donner différentes instructions : avancer, reculer, s’arrêter x secondes, ou exécuter une instruction tant qu'aucun obstacle n'est détecté''&lt;/div&gt;</summary>
		<author><name>Mbarret</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=PSE_SE3_2023/2024&amp;diff=3450</id>
		<title>PSE SE3 2023/2024</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=PSE_SE3_2023/2024&amp;diff=3450"/>
		<updated>2024-03-11T13:00:08Z</updated>

		<summary type="html">&lt;p&gt;Mbarret : /* Réalisations des binômes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Objectif =&lt;br /&gt;
&lt;br /&gt;
Pour l'année académique 2023/2024 il est toujours demandé de réaliser un système embarqué.&lt;br /&gt;
&lt;br /&gt;
== Microcontrôleur ==&lt;br /&gt;
&lt;br /&gt;
Pour éviter les problème avec les conversions analogique vers numérique vous utiliserez un ATmega16u4 ou un ATmega32u4. La programmation peut ainsi se faire très simplement par DFU/USB.&lt;br /&gt;
&lt;br /&gt;
== Energie ==&lt;br /&gt;
&lt;br /&gt;
Vos cartes doivent pouvoir être alimentées de façon hybride :&lt;br /&gt;
* par un port USB, méthode utilisée pour la programmation et les tests ;&lt;br /&gt;
* par une batterie Lithium, en mode autonome.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:puce_max1811.jpg|Puce de contrôle de charge&lt;br /&gt;
File:batteries_LiPo.jpg|Batteries 100mAh et 300mAh, connecteur molex mâle&lt;br /&gt;
File:batterie_LiPo_FQ777.jpg|Batterie 100mAh 15x20x5mm&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il est conseillé de séparer au maximum les deux alimentations, voir la seconde version de la carte de test de chargement de batterie.&lt;br /&gt;
&lt;br /&gt;
== Fonctionnalités ==&lt;br /&gt;
&lt;br /&gt;
Vos cartes doivent toutes comporter des LED commandées par le microcontrôleur. Les autres fonctionnalités peuvent être choisies dans la liste suivante (non exhaustive). Les fonctionnalités doivent être validées par un intervenant.&lt;br /&gt;
&lt;br /&gt;
* Vous pouvez partir sur le projet voiture de l'an passé en simplifiant l'aspect mécanique : deux moteurs pour les deux roues motrices, des roues directement enfilées sur les méplats des moteurs continus ou sur des engrenages montés en force sur l'axe des moteurs pas à pas. Le comportement de la voiture est téléchargé par une liaison USB/série et permet de spécifier une suite de commandes sur les deux moteurs et les lampes de la voiture.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
file:2023-chassis-simple-dessus.png|Chassis vu de dessus&lt;br /&gt;
file:2023-chassis-simple-cote.png|Chassis vu de coté&lt;br /&gt;
File:micro-moteur-pas-a-pas-simple.jpg|Micro-moteur pas à pas propulsion&lt;br /&gt;
File:mini-motoreducteur.jpg|Mini-moteur continu avec réducteur&lt;br /&gt;
File:pilote-moteur-TB6612FNG.png|Pilote pour le mini-moteur continu (TB6612FNG)&lt;br /&gt;
File:detecteur-proximite-OPB733.png|Puce de détection d'obstacle (OPB733)&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Vous pouvez partir sur un objet autonome communicant de type capteur, par exemple un capteur de température ou un micro espion. Le coté autonome est donné par la batterie, le coté communicant est à travailler à partir de la puce NRF24L01. Cette puce est une puce radio générale. Vous pouvez la tester à partir de la carte de test présenté dans la suite de ce sujet. Pour la réception des données de votre objet plusieurs alternatives sont possibles : mettre rapidement au point un récepteur à base de module basé sur un NRF24L01 et un Arduino ou vous entendre avec un autre binôme dont l'objet est soit :&lt;br /&gt;
** une centrale d'affichage des données des objets communicants sur des afficheurs 7 segments, un écran LCD alphanumérique ou un écran LCD graphique ;&lt;br /&gt;
** un périphérique USB de type carte son permettant de récupérer le flux du micro espion, dans ce dernier cas attention à bien sélectionner un microcontrôleur adapté.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:module_nrf24L01.jpg|Module de communication 2,4Ghz&lt;br /&gt;
File:puce_nrf24L01.jpg|Puce de communication (soudure complexe)&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Vous pouvez tenter un objet autonome communicant de type actionneur, par exemple un haut-parleur diffusant les sons envoyés par un module radio. Là encore les sons peuvent être envoyés par un prototype à base d'Arduino ou par la carte d'un autre binôme réalisant un périphérique USB de type audio. Dans ce dernier cas attention à bien sélectionner un microcontrôleur adapté.&lt;br /&gt;
&lt;br /&gt;
* Enfin si vous ne vous sentez pas trop sûr de vous il reste toujours la possibilité de l'objet complétement autonome comportant des capteurs et des actionneurs et réagissant en fonction de son environnement. Un exemple est un détecteur de mouvement à base de capteur PIR (Passive Infra-Red) donnant lieu à une séquence animée à base de LED ou à une séquence sonore.&lt;br /&gt;
&lt;br /&gt;
= Cartes de test =&lt;br /&gt;
&lt;br /&gt;
Cette année, plutôt que vous proposer des schémas complets de voitures, il a été décidé de vous proposer des cartes démontrant, chacune, une fonctionnalité éventuellement intégrable dans votre voiture.&lt;br /&gt;
&lt;br /&gt;
== Test du chargeur ==&lt;br /&gt;
&lt;br /&gt;
[[Fichier:2023-ChargeurLiPo-Schema.pdf|thumb|left|400px]]&lt;br /&gt;
[[Fichier:2023-ChargeurLiPo-PCB.jpg|thumb|right|400px]]&lt;br /&gt;
&lt;br /&gt;
Les schéma et routage de la carte. Avec une erreur de base, le microcontrôleur est un ATmega32u2, c'est à dire un AVR sans ADC donc récupérer la tension de la batterie sera en tout ou rien. Un autre problème de conception est la trop faible charge de la LED qui peine à décharger la batterie.&lt;br /&gt;
&lt;br /&gt;
Projet KiCAD : [[Fichier:2023-ChargeurLiPo-KiCAD.zip]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p style=&amp;quot;clear: both;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Fichier:2023-ChargeurLiPo-Complete1.jpg|thumb|left|150px]]&lt;br /&gt;
[[Fichier:2023-ChargeurLiPo-Complete2.jpg|thumb|right|400px]]&lt;br /&gt;
&lt;br /&gt;
Vous trouvez ici deux photos de la carte soudée.&lt;br /&gt;
&lt;br /&gt;
Vous avez aussi un programme LUFA basé sur la démonstration &amp;lt;code&amp;gt;VirtualSerial&amp;lt;/code&amp;gt; pour contrôler la carte, en particulier lancer la charge de la batterie et voir si sa tension se traduit par un état haut ou bas. Tapez n'importe quoi avec un retour chariot dans un terminal série pour voir la liste des commandes possibles.&lt;br /&gt;
&lt;br /&gt;
Programme : [[Média:2023-ChargeurLiPo-VirtualSerial.zip]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p style=&amp;quot;clear: both;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Les tests de la première version de la carte n'ont pas été super-concluant. Il faut dire qu'il y avait quelques erreurs de conception :&lt;br /&gt;
* le plus grave : le condensateur en parallèle de la batterie était noté 100nF au lieu des 2,2µF indiqué dans les documents technique, de plus le condensateur de 4,7µF demandé sur l'alimentation de la puce n'était pas implanté ;&lt;br /&gt;
* l'idée de commander la LED d'éclairage via le 5V du connecteur USB n'était pas très malin, cela interdisait une utilisation de la LED la carte non connectée sur une alimentation USB ;&lt;br /&gt;
* comme indiqué plus haut, il vaut mieux utiliser un ATmega16u4 qu'un ATmega16u2 ;&lt;br /&gt;
* plus généralement déconnecter au maximum la partie &amp;quot;utilisation&amp;quot; de la batterie de la partie &amp;quot;recharge&amp;quot; de la batterie réduit les problèmes potentiels.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:2023-ChargeurLiPo-Schema-V2.pdf|thumb|left|400px]]&lt;br /&gt;
[[Fichier:2023-ChargeurLiPo-PCB-V2.png|thumb|right|400px]]&lt;br /&gt;
&lt;br /&gt;
Nouvelle version de la carte avec deux connecteurs USB : un USB A pour sa programmation et son fonctionnement USB, un USB mini pour la recharge de la batterie. Un interrupteur permet d'utiliser la LED, un autre de démarrer le microcontrôleur.&lt;br /&gt;
&lt;br /&gt;
Projet KiCAD : [[Fichier:2023-ChargeurLiPo-KiCAD-V2.zip]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p style=&amp;quot;clear: both;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Test du transmetteur radio ==&lt;br /&gt;
&lt;br /&gt;
[[Fichier:2023-BlueTooth-Schema.pdf|thumb|left|400px]]&lt;br /&gt;
[[Fichier:2023-BlueTooth-PCB.jpg|thumb|right|400px]]&lt;br /&gt;
&lt;br /&gt;
Contrairement au titre du projet KiCAD cette carte est un transmetteur/récepteur radio générique.&lt;br /&gt;
&lt;br /&gt;
Projet KiCAD : [[Fichier:2023-BlueTooth-KiCAD.zip]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p style=&amp;quot;clear: both;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Réalisations des binômes =&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Numéro !! Elèves !! Page &lt;br /&gt;
|-&lt;br /&gt;
| Binôme 1&lt;br /&gt;
| Victorien DETREZ &amp;amp; Benjamin CART&lt;br /&gt;
| [[SE3Binome2023-1|Binôme 1 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 2&lt;br /&gt;
| Bilal MOUSSA &amp;amp; Yassine YAHIANI&lt;br /&gt;
| [[SE3Binome2023-2|Binôme 2 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 3&lt;br /&gt;
| Kaoutar EL BACHIRI &amp;amp; Maxime BARRET&lt;br /&gt;
| [[SE3Binome2023-3|Binôme 3 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 4&lt;br /&gt;
| Prénom NOM &amp;amp; Prénom NOM&lt;br /&gt;
| [[SE3Binome2023-4|Binôme 4 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 5&lt;br /&gt;
| Antoine LECOMTE &amp;amp; Rémi BOURSAULT&lt;br /&gt;
| [[SE3Binome2023-5|Binôme 5 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 6&lt;br /&gt;
| Lililan GREVIN &amp;amp; Pierre CASIMIRI&lt;br /&gt;
| [[SE3Binome2023-6|Binôme 6 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 7&lt;br /&gt;
| Augustin DJAJDJA-AVONYO &amp;amp; Kévan TOURON&lt;br /&gt;
| [[SE3Binome2023-7|Binôme 7 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 8&lt;br /&gt;
| Justin WACQUET &amp;amp; Ibrahim TEPELI&lt;br /&gt;
| [[SE3Binome2023-8|Binôme 8 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Monôme 9&lt;br /&gt;
| Mahmoud RABIA&lt;br /&gt;
| [[SE3Binome2023-9|Monôme 9 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 10&lt;br /&gt;
| Camille CARIAT &amp;amp; Louis BONNINGRE&lt;br /&gt;
| [[SE3Binome2023-10|Binôme 10 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Réalisations en programmation des systèmes embarqués =&lt;br /&gt;
&lt;br /&gt;
== Binômes ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Numéro !! Elèves !! Page &lt;br /&gt;
|-&lt;br /&gt;
| Binôme 1&lt;br /&gt;
| Kaoutar EL BACHIRI &amp;amp; Maxime BARRET&lt;br /&gt;
| [[SE3_PSE_Binome2023-1|Binôme 1 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 2&lt;br /&gt;
| Sarah Deparis &amp;amp; Agathe Houdusse&lt;br /&gt;
| [[SE3_PSE_Binome2023-2|Binôme 2 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 3&lt;br /&gt;
| Victorien DETREZ &amp;amp; Benjamin CART&lt;br /&gt;
| [[SE3_PSE_Binome2023-3|Binôme 3 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 4&lt;br /&gt;
| Bilal MOUSSA &amp;amp; Yassine YAHIANI&lt;br /&gt;
| [[SE3_PSE_Binome2023-4|Binôme 4 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 5&lt;br /&gt;
| Prénom NOM &amp;amp; Prénom NOM&lt;br /&gt;
| [[SE3_PSE_Binome2023-5|Binôme 5 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 6&lt;br /&gt;
| Lilian GREVIN &amp;amp; Pierre CASIMIRI&lt;br /&gt;
| [[SE3_PSE_Binome2023-6|Binôme 6 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 7&lt;br /&gt;
| Kévan TOURON &amp;amp; Augustin DJADJA-AVONYO&lt;br /&gt;
| [[SE3_PSE_Binome2023-7|Binôme 7 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 8&lt;br /&gt;
| Prénom NOM &amp;amp; Prénom NOM&lt;br /&gt;
| [[SE3_PSE_Binome2023-8|Binôme 8 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 9&lt;br /&gt;
| Prénom NOM &amp;amp; Prénom NOM&lt;br /&gt;
| [[SE3_PSE_Binome2023-9|Binôme 9 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 10&lt;br /&gt;
| Camille CARIAT &amp;amp; RABIA Mahmoud&lt;br /&gt;
| [[SE3_PSE_Binome2023-10|Binôme 10 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Manette USB ==&lt;br /&gt;
&lt;br /&gt;
Projet KiCAD de base pour les manettes : [[Fichier:2023-ManetteSE3-KiCAD.zip]]&lt;br /&gt;
&lt;br /&gt;
Utilisez vos pages Wiki pour :&lt;br /&gt;
* attacher votre projet KiCAD ;&lt;br /&gt;
* déposer une photo de la carte soudée.&lt;br /&gt;
&lt;br /&gt;
== Programmateur AVR ==&lt;br /&gt;
&lt;br /&gt;
Utilisez vos pages Wiki pour :&lt;br /&gt;
* attacher vos programmes C (LUFA et libusb) ;&lt;br /&gt;
* déposer une photo de la carte soudée ;&lt;br /&gt;
* déposer une très courte vidéo de la carte avec les LED clignotantes ;&lt;br /&gt;
* déposer une copie écran montrant l'affichage de la communication entre votre programme libusb, votre carte et le microcontrôleur AVR.&lt;/div&gt;</summary>
		<author><name>Mbarret</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2023-3&amp;diff=3396</id>
		<title>SE3Binome2023-3</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2023-3&amp;diff=3396"/>
		<updated>2024-03-05T14:03:40Z</updated>

		<summary type="html">&lt;p&gt;Mbarret : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Projet: Voiture commandée par USB &lt;br /&gt;
&lt;br /&gt;
Limitations et fonctionnalités:&amp;lt;br&amp;gt;&lt;br /&gt;
-taille de la carte 10x10cm maximum &amp;lt;br&amp;gt;&lt;br /&gt;
-Utilisation de LEDs (jaunes) comme clignotants de la voiture ainsi que pour les feux de recul (blanc) et feux de stop à l’arrêt (Rouge).  &amp;lt;br&amp;gt;&lt;br /&gt;
-Présence d'un port USB pour la programmation&amp;lt;br&amp;gt;&lt;br /&gt;
-Gestion de l'énergie par batterie LiPo&lt;br /&gt;
&lt;br /&gt;
-détection d'obstacle&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Composants prévus à la conception: Batterie LiPo + Puce de controle MAX1811, 4 Leds jaunes, 2 leds blanches et 2 leds rouges, utilisation des mini-moteurs continus et du pilote des moteurs, microcontrôleur ATMega16u4, capteur de proximité à l'avant .&lt;/div&gt;</summary>
		<author><name>Mbarret</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2023-3&amp;diff=3392</id>
		<title>SE3Binome2023-3</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2023-3&amp;diff=3392"/>
		<updated>2024-03-05T13:58:11Z</updated>

		<summary type="html">&lt;p&gt;Mbarret : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Projet: Voiture commandée par USB&lt;br /&gt;
&lt;br /&gt;
Limitations et fonctionnalités:&amp;lt;br&amp;gt;&lt;br /&gt;
-taille de la carte 10x10cm maximum &amp;lt;br&amp;gt;&lt;br /&gt;
-Utilisation de LEDs (jaunes) comme clignotants de la voiture ainsi que pour les feux de recul (blanc) et feux de stop à l’arrêt (Rouge).  &amp;lt;br&amp;gt;&lt;br /&gt;
-Présence d'un port USB pour la programmation&amp;lt;br&amp;gt;&lt;br /&gt;
-Gestion de l'énergie par batterie LiPo&lt;br /&gt;
&lt;br /&gt;
-détection d'obstacle&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Composants prévus à la conception: Batterie LiPo + Puce de controle MAX1811, 4 Leds jaunes, 2 leds blanches et 2 leds rouges, utilisation des mini-moteurs continus et du pilote des moteurs, microcontrôleur ATMega16u4, capteur de proximité à l'avant .&lt;/div&gt;</summary>
		<author><name>Mbarret</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2023-3&amp;diff=3382</id>
		<title>SE3Binome2023-3</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2023-3&amp;diff=3382"/>
		<updated>2024-03-05T13:43:42Z</updated>

		<summary type="html">&lt;p&gt;Mbarret : Page créée avec « Projet: Voiture commandée par USB  Limitations et fonctionnalités:&amp;lt;br&amp;gt; -taille de la carte 10x10cm maximum &amp;lt;br&amp;gt; -Utilisation de LEDs (jaunes) comme clignotants de la voiture ainsi que pour les feux de recul (blanc) et feux de stop à l’arrêt (Rouge).  Clignotants si partie mécanique réalisée.&amp;lt;br&amp;gt; -Présence d'un port USB pour la programmation&amp;lt;br&amp;gt; -Gestion de l'énergie par batterie LiPo&amp;lt;br&amp;gt;  Composants prévus à la conception: Batterie LiPo + Puce de con... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Projet: Voiture commandée par USB&lt;br /&gt;
&lt;br /&gt;
Limitations et fonctionnalités:&amp;lt;br&amp;gt;&lt;br /&gt;
-taille de la carte 10x10cm maximum &amp;lt;br&amp;gt;&lt;br /&gt;
-Utilisation de LEDs (jaunes) comme clignotants de la voiture ainsi que pour les feux de recul (blanc) et feux de stop à l’arrêt (Rouge).  Clignotants si partie mécanique réalisée.&amp;lt;br&amp;gt;&lt;br /&gt;
-Présence d'un port USB pour la programmation&amp;lt;br&amp;gt;&lt;br /&gt;
-Gestion de l'énergie par batterie LiPo&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Composants prévus à la conception: Batterie LiPo + Puce de controle MAX1811, 4 Leds jaunes, 2 leds blanches et 2 leds rouges, utilisation des mini-moteurs continus et du pilote des moteurs, microcontrôleur ATMega16u4.&lt;/div&gt;</summary>
		<author><name>Mbarret</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE3_PSE_Binome2023-1&amp;diff=3381</id>
		<title>SE3 PSE Binome2023-1</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE3_PSE_Binome2023-1&amp;diff=3381"/>
		<updated>2024-03-05T13:43:29Z</updated>

		<summary type="html">&lt;p&gt;Mbarret : Page blanchie&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Mbarret</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=PSE_SE3_2023/2024&amp;diff=3379</id>
		<title>PSE SE3 2023/2024</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=PSE_SE3_2023/2024&amp;diff=3379"/>
		<updated>2024-03-05T13:42:42Z</updated>

		<summary type="html">&lt;p&gt;Mbarret : /* Réalisations des binômes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Objectif =&lt;br /&gt;
&lt;br /&gt;
Pour l'année académique 2023/2024 il est toujours demandé de réaliser un système embarqué.&lt;br /&gt;
&lt;br /&gt;
== Microcontrôleur ==&lt;br /&gt;
&lt;br /&gt;
Pour éviter les problème avec les conversions analogique vers numérique vous utiliserez un ATmega16u4 ou un ATmega32u4. La programmation peut ainsi se faire très simplement par DFU/USB.&lt;br /&gt;
&lt;br /&gt;
== Energie ==&lt;br /&gt;
&lt;br /&gt;
Vos cartes doivent pouvoir être alimentées de façon hybride :&lt;br /&gt;
* par un port USB, méthode utilisée pour la programmation et les tests ;&lt;br /&gt;
* par une batterie Lithium, en mode autonome.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:puce_max1811.jpg|Puce de contrôle de charge&lt;br /&gt;
File:batteries_LiPo.jpg|Batteries 100mAh et 300mAh, connecteur molex mâle&lt;br /&gt;
File:batterie_LiPo_FQ777.jpg|Batterie 100mAh 15x20x5mm&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il est conseillé de séparer au maximum les deux alimentations, voir la seconde version de la carte de test de chargement de batterie.&lt;br /&gt;
&lt;br /&gt;
== Fonctionnalités ==&lt;br /&gt;
&lt;br /&gt;
Vos cartes doivent toutes comporter des LED commandées par le microcontrôleur. Les autres fonctionnalités peuvent être choisies dans la liste suivante (non exhaustive). Les fonctionnalités doivent être validées par un intervenant.&lt;br /&gt;
&lt;br /&gt;
* Vous pouvez partir sur le projet voiture de l'an passé en simplifiant l'aspect mécanique : deux moteurs pour les deux roues motrices, des roues directement enfilées sur les méplats des moteurs continus ou sur des engrenages montés en force sur l'axe des moteurs pas à pas. Le comportement de la voiture est téléchargé par une liaison USB/série et permet de spécifier une suite de commandes sur les deux moteurs et les lampes de la voiture.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
file:2023-chassis-simple-dessus.png|Chassis vu de dessus&lt;br /&gt;
file:2023-chassis-simple-cote.png|Chassis vu de coté&lt;br /&gt;
File:micro-moteur-pas-a-pas-simple.jpg|Micro-moteur pas à pas propulsion&lt;br /&gt;
File:mini-motoreducteur.jpg|Mini-moteur continu avec réducteur&lt;br /&gt;
File:pilote-moteur-TB6612FNG.png|Pilote pour le mini-moteur continu (TB6612FNG)&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Vous pouvez partir sur un objet autonome communicant de type capteur, par exemple un capteur de température ou un micro espion. Le coté autonome est donné par la batterie, le coté communicant est à travailler à partir de la puce NRF24L01. Cette puce est une puce radio générale. Vous pouvez la tester à partir de la carte de test présenté dans la suite de ce sujet. Pour la réception des données de votre objet plusieurs alternatives sont possibles : mettre rapidement au point un récepteur à base de module basé sur un NRF24L01 et un Arduino ou vous entendre avec un autre binôme dont l'objet est soit :&lt;br /&gt;
** une centrale d'affichage des données des objets communicants sur des afficheurs 7 segments, un écran LCD alphanumérique ou un écran LCD graphique ;&lt;br /&gt;
** un périphérique USB de type carte son permettant de récupérer le flux du micro espion, dans ce dernier cas attention à bien sélectionner un microcontrôleur adapté.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:module_nrf24L01.jpg|Module de communication 2,4Ghz&lt;br /&gt;
File:puce_nrf24L01.jpg|Puce de communication (soudure complexe)&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Vous pouvez tenter un objet autonome communicant de type actionneur, par exemple un haut-parleur diffusant les sons envoyés par un module radio. Là encore les sons peuvent être envoyés par un prototype à base d'Arduino ou par la carte d'un autre binôme réalisant un périphérique USB de type audio. Dans ce dernier cas attention à bien sélectionner un microcontrôleur adapté.&lt;br /&gt;
&lt;br /&gt;
* Enfin si vous ne vous sentez pas trop sûr de vous il reste toujours la possibilité de l'objet complétement autonome comportant des capteurs et des actionneurs et réagissant en fonction de son environnement. Un exemple est un détecteur de mouvement à base de capteur PIR (Passive Infra-Red) donnant lieu à une séquence animée à base de LED ou à une séquence sonore.&lt;br /&gt;
&lt;br /&gt;
= Cartes de test =&lt;br /&gt;
&lt;br /&gt;
Cette année, plutôt que vous proposer des schémas complets de voitures, il a été décidé de vous proposer des cartes démontrant, chacune, une fonctionnalité éventuellement intégrable dans votre voiture.&lt;br /&gt;
&lt;br /&gt;
== Test du chargeur ==&lt;br /&gt;
&lt;br /&gt;
[[Fichier:2023-ChargeurLiPo-Schema.pdf|thumb|left|400px]]&lt;br /&gt;
[[Fichier:2023-ChargeurLiPo-PCB.jpg|thumb|right|400px]]&lt;br /&gt;
&lt;br /&gt;
Les schéma et routage de la carte. Avec une erreur de base, le microcontrôleur est un ATmega32u2, c'est à dire un AVR sans ADC donc récupérer la tension de la batterie sera en tout ou rien. Un autre problème de conception est la trop faible charge de la LED qui peine à décharger la batterie.&lt;br /&gt;
&lt;br /&gt;
Projet KiCAD : [[Fichier:2023-ChargeurLiPo-KiCAD.zip]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p style=&amp;quot;clear: both;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Fichier:2023-ChargeurLiPo-Complete1.jpg|thumb|left|150px]]&lt;br /&gt;
[[Fichier:2023-ChargeurLiPo-Complete2.jpg|thumb|right|400px]]&lt;br /&gt;
&lt;br /&gt;
Vous trouvez ici deux photos de la carte soudée.&lt;br /&gt;
&lt;br /&gt;
Vous avez aussi un programme LUFA basé sur la démonstration &amp;lt;code&amp;gt;VirtualSerial&amp;lt;/code&amp;gt; pour contrôler la carte, en particulier lancer la charge de la batterie et voir si sa tension se traduit par un état haut ou bas. Tapez n'importe quoi avec un retour chariot dans un terminal série pour voir la liste des commandes possibles.&lt;br /&gt;
&lt;br /&gt;
Programme : [[Média:2023-ChargeurLiPo-VirtualSerial.zip]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p style=&amp;quot;clear: both;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Les tests de la première version de la carte n'ont pas été super-concluant. Il faut dire qu'il y avait quelques erreurs de conception :&lt;br /&gt;
* le plus grave : le condensateur en parallèle de la batterie était noté 100nF au lieu des 2,2µF indiqué dans les documents technique, de plus le condensateur de 4,7µF demandé sur l'alimentation de la puce n'était pas implanté ;&lt;br /&gt;
* l'idée de commander la LED d'éclairage via le 5V du connecteur USB n'était pas très malin, cela interdisait une utilisation de la LED la carte non connectée sur une alimentation USB ;&lt;br /&gt;
* comme indiqué plus haut, il vaut mieux utiliser un ATmega16u4 qu'un ATmega16u2 ;&lt;br /&gt;
* plus généralement déconnecter au maximum la partie &amp;quot;utilisation&amp;quot; de la batterie de la partie &amp;quot;recharge&amp;quot; de la batterie réduit les problèmes potentiels.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:2023-ChargeurLiPo-Schema-V2.pdf|thumb|left|400px]]&lt;br /&gt;
[[Fichier:2023-ChargeurLiPo-PCB-V2.png|thumb|right|400px]]&lt;br /&gt;
&lt;br /&gt;
Nouvelle version de la carte avec deux connecteurs USB : un USB A pour sa programmation et son fonctionnement USB, un USB mini pour la recharge de la batterie. Un interrupteur permet d'utiliser la LED, un autre de démarrer le microcontrôleur.&lt;br /&gt;
&lt;br /&gt;
Projet KiCAD : [[Fichier:2023-ChargeurLiPo-KiCAD-V2.zip]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p style=&amp;quot;clear: both;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Test du transmetteur radio ==&lt;br /&gt;
&lt;br /&gt;
[[Fichier:2023-BlueTooth-Schema.pdf|thumb|left|400px]]&lt;br /&gt;
[[Fichier:2023-BlueTooth-PCB.jpg|thumb|right|400px]]&lt;br /&gt;
&lt;br /&gt;
Contrairement au titre du projet KiCAD cette carte est un transmetteur/récepteur radio générique.&lt;br /&gt;
&lt;br /&gt;
Projet KiCAD : [[Fichier:2023-BlueTooth-KiCAD.zip]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p style=&amp;quot;clear: both;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Réalisations des binômes =&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Numéro !! Elèves !! Page &lt;br /&gt;
|-&lt;br /&gt;
| Binôme 1&lt;br /&gt;
| Victorien DETREZ &amp;amp; Benjamin CART&lt;br /&gt;
| [[SE3Binome2023-1|Binôme 1 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 2&lt;br /&gt;
| Bilal MOUSSA &amp;amp; Yassine YAHIANI&lt;br /&gt;
| [[SE3Binome2023-2|Binôme 2 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 3&lt;br /&gt;
| Kaoutar El Bachiri &amp;amp; Maxime BARRET&lt;br /&gt;
| [[SE3Binome2023-3|Binôme 3 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 4&lt;br /&gt;
| Prénom NOM &amp;amp; Prénom NOM&lt;br /&gt;
| [[SE3Binome2023-4|Binôme 4 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 5&lt;br /&gt;
| Prénom NOM &amp;amp; Prénom NOM&lt;br /&gt;
| [[SE3Binome2023-5|Binôme 5 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 6&lt;br /&gt;
| Lililan GREVIN &amp;amp; Pierre CASIMIRI&lt;br /&gt;
| [[SE3Binome2023-6|Binôme 6 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 7&lt;br /&gt;
| Augustin DJAJDJA-AVONYO &amp;amp; Kévan TOURON&lt;br /&gt;
| [[SE3Binome2023-7|Binôme 7 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 8&lt;br /&gt;
| Justin WACQUET &amp;amp; Ibrahim TEPELI&lt;br /&gt;
| [[SE3Binome2023-8|Binôme 8 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Monôme 9&lt;br /&gt;
| Mahmoud RABIA&lt;br /&gt;
| [[SE3Binome2023-9|Monôme 9 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 10&lt;br /&gt;
| Prénom NOM &amp;amp; Prénom NOM&lt;br /&gt;
| [[SE3Binome2023-10|Binôme 10 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Réalisations en programmation des systèmes embarqués =&lt;br /&gt;
&lt;br /&gt;
== Binômes ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Numéro !! Elèves !! Page &lt;br /&gt;
|-&lt;br /&gt;
| Binôme 1&lt;br /&gt;
| Kaoutar EL BACHIRI &amp;amp; Maxime BARRET&lt;br /&gt;
| [[SE3_PSE_Binome2023-1|Binôme 1 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 2&lt;br /&gt;
| Sarah Deparis &amp;amp; Agathe Houdusse&lt;br /&gt;
| [[SE3_PSE_Binome2023-2|Binôme 2 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 3&lt;br /&gt;
| Victorien DETREZ &amp;amp; Benjamin CART&lt;br /&gt;
| [[SE3_PSE_Binome2023-3|Binôme 3 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 4&lt;br /&gt;
| Prénom NOM &amp;amp; Prénom NOM&lt;br /&gt;
| [[SE3_PSE_Binome2023-4|Binôme 4 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 5&lt;br /&gt;
| Prénom NOM &amp;amp; Prénom NOM&lt;br /&gt;
| [[SE3_PSE_Binome2023-5|Binôme 5 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 6&lt;br /&gt;
| Lilian GREVIN &amp;amp; Pierre CASIMIRI&lt;br /&gt;
| [[SE3_PSE_Binome2023-6|Binôme 6 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 7&lt;br /&gt;
| Prénom NOM &amp;amp; Prénom NOM&lt;br /&gt;
| [[SE3_PSE_Binome2023-7|Binôme 7 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 8&lt;br /&gt;
| Prénom NOM &amp;amp; Prénom NOM&lt;br /&gt;
| [[SE3_PSE_Binome2023-8|Binôme 8 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 9&lt;br /&gt;
| Prénom NOM &amp;amp; Prénom NOM&lt;br /&gt;
| [[SE3_PSE_Binome2023-9|Binôme 9 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 10&lt;br /&gt;
| Prénom NOM &amp;amp; Prénom NOM&lt;br /&gt;
| [[SE3_PSE_Binome2023-10|Binôme 10 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Manette USB ==&lt;br /&gt;
&lt;br /&gt;
Projet KiCAD de base pour les manettes : [[Fichier:2023-ManetteSE3-KiCAD.zip]]&lt;br /&gt;
&lt;br /&gt;
Utilisez vos pages Wiki pour :&lt;br /&gt;
* attacher votre projet KiCAD ;&lt;br /&gt;
* déposer une photo de la carte soudée.&lt;br /&gt;
&lt;br /&gt;
== Programmateur AVR ==&lt;br /&gt;
&lt;br /&gt;
Utilisez vos pages Wiki pour :&lt;br /&gt;
* attacher vos programmes C (LUFA et libusb) ;&lt;br /&gt;
* déposer une photo de la carte soudée ;&lt;br /&gt;
* déposer une très courte vidéo de la carte avec les LED clignotantes ;&lt;br /&gt;
* déposer une copie écran montrant l'affichage de la communication entre votre programme libusb, votre carte et le microcontrôleur AVR.&lt;/div&gt;</summary>
		<author><name>Mbarret</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE3_PSE_Binome2023-1&amp;diff=3376</id>
		<title>SE3 PSE Binome2023-1</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE3_PSE_Binome2023-1&amp;diff=3376"/>
		<updated>2024-03-05T13:40:34Z</updated>

		<summary type="html">&lt;p&gt;Mbarret : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Projet: Voiture commandée par USB&lt;br /&gt;
&lt;br /&gt;
Limitations et fonctionnalités:&amp;lt;br&amp;gt;&lt;br /&gt;
-taille de la carte 10x10cm maximum &amp;lt;br&amp;gt;&lt;br /&gt;
-Utilisation de LEDs (jaunes) comme clignotants de la voiture ainsi que pour les feux de recul (blanc) et feux de stop à l’arrêt (Rouge).  Clignotants si partie mécanique réalisée.&amp;lt;br&amp;gt;&lt;br /&gt;
-Présence d'un port USB pour la programmation&amp;lt;br&amp;gt;&lt;br /&gt;
-Gestion de l'énergie par batterie LiPo&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Composants prévus à la conception: Batterie LiPo + Puce de controle MAX1811, 4 Leds jaunes, 2 leds blanches et 2 leds rouges, utilisation des mini-moteurs continus et du pilote des moteurs, microcontrôleur ATMega16u4.&lt;/div&gt;</summary>
		<author><name>Mbarret</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE3_PSE_Binome2023-1&amp;diff=3374</id>
		<title>SE3 PSE Binome2023-1</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE3_PSE_Binome2023-1&amp;diff=3374"/>
		<updated>2024-03-05T13:36:17Z</updated>

		<summary type="html">&lt;p&gt;Mbarret : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Projet: Voiture commandée par USB&lt;br /&gt;
&lt;br /&gt;
Limitations et fonctionnalités:&amp;lt;br&amp;gt;&lt;br /&gt;
-taille de la carte 10x10cm maximum &amp;lt;br&amp;gt;&lt;br /&gt;
-Utilisation de LEDs (jaunes) comme clignotants de la voiture ainsi que pour les feux de recul (blanc) et feux de stop à l’arrêt (Rouge).&amp;lt;br&amp;gt;&lt;br /&gt;
-Présence d'un port USB pour la programmation&amp;lt;br&amp;gt;&lt;br /&gt;
-Gestion de l'énergie par batterie LiPo&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Composants prévus à la conception: Batterie LiPo, 4 Leds jaunes, 2 leds blanches et 2 leds rouges.&lt;/div&gt;</summary>
		<author><name>Mbarret</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE3_PSE_Binome2023-1&amp;diff=3373</id>
		<title>SE3 PSE Binome2023-1</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE3_PSE_Binome2023-1&amp;diff=3373"/>
		<updated>2024-03-05T13:36:06Z</updated>

		<summary type="html">&lt;p&gt;Mbarret : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Projet: Voiture commandée par USB&lt;br /&gt;
&lt;br /&gt;
Limitations et fonctionnalités:&lt;br /&gt;
-taille de la carte 10x10cm maximum &amp;lt;br&amp;gt;&lt;br /&gt;
-Utilisation de LEDs (jaunes) comme clignotants de la voiture ainsi que pour les feux de recul (blanc) et feux de stop à l’arrêt (Rouge).&amp;lt;br&amp;gt;&lt;br /&gt;
-Présence d'un port USB pour la programmation&amp;lt;br&amp;gt;&lt;br /&gt;
-Gestion de l'énergie par batterie LiPo&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Composants prévus à la conception: Batterie LiPo, 4 Leds jaunes, 2 leds blanches et 2 leds rouges.&lt;/div&gt;</summary>
		<author><name>Mbarret</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE3_PSE_Binome2023-1&amp;diff=3372</id>
		<title>SE3 PSE Binome2023-1</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE3_PSE_Binome2023-1&amp;diff=3372"/>
		<updated>2024-03-05T13:35:53Z</updated>

		<summary type="html">&lt;p&gt;Mbarret : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Projet: Voiture commandée par USB&lt;br /&gt;
&lt;br /&gt;
Limitations et fonctionnalités:&lt;br /&gt;
-taille de la carte 10x10cm maximum &amp;lt;br&amp;gt;&lt;br /&gt;
-Utilisation de LEDs (jaunes) comme clignotants de la voiture ainsi que pour les feux de recul (blanc) et feux de stop à l’arrêt (Rouge).&lt;br /&gt;
-Présence d'un port USB pour la programmation&lt;br /&gt;
-Gestion de l'énergie par batterie LiPo&lt;br /&gt;
&lt;br /&gt;
Composants prévus à la conception: Batterie LiPo, 4 Leds jaunes, 2 leds blanches et 2 leds rouges.&lt;/div&gt;</summary>
		<author><name>Mbarret</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE3_PSE_Binome2023-1&amp;diff=3371</id>
		<title>SE3 PSE Binome2023-1</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE3_PSE_Binome2023-1&amp;diff=3371"/>
		<updated>2024-03-05T13:35:36Z</updated>

		<summary type="html">&lt;p&gt;Mbarret : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Projet: Voiture commandée par USB&lt;br /&gt;
&lt;br /&gt;
Limitations et fonctionnalités:&lt;br /&gt;
-taille de la carte 10x10cm maximum&lt;br /&gt;
-Utilisation de LEDs (jaunes) comme clignotants de la voiture ainsi que pour les feux de recul (blanc) et feux de stop à l’arrêt (Rouge).&lt;br /&gt;
-Présence d'un port USB pour la programmation&lt;br /&gt;
-Gestion de l'énergie par batterie LiPo&lt;br /&gt;
&lt;br /&gt;
Composants prévus à la conception: Batterie LiPo, 4 Leds jaunes, 2 leds blanches et 2 leds rouges.&lt;/div&gt;</summary>
		<author><name>Mbarret</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE3_PSE_Binome2023-1&amp;diff=3367</id>
		<title>SE3 PSE Binome2023-1</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE3_PSE_Binome2023-1&amp;diff=3367"/>
		<updated>2024-03-05T13:33:13Z</updated>

		<summary type="html">&lt;p&gt;Mbarret : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Projet: Voiture commandée par USB&lt;br /&gt;
&lt;br /&gt;
Limitations et fonctionnalités:&lt;br /&gt;
-taille de la carte 10x10cm maximum&lt;br /&gt;
-Utilisation de LEDs (jaunes) comme clignotants de la voiture ainsi que pour les feux de recul (blanc) et feux de stop à l’arrêt (Rouge).&lt;/div&gt;</summary>
		<author><name>Mbarret</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE3_PSE_Binome2023-1&amp;diff=3358</id>
		<title>SE3 PSE Binome2023-1</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE3_PSE_Binome2023-1&amp;diff=3358"/>
		<updated>2024-03-05T13:27:56Z</updated>

		<summary type="html">&lt;p&gt;Mbarret : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Projet: Voiture commandée par USB&lt;br /&gt;
&lt;br /&gt;
Limitations:&lt;br /&gt;
-taille de la carte 10x10cm maximum&lt;/div&gt;</summary>
		<author><name>Mbarret</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=PSE_SE3_2023/2024&amp;diff=3354</id>
		<title>PSE SE3 2023/2024</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=PSE_SE3_2023/2024&amp;diff=3354"/>
		<updated>2024-03-05T13:24:01Z</updated>

		<summary type="html">&lt;p&gt;Mbarret : /* Binômes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Objectif =&lt;br /&gt;
&lt;br /&gt;
Pour l'année académique 2023/2024 il est toujours demandé de réaliser un système embarqué.&lt;br /&gt;
&lt;br /&gt;
== Microcontrôleur ==&lt;br /&gt;
&lt;br /&gt;
Pour éviter les problème avec les conversions analogique vers numérique vous utiliserez un ATmega16u4 ou un ATmega32u4. La programmation peut ainsi se faire très simplement par DFU/USB.&lt;br /&gt;
&lt;br /&gt;
== Energie ==&lt;br /&gt;
&lt;br /&gt;
Vos cartes doivent pouvoir être alimentées de façon hybride :&lt;br /&gt;
* par un port USB, méthode utilisée pour la programmation et les tests ;&lt;br /&gt;
* par une batterie Lithium, en mode autonome.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:puce_max1811.jpg|Puce de contrôle de charge&lt;br /&gt;
File:batteries_LiPo.jpg|Batteries 100mAh et 300mAh, connecteur molex mâle&lt;br /&gt;
File:batterie_LiPo_FQ777.jpg|Batterie 100mAh 15x20x5mm&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il est conseillé de séparer au maximum les deux alimentations, voir la seconde version de la carte de test de chargement de batterie.&lt;br /&gt;
&lt;br /&gt;
== Fonctionnalités ==&lt;br /&gt;
&lt;br /&gt;
Vos cartes doivent toutes comporter des LED commandées par le microcontrôleur. Les autres fonctionnalités peuvent être choisies dans la liste suivante (non exhaustive). Les fonctionnalités doivent être validées par un intervenant.&lt;br /&gt;
&lt;br /&gt;
* Vous pouvez partir sur le projet voiture de l'an passé en simplifiant l'aspect mécanique : deux moteurs pour les deux roues motrices, des roues directement enfilées sur les méplats des moteurs continus ou sur des engrenages montés en force sur l'axe des moteurs pas à pas. Le comportement de la voiture est téléchargé par une liaison USB/série et permet de spécifier une suite de commandes sur les deux moteurs et les lampes de la voiture.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
file:2023-chassis-simple-dessus.png|Chassis vu de dessus&lt;br /&gt;
file:2023-chassis-simple-cote.png|Chassis vu de coté&lt;br /&gt;
File:micro-moteur-pas-a-pas-simple.jpg|Micro-moteur pas à pas propulsion&lt;br /&gt;
File:mini-motoreducteur.jpg|Mini-moteur continu avec réducteur&lt;br /&gt;
File:pilote-moteur-TB6612FNG.png|Pilote pour le mini-moteur continu (TB6612FNG)&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Vous pouvez partir sur un objet autonome communicant de type capteur, par exemple un capteur de température ou un micro espion. Le coté autonome est donné par la batterie, le coté communicant est à travailler à partir de la puce NRF24L01. Cette puce est une puce radio générale. Vous pouvez la tester à partir de la carte de test présenté dans la suite de ce sujet. Pour la réception des données de votre objet plusieurs alternatives sont possibles : mettre rapidement au point un récepteur à base de module basé sur un NRF24L01 et un Arduino ou vous entendre avec un autre binôme dont l'objet est soit :&lt;br /&gt;
** une centrale d'affichage des données des objets communicants sur des afficheurs 7 segments, un écran LCD alphanumérique ou un écran LCD graphique ;&lt;br /&gt;
** un périphérique USB de type carte son permettant de récupérer le flux du micro espion, dans ce dernier cas attention à bien sélectionner un microcontrôleur adapté.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:module_nrf24L01.jpg|Module de communication 2,4Ghz&lt;br /&gt;
File:puce_nrf24L01.jpg|Puce de communication (soudure complexe)&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Vous pouvez tenter un objet autonome communicant de type actionneur, par exemple un haut-parleur diffusant les sons envoyés par un module radio. Là encore les sons peuvent être envoyés par un prototype à base d'Arduino ou par la carte d'un autre binôme réalisant un périphérique USB de type audio. Dans ce dernier cas attention à bien sélectionner un microcontrôleur adapté.&lt;br /&gt;
&lt;br /&gt;
* Enfin si vous ne vous sentez pas trop sûr de vous il reste toujours la possibilité de l'objet complétement autonome comportant des capteurs et des actionneurs et réagissant en fonction de son environnement. Un exemple est un détecteur de mouvement à base de capteur PIR (Passive Infra-Red) donnant lieu à une séquence animée à base de LED ou à une séquence sonore.&lt;br /&gt;
&lt;br /&gt;
= Cartes de test =&lt;br /&gt;
&lt;br /&gt;
Cette année, plutôt que vous proposer des schémas complets de voitures, il a été décidé de vous proposer des cartes démontrant, chacune, une fonctionnalité éventuellement intégrable dans votre voiture.&lt;br /&gt;
&lt;br /&gt;
== Test du chargeur ==&lt;br /&gt;
&lt;br /&gt;
[[Fichier:2023-ChargeurLiPo-Schema.pdf|thumb|left|400px]]&lt;br /&gt;
[[Fichier:2023-ChargeurLiPo-PCB.jpg|thumb|right|400px]]&lt;br /&gt;
&lt;br /&gt;
Les schéma et routage de la carte. Avec une erreur de base, le microcontrôleur est un ATmega32u2, c'est à dire un AVR sans ADC donc récupérer la tension de la batterie sera en tout ou rien. Un autre problème de conception est la trop faible charge de la LED qui peine à décharger la batterie.&lt;br /&gt;
&lt;br /&gt;
Projet KiCAD : [[Fichier:2023-ChargeurLiPo-KiCAD.zip]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p style=&amp;quot;clear: both;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Fichier:2023-ChargeurLiPo-Complete1.jpg|thumb|left|150px]]&lt;br /&gt;
[[Fichier:2023-ChargeurLiPo-Complete2.jpg|thumb|right|400px]]&lt;br /&gt;
&lt;br /&gt;
Vous trouvez ici deux photos de la carte soudée.&lt;br /&gt;
&lt;br /&gt;
Vous avez aussi un programme LUFA basé sur la démonstration &amp;lt;code&amp;gt;VirtualSerial&amp;lt;/code&amp;gt; pour contrôler la carte, en particulier lancer la charge de la batterie et voir si sa tension se traduit par un état haut ou bas. Tapez n'importe quoi avec un retour chariot dans un terminal série pour voir la liste des commandes possibles.&lt;br /&gt;
&lt;br /&gt;
Programme : [[Media:2023-ChargeurLiPo-VirtualSerial.zip]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p style=&amp;quot;clear: both;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Les tests de la première version de la carte n'ont pas été super-concluant. Il faut dire qu'il y avait quelques erreurs de conception :&lt;br /&gt;
* le plus grave : le condensateur en parallèle de la batterie était noté 100nF au lieu des 2,2µF indiqué dans les documents technique, de plus le condensateur de 4,7µF demandé sur l'alimentation de la puce n'était pas implanté ;&lt;br /&gt;
* l'idée de commander la LED d'éclairage via le 5V du connecteur USB n'était pas très malin, cela interdisait une utilisation de la LED la carte non connectée sur une alimentation USB ;&lt;br /&gt;
* comme indiqué plus haut, il vaut mieux utiliser un ATmega16u4 qu'un ATmega16u2 ;&lt;br /&gt;
* plus généralement déconnecter au maximum la partie &amp;quot;utilisation&amp;quot; de la batterie de la partie &amp;quot;recharge&amp;quot; de la batterie réduit les problèmes potentiels.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:2023-ChargeurLiPo-Schema-V2.pdf|thumb|left|400px]]&lt;br /&gt;
[[Fichier:2023-ChargeurLiPo-PCB-V2.png|thumb|right|400px]]&lt;br /&gt;
&lt;br /&gt;
Nouvelle version de la carte avec deux connecteurs USB : un USB A pour sa programmation et son fonctionnement USB, un USB mini pour la recharge de la batterie. Un interrupteur permet d'utiliser la LED, un autre de démarrer le microcontrôleur.&lt;br /&gt;
&lt;br /&gt;
Projet KiCAD : [[Fichier:2023-ChargeurLiPo-KiCAD-V2.zip]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p style=&amp;quot;clear: both;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Test du transmetteur radio ==&lt;br /&gt;
&lt;br /&gt;
[[Fichier:2023-BlueTooth-Schema.pdf|thumb|left|400px]]&lt;br /&gt;
[[Fichier:2023-BlueTooth-PCB.jpg|thumb|right|400px]]&lt;br /&gt;
&lt;br /&gt;
Contrairement au titre du projet KiCAD cette carte est un transmetteur/récepteur radio générique.&lt;br /&gt;
&lt;br /&gt;
Projet KiCAD : [[Fichier:2023-BlueTooth-KiCAD.zip]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p style=&amp;quot;clear: both;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Réalisations des binômes =&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Numéro !! Elèves !! Page &lt;br /&gt;
|-&lt;br /&gt;
| Binôme 1&lt;br /&gt;
| Prénom NOM &amp;amp; Prénom NOM&lt;br /&gt;
| [[SE3Binome2023-1|Binôme 1 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 2&lt;br /&gt;
| Prénom NOM &amp;amp; Prénom NOM&lt;br /&gt;
| [[SE3Binome2023-2|Binôme 2 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 3&lt;br /&gt;
| Prénom NOM &amp;amp; Prénom NOM&lt;br /&gt;
| [[SE3Binome2023-3|Binôme 3 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 4&lt;br /&gt;
| Prénom NOM &amp;amp; Prénom NOM&lt;br /&gt;
| [[SE3Binome2023-4|Binôme 4 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 5&lt;br /&gt;
| Prénom NOM &amp;amp; Prénom NOM&lt;br /&gt;
| [[SE3Binome2023-5|Binôme 5 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 6&lt;br /&gt;
| Prénom NOM &amp;amp; Prénom NOM&lt;br /&gt;
| [[SE3Binome2023-6|Binôme 6 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 7&lt;br /&gt;
| Prénom NOM &amp;amp; Prénom NOM&lt;br /&gt;
| [[SE3Binome2023-7|Binôme 7 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 8&lt;br /&gt;
| Prénom NOM &amp;amp; Prénom NOM&lt;br /&gt;
| [[SE3Binome2023-8|Binôme 8 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 9&lt;br /&gt;
| Prénom NOM &amp;amp; Prénom NOM&lt;br /&gt;
| [[SE3Binome2023-9|Binôme 9 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 10&lt;br /&gt;
| Prénom NOM &amp;amp; Prénom NOM&lt;br /&gt;
| [[SE3Binome2023-10|Binôme 10 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Réalisations en programmation des systèmes embarqués =&lt;br /&gt;
&lt;br /&gt;
== Binômes ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Numéro !! Elèves !! Page &lt;br /&gt;
|-&lt;br /&gt;
| Binôme 1&lt;br /&gt;
| Kaoutar EL BACHIRI &amp;amp; Maxime BARRET&lt;br /&gt;
| [[SE3_PSE_Binome2023-1|Binôme 1 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 2&lt;br /&gt;
| Prénom NOM &amp;amp; Prénom NOM&lt;br /&gt;
| [[SE3_PSE_Binome2023-2|Binôme 2 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 3&lt;br /&gt;
| Prénom NOM &amp;amp; Prénom NOM&lt;br /&gt;
| [[SE3_PSE_Binome2023-3|Binôme 3 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 4&lt;br /&gt;
| Prénom NOM &amp;amp; Prénom NOM&lt;br /&gt;
| [[SE3_PSE_Binome2023-4|Binôme 4 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 5&lt;br /&gt;
| Prénom NOM &amp;amp; Prénom NOM&lt;br /&gt;
| [[SE3_PSE_Binome2023-5|Binôme 5 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 6&lt;br /&gt;
| Prénom NOM &amp;amp; Prénom NOM&lt;br /&gt;
| [[SE3_PSE_Binome2023-6|Binôme 6 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 7&lt;br /&gt;
| Prénom NOM &amp;amp; Prénom NOM&lt;br /&gt;
| [[SE3_PSE_Binome2023-7|Binôme 7 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 8&lt;br /&gt;
| Prénom NOM &amp;amp; Prénom NOM&lt;br /&gt;
| [[SE3_PSE_Binome2023-8|Binôme 8 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 9&lt;br /&gt;
| Prénom NOM &amp;amp; Prénom NOM&lt;br /&gt;
| [[SE3_PSE_Binome2023-9|Binôme 9 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 10&lt;br /&gt;
| Prénom NOM &amp;amp; Prénom NOM&lt;br /&gt;
| [[SE3_PSE_Binome2023-10|Binôme 10 2023/2024]]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Manette USB ==&lt;br /&gt;
&lt;br /&gt;
Projet KiCAD de base pour les manettes : [[Fichier:2023-ManetteSE3-KiCAD.zip]]&lt;br /&gt;
&lt;br /&gt;
Utilisez vos pages Wiki pour :&lt;br /&gt;
* attacher votre projet KiCAD ;&lt;br /&gt;
* déposer une photo de la carte soudée.&lt;br /&gt;
&lt;br /&gt;
== Programmateur AVR ==&lt;br /&gt;
&lt;br /&gt;
Utilisez vos pages Wiki pour :&lt;br /&gt;
* attacher vos programmes C (LUFA et libusb) ;&lt;br /&gt;
* déposer une photo de la carte soudée ;&lt;br /&gt;
* déposer une très courte vidéo de la carte avec les LED clignotantes ;&lt;br /&gt;
* déposer une copie écran montrant l'affichage de la communication entre votre programme libusb, votre carte et le microcontrôleur AVR.&lt;/div&gt;</summary>
		<author><name>Mbarret</name></author>
	</entry>
</feed>