<?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=Tnehari</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=Tnehari"/>
	<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php/Sp%C3%A9cial:Contributions/Tnehari"/>
	<updated>2026-05-14T03:43:29Z</updated>
	<subtitle>Contributions</subtitle>
	<generator>MediaWiki 1.39.1</generator>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2023-1&amp;diff=2923</id>
		<title>SE4Binome2023-1</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2023-1&amp;diff=2923"/>
		<updated>2024-01-17T15:32:20Z</updated>

		<summary type="html">&lt;p&gt;Tnehari : /* Conclusion */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Ordonnanceur =&lt;br /&gt;
&lt;br /&gt;
== Soudure et Test du SHIELD ==&lt;br /&gt;
Au cours des 2 premières séances nous avons soudé et testé notre Shield&lt;br /&gt;
[[Fichier:ShieldSoudé.jpg|thumb|center|300x300px|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Shield soudé et monté sur Arduino&amp;lt;/div&amp;gt;]]&lt;br /&gt;
 &lt;br /&gt;
Sur l'un des connecteurs, la led est abîmée dû à une soudure excessive. Sachant que les leds sont uniquement utilisées en tant qu'indicateurs pour savoir quelle carte fille à le contrôle et que nous n'en utiliserons pas plus de 3 pour tester nos programmes, cela ne vas pas avoir d'influence négative.&lt;br /&gt;
Le potentiomètre permet de régler le niveau de luminosité de l'écran et le connecteur HE10 permettra de comuniquer avec l'écran.&lt;br /&gt;
Les problèmes rencontrés sont les suivants : Au départ, la carte ne fonctionnait pas, le soucis étant le quartz mal soudé, c'est à l'aide d'un pistolet à air chaud que celui-ci à été ressoudé. Un autre problème était le reset de la carte fille qui ne fonctionnait pas non plus, une ressoudure classique a permis de le faire fonctionner.&lt;br /&gt;
&lt;br /&gt;
{| class=wikitable style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Code&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Image&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void init_led(){&lt;br /&gt;
  DDRD=0x92;&lt;br /&gt;
  DDRC=0x09;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
  init_led();&lt;br /&gt;
  while(1)&lt;br /&gt;
    {&lt;br /&gt;
	PORTD=0x92;&lt;br /&gt;
	PORTC=0x09;&lt;br /&gt;
    }&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
[[Fichier:ShieldLed.jpg|thumb|center|300x300px|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Test des Leds du Shield&amp;lt;/div&amp;gt;]]&lt;br /&gt;
|}&lt;br /&gt;
Puis nous avons aussi soudé l'adaptateur HE10 pour l'utilisation de la matrice de leds[[Fichier:Adaptateur HE10.jpg|thumb|center|300x300px|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Adaptateur HE10 pour Matrice de leds&amp;lt;/div&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
== Programmation de l'Ordonnanceur ==&lt;br /&gt;
Nous commençons maintenant l'ordonnanceur, tout d'abord nous créeons la structure de nos Taches.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:50%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
struct TacheInfo{&lt;br /&gt;
	void (*depart)(void);&lt;br /&gt;
	uint16_t SPointeur;&lt;br /&gt;
	int etat;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
|}&lt;br /&gt;
Puis nous ajoutons les 2 premières taches demandées qui sont de faire clignoter 2 leds différentes à des timing différents.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:50%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
void TacheA(){&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
        PORTC ^= 0x08;&lt;br /&gt;
	_delay_ms(300);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void TacheB(){&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
        PORTD ^= 0x80;&lt;br /&gt;
	_delay_ms(500);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
struct TacheInfo Taches[2]={&lt;br /&gt;
  {TacheA,0x0600,0},&lt;br /&gt;
  {TacheB,0x0700,0}&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
On s'occupe maintenant de l'ordonnanceur, ainsi que de l'ISR.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:50%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
void ordonnanceur ()&lt;br /&gt;
{	&lt;br /&gt;
	PORTD ^= 0x02;&lt;br /&gt;
	courant++;&lt;br /&gt;
	if (courant == NBR_TACHE) courant = 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect,ISR_NAKED)&lt;br /&gt;
{&lt;br /&gt;
	/* Sauvegarde du contexte de la tâche interrompue */&lt;br /&gt;
	SAVE_REGISTER();&lt;br /&gt;
	Taches[courant].SPointeur = SP;&lt;br /&gt;
&lt;br /&gt;
	/* Appel à l'ordonnanceur */&lt;br /&gt;
	ordonnanceur();&lt;br /&gt;
&lt;br /&gt;
	/* Récupération du contexte de la tâche ré-activée */&lt;br /&gt;
	SP = Taches[courant].SPointeur;&lt;br /&gt;
	RESTORE_REGISTER();&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;
Nous avons décider de faire clignoter une LED (PORTD ^= 0x02) à chaques utilisations de la fonction ordonnanceur() dans l'ISR.&lt;br /&gt;
&lt;br /&gt;
La variable courant indique la Tache qui est actuellement en cours.&lt;br /&gt;
&lt;br /&gt;
A chaque chaques changements de tache, l'ISR se déclenche enregistre la tache en cours (les registres ainsi que le Stack Pointer), appel l'ordonnanceur, puis change &amp;quot;charge&amp;quot; la tache suivante.&lt;br /&gt;
&lt;br /&gt;
On oublie pas maintenant de générer l'interruption toute les 20ms, pour cela on choisit un prescaler de 1024 et un nombre de ticks de 312.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:50%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
#define PRESCALER 1024&lt;br /&gt;
#define NB_TICK  312&lt;br /&gt;
#define CTC1  WGM12&lt;br /&gt;
&lt;br /&gt;
void init_timer(){&lt;br /&gt;
TCCR1A = 0;  // No output pin connected, no PWM mode enabled&lt;br /&gt;
TCCR1B = 1&amp;lt;&amp;lt;CTC1; // No input pin used, clear timer counter on compare match&lt;br /&gt;
#if (PRESCALER==1024)&lt;br /&gt;
 TCCR1B |= (1&amp;lt;&amp;lt;CS12 | 1&amp;lt;&amp;lt;CS10);&lt;br /&gt;
#endif&lt;br /&gt;
OCR1A = NB_TICK;&lt;br /&gt;
TCNT1 = 0;&lt;br /&gt;
TIMSK1 = (1&amp;lt;&amp;lt;OCIE1A); // No overflow mode enabled, no input interrupt, output compare interrupt&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Ainsi que d'initialiser les Taches pour assurer le bon fonctionnement de notre ordonnanceur.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:50%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
void init_taches(int pid)&lt;br /&gt;
{&lt;br /&gt;
	int save=SP;&lt;br /&gt;
	SP=Taches[pid].SPointeur;&lt;br /&gt;
	uint16_t adresse=(uint16_t)Taches[pid].depart;&lt;br /&gt;
	asm volatile (&amp;quot;push %0 \n\t&amp;quot; : : &amp;quot;r&amp;quot; (adresse &amp;amp; 0x00ff));&lt;br /&gt;
	asm volatile (&amp;quot;push %0 \n\t&amp;quot; : : &amp;quot;r&amp;quot; ((adresse &amp;amp; 0xff00) &amp;gt;&amp;gt; 8));&lt;br /&gt;
	SAVE_REGISTER();&lt;br /&gt;
	Taches[pid].SPointeur=SP;&lt;br /&gt;
	SP=save;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
On peut maintenant tester notre ordonnanceur.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Video Test&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
#define NBR_TACHE 2&lt;br /&gt;
int main(void){&lt;br /&gt;
	init_ports();&lt;br /&gt;
	init_timer();&lt;br /&gt;
	init_taches(1);&lt;br /&gt;
	sei();&lt;br /&gt;
	SP = Taches[courant].SPointeur;&lt;br /&gt;
	Taches[courant].depart();&lt;br /&gt;
	return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |[[Fichier:Video 2leds shield.mp4|centré|vignette|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Video test du clignotement de 2 Leds &amp;lt;/div&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
Les 2 leds clignotent bien avec le bon timing, et la led témoin de l'ordonnanceur clignotent aussi, ce qui indique que l'ISR est bien actif.&lt;br /&gt;
&lt;br /&gt;
Nous pouvons donc maitenant passer à la gestion des &amp;quot;sleeps&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
En effet, l'utilisation de _delay_ms dans chaque tache n'est pas la manière la plus optimale de procéder. Et meme cela nous bloquera par la suite.&lt;br /&gt;
&lt;br /&gt;
Nous ajoute donc à la structure de nos Taches, une structure InfoEndormi, qui, comme son nom l'indique nous donne des informations si la tache est endormie. A savoir la raison mais aussi des donnees comme par exemple le temps que cette tache doit passer endormie.&lt;br /&gt;
&lt;br /&gt;
Puis afin de remplacer _delay_ms, nous créeons une fonction Attente qui endors une tache pour un temps donné.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
#define REVEILLE 0&lt;br /&gt;
#define ENDORMI 1&lt;br /&gt;
#define RAISON_DELAY 0&lt;br /&gt;
&lt;br /&gt;
struct InfoEndormi{&lt;br /&gt;
    int raison;&lt;br /&gt;
    uint16_t donnee;&lt;br /&gt;
}sleep_t;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
struct TacheInfo{&lt;br /&gt;
    void (*depart)(void); &lt;br /&gt;
    uint16_t SPointeur;&lt;br /&gt;
    int etat;&lt;br /&gt;
    struct InfoEndormi endormi;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
void Attente(uint16_t temps_ms){&lt;br /&gt;
    cli();&lt;br /&gt;
    Taches[Tache_courante].etat = ENDORMI;&lt;br /&gt;
    Taches[Tache_courante].endormi.raison = RAISON_DELAY;&lt;br /&gt;
    Taches[Tache_courante].endormi.donnee = temps_ms;&lt;br /&gt;
    TCNT1 = 0;&lt;br /&gt;
    sei();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
Voila maitenant nos taches, il est important de créer une TacheZombie qui comme son nom l'indique est toujours révéillée.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:50%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
void TacheZombie() //Tache toujours réveillé&lt;br /&gt;
{&lt;br /&gt;
	while(1)&lt;br /&gt;
	{&lt;br /&gt;
		_delay_ms(1.5*PERIODE_INTERUPTION); //Delay légèrement supèrieur à la periode pour éviter tout soucis&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void TacheA()&lt;br /&gt;
{&lt;br /&gt;
	while(1)&lt;br /&gt;
	{&lt;br /&gt;
		PORTC ^= 0x08;&lt;br /&gt;
		Attente(300);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void TacheB()&lt;br /&gt;
{&lt;br /&gt;
	while(1)&lt;br /&gt;
	{&lt;br /&gt;
		PORTD ^= 0x80;&lt;br /&gt;
		Attente(500);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Il est important maitenant de modifier notre ordonnanceur afin que celui-ci puisse recalculer le nouveau temps de sleep d'une tache et si ce temps devient inférieur ou ègale à 0 alors l'ordonnacnceur réveille la tache.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:50%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
void ordonnanceur ()&lt;br /&gt;
{&lt;br /&gt;
	PORTD ^= 0x02;&lt;br /&gt;
	for(int i = 0; i &amp;lt; NBR_TACHE; i++)&lt;br /&gt;
	{&lt;br /&gt;
		if(Taches[i].etat == ENDORMI &amp;amp;&amp;amp; Taches[Tache_courante].endormi.raison == RAISON_DELAY)&lt;br /&gt;
		{&lt;br /&gt;
			uint16_t diff_temps = PERIODE_INTERUPTION;&lt;br /&gt;
			if(TCNT1 != 0)&lt;br /&gt;
			{&lt;br /&gt;
				//Calcul précis de la différence de temps (pas obligatoirement 20 ms)&lt;br /&gt;
				diff_temps = ((TCNT1*PERIODE_INTERUPTION*10)/OCR1A)/10;&lt;br /&gt;
				TCNT1 = 0;&lt;br /&gt;
			}&lt;br /&gt;
			Taches[i].endormi.donnee  -= diff_temps;&lt;br /&gt;
            &lt;br /&gt;
			if(Taches[i].endormi.donnee &amp;lt;= 0)&lt;br /&gt;
			{&lt;br /&gt;
				Taches[i].etat = REVEILLE;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
    &lt;br /&gt;
	do&lt;br /&gt;
	{&lt;br /&gt;
		Tache_courante++;&lt;br /&gt;
		if (Tache_courante == NBR_TACHE) Tache_courante = 0;&lt;br /&gt;
    }&lt;br /&gt;
	while(Taches[Tache_courante].etat == ENDORMI);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Maintenant que cela est fait, nous pouvons ajouter 2 nouvelles taches qui sont la lecture et l'ecriture sur le port série.&lt;br /&gt;
&lt;br /&gt;
Pour cela, nous allons procéder avec des sémaphores. En effet, il ne peut y avoir que 1 seule tache en écriture ou en lecture, il faut donc que si plusieurs taches essaient de prendre la ressource, cette ressource soit donner à la première arrivé et que les autres taches en attendant patientent.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:50%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
void semaphore_e(int ACTION){&lt;br /&gt;
	if (ACTION == PRENDRE)&lt;br /&gt;
	{&lt;br /&gt;
		while(1)&lt;br /&gt;
		{&lt;br /&gt;
			cli();&lt;br /&gt;
			if (semaphore_ecriture &amp;gt; 0) //Si ressource dispo &lt;br /&gt;
			{&lt;br /&gt;
				semaphore_ecriture = 0;&lt;br /&gt;
				sei();&lt;br /&gt;
				break;&lt;br /&gt;
        		} else&lt;br /&gt;
			{&lt;br /&gt;
				// La ressource est occupée, on endort la tache&lt;br /&gt;
				Taches[Tache_courante].etat = ENDORMI;&lt;br /&gt;
				Taches[Tache_courante].endormi.raison = RAISON_ECRITURE;&lt;br /&gt;
				TCNT1=0;&lt;br /&gt;
				TIMER1_COMPA_vect();&lt;br /&gt;
			}&lt;br /&gt;
			sei();&lt;br /&gt;
			while(semaphore_ecriture==0);&lt;br /&gt;
		}&lt;br /&gt;
			&lt;br /&gt;
	}&lt;br /&gt;
	else if (ACTION == LAISSER)&lt;br /&gt;
	{&lt;br /&gt;
		cli();&lt;br /&gt;
		semaphore_ecriture = 1;&lt;br /&gt;
		sei();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
On fait la meme chose pour la lecture.&lt;br /&gt;
&lt;br /&gt;
On oublie pas d'initialiser le port série avec les bons paramètres, créer les taches, puis on test.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Image&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
void init_serie(long int vitesse){&lt;br /&gt;
	UBRR0=FREQ_CPU/(((unsigned long int)vitesse)&amp;lt;&amp;lt;4)-1; &lt;br /&gt;
        // configure la vitesse&lt;br /&gt;
	UCSR0B=(1&amp;lt;&amp;lt;TXEN0 | 1&amp;lt;&amp;lt;RXEN0);   // autorise l'envoi et la réception&lt;br /&gt;
	UCSR0C=(1&amp;lt;&amp;lt;UCSZ01 | 1&amp;lt;&amp;lt;UCSZ00); // 8 bits et 1 bit de stop&lt;br /&gt;
	UCSR0A &amp;amp;= ~(1 &amp;lt;&amp;lt; U2X0);         // double vitesse désactivée&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |[[Fichier:Lecture EcritureSerie.jpg|centré|vignette|356x356px|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Test de la lecture et de l'écriture sur le port série.(On écrie 9 caractères puis le shield nous renvoie les mêmes 9) &amp;lt;/div&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Carte électronique numérique =&lt;br /&gt;
&lt;br /&gt;
== Conception et Création ==&lt;br /&gt;
Nous avons choisi la Carte Fille : Ecran LCD &lt;br /&gt;
&lt;br /&gt;
Pendant la 3ème séance nous avons finis le Schématic de la carte &lt;br /&gt;
[[Fichier:SCH.png|centré|vignette|700x700px|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Schematic de la Carte Fille : Ecran LCD&amp;lt;/div&amp;gt;]]&lt;br /&gt;
Puis nous avons Routé la carte et envoyé à la Fabrication&lt;br /&gt;
[[Fichier:PCB LCD.png|centré|vignette|550x550px|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Routage de la Carte Fille : Ecran LCD&amp;lt;/div&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
{| class=wikitable style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Carte non soudée&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Carte soudée&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Video Test&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:33%;&amp;quot; |[[Fichier:Carte LCD non soudée.jpg|centré|vignette|300x300px|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Carte non soudée&amp;lt;/div&amp;gt;]]&lt;br /&gt;
| style=&amp;quot;width:33%;&amp;quot; |[[Fichier:Carte LCD soudee.jpg|centré|vignette|400x400px|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Carte soudée&amp;lt;/div&amp;gt;]]&lt;br /&gt;
| style=&amp;quot;width:33%;&amp;quot; |[[Fichier:Video TestLCD.mp4|centré|vignette|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Video test des leds&amp;lt;/div&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Programmation de la carte LCD ==&lt;br /&gt;
Tout d'abord, nous avons voulu tester le bon fonctionnement de notre carte mais surtout du bon controle de l'ecran HD44780 grâce à l'IDE Arduino.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Image&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
const int rs = 2, en = 18, d4 = 14, d5 = 15, d6 = 16, d7 = 17;&lt;br /&gt;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  // set up the LCD's number of columns and rows:&lt;br /&gt;
  pinMode(9,OUTPUT);&lt;br /&gt;
  digitalWrite(9,LOW);&lt;br /&gt;
  lcd.begin(16, 2);&lt;br /&gt;
  // Print a message to the LCD.&lt;br /&gt;
  lcd.print(&amp;quot;Je compte&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  // set the cursor to column 0, line 1&lt;br /&gt;
  // (note: line 1 is the second row, since counting begins with 0):&lt;br /&gt;
  lcd.setCursor(0, 1);&lt;br /&gt;
  // print the number of seconds since reset:&lt;br /&gt;
  lcd.print(millis() / 1000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |[[Fichier:TestLCDArduino.jpg|centré|vignette|375x375px|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Test LCD via IDE Arduino&amp;lt;/div&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
Maintenant que cela fonctionne, nous pouvons commencer à écrire notre Librairie pour faire fonctionner notre carte.&lt;br /&gt;
&lt;br /&gt;
=== Librairie HD44780 ===&lt;br /&gt;
Nous avons commencer par reprendre la librairie d'ancien élève, merci à eux pour leur travail.&lt;br /&gt;
&lt;br /&gt;
Dans notre cas, pour l'utilisation la plus simple nous avons besoin de plusieurs fonctions. La première écrit un caractère sur l'écran, la deuxième copie une ligne et la dernière efface une ligne.&lt;br /&gt;
&lt;br /&gt;
HD44780_CopyLine1in0 :&lt;br /&gt;
&lt;br /&gt;
Permet de copier la seconde ligne sur la première. Pour ce faire, on se place au début de la première ligne, on écrit le contenu du tableau de caractère, et on le vide ensuite (EmptyLine1).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:50%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
void HD44780_CopyLine1in0(char line1[], int nbrows, int nbcols, int ind_line1) {&lt;br /&gt;
    for (int i = 0; i &amp;lt; ind_line1; i++) {&lt;br /&gt;
        int address_ligne0 = HD44780_XY2Adrr(nbrows, nbcols, 0, i);&lt;br /&gt;
        HD44780_WriteCommand(LCD_ADDRSET | address_ligne0);&lt;br /&gt;
        HD44780_WriteData(line1[i],0);&lt;br /&gt;
    }&lt;br /&gt;
    HD44780_EmptyLine1(line1,nbcols);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
HD44780_EraseLine  :&lt;br /&gt;
&lt;br /&gt;
Permet d'effacer une ligne. Pour ce faire on se place au début de la ligne voulue, et on écrit une suite de caractère vide.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:50%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; |Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
void HD44780_EraseLine(int nbrows, int nbcols, int line) {&lt;br /&gt;
    int address_line1;&lt;br /&gt;
    char espace = ' ';&lt;br /&gt;
    for (int i = 0; i &amp;lt; nbcols; i++) {&lt;br /&gt;
    	address_line1 = HD44780_XY2Adrr(nbrows, nbcols, line, i);&lt;br /&gt;
    	HD44780_WriteCommand(LCD_ADDRSET | address_line1);&lt;br /&gt;
	    HD44780_WriteData(espace,0);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
HD44780_WriteChar  :&lt;br /&gt;
&lt;br /&gt;
Permet d'écrire un caractère sur l'écran. Chaque caractère écrit sur la seconde ligne est placé dans un tableau de caractère. &lt;br /&gt;
&lt;br /&gt;
Lorsqu'on arrive au bout d'une ligne : Si nous sommes à la première ligne (Ligne 0), on passe à la seconde (Ligne 1) et on se replace au début des colonnes. Si nous sommes à la seconde ligne, on efface les deux lignes et on copie la seconde ligne sur la première ligne de l'écran, et on se replace au début de la seconde.  &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:50%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; |Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
void HD44780_WriteChar(char car, char line1[], int* ind_line1, int nbrows, int nbcols, int* row, int* col) {&lt;br /&gt;
    if ((*col) == nbcols) {&lt;br /&gt;
        (*col) = 0;&lt;br /&gt;
        if ((*row) &amp;lt;= 1) (*row)++;&lt;br /&gt;
        if ((*row) &amp;gt; 1) {&lt;br /&gt;
            (*row) = 1;&lt;br /&gt;
            HD44780_EraseLine(nbrows, nbcols,0);&lt;br /&gt;
            HD44780_EraseLine(nbrows, nbcols,1);&lt;br /&gt;
            HD44780_CopyLine1in0(line1, nbrows, nbcols,*ind_line1);&lt;br /&gt;
        }&lt;br /&gt;
        (*ind_line1) = 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    int address = HD44780_XY2Adrr(nbrows, nbcols, *row, *col);&lt;br /&gt;
    HD44780_WriteCommand(LCD_ADDRSET | address);&lt;br /&gt;
    HD44780_WriteData(car,1);&lt;br /&gt;
    (*col)++;&lt;br /&gt;
    if ((*row) == 1) &lt;br /&gt;
    {&lt;br /&gt;
        line1[*ind_line1] = car;&lt;br /&gt;
        (*ind_line1)++;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:50%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; |Video Test&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |[[Fichier:Video test de la librairie.mp4|centré|vignette|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Video test de la librairie&amp;lt;/div&amp;gt;]]&lt;br /&gt;
|}Super, ca fonctionne !   &lt;br /&gt;
&lt;br /&gt;
Désormais, nous voulons que notre écran affiche ce qu'il recoit via le bus SPI.   &lt;br /&gt;
&lt;br /&gt;
=== Communication SPI ===&lt;br /&gt;
Pour cela il nous faut initialiser le maitre (un arduino UNO) et l'esclave (notre carte LCD).   &lt;br /&gt;
&lt;br /&gt;
Puis que le maitre transmette des données et que l'esclave les recoivent.   &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code Maitre&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code Esclave&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
void SPI_init()&lt;br /&gt;
{&lt;br /&gt;
    DDRB |= (1 &amp;lt;&amp;lt; SPI_MOSI) | (1 &amp;lt;&amp;lt; SPI_SCK) | (1 &amp;lt;&amp;lt; SPI_SS);&lt;br /&gt;
    DDRB &amp;amp;= ~(1 &amp;lt;&amp;lt; SPI_MISO);&lt;br /&gt;
    SPCR |= (1 &amp;lt;&amp;lt; MSTR);&lt;br /&gt;
    SPCR |= (1 &amp;lt;&amp;lt; SPE) | (1&amp;lt;&amp;lt;SPR0) | (1&amp;lt;&amp;lt;SPR1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void SPI_MasterTransmit(char cData)&lt;br /&gt;
{&lt;br /&gt;
SPDR = cData;&lt;br /&gt;
while(!(SPSR &amp;amp; (1&amp;lt;&amp;lt;SPIF)));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
void SPI_init()&lt;br /&gt;
{&lt;br /&gt;
    DDRB |= (1 &amp;lt;&amp;lt; SPI_MISO);&lt;br /&gt;
    DDRB &amp;amp;= ~((1 &amp;lt;&amp;lt; SPI_MOSI) | (1 &amp;lt;&amp;lt; SPI_SCK) | (1 &amp;lt;&amp;lt; SPI_SS));&lt;br /&gt;
    SPCR |= (1 &amp;lt;&amp;lt; SPE); &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
char SPI_SlaveReceive(void)&lt;br /&gt;
{&lt;br /&gt;
    /* Attendre la fin de la réception */&lt;br /&gt;
    while (!(SPSR &amp;amp; (1 &amp;lt;&amp;lt; SPIF)));&lt;br /&gt;
    char receivedData = SPDR;&lt;br /&gt;
    return receivedData;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
Faisons un petit test en envoyant des 'A' suivis de 'B' et enfin un 'X' pour terminer.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code Test du Maitre&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Video Test&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    while (x&amp;lt;17)&lt;br /&gt;
    {&lt;br /&gt;
      SPI_MasterTransmit('A');&lt;br /&gt;
      _delay_ms(100);&lt;br /&gt;
      SPI_MasterTransmit('B');&lt;br /&gt;
      x++;&lt;br /&gt;
      PORTD ^= (1&amp;lt;&amp;lt;7);&lt;br /&gt;
      _delay_ms(100);&lt;br /&gt;
    }&lt;br /&gt;
    SPI_MasterTransmit('X');&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;  &lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |[[Fichier:Video test SPI.mp4|centré|vignette|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Video test de transmission par SPI&amp;lt;/div&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
|}Notre test fonctionne mais cela n'a pas été sans peine. Nous avons rencontré énormément de problème sur la communication SPI. La communication était clairement douteuse et aléatoire.   &lt;br /&gt;
&lt;br /&gt;
==== Problèmes rencontrés ====&lt;br /&gt;
Plusieurs pistes ont été considérées pour comprendre le problème qu'on avait avec le SPI, était-ce l'arduino UNO? Notre connecteur? Le shield? Notre carte?&lt;br /&gt;
Au départ, par soucis de praticité, nous voulions utiliser l'arduino UNO qui disposait de fonctionnalités de test simple avant de passer au shield, mais à chaque essai, le SPI ne fonctionait pas correctement bien qu'on pouvait observer à l'oscilloscope que le message était bien envoyé à notre carte.&lt;br /&gt;
&lt;br /&gt;
Finalement, nous sommes directement passé à la communication SPI avec notre shield, qui cette fois-ci, permettait d'avoir un résultat satisfaisant. Le résultat n'était pas parfait car on remarquait que la position des fils déterminait si la communication allait fonctionner, il fallait donc trouver la position qui permettait cette communication.&lt;br /&gt;
Pour régler ce problème, nous avons déterminé la fréquence de travail du SPI utilisé par le shield et notre carte, pour vérifier qu'il n'y ait pas de problèmes de synchronisation ou que la fréquence utilisée soit bien adaptée. Pour ce faire nous avons observé à l'oscilloscope les différentes divisions de fréquences possibles en vérifiant en même temps que la communication SPI fonctionne bien. Les résultats sont surprenant, car peu importe la fréquence de travail, aucun problème n'a été détécté.&lt;br /&gt;
&lt;br /&gt;
=== Communication SPI par interruption ===&lt;br /&gt;
Il nous faut maitenant communiquer par SPI par interruption car cela offre certains avantages par rapport à la communication SPI standard sans interruption, en particulier en termes d'efficacité et de gestion du temps. En effet, l'utilisation d'interruptions permet au microcontrôleur de gérer d'autres tâches pendant les transferts SPI. Plutôt que d'attendre de manière synchrone la fin d'une transaction SPI, le microcontrôleur peut être informé via une interruption lorsque les données sont prêtes à être lues ou écrites. Cela permet un multitâche plus efficace. Ce qui va nous être trés pratique sachant que le projet comporte plusieurs cartes filles.&lt;br /&gt;
&lt;br /&gt;
Pour cela il nous faut coté maitre et esclave activé le mode SPI Interrupt lors de l'initialisation du SPI, on rajoute donc &amp;lt;code&amp;gt;SPCR |= (1&amp;lt;&amp;lt;SPIE);&amp;lt;/code&amp;gt; lors à l'initialisation.&lt;br /&gt;
&lt;br /&gt;
Ensuite on génère l'interruption coté esclave à la fin de l'initalisation et on configure notre ISR.&lt;br /&gt;
&lt;br /&gt;
Le maitre à plusieurs type d'envoie possible :&lt;br /&gt;
&lt;br /&gt;
0x00 : Demande le type de la carte.&lt;br /&gt;
&lt;br /&gt;
0x01 : Active la communication avec la carte LCD.&lt;br /&gt;
&lt;br /&gt;
0xff   : Met fin à la communication.&lt;br /&gt;
&lt;br /&gt;
Voici comment l'ISR lui fonctionne, si je recois 0x00 je renvoie on type, 0x01 je passe en mode EnReception. &lt;br /&gt;
&lt;br /&gt;
En mode EnReception : lorsque je recois un octet je l'ajoute à un buffer, lorsque je recois 0xff je désactive le mode en Reception.&lt;br /&gt;
&lt;br /&gt;
Dans mon main, une fois que mon mode EnRecption est désactivé mais que mon indice du buffer et supérieur à 0 alors je peux traiter mes octets.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code ISR&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code Main&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
ISR(SPI_STC_vect) {&lt;br /&gt;
    uint8_t  data = SPDR;&lt;br /&gt;
    if(EnReception == 1)&lt;br /&gt;
        switch (data){&lt;br /&gt;
	   case 0xff:&lt;br /&gt;
		EnReception=0;&lt;br /&gt;
		break;&lt;br /&gt;
	   default :&lt;br /&gt;
		buffer[IndBuffer++]=data;&lt;br /&gt;
	}&lt;br /&gt;
    else&lt;br /&gt;
        switch (data){&lt;br /&gt;
            case 0x00: &lt;br /&gt;
		sendType();&lt;br /&gt;
		break;&lt;br /&gt;
           case 0x01:&lt;br /&gt;
		EnReception=1;&lt;br /&gt;
		break;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
while (1) {&lt;br /&gt;
	if (EnReception == 0 &amp;amp;&amp;amp; IndBuffer&amp;gt;0)&lt;br /&gt;
	{&lt;br /&gt;
		for(int i=0; i &amp;lt; IndBuffer; i++)&lt;br /&gt;
		{&lt;br /&gt;
			&amp;quot;Fonction de traitement&amp;quot;&lt;br /&gt;
		}&lt;br /&gt;
		IndBuffer=0;&lt;br /&gt;
	}&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Gestion des caractères spéciaux ===&lt;br /&gt;
Nous avons décider de gérer 4 caractères spéciaux différents : \n , \t, \b, \r&lt;br /&gt;
&lt;br /&gt;
Pour cela on créé la fonction &amp;lt;code&amp;gt;HD44780_Traitement&amp;lt;/code&amp;gt; qui sera notre fonction principale.&lt;br /&gt;
&lt;br /&gt;
Si on recoit un caractère classique alors on l'affiche grâce à &amp;lt;code&amp;gt;HD44780_WriteChar&amp;lt;/code&amp;gt; précédemment crée.&lt;br /&gt;
&lt;br /&gt;
Sinon il sagit d'un caractère spécial et alors on le traite dans un switch case :&lt;br /&gt;
&lt;br /&gt;
==== \n ====&lt;br /&gt;
Si on est sur la première ligne, on se place au début de la seconde.&lt;br /&gt;
&lt;br /&gt;
Si on est sur la seconde ligne, on efface les deux lignes et on copie la seconde ligne sur la première ligne de l'écran, et on se replace au début de la seconde.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code \n&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Video Test&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
        case '\n': //Retour à la ligne&lt;br /&gt;
            switch (*row)&lt;br /&gt;
            {&lt;br /&gt;
                case 0:&lt;br /&gt;
                    (*col) = 0;&lt;br /&gt;
                    (*row) = 1;&lt;br /&gt;
                    break;&lt;br /&gt;
                case 1:&lt;br /&gt;
                    *col = 0;&lt;br /&gt;
                    HD44780_EraseLine(nbrows, nbcols,0);&lt;br /&gt;
                    HD44780_EraseLine(nbrows, nbcols,1);&lt;br /&gt;
                    HD44780_CopyLine1in0(line1, nbrows, nbcols,*ind_line1); &lt;br /&gt;
                    *ind_line1 = 0;&lt;br /&gt;
                    break;    &lt;br /&gt;
            }&lt;br /&gt;
            break;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |[[Fichier:Video retour a la ligne.mp4|centré|vignette|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Video test du retour à la ligne &amp;lt;/div&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== \r ====&lt;br /&gt;
On se replace au début de la ligne sur laquelle on est actuellement en train d'écrire.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code \r&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Video Test&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
case '\r': // Retour chariot&lt;br /&gt;
            *col = 0;&lt;br /&gt;
            (*ind_line1) = 0;&lt;br /&gt;
            HD44780_EmptyLine1(line1,nbcols);&lt;br /&gt;
            break;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |[[Fichier:Video retour charriot.mp4|centré|vignette|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Video test du retour chariot &amp;lt;/div&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== \r ====&lt;br /&gt;
On efface le caractère précédent, ajuste la position du curseur, et passe à la ligne supérieure si nécessaire.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code \b&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Video Test&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
case '\b': // Retour arrière&lt;br /&gt;
            switch (*row)&lt;br /&gt;
            {&lt;br /&gt;
                case 0:&lt;br /&gt;
                    if (*col &amp;gt; 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        (*col)--;//Retourne sur le caractère précédent&lt;br /&gt;
                        char espace = ' ';&lt;br /&gt;
                        int address = HD44780_XY2Adrr(nbrows, nbcols, *row, *col);&lt;br /&gt;
                        HD44780_WriteCommand(LCD_ADDRSET | address);&lt;br /&gt;
                        HD44780_WriteData(espace, 1);//&amp;quot;L'efface&amp;quot;&lt;br /&gt;
                        _delay_ms(500);&lt;br /&gt;
&lt;br /&gt;
                    }&lt;br /&gt;
                    break;&lt;br /&gt;
                case 1:&lt;br /&gt;
                    if (*col &amp;gt; 0)&lt;br /&gt;
                    {&lt;br /&gt;
                      (*col)--;&lt;br /&gt;
                      (*ind_line1) --;&lt;br /&gt;
                    }&lt;br /&gt;
                    else &lt;br /&gt;
                    {&lt;br /&gt;
                      (*row) = 0;&lt;br /&gt;
                      (*col) = 15;&lt;br /&gt;
                    }&lt;br /&gt;
                    char espace = ' ';&lt;br /&gt;
                    int address = HD44780_XY2Adrr(nbrows, nbcols, *row, *col);&lt;br /&gt;
                    HD44780_WriteCommand(LCD_ADDRSET | address);&lt;br /&gt;
                    HD44780_WriteData(espace, 1);&lt;br /&gt;
                    break;&lt;br /&gt;
            }&lt;br /&gt;
            break;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |[[Fichier:Video Supprésion.mp4|centré|vignette|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Video test du retour arrière &amp;lt;/div&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== \t ====&lt;br /&gt;
On écrit 4 espaces, à la suite de notre position actuelle.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code \t&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Video Test&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
case '\t': // Tabulation de 4 caractères&lt;br /&gt;
            for (int i=0; i &amp;lt; 4; i++)&lt;br /&gt;
            {   &lt;br /&gt;
                char espace = ' ';&lt;br /&gt;
                HD44780_WriteChar(espace,line1,ind_line1,nbrows,nbcols,row,col);&lt;br /&gt;
            }&lt;br /&gt;
            break;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |[[Fichier:Video Tabulation.mp4|centré|vignette|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Video test de la Tabulation &amp;lt;/div&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Gestion des codes VT100 ===&lt;br /&gt;
Pour finir, nous allons gérer quelques codes VT100, les déplacements de curseurs.&lt;br /&gt;
&lt;br /&gt;
Pour envoyer un code VT100 pour déplacer le curseur le maitre doit nous envoyer:&lt;br /&gt;
&lt;br /&gt;
# Le code ESCAPE (0x1b)&lt;br /&gt;
# Le CURSOR_MODE (0x1c)&lt;br /&gt;
# Et enfin le mouvement du curseur souhaité CURSOR_UP (0x41),  CURSOR_DOWN (0x42), CURSOR_RIGHT (0x43), CURSOR_LEFT (0x44).&lt;br /&gt;
&lt;br /&gt;
On gère cela dans la fonction VT100_Traitement.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:50%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; |Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
void VT100_Traitement(char car, int nbrows, int nbcols, int* row, int* col, int* vt100_mode)&lt;br /&gt;
{&lt;br /&gt;
    if (*vt100_mode == 1) // CURSOR_MODE&lt;br /&gt;
    {&lt;br /&gt;
        int address;&lt;br /&gt;
&lt;br /&gt;
        switch (car)&lt;br /&gt;
        {&lt;br /&gt;
            case CURSOR_UP:&lt;br /&gt;
                *row = (*row == 1) ? 0 : *row;&lt;br /&gt;
                break;&lt;br /&gt;
&lt;br /&gt;
            case CURSOR_DOWN:&lt;br /&gt;
                *row = (*row == 0) ? 1 : *row;&lt;br /&gt;
                break;&lt;br /&gt;
&lt;br /&gt;
            case CURSOR_RIGHT:&lt;br /&gt;
                *col = (*col &amp;lt; nbcols - 1) ? (*col + 1) : *col;&lt;br /&gt;
                break;&lt;br /&gt;
&lt;br /&gt;
            case CURSOR_LEFT:&lt;br /&gt;
                *col = (*col &amp;gt; 0) ? (*col - 1) : *col;&lt;br /&gt;
                break;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        address = HD44780_XY2Adrr(nbrows, nbcols, *row, *col);&lt;br /&gt;
        HD44780_WriteCommand(LCD_ADDRSET | address);&lt;br /&gt;
        HD44780_WriteCommand(LCD_ON | CURSOR_BLINK);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:50%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; |Video Test&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |[[Fichier:Video VT100.mp4|centré|vignette|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Video test des codes VT100&amp;lt;/div&amp;gt;]]&lt;br /&gt;
|}&lt;br /&gt;
=== Gestion des primitives systèmes ===&lt;br /&gt;
Voici les primitives systèmes pour la carte mère, elle permettent de communiquer les chaînes de caractères à envoyer en préparant une transmission SPI constituée de l'octet de commande 0x01 et des données correspondants aux caractères.&lt;br /&gt;
&lt;br /&gt;
La fonction Reset_Display permet de reset l'affichage de l'écran et permet aussi à la carte mère de le remarquer en lui attribuant un numéro de port.&lt;br /&gt;
&lt;br /&gt;
La fonction Transmit_to_display est la fonction de transmission de données par SPI. Elle utilise les fonctions SPI créées précédemment pour envoyer les données à afficher.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:50%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; |Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
void Reset_display(volatile uint8_t *resPort, volatile uint8_t resSel) //Utile pour reset l'ecran&lt;br /&gt;
{&lt;br /&gt;
    *resPort &amp;amp;= ~(1&amp;lt;&amp;lt;resSel);&lt;br /&gt;
    _delay_ms(1);&lt;br /&gt;
    *resPort |= (1&amp;lt;&amp;lt;resSel);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void Transmit_To_display(uint8_t data, volatile uint8_t *ssPort, volatile uint8_t ss)&lt;br /&gt;
{&lt;br /&gt;
	selectSlaveSPI(ssPort,ss);&lt;br /&gt;
	_delay_ms(1);&lt;br /&gt;
	transferSPI(data);&lt;br /&gt;
	_delay_ms(1);&lt;br /&gt;
	unselectSlaveSPI(ssPort,ss);&lt;br /&gt;
	_delay_ms(1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Conclusion =&lt;br /&gt;
Pour conclure, faisons un bilan de ce qui a été produit:&lt;br /&gt;
&lt;br /&gt;
-Une carte fille fonctionnelle qui gère l'affichage d'un écran LCD&lt;br /&gt;
&lt;br /&gt;
-Communication SPI par interruption&lt;br /&gt;
&lt;br /&gt;
-Ordonnanceur avec un système de priorité (sémaphore)&lt;br /&gt;
&lt;br /&gt;
-Défilement de automatique de l'écran&lt;br /&gt;
&lt;br /&gt;
-Gestion des caractères spéciaux&lt;br /&gt;
&lt;br /&gt;
-Primitives systèmes pour la carte mère&lt;br /&gt;
&lt;br /&gt;
Malheureusement, par manque de temps, nous n'avons pas pu faire communiquer les cartes filles ensemble en les connectant à la carte mère. Nous restons cependant très satisfait du résultat et des fonctionnalités de notre carte!&lt;br /&gt;
&lt;br /&gt;
= Références utiles =&lt;br /&gt;
Lien du git :&lt;br /&gt;
&lt;br /&gt;
https://archives.plil.fr/mchauvel/PICO_Taha_NEHARI_Martin_CHAUVELIERE.git&lt;/div&gt;</summary>
		<author><name>Tnehari</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2023-1&amp;diff=2835</id>
		<title>SE4Binome2023-1</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2023-1&amp;diff=2835"/>
		<updated>2024-01-16T16:54:22Z</updated>

		<summary type="html">&lt;p&gt;Tnehari : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Ordonnanceur =&lt;br /&gt;
&lt;br /&gt;
== Soudure et Test du SHIELD ==&lt;br /&gt;
Au cours des 2 premières séances nous avons soudé et testé notre Shield&lt;br /&gt;
[[Fichier:ShieldSoudé.jpg|thumb|center|300x300px|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Shield soudé et monté sur Arduino&amp;lt;/div&amp;gt;]]&lt;br /&gt;
 &lt;br /&gt;
Sur l'un des connecteurs, la led est abîmée dû à une soudure excessive. Sachant que les leds sont uniquement utilisées en tant qu'indicateurs pour savoir quelle carte fille à le contrôle et que nous n'en utiliserons pas plus de 3 pour tester nos programmes, cela ne vas pas avoir d'influence négative.&lt;br /&gt;
Le potentiomètre permet de régler le niveau de luminosité de l'écran et le connecteur HE10 permettra de comuniquer avec l'écran.&lt;br /&gt;
Les problèmes rencontrés sont les suivants : Au départ, la carte ne fonctionnait pas, le soucis étant le quartz mal soudé, c'est à l'aide d'un pistolet à air chaud que celui-ci à été ressoudé. Un autre problème était le reset de la carte fille qui ne fonctionnait pas non plus, une ressoudure classique a permis de le faire fonctionner.&lt;br /&gt;
&lt;br /&gt;
{| class=wikitable style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Code&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Image&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void init_led(){&lt;br /&gt;
  DDRD=0x92;&lt;br /&gt;
  DDRC=0x09;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
  init_led();&lt;br /&gt;
  while(1)&lt;br /&gt;
    {&lt;br /&gt;
	PORTD=0x92;&lt;br /&gt;
	PORTC=0x09;&lt;br /&gt;
    }&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;  &lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
[[Fichier:ShieldLed.jpg|thumb|center|300x300px|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Test des Leds du Shield&amp;lt;/div&amp;gt;]]&lt;br /&gt;
|}&lt;br /&gt;
Puis nous avons aussi soudé l'adaptateur HE10 pour l'utilisation de la matrice de leds[[Fichier:Adaptateur HE10.jpg|thumb|center|300x300px|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Adaptateur HE10 pour Matrice de leds&amp;lt;/div&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
== Programmation de l'Ordonnanceur ==&lt;br /&gt;
Nous commençons maintenant l'ordonnanceur, tout d'abord nous créeons la structure de nos Taches.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct TacheInfo{&lt;br /&gt;
	void (*depart)(void);&lt;br /&gt;
	uint16_t SPointeur;&lt;br /&gt;
	int etat;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;  &lt;br /&gt;
|}&lt;br /&gt;
Puis nous ajoutons les 2 premières taches demandées qui sont de faire clignoter 2 leds différentes à des timing différents.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void TacheA(){&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
        PORTC ^= 0x08;&lt;br /&gt;
	_delay_ms(300);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void TacheB(){&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
        PORTD ^= 0x80;&lt;br /&gt;
	_delay_ms(500);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
struct TacheInfo Taches[2]={&lt;br /&gt;
  {TacheA,0x0600,0},&lt;br /&gt;
  {TacheB,0x0700,0}&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;  &lt;br /&gt;
|}&lt;br /&gt;
On s'occupe maintenant de l'ordonnanceur, ainsi que de l'ISR.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void ordonnanceur ()&lt;br /&gt;
{	&lt;br /&gt;
	PORTD ^= 0x02;&lt;br /&gt;
	courant++;&lt;br /&gt;
	if (courant == NBR_TACHE) courant = 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect,ISR_NAKED)&lt;br /&gt;
{&lt;br /&gt;
	/* Sauvegarde du contexte de la tâche interrompue */&lt;br /&gt;
	SAVE_REGISTER();&lt;br /&gt;
	Taches[courant].SPointeur = SP;&lt;br /&gt;
&lt;br /&gt;
	/* Appel à l'ordonnanceur */&lt;br /&gt;
	ordonnanceur();&lt;br /&gt;
&lt;br /&gt;
	/* Récupération du contexte de la tâche ré-activée */&lt;br /&gt;
	SP = Taches[courant].SPointeur;&lt;br /&gt;
	RESTORE_REGISTER();&lt;br /&gt;
	asm volatile ( &amp;quot;reti&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Nous avons décider de faire clignoter une LED (PORTD ^= 0x02) à chaques utilisations de la fonction ordonnanceur() dans l'ISR.&lt;br /&gt;
&lt;br /&gt;
La variable courant indique la Tache qui est actuellement en cours.&lt;br /&gt;
&lt;br /&gt;
A chaque chaques changements de tache, l'ISR se déclenche enregistre la tache en cours (les registres ainsi que le Stack Pointer), appel l'ordonnanceur, puis change &amp;quot;charge&amp;quot; la tache suivante.&lt;br /&gt;
&lt;br /&gt;
On oublie pas maintenant de générer l'interruption toute les 20ms, pour cela on choisit un prescaler de 1024 et un nombre de ticks de 312.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define PRESCALER 1024&lt;br /&gt;
#define NB_TICK  312&lt;br /&gt;
#define CTC1  WGM12&lt;br /&gt;
&lt;br /&gt;
void init_timer(){&lt;br /&gt;
TCCR1A = 0;  // No output pin connected, no PWM mode enabled&lt;br /&gt;
TCCR1B = 1&amp;lt;&amp;lt;CTC1; // No input pin used, clear timer counter on compare match&lt;br /&gt;
#if (PRESCALER==1024)&lt;br /&gt;
 TCCR1B |= (1&amp;lt;&amp;lt;CS12 | 1&amp;lt;&amp;lt;CS10);&lt;br /&gt;
#endif&lt;br /&gt;
OCR1A = NB_TICK;&lt;br /&gt;
TCNT1 = 0;&lt;br /&gt;
TIMSK1 = (1&amp;lt;&amp;lt;OCIE1A); // No overflow mode enabled, no input interrupt, output compare interrupt&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Ainsi que d'initialiser les Taches pour assurer le bon fonctionnement de notre ordonnanceur.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void init_taches(int pid)&lt;br /&gt;
{&lt;br /&gt;
	int save=SP;&lt;br /&gt;
	SP=Taches[pid].SPointeur;&lt;br /&gt;
	uint16_t adresse=(uint16_t)Taches[pid].depart;&lt;br /&gt;
	asm volatile (&amp;quot;push %0 \n\t&amp;quot; : : &amp;quot;r&amp;quot; (adresse &amp;amp; 0x00ff));&lt;br /&gt;
	asm volatile (&amp;quot;push %0 \n\t&amp;quot; : : &amp;quot;r&amp;quot; ((adresse &amp;amp; 0xff00) &amp;gt;&amp;gt; 8));&lt;br /&gt;
	SAVE_REGISTER();&lt;br /&gt;
	Taches[pid].SPointeur=SP;&lt;br /&gt;
	SP=save;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
On peut maintenant tester notre ordonnanceur.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Vidéo&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define NBR_TACHE 2&lt;br /&gt;
int main(void){&lt;br /&gt;
	init_ports();&lt;br /&gt;
	init_timer();&lt;br /&gt;
	init_taches(1);&lt;br /&gt;
	sei();&lt;br /&gt;
	SP = Taches[courant].SPointeur;&lt;br /&gt;
	Taches[courant].depart();&lt;br /&gt;
	return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;  &lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
Les 2 leds clignotent bien avec le bon timing, et la led témoin de l'ordonnanceur clignotent aussi, ce qui indique que l'ISR est bien actif.&lt;br /&gt;
&lt;br /&gt;
Nous pouvons donc maitenant passer à la gestion des &amp;quot;sleeps&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
En effet, l'utilisation de _delay_ms dans chaque tache n'est pas la manière la plus optimale de procéder. Et meme cela nous bloquera par la suite.&lt;br /&gt;
&lt;br /&gt;
Nous ajoute donc à la structure de nos Taches, une structure InfoEndormi, qui, comme son nom l'indique nous donne des informations si la tache est endormie. A savoir la raison mais aussi des donnees comme par exemple le temps que cette tache doit passer endormie.&lt;br /&gt;
&lt;br /&gt;
Puis afin de remplacer _delay_ms, nous créeons une fonction Attente qui endors une tache pour un temps donné.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define REVEILLE 0&lt;br /&gt;
#define ENDORMI 1&lt;br /&gt;
#define RAISON_DELAY 0&lt;br /&gt;
&lt;br /&gt;
struct InfoEndormi{&lt;br /&gt;
    int raison;&lt;br /&gt;
    uint16_t donnee;&lt;br /&gt;
}sleep_t;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
struct TacheInfo{&lt;br /&gt;
    void (*depart)(void); &lt;br /&gt;
    uint16_t SPointeur;&lt;br /&gt;
    int etat;&lt;br /&gt;
    struct InfoEndormi endormi;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;  &lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&amp;lt;pre&amp;gt;&lt;br /&gt;
void Attente(uint16_t temps_ms){&lt;br /&gt;
    cli();&lt;br /&gt;
    Taches[Tache_courante].etat = ENDORMI;&lt;br /&gt;
    Taches[Tache_courante].endormi.raison = RAISON_DELAY;&lt;br /&gt;
    Taches[Tache_courante].endormi.donnee = temps_ms;&lt;br /&gt;
    TCNT1 = 0;&lt;br /&gt;
    sei();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
Voila maitenant nos taches, il est important de créer une TacheZombie qui comme son nom l'indique est toujours révéillée.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void TacheZombie() //Tache toujours réveillé&lt;br /&gt;
{&lt;br /&gt;
	while(1)&lt;br /&gt;
	{&lt;br /&gt;
		_delay_ms(1.5*PERIODE_INTERUPTION); //Delay légèrement supèrieur à la periode pour éviter tout soucis&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void TacheA()&lt;br /&gt;
{&lt;br /&gt;
	while(1)&lt;br /&gt;
	{&lt;br /&gt;
		PORTC ^= 0x08;&lt;br /&gt;
		Attente(300);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void TacheB()&lt;br /&gt;
{&lt;br /&gt;
	while(1)&lt;br /&gt;
	{&lt;br /&gt;
		PORTD ^= 0x80;&lt;br /&gt;
		Attente(500);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Il est important maitenant de modifier notre ordonnanceur afin que celui-ci puisse recalculer le nouveau temps de sleep d'une tache et si ce temps devient inférieur ou ègale à 0 alors l'ordonnacnceur réveille la tache.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void ordonnanceur ()&lt;br /&gt;
{&lt;br /&gt;
	PORTD ^= 0x02;&lt;br /&gt;
	for(int i = 0; i &amp;lt; NBR_TACHE; i++)&lt;br /&gt;
	{&lt;br /&gt;
		if(Taches[i].etat == ENDORMI &amp;amp;&amp;amp; Taches[Tache_courante].endormi.raison == RAISON_DELAY)&lt;br /&gt;
		{&lt;br /&gt;
			uint16_t diff_temps = PERIODE_INTERUPTION;&lt;br /&gt;
			if(TCNT1 != 0)&lt;br /&gt;
			{&lt;br /&gt;
				//Calcul précis de la différence de temps (pas obligatoirement 20 ms)&lt;br /&gt;
				diff_temps = ((TCNT1*PERIODE_INTERUPTION*10)/OCR1A)/10;&lt;br /&gt;
				TCNT1 = 0;&lt;br /&gt;
			}&lt;br /&gt;
			Taches[i].endormi.donnee  -= diff_temps;&lt;br /&gt;
            &lt;br /&gt;
			if(Taches[i].endormi.donnee &amp;lt;= 0)&lt;br /&gt;
			{&lt;br /&gt;
				Taches[i].etat = REVEILLE;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
    &lt;br /&gt;
	do&lt;br /&gt;
	{&lt;br /&gt;
		Tache_courante++;&lt;br /&gt;
		if (Tache_courante == NBR_TACHE) Tache_courante = 0;&lt;br /&gt;
    }&lt;br /&gt;
	while(Taches[Tache_courante].etat == ENDORMI);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Maintenant que cela est fait, nous pouvons ajouter 2 nouvelles taches qui sont la lecture et l'ecriture sur le port série.&lt;br /&gt;
&lt;br /&gt;
Pour cela, nous allons procéder avec des sémaphores. En effet, il ne peut y avoir que 1 seule tache en écriture ou en lecture, il faut donc que si plusieurs taches essaient de prendre la ressource, cette ressource soit donner à la première arrivé et que les autres taches en attendant patientent.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void semaphore_e(int ACTION){&lt;br /&gt;
	if (ACTION == PRENDRE)&lt;br /&gt;
	{&lt;br /&gt;
		while(1)&lt;br /&gt;
		{&lt;br /&gt;
			cli();&lt;br /&gt;
			if (semaphore_ecriture &amp;gt; 0) //Si ressource dispo &lt;br /&gt;
			{&lt;br /&gt;
				semaphore_ecriture = 0;&lt;br /&gt;
				sei();&lt;br /&gt;
				break;&lt;br /&gt;
        		} else&lt;br /&gt;
			{&lt;br /&gt;
				// La ressource est occupée, on endort la tache&lt;br /&gt;
				Taches[Tache_courante].etat = ENDORMI;&lt;br /&gt;
				Taches[Tache_courante].endormi.raison = RAISON_ECRITURE;&lt;br /&gt;
				TCNT1=0;&lt;br /&gt;
				TIMER1_COMPA_vect();&lt;br /&gt;
			}&lt;br /&gt;
			sei();&lt;br /&gt;
			while(semaphore_ecriture==0);&lt;br /&gt;
		}&lt;br /&gt;
			&lt;br /&gt;
	}&lt;br /&gt;
	else if (ACTION == LAISSER)&lt;br /&gt;
	{&lt;br /&gt;
		cli();&lt;br /&gt;
		semaphore_ecriture = 1;&lt;br /&gt;
		sei();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
On fait la meme chose pour la lecture.&lt;br /&gt;
&lt;br /&gt;
On oublie pas d'initialiser le port série avec les bons paramètres, créer les taches, puis on test.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Image&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void init_serie(long int vitesse){&lt;br /&gt;
	UBRR0=FREQ_CPU/(((unsigned long int)vitesse)&amp;lt;&amp;lt;4)-1; &lt;br /&gt;
        // configure la vitesse&lt;br /&gt;
	UCSR0B=(1&amp;lt;&amp;lt;TXEN0 | 1&amp;lt;&amp;lt;RXEN0);   // autorise l'envoi et la réception&lt;br /&gt;
	UCSR0C=(1&amp;lt;&amp;lt;UCSZ01 | 1&amp;lt;&amp;lt;UCSZ00); // 8 bits et 1 bit de stop&lt;br /&gt;
	UCSR0A &amp;amp;= ~(1 &amp;lt;&amp;lt; U2X0);         // double vitesse désactivée&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |[[Fichier:Lecture EcritureSerie.jpg|centré|vignette|356x356px|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Test de la lecture et de l'écriture sur le port série.(On écrie 9 caractères puis le shield nous renvoie les mêmes 9) &amp;lt;/div&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
= Carte FPGA =&lt;br /&gt;
&lt;br /&gt;
= Carte électronique numérique =&lt;br /&gt;
&lt;br /&gt;
== Conception et Création ==&lt;br /&gt;
Nous avons choisi la Carte Fille : Ecran LCD &lt;br /&gt;
&lt;br /&gt;
Pendant la 3ème séance nous avons finis le Schématic de la carte &lt;br /&gt;
[[Fichier:SCH.png|centré|vignette|700x700px|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Schematic de la Carte Fille : Ecran LCD&amp;lt;/div&amp;gt;]]&lt;br /&gt;
Puis nous avons Routé la carte et envoyé à la Fabrication&lt;br /&gt;
[[Fichier:PCB LCD.png|centré|vignette|550x550px|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Routage de la Carte Fille : Ecran LCD&amp;lt;/div&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
{| class=wikitable style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Carte non soudée&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Carte soudé&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Video Test&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |[[Fichier:Carte LCD non soudée.jpg|centré|vignette|300x300px|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Carte non soudée&amp;lt;/div&amp;gt;]]&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |[[Fichier:Carte LCD soudee.jpg|centré|vignette|400x400px|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Carte soudée&amp;lt;/div&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Programmation de la carte LCD ==&lt;br /&gt;
Tout d'abord, nous avons voulu tester le bon fonctionnement de notre carte mais surtout du bon controle de l'ecran HD44780 grâce à l'IDE Arduino.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Image&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
const int rs = 2, en = 18, d4 = 14, d5 = 15, d6 = 16, d7 = 17;&lt;br /&gt;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  // set up the LCD's number of columns and rows:&lt;br /&gt;
  pinMode(9,OUTPUT);&lt;br /&gt;
  digitalWrite(9,LOW);&lt;br /&gt;
  lcd.begin(16, 2);&lt;br /&gt;
  // Print a message to the LCD.&lt;br /&gt;
  lcd.print(&amp;quot;Je compte&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  // set the cursor to column 0, line 1&lt;br /&gt;
  // (note: line 1 is the second row, since counting begins with 0):&lt;br /&gt;
  lcd.setCursor(0, 1);&lt;br /&gt;
  // print the number of seconds since reset:&lt;br /&gt;
  lcd.print(millis() / 1000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |[[Fichier:TestLCDArduino.jpg|centré|vignette|375x375px|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Test LCD via IDE Arduino&amp;lt;/div&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
Maintenant que cela fonctionne, nous pouvons commencer à écrire notre Librairie pour faire fonctionner notre carte.&lt;br /&gt;
&lt;br /&gt;
=== Librairie HD44780 ===&lt;br /&gt;
Nous avons commencer par reprendre la librairie d'ancien élève, merci à eux pour leur travail.&lt;br /&gt;
&lt;br /&gt;
Dans notre cas, pour l'utilisation la plus simple nous avons besoin de plusieurs fonctions. La première écrit un caractère sur l'écran, la deuxième copie une ligne et la dernière efface une ligne.&lt;br /&gt;
&lt;br /&gt;
HD44780_CopyLine1in0 :&lt;br /&gt;
&lt;br /&gt;
Permet de copier la seconde ligne sur la première. Pour ce faire, on se place au début de la première ligne, on écrit le contenu du tableau de caractère, et on le vide ensuite (EmptyLine1).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void HD44780_CopyLine1in0(char line1[], int nbrows, int nbcols, int ind_line1) {&lt;br /&gt;
    for (int i = 0; i &amp;lt; ind_line1; i++) {&lt;br /&gt;
        int address_ligne0 = HD44780_XY2Adrr(nbrows, nbcols, 0, i);&lt;br /&gt;
        HD44780_WriteCommand(LCD_ADDRSET | address_ligne0);&lt;br /&gt;
        HD44780_WriteData(line1[i],0);&lt;br /&gt;
    }&lt;br /&gt;
    HD44780_EmptyLine1(line1,nbcols);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
HD44780_EraseLine  :&lt;br /&gt;
&lt;br /&gt;
Permet d'effacer une ligne. Pour ce faire on se place au début de la ligne voulue, et on écrit une suite de caractère vide.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; |Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void HD44780_EraseLine(int nbrows, int nbcols, int line) {&lt;br /&gt;
    int address_line1;&lt;br /&gt;
    char espace = ' ';&lt;br /&gt;
    for (int i = 0; i &amp;lt; nbcols; i++) {&lt;br /&gt;
    	address_line1 = HD44780_XY2Adrr(nbrows, nbcols, line, i);&lt;br /&gt;
    	HD44780_WriteCommand(LCD_ADDRSET | address_line1);&lt;br /&gt;
	    HD44780_WriteData(espace,0);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
HD44780_WriteChar  :&lt;br /&gt;
&lt;br /&gt;
Permet d'écrire un caractère sur l'écran. Chaque caractère écrit sur la seconde ligne est placé dans un tableau de caractère. &lt;br /&gt;
&lt;br /&gt;
Lorsqu'on arrive au bout d'une ligne : Si nous sommes à la première ligne (Ligne 0), on passe à la seconde (Ligne 1) et on se replace au début des colonnes. Si nous sommes à la seconde ligne, on efface les deux lignes et on copie la seconde ligne sur la première ligne de l'écran, et on se replace au début de la seconde.  &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; |Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void HD44780_WriteChar(char car, char line1[], int* ind_line1, int nbrows, int nbcols, int* row, int* col) {&lt;br /&gt;
    if ((*col) == nbcols) {&lt;br /&gt;
        (*col) = 0;&lt;br /&gt;
        if ((*row) &amp;lt;= 1) (*row)++;&lt;br /&gt;
        if ((*row) &amp;gt; 1) {&lt;br /&gt;
            (*row) = 1;&lt;br /&gt;
            HD44780_EraseLine(nbrows, nbcols,0);&lt;br /&gt;
            HD44780_EraseLine(nbrows, nbcols,1);&lt;br /&gt;
            HD44780_CopyLine1in0(line1, nbrows, nbcols,*ind_line1);&lt;br /&gt;
        }&lt;br /&gt;
        (*ind_line1) = 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    int address = HD44780_XY2Adrr(nbrows, nbcols, *row, *col);&lt;br /&gt;
    HD44780_WriteCommand(LCD_ADDRSET | address);&lt;br /&gt;
    HD44780_WriteData(car,1);&lt;br /&gt;
    (*col)++;&lt;br /&gt;
    if ((*row) == 1) &lt;br /&gt;
    {&lt;br /&gt;
        line1[*ind_line1] = car;&lt;br /&gt;
        (*ind_line1)++;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}VIDEO   &lt;br /&gt;
&lt;br /&gt;
Super, ca fonctionne !   &lt;br /&gt;
&lt;br /&gt;
Désormais, nous voulons que notre écran affiche ce qu'il recoit via le bus SPI.   &lt;br /&gt;
&lt;br /&gt;
=== Communication SPI ===&lt;br /&gt;
Pour cela il nous faut initialiser le maitre (un arduino UNO) et l'esclave (notre carte LCD).   &lt;br /&gt;
&lt;br /&gt;
Puis que le maitre transmette des données et que l'esclave les recoivent.   &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code Maitre&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code Esclave&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void SPI_init()&lt;br /&gt;
{&lt;br /&gt;
    DDRB |= (1 &amp;lt;&amp;lt; SPI_MOSI) | (1 &amp;lt;&amp;lt; SPI_SCK) | (1 &amp;lt;&amp;lt; SPI_SS);&lt;br /&gt;
    DDRB &amp;amp;= ~(1 &amp;lt;&amp;lt; SPI_MISO);&lt;br /&gt;
    SPCR |= (1 &amp;lt;&amp;lt; MSTR);&lt;br /&gt;
    SPCR |= (1 &amp;lt;&amp;lt; SPE) | (1&amp;lt;&amp;lt;SPR0) | (1&amp;lt;&amp;lt;SPR1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void SPI_MasterTransmit(char cData)&lt;br /&gt;
{&lt;br /&gt;
SPDR = cData;&lt;br /&gt;
while(!(SPSR &amp;amp; (1&amp;lt;&amp;lt;SPIF)));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;  &lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&amp;lt;pre&amp;gt;&lt;br /&gt;
void SPI_init()&lt;br /&gt;
{&lt;br /&gt;
    DDRB |= (1 &amp;lt;&amp;lt; SPI_MISO);&lt;br /&gt;
    DDRB &amp;amp;= ~((1 &amp;lt;&amp;lt; SPI_MOSI) | (1 &amp;lt;&amp;lt; SPI_SCK) | (1 &amp;lt;&amp;lt; SPI_SS));&lt;br /&gt;
    SPCR |= (1 &amp;lt;&amp;lt; SPE); &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
char SPI_SlaveReceive(void)&lt;br /&gt;
{&lt;br /&gt;
    /* Attendre la fin de la réception */&lt;br /&gt;
    while (!(SPSR &amp;amp; (1 &amp;lt;&amp;lt; SPIF)));&lt;br /&gt;
    char receivedData = SPDR;&lt;br /&gt;
    return receivedData;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
Faisons un petit test en envoyant des 'A' suivis de 'B' et enfin un 'X' pour terminer.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code Test du Maitre&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Video&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    while (x&amp;lt;17)&lt;br /&gt;
    {&lt;br /&gt;
      SPI_MasterTransmit('A');&lt;br /&gt;
      _delay_ms(100);&lt;br /&gt;
      SPI_MasterTransmit('B');&lt;br /&gt;
      x++;&lt;br /&gt;
      PORTD ^= (1&amp;lt;&amp;lt;7);&lt;br /&gt;
      _delay_ms(100);&lt;br /&gt;
    }&lt;br /&gt;
    SPI_MasterTransmit('X');&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;  &lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
|}Notre test fonctionne mais cela n'a pas été sans peine. Nous avons rencontré énormément de problème sur la communication SPI. La communication était clairement douteuse et aléatoire.   &lt;br /&gt;
&lt;br /&gt;
==== Problèmes rencontrés ====&lt;br /&gt;
Plusieurs pistes ont été considérées pour comprendre le problème qu'on avait avec le SPI, était-ce l'arduino UNO? Notre connecteur? Le shield? Notre carte?&lt;br /&gt;
Au départ, par soucis de praticité, nous voulions utiliser l'arduino UNO qui disposait de fonctionnalités de test simple avant de passer au shield, mais à chaque essai, le SPI ne fonctionait pas correctement bien qu'on pouvait observer à l'oscilloscope que le message était bien envoyé à notre carte.&lt;br /&gt;
&lt;br /&gt;
Finalement, nous sommes directement passé à la communication SPI avec notre shield, qui cette fois-ci, permettait d'avoir un résultat satisfaisant. Le résultat n'était pas parfait car on remarquait que la position des fils déterminait si la communication allait fonctionner, il fallait donc trouver la position qui permettait cette communication.&lt;br /&gt;
Pour régler ce problème, nous avons déterminé la fréquence de travail du SPI utilisé par le shield et notre carte, pour vérifier qu'il n'y ait pas de problèmes de synchronisation ou que la fréquence utilisée soit bien adaptée. Pour ce faire nous avons observé à l'oscilloscope les différentes divisions de fréquences possibles en vérifiant en même temps que la communication SPI fonctionne bien. Les résultats sont surprenant, car peu importe la fréquence de travail, aucun problème n'a été détécté.&lt;br /&gt;
&lt;br /&gt;
=== Communication SPI par interruption ===&lt;br /&gt;
Il nous faut maitenant communiquer par SPI par interruption car cela offre certains avantages par rapport à la communication SPI standard sans interruption, en particulier en termes d'efficacité et de gestion du temps. En effet, l'utilisation d'interruptions permet au microcontrôleur de gérer d'autres tâches pendant les transferts SPI. Plutôt que d'attendre de manière synchrone la fin d'une transaction SPI, le microcontrôleur peut être informé via une interruption lorsque les données sont prêtes à être lues ou écrites. Cela permet un multitâche plus efficace. Ce qui va nous être trés pratique sachant que le projet comporte plusieurs cartes filles.&lt;br /&gt;
&lt;br /&gt;
Pour cela il nous faut coté maitre et esclave activé le mode SPI Interrupt lors de l'initialisation du SPI, on rajoute donc &amp;lt;code&amp;gt;SPCR |= (1&amp;lt;&amp;lt;SPIE);&amp;lt;/code&amp;gt; lors à l'initialisation.&lt;br /&gt;
&lt;br /&gt;
Ensuite on génère l'interruption coté esclave à la fin de l'initalisation et on configure notre ISR.&lt;br /&gt;
&lt;br /&gt;
Le maitre à plusieurs type d'envoie possible :&lt;br /&gt;
&lt;br /&gt;
0x00 : Demande le type de la carte.&lt;br /&gt;
&lt;br /&gt;
0x01 : Active la communication avec la carte LCD.&lt;br /&gt;
&lt;br /&gt;
0xff   : Met fin à la communication.&lt;br /&gt;
&lt;br /&gt;
Voici comment l'ISR lui fonctionne, si je recois 0x00 je renvoie on type, 0x01 je passe en mode EnReception. &lt;br /&gt;
&lt;br /&gt;
En mode EnReception : lorsque je recois un octet je l'ajoute à un buffer, lorsque je recois 0xff je désactive le mode en Reception.&lt;br /&gt;
&lt;br /&gt;
Dans mon main, une fois que mon mode EnRecption est désactivé mais que mon indice du buffer et supérieur à 0 alors je peux traiter mes octets.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code ISR&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code Main&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ISR(SPI_STC_vect) {&lt;br /&gt;
    uint8_t  data = SPDR;&lt;br /&gt;
    if(EnReception == 1)&lt;br /&gt;
        switch (data){&lt;br /&gt;
	   case 0xff:&lt;br /&gt;
		EnReception=0;&lt;br /&gt;
		break;&lt;br /&gt;
	   default :&lt;br /&gt;
		buffer[IndBuffer++]=data;&lt;br /&gt;
	}&lt;br /&gt;
    else&lt;br /&gt;
        switch (data){&lt;br /&gt;
            case 0x00: &lt;br /&gt;
		sendType();&lt;br /&gt;
		break;&lt;br /&gt;
           case 0x01:&lt;br /&gt;
		EnReception=1;&lt;br /&gt;
		break;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;  &lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&amp;lt;pre&amp;gt;&lt;br /&gt;
while (1) {&lt;br /&gt;
	if (EnReception == 0 &amp;amp;&amp;amp; IndBuffer&amp;gt;0)&lt;br /&gt;
	{&lt;br /&gt;
		for(int i=0; i &amp;lt; IndBuffer; i++)&lt;br /&gt;
		{&lt;br /&gt;
			&amp;quot;Fonction de traitement&amp;quot;&lt;br /&gt;
		}&lt;br /&gt;
		IndBuffer=0;&lt;br /&gt;
	}&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Gestion des caractères spéciaux ===&lt;br /&gt;
Nous avons décider de gérer 4 caractères spéciaux différents : \n , \t, \b, \r&lt;br /&gt;
&lt;br /&gt;
Pour cela on créé la fonction &amp;lt;code&amp;gt;HD44780_Traitement&amp;lt;/code&amp;gt; qui sera notre fonction principale.&lt;br /&gt;
&lt;br /&gt;
Si on recoit un caractère classique alors on l'affiche grâce à &amp;lt;code&amp;gt;HD44780_WriteChar&amp;lt;/code&amp;gt; précédemment crée.&lt;br /&gt;
&lt;br /&gt;
Sinon il sagit d'un caractère spécial et alors on le traite dans un switch case :&lt;br /&gt;
&lt;br /&gt;
==== \n ====&lt;br /&gt;
Si on est sur la première ligne, on se place au début de la seconde.&lt;br /&gt;
&lt;br /&gt;
Si on est sur la seconde ligne, on efface les deux lignes et on copie la seconde ligne sur la première ligne de l'écran, et on se replace au début de la seconde.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code \n&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Video&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        case '\n': //Retour à la ligne&lt;br /&gt;
            switch (*row)&lt;br /&gt;
            {&lt;br /&gt;
                case 0:&lt;br /&gt;
                    (*col) = 0;&lt;br /&gt;
                    (*row) = 1;&lt;br /&gt;
                    break;&lt;br /&gt;
                case 1:&lt;br /&gt;
                    *col = 0;&lt;br /&gt;
                    HD44780_EraseLine(nbrows, nbcols,0);&lt;br /&gt;
                    HD44780_EraseLine(nbrows, nbcols,1);&lt;br /&gt;
                    HD44780_CopyLine1in0(line1, nbrows, nbcols,*ind_line1); &lt;br /&gt;
                    *ind_line1 = 0;&lt;br /&gt;
                    break;    &lt;br /&gt;
            }&lt;br /&gt;
            break;&lt;br /&gt;
&amp;lt;/pre&amp;gt;  &lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== \r ====&lt;br /&gt;
On se replace au début de la ligne sur laquelle on est actuellement en train d'écrire.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code \r&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Video&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
case '\r': // Retour chariot&lt;br /&gt;
            *col = 0;&lt;br /&gt;
            (*ind_line1) = 0;&lt;br /&gt;
            HD44780_EmptyLine1(line1,nbcols);&lt;br /&gt;
            break;&lt;br /&gt;
&amp;lt;/pre&amp;gt;  &lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== \r ====&lt;br /&gt;
On efface le caractère précédent, ajuste la position du curseur, et passe à la ligne supérieure si nécessaire.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code \b&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Video&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
case '\b': // Retour arrière&lt;br /&gt;
            switch (*row)&lt;br /&gt;
            {&lt;br /&gt;
                case 0:&lt;br /&gt;
                    if (*col &amp;gt; 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        (*col)--;//Retourne sur le caractère précédent&lt;br /&gt;
                        char espace = ' ';&lt;br /&gt;
                        int address = HD44780_XY2Adrr(nbrows, nbcols, *row, *col);&lt;br /&gt;
                        HD44780_WriteCommand(LCD_ADDRSET | address);&lt;br /&gt;
                        HD44780_WriteData(espace, 1);//&amp;quot;L'efface&amp;quot;&lt;br /&gt;
                        _delay_ms(500);&lt;br /&gt;
&lt;br /&gt;
                    }&lt;br /&gt;
                    break;&lt;br /&gt;
                case 1:&lt;br /&gt;
                    if (*col &amp;gt; 0)&lt;br /&gt;
                    {&lt;br /&gt;
                      (*col)--;&lt;br /&gt;
                      (*ind_line1) --;&lt;br /&gt;
                    }&lt;br /&gt;
                    else &lt;br /&gt;
                    {&lt;br /&gt;
                      (*row) = 0;&lt;br /&gt;
                      (*col) = 15;&lt;br /&gt;
                    }&lt;br /&gt;
                    char espace = ' ';&lt;br /&gt;
                    int address = HD44780_XY2Adrr(nbrows, nbcols, *row, *col);&lt;br /&gt;
                    HD44780_WriteCommand(LCD_ADDRSET | address);&lt;br /&gt;
                    HD44780_WriteData(espace, 1);&lt;br /&gt;
                    break;&lt;br /&gt;
            }&lt;br /&gt;
            break;&lt;br /&gt;
&amp;lt;/pre&amp;gt;  &lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== \t ====&lt;br /&gt;
On écrit 4 espaces, à la suite de notre position actuelle.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code \t&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Video&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
case '\t': // Tabulation de 4 caractères&lt;br /&gt;
            for (int i=0; i &amp;lt; 4; i++)&lt;br /&gt;
            {   &lt;br /&gt;
                char espace = ' ';&lt;br /&gt;
                HD44780_WriteChar(espace,line1,ind_line1,nbrows,nbcols,row,col);&lt;br /&gt;
            }&lt;br /&gt;
            break;&lt;br /&gt;
&amp;lt;/pre&amp;gt;  &lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Gestion des codes VT100 ===&lt;br /&gt;
Pour finir, nous allons gérer quelques codes VT100, les déplacements de curseurs.&lt;br /&gt;
&lt;br /&gt;
Pour envoyer un code VT100 pour déplacer le curseur le maitre doit nous envoyer:&lt;br /&gt;
&lt;br /&gt;
# Le code ESCAPE (0x1b)&lt;br /&gt;
# Le CURSOR_MODE (0x1c)&lt;br /&gt;
# Et enfin le mouvement du curseur souhaité CURSOR_UP (0x41),  CURSOR_DOWN (0x42), CURSOR_RIGHT (0x43), CURSOR_LEFT (0x44).&lt;br /&gt;
&lt;br /&gt;
On gère cela dans la fonction VT100_Traitement.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; |Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void VT100_Traitement(char car, int nbrows, int nbcols, int* row, int* col, int* vt100_mode)&lt;br /&gt;
{&lt;br /&gt;
    if (*vt100_mode == 1) // CURSOR_MODE&lt;br /&gt;
    {&lt;br /&gt;
        int address;&lt;br /&gt;
&lt;br /&gt;
        switch (car)&lt;br /&gt;
        {&lt;br /&gt;
            case CURSOR_UP:&lt;br /&gt;
                *row = (*row == 1) ? 0 : *row;&lt;br /&gt;
                break;&lt;br /&gt;
&lt;br /&gt;
            case CURSOR_DOWN:&lt;br /&gt;
                *row = (*row == 0) ? 1 : *row;&lt;br /&gt;
                break;&lt;br /&gt;
&lt;br /&gt;
            case CURSOR_RIGHT:&lt;br /&gt;
                *col = (*col &amp;lt; nbcols - 1) ? (*col + 1) : *col;&lt;br /&gt;
                break;&lt;br /&gt;
&lt;br /&gt;
            case CURSOR_LEFT:&lt;br /&gt;
                *col = (*col &amp;gt; 0) ? (*col - 1) : *col;&lt;br /&gt;
                break;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        address = HD44780_XY2Adrr(nbrows, nbcols, *row, *col);&lt;br /&gt;
        HD44780_WriteCommand(LCD_ADDRSET | address);&lt;br /&gt;
        HD44780_WriteCommand(LCD_ON | CURSOR_BLINK);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
VIDEO&lt;br /&gt;
&lt;br /&gt;
=== '''Gestion des primitives systèmes''' ===&lt;br /&gt;
Voici les primitives systèmes pour la carte mère, elle permettent de communiquer les chaînes de caractères à envoyer en préparant une transmission SPI constituée de l'octet de commande 0x01 et des données correspondants aux caractères.&lt;br /&gt;
&lt;br /&gt;
La fonction Reset_Display permet de reset l'affichage de l'écran et permet aussi à la carte mère de le remarquer en lui attribuant un numéro de port.&lt;br /&gt;
&lt;br /&gt;
La fonction Transmit_to_display est la fonction de transmission de données par SPI. Elle utilise les fonctions SPI créées précédemment pour envoyer les données à afficher.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; |Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;#include &amp;quot;display.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
void Reset_display(volatile uint8_t *resPort, volatile uint8_t resSel) //Utile pour reset l'ecran&lt;br /&gt;
{&lt;br /&gt;
    *resPort &amp;amp;= ~(1&amp;lt;&amp;lt;resSel);&lt;br /&gt;
    _delay_ms(1);&lt;br /&gt;
    *resPort |= (1&amp;lt;&amp;lt;resSel);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void Transmit_To_display(uint8_t data, volatile uint8_t *ssPort, volatile uint8_t ss)&lt;br /&gt;
{&lt;br /&gt;
	selectSlaveSPI(ssPort,ss);&lt;br /&gt;
	_delay_ms(1);&lt;br /&gt;
	transferSPI(data);&lt;br /&gt;
	_delay_ms(1);&lt;br /&gt;
	unselectSlaveSPI(ssPort,ss);&lt;br /&gt;
	_delay_ms(1);&lt;br /&gt;
}&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
= Références utiles =&lt;br /&gt;
Lien du git :&lt;br /&gt;
&lt;br /&gt;
https://archives.plil.fr/mchauvel/PICO_Taha_NEHARI_Martin_CHAUVELIERE.git&lt;br /&gt;
&lt;br /&gt;
https://github.com/Matiasus/HD44780&lt;br /&gt;
&lt;br /&gt;
NHD-C12832A1Z-FSW-FBW-3V3-ND&lt;br /&gt;
&lt;br /&gt;
http://cdzillidan.free.fr/electronique-numerique/modules/afficheurs-lcd/hd44780/fonctionnement-interne.html&lt;br /&gt;
&lt;br /&gt;
https://michlstechblog.info/blog/raspberry-pi-connecting-a-hd44780-display-with-i2c-bus/&lt;br /&gt;
&lt;br /&gt;
ReX : Merci d'utiliser le squelette de page présenté en séance.&lt;/div&gt;</summary>
		<author><name>Tnehari</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2023-1&amp;diff=2834</id>
		<title>SE4Binome2023-1</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2023-1&amp;diff=2834"/>
		<updated>2024-01-16T16:53:27Z</updated>

		<summary type="html">&lt;p&gt;Tnehari : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Ordonnanceur =&lt;br /&gt;
&lt;br /&gt;
== Soudure et Test du SHIELD ==&lt;br /&gt;
Au cours des 2 premières séances nous avons soudé et testé notre Shield&lt;br /&gt;
[[Fichier:ShieldSoudé.jpg|thumb|center|300x300px|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Shield soudé et monté sur Arduino&amp;lt;/div&amp;gt;]]&lt;br /&gt;
 &lt;br /&gt;
Sur l'un des connecteurs, la led est abîmée dû à une soudure excessive. Sachant que les leds sont uniquement utilisées en tant qu'indicateurs pour savoir quelle carte fille à le contrôle et que nous n'en utiliserons pas plus de 3 pour tester nos programmes, cela ne vas pas avoir d'influence négative.&lt;br /&gt;
Le potentiomètre permet de régler le niveau de luminosité de l'écran et le connecteur HE10 permettra de comuniquer avec l'écran.&lt;br /&gt;
Les problèmes rencontrés sont les suivants : Au départ, la carte ne fonctionnait pas, le soucis étant le quartz mal soudé, c'est à l'aide d'un pistolet à air chaud que celui-ci à été ressoudé. Un autre problème était le reset de la carte fille qui ne fonctionnait pas non plus, une ressoudure classique a permis de le faire fonctionner.&lt;br /&gt;
&lt;br /&gt;
{| class=wikitable style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Code&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Image&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void init_led(){&lt;br /&gt;
  DDRD=0x92;&lt;br /&gt;
  DDRC=0x09;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
  init_led();&lt;br /&gt;
  while(1)&lt;br /&gt;
    {&lt;br /&gt;
	PORTD=0x92;&lt;br /&gt;
	PORTC=0x09;&lt;br /&gt;
    }&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;  &lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
[[Fichier:ShieldLed.jpg|thumb|center|300x300px|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Test des Leds du Shield&amp;lt;/div&amp;gt;]]&lt;br /&gt;
|}&lt;br /&gt;
Puis nous avons aussi soudé l'adaptateur HE10 pour l'utilisation de la matrice de leds[[Fichier:Adaptateur HE10.jpg|thumb|center|300x300px|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Adaptateur HE10 pour Matrice de leds&amp;lt;/div&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
== Programmation de l'Ordonnanceur ==&lt;br /&gt;
Nous commençons maintenant l'ordonnanceur, tout d'abord nous créeons la structure de nos Taches.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct TacheInfo{&lt;br /&gt;
	void (*depart)(void);&lt;br /&gt;
	uint16_t SPointeur;&lt;br /&gt;
	int etat;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;  &lt;br /&gt;
|}&lt;br /&gt;
Puis nous ajoutons les 2 premières taches demandées qui sont de faire clignoter 2 leds différentes à des timing différents.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void TacheA(){&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
        PORTC ^= 0x08;&lt;br /&gt;
	_delay_ms(300);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void TacheB(){&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
        PORTD ^= 0x80;&lt;br /&gt;
	_delay_ms(500);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
struct TacheInfo Taches[2]={&lt;br /&gt;
  {TacheA,0x0600,0},&lt;br /&gt;
  {TacheB,0x0700,0}&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;  &lt;br /&gt;
|}&lt;br /&gt;
On s'occupe maintenant de l'ordonnanceur, ainsi que de l'ISR.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void ordonnanceur ()&lt;br /&gt;
{	&lt;br /&gt;
	PORTD ^= 0x02;&lt;br /&gt;
	courant++;&lt;br /&gt;
	if (courant == NBR_TACHE) courant = 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect,ISR_NAKED)&lt;br /&gt;
{&lt;br /&gt;
	/* Sauvegarde du contexte de la tâche interrompue */&lt;br /&gt;
	SAVE_REGISTER();&lt;br /&gt;
	Taches[courant].SPointeur = SP;&lt;br /&gt;
&lt;br /&gt;
	/* Appel à l'ordonnanceur */&lt;br /&gt;
	ordonnanceur();&lt;br /&gt;
&lt;br /&gt;
	/* Récupération du contexte de la tâche ré-activée */&lt;br /&gt;
	SP = Taches[courant].SPointeur;&lt;br /&gt;
	RESTORE_REGISTER();&lt;br /&gt;
	asm volatile ( &amp;quot;reti&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Nous avons décider de faire clignoter une LED (PORTD ^= 0x02) à chaques utilisations de la fonction ordonnanceur() dans l'ISR.&lt;br /&gt;
&lt;br /&gt;
La variable courant indique la Tache qui est actuellement en cours.&lt;br /&gt;
&lt;br /&gt;
A chaque chaques changements de tache, l'ISR se déclenche enregistre la tache en cours (les registres ainsi que le Stack Pointer), appel l'ordonnanceur, puis change &amp;quot;charge&amp;quot; la tache suivante.&lt;br /&gt;
&lt;br /&gt;
On oublie pas maintenant de générer l'interruption toute les 20ms, pour cela on choisit un prescaler de 1024 et un nombre de ticks de 312.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define PRESCALER 1024&lt;br /&gt;
#define NB_TICK  312&lt;br /&gt;
#define CTC1  WGM12&lt;br /&gt;
&lt;br /&gt;
void init_timer(){&lt;br /&gt;
TCCR1A = 0;  // No output pin connected, no PWM mode enabled&lt;br /&gt;
TCCR1B = 1&amp;lt;&amp;lt;CTC1; // No input pin used, clear timer counter on compare match&lt;br /&gt;
#if (PRESCALER==1024)&lt;br /&gt;
 TCCR1B |= (1&amp;lt;&amp;lt;CS12 | 1&amp;lt;&amp;lt;CS10);&lt;br /&gt;
#endif&lt;br /&gt;
OCR1A = NB_TICK;&lt;br /&gt;
TCNT1 = 0;&lt;br /&gt;
TIMSK1 = (1&amp;lt;&amp;lt;OCIE1A); // No overflow mode enabled, no input interrupt, output compare interrupt&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Ainsi que d'initialiser les Taches pour assurer le bon fonctionnement de notre ordonnanceur.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void init_taches(int pid)&lt;br /&gt;
{&lt;br /&gt;
	int save=SP;&lt;br /&gt;
	SP=Taches[pid].SPointeur;&lt;br /&gt;
	uint16_t adresse=(uint16_t)Taches[pid].depart;&lt;br /&gt;
	asm volatile (&amp;quot;push %0 \n\t&amp;quot; : : &amp;quot;r&amp;quot; (adresse &amp;amp; 0x00ff));&lt;br /&gt;
	asm volatile (&amp;quot;push %0 \n\t&amp;quot; : : &amp;quot;r&amp;quot; ((adresse &amp;amp; 0xff00) &amp;gt;&amp;gt; 8));&lt;br /&gt;
	SAVE_REGISTER();&lt;br /&gt;
	Taches[pid].SPointeur=SP;&lt;br /&gt;
	SP=save;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
On peut maintenant tester notre ordonnanceur.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Vidéo&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define NBR_TACHE 2&lt;br /&gt;
int main(void){&lt;br /&gt;
	init_ports();&lt;br /&gt;
	init_timer();&lt;br /&gt;
	init_taches(1);&lt;br /&gt;
	sei();&lt;br /&gt;
	SP = Taches[courant].SPointeur;&lt;br /&gt;
	Taches[courant].depart();&lt;br /&gt;
	return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;  &lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
Les 2 leds clignotent bien avec le bon timing, et la led témoin de l'ordonnanceur clignotent aussi, ce qui indique que l'ISR est bien actif.&lt;br /&gt;
&lt;br /&gt;
Nous pouvons donc maitenant passer à la gestion des &amp;quot;sleeps&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
En effet, l'utilisation de _delay_ms dans chaque tache n'est pas la manière la plus optimale de procéder. Et meme cela nous bloquera par la suite.&lt;br /&gt;
&lt;br /&gt;
Nous ajoute donc à la structure de nos Taches, une structure InfoEndormi, qui, comme son nom l'indique nous donne des informations si la tache est endormie. A savoir la raison mais aussi des donnees comme par exemple le temps que cette tache doit passer endormie.&lt;br /&gt;
&lt;br /&gt;
Puis afin de remplacer _delay_ms, nous créeons une fonction Attente qui endors une tache pour un temps donné.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define REVEILLE 0&lt;br /&gt;
#define ENDORMI 1&lt;br /&gt;
#define RAISON_DELAY 0&lt;br /&gt;
&lt;br /&gt;
struct InfoEndormi{&lt;br /&gt;
    int raison;&lt;br /&gt;
    uint16_t donnee;&lt;br /&gt;
}sleep_t;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
struct TacheInfo{&lt;br /&gt;
    void (*depart)(void); &lt;br /&gt;
    uint16_t SPointeur;&lt;br /&gt;
    int etat;&lt;br /&gt;
    struct InfoEndormi endormi;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;  &lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&amp;lt;pre&amp;gt;&lt;br /&gt;
void Attente(uint16_t temps_ms){&lt;br /&gt;
    cli();&lt;br /&gt;
    Taches[Tache_courante].etat = ENDORMI;&lt;br /&gt;
    Taches[Tache_courante].endormi.raison = RAISON_DELAY;&lt;br /&gt;
    Taches[Tache_courante].endormi.donnee = temps_ms;&lt;br /&gt;
    TCNT1 = 0;&lt;br /&gt;
    sei();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
Voila maitenant nos taches, il est important de créer une TacheZombie qui comme son nom l'indique est toujours révéillée.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void TacheZombie() //Tache toujours réveillé&lt;br /&gt;
{&lt;br /&gt;
	while(1)&lt;br /&gt;
	{&lt;br /&gt;
		_delay_ms(1.5*PERIODE_INTERUPTION); //Delay légèrement supèrieur à la periode pour éviter tout soucis&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void TacheA()&lt;br /&gt;
{&lt;br /&gt;
	while(1)&lt;br /&gt;
	{&lt;br /&gt;
		PORTC ^= 0x08;&lt;br /&gt;
		Attente(300);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void TacheB()&lt;br /&gt;
{&lt;br /&gt;
	while(1)&lt;br /&gt;
	{&lt;br /&gt;
		PORTD ^= 0x80;&lt;br /&gt;
		Attente(500);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Il est important maitenant de modifier notre ordonnanceur afin que celui-ci puisse recalculer le nouveau temps de sleep d'une tache et si ce temps devient inférieur ou ègale à 0 alors l'ordonnacnceur réveille la tache.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void ordonnanceur ()&lt;br /&gt;
{&lt;br /&gt;
	PORTD ^= 0x02;&lt;br /&gt;
	for(int i = 0; i &amp;lt; NBR_TACHE; i++)&lt;br /&gt;
	{&lt;br /&gt;
		if(Taches[i].etat == ENDORMI &amp;amp;&amp;amp; Taches[Tache_courante].endormi.raison == RAISON_DELAY)&lt;br /&gt;
		{&lt;br /&gt;
			uint16_t diff_temps = PERIODE_INTERUPTION;&lt;br /&gt;
			if(TCNT1 != 0)&lt;br /&gt;
			{&lt;br /&gt;
				//Calcul précis de la différence de temps (pas obligatoirement 20 ms)&lt;br /&gt;
				diff_temps = ((TCNT1*PERIODE_INTERUPTION*10)/OCR1A)/10;&lt;br /&gt;
				TCNT1 = 0;&lt;br /&gt;
			}&lt;br /&gt;
			Taches[i].endormi.donnee  -= diff_temps;&lt;br /&gt;
            &lt;br /&gt;
			if(Taches[i].endormi.donnee &amp;lt;= 0)&lt;br /&gt;
			{&lt;br /&gt;
				Taches[i].etat = REVEILLE;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
    &lt;br /&gt;
	do&lt;br /&gt;
	{&lt;br /&gt;
		Tache_courante++;&lt;br /&gt;
		if (Tache_courante == NBR_TACHE) Tache_courante = 0;&lt;br /&gt;
    }&lt;br /&gt;
	while(Taches[Tache_courante].etat == ENDORMI);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Maintenant que cela est fait, nous pouvons ajouter 2 nouvelles taches qui sont la lecture et l'ecriture sur le port série.&lt;br /&gt;
&lt;br /&gt;
Pour cela, nous allons procéder avec des sémaphores. En effet, il ne peut y avoir que 1 seule tache en écriture ou en lecture, il faut donc que si plusieurs taches essaient de prendre la ressource, cette ressource soit donner à la première arrivé et que les autres taches en attendant patientent.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void semaphore_e(int ACTION){&lt;br /&gt;
	if (ACTION == PRENDRE)&lt;br /&gt;
	{&lt;br /&gt;
		while(1)&lt;br /&gt;
		{&lt;br /&gt;
			cli();&lt;br /&gt;
			if (semaphore_ecriture &amp;gt; 0) //Si ressource dispo &lt;br /&gt;
			{&lt;br /&gt;
				semaphore_ecriture = 0;&lt;br /&gt;
				sei();&lt;br /&gt;
				break;&lt;br /&gt;
        		} else&lt;br /&gt;
			{&lt;br /&gt;
				// La ressource est occupée, on endort la tache&lt;br /&gt;
				Taches[Tache_courante].etat = ENDORMI;&lt;br /&gt;
				Taches[Tache_courante].endormi.raison = RAISON_ECRITURE;&lt;br /&gt;
				TCNT1=0;&lt;br /&gt;
				TIMER1_COMPA_vect();&lt;br /&gt;
			}&lt;br /&gt;
			sei();&lt;br /&gt;
			while(semaphore_ecriture==0);&lt;br /&gt;
		}&lt;br /&gt;
			&lt;br /&gt;
	}&lt;br /&gt;
	else if (ACTION == LAISSER)&lt;br /&gt;
	{&lt;br /&gt;
		cli();&lt;br /&gt;
		semaphore_ecriture = 1;&lt;br /&gt;
		sei();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
On fait la meme chose pour la lecture.&lt;br /&gt;
&lt;br /&gt;
On oublie pas d'initialiser le port série avec les bons paramètres, créer les taches, puis on test.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Image&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void init_serie(long int vitesse){&lt;br /&gt;
	UBRR0=FREQ_CPU/(((unsigned long int)vitesse)&amp;lt;&amp;lt;4)-1; &lt;br /&gt;
        // configure la vitesse&lt;br /&gt;
	UCSR0B=(1&amp;lt;&amp;lt;TXEN0 | 1&amp;lt;&amp;lt;RXEN0);   // autorise l'envoi et la réception&lt;br /&gt;
	UCSR0C=(1&amp;lt;&amp;lt;UCSZ01 | 1&amp;lt;&amp;lt;UCSZ00); // 8 bits et 1 bit de stop&lt;br /&gt;
	UCSR0A &amp;amp;= ~(1 &amp;lt;&amp;lt; U2X0);         // double vitesse désactivée&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |[[Fichier:Lecture EcritureSerie.jpg|centré|vignette|356x356px|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Test de la lecture et de l'écriture sur le port série.(On écrie 9 caractères puis le shield nous renvoie les mêmes 9) &amp;lt;/div&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
= Carte FPGA =&lt;br /&gt;
&lt;br /&gt;
= Carte électronique numérique =&lt;br /&gt;
&lt;br /&gt;
== Conception et Création ==&lt;br /&gt;
Nous avons choisi la Carte Fille : Ecran LCD &lt;br /&gt;
&lt;br /&gt;
Pendant la 3ème séance nous avons finis le Schématic de la carte &lt;br /&gt;
[[Fichier:SCH.png|centré|vignette|700x700px|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Schematic de la Carte Fille : Ecran LCD&amp;lt;/div&amp;gt;]]&lt;br /&gt;
Puis nous avons Routé la carte et envoyé à la Fabrication&lt;br /&gt;
[[Fichier:PCB LCD.png|centré|vignette|550x550px|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Routage de la Carte Fille : Ecran LCD&amp;lt;/div&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
{| class=wikitable style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Carte non soudée&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Carte soudé&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Video Test&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |[[Fichier:Carte LCD non soudée.jpg|centré|vignette|300x300px|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Carte non soudée&amp;lt;/div&amp;gt;]]&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |[[Fichier:Carte LCD soudee.jpg|centré|vignette|400x400px|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Carte soudée&amp;lt;/div&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Programmation de la carte LCD ==&lt;br /&gt;
Tout d'abord, nous avons voulu tester le bon fonctionnement de notre carte mais surtout du bon controle de l'ecran HD44780 grâce à l'IDE Arduino.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Image&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
const int rs = 2, en = 18, d4 = 14, d5 = 15, d6 = 16, d7 = 17;&lt;br /&gt;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  // set up the LCD's number of columns and rows:&lt;br /&gt;
  pinMode(9,OUTPUT);&lt;br /&gt;
  digitalWrite(9,LOW);&lt;br /&gt;
  lcd.begin(16, 2);&lt;br /&gt;
  // Print a message to the LCD.&lt;br /&gt;
  lcd.print(&amp;quot;Je compte&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  // set the cursor to column 0, line 1&lt;br /&gt;
  // (note: line 1 is the second row, since counting begins with 0):&lt;br /&gt;
  lcd.setCursor(0, 1);&lt;br /&gt;
  // print the number of seconds since reset:&lt;br /&gt;
  lcd.print(millis() / 1000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |[[Fichier:TestLCDArduino.jpg|centré|vignette|375x375px|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Test LCD via IDE Arduino&amp;lt;/div&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
Maintenant que cela fonctionne, nous pouvons commencer à écrire notre Librairie pour faire fonctionner notre carte.&lt;br /&gt;
&lt;br /&gt;
=== Librairie HD44780 ===&lt;br /&gt;
Nous avons commencer par reprendre la librairie d'ancien élève, merci à eux pour leur travail.&lt;br /&gt;
&lt;br /&gt;
Dans notre cas, pour l'utilisation la plus simple nous avons besoin de plusieurs fonctions. La première écrit un caractère sur l'écran, la deuxième copie une ligne et la dernière efface une ligne.&lt;br /&gt;
&lt;br /&gt;
HD44780_CopyLine1in0 :&lt;br /&gt;
&lt;br /&gt;
Permet de copier la seconde ligne sur la première. Pour ce faire, on se place au début de la première ligne, on écrit le contenu du tableau de caractère, et on le vide ensuite (EmptyLine1).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void HD44780_CopyLine1in0(char line1[], int nbrows, int nbcols, int ind_line1) {&lt;br /&gt;
    for (int i = 0; i &amp;lt; ind_line1; i++) {&lt;br /&gt;
        int address_ligne0 = HD44780_XY2Adrr(nbrows, nbcols, 0, i);&lt;br /&gt;
        HD44780_WriteCommand(LCD_ADDRSET | address_ligne0);&lt;br /&gt;
        HD44780_WriteData(line1[i],0);&lt;br /&gt;
    }&lt;br /&gt;
    HD44780_EmptyLine1(line1,nbcols);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
HD44780_EraseLine  :&lt;br /&gt;
&lt;br /&gt;
Permet d'effacer une ligne. Pour ce faire on se place au début de la ligne voulue, et on écrit une suite de caractère vide.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; |Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void HD44780_EraseLine(int nbrows, int nbcols, int line) {&lt;br /&gt;
    int address_line1;&lt;br /&gt;
    char espace = ' ';&lt;br /&gt;
    for (int i = 0; i &amp;lt; nbcols; i++) {&lt;br /&gt;
    	address_line1 = HD44780_XY2Adrr(nbrows, nbcols, line, i);&lt;br /&gt;
    	HD44780_WriteCommand(LCD_ADDRSET | address_line1);&lt;br /&gt;
	    HD44780_WriteData(espace,0);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
HD44780_WriteChar  :&lt;br /&gt;
&lt;br /&gt;
Permet d'écrire un caractère sur l'écran. Chaque caractère écrit sur la seconde ligne est placé dans un tableau de caractère. &lt;br /&gt;
&lt;br /&gt;
Lorsqu'on arrive au bout d'une ligne : Si nous sommes à la première ligne (Ligne 0), on passe à la seconde (Ligne 1) et on se replace au début des colonnes. Si nous sommes à la seconde ligne, on efface les deux lignes et on copie la seconde ligne sur la première ligne de l'écran, et on se replace au début de la seconde.  &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; |Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void HD44780_WriteChar(char car, char line1[], int* ind_line1, int nbrows, int nbcols, int* row, int* col) {&lt;br /&gt;
    if ((*col) == nbcols) {&lt;br /&gt;
        (*col) = 0;&lt;br /&gt;
        if ((*row) &amp;lt;= 1) (*row)++;&lt;br /&gt;
        if ((*row) &amp;gt; 1) {&lt;br /&gt;
            (*row) = 1;&lt;br /&gt;
            HD44780_EraseLine(nbrows, nbcols,0);&lt;br /&gt;
            HD44780_EraseLine(nbrows, nbcols,1);&lt;br /&gt;
            HD44780_CopyLine1in0(line1, nbrows, nbcols,*ind_line1);&lt;br /&gt;
        }&lt;br /&gt;
        (*ind_line1) = 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    int address = HD44780_XY2Adrr(nbrows, nbcols, *row, *col);&lt;br /&gt;
    HD44780_WriteCommand(LCD_ADDRSET | address);&lt;br /&gt;
    HD44780_WriteData(car,1);&lt;br /&gt;
    (*col)++;&lt;br /&gt;
    if ((*row) == 1) &lt;br /&gt;
    {&lt;br /&gt;
        line1[*ind_line1] = car;&lt;br /&gt;
        (*ind_line1)++;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}VIDEO   &lt;br /&gt;
&lt;br /&gt;
Super, ca fonctionne !   &lt;br /&gt;
&lt;br /&gt;
Désormais, nous voulons que notre écran affiche ce qu'il recoit via le bus SPI.   &lt;br /&gt;
&lt;br /&gt;
=== Communication SPI ===&lt;br /&gt;
Pour cela il nous faut initialiser le maitre (un arduino UNO) et l'esclave (notre carte LCD).   &lt;br /&gt;
&lt;br /&gt;
Puis que le maitre transmette des données et que l'esclave les recoivent.   &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code Maitre&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code Esclave&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void SPI_init()&lt;br /&gt;
{&lt;br /&gt;
    DDRB |= (1 &amp;lt;&amp;lt; SPI_MOSI) | (1 &amp;lt;&amp;lt; SPI_SCK) | (1 &amp;lt;&amp;lt; SPI_SS);&lt;br /&gt;
    DDRB &amp;amp;= ~(1 &amp;lt;&amp;lt; SPI_MISO);&lt;br /&gt;
    SPCR |= (1 &amp;lt;&amp;lt; MSTR);&lt;br /&gt;
    SPCR |= (1 &amp;lt;&amp;lt; SPE) | (1&amp;lt;&amp;lt;SPR0) | (1&amp;lt;&amp;lt;SPR1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void SPI_MasterTransmit(char cData)&lt;br /&gt;
{&lt;br /&gt;
SPDR = cData;&lt;br /&gt;
while(!(SPSR &amp;amp; (1&amp;lt;&amp;lt;SPIF)));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;  &lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&amp;lt;pre&amp;gt;&lt;br /&gt;
void SPI_init()&lt;br /&gt;
{&lt;br /&gt;
    DDRB |= (1 &amp;lt;&amp;lt; SPI_MISO);&lt;br /&gt;
    DDRB &amp;amp;= ~((1 &amp;lt;&amp;lt; SPI_MOSI) | (1 &amp;lt;&amp;lt; SPI_SCK) | (1 &amp;lt;&amp;lt; SPI_SS));&lt;br /&gt;
    SPCR |= (1 &amp;lt;&amp;lt; SPE); &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
char SPI_SlaveReceive(void)&lt;br /&gt;
{&lt;br /&gt;
    /* Attendre la fin de la réception */&lt;br /&gt;
    while (!(SPSR &amp;amp; (1 &amp;lt;&amp;lt; SPIF)));&lt;br /&gt;
    char receivedData = SPDR;&lt;br /&gt;
    return receivedData;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
Faisons un petit test en envoyant des 'A' suivis de 'B' et enfin un 'X' pour terminer.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code Test du Maitre&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Video&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    while (x&amp;lt;17)&lt;br /&gt;
    {&lt;br /&gt;
      SPI_MasterTransmit('A');&lt;br /&gt;
      _delay_ms(100);&lt;br /&gt;
      SPI_MasterTransmit('B');&lt;br /&gt;
      x++;&lt;br /&gt;
      PORTD ^= (1&amp;lt;&amp;lt;7);&lt;br /&gt;
      _delay_ms(100);&lt;br /&gt;
    }&lt;br /&gt;
    SPI_MasterTransmit('X');&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;  &lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
|}Notre test fonctionne mais cela n'a pas été sans peine. Nous avons rencontré énormément de problème sur la communication SPI. La communication était clairement douteuse et aléatoire.   &lt;br /&gt;
&lt;br /&gt;
==== Problèmes rencontrés ====&lt;br /&gt;
Plusieurs pistes ont été considérées pour comprendre le problème qu'on avait avec le SPI, était-ce l'arduino UNO? Notre connecteur? Le shield? Notre carte?&lt;br /&gt;
Au départ, par soucis de praticité, nous voulions utiliser l'arduino UNO qui disposait de fonctionnalités de test simple avant de passer au shield, mais à chaque essai, le SPI ne fonctionait pas correctement bien qu'on pouvait observer à l'oscilloscope que le message était bien envoyé à notre carte.&lt;br /&gt;
&lt;br /&gt;
Finalement, nous sommes directement passé à la communication SPI avec notre shield, qui cette fois-ci, permettait d'avoir un résultat satisfaisant. Le résultat n'était pas parfait car on remarquait que la position des fils déterminait si la communication allait fonctionner, il fallait donc trouver la position qui permettait cette communication.&lt;br /&gt;
Pour régler ce problème, nous avons déterminé la fréquence de travail du SPI utilisé par le shield et notre carte, pour vérifier qu'il n'y ait pas de problèmes de synchronisation ou que la fréquence utilisée soit bien adaptée. Pour ce faire nous avons observé à l'oscilloscope les différentes divisions de fréquences possibles en vérifiant en même temps que la communication SPI fonctionne bien. Les résultats sont surprenant, car peu importe la fréquence de travail, aucun problème n'a été détécté.&lt;br /&gt;
&lt;br /&gt;
=== Communication SPI par interruption ===&lt;br /&gt;
Il nous faut maitenant communiquer par SPI par interruption car cela offre certains avantages par rapport à la communication SPI standard sans interruption, en particulier en termes d'efficacité et de gestion du temps. En effet, l'utilisation d'interruptions permet au microcontrôleur de gérer d'autres tâches pendant les transferts SPI. Plutôt que d'attendre de manière synchrone la fin d'une transaction SPI, le microcontrôleur peut être informé via une interruption lorsque les données sont prêtes à être lues ou écrites. Cela permet un multitâche plus efficace. Ce qui va nous être trés pratique sachant que le projet comporte plusieurs cartes filles.&lt;br /&gt;
&lt;br /&gt;
Pour cela il nous faut coté maitre et esclave activé le mode SPI Interrupt lors de l'initialisation du SPI, on rajoute donc &amp;lt;code&amp;gt;SPCR |= (1&amp;lt;&amp;lt;SPIE);&amp;lt;/code&amp;gt; lors à l'initialisation.&lt;br /&gt;
&lt;br /&gt;
Ensuite on génère l'interruption coté esclave à la fin de l'initalisation et on configure notre ISR.&lt;br /&gt;
&lt;br /&gt;
Le maitre à plusieurs type d'envoie possible :&lt;br /&gt;
&lt;br /&gt;
0x00 : Demande le type de la carte.&lt;br /&gt;
&lt;br /&gt;
0x01 : Active la communication avec la carte LCD.&lt;br /&gt;
&lt;br /&gt;
0xff   : Met fin à la communication.&lt;br /&gt;
&lt;br /&gt;
Voici comment l'ISR lui fonctionne, si je recois 0x00 je renvoie on type, 0x01 je passe en mode EnReception. &lt;br /&gt;
&lt;br /&gt;
En mode EnReception : lorsque je recois un octet je l'ajoute à un buffer, lorsque je recois 0xff je désactive le mode en Reception.&lt;br /&gt;
&lt;br /&gt;
Dans mon main, une fois que mon mode EnRecption est désactivé mais que mon indice du buffer et supérieur à 0 alors je peux traiter mes octets.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code ISR&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code Main&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ISR(SPI_STC_vect) {&lt;br /&gt;
    uint8_t  data = SPDR;&lt;br /&gt;
    if(EnReception == 1)&lt;br /&gt;
        switch (data){&lt;br /&gt;
	   case 0xff:&lt;br /&gt;
		EnReception=0;&lt;br /&gt;
		break;&lt;br /&gt;
	   default :&lt;br /&gt;
		buffer[IndBuffer++]=data;&lt;br /&gt;
	}&lt;br /&gt;
    else&lt;br /&gt;
        switch (data){&lt;br /&gt;
            case 0x00: &lt;br /&gt;
		sendType();&lt;br /&gt;
		break;&lt;br /&gt;
           case 0x01:&lt;br /&gt;
		EnReception=1;&lt;br /&gt;
		break;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;  &lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&amp;lt;pre&amp;gt;&lt;br /&gt;
while (1) {&lt;br /&gt;
	if (EnReception == 0 &amp;amp;&amp;amp; IndBuffer&amp;gt;0)&lt;br /&gt;
	{&lt;br /&gt;
		for(int i=0; i &amp;lt; IndBuffer; i++)&lt;br /&gt;
		{&lt;br /&gt;
			&amp;quot;Fonction de traitement&amp;quot;&lt;br /&gt;
		}&lt;br /&gt;
		IndBuffer=0;&lt;br /&gt;
	}&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Gestion des caractères spéciaux ===&lt;br /&gt;
Nous avons décider de gérer 4 caractères spéciaux différents : \n , \t, \b, \r&lt;br /&gt;
&lt;br /&gt;
Pour cela on créé la fonction &amp;lt;code&amp;gt;HD44780_Traitement&amp;lt;/code&amp;gt; qui sera notre fonction principale.&lt;br /&gt;
&lt;br /&gt;
Si on recoit un caractère classique alors on l'affiche grâce à &amp;lt;code&amp;gt;HD44780_WriteChar&amp;lt;/code&amp;gt; précédemment crée.&lt;br /&gt;
&lt;br /&gt;
Sinon il sagit d'un caractère spécial et alors on le traite dans un switch case :&lt;br /&gt;
&lt;br /&gt;
==== \n ====&lt;br /&gt;
Si on est sur la première ligne, on se place au début de la seconde.&lt;br /&gt;
&lt;br /&gt;
Si on est sur la seconde ligne, on efface les deux lignes et on copie la seconde ligne sur la première ligne de l'écran, et on se replace au début de la seconde.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code \n&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Video&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        case '\n': //Retour à la ligne&lt;br /&gt;
            switch (*row)&lt;br /&gt;
            {&lt;br /&gt;
                case 0:&lt;br /&gt;
                    (*col) = 0;&lt;br /&gt;
                    (*row) = 1;&lt;br /&gt;
                    break;&lt;br /&gt;
                case 1:&lt;br /&gt;
                    *col = 0;&lt;br /&gt;
                    HD44780_EraseLine(nbrows, nbcols,0);&lt;br /&gt;
                    HD44780_EraseLine(nbrows, nbcols,1);&lt;br /&gt;
                    HD44780_CopyLine1in0(line1, nbrows, nbcols,*ind_line1); &lt;br /&gt;
                    *ind_line1 = 0;&lt;br /&gt;
                    break;    &lt;br /&gt;
            }&lt;br /&gt;
            break;&lt;br /&gt;
&amp;lt;/pre&amp;gt;  &lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== \r ====&lt;br /&gt;
On se replace au début de la ligne sur laquelle on est actuellement en train d'écrire.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code \r&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Video&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
case '\r': // Retour chariot&lt;br /&gt;
            *col = 0;&lt;br /&gt;
            (*ind_line1) = 0;&lt;br /&gt;
            HD44780_EmptyLine1(line1,nbcols);&lt;br /&gt;
            break;&lt;br /&gt;
&amp;lt;/pre&amp;gt;  &lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== \r ====&lt;br /&gt;
On efface le caractère précédent, ajuste la position du curseur, et passe à la ligne supérieure si nécessaire.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code \b&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Video&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
case '\b': // Retour arrière&lt;br /&gt;
            switch (*row)&lt;br /&gt;
            {&lt;br /&gt;
                case 0:&lt;br /&gt;
                    if (*col &amp;gt; 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        (*col)--;//Retourne sur le caractère précédent&lt;br /&gt;
                        char espace = ' ';&lt;br /&gt;
                        int address = HD44780_XY2Adrr(nbrows, nbcols, *row, *col);&lt;br /&gt;
                        HD44780_WriteCommand(LCD_ADDRSET | address);&lt;br /&gt;
                        HD44780_WriteData(espace, 1);//&amp;quot;L'efface&amp;quot;&lt;br /&gt;
                        _delay_ms(500);&lt;br /&gt;
&lt;br /&gt;
                    }&lt;br /&gt;
                    break;&lt;br /&gt;
                case 1:&lt;br /&gt;
                    if (*col &amp;gt; 0)&lt;br /&gt;
                    {&lt;br /&gt;
                      (*col)--;&lt;br /&gt;
                      (*ind_line1) --;&lt;br /&gt;
                    }&lt;br /&gt;
                    else &lt;br /&gt;
                    {&lt;br /&gt;
                      (*row) = 0;&lt;br /&gt;
                      (*col) = 15;&lt;br /&gt;
                    }&lt;br /&gt;
                    char espace = ' ';&lt;br /&gt;
                    int address = HD44780_XY2Adrr(nbrows, nbcols, *row, *col);&lt;br /&gt;
                    HD44780_WriteCommand(LCD_ADDRSET | address);&lt;br /&gt;
                    HD44780_WriteData(espace, 1);&lt;br /&gt;
                    break;&lt;br /&gt;
            }&lt;br /&gt;
            break;&lt;br /&gt;
&amp;lt;/pre&amp;gt;  &lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== \t ====&lt;br /&gt;
On écrit 4 espaces, à la suite de notre position actuelle.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code \t&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Video&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
case '\t': // Tabulation de 4 caractères&lt;br /&gt;
            for (int i=0; i &amp;lt; 4; i++)&lt;br /&gt;
            {   &lt;br /&gt;
                char espace = ' ';&lt;br /&gt;
                HD44780_WriteChar(espace,line1,ind_line1,nbrows,nbcols,row,col);&lt;br /&gt;
            }&lt;br /&gt;
            break;&lt;br /&gt;
&amp;lt;/pre&amp;gt;  &lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Gestion des codes VT100 ===&lt;br /&gt;
Pour finir, nous allons gérer quelques codes VT100, les déplacements de curseurs.&lt;br /&gt;
&lt;br /&gt;
Pour envoyer un code VT100 pour déplacer le curseur le maitre doit nous envoyer:&lt;br /&gt;
&lt;br /&gt;
# Le code ESCAPE (0x1b)&lt;br /&gt;
# Le CURSOR_MODE (0x1c)&lt;br /&gt;
# Et enfin le mouvement du curseur souhaité CURSOR_UP (0x41),  CURSOR_DOWN (0x42), CURSOR_RIGHT (0x43), CURSOR_LEFT (0x44).&lt;br /&gt;
&lt;br /&gt;
On gère cela dans la fonction VT100_Traitement.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; |Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void VT100_Traitement(char car, int nbrows, int nbcols, int* row, int* col, int* vt100_mode)&lt;br /&gt;
{&lt;br /&gt;
    if (*vt100_mode == 1) // CURSOR_MODE&lt;br /&gt;
    {&lt;br /&gt;
        int address;&lt;br /&gt;
&lt;br /&gt;
        switch (car)&lt;br /&gt;
        {&lt;br /&gt;
            case CURSOR_UP:&lt;br /&gt;
                *row = (*row == 1) ? 0 : *row;&lt;br /&gt;
                break;&lt;br /&gt;
&lt;br /&gt;
            case CURSOR_DOWN:&lt;br /&gt;
                *row = (*row == 0) ? 1 : *row;&lt;br /&gt;
                break;&lt;br /&gt;
&lt;br /&gt;
            case CURSOR_RIGHT:&lt;br /&gt;
                *col = (*col &amp;lt; nbcols - 1) ? (*col + 1) : *col;&lt;br /&gt;
                break;&lt;br /&gt;
&lt;br /&gt;
            case CURSOR_LEFT:&lt;br /&gt;
                *col = (*col &amp;gt; 0) ? (*col - 1) : *col;&lt;br /&gt;
                break;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        address = HD44780_XY2Adrr(nbrows, nbcols, *row, *col);&lt;br /&gt;
        HD44780_WriteCommand(LCD_ADDRSET | address);&lt;br /&gt;
        HD44780_WriteCommand(LCD_ON | CURSOR_BLINK);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
VIDEO&lt;br /&gt;
&lt;br /&gt;
'''Gestion des codes VT100'''&lt;br /&gt;
&lt;br /&gt;
Voici les primitives systèmes pour la carte mère, elle permettent de communiquer les chaînes de caractères à envoyer en préparant une transmission SPI constituée de l'octet de commande 0x01 et des données correspondants aux caractères.&lt;br /&gt;
&lt;br /&gt;
La fonction Reset_Display permet de reset l'affichage de l'écran et permet aussi à la carte mère de le remarquer en lui attribuant un numéro de port.&lt;br /&gt;
&lt;br /&gt;
La fonction Transmit_to_display est la fonction de transmission de données par SPI. Elle utilise les fonctions SPI créées précédemment pour envoyer les données à afficher.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; |Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;#include &amp;quot;display.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
void Reset_display(volatile uint8_t *resPort, volatile uint8_t resSel) //Utile pour reset l'ecran&lt;br /&gt;
{&lt;br /&gt;
    *resPort &amp;amp;= ~(1&amp;lt;&amp;lt;resSel);&lt;br /&gt;
    _delay_ms(1);&lt;br /&gt;
    *resPort |= (1&amp;lt;&amp;lt;resSel);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void Transmit_To_display(uint8_t data, volatile uint8_t *ssPort, volatile uint8_t ss)&lt;br /&gt;
{&lt;br /&gt;
	selectSlaveSPI(ssPort,ss);&lt;br /&gt;
	_delay_ms(1);&lt;br /&gt;
	transferSPI(data);&lt;br /&gt;
	_delay_ms(1);&lt;br /&gt;
	unselectSlaveSPI(ssPort,ss);&lt;br /&gt;
	_delay_ms(1);&lt;br /&gt;
}&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
= Références utiles =&lt;br /&gt;
Lien du git :&lt;br /&gt;
&lt;br /&gt;
https://archives.plil.fr/mchauvel/PICO_Taha_NEHARI_Martin_CHAUVELIERE.git&lt;br /&gt;
&lt;br /&gt;
https://github.com/Matiasus/HD44780&lt;br /&gt;
&lt;br /&gt;
NHD-C12832A1Z-FSW-FBW-3V3-ND&lt;br /&gt;
&lt;br /&gt;
http://cdzillidan.free.fr/electronique-numerique/modules/afficheurs-lcd/hd44780/fonctionnement-interne.html&lt;br /&gt;
&lt;br /&gt;
https://michlstechblog.info/blog/raspberry-pi-connecting-a-hd44780-display-with-i2c-bus/&lt;br /&gt;
&lt;br /&gt;
ReX : Merci d'utiliser le squelette de page présenté en séance.&lt;/div&gt;</summary>
		<author><name>Tnehari</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2023-1&amp;diff=2824</id>
		<title>SE4Binome2023-1</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2023-1&amp;diff=2824"/>
		<updated>2024-01-16T15:54:47Z</updated>

		<summary type="html">&lt;p&gt;Tnehari : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Ordonnanceur =&lt;br /&gt;
&lt;br /&gt;
== Soudure et Test du SHIELD ==&lt;br /&gt;
Au cours des 2 premières séances nous avons soudé et testé notre Shield&lt;br /&gt;
[[Fichier:ShieldSoudé.jpg|thumb|center|300x300px|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Shield soudé et monté sur Arduino&amp;lt;/div&amp;gt;]]&lt;br /&gt;
 &lt;br /&gt;
Sur l'un des connecteurs, la led est abîmée dû à une soudure excessive. Sachant que les leds sont uniquement utilisées en tant qu'indicateurs pour savoir quelle carte fille à le contrôle et que nous n'en utiliserons pas plus de 3 pour tester nos programmes, cela ne vas pas avoir d'influence négative.&lt;br /&gt;
Le potentiomètre permet de régler le niveau de luminosité de l'écran et le connecteur HE10 permettra de comuniquer avec l'écran.&lt;br /&gt;
Les problèmes rencontrés sont les suivants : Au départ, la carte ne fonctionnait pas, le soucis étant le quartz mal soudé, c'est à l'aide d'un pistolet à air chaud que celui-ci à été ressoudé. Un autre problème était le reset de la carte fille qui ne fonctionnait pas non plus, une ressoudure classique a permis de le faire fonctionner.&lt;br /&gt;
&lt;br /&gt;
{| class=wikitable style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Code&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Image&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void init_led(){&lt;br /&gt;
  DDRD=0x92;&lt;br /&gt;
  DDRC=0x09;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
  init_led();&lt;br /&gt;
  while(1)&lt;br /&gt;
    {&lt;br /&gt;
	PORTD=0x92;&lt;br /&gt;
	PORTC=0x09;&lt;br /&gt;
    }&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;  &lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
[[Fichier:ShieldLed.jpg|thumb|center|300x300px|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Test des Leds du Shield&amp;lt;/div&amp;gt;]]&lt;br /&gt;
|}&lt;br /&gt;
Puis nous avons aussi soudé l'adaptateur HE10 pour l'utilisation de la matrice de leds[[Fichier:Adaptateur HE10.jpg|thumb|center|300x300px|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Adaptateur HE10 pour Matrice de leds&amp;lt;/div&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
== Programmation de l'Ordonnanceur ==&lt;br /&gt;
Nous commençons maintenant l'ordonnanceur, tout d'abord nous créeons la structure de nos Taches.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct TacheInfo{&lt;br /&gt;
	void (*depart)(void);&lt;br /&gt;
	uint16_t SPointeur;&lt;br /&gt;
	int etat;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;  &lt;br /&gt;
|}&lt;br /&gt;
Puis nous ajoutons les 2 premières taches demandées qui sont de faire clignoter 2 leds différentes à des timing différents.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void TacheA(){&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
        PORTC ^= 0x08;&lt;br /&gt;
	_delay_ms(300);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void TacheB(){&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
        PORTD ^= 0x80;&lt;br /&gt;
	_delay_ms(500);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
struct TacheInfo Taches[2]={&lt;br /&gt;
  {TacheA,0x0600,0},&lt;br /&gt;
  {TacheB,0x0700,0}&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;  &lt;br /&gt;
|}&lt;br /&gt;
On s'occupe maintenant de l'ordonnanceur, ainsi que de l'ISR.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void ordonnanceur ()&lt;br /&gt;
{	&lt;br /&gt;
	PORTD ^= 0x02;&lt;br /&gt;
	courant++;&lt;br /&gt;
	if (courant == NBR_TACHE) courant = 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect,ISR_NAKED)&lt;br /&gt;
{&lt;br /&gt;
	/* Sauvegarde du contexte de la tâche interrompue */&lt;br /&gt;
	SAVE_REGISTER();&lt;br /&gt;
	Taches[courant].SPointeur = SP;&lt;br /&gt;
&lt;br /&gt;
	/* Appel à l'ordonnanceur */&lt;br /&gt;
	ordonnanceur();&lt;br /&gt;
&lt;br /&gt;
	/* Récupération du contexte de la tâche ré-activée */&lt;br /&gt;
	SP = Taches[courant].SPointeur;&lt;br /&gt;
	RESTORE_REGISTER();&lt;br /&gt;
	asm volatile ( &amp;quot;reti&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Nous avons décider de faire clignoter une LED (PORTD ^= 0x02) à chaques utilisations de la fonction ordonnanceur() dans l'ISR.&lt;br /&gt;
&lt;br /&gt;
La variable courant indique la Tache qui est actuellement en cours.&lt;br /&gt;
&lt;br /&gt;
A chaque chaques changements de tache, l'ISR se déclenche enregistre la tache en cours (les registres ainsi que le Stack Pointer), appel l'ordonnanceur, puis change &amp;quot;charge&amp;quot; la tache suivante.&lt;br /&gt;
&lt;br /&gt;
On oublie pas maintenant de générer l'interruption toute les 20ms, pour cela on choisit un prescaler de 1024 et un nombre de ticks de 312.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define PRESCALER 1024&lt;br /&gt;
#define NB_TICK  312&lt;br /&gt;
#define CTC1  WGM12&lt;br /&gt;
&lt;br /&gt;
void init_timer(){&lt;br /&gt;
TCCR1A = 0;  // No output pin connected, no PWM mode enabled&lt;br /&gt;
TCCR1B = 1&amp;lt;&amp;lt;CTC1; // No input pin used, clear timer counter on compare match&lt;br /&gt;
#if (PRESCALER==1024)&lt;br /&gt;
 TCCR1B |= (1&amp;lt;&amp;lt;CS12 | 1&amp;lt;&amp;lt;CS10);&lt;br /&gt;
#endif&lt;br /&gt;
OCR1A = NB_TICK;&lt;br /&gt;
TCNT1 = 0;&lt;br /&gt;
TIMSK1 = (1&amp;lt;&amp;lt;OCIE1A); // No overflow mode enabled, no input interrupt, output compare interrupt&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Ainsi que d'initialiser les Taches pour assurer le bon fonctionnement de notre ordonnanceur.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void init_taches(int pid)&lt;br /&gt;
{&lt;br /&gt;
	int save=SP;&lt;br /&gt;
	SP=Taches[pid].SPointeur;&lt;br /&gt;
	uint16_t adresse=(uint16_t)Taches[pid].depart;&lt;br /&gt;
	asm volatile (&amp;quot;push %0 \n\t&amp;quot; : : &amp;quot;r&amp;quot; (adresse &amp;amp; 0x00ff));&lt;br /&gt;
	asm volatile (&amp;quot;push %0 \n\t&amp;quot; : : &amp;quot;r&amp;quot; ((adresse &amp;amp; 0xff00) &amp;gt;&amp;gt; 8));&lt;br /&gt;
	SAVE_REGISTER();&lt;br /&gt;
	Taches[pid].SPointeur=SP;&lt;br /&gt;
	SP=save;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
On peut maintenant tester notre ordonnanceur.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Vidéo&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define NBR_TACHE 2&lt;br /&gt;
int main(void){&lt;br /&gt;
	init_ports();&lt;br /&gt;
	init_timer();&lt;br /&gt;
	init_taches(1);&lt;br /&gt;
	sei();&lt;br /&gt;
	SP = Taches[courant].SPointeur;&lt;br /&gt;
	Taches[courant].depart();&lt;br /&gt;
	return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;  &lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
Les 2 leds clignotent bien avec le bon timing, et la led témoin de l'ordonnanceur clignotent aussi, ce qui indique que l'ISR est bien actif.&lt;br /&gt;
&lt;br /&gt;
Nous pouvons donc maitenant passer à la gestion des &amp;quot;sleeps&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
En effet, l'utilisation de _delay_ms dans chaque tache n'est pas la manière la plus optimale de procéder. Et meme cela nous bloquera par la suite.&lt;br /&gt;
&lt;br /&gt;
Nous ajoute donc à la structure de nos Taches, une structure InfoEndormi, qui, comme son nom l'indique nous donne des informations si la tache est endormie. A savoir la raison mais aussi des donnees comme par exemple le temps que cette tache doit passer endormie.&lt;br /&gt;
&lt;br /&gt;
Puis afin de remplacer _delay_ms, nous créeons une fonction Attente qui endors une tache pour un temps donné.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define REVEILLE 0&lt;br /&gt;
#define ENDORMI 1&lt;br /&gt;
#define RAISON_DELAY 0&lt;br /&gt;
&lt;br /&gt;
struct InfoEndormi{&lt;br /&gt;
    int raison;&lt;br /&gt;
    uint16_t donnee;&lt;br /&gt;
}sleep_t;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
struct TacheInfo{&lt;br /&gt;
    void (*depart)(void); &lt;br /&gt;
    uint16_t SPointeur;&lt;br /&gt;
    int etat;&lt;br /&gt;
    struct InfoEndormi endormi;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;  &lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&amp;lt;pre&amp;gt;&lt;br /&gt;
void Attente(uint16_t temps_ms){&lt;br /&gt;
    cli();&lt;br /&gt;
    Taches[Tache_courante].etat = ENDORMI;&lt;br /&gt;
    Taches[Tache_courante].endormi.raison = RAISON_DELAY;&lt;br /&gt;
    Taches[Tache_courante].endormi.donnee = temps_ms;&lt;br /&gt;
    TCNT1 = 0;&lt;br /&gt;
    sei();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
Voila maitenant nos taches, il est important de créer une TacheZombie qui comme son nom l'indique est toujours révéillée.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void TacheZombie() //Tache toujours réveillé&lt;br /&gt;
{&lt;br /&gt;
	while(1)&lt;br /&gt;
	{&lt;br /&gt;
		_delay_ms(1.5*PERIODE_INTERUPTION); //Delay légèrement supèrieur à la periode pour éviter tout soucis&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void TacheA()&lt;br /&gt;
{&lt;br /&gt;
	while(1)&lt;br /&gt;
	{&lt;br /&gt;
		PORTC ^= 0x08;&lt;br /&gt;
		Attente(300);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void TacheB()&lt;br /&gt;
{&lt;br /&gt;
	while(1)&lt;br /&gt;
	{&lt;br /&gt;
		PORTD ^= 0x80;&lt;br /&gt;
		Attente(500);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Il est important maitenant de modifier notre ordonnanceur afin que celui-ci puisse recalculer le nouveau temps de sleep d'une tache et si ce temps devient inférieur ou ègale à 0 alors l'ordonnacnceur réveille la tache.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void ordonnanceur ()&lt;br /&gt;
{&lt;br /&gt;
	PORTD ^= 0x02;&lt;br /&gt;
	for(int i = 0; i &amp;lt; NBR_TACHE; i++)&lt;br /&gt;
	{&lt;br /&gt;
		if(Taches[i].etat == ENDORMI &amp;amp;&amp;amp; Taches[Tache_courante].endormi.raison == RAISON_DELAY)&lt;br /&gt;
		{&lt;br /&gt;
			uint16_t diff_temps = PERIODE_INTERUPTION;&lt;br /&gt;
			if(TCNT1 != 0)&lt;br /&gt;
			{&lt;br /&gt;
				//Calcul précis de la différence de temps (pas obligatoirement 20 ms)&lt;br /&gt;
				diff_temps = ((TCNT1*PERIODE_INTERUPTION*10)/OCR1A)/10;&lt;br /&gt;
				TCNT1 = 0;&lt;br /&gt;
			}&lt;br /&gt;
			Taches[i].endormi.donnee  -= diff_temps;&lt;br /&gt;
            &lt;br /&gt;
			if(Taches[i].endormi.donnee &amp;lt;= 0)&lt;br /&gt;
			{&lt;br /&gt;
				Taches[i].etat = REVEILLE;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
    &lt;br /&gt;
	do&lt;br /&gt;
	{&lt;br /&gt;
		Tache_courante++;&lt;br /&gt;
		if (Tache_courante == NBR_TACHE) Tache_courante = 0;&lt;br /&gt;
    }&lt;br /&gt;
	while(Taches[Tache_courante].etat == ENDORMI);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Maintenant que cela est fait, nous pouvons ajouter 2 nouvelles taches qui sont la lecture et l'ecriture sur le port série.&lt;br /&gt;
&lt;br /&gt;
Pour cela, nous allons procéder avec des sémaphores. En effet, il ne peut y avoir que 1 seule tache en écriture ou en lecture, il faut donc que si plusieurs taches essaient de prendre la ressource, cette ressource soit donner à la première arrivé et que les autres taches en attendant patientent.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void semaphore_e(int ACTION){&lt;br /&gt;
	if (ACTION == PRENDRE)&lt;br /&gt;
	{&lt;br /&gt;
		while(1)&lt;br /&gt;
		{&lt;br /&gt;
			cli();&lt;br /&gt;
			if (semaphore_ecriture &amp;gt; 0) //Si ressource dispo &lt;br /&gt;
			{&lt;br /&gt;
				semaphore_ecriture = 0;&lt;br /&gt;
				sei();&lt;br /&gt;
				break;&lt;br /&gt;
        		} else&lt;br /&gt;
			{&lt;br /&gt;
				// La ressource est occupée, on endort la tache&lt;br /&gt;
				Taches[Tache_courante].etat = ENDORMI;&lt;br /&gt;
				Taches[Tache_courante].endormi.raison = RAISON_ECRITURE;&lt;br /&gt;
				TCNT1=0;&lt;br /&gt;
				TIMER1_COMPA_vect();&lt;br /&gt;
			}&lt;br /&gt;
			sei();&lt;br /&gt;
			while(semaphore_ecriture==0);&lt;br /&gt;
		}&lt;br /&gt;
			&lt;br /&gt;
	}&lt;br /&gt;
	else if (ACTION == LAISSER)&lt;br /&gt;
	{&lt;br /&gt;
		cli();&lt;br /&gt;
		semaphore_ecriture = 1;&lt;br /&gt;
		sei();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
On fait la meme chose pour la lecture.&lt;br /&gt;
&lt;br /&gt;
On oublie pas d'initialiser le port série avec les bons paramètres, créer les taches, puis on test.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Image&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void init_serie(long int vitesse){&lt;br /&gt;
	UBRR0=FREQ_CPU/(((unsigned long int)vitesse)&amp;lt;&amp;lt;4)-1; &lt;br /&gt;
        // configure la vitesse&lt;br /&gt;
	UCSR0B=(1&amp;lt;&amp;lt;TXEN0 | 1&amp;lt;&amp;lt;RXEN0);   // autorise l'envoi et la réception&lt;br /&gt;
	UCSR0C=(1&amp;lt;&amp;lt;UCSZ01 | 1&amp;lt;&amp;lt;UCSZ00); // 8 bits et 1 bit de stop&lt;br /&gt;
	UCSR0A &amp;amp;= ~(1 &amp;lt;&amp;lt; U2X0);         // double vitesse désactivée&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |[[Fichier:Lecture EcritureSerie.jpg|centré|vignette|356x356px|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Test de la lecture et de l'écriture sur le port série.(On écrie 9 caractères puis le shield nous renvoie les mêmes 9) &amp;lt;/div&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
= Carte FPGA =&lt;br /&gt;
&lt;br /&gt;
= Carte électronique numérique =&lt;br /&gt;
&lt;br /&gt;
== Conception et Création ==&lt;br /&gt;
Nous avons choisi la Carte Fille : Ecran LCD &lt;br /&gt;
&lt;br /&gt;
Pendant la 3ème séance nous avons finis le Schématic de la carte &lt;br /&gt;
[[Fichier:SCH.png|centré|vignette|700x700px|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Schematic de la Carte Fille : Ecran LCD&amp;lt;/div&amp;gt;]]&lt;br /&gt;
Puis nous avons Routé la carte et envoyé à la Fabrication&lt;br /&gt;
[[Fichier:PCB LCD.png|centré|vignette|550x550px|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Routage de la Carte Fille : Ecran LCD&amp;lt;/div&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
{| class=wikitable style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Carte non soudée&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Carte soudé&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Video Test&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |[[Fichier:Carte LCD non soudée.jpg|centré|vignette|300x300px|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Carte non soudée&amp;lt;/div&amp;gt;]]&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |[[Fichier:Carte LCD soudee.jpg|centré|vignette|400x400px|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Carte soudée&amp;lt;/div&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Programmation de la carte LCD ==&lt;br /&gt;
Tout d'abord, nous avons voulu tester le bon fonctionnement de notre carte mais surtout du bon controle de l'ecran HD44780 grâce à l'IDE Arduino.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Image&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
const int rs = 2, en = 18, d4 = 14, d5 = 15, d6 = 16, d7 = 17;&lt;br /&gt;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  // set up the LCD's number of columns and rows:&lt;br /&gt;
  pinMode(9,OUTPUT);&lt;br /&gt;
  digitalWrite(9,LOW);&lt;br /&gt;
  lcd.begin(16, 2);&lt;br /&gt;
  // Print a message to the LCD.&lt;br /&gt;
  lcd.print(&amp;quot;Je compte&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  // set the cursor to column 0, line 1&lt;br /&gt;
  // (note: line 1 is the second row, since counting begins with 0):&lt;br /&gt;
  lcd.setCursor(0, 1);&lt;br /&gt;
  // print the number of seconds since reset:&lt;br /&gt;
  lcd.print(millis() / 1000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |[[Fichier:TestLCDArduino.jpg|centré|vignette|375x375px|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Test LCD via IDE Arduino&amp;lt;/div&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
Maintenant que cela fonctionne, nous pouvons commencer à écrire notre Librairie pour faire fonctionner notre carte.&lt;br /&gt;
&lt;br /&gt;
=== Librairie HD44780 ===&lt;br /&gt;
Nous avons commencer par reprendre la librairie d'ancien élève, merci à eux pour leur travail.&lt;br /&gt;
&lt;br /&gt;
Dans notre cas, pour l'utilisation la plus simple nous avons besoin de plusieurs fonctions. La première écrit un caractère sur l'écran, la deuxième copie une ligne et la dernière efface une ligne.&lt;br /&gt;
&lt;br /&gt;
HD44780_CopyLine1in0 :&lt;br /&gt;
&lt;br /&gt;
Permet de copier la seconde ligne sur la première. Pour ce faire, on se place au début de la première ligne, on écrit le contenu du tableau de caractère, et on le vide ensuite (EmptyLine1).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void HD44780_CopyLine1in0(char line1[], int nbrows, int nbcols, int ind_line1) {&lt;br /&gt;
    for (int i = 0; i &amp;lt; ind_line1; i++) {&lt;br /&gt;
        int address_ligne0 = HD44780_XY2Adrr(nbrows, nbcols, 0, i);&lt;br /&gt;
        HD44780_WriteCommand(LCD_ADDRSET | address_ligne0);&lt;br /&gt;
        HD44780_WriteData(line1[i],0);&lt;br /&gt;
    }&lt;br /&gt;
    HD44780_EmptyLine1(line1,nbcols);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
HD44780_EraseLine  :&lt;br /&gt;
&lt;br /&gt;
Permet d'effacer une ligne. Pour ce faire on se place au début de la ligne voulue, et on écrit une suite de caractère vide.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; |Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void HD44780_EraseLine(int nbrows, int nbcols, int line) {&lt;br /&gt;
    int address_line1;&lt;br /&gt;
    char espace = ' ';&lt;br /&gt;
    for (int i = 0; i &amp;lt; nbcols; i++) {&lt;br /&gt;
    	address_line1 = HD44780_XY2Adrr(nbrows, nbcols, line, i);&lt;br /&gt;
    	HD44780_WriteCommand(LCD_ADDRSET | address_line1);&lt;br /&gt;
	    HD44780_WriteData(espace,0);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
HD44780_WriteChar  :&lt;br /&gt;
&lt;br /&gt;
Permet d'écrire un caractère sur l'écran. Chaque caractère écrit sur la seconde ligne est placé dans un tableau de caractère. &lt;br /&gt;
&lt;br /&gt;
Lorsqu'on arrive au bout d'une ligne : Si nous sommes à la première ligne (Ligne 0), on passe à la seconde (Ligne 1) et on se replace au début des colonnes. Si nous sommes à la seconde ligne, on efface les deux lignes et on copie la seconde ligne sur la première ligne de l'écran, et on se replace au début de la seconde.  &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; |Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void HD44780_WriteChar(char car, char line1[], int* ind_line1, int nbrows, int nbcols, int* row, int* col) {&lt;br /&gt;
    if ((*col) == nbcols) {&lt;br /&gt;
        (*col) = 0;&lt;br /&gt;
        if ((*row) &amp;lt;= 1) (*row)++;&lt;br /&gt;
        if ((*row) &amp;gt; 1) {&lt;br /&gt;
            (*row) = 1;&lt;br /&gt;
            HD44780_EraseLine(nbrows, nbcols,0);&lt;br /&gt;
            HD44780_EraseLine(nbrows, nbcols,1);&lt;br /&gt;
            HD44780_CopyLine1in0(line1, nbrows, nbcols,*ind_line1);&lt;br /&gt;
        }&lt;br /&gt;
        (*ind_line1) = 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    int address = HD44780_XY2Adrr(nbrows, nbcols, *row, *col);&lt;br /&gt;
    HD44780_WriteCommand(LCD_ADDRSET | address);&lt;br /&gt;
    HD44780_WriteData(car,1);&lt;br /&gt;
    (*col)++;&lt;br /&gt;
    if ((*row) == 1) &lt;br /&gt;
    {&lt;br /&gt;
        line1[*ind_line1] = car;&lt;br /&gt;
        (*ind_line1)++;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}VIDEO   &lt;br /&gt;
&lt;br /&gt;
Super, ca fonctionne !   &lt;br /&gt;
&lt;br /&gt;
Désormais, nous voulons que notre écran affiche ce qu'il recoit via le bus SPI.   &lt;br /&gt;
&lt;br /&gt;
=== Communication SPI ===&lt;br /&gt;
Pour cela il nous faut initialiser le maitre (un arduino UNO) et l'esclave (notre carte LCD).   &lt;br /&gt;
&lt;br /&gt;
Puis que le maitre transmette des données et que l'esclave les recoivent.   &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code Maitre&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code Esclave&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void SPI_init()&lt;br /&gt;
{&lt;br /&gt;
    DDRB |= (1 &amp;lt;&amp;lt; SPI_MOSI) | (1 &amp;lt;&amp;lt; SPI_SCK) | (1 &amp;lt;&amp;lt; SPI_SS);&lt;br /&gt;
    DDRB &amp;amp;= ~(1 &amp;lt;&amp;lt; SPI_MISO);&lt;br /&gt;
    SPCR |= (1 &amp;lt;&amp;lt; MSTR);&lt;br /&gt;
    SPCR |= (1 &amp;lt;&amp;lt; SPE) | (1&amp;lt;&amp;lt;SPR0) | (1&amp;lt;&amp;lt;SPR1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void SPI_MasterTransmit(char cData)&lt;br /&gt;
{&lt;br /&gt;
SPDR = cData;&lt;br /&gt;
while(!(SPSR &amp;amp; (1&amp;lt;&amp;lt;SPIF)));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;  &lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&amp;lt;pre&amp;gt;&lt;br /&gt;
void SPI_init()&lt;br /&gt;
{&lt;br /&gt;
    DDRB |= (1 &amp;lt;&amp;lt; SPI_MISO);&lt;br /&gt;
    DDRB &amp;amp;= ~((1 &amp;lt;&amp;lt; SPI_MOSI) | (1 &amp;lt;&amp;lt; SPI_SCK) | (1 &amp;lt;&amp;lt; SPI_SS));&lt;br /&gt;
    SPCR |= (1 &amp;lt;&amp;lt; SPE); &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
char SPI_SlaveReceive(void)&lt;br /&gt;
{&lt;br /&gt;
    /* Attendre la fin de la réception */&lt;br /&gt;
    while (!(SPSR &amp;amp; (1 &amp;lt;&amp;lt; SPIF)));&lt;br /&gt;
    char receivedData = SPDR;&lt;br /&gt;
    return receivedData;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
Faisons un petit test en envoyant des 'A' suivis de 'B' et enfin un 'X' pour terminer.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code Test du Maitre&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Video&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    while (x&amp;lt;17)&lt;br /&gt;
    {&lt;br /&gt;
      SPI_MasterTransmit('A');&lt;br /&gt;
      _delay_ms(100);&lt;br /&gt;
      SPI_MasterTransmit('B');&lt;br /&gt;
      x++;&lt;br /&gt;
      PORTD ^= (1&amp;lt;&amp;lt;7);&lt;br /&gt;
      _delay_ms(100);&lt;br /&gt;
    }&lt;br /&gt;
    SPI_MasterTransmit('X');&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;  &lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
|}Notre test fonctionne mais cela n'a pas été sans peine. Nous avons rencontré énormément de problème sur la communication SPI. La communication était clairement douteuse et aléatoire.   &lt;br /&gt;
&lt;br /&gt;
==== Problèmes rencontrés ====&lt;br /&gt;
Plusieurs pistes ont été considérées pour comprendre le problème qu'on avait avec le SPI, était-ce l'arduino UNO? Notre connecteur? Le shield? Notre carte?&lt;br /&gt;
Au départ, par soucis de praticité, nous voulions utiliser l'arduino UNO qui disposait de fonctionnalités de test simple avant de passer au shield, mais à chaque essai, le SPI ne fonctionait pas correctement bien qu'on pouvait observer à l'oscilloscope que le message était bien envoyé à notre carte.&lt;br /&gt;
Finalement, nous sommes directement passé à la communication SPI avec notre shield, qui cette fois-ci, permettait d'avoir un résultat satisfaisant. Le résultat n'était pas parfait car on remarquait que la position des fils déterminait si la communication allait fonctionner, il fallait donc trouver la position qui permettait cette communication.&lt;br /&gt;
Pour régler ce problème, nous avons déterminé la fréquence de travail du SPI utilisé par le shield et notre carte, pour vérifier qu'il n'y ait pas de problèmes de synchronisation ou que la fréquence utilisée soit bien adaptée. Pour ce faire nous avons observé à l'oscilloscope les différentes divisions de fréquences possibles en vérifiant en même temps que la communication SPI fonctionne bien. Les résultats sont surprenant, car peu importe la fréquence de travail, aucun problème n'a été détécté.&lt;br /&gt;
&lt;br /&gt;
= Références utiles =&lt;br /&gt;
Lien du git :&lt;br /&gt;
&lt;br /&gt;
https://archives.plil.fr/mchauvel/PICO_Taha_NEHARI_Martin_CHAUVELIERE.git&lt;br /&gt;
&lt;br /&gt;
https://github.com/Matiasus/HD44780&lt;br /&gt;
&lt;br /&gt;
NHD-C12832A1Z-FSW-FBW-3V3-ND&lt;br /&gt;
&lt;br /&gt;
http://cdzillidan.free.fr/electronique-numerique/modules/afficheurs-lcd/hd44780/fonctionnement-interne.html&lt;br /&gt;
&lt;br /&gt;
https://michlstechblog.info/blog/raspberry-pi-connecting-a-hd44780-display-with-i2c-bus/&lt;br /&gt;
&lt;br /&gt;
ReX : Merci d'utiliser le squelette de page présenté en séance.&lt;/div&gt;</summary>
		<author><name>Tnehari</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2023-1&amp;diff=2789</id>
		<title>SE4Binome2023-1</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2023-1&amp;diff=2789"/>
		<updated>2024-01-16T14:04:56Z</updated>

		<summary type="html">&lt;p&gt;Tnehari : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Ordonnanceur =&lt;br /&gt;
&lt;br /&gt;
== Soudure et Test du SHIELD ==&lt;br /&gt;
Au cours des 2 premières séances nous avons soudé et testé notre Shield&lt;br /&gt;
[[Fichier:ShieldSoudé.jpg|thumb|center|300x300px|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Shield soudé et monté sur Arduino&amp;lt;/div&amp;gt;]]&lt;br /&gt;
 &lt;br /&gt;
Sur l'un des connecteurs, la led est abîmée dû à une soudure excessive. Sachant que les leds sont uniquement utilisées en tant qu'indicateurs pour savoir quelle carte fille à le contrôle et que nous n'en utiliserons pas plus de 3 pour tester nos programmes, cela ne vas pas avoir d'influence négative.&lt;br /&gt;
Le potentiomètre permet de régler le niveau de luminosité de l'écran et le connecteur HE10 permettra de comuniquer avec l'écran.&lt;br /&gt;
Les problèmes rencontrés sont les suivants : Au départ, la carte ne fonctionnait pas, le soucis étant le quartz mal soudé, c'est à l'aide d'un pistolet à air chaud que celui-ci à été ressoudé. Un autre problème était le reset de la carte fille qui ne fonctionnait pas non plus, une ressoudure classique a permis de le faire fonctionner.&lt;br /&gt;
&lt;br /&gt;
{| class=wikitable style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Code&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Image&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void init_led(){&lt;br /&gt;
  DDRD=0x92;&lt;br /&gt;
  DDRC=0x09;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
  init_led();&lt;br /&gt;
  while(1)&lt;br /&gt;
    {&lt;br /&gt;
	PORTD=0x92;&lt;br /&gt;
	PORTC=0x09;&lt;br /&gt;
    }&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;  &lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
[[Fichier:ShieldLed.jpg|thumb|center|300x300px|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Test des Leds du Shield&amp;lt;/div&amp;gt;]]&lt;br /&gt;
|}&lt;br /&gt;
Puis nous avons aussi soudé l'adaptateur HE10 pour l'utilisation de la matrice de leds[[Fichier:Adaptateur HE10.jpg|thumb|center|300x300px|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Adaptateur HE10 pour Matrice de leds&amp;lt;/div&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
= Codage de l'Ordonnanceur =&lt;br /&gt;
Nous commençons maintenant l'ordonnanceur, tout d'abord nous créeons la structure de nos Taches.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct TacheInfo{&lt;br /&gt;
	void (*depart)(void);&lt;br /&gt;
	uint16_t SPointeur;&lt;br /&gt;
	int etat;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;  &lt;br /&gt;
|}&lt;br /&gt;
Puis nous ajoutons les 2 premières taches demandées qui sont de faire clignoter 2 leds différentes à des timing différents.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void TacheA(){&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
        PORTC ^= 0x08;&lt;br /&gt;
	_delay_ms(300);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void TacheB(){&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
        PORTD ^= 0x80;&lt;br /&gt;
	_delay_ms(500);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
struct TacheInfo Taches[2]={&lt;br /&gt;
  {TacheA,0x0600,0},&lt;br /&gt;
  {TacheB,0x0700,0}&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;  &lt;br /&gt;
|}&lt;br /&gt;
On s'occupe maintenant de l'ordonnanceur, ainsi que de l'ISR.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void ordonnanceur ()&lt;br /&gt;
{	&lt;br /&gt;
	PORTD ^= 0x02;&lt;br /&gt;
	courant++;&lt;br /&gt;
	if (courant == NBR_TACHE) courant = 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect,ISR_NAKED)&lt;br /&gt;
{&lt;br /&gt;
	/* Sauvegarde du contexte de la tâche interrompue */&lt;br /&gt;
	SAVE_REGISTER();&lt;br /&gt;
	Taches[courant].SPointeur = SP;&lt;br /&gt;
&lt;br /&gt;
	/* Appel à l'ordonnanceur */&lt;br /&gt;
	ordonnanceur();&lt;br /&gt;
&lt;br /&gt;
	/* Récupération du contexte de la tâche ré-activée */&lt;br /&gt;
	SP = Taches[courant].SPointeur;&lt;br /&gt;
	RESTORE_REGISTER();&lt;br /&gt;
	asm volatile ( &amp;quot;reti&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Nous avons décider de faire clignoter une LED (PORTD ^= 0x02) à chaques utilisations de la fonction ordonnanceur() dans l'ISR.&lt;br /&gt;
&lt;br /&gt;
La variable courant indique la Tache qui est actuellement en cours.&lt;br /&gt;
&lt;br /&gt;
A chaque chaques changements de tache, l'ISR se déclenche enregistre la tache en cours (les registres ainsi que le Stack Pointer), appel l'ordonnanceur, puis change &amp;quot;charge&amp;quot; la tache suivante.&lt;br /&gt;
&lt;br /&gt;
On oublie pas maintenant de générer l'interruption toute les 20ms, pour cela on choisit un prescaler de 1024 et un nombre de ticks de 312.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define PRESCALER 1024&lt;br /&gt;
#define NB_TICK  312&lt;br /&gt;
#define CTC1  WGM12&lt;br /&gt;
&lt;br /&gt;
void init_timer(){&lt;br /&gt;
TCCR1A = 0;  // No output pin connected, no PWM mode enabled&lt;br /&gt;
TCCR1B = 1&amp;lt;&amp;lt;CTC1; // No input pin used, clear timer counter on compare match&lt;br /&gt;
#if (PRESCALER==1024)&lt;br /&gt;
 TCCR1B |= (1&amp;lt;&amp;lt;CS12 | 1&amp;lt;&amp;lt;CS10);&lt;br /&gt;
#endif&lt;br /&gt;
OCR1A = NB_TICK;&lt;br /&gt;
TCNT1 = 0;&lt;br /&gt;
TIMSK1 = (1&amp;lt;&amp;lt;OCIE1A); // No overflow mode enabled, no input interrupt, output compare interrupt&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Ainsi que d'initialiser les Taches pour assurer le bon fonctionnement de notre ordonnanceur.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void init_taches(int pid)&lt;br /&gt;
{&lt;br /&gt;
	int save=SP;&lt;br /&gt;
	SP=Taches[pid].SPointeur;&lt;br /&gt;
	uint16_t adresse=(uint16_t)Taches[pid].depart;&lt;br /&gt;
	asm volatile (&amp;quot;push %0 \n\t&amp;quot; : : &amp;quot;r&amp;quot; (adresse &amp;amp; 0x00ff));&lt;br /&gt;
	asm volatile (&amp;quot;push %0 \n\t&amp;quot; : : &amp;quot;r&amp;quot; ((adresse &amp;amp; 0xff00) &amp;gt;&amp;gt; 8));&lt;br /&gt;
	SAVE_REGISTER();&lt;br /&gt;
	Taches[pid].SPointeur=SP;&lt;br /&gt;
	SP=save;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
On peut maintenant tester notre ordonnanceur.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Vidéo&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define NBR_TACHE 2&lt;br /&gt;
int main(void){&lt;br /&gt;
	init_ports();&lt;br /&gt;
	init_timer();&lt;br /&gt;
	init_taches(1);&lt;br /&gt;
	sei();&lt;br /&gt;
	SP = Taches[courant].SPointeur;&lt;br /&gt;
	Taches[courant].depart();&lt;br /&gt;
	return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;  &lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
Les 2 leds clignotent bien avec le bon timing, et la led témoin de l'ordonnanceur clignotent aussi, ce qui indique que l'ISR est bien actif.&lt;br /&gt;
&lt;br /&gt;
Nous pouvons donc maitenant passer à la gestion des &amp;quot;sleeps&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
En effet, l'utilisation de _delay_ms dans chaque tache n'est pas la manière la plus optimale de procéder. Et meme cela nous bloquera par la suite.&lt;br /&gt;
&lt;br /&gt;
Nous ajoute donc à la structure de nos Taches, une structure InfoEndormi, qui, comme son nom l'indique nous donne des informations si la tache est endormie. A savoir la raison mais aussi des donnees comme par exemple le temps que cette tache doit passer endormie.&lt;br /&gt;
&lt;br /&gt;
Puis afin de remplacer _delay_ms, nous créeons une fonction Attente qui endors une tache pour un temps donné.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define REVEILLE 0&lt;br /&gt;
#define ENDORMI 1&lt;br /&gt;
#define RAISON_DELAY 0&lt;br /&gt;
&lt;br /&gt;
struct InfoEndormi{&lt;br /&gt;
    int raison;&lt;br /&gt;
    uint16_t donnee;&lt;br /&gt;
}sleep_t;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
struct TacheInfo{&lt;br /&gt;
    void (*depart)(void); &lt;br /&gt;
    uint16_t SPointeur;&lt;br /&gt;
    int etat;&lt;br /&gt;
    struct InfoEndormi endormi;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;  &lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&amp;lt;pre&amp;gt;&lt;br /&gt;
void Attente(uint16_t temps_ms){&lt;br /&gt;
    cli();&lt;br /&gt;
    Taches[Tache_courante].etat = ENDORMI;&lt;br /&gt;
    Taches[Tache_courante].endormi.raison = RAISON_DELAY;&lt;br /&gt;
    Taches[Tache_courante].endormi.donnee = temps_ms;&lt;br /&gt;
    TCNT1 = 0;&lt;br /&gt;
    sei();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
Voila maitenant nos taches, il est important de créer une TacheZombie qui comme son nom l'indique est toujours révéillée.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void TacheZombie() //Tache toujours réveillé&lt;br /&gt;
{&lt;br /&gt;
	while(1)&lt;br /&gt;
	{&lt;br /&gt;
		_delay_ms(1.5*PERIODE_INTERUPTION); //Delay légèrement supèrieur à la periode pour éviter tout soucis&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void TacheA()&lt;br /&gt;
{&lt;br /&gt;
	while(1)&lt;br /&gt;
	{&lt;br /&gt;
		PORTC ^= 0x08;&lt;br /&gt;
		Attente(300);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void TacheB()&lt;br /&gt;
{&lt;br /&gt;
	while(1)&lt;br /&gt;
	{&lt;br /&gt;
		PORTD ^= 0x80;&lt;br /&gt;
		Attente(500);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Il est important maitenant de modifier notre ordonnanceur afin que celui-ci puisse recalculer le nouveau temps de sleep d'une tache et si ce temps devient inférieur ou ègale à 0 alors l'ordonnacnceur réveille la tache.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Code&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void ordonnanceur ()&lt;br /&gt;
{&lt;br /&gt;
	PORTD ^= 0x02;&lt;br /&gt;
	for(int i = 0; i &amp;lt; NBR_TACHE; i++)&lt;br /&gt;
	{&lt;br /&gt;
		if(Taches[i].etat == ENDORMI &amp;amp;&amp;amp; Taches[Tache_courante].endormi.raison == RAISON_DELAY)&lt;br /&gt;
		{&lt;br /&gt;
			uint16_t diff_temps = PERIODE_INTERUPTION;&lt;br /&gt;
			if(TCNT1 != 0)&lt;br /&gt;
			{&lt;br /&gt;
				//Calcul précis de la différence de temps (pas obligatoirement 20 ms)&lt;br /&gt;
				diff_temps = ((TCNT1*PERIODE_INTERUPTION*10)/OCR1A)/10;&lt;br /&gt;
				TCNT1 = 0;&lt;br /&gt;
			}&lt;br /&gt;
			Taches[i].endormi.donnee  -= diff_temps;&lt;br /&gt;
            &lt;br /&gt;
			if(Taches[i].endormi.donnee &amp;lt;= 0)&lt;br /&gt;
			{&lt;br /&gt;
				Taches[i].etat = REVEILLE;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
    &lt;br /&gt;
	do&lt;br /&gt;
	{&lt;br /&gt;
		Tache_courante++;&lt;br /&gt;
		if (Tache_courante == NBR_TACHE) Tache_courante = 0;&lt;br /&gt;
    }&lt;br /&gt;
	while(Taches[Tache_courante].etat == ENDORMI);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Maintenant que cela est fait, nous pouvons ajouter 2 nouvelles taches qui sont la lecture et l'ecriture sur le port série.&lt;br /&gt;
&lt;br /&gt;
= Carte FPGA =&lt;br /&gt;
&lt;br /&gt;
= Carte électronique numérique =&lt;br /&gt;
Nous avons choisi la Carte Fille : Ecran LCD &lt;br /&gt;
&lt;br /&gt;
Pendant la 3ème séance nous avons finis le Schématic de la carte &lt;br /&gt;
[[Fichier:SCH.png|centré|vignette|700x700px|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Schematic de la Carte Fille : Ecran LCD&amp;lt;/div&amp;gt;]]&lt;br /&gt;
Puis nous avons Routé la carte et envoyé à la Fabrication&lt;br /&gt;
[[Fichier:PCB LCD.png|centré|vignette|550x550px|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Routage de la Carte Fille : Ecran LCD&amp;lt;/div&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
{| class=wikitable style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Carte non soudée&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Carte soudé&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |[[Fichier:Carte LCD non soudée.jpg|centré|vignette|300x300px|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Carte non soudée&amp;lt;/div&amp;gt;]]&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; |[[Fichier:Carte LCD soudee.jpg|centré|vignette|400x400px|&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;Carte soudée&amp;lt;/div&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Références utiles =&lt;br /&gt;
Lien du git :&lt;br /&gt;
&lt;br /&gt;
https://archives.plil.fr/mchauvel/PICO_Taha_NEHARI_Martin_CHAUVELIERE.git&lt;br /&gt;
&lt;br /&gt;
https://github.com/Matiasus/HD44780&lt;br /&gt;
&lt;br /&gt;
NHD-C12832A1Z-FSW-FBW-3V3-ND&lt;br /&gt;
&lt;br /&gt;
http://cdzillidan.free.fr/electronique-numerique/modules/afficheurs-lcd/hd44780/fonctionnement-interne.html&lt;br /&gt;
&lt;br /&gt;
https://michlstechblog.info/blog/raspberry-pi-connecting-a-hd44780-display-with-i2c-bus/&lt;br /&gt;
&lt;br /&gt;
ReX : Merci d'utiliser le squelette de page présenté en séance.&lt;/div&gt;</summary>
		<author><name>Tnehari</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2022-11&amp;diff=916</id>
		<title>SE3Binome2022-11</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2022-11&amp;diff=916"/>
		<updated>2023-05-28T20:26:07Z</updated>

		<summary type="html">&lt;p&gt;Tnehari : Ajout Liens vidéo pour moteur et Leds&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''&amp;lt;big&amp;gt;Caractéristiques de notre système:&amp;lt;/big&amp;gt;''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Modèle réduit au 1.43&lt;br /&gt;
* Commande Bluetooth via application téléphone (MIT App Inventor) en temps réel:&lt;br /&gt;
** Joystick directionnel&lt;br /&gt;
** Boutons pour les clignotants&lt;br /&gt;
** Bonus : klaxon&lt;br /&gt;
* Module Bluetooth Low Energy&lt;br /&gt;
* Moteur CC avec réductuer + Pilote (DRV8210DRLR) (Propulsion)&lt;br /&gt;
* Moteur glissière pas à pas (Direction)&lt;br /&gt;
* 2 LEDs avant BLANCHES lorsque le véhicule avance&lt;br /&gt;
* 2 LEDs arrière ROUGES lorsque le véhicule recule&lt;br /&gt;
* 4 LEDs JAUNES pour les clignotants&lt;br /&gt;
* Lien du git : https://archives.plil.fr/mchauvel/PSE_tnehari_mchauvel.git&lt;br /&gt;
&lt;br /&gt;
== '''Module Bluetooth Low Energy''' ==&lt;br /&gt;
Après étude de la [https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/Bluetooth-Low-Energy-BLE-Module-DS60001372K.pdf datasheet] (page 15 figure 2-5) nous avons pu recréer le composant BM71BLE01FC2-0B04AA sur kicad. Nous nous sommes aussi rendus compte que l'antenne ([https://fr.farnell.com/pulse-electronics/ant3216ll00r2400a/antenne-helix-chip-ceram-433mhz/dp/4125786?st=ANT3216LL00R2400A ANT3216LL00R2400A]) bluetooth était externe au module. Nous attendons alors la livraison.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Le module sera alors ajouté au fichier kicad déja existant modifié (en fonction de ce que l'on compte utiliser).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:ComposantBM71.png|gauche|cadre]]&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== LEDs ==&lt;br /&gt;
[[Fichier:Switch.png|cadre]]&lt;br /&gt;
Comme vu précedemment, nous avons fait le choix d'utiliser huit Leds, deux pour la marche avant, deux pour la marche arrière, deux pour le clignotant gauche et deux pour le clignotant droit.&lt;br /&gt;
Nous avons aussi connecté ces Leds au microcontrôleur.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LEDs.png|gauche|cadre]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LEDs Controleur.png|centré|cadre]]&lt;br /&gt;
&lt;br /&gt;
== En plus de cela nous avons adapter les labels en enlevant ceux qui n'étaient pas nécessaires et en modifiant ceux associés à un sous PCB. Nous avons aussi ajouté un bouton au port RESET. ==&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;
== Footprints et rootage ==&lt;br /&gt;
[[Fichier:Rootage Debut.png|vignette]]&lt;br /&gt;
07/04/23: Placement initial des composants sur la carte, Correction des dernières erreurs au niveau des pads des footprints que nous avons créé.&lt;br /&gt;
&lt;br /&gt;
02/05/23: Carte reçue.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Soudure des composants ==&lt;br /&gt;
ATMega8u2&lt;br /&gt;
&lt;br /&gt;
USB&lt;br /&gt;
&lt;br /&gt;
LEDs&lt;br /&gt;
&lt;br /&gt;
Résistances&lt;br /&gt;
&lt;br /&gt;
Capacités&lt;br /&gt;
&lt;br /&gt;
== Code voiture ==&lt;br /&gt;
[[Fichier:TestLeds.png|vignette]]&lt;br /&gt;
Une fois le test de clignotement des Leds effectué, on passe au code de contrôle de la voiture.&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;
== Moteur et Leds sur carte (Liens) ==&lt;br /&gt;
[[Fichier:Moteur.mp4|gauche|vignette|2x2px|Mot]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:.Leds.mp4|centré|vignette|Leds]]&lt;/div&gt;</summary>
		<author><name>Tnehari</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=Fichier:.Leds.mp4&amp;diff=915</id>
		<title>Fichier:.Leds.mp4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=Fichier:.Leds.mp4&amp;diff=915"/>
		<updated>2023-05-28T20:24:52Z</updated>

		<summary type="html">&lt;p&gt;Tnehari : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Leds&lt;/div&gt;</summary>
		<author><name>Tnehari</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=Fichier:Image_LEds.jpg&amp;diff=914</id>
		<title>Fichier:Image LEds.jpg</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=Fichier:Image_LEds.jpg&amp;diff=914"/>
		<updated>2023-05-28T20:24:33Z</updated>

		<summary type="html">&lt;p&gt;Tnehari : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Leds av ar&lt;/div&gt;</summary>
		<author><name>Tnehari</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=Fichier:Image_moteur.jpg&amp;diff=913</id>
		<title>Fichier:Image moteur.jpg</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=Fichier:Image_moteur.jpg&amp;diff=913"/>
		<updated>2023-05-28T20:12:45Z</updated>

		<summary type="html">&lt;p&gt;Tnehari : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Image moteur&lt;/div&gt;</summary>
		<author><name>Tnehari</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=Fichier:Moteur.mp4&amp;diff=912</id>
		<title>Fichier:Moteur.mp4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=Fichier:Moteur.mp4&amp;diff=912"/>
		<updated>2023-05-28T20:09:45Z</updated>

		<summary type="html">&lt;p&gt;Tnehari : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Propulsion&lt;/div&gt;</summary>
		<author><name>Tnehari</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2022-11&amp;diff=701</id>
		<title>SE3Binome2022-11</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2022-11&amp;diff=701"/>
		<updated>2023-05-16T08:58:20Z</updated>

		<summary type="html">&lt;p&gt;Tnehari : Ajout des parties soudure et code, à compléter&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''&amp;lt;big&amp;gt;Caractéristiques de notre système:&amp;lt;/big&amp;gt;''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Modèle réduit au 1.43&lt;br /&gt;
* Commande Bluetooth via application téléphone (MIT App Inventor) en temps réel:&lt;br /&gt;
** Joystick directionnel&lt;br /&gt;
** Boutons pour les clignotants&lt;br /&gt;
** Bonus : klaxon&lt;br /&gt;
* Module Bluetooth Low Energy&lt;br /&gt;
* Moteur CC avec réductuer + Pilote (DRV8210DRLR) (Propulsion)&lt;br /&gt;
* Moteur glissière pas à pas (Direction)&lt;br /&gt;
* 2 LEDs avant BLANCHES lorsque le véhicule avance&lt;br /&gt;
* 2 LEDs arrière ROUGES lorsque le véhicule recule&lt;br /&gt;
* 4 LEDs JAUNES pour les clignotants&lt;br /&gt;
* Lien du git : https://archives.plil.fr/mchauvel/PSE_tnehari_mchauvel.git&lt;br /&gt;
&lt;br /&gt;
== '''Module Bluetooth Low Energy''' ==&lt;br /&gt;
Après étude de la [https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/Bluetooth-Low-Energy-BLE-Module-DS60001372K.pdf datasheet] (page 15 figure 2-5) nous avons pu recréer le composant BM71BLE01FC2-0B04AA sur kicad. Nous nous sommes aussi rendus compte que l'antenne ([https://fr.farnell.com/pulse-electronics/ant3216ll00r2400a/antenne-helix-chip-ceram-433mhz/dp/4125786?st=ANT3216LL00R2400A ANT3216LL00R2400A]) bluetooth était externe au module. Nous attendons alors la livraison.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Le module sera alors ajouté au fichier kicad déja existant modifié (en fonction de ce que l'on compte utiliser).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:ComposantBM71.png|gauche|cadre]]&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== LEDs ==&lt;br /&gt;
[[Fichier:Switch.png|cadre]]&lt;br /&gt;
Comme vu précedemment, nous avons fait le choix d'utiliser huit Leds, deux pour la marche avant, deux pour la marche arrière, deux pour le clignotant gauche et deux pour le clignotant droit.&lt;br /&gt;
Nous avons aussi connecté ces Leds au microcontrôleur.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LEDs.png|gauche|cadre]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LEDs Controleur.png|centré|cadre]]&lt;br /&gt;
&lt;br /&gt;
== En plus de cela nous avons adapter les labels en enlevant ceux qui n'étaient pas nécessaires et en modifiant ceux associés à un sous PCB. Nous avons aussi ajouté un bouton au port RESET. ==&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;
== Footprints et rootage ==&lt;br /&gt;
[[Fichier:Rootage Debut.png|vignette]]&lt;br /&gt;
07/04/23: Placement initial des composants sur la carte, Correction des dernières erreurs au niveau des pads des footprints que nous avons créé.&lt;br /&gt;
&lt;br /&gt;
02/05/23: Carte reçue.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Soudure des composants ==&lt;br /&gt;
ATMega8u2&lt;br /&gt;
&lt;br /&gt;
USB&lt;br /&gt;
&lt;br /&gt;
LEDs&lt;br /&gt;
&lt;br /&gt;
Résistances&lt;br /&gt;
&lt;br /&gt;
Capacités&lt;br /&gt;
&lt;br /&gt;
== Code voiture ==&lt;br /&gt;
[[Fichier:TestLeds.png|vignette]]&lt;br /&gt;
Une fois le test de clignotement des Leds effectué, on passe au code de cntrôle de la voiture.&lt;/div&gt;</summary>
		<author><name>Tnehari</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=Fichier:TestLeds.png&amp;diff=698</id>
		<title>Fichier:TestLeds.png</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=Fichier:TestLeds.png&amp;diff=698"/>
		<updated>2023-05-16T08:57:32Z</updated>

		<summary type="html">&lt;p&gt;Tnehari : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Clignotement des Leds&lt;/div&gt;</summary>
		<author><name>Tnehari</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE3_PSE_Binome2022-10&amp;diff=585</id>
		<title>SE3 PSE Binome2022-10</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE3_PSE_Binome2022-10&amp;diff=585"/>
		<updated>2023-04-12T14:19:49Z</updated>

		<summary type="html">&lt;p&gt;Tnehari : Ajout vidéo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Lien du git : https://archives.plil.fr/mchauvel/PSE_tnehari_mchauvel.git&lt;br /&gt;
&lt;br /&gt;
Voir vidéo LED clignotante.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:SCHEMATIC.png|vignette|Schematic de notre carte|gauche]][[Fichier:VIEW 3D.png|vignette|gauche|Vue 3D de la carte]][[Fichier:PCB.png|vignette|gauche|Rootage de la carte]]&lt;br /&gt;
[[Fichier:Clignotement des LEDs.png|gauche|vignette|Fonction pour faire clignoter les LEDs]]&amp;lt;gallery&amp;gt;&lt;br /&gt;
Fichier:Led clignotante.mp4|LED clignotante&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;/div&gt;</summary>
		<author><name>Tnehari</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=Fichier:Carte_PSE.jpg&amp;diff=584</id>
		<title>Fichier:Carte PSE.jpg</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=Fichier:Carte_PSE.jpg&amp;diff=584"/>
		<updated>2023-04-12T14:17:20Z</updated>

		<summary type="html">&lt;p&gt;Tnehari : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;LED&lt;/div&gt;</summary>
		<author><name>Tnehari</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=Fichier:Led_clignotante.mp4&amp;diff=583</id>
		<title>Fichier:Led clignotante.mp4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=Fichier:Led_clignotante.mp4&amp;diff=583"/>
		<updated>2023-04-12T14:08:22Z</updated>

		<summary type="html">&lt;p&gt;Tnehari : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Une seule LED clignote, l'autre étant soudée à l'envers.&lt;/div&gt;</summary>
		<author><name>Tnehari</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2022-11&amp;diff=542</id>
		<title>SE3Binome2022-11</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2022-11&amp;diff=542"/>
		<updated>2023-04-11T18:53:41Z</updated>

		<summary type="html">&lt;p&gt;Tnehari : Ajout du lien du git dans lequel se trouve la carte quasiment complétée (il manque UNE connexion au moteur).&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''&amp;lt;big&amp;gt;Caractéristiques de notre système:&amp;lt;/big&amp;gt;''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Modèle réduit au 1.43&lt;br /&gt;
* Commande Bluetooth via application téléphone (MIT App Inventor) en temps réel:&lt;br /&gt;
** Joystick directionnel&lt;br /&gt;
** Boutons pour les clignotants&lt;br /&gt;
** Bonus : klaxon&lt;br /&gt;
* Module Bluetooth Low Energy&lt;br /&gt;
* Moteur CC avec réductuer + Pilote (DRV8210DRLR) (Propulsion)&lt;br /&gt;
* Moteur glissière pas à pas (Direction)&lt;br /&gt;
* 2 LEDs avant BLANCHES lorsque le véhicule avance&lt;br /&gt;
* 2 LEDs arrière ROUGES lorsque le véhicule recule&lt;br /&gt;
* 4 LEDs JAUNES pour les clignotants&lt;br /&gt;
* Lien du git : https://archives.plil.fr/mchauvel/PSE_tnehari_mchauvel.git&lt;br /&gt;
&lt;br /&gt;
== '''Module Bluetooth Low Energy''' ==&lt;br /&gt;
Après étude de la [https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/Bluetooth-Low-Energy-BLE-Module-DS60001372K.pdf datasheet] (page 15 figure 2-5) nous avons pu recréer le composant BM71BLE01FC2-0B04AA sur kicad. Nous nous sommes aussi rendus compte que l'antenne ([https://fr.farnell.com/pulse-electronics/ant3216ll00r2400a/antenne-helix-chip-ceram-433mhz/dp/4125786?st=ANT3216LL00R2400A ANT3216LL00R2400A]) bluetooth était externe au module. Nous attendons alors la livraison.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Le module sera alors ajouté au fichier kicad déja existant modifié (en fonction de ce que l'on compte utiliser).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:ComposantBM71.png|gauche|cadre]]&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== LEDs ==&lt;br /&gt;
[[Fichier:Switch.png|cadre]]&lt;br /&gt;
Comme vu précedemment, nous avons fait le choix d'utiliser huit Leds, deux pour la marche avant, deux pour la marche arrière, deux pour le clignotant gauche et deux pour le clignotant droit.&lt;br /&gt;
Nous avons aussi connecté ces Leds au microcontrôleur.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LEDs.png|gauche|cadre]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LEDs Controleur.png|centré|cadre]]&lt;br /&gt;
&lt;br /&gt;
== En plus de cela nous avons adapter les labels en enlevant ceux qui n'étaient pas nécessaires et en modifiant ceux associés à un sous PCB. Nous avons aussi ajouté un bouton au port RESET. ==&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;
== Footprints et rootage ==&lt;br /&gt;
[[Fichier:Rootage Debut.png|vignette]]&lt;br /&gt;
07/04/23: Placement initial des composants sur la carte, Correction des dernières erreurs au niveau des pads des footprints que nous avons créé.&lt;/div&gt;</summary>
		<author><name>Tnehari</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2022-11&amp;diff=430</id>
		<title>SE3Binome2022-11</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2022-11&amp;diff=430"/>
		<updated>2023-04-07T13:41:30Z</updated>

		<summary type="html">&lt;p&gt;Tnehari : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''&amp;lt;big&amp;gt;Caractéristiques de notre système:&amp;lt;/big&amp;gt;''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Modèle réduit au 1.43&lt;br /&gt;
* Commande Bluetooth via application téléphone (MIT App Inventor) en temps réel:&lt;br /&gt;
** Joystick directionnel&lt;br /&gt;
** Boutons pour les clignotants&lt;br /&gt;
** Bonus : klaxon&lt;br /&gt;
* Module Bluetooth Low Energy&lt;br /&gt;
* Moteur CC avec réductuer + Pilote (DRV8210DRLR) (Propulsion)&lt;br /&gt;
* Moteur glissière pas à pas (Direction)&lt;br /&gt;
* 2 LEDs avant BLANCHES lorsque le véhicule avance&lt;br /&gt;
* 2 LEDs arrière ROUGES lorsque le véhicule recule&lt;br /&gt;
* 4 LEDs JAUNES pour les clignotants&lt;br /&gt;
&lt;br /&gt;
== '''Module Bluetooth Low Energy''' ==&lt;br /&gt;
Après étude de la [https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/Bluetooth-Low-Energy-BLE-Module-DS60001372K.pdf datasheet] (page 15 figure 2-5) nous avons pu recréer le composant BM71BLE01FC2-0B04AA sur kicad. Nous nous sommes aussi rendus compte que l'antenne ([https://fr.farnell.com/pulse-electronics/ant3216ll00r2400a/antenne-helix-chip-ceram-433mhz/dp/4125786?st=ANT3216LL00R2400A ANT3216LL00R2400A]) bluetooth était externe au module. Nous attendons alors la livraison.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Le module sera alors ajouté au fichier kicad déja existant modifié (en fonction de ce que l'on compte utiliser).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:ComposantBM71.png|gauche|cadre]]&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== LEDs ==&lt;br /&gt;
[[Fichier:Switch.png|cadre]]&lt;br /&gt;
Comme vu précedemment, nous avons fait le choix d'utiliser huit Leds, deux pour la marche avant, deux pour la marche arrière, deux pour le clignotant gauche et deux pour le clignotant droit.&lt;br /&gt;
Nous avons aussi connecté ces Leds au microcontrôleur.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LEDs.png|gauche|cadre]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LEDs Controleur.png|centré|cadre]]&lt;br /&gt;
&lt;br /&gt;
== En plus de cela nous avons adapter les labels en enlevant ceux qui n'étaient pas nécessaires et en modifiant ceux associés à un sous PCB. Nous avons aussi ajouté un bouton au port RESET. ==&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;
== Footprints et rootage ==&lt;br /&gt;
[[Fichier:Rootage Debut.png|vignette]]&lt;br /&gt;
07/04/23: Placement initial des composants sur la carte, Correction des dernières erreurs au niveau des pads des footprints que nous avons créé.&lt;/div&gt;</summary>
		<author><name>Tnehari</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=Fichier:Rootage_Debut.png&amp;diff=429</id>
		<title>Fichier:Rootage Debut.png</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=Fichier:Rootage_Debut.png&amp;diff=429"/>
		<updated>2023-04-07T13:39:08Z</updated>

		<summary type="html">&lt;p&gt;Tnehari : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Placement initial des composants (sujet à changement évidemment)&lt;/div&gt;</summary>
		<author><name>Tnehari</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE3_PSE_Binome2022-10&amp;diff=387</id>
		<title>SE3 PSE Binome2022-10</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE3_PSE_Binome2022-10&amp;diff=387"/>
		<updated>2023-04-06T10:21:16Z</updated>

		<summary type="html">&lt;p&gt;Tnehari : Page créée avec « Lien du git : https://archives.plil.fr/mchauvel/PSE_tnehari_mchauvel.git vignettevignette]] »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Lien du git : https://archives.plil.fr/mchauvel/PSE_tnehari_mchauvel.git&lt;br /&gt;
[[Fichier:SCHEMATIC.png|vignette|[[Fichier:VIEW 3D.png|vignette]][[Fichier:PCB.png|vignette]]]]&lt;/div&gt;</summary>
		<author><name>Tnehari</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=Fichier:PCB.png&amp;diff=386</id>
		<title>Fichier:PCB.png</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=Fichier:PCB.png&amp;diff=386"/>
		<updated>2023-04-06T10:21:05Z</updated>

		<summary type="html">&lt;p&gt;Tnehari : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;PCB&lt;/div&gt;</summary>
		<author><name>Tnehari</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=Fichier:VIEW_3D.png&amp;diff=385</id>
		<title>Fichier:VIEW 3D.png</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=Fichier:VIEW_3D.png&amp;diff=385"/>
		<updated>2023-04-06T10:20:32Z</updated>

		<summary type="html">&lt;p&gt;Tnehari : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;VIEW3D&lt;/div&gt;</summary>
		<author><name>Tnehari</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=Fichier:SCHEMATIC.png&amp;diff=384</id>
		<title>Fichier:SCHEMATIC.png</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=Fichier:SCHEMATIC.png&amp;diff=384"/>
		<updated>2023-04-06T10:19:35Z</updated>

		<summary type="html">&lt;p&gt;Tnehari : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;SCHEMATIC&lt;/div&gt;</summary>
		<author><name>Tnehari</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=PSE_SE3_2022/2023&amp;diff=380</id>
		<title>PSE SE3 2022/2023</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=PSE_SE3_2022/2023&amp;diff=380"/>
		<updated>2023-04-06T10:08:10Z</updated>

		<summary type="html">&lt;p&gt;Tnehari : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Objectif =&lt;br /&gt;
&lt;br /&gt;
Pour l'année académique 2022/2023 il demandé de motoriser un modèle réduit de voiture au 1:87ème ou au 1:43ème avec contrôle par microcontrôleur.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:modele-voiture-1-87.jpg|Modéle réduit au 1:87&lt;br /&gt;
File:modele-voiture-1-43.jpg|Modéle réduit au 1:43&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Votre objectif est de concevoir votre propre modèle à l'aide des éléments présentés dans cette page. Vous ne devez pas forcément fusionner l'ensemble&lt;br /&gt;
des possibilités, d'ailleurs certaines sont incompatibles entre elles. Partir sur quelque chose de simple n'est pas infamant du moment qu'il est proprement exécuté et qu'il débouche sur un prototype fonctionnel.&lt;br /&gt;
&lt;br /&gt;
Certes si vous nous sortez une voiture au 1:87ème totalement fonctionnelle avec propulsion, roues avant directionnelles, chargeur de batterie intégré et contrôle radio nous serons enchantés et nous aurons assez peu de difficulté à vous noter. Maintenant si vous partez sur un simple chassis au 1:43ème avec propulsion utilisant de simples poulies, roue folle permettant des reculs avec virage (axe de roue non fixe) et contrôle par programmation, vous aurez rempli le contrat.&lt;br /&gt;
&lt;br /&gt;
= Mécanique =&lt;br /&gt;
&lt;br /&gt;
La partie mécanique n'est pas évaluée dans ce projet car elle est hors-sujet pour la filière. Par contre, une démonstration avec une voiture mobile est un excellent moyen de prouver que votre projet fonctionne.&lt;br /&gt;
&lt;br /&gt;
[[file:2022-chassis.png|thumb|400px|right|Image du chassis]]&lt;br /&gt;
&lt;br /&gt;
Pour vous aider nous avons modélisé un chassis avec roues avant directionnelles.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
file:2022-chassis-dessus.pdf|Chassis vu de dessus&lt;br /&gt;
file:2022-chassis-dessous.pdf|Chassis vu de dessous&lt;br /&gt;
file:2022-chassis-cote-1.pdf|Chassis vu de coté&lt;br /&gt;
file:2022-chassis-cote-2.pdf|Chassis vu d'un autre coté&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le fichier &amp;lt;code&amp;gt;freeCAD&amp;lt;/code&amp;gt; du chassis [[file:chassis-2022.tar]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear: both;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Seconde version de chassis.&lt;br /&gt;
&lt;br /&gt;
[[file:2022-chassis2.png|thumb|400px|right|Image du chassis]]&lt;br /&gt;
&lt;br /&gt;
Pour vous aider nous avons modélisé un chassis avec roues avant directionnelles.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
file:2022-chassis2-dessus.pdf|Chassis vu de dessus&lt;br /&gt;
file:2022-chassis2-dessous.pdf|Chassis vu de dessous&lt;br /&gt;
file:2022-chassis2-cote-1.pdf|Chassis vu de coté&lt;br /&gt;
file:2022-chassis2-cote-2.pdf|Chassis vu d'un autre coté&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le fichier &amp;lt;code&amp;gt;freeCAD&amp;lt;/code&amp;gt; du chassis [[file:chassis2-2022.tar]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear: both;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[file:2022-roue_folle.png|thumb|200px|right|Image de la roue]]&lt;br /&gt;
&lt;br /&gt;
Vous avez aussi un modèle de principe pour une roue folle avec recul en virant.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
file:2022-roue-folle.pdf|Roue en 3D&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le fichier &amp;lt;code&amp;gt;freeCAD&amp;lt;/code&amp;gt; de la roue [[file:roue-folle-2022.tar]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear: both;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Au niveau accessoires vous pouvez, ou pourrez, disposer des éléments suivants :&lt;br /&gt;
* engrenages métal pour axe 0.7mm, disponibles et semblent s'adapter aux micro-moteurs simples ;&lt;br /&gt;
* vis sans fin métal pour axe de 1mm (diamètre extérieur 3,8mm), disponibles, prévues pour l'axe des voitures 1:87 ;&lt;br /&gt;
* vis sans fil plastique pour axe 2mm, disponibles mais s'adaptent mal aux axes des voitures 1:43 ;&lt;br /&gt;
* vis sans fil plastique pour axe &amp;lt;2mm, disponibles, prévues pour l'axe des voitures 1:43 ;&lt;br /&gt;
* engrenages plastiques pour axe de 3mm, disponibles, pour les moteurs continus.&lt;br /&gt;
&lt;br /&gt;
= Moteurs =&lt;br /&gt;
&lt;br /&gt;
La commande des moteurs n'est pas, elle, optionnelle.&lt;br /&gt;
&lt;br /&gt;
Plusieurs types de moteurs sont disponibles.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:micro-moteur-pas-a-pas-simple.jpg|Micro-moteur pas à pas propulsion&lt;br /&gt;
File:micro-moteur-pas-a-pas-simple-dims.jpg|Dimensions du micro-moteur propulsion&lt;br /&gt;
File:micro-glissiere-pas-a-pas.jpg|Micro-moteur glissière pas à pas&lt;br /&gt;
File:micro-glissiere-pas-a-pas-dimensions.jpg|Dimensions du micro-moteur glissière&lt;br /&gt;
File:micro-glissiere-pas-a-pas-connecteurs.jpg|Connecteurs du micro-moteur glissière&lt;br /&gt;
File:mini-motoreducteur.jpg|Mini-moteur continu avec réducteur&lt;br /&gt;
File:pilote-motoreducteur.jpg|Pilote pour le mini-moteur continu (DRV8210DRLR)&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[file:2022-banc-essai-micro-moteurs.jpg|thumb|250px|right|Banc d'essai des micro-moteurs]]&lt;br /&gt;
&lt;br /&gt;
Ressources pour les moteurs :&lt;br /&gt;
* les micro-moteurs peuvent éventuellement fonctionner sans pilote (alimentation directe par le microcontrôleur), il reste à vérifier que le couple obtenu suffit et que l'utilisation de plusieurs périphériques n'effondre pas le microcontrôleur ;&lt;br /&gt;
* empreintes approximatives pour les microcontrôleurs (à peaufiner) : [[file:KiCAD-lib-micro-motors.tar]] ;&lt;br /&gt;
* premier jet du PCB de coté pour le micro-moteur glissière : [[file:KiCAD-slider-side-2022.tar]] ;&lt;br /&gt;
* programme C pour les micro-moteurs pas à pas sans pilote (vidéo de démonstration ci-dessous) : [[Média:Programme_moteur_pap.tar]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear: both;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[file:2022-demo-micro-moteur.mp4|500px|left|Vidéo pour le micro-moteur]]&lt;br /&gt;
[[file:2022-demo-micro-slider.mp4|500px|right|Vidéo pour le micro-moteur glissière]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear: both;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Cartes électroniques =&lt;br /&gt;
&lt;br /&gt;
Vous devez concevoir une carte électronique pour contrôler la voiture. La conception doit se faire en utilisant le logiciel KiCAD.&lt;br /&gt;
&lt;br /&gt;
Il est recommandé de reporter au maximum les fonctions mécaniques sur la carte. Le chassis peut ainsi être entièrement constitué de PCB, y compris les pièces mobiles.&lt;br /&gt;
&lt;br /&gt;
Nous vous donnons deux exemples de schémas électroniques.&lt;br /&gt;
&lt;br /&gt;
== Exemple de carte pour la voiture au 1:87 ==&lt;br /&gt;
&lt;br /&gt;
Le schéma électronique de la carte :&lt;br /&gt;
[[file:2022-schema-voiture-rex.pdf|thumb|400px|center|Schéma pour une voiture 1:87]]&lt;br /&gt;
Dans le schéma vous pouvez trouver les fonctionnalités suivantes :&lt;br /&gt;
* une alimentation avec un régulateur pour passer du 5V USB à une tension de 3.3V mais aussi avec un dispositif pour sélectionner une alimentation par USB ou par batterie ;&lt;br /&gt;
* le microcontrôleur avec son horloge mais aussi son connecteur de programmation ISP et le connecteur USB ;&lt;br /&gt;
* un dispositif de recharge de la batterie LiPo avec une entrée pour tester la tension de la batterie (sur une entrée numérique donc avec peu de sensibilité) ;&lt;br /&gt;
* deux moteurs pas à pas et un système d'éclairage ;&lt;br /&gt;
* enfin un module de communication radio.&lt;br /&gt;
&lt;br /&gt;
Après le routage les cartes suivantes sont obtenues.&lt;br /&gt;
[[file:2022-PCB-voiture-rex.pdf|thumb|400px|center|Cartes pour une voiture 1:87]]&lt;br /&gt;
&lt;br /&gt;
Un total de 8 cartes sont prévues :&lt;br /&gt;
* principalement la carte chassis sur laquelle sont implantés les puces microcontrôleur, charge de LiPo et communication radio ;&lt;br /&gt;
* le moteur-glissière nécessite une micro-carte de côté pour récupérer les phases ; &lt;br /&gt;
* tous les composants ne tiennent pas sur le chassis 50x20mm, une carte fille est donc prévue pour porter l'éclairage, l'antenne radio et même des pistes supplémentaires ;&lt;br /&gt;
* 3 petites cartes sont dédiées pour recevoir les roues : deux pour les roues directionnelles et une pour le train arrière, sur ces cartes doivent êtres soudés des morceaux de tube de cuivre recevant les axes ;&lt;br /&gt;
* toujours sur le principe que la carte principale ne permet pas de recevoir tous les éléments, une carte fille permet de connecter l'ISP et une autre l'USB.&lt;br /&gt;
&lt;br /&gt;
Les cartes ont été commandées. En aucun cas il est prévu que ces cartes fonctionnent dans leur version initiale. C'est d'ailleurs la démarche &amp;quot;bureau d'études&amp;quot; que nous souhaitons que vous assimiliez. Ces cartes vont permettre d'avancer dans le projet pour éventuellement aboutir sur une seconde version des cartes. Ci-dessous sont listés les points que les premières cartes vont permettre d'éclaircir.&lt;br /&gt;
* Le microcontrôleur devrait fonctionner mais le principe des cartes filles pour la programmation ISP et DFU/USB est à valider.&lt;br /&gt;
* Il y a peu de chances pour que les empreintes pour les micro-moteurs pas à pas soient exactes mais ce devrait être une bonne base pour aboutir à une seconde version fonctionnelle.&lt;br /&gt;
* L'aspect mécanique est aussi à tester et à corriger : les roues directionnelles fonctionnent-elles ? quels problèmes sont rencontrés pour la transmission de la propulsion via l'engrenage et la vis sans fin.&lt;br /&gt;
* Le dispositif d'alimentation par USB ou par batterie est-il fonctionnel ? Le test de tension de la batterie donne-t-il quelque chose ? La recharge de la batterie par le MAX1811 marche-t-elle ?&lt;br /&gt;
* La transmission radio est-elle fonctionnelle ? En particulier les libertés prises au niveau de l'antenne sur PCB dégradent-elles beaucoup cette transmission ?&lt;br /&gt;
&lt;br /&gt;
Les sources pour le logiciel KiCAD version 5.1 : [[Média:2022-voiture-kicad-rex.tgz|Fichiers KiCAD pour la voiture 1:87]].&lt;br /&gt;
&lt;br /&gt;
Uniquement les sources pour les empreintes des moteurs pas à pas (modifiées) : [[Média:Rex-motors.zip|Empreintes KiCAD pour les moteurs pas à pas]].&lt;br /&gt;
&lt;br /&gt;
== Exemple de carte pour la voiture au 1:43 ==&lt;br /&gt;
&lt;br /&gt;
[[file:2022-schema-voiture-boe.pdf|thumb|400px|right|Schéma pour une voiture 1:43]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear: both;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Le microcontrôleur ==&lt;br /&gt;
&lt;br /&gt;
Vous utiliserez un microcontrôleur ATMega16u2 comme coeur de votre circuit imprimé. Prenez exemple sur la partie microcontrôleur des schémas fournis.&lt;br /&gt;
&lt;br /&gt;
La programmation du microcontrôleur se fera par DFU USB.&lt;br /&gt;
&lt;br /&gt;
== Energie ==&lt;br /&gt;
&lt;br /&gt;
La carte électronique de votre voiture est alimentée par une batterie LiPo. La batterie peut être chargée en utilisant une puce MAX1811. Voir les schémas fournis pour avoir une idée de commencer utiliser une puce MAX1811.&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;
Les connecteurs adaptés aux batteries FQ777 ont aussi été commandés (micro JST 2 broches 1.25mm).&lt;br /&gt;
&lt;br /&gt;
== Eclairage ==&lt;br /&gt;
&lt;br /&gt;
Vous pouvez vous lâcher sur les LED pour simuler les dispositifs lumineux de votre voiture. Attention cependant votre micro-contrôleur n'a qu'un nombre limité de sorties.&lt;br /&gt;
&lt;br /&gt;
== Contrôle de la voiture ==&lt;br /&gt;
&lt;br /&gt;
=== Contrôle par programmation ===&lt;br /&gt;
&lt;br /&gt;
Il est recommandé d'utiliser la fonctionnalité USB pour pouvoir programmer le comportement de la voiture. A défaut une programmation par port série est acceptable. Le programme PC permettant d'envoyer la suite d'instructions que la voiture doit réaliser est aussi à votre charge.&lt;br /&gt;
&lt;br /&gt;
=== Radio-contrôle ===&lt;br /&gt;
&lt;br /&gt;
Vous avez deux possibilités pour la commande à distance de votre voiture, soit une communication radio classique, soit une communication BlueTooth.&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:module_BLE.jpg|Module Bluetooth Low Energy&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Les modules RF 2,4Ghz utilisent une puce NRF24L01, ces modules étant un peu encombrants, quelques puces ont été commandées pour intégration directe sur le PCB (disponibilité fin février). Vous avez un exemple d'utilisation sur le premier schéma de carte fourni plus haut. Les puces NRF24L01 doivent être alimentées en 3,3V mais ses E/S sont compatibles 5V. Il n'est donc pas obligatoire de passer l'ATMega16u2 en 3,3V.&lt;br /&gt;
&lt;br /&gt;
= Réalisation des groupes =&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;
| Trinôme 1&lt;br /&gt;
| Sarra BEZZINE &amp;amp; Heriniaina ANDRIANIRINTSOA &amp;amp; Imen MLIKA&lt;br /&gt;
| [[SE3Binome2022-1|Trinôme 1 2022/2023]]&lt;br /&gt;
|-&lt;br /&gt;
| Trinôme 2&lt;br /&gt;
| Younes BENMBAREK &amp;amp; Camille CARIAT &amp;amp; Abdel ZONGO&lt;br /&gt;
| [[SE3Trinome2022-2|Trinôme 2 2022/2023]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 3&lt;br /&gt;
| Simon CRUCHET &amp;amp; Amaury BECQUET&lt;br /&gt;
| [[SE3Binome2022-3|Binôme 3 2022/2023]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 4&lt;br /&gt;
| Romain DUHR &amp;amp; Louis DERYCKERE&lt;br /&gt;
| [[SE3Binome2022-4|Binôme 4 2022/2023]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 5&lt;br /&gt;
| Youness EL QASTALANI &amp;amp; Chaymae Rhanim&lt;br /&gt;
| [[SE3Binome2022-5|Binôme 5 2022/2023]]&lt;br /&gt;
|-&lt;br /&gt;
| Trinôme 6&lt;br /&gt;
| Stephane KADER ISSACK &amp;amp; Marion NORMAND &amp;amp; Amaury DA PONTE&lt;br /&gt;
| [[SE3Trinome2022-6|Trinôme 6 2022/2023]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 7&lt;br /&gt;
| Alexandre BRASSEUR &amp;amp; Louis WIJSMAN&lt;br /&gt;
| [[SE3Binome2022-7|Binôme 7 2022/2023]]&lt;br /&gt;
|-&lt;br /&gt;
| Trinôme 8&lt;br /&gt;
| Némo CAZIN &amp;amp; Antoine CEGARRA &amp;amp; Adrien PALIFERRO&lt;br /&gt;
| [[SE3Trinome2022-8|Trinôme 8 2022/2023]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 9&lt;br /&gt;
| Thomas NAVE &amp;amp; Thibault DUYCK&lt;br /&gt;
| [[SE3Binome2022-9|Binôme 9 2022/2023]]&lt;br /&gt;
|-&lt;br /&gt;
| Monôme 10&lt;br /&gt;
| Adrien GONTIER&lt;br /&gt;
| [[SE3Monome2022-10|Monôme 10 2022/2023]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 11&lt;br /&gt;
| Taha NEHARI &amp;amp; Martin CHAUVELIERE &lt;br /&gt;
| [[SE3Binome2022-11|Binôme 11 2022/2023]]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
Absents :&lt;br /&gt;
* Imen MLIKA&lt;br /&gt;
* Ababacar sadikh NDOYE&lt;br /&gt;
&lt;br /&gt;
= Réalisation &amp;quot;programmateur AVR&amp;quot; =&lt;br /&gt;
&lt;br /&gt;
Utilisez ces pages pour :&lt;br /&gt;
* indiquer l'URL HTTPS de votre archive GIT sur laquelle trouver le projet KiCAD et les programmes C (LUFA et libusb) ;&lt;br /&gt;
* un schéma 3D de votre PCB ;&lt;br /&gt;
* une photo de la carte soudée ;&lt;br /&gt;
* une très courte vidéo de la carte avec les LED clignotantes ;&lt;br /&gt;
* une copie écran montrant l'affichage de la communication entre votre programme libusb, votre carte et le microcontrôleur AVR.&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;
| Simon CRUCHET &amp;amp; Amaury BECQUET &lt;br /&gt;
| [[SE3_PSE_Binome2022-1|Binôme 1 2022/2023]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 2&lt;br /&gt;
| Romain DUHR &amp;amp; Louis DERYCKÈRE&lt;br /&gt;
| [[SE3_PSE_Binome2022-2|Binôme 2 2022/2023]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 3&lt;br /&gt;
| Chaymae RHANIM &amp;amp; Heriniaina ANDRIANIRINTSOA&lt;br /&gt;
| [[SE3_PSE_Binome2022-3|Binôme 3 2022/2023]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 4&lt;br /&gt;
| Stéphane Kader Issack &amp;amp; Marion Normand&lt;br /&gt;
| [[SE3_PSE_Binome2022-4|Binôme 4 2022/2023]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 5&lt;br /&gt;
| Thomas NAVE &amp;amp; Thibault DUYCK&lt;br /&gt;
| [[SE3_PSE_Binome2022-5|Binôme 5 2022/2023]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 6&lt;br /&gt;
| Amaury Da Ponte&lt;br /&gt;
| [[SE3_PSE_Binome2022-6|Binôme 6 2022/2023]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 7&lt;br /&gt;
| Sarra Bezzine &amp;amp; Imen MLika&lt;br /&gt;
| [[SE3_PSE_Binome2022-7|Binôme 7 2022/2023]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 8&lt;br /&gt;
| Némo CAZIN &amp;amp; Antoine CEGARRA&lt;br /&gt;
| [[SE3_PSE_Binome2022-8|Binôme 8 2022/2023]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 9&lt;br /&gt;
| Alexandre BRASSEUR &amp;amp; Louis WIJSMAN&lt;br /&gt;
| [[SE3_PSE_Binome2022-9|Binôme 9 2022/2023]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 10&lt;br /&gt;
| Taha NEHARI &amp;amp; Martin CHAUVELIERE&lt;br /&gt;
| [[SE3_PSE_Binnome2022-10|Binôme 10 2022/2023]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 11&lt;br /&gt;
| Prénom Nom &amp;amp; Prénom Nom &lt;br /&gt;
| [[SE3_PSE_Binome2022-11|Binôme 11 2022/2023]]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Tnehari</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2022-11&amp;diff=284</id>
		<title>SE3Binome2022-11</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2022-11&amp;diff=284"/>
		<updated>2023-03-14T14:39:07Z</updated>

		<summary type="html">&lt;p&gt;Tnehari : /* Switch */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''&amp;lt;big&amp;gt;Caractéristiques de notre système:&amp;lt;/big&amp;gt;''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Modèle réduit au 1.43&lt;br /&gt;
* Commande Bluetooth via application téléphone (MIT App Inventor) en temps réel:&lt;br /&gt;
** Joystick directionnel&lt;br /&gt;
** Boutons pour les clignotants&lt;br /&gt;
** Bonus : klaxon&lt;br /&gt;
* Module Bluetooth Low Energy&lt;br /&gt;
* Moteur CC avec réductuer + Pilote (DRV8210DRLR) (Propulsion)&lt;br /&gt;
* Moteur glissière pas à pas (Direction)&lt;br /&gt;
* 2 LEDs avant BLANCHES lorsque le véhicule avance&lt;br /&gt;
* 2 LEDs arrière ROUGES lorsque le véhicule recule&lt;br /&gt;
* 4 LEDs JAUNES pour les clignotants&lt;br /&gt;
&lt;br /&gt;
== '''Module Bluetooth Low Energy''' ==&lt;br /&gt;
Après étude de la [https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/Bluetooth-Low-Energy-BLE-Module-DS60001372K.pdf datasheet] (page 15 figure 2-5) nous avons pu recréer le composant BM71BLE01FC2-0B04AA sur kicad. Nous nous sommes aussi rendus compte que l'antenne ([https://fr.farnell.com/pulse-electronics/ant3216ll00r2400a/antenne-helix-chip-ceram-433mhz/dp/4125786?st=ANT3216LL00R2400A ANT3216LL00R2400A]) bluetooth était externe au module. Nous attendons alors la livraison.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Le module sera alors ajouté au fichier kicad déja existant modifié (en fonction de ce que l'on compte utiliser).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:ComposantBM71.png|gauche|cadre]]&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== LEDs ==&lt;br /&gt;
[[Fichier:Switch.png|cadre]]&lt;br /&gt;
Comme vu précedemment, nous avons fait le choix d'utiliser huit Leds, deux pour la marche avant, deux pour la marche arrière, deux pour le clignotant gauche et deux pour le clignotant droit.&lt;br /&gt;
Nous avons aussi connecté ces Leds au microcontrôleur.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LEDs.png|gauche|cadre]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LEDs Controleur.png|centré|cadre]]En plus de cela nous avons adapter les labels en enlevant ceux qui n'étaient pas nécessaires et en modifiant ceux associés à un sous PCB. Nous avons aussi ajouté un bouton au port RESET.&lt;/div&gt;</summary>
		<author><name>Tnehari</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=Fichier:Switch.png&amp;diff=281</id>
		<title>Fichier:Switch.png</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=Fichier:Switch.png&amp;diff=281"/>
		<updated>2023-03-14T14:37:35Z</updated>

		<summary type="html">&lt;p&gt;Tnehari : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Switch&lt;/div&gt;</summary>
		<author><name>Tnehari</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2022-11&amp;diff=280</id>
		<title>SE3Binome2022-11</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2022-11&amp;diff=280"/>
		<updated>2023-03-14T14:37:15Z</updated>

		<summary type="html">&lt;p&gt;Tnehari : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''&amp;lt;big&amp;gt;Caractéristiques de notre système:&amp;lt;/big&amp;gt;''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Modèle réduit au 1.43&lt;br /&gt;
* Commande Bluetooth via application téléphone (MIT App Inventor) en temps réel:&lt;br /&gt;
** Joystick directionnel&lt;br /&gt;
** Boutons pour les clignotants&lt;br /&gt;
** Bonus : klaxon&lt;br /&gt;
* Module Bluetooth Low Energy&lt;br /&gt;
* Moteur CC avec réductuer + Pilote (DRV8210DRLR) (Propulsion)&lt;br /&gt;
* Moteur glissière pas à pas (Direction)&lt;br /&gt;
* 2 LEDs avant BLANCHES lorsque le véhicule avance&lt;br /&gt;
* 2 LEDs arrière ROUGES lorsque le véhicule recule&lt;br /&gt;
* 4 LEDs JAUNES pour les clignotants&lt;br /&gt;
&lt;br /&gt;
== '''Module Bluetooth Low Energy''' ==&lt;br /&gt;
Après étude de la [https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/Bluetooth-Low-Energy-BLE-Module-DS60001372K.pdf datasheet] (page 15 figure 2-5) nous avons pu recréer le composant BM71BLE01FC2-0B04AA sur kicad. Nous nous sommes aussi rendus compte que l'antenne ([https://fr.farnell.com/pulse-electronics/ant3216ll00r2400a/antenne-helix-chip-ceram-433mhz/dp/4125786?st=ANT3216LL00R2400A ANT3216LL00R2400A]) bluetooth était externe au module. Nous attendons alors la livraison.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Le module sera alors ajouté au fichier kicad déja existant modifié (en fonction de ce que l'on compte utiliser).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:ComposantBM71.png|gauche|cadre]]&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== LEDs ==&lt;br /&gt;
Comme vu précedemment, nous avons fait le choix d'utiliser huit Leds, deux pour la marche avant, deux pour la marche arrière, deux pour le clignotant gauche et deux pour le clignotant droit.&lt;br /&gt;
Nous avons aussi connecté ces Leds au microcontrôleur.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LEDs.png|gauche|cadre]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LEDs Controleur.png|centré|cadre]]En plus de cela nous avons adapter les labels en enlevant ceux qui n'étaient pas nécessaires et en modifiant ceux associés à un sous PCB. Nous avons aussi ajouté un bouton au port RESET.&lt;/div&gt;</summary>
		<author><name>Tnehari</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2022-11&amp;diff=277</id>
		<title>SE3Binome2022-11</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2022-11&amp;diff=277"/>
		<updated>2023-03-14T14:36:22Z</updated>

		<summary type="html">&lt;p&gt;Tnehari : /* LEDs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''&amp;lt;big&amp;gt;Caractéristiques de notre système:&amp;lt;/big&amp;gt;''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Modèle réduit au 1.43&lt;br /&gt;
* Commande Bluetooth via application téléphone (MIT App Inventor) en temps réel:&lt;br /&gt;
** Joystick directionnel&lt;br /&gt;
** Boutons pour les clignotants&lt;br /&gt;
** Bonus : klaxon&lt;br /&gt;
* Module Bluetooth Low Energy&lt;br /&gt;
* Moteur CC avec réductuer + Pilote (DRV8210DRLR) (Propulsion)&lt;br /&gt;
* Moteur glissière pas à pas (Direction)&lt;br /&gt;
* 2 LEDs avant BLANCHES lorsque le véhicule avance&lt;br /&gt;
* 2 LEDs arrière ROUGES lorsque le véhicule recule&lt;br /&gt;
* 4 LEDs JAUNES pour les clignotants&lt;br /&gt;
&lt;br /&gt;
== '''Module Bluetooth Low Energy''' ==&lt;br /&gt;
Après étude de la [https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/Bluetooth-Low-Energy-BLE-Module-DS60001372K.pdf datasheet] (page 15 figure 2-5) nous avons pu recréer le composant BM71BLE01FC2-0B04AA sur kicad. Nous nous sommes aussi rendus compte que l'antenne ([https://fr.farnell.com/pulse-electronics/ant3216ll00r2400a/antenne-helix-chip-ceram-433mhz/dp/4125786?st=ANT3216LL00R2400A ANT3216LL00R2400A]) bluetooth était externe au module. Nous attendons alors la livraison.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Le module sera alors ajouté au fichier kicad déja existant modifié (en fonction de ce que l'on compte utiliser).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:ComposantBM71.png|gauche|cadre]]&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== LEDs ==&lt;br /&gt;
Comme vu précedemment, nous avons fait le choix d'utiliser huit Leds, deux pour la marche avant, deux pour la marche arrière, deux pour le clignotant gauche et deux pour le clignotant droit.&lt;br /&gt;
Nous avons aussi connecté ces Leds au microcontrôleur.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LEDs.png|gauche|cadre]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LEDs Controleur.png|centré|cadre]]En plus de cela nous avons adapter les labels en enlevant ceux qui n'étaient pas nécessaires et en modifiant ceux associés à un sous PCB.&lt;/div&gt;</summary>
		<author><name>Tnehari</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2022-11&amp;diff=274</id>
		<title>SE3Binome2022-11</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2022-11&amp;diff=274"/>
		<updated>2023-03-14T14:34:33Z</updated>

		<summary type="html">&lt;p&gt;Tnehari : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''&amp;lt;big&amp;gt;Caractéristiques de notre système:&amp;lt;/big&amp;gt;''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Modèle réduit au 1.43&lt;br /&gt;
* Commande Bluetooth via application téléphone (MIT App Inventor) en temps réel:&lt;br /&gt;
** Joystick directionnel&lt;br /&gt;
** Boutons pour les clignotants&lt;br /&gt;
** Bonus : klaxon&lt;br /&gt;
* Module Bluetooth Low Energy&lt;br /&gt;
* Moteur CC avec réductuer + Pilote (DRV8210DRLR) (Propulsion)&lt;br /&gt;
* Moteur glissière pas à pas (Direction)&lt;br /&gt;
* 2 LEDs avant BLANCHES lorsque le véhicule avance&lt;br /&gt;
* 2 LEDs arrière ROUGES lorsque le véhicule recule&lt;br /&gt;
* 4 LEDs JAUNES pour les clignotants&lt;br /&gt;
&lt;br /&gt;
== '''Module Bluetooth Low Energy''' ==&lt;br /&gt;
Après étude de la [https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/Bluetooth-Low-Energy-BLE-Module-DS60001372K.pdf datasheet] (page 15 figure 2-5) nous avons pu recréer le composant BM71BLE01FC2-0B04AA sur kicad. Nous nous sommes aussi rendus compte que l'antenne ([https://fr.farnell.com/pulse-electronics/ant3216ll00r2400a/antenne-helix-chip-ceram-433mhz/dp/4125786?st=ANT3216LL00R2400A ANT3216LL00R2400A]) bluetooth était externe au module. Nous attendons alors la livraison.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Le module sera alors ajouté au fichier kicad déja existant modifié (en fonction de ce que l'on compte utiliser).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:ComposantBM71.png|gauche|cadre]]&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== LEDs ==&lt;br /&gt;
Comme vu précedemment, nous avons fait le choix d'utiliser huit Leds, deux pour la marche avant, deux pour la marche arrière, deux pour le clignotant gauche et deux pour le clignotant droit.&lt;br /&gt;
Nous avons aussi connecté ces Leds au microcontrôleur.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LEDs.png|gauche|cadre]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LEDs Controleur.png|centré|cadre]]&lt;/div&gt;</summary>
		<author><name>Tnehari</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2022-11&amp;diff=273</id>
		<title>SE3Binome2022-11</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2022-11&amp;diff=273"/>
		<updated>2023-03-14T14:34:03Z</updated>

		<summary type="html">&lt;p&gt;Tnehari : /* LEDs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''&amp;lt;big&amp;gt;Caractéristiques de notre système:&amp;lt;/big&amp;gt;''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Modèle réduit au 1.43&lt;br /&gt;
* Commande Bluetooth via application téléphone (MIT App Inventor) en temps réel:&lt;br /&gt;
** Joystick directionnel&lt;br /&gt;
** Boutons pour les clignotants&lt;br /&gt;
** Bonus : klaxon&lt;br /&gt;
* Module Bluetooth Low Energy&lt;br /&gt;
* Moteur CC avec réductuer + Pilote (DRV8210DRLR) (Propulsion)&lt;br /&gt;
* Moteur glissière pas à pas (Direction)&lt;br /&gt;
* 2 LEDs avant BLANCHES lorsque le véhicule avance&lt;br /&gt;
* 2 LEDs arrière ROUGES lorsque le véhicule recule&lt;br /&gt;
* 4 LEDs JAUNES pour les clignotants&lt;br /&gt;
&lt;br /&gt;
== '''Module Bluetooth Low Energy''' ==&lt;br /&gt;
Après étude de la [https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/Bluetooth-Low-Energy-BLE-Module-DS60001372K.pdf datasheet] (page 15 figure 2-5) nous avons pu recréer le composant BM71BLE01FC2-0B04AA sur kicad. Nous nous sommes aussi rendus compte que l'antenne ([https://fr.farnell.com/pulse-electronics/ant3216ll00r2400a/antenne-helix-chip-ceram-433mhz/dp/4125786?st=ANT3216LL00R2400A ANT3216LL00R2400A]) bluetooth était externe au module. Nous attendons alors la livraison.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Le module sera alors ajouté au fichier kicad déja existant modifié (en fonction de ce que l'on compte utiliser).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:ComposantBM71.png|gauche|cadre]]&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;
&lt;br /&gt;
&lt;br /&gt;
== LEDs ==&lt;br /&gt;
Comme vu précedemment, nous avons fait le choix d'utiliser huit Leds, deux pour la marche avant, deux pour la marche arrière, deux pour le clignotant gauche et deux pour le clignotant droit.&lt;br /&gt;
Nous avons aussi connecté ces Leds au microcontrôleur.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LEDs.png|gauche|cadre]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LEDs Controleur.png|centré|cadre]]&lt;/div&gt;</summary>
		<author><name>Tnehari</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2022-11&amp;diff=270</id>
		<title>SE3Binome2022-11</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2022-11&amp;diff=270"/>
		<updated>2023-03-14T14:30:57Z</updated>

		<summary type="html">&lt;p&gt;Tnehari : /* LEDs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''&amp;lt;big&amp;gt;Caractéristiques de notre système:&amp;lt;/big&amp;gt;''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Modèle réduit au 1.43&lt;br /&gt;
* Commande Bluetooth via application téléphone (MIT App Inventor) en temps réel:&lt;br /&gt;
** Joystick directionnel&lt;br /&gt;
** Boutons pour les clignotants&lt;br /&gt;
** Bonus : klaxon&lt;br /&gt;
* Module Bluetooth Low Energy&lt;br /&gt;
* Moteur CC avec réductuer + Pilote (DRV8210DRLR) (Propulsion)&lt;br /&gt;
* Moteur glissière pas à pas (Direction)&lt;br /&gt;
* 2 LEDs avant BLANCHES lorsque le véhicule avance&lt;br /&gt;
* 2 LEDs arrière ROUGES lorsque le véhicule recule&lt;br /&gt;
* 4 LEDs JAUNES pour les clignotants&lt;br /&gt;
&lt;br /&gt;
== '''Module Bluetooth Low Energy''' ==&lt;br /&gt;
Après étude de la [https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/Bluetooth-Low-Energy-BLE-Module-DS60001372K.pdf datasheet] (page 15 figure 2-5) nous avons pu recréer le composant BM71BLE01FC2-0B04AA sur kicad. Nous nous sommes aussi rendus compte que l'antenne ([https://fr.farnell.com/pulse-electronics/ant3216ll00r2400a/antenne-helix-chip-ceram-433mhz/dp/4125786?st=ANT3216LL00R2400A ANT3216LL00R2400A]) bluetooth était externe au module. Nous attendons alors la livraison.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Le module sera alors ajouté au fichier kicad déja existant modifié (en fonction de ce que l'on compte utiliser).&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;
&lt;br /&gt;
== LEDs ==&lt;br /&gt;
[[Fichier:LEDs Controleur.png|centré|vignette]]&lt;br /&gt;
Comme vu précedemment, nous avons fait le choix d'utiliser huit Leds, deux pour la marche avant, deux pour la marche arrière, deux pour le clignotant gauche et deux pour le clignotant droit.&lt;br /&gt;
Nous avons aussi connecté ces Leds au microcontrôleur.&lt;/div&gt;</summary>
		<author><name>Tnehari</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2022-11&amp;diff=269</id>
		<title>SE3Binome2022-11</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2022-11&amp;diff=269"/>
		<updated>2023-03-14T14:30:14Z</updated>

		<summary type="html">&lt;p&gt;Tnehari : /* LEDs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''&amp;lt;big&amp;gt;Caractéristiques de notre système:&amp;lt;/big&amp;gt;''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Modèle réduit au 1.43&lt;br /&gt;
* Commande Bluetooth via application téléphone (MIT App Inventor) en temps réel:&lt;br /&gt;
** Joystick directionnel&lt;br /&gt;
** Boutons pour les clignotants&lt;br /&gt;
** Bonus : klaxon&lt;br /&gt;
* Module Bluetooth Low Energy&lt;br /&gt;
* Moteur CC avec réductuer + Pilote (DRV8210DRLR) (Propulsion)&lt;br /&gt;
* Moteur glissière pas à pas (Direction)&lt;br /&gt;
* 2 LEDs avant BLANCHES lorsque le véhicule avance&lt;br /&gt;
* 2 LEDs arrière ROUGES lorsque le véhicule recule&lt;br /&gt;
* 4 LEDs JAUNES pour les clignotants&lt;br /&gt;
&lt;br /&gt;
== '''Module Bluetooth Low Energy''' ==&lt;br /&gt;
Après étude de la [https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/Bluetooth-Low-Energy-BLE-Module-DS60001372K.pdf datasheet] (page 15 figure 2-5) nous avons pu recréer le composant BM71BLE01FC2-0B04AA sur kicad. Nous nous sommes aussi rendus compte que l'antenne ([https://fr.farnell.com/pulse-electronics/ant3216ll00r2400a/antenne-helix-chip-ceram-433mhz/dp/4125786?st=ANT3216LL00R2400A ANT3216LL00R2400A]) bluetooth était externe au module. Nous attendons alors la livraison.&lt;br /&gt;
[[Fichier:ComposantBM71.png|vignette]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Le module sera alors ajouté au fichier kicad déja existant modifié (en fonction de ce que l'on compte utiliser).&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;
&lt;br /&gt;
== LEDs ==&lt;br /&gt;
Comme vu précedemment, nous avons fait le choix d'utiliser huit Leds, deux pour la marche avant, deux pour la marche arrière, deux pour le clignotant gauche et deux pour le clignotant droit.&lt;br /&gt;
[[Fichier:LEDs.png|vignette]]&lt;br /&gt;
Nous avons aussi connecté ces Leds au microcontrôleur.&lt;/div&gt;</summary>
		<author><name>Tnehari</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=Fichier:LEDs_Controleur.png&amp;diff=268</id>
		<title>Fichier:LEDs Controleur.png</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=Fichier:LEDs_Controleur.png&amp;diff=268"/>
		<updated>2023-03-14T14:29:16Z</updated>

		<summary type="html">&lt;p&gt;Tnehari : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;LEDS CONTROLEUR&lt;/div&gt;</summary>
		<author><name>Tnehari</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2022-11&amp;diff=267</id>
		<title>SE3Binome2022-11</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2022-11&amp;diff=267"/>
		<updated>2023-03-14T14:26:51Z</updated>

		<summary type="html">&lt;p&gt;Tnehari : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''&amp;lt;big&amp;gt;Caractéristiques de notre système:&amp;lt;/big&amp;gt;''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Modèle réduit au 1.43&lt;br /&gt;
* Commande Bluetooth via application téléphone (MIT App Inventor) en temps réel:&lt;br /&gt;
** Joystick directionnel&lt;br /&gt;
** Boutons pour les clignotants&lt;br /&gt;
** Bonus : klaxon&lt;br /&gt;
* Module Bluetooth Low Energy&lt;br /&gt;
* Moteur CC avec réductuer + Pilote (DRV8210DRLR) (Propulsion)&lt;br /&gt;
* Moteur glissière pas à pas (Direction)&lt;br /&gt;
* 2 LEDs avant BLANCHES lorsque le véhicule avance&lt;br /&gt;
* 2 LEDs arrière ROUGES lorsque le véhicule recule&lt;br /&gt;
* 4 LEDs JAUNES pour les clignotants&lt;br /&gt;
&lt;br /&gt;
== '''Module Bluetooth Low Energy''' ==&lt;br /&gt;
Après étude de la [https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/Bluetooth-Low-Energy-BLE-Module-DS60001372K.pdf datasheet] (page 15 figure 2-5) nous avons pu recréer le composant BM71BLE01FC2-0B04AA sur kicad. Nous nous sommes aussi rendus compte que l'antenne ([https://fr.farnell.com/pulse-electronics/ant3216ll00r2400a/antenne-helix-chip-ceram-433mhz/dp/4125786?st=ANT3216LL00R2400A ANT3216LL00R2400A]) bluetooth était externe au module. Nous attendons alors la livraison.&lt;br /&gt;
[[Fichier:ComposantBM71.png|vignette]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Le module sera alors ajouté au fichier kicad déja existant modifié (en fonction de ce que l'on compte utiliser).&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;
== LEDs ==&lt;br /&gt;
Comme vu précedemment, nous avons fait le choix d'utiliser huit Leds, deux pour la marche avant, deux pour la marche arrière, deux pour le clignotant gauche et deux pour le clignotant droit.&lt;br /&gt;
[[Fichier:LEDs.png|vignette]]&lt;br /&gt;
Nous avons aussi connecté ces Leds a&lt;/div&gt;</summary>
		<author><name>Tnehari</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2022-11&amp;diff=265</id>
		<title>SE3Binome2022-11</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2022-11&amp;diff=265"/>
		<updated>2023-03-14T14:26:02Z</updated>

		<summary type="html">&lt;p&gt;Tnehari : /* LEDs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''&amp;lt;big&amp;gt;Caractéristiques de notre système:&amp;lt;/big&amp;gt;''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Modèle réduit au 1.43&lt;br /&gt;
* Commande Bluetooth via application téléphone (MIT App Inventor) en temps réel:&lt;br /&gt;
** Joystick directionnel&lt;br /&gt;
** Boutons pour les clignotants&lt;br /&gt;
** Bonus : klaxon&lt;br /&gt;
* Module Bluetooth Low Energy&lt;br /&gt;
* Moteur CC avec réductuer + Pilote (DRV8210DRLR) (Propulsion)&lt;br /&gt;
* Moteur glissière pas à pas (Direction)&lt;br /&gt;
* 2 LEDs avant BLANCHES lorsque le véhicule avance&lt;br /&gt;
* 2 LEDs arrière ROUGES lorsque le véhicule recule&lt;br /&gt;
* 4 LEDs JAUNES pour les clignotants&lt;br /&gt;
&lt;br /&gt;
== '''Module Bluetooth Low Energy''' ==&lt;br /&gt;
Après étude de la [https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/Bluetooth-Low-Energy-BLE-Module-DS60001372K.pdf datasheet] (page 15 figure 2-5) nous avons pu recréer le composant BM71BLE01FC2-0B04AA sur kicad. Nous nous sommes aussi rendus compte que l'antenne ([https://fr.farnell.com/pulse-electronics/ant3216ll00r2400a/antenne-helix-chip-ceram-433mhz/dp/4125786?st=ANT3216LL00R2400A ANT3216LL00R2400A]) bluetooth était externe au module. Nous attendons alors la livraison.&lt;br /&gt;
[[Fichier:ComposantBM71.png|vignette]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Le module sera alors ajouté au fichier kicad déja existant modifié (en fonction de ce que l'on compte utiliser).&lt;br /&gt;
&lt;br /&gt;
== LEDs ==&lt;br /&gt;
Comme vu précedemment, nous avons fait le choix d'utiliser huit Leds, deux pour la marche avant, deux pour la marche arrière, deux pour le clignotant gauche et deux pour le clignotant droit.&lt;br /&gt;
[[Fichier:LEDs.png|vignette]]&lt;br /&gt;
Nous avons aussi connecté ces Leds a&lt;/div&gt;</summary>
		<author><name>Tnehari</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=Fichier:LEDs.png&amp;diff=264</id>
		<title>Fichier:LEDs.png</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=Fichier:LEDs.png&amp;diff=264"/>
		<updated>2023-03-14T14:21:19Z</updated>

		<summary type="html">&lt;p&gt;Tnehari : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;LEDs&lt;/div&gt;</summary>
		<author><name>Tnehari</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2022-11&amp;diff=263</id>
		<title>SE3Binome2022-11</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2022-11&amp;diff=263"/>
		<updated>2023-03-14T14:20:10Z</updated>

		<summary type="html">&lt;p&gt;Tnehari : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''&amp;lt;big&amp;gt;Caractéristiques de notre système:&amp;lt;/big&amp;gt;''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Modèle réduit au 1.43&lt;br /&gt;
* Commande Bluetooth via application téléphone (MIT App Inventor) en temps réel:&lt;br /&gt;
** Joystick directionnel&lt;br /&gt;
** Boutons pour les clignotants&lt;br /&gt;
** Bonus : klaxon&lt;br /&gt;
* Module Bluetooth Low Energy&lt;br /&gt;
* Moteur CC avec réductuer + Pilote (DRV8210DRLR) (Propulsion)&lt;br /&gt;
* Moteur glissière pas à pas (Direction)&lt;br /&gt;
* 2 LEDs avant BLANCHES lorsque le véhicule avance&lt;br /&gt;
* 2 LEDs arrière ROUGES lorsque le véhicule recule&lt;br /&gt;
* 4 LEDs JAUNES pour les clignotants&lt;br /&gt;
&lt;br /&gt;
== '''Module Bluetooth Low Energy''' ==&lt;br /&gt;
Après étude de la [https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/Bluetooth-Low-Energy-BLE-Module-DS60001372K.pdf datasheet] (page 15 figure 2-5) nous avons pu recréer le composant BM71BLE01FC2-0B04AA sur kicad. Nous nous sommes aussi rendus compte que l'antenne ([https://fr.farnell.com/pulse-electronics/ant3216ll00r2400a/antenne-helix-chip-ceram-433mhz/dp/4125786?st=ANT3216LL00R2400A ANT3216LL00R2400A]) bluetooth était externe au module. Nous attendons alors la livraison.&lt;br /&gt;
[[Fichier:ComposantBM71.png|vignette]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Le module sera alors ajouté au fichier kicad déja existant modifié (en fonction de ce que l'on compte utiliser).&lt;br /&gt;
&lt;br /&gt;
== '''LEDs''' ==&lt;/div&gt;</summary>
		<author><name>Tnehari</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2022-11&amp;diff=242</id>
		<title>SE3Binome2022-11</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2022-11&amp;diff=242"/>
		<updated>2023-02-28T14:16:13Z</updated>

		<summary type="html">&lt;p&gt;Tnehari : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''&amp;lt;big&amp;gt;Caractéristiques de notre système:&amp;lt;/big&amp;gt;''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Modèle réduit au 1.43&lt;br /&gt;
* Commande Bluetooth via application téléphone (MIT App Inventor) en temps réel:&lt;br /&gt;
** Joystick directionnel&lt;br /&gt;
** Boutons pour les clignotants&lt;br /&gt;
** Bonus : klaxon&lt;br /&gt;
* Module Bluetooth Low Energy&lt;br /&gt;
* Moteur CC avec réductuer + Pilote (DRV8210DRLR) (Propulsion)&lt;br /&gt;
* Moteur glissière pas à pas (Direction)&lt;br /&gt;
* 2 LEDs avant BLANCHES lorsque le véhicule avance&lt;br /&gt;
* 2 LEDs arrière ROUGES lorsque le véhicule recule&lt;br /&gt;
* 4 LEDs JAUNES pour les clignotants&lt;br /&gt;
&lt;br /&gt;
== '''Module Bluetooth Low Energy''' ==&lt;br /&gt;
Après étude de la [https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/Bluetooth-Low-Energy-BLE-Module-DS60001372K.pdf datasheet] (page 15 figure 2-5) nous avons pu recréer le composant BM71BLE01FC2-0B04AA sur kicad. Nous nous sommes aussi rendus compte que l'antenne ([https://fr.farnell.com/pulse-electronics/ant3216ll00r2400a/antenne-helix-chip-ceram-433mhz/dp/4125786?st=ANT3216LL00R2400A ANT3216LL00R2400A]) bluetooth était externe au module. Nous attendons alors la livraison.&lt;br /&gt;
[[Fichier:ComposantBM71.png|vignette]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Le module sera alors ajouté au fichier kicad déja existant modifié (en fonction de ce que l'on compte utiliser).&lt;/div&gt;</summary>
		<author><name>Tnehari</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2022-11&amp;diff=241</id>
		<title>SE3Binome2022-11</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2022-11&amp;diff=241"/>
		<updated>2023-02-28T14:15:16Z</updated>

		<summary type="html">&lt;p&gt;Tnehari : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''&amp;lt;big&amp;gt;Caractéristiques de notre système:&amp;lt;/big&amp;gt;''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Modèle réduit au 1.43&lt;br /&gt;
* Commande Bluetooth via application téléphone (MIT App Inventor) en temps réel:&lt;br /&gt;
** Joystick directionnel&lt;br /&gt;
** Boutons pour les clignotants&lt;br /&gt;
** Bonus : klaxon&lt;br /&gt;
* Module Bluetooth Low Energy&lt;br /&gt;
* Moteur CC avec réductuer + Pilote (DRV8210DRLR) (Propulsion)&lt;br /&gt;
* Moteur glissière pas à pas (Direction)&lt;br /&gt;
* 2 LEDs avant BLANCHES lorsque le véhicule avance&lt;br /&gt;
* 2 LEDs arrière ROUGES lorsque le véhicule recule&lt;br /&gt;
* 4 LEDs JAUNES pour les clignotants&lt;br /&gt;
&lt;br /&gt;
== '''Module Bluetooth Low Energy''' ==&lt;br /&gt;
Après étude de la [https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/Bluetooth-Low-Energy-BLE-Module-DS60001372K.pdf datasheet] (page 15 figure 2-5) nous avons pu recréer le composant BM71BLE01FC2-0B04AA sur kicad. Nous nous sommes aussi rendus compte que l'antenne (ANT3216LL00R2400A) bluetooth était externe au module. Nous attendons alors la livraison.&lt;br /&gt;
[[Fichier:ComposantBM71.png|vignette]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Le module sera alors ajouté au fichier kicad déja existant modifié (en fonction de ce que l'on compte utiliser).&lt;/div&gt;</summary>
		<author><name>Tnehari</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=Fichier:ComposantBM71.png&amp;diff=240</id>
		<title>Fichier:ComposantBM71.png</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=Fichier:ComposantBM71.png&amp;diff=240"/>
		<updated>2023-02-28T14:13:41Z</updated>

		<summary type="html">&lt;p&gt;Tnehari : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le composant BM71BLE01FC2 sans l'antenne externe.&lt;/div&gt;</summary>
		<author><name>Tnehari</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2022-11&amp;diff=162</id>
		<title>SE3Binome2022-11</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2022-11&amp;diff=162"/>
		<updated>2023-02-14T14:23:24Z</updated>

		<summary type="html">&lt;p&gt;Tnehari : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''&amp;lt;big&amp;gt;Caractéristiques de notre système:&amp;lt;/big&amp;gt;''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
- Modèle réduit au 1.43&lt;br /&gt;
&lt;br /&gt;
- Commande Bluetooth via application téléphone (MIT App Inventor) en temps réel:&amp;lt;blockquote&amp;gt;° Joystick directionnel&lt;br /&gt;
&lt;br /&gt;
° Boutons pour les clignotants&lt;br /&gt;
&lt;br /&gt;
° Bonus : klaxon&amp;lt;/blockquote&amp;gt;- Module Bluetooth Low Energy&lt;br /&gt;
&lt;br /&gt;
- Moteur CC avec réductuer + Pilote (DRV8210DRLR) (Propulsion)&lt;br /&gt;
&lt;br /&gt;
- Moteur glissière pas à pas (Direction)&lt;br /&gt;
&lt;br /&gt;
- 2 LEDs avant BLANCHES lorsque le véhicule avance&lt;br /&gt;
&lt;br /&gt;
- 2 LEDs arrière ROUGES lorsque le véhicule recule&lt;br /&gt;
&lt;br /&gt;
- 4 LEDs JAUNES pour les clignotants&lt;/div&gt;</summary>
		<author><name>Tnehari</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2022-11&amp;diff=161</id>
		<title>SE3Binome2022-11</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2022-11&amp;diff=161"/>
		<updated>2023-02-14T14:23:04Z</updated>

		<summary type="html">&lt;p&gt;Tnehari : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== '''&amp;lt;u&amp;gt;&amp;lt;big&amp;gt;Caractéristiques de notre système:&amp;lt;/big&amp;gt;&amp;lt;/u&amp;gt;''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
- Modèle réduit au 1.43&lt;br /&gt;
&lt;br /&gt;
- Commande Bluetooth via application téléphone (MIT App Inventor) en temps réel:&amp;lt;blockquote&amp;gt;° Joystick directionnel&lt;br /&gt;
&lt;br /&gt;
° Boutons pour les clignotants&lt;br /&gt;
&lt;br /&gt;
° Bonus : klaxon&amp;lt;/blockquote&amp;gt;- Module Bluetooth Low Energy&lt;br /&gt;
&lt;br /&gt;
- Moteur CC avec réductuer + Pilote (DRV8210DRLR) (Propulsion)&lt;br /&gt;
&lt;br /&gt;
- Moteur glissière pas à pas (Direction)&lt;br /&gt;
&lt;br /&gt;
- 2 LEDs avant BLANCHES lorsque le véhicule avance&lt;br /&gt;
&lt;br /&gt;
- 2 LEDs arrière ROUGES lorsque le véhicule recule&lt;br /&gt;
&lt;br /&gt;
- 4 LEDs JAUNES pour les clignotants&lt;/div&gt;</summary>
		<author><name>Tnehari</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2022-11&amp;diff=160</id>
		<title>SE3Binome2022-11</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE3Binome2022-11&amp;diff=160"/>
		<updated>2023-02-14T14:21:49Z</updated>

		<summary type="html">&lt;p&gt;Tnehari : Page créée avec « Caractéristiques de notre système:   - Modèle réduit au 1.43  - Commande Bluetooth via application téléphone (MIT App Inventor) en temps réel:  ° Joystick directionnel  ° Boutons pour les clignotants  ° Bonus : klaxon  - Module Bluetooth Low Energy  - Moteur CC avec réductuer + Pilote (DRV8210DRLR) (Propulsion)  - Moteur glissière pas à pas (Direction)  - 2 LEDs avant BLANCHES lorsque le véhicule avance  - 2 LEDs arrière ROUGES lorsque le véhicule... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Caractéristiques de notre système:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
- Modèle réduit au 1.43&lt;br /&gt;
&lt;br /&gt;
- Commande Bluetooth via application téléphone (MIT App Inventor) en temps réel:&lt;br /&gt;
&lt;br /&gt;
° Joystick directionnel&lt;br /&gt;
&lt;br /&gt;
° Boutons pour les clignotants&lt;br /&gt;
&lt;br /&gt;
° Bonus : klaxon&lt;br /&gt;
&lt;br /&gt;
- Module Bluetooth Low Energy&lt;br /&gt;
&lt;br /&gt;
- Moteur CC avec réductuer + Pilote (DRV8210DRLR) (Propulsion)&lt;br /&gt;
&lt;br /&gt;
- Moteur glissière pas à pas (Direction)&lt;br /&gt;
&lt;br /&gt;
- 2 LEDs avant BLANCHES lorsque le véhicule avance&lt;br /&gt;
&lt;br /&gt;
- 2 LEDs arrière ROUGES lorsque le véhicule recule&lt;br /&gt;
&lt;br /&gt;
- 4 LEDs JAUNES pour les clignotants&lt;/div&gt;</summary>
		<author><name>Tnehari</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=PSE_SE3_2022/2023&amp;diff=146</id>
		<title>PSE SE3 2022/2023</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=PSE_SE3_2022/2023&amp;diff=146"/>
		<updated>2023-02-14T14:06:34Z</updated>

		<summary type="html">&lt;p&gt;Tnehari : /* Réalisation des groupes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Objectif =&lt;br /&gt;
&lt;br /&gt;
Pour l'année académique 2022/2023 il demandé de motoriser un modèle réduit de voiture au 1:87ème ou au 1:43ème avec contrôle par microcontrôleur.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:modele-voiture-1-87.jpg|Modéle réduit au 1:87&lt;br /&gt;
File:modele-voiture-1-43.jpg|Modéle réduit au 1:43&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Votre objectif est de concevoir votre propre modèle à l'aide des éléments présentés dans cette page. Vous ne devez pas forcément fusionner l'ensemble&lt;br /&gt;
des possibilités, d'ailleurs certaines sont incompatibles entre elles. Partir sur quelque chose de simple n'est pas infamant du moment qu'il est proprement exécuté et qu'il débouche sur un prototype fonctionnel.&lt;br /&gt;
&lt;br /&gt;
Certes si vous nous sortez une voiture au 1:87ème totalement fonctionnelle avec propulsion, roues avant directionnelles, chargeur de batterie intégré et contrôle radio nous serons enchantés et nous aurons assez peu de difficulté à vous noter. Maintenant si vous partez sur un simple chassis au 1:43ème avec propulsion utilisant de simples poulies, roue folle permettant des reculs avec virage (axe de roue non fixe) et contrôle par programmation, vous aurez rempli le contrat.&lt;br /&gt;
&lt;br /&gt;
= Mécanique =&lt;br /&gt;
&lt;br /&gt;
La partie mécanique n'est pas évaluée dans ce projet car elle est hors-sujet pour la filière. Par contre, une démonstration avec une voiture mobile est un excellent moyen de prouver que votre projet fonctionne.&lt;br /&gt;
&lt;br /&gt;
[[file:2022-chassis.png|thumb|400px|right|Image du chassis]]&lt;br /&gt;
&lt;br /&gt;
Pour vous aider nous avons modélisé un chassis avec roues avant directionnelles.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
file:2022-chassis-dessus.pdf|Chassis vu de dessus&lt;br /&gt;
file:2022-chassis-dessous.pdf|Chassis vu de dessous&lt;br /&gt;
file:2022-chassis-cote-1.pdf|Chassis vu de coté&lt;br /&gt;
file:2022-chassis-cote-2.pdf|Chassis vu d'un autre coté&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le fichier &amp;lt;code&amp;gt;freeCAD&amp;lt;/code&amp;gt; du chassis [[file:chassis-2022.tar]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear: both;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[file:2022-roue_folle.png|thumb|200px|right|Image de la roue]]&lt;br /&gt;
&lt;br /&gt;
Vous avez aussi un modèle de principe pour une roue folle avec recul en virant.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
file:2022-roue-folle.pdf|Roue en 3D&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le fichier &amp;lt;code&amp;gt;freeCAD&amp;lt;/code&amp;gt; de la roue [[file:roue-folle-2022.tar]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear: both;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Au niveau accessoires vous pouvez, ou pourrez, disposer des éléments suivants :&lt;br /&gt;
* engrenages métal pour axe 0.7mm, disponibles et semblent s'adapter aux micro-moteurs simples ;&lt;br /&gt;
* vis sans fil plastique pour axe 2mm, disponibles mais s'adaptent mal aux axes des voitures 1:43 ;&lt;br /&gt;
* vis sans fin 3,8mm pour axe de 1mm, &amp;quot;en cours de livraison&amp;quot;, prévues pour l'axe des voitures 1:87 ;&lt;br /&gt;
* divers engrenages plastiques pour les voitures 1:43, arrivés en france ;&lt;br /&gt;
* engrenages plastique pour axe de 1mm (voitures 1:43), arrivés en france.&lt;br /&gt;
&lt;br /&gt;
= Moteurs =&lt;br /&gt;
&lt;br /&gt;
La commande des moteurs n'est pas, elle, optionnelle.&lt;br /&gt;
&lt;br /&gt;
Plusieurs types de moteurs sont disponibles.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:micro-moteur-pas-a-pas-simple.jpg|Micro-moteur pas à pas propulsion&lt;br /&gt;
File:micro-moteur-pas-a-pas-simple-dims.jpg|Dimensions du micro-moteur propulsion&lt;br /&gt;
File:micro-glissiere-pas-a-pas.jpg|Micro-moteur glissière pas à pas&lt;br /&gt;
File:micro-glissiere-pas-a-pas-dimensions.jpg|Dimensions du micro-moteur glissière&lt;br /&gt;
File:micro-glissiere-pas-a-pas-connecteurs.jpg|Connecteurs du micro-moteur glissière&lt;br /&gt;
File:mini-motoreducteur.jpg|Mini-moteur continu avec réducteur&lt;br /&gt;
File:pilote-motoreducteur.jpg|Pilote pour le mini-moteur continu (DRV8210DRLR)&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[file:2022-banc-essai-micro-moteurs.jpg|thumb|250px|right|Banc d'essai des micro-moteurs]]&lt;br /&gt;
&lt;br /&gt;
Ressources pour les moteurs :&lt;br /&gt;
* les micro-moteurs peuvent éventuellement fonctionner sans pilote (alimentation directe par le microcontrôleur), il reste à vérifier que le couple obtenu suffit et que l'utilisation de plusieurs périphériques n'effondre pas le microcontrôleur ;&lt;br /&gt;
* empreintes approximatives pour les microcontrôleurs (à peaufiner) : [[file:KiCAD-lib-micro-motors.tar]] ;&lt;br /&gt;
* premier jet du PCB de coté pour le micro-moteur glissière : [[file:KiCAD-slider-side-2022.tar]] ;&lt;br /&gt;
* programme C pour les micro-moteurs pas à pas sans pilote (vidéo de démonstration ci-dessous) : [[Média:Programme_moteur_pap.tar]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear: both;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[file:2022-demo-micro-moteur.mp4|500px|left|Vidéo pour le micro-moteur]]&lt;br /&gt;
[[file:2022-demo-micro-slider.mp4|500px|right|Vidéo pour le micro-moteur glissière]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear: both;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Carte électronique =&lt;br /&gt;
&lt;br /&gt;
Vous devez concevoir une carte électronique pour contrôler la voiture. La conception doit se faire en utilisant le logiciel KiCAD.&lt;br /&gt;
&lt;br /&gt;
Il est recommandé de reporter au maximum les fonctions mécaniques sur la carte. Le chassis peut ainsi être entièrement constitué de PCB, y compris les pièces mobiles.&lt;br /&gt;
&lt;br /&gt;
Nous vous donnons deux exemples de schémas électroniques :&lt;br /&gt;
&lt;br /&gt;
[[file:2022-schema-voiture-rex.pdf|thumb|400px|left|Schéma pour une voiture 1:87]]&lt;br /&gt;
&lt;br /&gt;
[[file:2022-schema-voiture-boe.pdf|thumb|400px|right|Schéma pour une voiture 1:43]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear: both;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Le microcontrôleur ==&lt;br /&gt;
&lt;br /&gt;
Vous utiliserez un microcontrôleur ATMega16u2 comme coeur de votre circuit imprimé. Prenez exemple sur la partie microcontrôleur des schémas fournis.&lt;br /&gt;
&lt;br /&gt;
La programmation du microcontrôleur se fera par DFU USB.&lt;br /&gt;
&lt;br /&gt;
== Energie ==&lt;br /&gt;
&lt;br /&gt;
La carte électronique de votre voiture est alimentée par une batterie LiPo. La batterie peut être chargée en utilisant une puce MAX1811. Voir les schémas fournis pour avoir une idée de commencer utiliser une puce MAX1811.&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;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Des batteries FQ777-124 mAh un peu moins encombrantes ont été commandées (disponibilité fin mars ?). Les connecteurs adaptés ont aussi été commandés (micro JST 2 broches 1.25mm).&lt;br /&gt;
&lt;br /&gt;
== Eclairage ==&lt;br /&gt;
&lt;br /&gt;
Vous pouvez vous lâcher sur les LED pour simuler les dispositifs lumineux de votre voiture. Attention cependant votre micro-contrôleur n'a qu'un nombre limité de sorties.&lt;br /&gt;
&lt;br /&gt;
== Contrôle de la voiture ==&lt;br /&gt;
&lt;br /&gt;
=== Contrôle par programmation ===&lt;br /&gt;
&lt;br /&gt;
Il est recommandé d'utiliser la fonctionnalité USB pour pouvoir programmer le comportement de la voiture. A défaut une programmation par port série est acceptable. Le programme PC permettant d'envoyer la suite d'instructions que la voiture doit réaliser est aussi à votre charge.&lt;br /&gt;
&lt;br /&gt;
=== Radio-contrôle ===&lt;br /&gt;
&lt;br /&gt;
Vous avez deux possibilités pour la commande à distance de votre voiture, soit une communication radio classique, soit une communication BlueTooth.&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:module_BLE.jpg|Module Bluetooth Low Energy&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Les modules RF 2,4Ghz utilisent une puce NRF24L01, ces modules étant un peu encombrants, quelques puces ont été commandées pour intégration directe sur le PCB (disponibilité fin février). Vous avez un exemple d'utilisation sur le premier schéma de carte fourni plus haut. Les puces NRF24L01 doivent être alimentées en 3,3V mais ses E/S sont compatibles 5V. Il n'est donc pas obligatoire de passer l'ATMega16u2 en 3,3V.&lt;br /&gt;
&lt;br /&gt;
= Réalisation des groupes =&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;
| Sarra BEZZINE &amp;amp; Heriniaina ANDRIANIRINTSOA&lt;br /&gt;
| [[SE3Binome2022-1|Binôme 1 2022/2023]]&lt;br /&gt;
|-&lt;br /&gt;
| Trinôme 2&lt;br /&gt;
| Younes BENMBAREK &amp;amp; Camille CARIAT &amp;amp; Abdel ZONGO&lt;br /&gt;
| [[SE3Trinome2022-2|Trinôme 2 2022/2023]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 3&lt;br /&gt;
| Simon CRUCHET &amp;amp; Amaury BECQUET&lt;br /&gt;
| [[SE3Binome2022-3|Binôme 3 2022/2023]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 4&lt;br /&gt;
| Romain DUHR &amp;amp; Louis DERYCKERE&lt;br /&gt;
| [[SE3Binome2022-4|Binôme 4 2022/2023]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 5&lt;br /&gt;
| Youness EL QASTALANI &amp;amp; Chaymae Rhanim&lt;br /&gt;
| [[SE3Binome2022-5|Binôme 5 2022/2023]]&lt;br /&gt;
|-&lt;br /&gt;
| Trinôme 6&lt;br /&gt;
| Stephane KADER ISSACK &amp;amp; Marion NORMAND &amp;amp; Amaury DA PONTE&lt;br /&gt;
| [[SE3Trinome2022-6|Trinôme 6 2022/2023]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 7&lt;br /&gt;
| Alexandre BRASSEUR &amp;amp; Louis WIJSMAN&lt;br /&gt;
| [[SE3Binome2022-7|Binôme 7 2022/2023]]&lt;br /&gt;
|-&lt;br /&gt;
| Trinôme 8&lt;br /&gt;
| Némo CAZIN &amp;amp; Antoine CEGARRA &amp;amp; Adrien PALIFERRO&lt;br /&gt;
| [[SE3Trinome2022-8|Trinôme 8 2022/2023]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 9&lt;br /&gt;
| Thomas NAVE &amp;amp; Thibault DUYCK&lt;br /&gt;
| [[SE3Trinome2022-9|Trinôme 9 2022/2023]]&lt;br /&gt;
|-&lt;br /&gt;
| Monôme 10&lt;br /&gt;
| Adrien GONTIER&lt;br /&gt;
| [[SE3Monome2022-10|Monôme 10 2022/2023]]&lt;br /&gt;
|-&lt;br /&gt;
| Binôme 11&lt;br /&gt;
| Taha NEHARI &amp;amp; Martin CHAUVELIERE &lt;br /&gt;
| [[SE3Binome2022-11|Binôme 11 2022/2023]]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Tnehari</name></author>
	</entry>
</feed>