« I2L 2023 Groupe3 » : différence entre les versions
(47 versions intermédiaires par 4 utilisateurs non affichées) | |||
Ligne 14 : | Ligne 14 : | ||
= Contre-proposition = | = Contre-proposition = | ||
Le périphérique USB doit être de type spécifique (classe 0) et utiliser un point d'accès de volume, vous pouvez vous appuyer sur cet exemple LUFA de base : [[Média:LUFA_Minimal.zip]]. | |||
Pour télécharger le texte à faire défiler vers la carte, vous écrirez une application avec la bibliothèque <code>libusb</code>. | |||
= Proposition définitive = | = Proposition définitive = | ||
L'écran LCD affichera en premiers lieux un message statique déroulant sous deux manières: | |||
* Affichage de gauche à droite | |||
* Affichage de bas en haut | |||
Ensuite le message souhaité sera écrit de manière dynamique sur un clavier d'ordinateur et une liaison USB se chargera de transmettre ce dernier sur l'écran LCD. | |||
= Carte = | = Carte = | ||
Ligne 34 : | Ligne 45 : | ||
<p style="clear: both;" /> | <p style="clear: both;" /> | ||
La position du connecteur de l'écran sur la carte n'est pas bien réfléchie. Du coup l'écran recouvre les LED et les boutons. Pour éviter le problème la carte a été rallongée avec des prolongateurs. | |||
[[Fichier:I2L-2023-Carte3Rallonge-G3-v2.jpg|thumb|center|400px]] | |||
Par ailleurs durant les journées des 28 et 29 septembre il n'avait pas été possible de faire fonctionner les écrans LCD. La carte avait été incriminée (avec le contrôle du contraste LCD). En fait c'était le code de l'étudiant SE qui était bogué. Avec un code correct, comme la photo ci-dessus le montre, l'affichage fonctionne sans problème : [[Média:I2L-2023-code-LCD.zip]]. | |||
= Code = | = Code = | ||
== Tests de la carte == | == Tests de la carte == | ||
[[Fichier:Chenillard_normal.png|vignette|269x269px|Chenillard normal|gauche]] | |||
[[Fichier:Chenillard_appui.png|néant|vignette|300x300px|Gestion appui de bouton]] | |||
Après avoir essayé de faire fonctionner l'écran LCD, nous avons constaté que rien ne se passait. Même après vérification de votre part. | |||
==Conception == | |||
===Configuration USB=== | |||
Après avoir modifié le Minimal, on obtient: | |||
Device Descriptor: | |||
bLength 18 | |||
bDescriptorType 1 | |||
bcdUSB 1.10 | |||
bDeviceClass 0 | |||
bDeviceSubClass 0 | |||
bDeviceProtocol 0 | |||
bMaxPacketSize0 8 | |||
idVendor 0x4242 USB Design by Example | |||
idProduct 0x0001 | |||
bcdDevice 0.01 | |||
iManufacturer 1 LUFA Library | |||
iProduct 2 LUFA Minimal | |||
iSerial 220 3423031383635110A1C0 | |||
bNumConfigurations 1 | |||
Configuration Descriptor: | |||
bLength 9 | |||
bDescriptorType 2 | |||
wTotalLength 0x0019 | |||
bNumInterfaces 1 | |||
bConfigurationValue 1 | |||
iConfiguration 0 | |||
bmAttributes 0x80 | |||
(Bus Powered) | |||
MaxPower 100mA | |||
Interface Descriptor: | |||
bLength 9 | |||
bDescriptorType 4 | |||
bInterfaceNumber 0 | |||
bAlternateSetting 0 | |||
bNumEndpoints 1 | |||
bInterfaceClass 255 Vendor Specific Class | |||
bInterfaceSubClass 255 Vendor Specific Subclass | |||
bInterfaceProtocol 255 Vendor Specific Protocol | |||
iInterface 0 | |||
Endpoint Descriptor: | |||
bLength 7 | |||
bDescriptorType 5 | |||
bEndpointAddress 0x02 EP 2 OUT | |||
bmAttributes 2 | |||
Transfer Type Bulk | |||
Synch Type None | |||
Usage Type Data | |||
wMaxPacketSize 0x0200 1x 512 bytes | |||
bInterval 5 | |||
== Compilation == | |||
=== Utilitaires : === | |||
* gcc-avr | |||
* avr-libc | |||
* dfu-programmer | |||
** DFU/USB | |||
=== Lancer le projet : === | |||
Afin de faire fonctionner notre projet, nous devons réaliser quelques étapes : | |||
== | # Compiler le programme dans le microcontrôleur (I2L-2023-Programmes-G3/lufa-LUFA-210130/Minimal) => sudo make dfu | ||
# Compiler le programme sur l'ordinateur pour envoyer les données au microcontrôleur (I2L-2023-Programmes-G3/DataFromPc) => sudo ./main | |||
==Réalisation== | ==Réalisation== | ||
Avant de commencer à transmettre le message par la clavier, nous avons décidé de mettre le message à afficher en dur dans le code, puis de le faire défiler de deux manières différentes. De gauche à droite et de bas en haut. | |||
=== Défilement de gauche à droite : === | |||
<syntaxhighlight lang="c"> | |||
/** | |||
* Permet défiler le message de gauche à droite | |||
* @param message | |||
*/ | |||
void defiler_GD(char *message) { | |||
char temp = message[0]; | |||
int length = strlen(message); | |||
for(int i = 0; i < length - 1; i++) { | |||
message[i] = message[i+1]; | |||
} | |||
message[length-1] = temp; | |||
} | |||
</syntaxhighlight><syntaxhighlight lang="c"> | |||
int main() { | |||
//uC configuration | |||
CLKSEL0 = 0b00010101; // sélection de l'horloge externe | |||
CLKSEL1 = 0b00001111; // minimum de 8Mhz | |||
CLKPR = (1<<CLKPCE); | |||
CLKPR = 0; | |||
MCUCR |= (1<<JTD); | |||
MCUCR |= (1<<JTD); | |||
//Configuration et séquence d'initilisation de l'écran LCD | |||
HD44780_Initialize(); | |||
HD44780_WriteCommand(LCD_ON|CURSOR_NONE); | |||
HD44780_WriteCommand(LCD_CLEAR); | |||
HD44780_WriteCommand(LCD_HOME); | |||
HD44780_WriteCommand(LCD_INCR_RIGHT); | |||
short int count = 100; | |||
char message[1000] = "La guerre civile fait rage entre l'Empire galactique et l'Alliance rebelle. Capturée par les troupes de choc de l'Empereur menées par le sombre et impitoyable Dark Vador, la princesse Leia Organa dissimule les plans de l'Etoile Noire."; | |||
// Défilement de gauche à droite | |||
while(1){ | |||
for(int c = 0; c < NB_COLS; c++){ | |||
int address=HD44780_XY2Adrr(NB_ROWS,NB_COLS,0,c); | |||
HD44780_WriteCommand(LCD_ADDRSET|address); | |||
if(message[c] == '\0') | |||
HD44780_WriteData(' '); | |||
else | |||
HD44780_WriteData(message[c]); | |||
} | |||
if(strlen(message) > 16){ | |||
defiler_GD(message); | |||
_delay_ms(500); | |||
} | |||
} | |||
return 0; | |||
} | |||
</syntaxhighlight> | |||
=== Défilement de bas en haut : === | |||
<syntaxhighlight lang="c"> | |||
/** | |||
* Permet de défiler le message de bas en haut | |||
* @param message | |||
*/ | |||
void defiler_BH(char *message) { | |||
char temp[NB_COLS + 1]; | |||
strncpy(temp, message, NB_COLS); | |||
temp[NB_COLS] = '\0'; | |||
memmove(message, message + NB_COLS, strlen(message) - NB_COLS + 1); | |||
strcat(message, temp); | |||
} | |||
</syntaxhighlight><syntaxhighlight lang="c"> | |||
//Défilement de bas en haut | |||
while(1){ | |||
for (int r = 0; r < NB_ROWS; r++) { | |||
for(int c = 0; c < NB_COLS; c++){ | |||
int address=HD44780_XY2Adrr(NB_ROWS,NB_COLS,r,c); | |||
HD44780_WriteCommand(LCD_ADDRSET|address); | |||
if(message[c + r * NB_COLS] == '\0') | |||
HD44780_WriteData(' '); | |||
else | |||
HD44780_WriteData(message[c + r * NB_COLS]); | |||
} | |||
} | |||
if(strlen(message) > 16){ | |||
defiler_BH(message); | |||
_delay_ms(2000); | |||
} | |||
} | |||
</syntaxhighlight> | |||
=== Message transmis par USB : === | |||
<syntaxhighlight lang="c"> | |||
/** | |||
* Ecrit dans l'EEPROM | |||
*/ | |||
void read_usb(void){ | |||
Endpoint_SelectEndpoint(OUT_EPADDR); | |||
if(Endpoint_IsOUTReceived()){ | |||
if(Endpoint_IsReadWriteAllowed()){ | |||
Endpoint_Read_EStream_LE(0, OUT_EPSIZE, NULL); | |||
} | |||
} | |||
Endpoint_ClearOUT(); | |||
} | |||
</syntaxhighlight><syntaxhighlight lang="c"> | |||
/** | |||
*Défile le message écrit dans l'EEPROM au clavier | |||
*/ | |||
int display_from_eeprom(int cpt){ | |||
int verif = 0; | |||
for(int c = 0; c < NB_COLS; c++){ | |||
char m = eeprom_read_byte((c+cpt) % 32); | |||
int address=HD44780_XY2Adrr(NB_ROWS,NB_COLS,0,c); | |||
HD44780_WriteCommand(LCD_ADDRSET|address); | |||
if(m == '\0') { | |||
verif = 1; | |||
HD44780_WriteData(' '); | |||
} | |||
else | |||
HD44780_WriteData(m); | |||
} | |||
return verif; | |||
} | |||
</syntaxhighlight> | |||
=Démonstrations= | =Démonstrations= | ||
=== Affichage d'un message en dur sur l'écran : === | |||
[[Fichier:20231018 152359.jpg|vignette|Affichage d'un message sur l'écran LCD|néant]] | |||
=== Défilement du message en dur : === | |||
[[Fichier:20231018 172703(1).mp4|vignette|Défilement d'un message de gauche à droite |gauche]] | |||
[[Fichier:20231018 172505.mp4|néant|vignette|Défilement d'un message de bas en haut]] | |||
<p style="clear: both;" /> | |||
=== Message transmis par USB : === | |||
[[Fichier:Message transmis par USB.mp4|gauche|vignette|Défilement du message transmis par USB]] | |||
=Rendus= | =Rendus= | ||
Ligne 60 : | Ligne 296 : | ||
Projet KiCAD : [[File:I2L-2023-Carte-G3.zip]] | Projet KiCAD : [[File:I2L-2023-Carte-G3.zip]] | ||
Programmes : [[ | Programmes : | ||
[[Fichier:I2L-2023-Programmes-G3.zip|néant|vignette|Sources du projet]] |
Version actuelle datée du 21 décembre 2023 à 15:16
Proposition de système
Un écran LCD à 2 lignes à contrôleur HD44780 affichera un message qui défilera de la gauche vers la droite ou du bas vers le haut.
Dans un premier temps, le message affiché sera stocké en dur dans la mémoire. Ensuite, le message pourra être entré au clavier. Enfin, un message stocké en mémoire pourra être affiché lorsque la connexion USB ne sera pas détectée.
Matériel requis :
- Le microcontrôleur ;
- Un écran LCD à 2 lignes à contrôleur HD44780 ;
- 2 LED ;
- 1 bouton (pour afficher le message de la première étape) ;
- une batterie ;
- 1 connecteur USB A.
Contre-proposition
Le périphérique USB doit être de type spécifique (classe 0) et utiliser un point d'accès de volume, vous pouvez vous appuyer sur cet exemple LUFA de base : Média:LUFA_Minimal.zip.
Pour télécharger le texte à faire défiler vers la carte, vous écrirez une application avec la bibliothèque libusb
.
Proposition définitive
L'écran LCD affichera en premiers lieux un message statique déroulant sous deux manières:
- Affichage de gauche à droite
- Affichage de bas en haut
Ensuite le message souhaité sera écrit de manière dynamique sur un clavier d'ordinateur et une liaison USB se chargera de transmettre ce dernier sur l'écran LCD.
Carte
Seconde version de la carte pour changer le modèle du potentiomètre.
La position du connecteur de l'écran sur la carte n'est pas bien réfléchie. Du coup l'écran recouvre les LED et les boutons. Pour éviter le problème la carte a été rallongée avec des prolongateurs.
Par ailleurs durant les journées des 28 et 29 septembre il n'avait pas été possible de faire fonctionner les écrans LCD. La carte avait été incriminée (avec le contrôle du contraste LCD). En fait c'était le code de l'étudiant SE qui était bogué. Avec un code correct, comme la photo ci-dessus le montre, l'affichage fonctionne sans problème : Média:I2L-2023-code-LCD.zip.
Code
Tests de la carte
Après avoir essayé de faire fonctionner l'écran LCD, nous avons constaté que rien ne se passait. Même après vérification de votre part.
Conception
Configuration USB
Après avoir modifié le Minimal, on obtient:
Device Descriptor:
bLength 18 bDescriptorType 1 bcdUSB 1.10 bDeviceClass 0 bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 8 idVendor 0x4242 USB Design by Example idProduct 0x0001 bcdDevice 0.01 iManufacturer 1 LUFA Library iProduct 2 LUFA Minimal iSerial 220 3423031383635110A1C0 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 0x0019 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 0 bmAttributes 0x80 (Bus Powered) MaxPower 100mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 255 Vendor Specific Class bInterfaceSubClass 255 Vendor Specific Subclass bInterfaceProtocol 255 Vendor Specific Protocol iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x02 EP 2 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 5
Compilation
Utilitaires :
- gcc-avr
- avr-libc
- dfu-programmer
- DFU/USB
Lancer le projet :
Afin de faire fonctionner notre projet, nous devons réaliser quelques étapes :
- Compiler le programme dans le microcontrôleur (I2L-2023-Programmes-G3/lufa-LUFA-210130/Minimal) => sudo make dfu
- Compiler le programme sur l'ordinateur pour envoyer les données au microcontrôleur (I2L-2023-Programmes-G3/DataFromPc) => sudo ./main
Réalisation
Avant de commencer à transmettre le message par la clavier, nous avons décidé de mettre le message à afficher en dur dans le code, puis de le faire défiler de deux manières différentes. De gauche à droite et de bas en haut.
Défilement de gauche à droite :
/**
* Permet défiler le message de gauche à droite
* @param message
*/
void defiler_GD(char *message) {
char temp = message[0];
int length = strlen(message);
for(int i = 0; i < length - 1; i++) {
message[i] = message[i+1];
}
message[length-1] = temp;
}
int main() {
//uC configuration
CLKSEL0 = 0b00010101; // sélection de l'horloge externe
CLKSEL1 = 0b00001111; // minimum de 8Mhz
CLKPR = (1<<CLKPCE);
CLKPR = 0;
MCUCR |= (1<<JTD);
MCUCR |= (1<<JTD);
//Configuration et séquence d'initilisation de l'écran LCD
HD44780_Initialize();
HD44780_WriteCommand(LCD_ON|CURSOR_NONE);
HD44780_WriteCommand(LCD_CLEAR);
HD44780_WriteCommand(LCD_HOME);
HD44780_WriteCommand(LCD_INCR_RIGHT);
short int count = 100;
char message[1000] = "La guerre civile fait rage entre l'Empire galactique et l'Alliance rebelle. Capturée par les troupes de choc de l'Empereur menées par le sombre et impitoyable Dark Vador, la princesse Leia Organa dissimule les plans de l'Etoile Noire.";
// Défilement de gauche à droite
while(1){
for(int c = 0; c < NB_COLS; c++){
int address=HD44780_XY2Adrr(NB_ROWS,NB_COLS,0,c);
HD44780_WriteCommand(LCD_ADDRSET|address);
if(message[c] == '\0')
HD44780_WriteData(' ');
else
HD44780_WriteData(message[c]);
}
if(strlen(message) > 16){
defiler_GD(message);
_delay_ms(500);
}
}
return 0;
}
Défilement de bas en haut :
/**
* Permet de défiler le message de bas en haut
* @param message
*/
void defiler_BH(char *message) {
char temp[NB_COLS + 1];
strncpy(temp, message, NB_COLS);
temp[NB_COLS] = '\0';
memmove(message, message + NB_COLS, strlen(message) - NB_COLS + 1);
strcat(message, temp);
}
//Défilement de bas en haut
while(1){
for (int r = 0; r < NB_ROWS; r++) {
for(int c = 0; c < NB_COLS; c++){
int address=HD44780_XY2Adrr(NB_ROWS,NB_COLS,r,c);
HD44780_WriteCommand(LCD_ADDRSET|address);
if(message[c + r * NB_COLS] == '\0')
HD44780_WriteData(' ');
else
HD44780_WriteData(message[c + r * NB_COLS]);
}
}
if(strlen(message) > 16){
defiler_BH(message);
_delay_ms(2000);
}
}
Message transmis par USB :
/**
* Ecrit dans l'EEPROM
*/
void read_usb(void){
Endpoint_SelectEndpoint(OUT_EPADDR);
if(Endpoint_IsOUTReceived()){
if(Endpoint_IsReadWriteAllowed()){
Endpoint_Read_EStream_LE(0, OUT_EPSIZE, NULL);
}
}
Endpoint_ClearOUT();
}
/**
*Défile le message écrit dans l'EEPROM au clavier
*/
int display_from_eeprom(int cpt){
int verif = 0;
for(int c = 0; c < NB_COLS; c++){
char m = eeprom_read_byte((c+cpt) % 32);
int address=HD44780_XY2Adrr(NB_ROWS,NB_COLS,0,c);
HD44780_WriteCommand(LCD_ADDRSET|address);
if(m == '\0') {
verif = 1;
HD44780_WriteData(' ');
}
else
HD44780_WriteData(m);
}
return verif;
}
Démonstrations
Affichage d'un message en dur sur l'écran :
Défilement du message en dur :
Message transmis par USB :
Rendus
Projet KiCAD : Fichier:I2L-2023-Carte-G3.zip
Programmes : Fichier:I2L-2023-Programmes-G3.zip