Communiquer entre un PC et la carte STM32 Nucleo
Maintenant que la carte STM32 Nucleo a été prise en main grâce au tutoriel précédent, il faut commencer à retrouver ses marques en explorant les différentes possibilités de la carte.
L'objectif du présent document est d'explorer comment communiquer entre un ordinateur et la carte STM32 Nucleo à travers du port série. L'utilisation du port série sous mbed est très proche de celle que l'on retrouve dans l’environnement arduino. D'ailleurs, il est tout à fait possible d'utiliser le moniteur série d'arduino pour communiquer avec la carte Nucleo.
La communication série est souvent utilisée soit comme solution de débogage du pauvre soit comme un moyen de dialoguer avec sa carte. Il est donc très important de prendre le temps d'appréhender les différentes possibilités qui nous sont offertes par mbed pour utiliser les périphériques séries.
Sommaire
- 1 La recette
- 1.1 Ingrédients
- 1.2 Préparation des ingrédients
- 1.3 Etape 1 : Communication Nucléo -> PC
- 1.4 Etape 2 : Communication Nucléo -> PC (Bis)
- 1.5 Etape 3 : Communication PC -> Nucleo
- 1.6 Etape 4 : Communication PC -> Nucleo et utilisation des interruptions
- 1.7 Etape 5 : Communication sans fil
- 1.8 Conclusion
La recette
Temps de préparation : 10 minutes
Temps de cuisson : 60 minutes
Ingrédients
Voici la liste des ingrédients utilisés pour faire ce tutoriel :
- Une carte Nucleo L152RE.
- Un ordinateur avec un navigateur compatible mbed (désolé pour les utilisateurs d'IE6).
- Une breadboard et les câbles qui vont avec.
- Un cable mini-USB (c'est devenu assez rare donc quand vous en avez un faites attention de pas vous le faire piquer).
- Un programme de communication sur le port série (l'outil présenté ci-dessous peut être remplacé par l'hyperterminal sous Windows ou le moniteur série de l'IDE Arduino)
Préparation des ingrédients
Parmi les ingrédients requis pour cette recette, seul le dernier nécessite une préparation préalable. Sous Linux il y a de très nombreux outils qui permettent de communiquer avec le port série. Le but de ce document n'étant pas de faire un usage avancé du port série, l'outils choisi est volontairement simple et accessible au plus grand nombre.
Moserial est un terminal série pour le bureau gnome. Il est simple et surtout est présent dans les dépôts officiels des principales distributions Linux.
fonctionnalités :
- Vue ASCII et HEX des données entrantes et sortantes
- Journalisation dans des fichiers données entrantes et/ou sortantes
- Gestion de profiles pour mémoriser les configurations courantes
- Plus facile à faire fonctionner que le classique Minicom
- Support de l'internationalisation
- Et en plus il a une documentation !
Installation
Pour l'installer sur une distribution Debian-like, il suffit de suivre ces quelques étapes.
- Ouvrir un terminal
- Mettre à jour le cache d'apt
sudo apt-get update
- Installer le programme
sudo apt-get install moserial
Si tout se déroule bien moserial est installé et prêt à être utilisé.
Utilisation
Avant de l'utiliser, il faut connaitre le nom de périphérique associé au port série de la carte Nucleo. Après avoir branché votre carte sur un port USB, lancez cette commande dans un terminal :
dmesg | grep tty
Vous devriez obtenir la une sortie comme celle-la :
[ 0.000000] console [tty0] enabled
[794.112918] usb 2-1.4: FTDI USB Serial Device converter now attached to ttyUSB0
[920.269137] cdc_acm 2-1.4:1.2: ttyACM1: USB ACM device
La dernière ligne vous indique le port sur lequel votre carte est connectée, dans ce cas c'est /dev/ttyACM0. Notez le ça nous servira lors du paramétrage du logiciel.
Maintenant ouvrez moserial par la méthode que vous préférez (cliquage de menu, ALT-F2, terminal, ...). Vous devriez obtenir la fenêtre suivante :
Le champ texte du haut est celui qui contient les données reçu par l'ordinateur et celui du bas les données que l'on a envoyé. Avant de se connecter à la carte il faut paramétrer le port utilisé. Pour ce faire cliquez sur la petite flèche à l'extrémité droite de la barre de menu. Vous devriez voir apparaître un menu avec une option "Paramétrage de port". Cliquez dessus pour voir apparaître la boite de dialogue suivante :
Modifiez les réglages pour qu'ils correspondent avec ceux de votre carte. Ici seul le paramètre "Périphérique" est important car les autres pourront être adapté au moment ou la carte sera programmée.
Pour vérifier que le paramétrage est correct cliquez sur le bouton "Connecter". Si tout va bien rien ne devrait se passer pour l'instant. À partir de ce moment la préparation de l'environnement est terminée. Les choses sérieuse vont vraiment commencer.
Etape 1 : Communication Nucléo -> PC
Le programme à écrire lors de cette étape va envoyer chaque seconde sur le port série une chaîne de caractères indiquant depuis combien de temps il fonctionne. Pour indiquer visuellement que le programme est actif nous ferons clignoter la LED de la carte au même rythme.
- Tout d'abord, en vous inspirant du [Débuter_avec_la_carte_STM32_Nucleo|tutoriel précédent], créez un nouveau programme appelez "Serial_Communication_Nucleo_to_PC".
- Importez la librairie "mbed" en cliquant sur le bouton "import".
- Créez un nouveau fichier source appelé "main.cpp". Pour retrouver les habitudes d'Arduino, ce fichier contiendra les deux fonctions "setup()" et "loop()" qui seront appelées dans la fonction "main()" suivant la même convention que dans les sketchs Arduino.
#include "mbed.h"
void setup()
{
}
void loop()
{
}
int main()
{
setup();
while(1) {
loop();
}
}
Déclarez les différentes variables dont on aura besoin. Au minimum on aura besoin d'un objet pour manipuler le port série permettant de communiquer avec le PC, d'une sortie numérique pour la LED d'état et un entier pour décompter le temps de fonctionnement.
Ajoutez le code suivant juste après la directive "#include" :
Serial pc(SERIAL_TX, SERIAL_RX);
DigitalOut stateLed(LED1);
int i = 0;
Une fois ces variables déclarées et initialisées, il faut faire tout les réglages dans la fonction "setup()". Ici les réglages correspondront à ceux préconisé pour le réglage de moserial.
- La vitesse de transmission (baud rate) est réglée à 115 200 baud/s avec la méthode "baud()",
- Le format des trames est réglé avec des mots d'une longueur de 8 bits, pas de bit de parité (SerialBase::None) et un bit d’arrêt avec la méthode "format".
void setup()
{
// Serial port configuration : 115200 bauds, 8-bit data, no parity, Stop bit 1
pc.baud(115200);
pc.format(8, SerialBase::None, 1);
pc.printf("Run little program !! Run !!\n");
}
À chaque tour de boucle le programme devra afficher son temps de fonctionnement, mettre à jour l'état de la LED et s'endormir pendant 1 seconde. La transmission sur le port série se fait grâce à la fonction "printf". La classe ["Serial"] héritant de la classe ["Stream"] elle dispose de plusieurs autres méthodes qui sont similaire aux fonctions que l'on trouve dans le fichier "stdio.h" du langage C.
void loop()
{
pc.printf("I run since %d seconds.\n", i++);
stateLed = !stateLed;
wait(1);
}
Compilez votre programme pour obtenir le fichier .bin à copier dans la carte.
Quand le programme est chargé dans votre carte et que la LED verte se met à clignoter, revenez sur moserial et cliquez sur le bouton "Connecter". Si tout se passe bien vous devriez avoir une fenêtre similaire à ceci :
Pendant mes essais, la carte mettait plus de 30 secondes à initialiser le port série correctement. Il fallait donc attendre (ou réessayer frénétiquement) avant d'arriver à obtenir l'écran ci-dessus. Je ne sais pas si ce comportement vient de mon OS ou de la carte elle-même.
Etape 2 : Communication Nucléo -> PC (Bis)
Le montage précédent bien que fort rigolo ne servait absolument à rien. Pour améliorer les choses, nous allons essayer d'envoyer au PC des données potentiellement plus utiles que le temps de fonctionnement. L'exemple présenté rajoutera au montage précédent un capteur d'humidité/température RHT03/DTH22. L'objectif du montage est d'envoyer à intervalle de temps régulier la température et l'humidité ambiante.
L'avantage de ce composant est qu'il existe une librairie dans mbed qui permet de l'utiliser facilement.
Au niveau du câblage rien d'extraordinaire, le composant est branché comme l'indique la documentation avec une résistance de pull-up de 1k sur la ligne de données. La pin sur laquelle le composant transmet ses informations est la D7.
Le code que l'on va injecter dans la carte Nucleo sera quasiment le même que précédemment mis à part l'utilisation de la bibliothèque RHT03.
#include "mbed.h"
#include "RHT03.h" //Include neede to use the RHT03 lib
RHT03 humtemp(D7); //Initalise the RHT03 (change pin number to the pin its connected to)
Serial pc(SERIAL_TX, SERIAL_RX);
DigitalOut stateLed(LED1);
void setup()
{
// Serial port configuration : 115200 bauds, 8-bit data, no parity, Stop bit 1
pc.baud(115200);
pc.format(8, SerialBase::None, 1);
pc.printf("Run little program !! Run !!\n");
wait(2); //Needed to make sure the sensor has time to initalise
}
void loop()
{
stateLed = !stateLed;
float temp;
float hum;
while(humtemp.readData() != RHT_ERROR_NONE) wait(1); //Loop keeps running until RHT03 is read succesfully
temp = humtemp.getTemperatureC(); //Gets the current temperature in centigrade
hum = humtemp.getHumidity(); //Gets the current humidity in percentage
pc.printf("Temperature = %f, Humidity = %f\n",temp,hum);
}
int main()
{
setup();
while(1) {
loop();
}
}
De la même façon que lors de l'étape précédente, on peut vérifier le bon fonctionnement du montage avec "moserial".
Etape 3 : Communication PC -> Nucleo
Le troisième montage est un grand classique de l'utilisation du port série. Cette fois-ci c'est l'ordinateur qui va envoyer des données à la carte Nucleo. Les données envoyés seront des commandes que la carte devra exécuter. L'idée étant ici de montrer principalement comment communiquer du PC vers la board, le montage sera un très classique montage avec une LED RGB. Les commandes reçues seront de la forme suivante :
- <Commande> ::= <Couleur>\r\n
- <Couleur> ::= R|G|B
Par exemple pour changer d'état la LED Rouge, il faudra envoyer comme instruction la chaîne de caractère "R\r\n".
Commençons par le montage :
La LED rouge est connectée sur la pin D3, la verte sur la D6 et la bleue sur la D9.
Le programme que l'on va proposer va s'inpirer de l'exemple "Nucleo_Blink_Led" sur lequel on va rajouter 2 LEDs.
#include "mbed.h"
DigitalOut redLed(D3);
DigitalOut greenLed(D6);
DigitalOut blueLed(D9);
Serial pc(SERIAL_TX, SERIAL_RX);
void setup()
{
redLed = 0;
greenLed = 0;
blueLed = 0;
// Serial port configuration : 115200 bauds, 8-bit data, no parity, Stop bit 1
pc.baud(115200);
pc.format(8, SerialBase::None, 1);
pc.printf("Run little program !! Run !!\n");
}
void loop()
{
if(pc.readable()){
char color;
color = pc.getc();
switch(color)
{
case 'R' :
redLed = !redLed;
break;
case 'G' :
greenLed = !greenLed;
break;
case 'B' :
blueLed = !blueLed;
break;
}
}
}
int main()
{
setup();
while(1) {
loop();
}
}