Pour réaliser les trames Modbus que j’avais besoin, je me suis aidé de la documentation « DMG_MODBUS_FR Rev1.2_300718 » disponible dans la bibliothèque de connaissance avec le mot clé « DITEL » « Modbus » et « ASCII » ainsi que du logiciel Dynamic 3 en consultant le script qu’il générait.
Un afficheur DITEL dispose de deux registres Modbus :
- Le premier registre %MW256 permet de communiquer en Caractères ASCII hexadécimaux ;
- Le second registre %MW514 en Variables.
4.1 Registre %MW256
4.1.1 Préfixe de la fenêtre 1
(* Luminosité 100% *)
TAB_BYTE[0] := 16#03;
TAB_BYTE[1] := 16#D0;
TAB_BYTE[2] := 16#31;
TAB_BYTE[3] := 16#30;
TAB_BYTE[4] := 16#30;(* Alignement *)
TAB_BYTE[5] := 16#03;
TAB_BYTE[6] := 16#CD;
TAB_BYTE[7] := 16#30;(* Synchronisme *)
TAB_BYTE[8] := 16#03;
TAB_BYTE[9] := 16#C9;(* Fenêtre *)
TAB_BYTE[10] := 16#03;
TAB_BYTE[11] := 16#D3;
TAB_BYTE[12] := 16#41;(* ID de la fenêtre (A)*)
TAB_BYTE[13] := 16#2C;(* , *)
TAB_BYTE[14] := 16#31;(* x1: Numéro de colonne où commence la fenêtre (côté droit) (1) *)
TAB_BYTE[15] := 16#2C;(* , *)
TAB_BYTE[16] := 16#31;(* y1: Numéro de ligne où commence la fenêtre (côté bas) (1) *)
TAB_BYTE[17] := 16#2C;(* , *)
TAB_BYTE[18] := 16#36;(* x2: Numéro de colonne où finit la fenêtre (côté gauche) (48) *)
TAB_BYTE[19] := 16#34;
TAB_BYTE[20] := 16#2C;(* , *)
TAB_BYTE[21] := 16#31;(* y2: Numéro de ligne où finit la fenêtre (coté haut) (1) *)(* Police Normal 7 pixel *)
TAB_BYTE[22] := 16#03;
TAB_BYTE[23] := 16#C1;
TAB_BYTE[24] := 16#38;(* Temps d'attente 1 seconde *)
TAB_BYTE[25] := 16#03;
TAB_BYTE[26] := 16#C5;
TAB_BYTE[27] := 16#34;(* Vitesse du mode d'apparition 97 *)
TAB_BYTE[28] := 16#03;
TAB_BYTE[29] := 16#C4;
TAB_BYTE[30] := 16#39;
TAB_BYTE[31] := 16#37;(* Mode d'affichage *)
TAB_BYTE[32] := 16#04;
IF ModeAffichage = 1 THEN
TAB_BYTE[33] := 16#E0; (* Défiler *)
ELSIF ModeAffichage = 2 THEN
TAB_BYTE[33] := 16#E5; (* Monter *)
ELSIF ModeAffichage = 3 THEN
TAB_BYTE[33] := 16#E6; (* Descendre *)
ELSE
TAB_BYTE[33] := 16#F0; (* Imédiat *)
END_IF;(* Fin *)
TAB_BYTE[34] := 16#00;FOR index :=0 TO 38 BY 2 DO
TAB_Int[index/2] := WORD_TO_INT(BYTE_AS_WORD (TAB_BYTE[index+1], TAB_BYTE[index]));
END_FOR;Prefixe := ascii_to_string(TAB_Int);
4.1.2 Afficher une variable
Chaîne de caractère à envoyer pour afficher une variable :
Variable_TAB_Int := string_to_ascii(LETTRE_VAR);(* Affichage variable *)
TAB_BYTE[0] := 16#03;
TAB_BYTE[1] := 16#AB;
TAB_BYTE[2] := 16#34;
TAB_BYTE[3] := 16#2E;
TAB_BYTE[4] := 16#32;
WORD_AS_BYTE (IN := INT_TO_WORD(Variable_TAB_Int[0]),
HIGH => TAB_BYTE[5]);
TAB_BYTE[6] := 16#1F;
TAB_BYTE[7] := 16#20;
TAB_BYTE[8] := 16#6D;(* Fin *)
TAB_BYTE[9] := 16#00;FOR index:=0 TO 38 BY 2 DO
TAB_Int[index/2] := WORD_TO_INT(BYTE_AS_WORD (TAB_BYTE[index+1], TAB_BYTE[index]));
END_FOR;Variable := ascii_to_string(TAB_Int);
Préparer la chaîne de caractère à envoyer pour afficher une variable.
4.1.3 Préfixe de la fenêtre 2
Si les paramètres telles que la luminosité, l'alignement, la police ou le temps d’attente ne sont pas réécrits, il conserve la dernière instruction envoyée.
Par exemple dans la 2e fenêtre, on a choisi de modifier la police. On a renvoyé le prétoken + token 03 C1 avec le code de la nouvelle police.
(* Fenêtre *)
TAB_BYTE[0] := 16#03;
TAB_BYTE[1] := 16#D3;
TAB_BYTE[2] := 16#42;(* ID de la fenêtre (B)*)
TAB_BYTE[3] := 16#2C;(* , *)
TAB_BYTE[4] := 16#31;(* x1: Numéro de colonne où commence la fenêtre (coté droit) (1) *)
TAB_BYTE[5] := 16#2C;(* , *)
TAB_BYTE[6] := 16#33;(* y1: Numéro de ligne où commence la fenêtre (coté bas) (1) *)
TAB_BYTE[7] := 16#2C;(* , *)
TAB_BYTE[8] := 16#36;(* x2: Numéro de colonne où finit la fenêtre (coté gauche) (48) *)
TAB_BYTE[9] := 16#34;
TAB_BYTE[10] := 16#2C;(* , *)
TAB_BYTE[11] := 16#34;(* y2: Numéro de ligne où finit la fenêtre (coté haut) (1) *)(* Police Normal 14 pixel *)
TAB_BYTE[12] := 16#03;
TAB_BYTE[13] := 16#C1;
TAB_BYTE[14] := 16#30;TAB_BYTE[15] := 16#04;
IF ModeAffichage = 1 THEN
TAB_BYTE[16] := 16#E0; (* Défiler *)
ELSIF ModeAffichage = 2 THEN
TAB_BYTE[16] := 16#E5; (* Monter *)
ELSIF ModeAffichage = 3 THEN
TAB_BYTE[16] := 16#E6; (* Descendre *)
ELSE
TAB_BYTE[16] := 16#F0; (* Imédiat *)
END_IF;(* Fin *)
TAB_BYTE[17] := 16#00;FOR index:=0 TO 38 BY 2 DO
TAB_Int[index/2] := WORD_TO_INT(BYTE_AS_WORD (TAB_BYTE[index+1], TAB_BYTE[index]));
END_FOR;Prefixe := ascii_to_string(TAB_Int);
4.1.4 Suffixe
Il est possible d’ajouter un suffixe pour effacer le texte lors d’un défilement, par exemple :
(* Effacer *)
TAB_Int[0] := 16#02B2;
Sufixe := ascii_to_string(TAB_Int);
4.1.5 Page fixe
Ensuite, j’ai créé un tableau de six pages de deux fenêtres chacune où on peut paramétrer le texte à afficher, le mode d’affichage ainsi que le temps d’affichage.
Le client a fait le choix que les deux premières pages soient fixes et qu’il puisse paramétrer les suivantes.
Sur la première page, c’est un message d’accueil en breton et en français.
La deuxième page s’affiche uniquement lorsque la porte est ouverte : la hauteur de passage s’affiche.
(* Texte à afficher non paramétrable *)
VARIABLE_A (LETTRE_VAR := 'A');
VARIABLE_B (LETTRE_VAR := 'B');AffMer_Page[0].TPS_AFF := 5;
AffMer_Page[0].FENETRE1.Texte := 'DEGEMER MAD';
AffMer_Page[0].FENETRE1.Mode := 3;
AffMer_Page[0].FENETRE2.Texte := 'BIENVENUE A PERROS-GUIREC';
AffMer_Page[0].FENETRE2.Mode := 1;AffPort_Page[0].FENETRE1.Texte := 'KENAVO';
AffPort_Page[0].FENETRE1.Mode := 3;
AffPort_Page[0].FENETRE2.Texte := 'A BIENTOT A PERROS-GUIREC';
AffPort_Page[0].FENETRE2.Mode := 1;IF SEQ_GESTION_PORTE.ETAT01.1 THEN
AffMer_Page[1].TPS_AFF := 10;
AffMer_Page[1].FENETRE1.Texte := 'HAUTEUR PASSAGE SEUIL ';
AffMer_Page[1].FENETRE1.Mode := 1;
AffMer_Page[1].FENETRE2.Texte := VARIABLE_A.Variable;
AffMer_Page[1].FENETRE2.Mode := 0;AffPort_Page[1].FENETRE1.Texte := 'HAUTEUR PASSAGE SEUIL ';
AffPort_Page[1].FENETRE1.Mode := 1;
AffPort_Page[1].FENETRE2.Texte := VARIABLE_A.Variable;
AffPort_Page[1].FENETRE2.Mode := 0;ELSE
AffMer_Page[1].FENETRE1.Texte := '';
AffMer_Page[1].FENETRE2.Texte := '';AffPort_Page[1].FENETRE1.Texte := '';
AffPort_Page[1].FENETRE2.Texte := '';
END_IF;
4.1.6 Préparer le message à afficher
Concaténation des différentes chaînes de caractère pour envoi à l’afficheur.
(* Texte afficheur côté mer *)AFF_MER_FENETRE1_PREFIXE (ModeAffichage := AffMer_Page[SEQ_COM_AFF.INT01].FENETRE1.Mode);
AFF_MER_FENETRE2_PREFIXE (ModeAffichage := AffMer_Page[SEQ_COM_AFF.INT01].FENETRE2.Mode);AffMer_Concat := '';
AffMer_Concat := CONCAT_STR (AffMer_Concat, AFF_MER_FENETRE1_PREFIXE.Prefixe);
AffMer_Concat := CONCAT_STR (AffMer_Concat, AffMer_Page[SEQ_COM_AFF.INT01].FENETRE1.Texte);
AffMer_Concat := CONCAT_STR (AffMer_Concat, AFF_MER_FENETRE2_PREFIXE.Prefixe);
AffMer_Concat := CONCAT_STR (AffMer_Concat, AffMer_Page[SEQ_COM_AFF.INT01].FENETRE2.Texte);TAB_ENVOI_AFF_1 := string_to_ascii(AffMer_Concat);
(* Afficheur Noir ditel *)
WRITE_VAR (ADR := ADDM('0.1.0{10.100.0.2}'),
OBJ := '%MW',
NUM := 256,
NB := 120,
EMIS := TAB_ENVOI_AFF_1,
GEST :=TAB_GEST_AFF );
4.2 Registre %MW514
Comme vue précédemment, sur la page 2, on a fait le choix d’afficher la variable A. La valeur à afficher est à envoyer au deuxième registre.
TAB_ENVOI_AFF_1[0]:=2; (* Pour indiquer que la variable est de type numérique 32 bit *)
TAB_ENVOI_AFF_1[1]:=0; (* NC *)
TAB_ENVOI_AFF_1[2]:=real_to_int((MER_LT-3.6)*100.0); (* Poids faible de la valeur *)
TAB_ENVOI_AFF_1[3] := 0; (* Poids fort de la valeur *)
TAB_ENVOI_AFF_1[4] := 2; (* Nombre de décimales *)
TAB_ENVOI_AFF_1[5] := 0; (* Couleur *)
0 et 1 Configuration des variables
2 à 5 Variable A
6 à 9 Variable B
…
102 à 105 Variable Z.
(* Afficheur Noir ditel *)
WRITE_VAR (ADR := ADDM('0.1.0{10.100.0.2}'),
OBJ := '%MW',
NUM := 514,
NB := 6,
EMIS := TAB_ENVOI_AFF_1,
GEST :=TAB_GEST_AFF );