02/12/2021
Liaison RS232 et AFFICHEUR LUNARTEC et Linux
Pré-requis
Linux shell , vi , gcc , langage C , cours C fichier , cours liaison serie et usage termios. (en texte)
Et utilisation de la lib QSerialPort de Qt pour finir en beauté. (en graphique)
PC Linux ubuntu 22.04 LTS
But
Utilisation de la liaison serie sous linux en émission.
Utilisation d'un afficheur du commerce, lecture de la documentation constructeur.
Usage le la liaison série sous linux , /dev/ttyS0 , stty , gestion de fichier
Utilisation de la liaison série en Shell et en C
Le but du TP est d’être a l'aise avec la liaison série.
Langage C , passage de paramètres (argc , argv , sprintf, open , close )
Pour vérifier le nom de votre port série :
sudo dmesg | grep tty
normalement c'est /dev/ttyS0 qui correspond au COM1 sous windows, mais selon les salles les machines ne sont pas les mêmes il va falloir adapter, un récapitulatif des salles et des cartes sérielles est donné un peu plus bas (salle E301,E302,E304)
Pour ne pas être root pour avoir le droit d'utiliser les ports Séries il faut appartenir au groupe dialout.
En root !! attention vous devenez root donc les variables $USER et $LOGNAME sont pour ROOT !
en étant dans votre compte : (pas root )
sudo adduser $USER dialout
sudo usermod -a -G dialout $LOGNAME
Vérifier qui est $USER ? qui est $LOGNAME avant de lancer les commandes !
Sinon adapter les commandes pour ajouter l'utilisateur que vous êtes pour le mettre dans le groupe dialout
Vérifier le contenu du fichier /etc/group
Pour valider déconnecter votre session et revenez vérifier que vous avez le droit d’écrire et lire sur ce périphérique.
vérification que la machine vous a dans le groupe dialout:
groups
bruno adm dialout cdrom sudo dip www-data plugdev lpadmin sambashare kvm wireshark
Device tty (liaison rs232) des différentes salles du lycée
E301 :La prise DB9 la plus a gauche (vue de l'arrière) est ttyS5 et l'autre ttyS4 à droite
E302 : sur la carte mère DB9 ttyS0 (ttyS4 non accessible du boitier)
E304: une prise DB9 ttyS5
work@worktosh:~$ stty -F /dev/ttyS0
speed 9600 baud; line = 0;
-brkint -imaxbel
man stty
pour connaitre cette commande qui permet de configurer les ports séries sous linux.
Les câbles sont a demander au professeur. (prévoir de le rendre a la fin de la séance ! ne pas le visser !)En binôme (voisin) connecter vos pc par le câble NULL MODEM
Vérifier que les 2 machines /dev/ttyXX soient bien configurer a la même vitesse, à l'aide de la commande stty
Pour commencer :
=> 300 b/s (stty -F /dev/ttyS0 speed 300)
Comme sous Unix / Linux tout est fichier ....
Sur le PC1
cat /dev/ttyXX
Sur le PC2
ls > /dev/ttyXX
echo "Bonjour le monde" > /dev/ttyXX
Cette commande va diriger les caractères de la fonction ls sur la liaison série.
constater !
Recommencer les mêmes manipulations (dans l'autre sens ouvrir plusieurs terminaux)
Même Manipulation pour les vitesses de 1200 b/s , 4800 b/s, 9600 b/s , 115200 b/s
Que voyez vous ?
echo , more , cat .. etc
sudo apt update && sudo apt install putty
Refaire les même manipulation avec Putty
Réaliser un dialogue entre vos 2 machines et Putty
Suivant la documentation du Lunartec ici présente : PE9441_12_65915.PDF
Retrouver dans la documentation constructeur la vitesse ,et comment sont les trames et les différentes balises.
Il n'existe aucun logiciel pour le lunartec sous windows , votre mission si vous l’acceptez et de réaliser un utilitaire pour utiliser facilement cet afficheur sous linux.
Après avoir pris connaissance de la documentation de cet afficheur nous avons 2 commandes importantes
En 9600 b/s pour notre afficheur
=>
stty -F /dev/ttyXXX speed 9600
Commande pour donner un numèro d'identifiant à votre afficheur (voir la DOC du LUNARTEC bien sur !!)
<ID><XX><E>
XX est le numéro d'identifiant en hexadécimal de l'afficheur que l'on va lui attribuer.
Car sur une même ligne TxD nous pouvons piloter d'autres afficheurs , qui auront d'autres identifiants.
=>
256 , 0x00 à 0xFF
=>
echo -n "<ID><00><E>" > /dev/ttyXX
# pour lui donner 00 comme identifiant
<ID00><L0><PB><FA><Mb><WB><FB>Dorian SNIR4e<E>
<ID00><L0><PB><FA><Mb><WB><FB>Bonjour le monde72<E>
le checksum se calcul sans la balise <ID00>
Questions facultatives
7-1 A quoi sert la balise <L0>
7-2 A quoi sert la balise <PB>
...
Le code en Hexadécimal en bleu se doit d'être calculé à chaque nouvelle phrase envoyée.
CS : Check Sum de OU exclusif. ^ pour le Ou exclusif en C.
Ici avec la chaine "<L0><PB><FA><Mb><WB><FB>Dorian SNIR"
On obtient le checksum avec ou exclusifs 0x4e en hexadécimal pour la chaine "<L0><PB><FA><Mb><WB><FB>Dorian SNIR"
la valeur du code ASCII '<' ^ 'L' ^ '0' ^ ..... ^'R' = 0x4e
man ascii
^ est l'opérateur ou exclusif. Comme indiqué sur la documentation du lunartec
Exemple pour envoyer AB sur l'afficheur.
[bruno@pollux:~/Works/lunartecV0/chksum] ./chkslunartec "<L0><PB><FA><Mb><WB><FB>"
57
[bruno@pollux:~/Works/lunartecV0/chksum]
57 ^"AB" = 0x54 comme checksum avec ou ex
0x57^0x41^0x42 = 0x54
[bruno@pollux:~/Works/lunartecV0/chksum] ./chkslunartec "<L0><PB><FA><Mb><WB><FB>AB"
54
echo "<ID00><L0><PB><FA><Mb><WB><FB>AB54<E>" > /dev/ttyXX
Ecrire un code en C qui permet d'obtenir cela:
./lunartec "<L0><PB><FA><Mb><WB><FB>Dorian SNIR"
4e
L'afficheur pourra afficher "Je suis le meilleur codeur du monde , bonjour le monde"
CHAINE est une chaine de caractere finissant par un caractère NULL
check est une variable entiere sur 8 bits
check =0
programme principal :
Si pas d'argument quitter en expliquant qu'il faut un argument.
Pointer au debut de l'argument
Tant que le pointeur ne pointe pas sur NULL faire
debut
check = check ou exclusif code ascii du caractere pointé dans l'argument
pointer l’élément suivant
fin
Afficher en hexadecimal check
Pour ne pas rester bloqué sur ce tp , comprendre et s'approprier ce code.
#include <stdio.h>
#include <stdlib.h>
int main (int argc,char **argv)
{
int i=0,cs=0;
if (argc!=2)
{
printf(" un argument SVP \n");
return (EXIT_FAILURE);
}
while (argv[1][i]!=0)
{
/* CS avec des ou exclusif */
cs=(argv[1][i++])^cs;
}
printf("%02x\n",cs); /* Afficher sur 2 digits %02x en hexa */
return (EXIT_SUCCESS);
}
En Shell vous pouvez tester vos chaines de caractères.
nom prenom > sur l'afficheur suivant le protocole Lunartec
Une fonction pour générer un checksum ou exclusif
unsigned char CheckSum(char *chaine)
unsigned char CheckSum(char * chaine)
{
int compteur;
unsigned char Calcs;
/* code a complèter */
}
return(Calcs);
}
intégrer cette fonction dans un code de test unitaire.
valider tester.
Et d'envoyer des caratères A sur la liaison serie, fournit gracieusement pour le tp.
./open /dev/ttyS0
.. modifier ce programme pour envoyer des textes
./lunartec /dev/ttyS0 "Vive le lycee Dorian"
Tous les messages seront affichables grâce a votre code.
Permet de régler la vitesse du port série que l'on va utiliser pour notre afficheur.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
int main() {
/* Ouvrir le port série ttyS0 */
int serial_port = open("/dev/ttyS0", O_RDWR);
if (serial_port < 0) {
printf("Erreur lors de l'ouverture du port série: %s\n", strerror(errno));
return EXIT_FAILURE;
}
/* Struct pour configurer les paramètres du port série */
struct termios tty;
/* Lire les paramètres actuels du port série */
if (tcgetattr(serial_port, &tty) != 0) {
printf("Erreur lors de la lecture des attributs: %s\n", strerror(errno));
close(serial_port);
return EXIT_FAILURE;
}
/* Configurer la vitesse d'entrée et de sortie à 9600 bauds */
cfsetispeed(&tty, B9600);
cfsetospeed(&tty, B9600);
/* Configurer le nombre de bits de données (8 bits) */
tty.c_cflag &= ~CSIZE; // Clear les bits de taille de caractère
tty.c_cflag |= CS8; // 8 bits par mot
/* Configurer 2 bits de stop */
tty.c_cflag |= CSTOPB;
/* Désactiver la parité */
tty.c_cflag &= ~PARENB;
/* Désactiver le contrôle matériel (RTS/CTS)*/
tty.c_cflag &= ~CRTSCTS;
/* Activer la lecture, désactiver le contrôle local */
tty.c_cflag |= CREAD | CLOCAL;
/* Désactiver le mode canonique, l'écho, et la génération de signaux */
tty.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
/* Désactiver le contrôle de flux en entrée et en sortie */
tty.c_iflag &= ~(IXON | IXOFF | IXANY);
/* Configurer la sortie brute (Raw mode) */
tty.c_oflag &= ~OPOST;
/* Appliquer les paramètres au port série */
if (tcsetattr(serial_port, TCSANOW, &tty) != 0) {
printf("Erreur lors de l'application des attributs: %s\n", strerror(errno));
close(serial_port);
return EXIT_FAILURE;
}
printf("Configuration du port série réussie.\n");
// Fermer le port série
close(serial_port);
return EXIT_SUCCESS;
}
Ecrire un programme qui envoie la chaîne directement sur l'afficheur par exemple:
./lunartec "Bonjour le monde"
le calcul du checksum se fera en fonction de la chaine passée en paramètre.
utiliser string.h pour jouer avec les chaines de caractères
Indices : sprintf peut être très utile
un printf dirigé vers une chaîne !
et strcpy et strcat aussi de la librairie string
./lunartec help
Donne une aide du logiciel
Cette question n'est pas obligatoire.
Version Qt ! pour ceux qui ont du temps et connaissent Qt
Ce petit projet en Qt permet de voir comment on peut utiliser la classe QserialPort
Installation de QserialPort (Qt5)
sudo apt update
sudo apt install libqt5serialport5
sudo apt install libqt5serialport5-dev
Dans le .pro, avoir cette ligne :
QT += serialport
Pour vous aider à terminer le projet il faut calculer le checksum (cs)
void MainWindow::on_pushButton_clicked()
{
QString str ="<L0><PB><FA><Mb><WB><FB>Dorian SNIR";
QString hexa;
QByteArray ChaineAscii = str.toUtf8();
unsigned char cs=0;
for (int compteur=0; compteur<ChaineAscii.length() ; compteur++)
{
cs=cs^ChaineAscii[compteur];
}
hexa.setNum(cs,16);
qDebug()<<hexa;
}