{"id":1431,"date":"2021-12-05T19:08:27","date_gmt":"2021-12-05T18:08:27","guid":{"rendered":"https:\/\/avionicsduino.com\/?page_id=1431"},"modified":"2025-09-26T22:25:22","modified_gmt":"2025-09-26T21:25:22","slug":"transmission-des-variables-numeriques-par-liaison-serie-uart-ou-can","status":"publish","type":"page","link":"https:\/\/avionicsduino.com\/index.php\/fr\/transmission-des-variables-numeriques-par-liaison-serie-uart-ou-can\/","title":{"rendered":"Transmission des valeurs num\u00e9riques par liaison s\u00e9rie (UART ou CAN)"},"content":{"rendered":"\n<p style=\"font-size:10px\"><em>(Page mise \u00e0 jour le 5\/12\/2021)<\/em><\/p>\n\n\n\n<p>Ce sujet est abord\u00e9 sur un grand nombre de forums Internet et de sites  Web, bien souvent sans apporter de solution simple, claire et efficace. Cette probl\u00e9matique nous concerne en avionique, o\u00f9 des modules ind\u00e9pendants doivent communiquer et \u00e9changer des donn\u00e9es num\u00e9riques. C&rsquo;est par exemple le cas dans notre<a href=\"https:\/\/avionicsduino.com\/index.php\/fr\/efis\/\" title=\"EFIS\"> EFIS<\/a>, o\u00f9 l&rsquo;<a href=\"https:\/\/avionicsduino.com\/index.php\/fr\/lahrs\/\" title=\"AHRS\">AHRS<\/a> et le<a href=\"https:\/\/avionicsduino.com\/index.php\/fr\/le-compas-digital\/\" title=\"Compas digital\"> magn\u00e9tom\u00e8tre distant<\/a> doivent communiquer avec le module principal. La transmission s\u00e9rie de caract\u00e8res ou de chaines de caract\u00e8res est tr\u00e8s simple, mais l&rsquo;envoi et la r\u00e9ception de variables num\u00e9riques cod\u00e9es sur plusieurs octets est moins intuitive, en particulier pour les nombres d\u00e9cimaux. Il y a plusieurs solutions possibles, le but de cette page est d&rsquo;exposer les principales, avec leurs avantages et leurs inconv\u00e9nients. La meilleure solution devra r\u00e9pondre \u00e0 ce cahier des charges : \u00eatre efficiente, avoir le code le plus compact possible, \u00eatre utilisable quel que soit le type de variable num\u00e9rique, quel que soit le type de transmission s\u00e9rie (UART ou CAN bus) et ne pas entra\u00eener de perte de pr\u00e9cision des donn\u00e9es num\u00e9riques transmises.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">La conversion en chaines de caract\u00e8res<\/h3>\n\n\n\n<p>Il faut le dire d&#8217;embl\u00e9e, c&rsquo;est la pire des solutions, elle est pourtant tr\u00e8s souvent \u00e9voqu\u00e9e sur les forums. Soit par exemple la variable x, de type float, et de valeur 3.14159274. Par une liaison s\u00e9rie UART, la fonction Arduino bien connue Serial.print(x,8) va certes parfaitement transmettre la chaine de 10 caract\u00e8res \u00ab\u00a03.14159274\u00a0\u00bb sur le terminal s\u00e9rie, ce qui pourrait sembler un bon d\u00e9but. Mais la voie s\u00e9rie a transmis 10 octets, alors que la variable float d&rsquo;origine n&rsquo;est cod\u00e9e que sur 4 octets. Donc ce n&rsquo;est pas tr\u00e8s efficient. Les probl\u00e8mes vont s&rsquo;accumuler lors de la r\u00e9ception. Il va falloir charger les caract\u00e8res re\u00e7us les uns \u00e0 la suite des autres, soit dans un objet de type String, soit dans un tableau de char (qu&rsquo;il faudra surdimensionner, pour s&rsquo;adapter aux nombres compos\u00e9s de beaucoup de chiffres). On pourra ensuite appliquer assez simplement la fonction toFloat() \u00e0 l&rsquo;objet String, ou la fonction atof() au tableau de char, fonctions qui se chargent de la conversion vers une variable de type float. Mais ces deux fonctions arrondissent \u00e0 2 chiffres apr\u00e8s la virgule. Malgr\u00e9 la d\u00e9bauche de ressources consomm\u00e9es, le r\u00e9sultat est donc d\u00e9cevant, la perte de pr\u00e9cision est importante. Rappelons au passage que l&rsquo;usage intensif et r\u00e9p\u00e9t\u00e9 d&rsquo;objets de type String est d\u00e9conseill\u00e9 car il peut entra\u00eener des plantages al\u00e9atoires. Les tableaux de char doivent toujours \u00eatre pr\u00e9f\u00e9r\u00e9s. Enfin, pour enterrer d\u00e9finitivement cette solution, notons qu&rsquo;elle n&rsquo;est absolument pas adapt\u00e9e au CAN bus, dont les messages ont une longueur maximale de 8 caract\u00e8res.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Le d\u00e9codage des octets constitutifs<\/h3>\n\n\n\n<p class=\"has-normal-font-size\">Le but est de d\u00e9composer les variables en leurs octets constitutifs, afin de transmettre ensuite ces octets les uns apr\u00e8s les autres. Puis faire l&rsquo;inverse \u00e0 la r\u00e9ception. La m\u00e9thode reste relativement simple pour les entiers, mais devient plus ardue pour les valeurs d\u00e9cimales, dont le format binaire de stockage en m\u00e9moire est nettement plus complexe.  <\/p>\n\n\n\n<p class=\"has-normal-font-size\">Prenons l&rsquo;exemple d&rsquo;une variable a, de type entier sign\u00e9 16 bits (int16_t), et de valeur hexad\u00e9cimale <span style=\"font-family:Arial;\">0xF3E2<\/span> (-3102 en d\u00e9cimal). Cette variable est constitu\u00e9e des 2 octets de valeurs 0xF3 et 0xE2. Pour calculer ces deux octets b et c, afin de pouvoir les transmettre, il faut faire appel aux op\u00e9rateurs logiques bit \u00e0 bit et aux op\u00e9rateurs de d\u00e9calage, ce qui est plut\u00f4t simple. Cela donne :<br><br><span style=\"font-family:Arial;font-size:16px;\">&nbsp;&nbsp; int16_t a = 0xF3E2<br>&nbsp;&nbsp;&nbsp;char b =  0xF3E2 &amp; 0xFF = 0xE2  (le &amp; 0xFF est facultatif, car b est de type char)<br>&nbsp;&nbsp;&nbsp;char c = 0xF3E2 &gt;&gt; 8 = 0xF3<\/span><\/p>\n\n\n\n<p>Il est simple d&rsquo;envoyer ensuite ces deux octets par une liaison s\u00e9rie, UART ou CAN. Lors de la r\u00e9ception, il est \u00e9galement assez simple de reconstituer l&rsquo;entier d&rsquo;origine, en faisant bien s\u00fbr attention \u00e0 l&rsquo;ordre d&rsquo;envoi et de r\u00e9ception des octets.<\/p>\n\n\n\n<p><span style=\"font-family:Arial;font-size:16px;\">&nbsp;&nbsp; int16_t a = (c &lt;&lt; 8) | b <\/span><\/p>\n\n\n\n<p>Pour un entier de 32 bits, la proc\u00e9dure est exactement la m\u00eame, avec quelques lignes de code suppl\u00e9mentaires.<\/p>\n\n\n\n<p>Les choses sont bien diff\u00e9rentes pour les nombres de type float. Ils sont exprim\u00e9s comme le produit d&rsquo;une mantisse et d&rsquo;une puissance de 2, sous la forme suivante :<\/p>\n\n\n\n<p class=\"has-text-align-center\">\u00b1 mantisse x 2<sup>exposant<\/sup><\/p>\n\n\n\n<p>Ils sont cod\u00e9s en m\u00e9moire sur 4 octets successifs, donc sur 32 bits, avec 1 bit de signe, suivi par 8 bits d&rsquo;exposant, et enfin 23 bits de mantisse (soit environ 7 chiffres significatifs). Dans ces conditions, il n&rsquo;est pas possible d&rsquo;utiliser les op\u00e9rateurs logiques et les op\u00e9rateurs de d\u00e9calage comme pour les entiers. Pour les floats, on peut en fait difficilement s&rsquo;en sortir sans acc\u00e9der explicitement \u00e0 leur stockage en m\u00e9moire, on verra que c&rsquo;est la 3\u00e8me solution, voir ci-dessous.<\/p>\n\n\n\n<p> Cependant, puisqu&rsquo;on peut facilement d\u00e9composer et transmettre les octets constitutifs d&rsquo;un entier, on pourrait imaginer convertir les nombres d\u00e9cimaux en nombres entiers, en les multipliant par une puissance de 10. Par exemple, pour transmettre le nombre d\u00e9cimal 12,345 il faudrait le multiplier par 10<sup>3<\/sup>, pour obtenir le nombre entier 12345, facile \u00e0 d\u00e9composer, puis \u00e0 transmettre, puis \u00e0 reconstituer \u00e0 la r\u00e9ception, et enfin \u00e0 diviser par 10<sup>3<\/sup> pour retrouver le nombre d&rsquo;origine. Beaucoup de lignes de code. Qu&rsquo;en serait-il pour un nombre de type double (64 bits sur les syst\u00e8mes ARM), comme 12,3456789 ? Il faudrait soit le multiplier par 10<sup>7<\/sup>, et obtenir ainsi un entier sur 64 bits (encore plus de lignes de code), soit accepter de perdre les derni\u00e8res d\u00e9cimales.<\/p>\n\n\n\n<p>Donc cette technique de d\u00e9codage en octets constitutifs est peu satisfaisante, assez lourde sur le plan du code, m\u00eame si elle pourrait \u00e0 la rigueur \u00eatre utilis\u00e9e pour les entiers. Mais surtout, \u00e0 quoi bon ? En effet, la 3\u00e8me solution s&rsquo;applique aussi bien aux entiers qu&rsquo;aux d\u00e9cimaux, et r\u00e9pond en tous points au cahier des charges indiqu\u00e9 en introduction.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">La m\u00e9moire et les pointeurs<\/h3>\n\n\n\n<p>On a d\u00e9j\u00e0 vu plus haut que les nombres d\u00e9cimaux  de type float sont cod\u00e9s en m\u00e9moire sur 4 octets successifs, soit 32 bits. Il en est de m\u00eame pour les entiers de type int et unsigned int, \u00e9galement cod\u00e9s sur 32 bits sur les syst\u00e8mes ARM. Les types long long et double sont cod\u00e9s sur 8 octets (64 bits). La solution id\u00e9ale pour transmettre un nombre, quel qu&rsquo;il soit, est en fait de transmettre le contenu des 4 ou 8 \u00ab\u00a0cases\u00a0\u00bb qu&rsquo;il occupe en m\u00e9moire. Donc 4 ou 8 octets \u00e0 transmettre les uns \u00e0 la suite des autres. Pour la r\u00e9ception, il faut d\u00e9clarer une variable du m\u00eame type, qui occupera donc \u00e9galement 4 ou 8 octets en m\u00e9moire, puis placer (dans le bon ordre) les octets re\u00e7us dans les cases m\u00e9moire r\u00e9serv\u00e9es pour cette variable. Laquelle prendra alors la valeur qui a \u00e9t\u00e9 transmise. <\/p>\n\n\n\n<p>Le langage C\/C++ utilis\u00e9 par nos microcontr\u00f4leurs Arduino et Teensy permet de faire cela facilement, car il permet d&rsquo;acc\u00e9der \u00e0 la m\u00e9moire gr\u00e2ce aux pointeurs. Un rappel pr\u00e9alable sur la m\u00e9moire et les pointeurs est n\u00e9cessaire. <\/p>\n\n\n\n<p>La m\u00e9moire est constitu\u00e9e d&#8217;emplacements \u00e9l\u00e9mentaires de 8 bits, soit un octet, on parle souvent de case m\u00e9moire. Toutes ces cases peuvent \u00eatre num\u00e9rot\u00e9es les unes \u00e0 la suite des autres, on parle d&rsquo;adresse m\u00e9moire ou de r\u00e9f\u00e9rence. Comme leur nom l&rsquo;indique, les pointeurs \u00ab\u00a0pointent\u00a0\u00bb sur un emplacement m\u00e9moire, ils indiquent donc une adresse particuli\u00e8re. Les pointeurs se comportent comme des variables un peu particuli\u00e8res, ils ont un nom, ils doivent \u00eatre d\u00e9clar\u00e9s, et surtout, ce qui est fondamental, ils sont typ\u00e9s : un pointeur de type char ne pointe que sur une seule case m\u00e9moire. Un pointeur de type int16_t pointe sur une case m\u00e9moire et celle qui suit, un pointeur de type float pointe sur une case et les 3 suivantes. L&rsquo;inconv\u00e9nient des pointeurs r\u00e9side essentiellement dans leur syntaxe qui, bien que tr\u00e8s logique, est souvent assez d\u00e9routante quand on les d\u00e9couvre. On va en expliquer les principes gr\u00e2ce \u00e0 de nombreux exemples.<\/p>\n\n\n\n<p>Voici un exemple de syntaxe de d\u00e9clarations de pointeurs. L&rsquo;ast\u00e9risque entre le type et le nom de la variable indique que cette derni\u00e8re est un pointeur. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>char * pPointeurN; \/\/ pPointeurN est un pointeur de type char\nint  * pPointeurM;\n<\/code><\/pre>\n\n\n\n<p>Dans l\u2019exemple ci-dessus,  <em>pPointeurN<\/em> est du type  \u00ab\u00a0Pointeur vers char\u00a0\u00bb, et <em>pPointeurM <\/em>est du type \u00ab\u00a0Pointeur vers entier\u00a0\u00bb. Au stade de la simple d\u00e9claration, un pointeur ne pointe sur rien. Tout comme une variable d\u00e9clar\u00e9e qui n&rsquo;a pas encore de valeur.<\/p>\n\n\n\n<p>Pour r\u00e9cup\u00e9rer dans une variable la valeur stock\u00e9e \u00e0 l\u2019adresse indiqu\u00e9e par un pointeur, la syntaxe est la suivante :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>char N = *pPointeurN;\nint M   = *pPointeurM;<\/code><\/pre>\n\n\n\n<p>On fait pr\u00e9c\u00e9der le nom du pointeur d&rsquo;une ast\u00e9risque. Il faut naturellement que le type de la variable soit le m\u00eame que le type du pointeur. Et pour que cela ait un sens, il faut que le pointeur ait \u00e9t\u00e9 initialis\u00e9, c&rsquo;est-\u00e0-dire qu&rsquo;il pointe sur quelque chose. On va voir un peu plus bas comment initialiser un pointeur.<\/p>\n\n\n\n<p>Donc <em>*pPointeurN<\/em> est une valeur et <em>pPointeurN<\/em> est une adresse m\u00e9moire (ou r\u00e9f\u00e9rence comme on l&rsquo;a vu plus haut). Le caract\u00e8re \u00ab\u00a0*\u00a0\u00bb est appel\u00e9 op\u00e9rateur de d\u00e9r\u00e9f\u00e9rencement.<\/p>\n\n\n\n<p>Pour obtenir l\u2019adresse \u00e0 laquelle est stock\u00e9e une variable, on fait pr\u00e9c\u00e9der son nom du caract\u00e8re \u00ab\u00a0&amp;\u00a0\u00bb, qui est appel\u00e9 op\u00e9rateur de r\u00e9f\u00e9rencement. Ainsi, <em>&amp;N<\/em> et <em>pPointeurN<\/em> d\u00e9signent la m\u00eame adresse dans les exemples ci-dessus.<\/p>\n\n\n\n<p>On peut d\u00e9clarer un pointeur en lui donnant une valeur :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>char N;   \nchar *pPointeurN = &amp;N;\n\nint  M;   \nint  *pPointeurM = &amp;M;<\/code><\/pre>\n\n\n\n<p>On peut aussi affecter une adresse \u00e0 un pointeur pr\u00e9alablement d\u00e9clar\u00e9 :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>pPointeurN = &amp;N; \/\/sous r\u00e9serve que les deux arguments soient du m\u00eame type<\/code><\/pre>\n\n\n\n<p>On peut modifier un pointeur, en lui ajoutant ou en lui retranchant une valeur enti\u00e8re. Mais attention : <strong>on avance ou recule d&rsquo;un nombre de cases m\u00e9moire \u00e9gal \u00e0 la taille du type du pointeur<\/strong>. Le r\u00e9sultat est un pointeur de m\u00eame type que le pointeur de d\u00e9part. Il faut faire attention, avec ce genre d&rsquo;op\u00e9ration, \u00e0 ne pas sortir du bloc m\u00e9moire que l\u2019on souhaite, car le compilateur n&rsquo;effectuera aucun contr\u00f4le. Cons\u00e9quence de ceci, si on veut se d\u00e9placer d&rsquo;une seule case m\u00e9moire \u00e0 l&rsquo;aide de l&rsquo;incr\u00e9mentation d&rsquo;un pointeur, ce dernier doit obligatoirement \u00eatre d&rsquo;un type cod\u00e9 sur un seul octet. Pour illustrer ceci, voir l&rsquo;exemple de code ci-dessous.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>char N;   \nchar * pPointeurN;\npPointeurN = &amp;N;\npPointeurN ++; \/\/ avance d'une seule case en m\u00e9moire\n\nuint32_t  M;   \nuint32_t  * pPointeurM = &amp;M;\npPointeurM ++; \/\/ avance de 4 cases m\u00e9moire<\/code><\/pre>\n\n\n\n<p>On pourrait alors imaginer avoir acc\u00e8s aux 4 emplacements m\u00e9moire contigus de la variable M de type uint32_t de l&rsquo;exemple pr\u00e9c\u00e9dent, en utilisant le pointeur de type char <em>pPointeurN<\/em>, comme ceci:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>pPointeurN = &amp;M;<\/code><\/pre>\n\n\n\n<p>Mais c&rsquo;est interdit en C\/C++. Si on essaye malgr\u00e9 tout de le faire, le compilateur proteste \u00e9nergiquement, avec le message suivant :\u00a0\u00bb<em>cannot convert &lsquo;uint32_t*&rsquo; to &lsquo;char*&rsquo; in assignment<\/em>\u00ab\u00a0. On va voir ci-dessous qu&rsquo;il y a une autre solution.<\/p>\n\n\n\n<p>Autre notion fondamentale concernant les pointeurs : le nom d\u2019un tableau est un pointeur. Si par exemple on a d\u00e9clar\u00e9 : <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>char liste&#91;4] = {'A', 'B', 'C', 'D'};<\/code><\/pre>\n\n\n\n<p>alors les notations <em>liste[1]<\/em> et <em>*(liste+1)<\/em> sont \u00e9quivalentes, retournant le 2\u00e8me caract\u00e8re du tableau, soit la lettre B. <em>liste <\/em>est un pointeur de type char qui contient l\u2019adresse du premier octet du tableau, d&rsquo;index 0,<em> liste+2<\/em> contient l&rsquo;adresse du 3\u00e8me octet, <em>*(liste+2)<\/em> retourne &lsquo;C&rsquo;&#8230; etc.<\/p>\n\n\n\n<p>Derni\u00e8re notion indispensable \u00e0 conna\u00eetre pour notre probl\u00e9matique de transmission s\u00e9rie de valeurs num\u00e9riques, celle de conversion de type forc\u00e9e : il est possible de convertir explicitement une <strong>valeur<\/strong> (et non une variable) en un type quelconque en for\u00e7ant la transformation. La syntaxe est :<\/p>\n\n\n\n<p><span style=\"font-family:Arial;font-size:16px;\">&nbsp;&nbsp; (type) expression<\/span><\/p>\n\n\n\n<p>Exemple avec des variables ordinaires :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>char A = 3;\nint B = 2;\nfloat C;\n\nC = A\/B;         \/\/ division enti\u00e8re de 3 par 2 : retourne 1.0\nC = (float)A\/B;  \/\/ division d\u00e9cimale de 3.0 par 2 : retourne 1.5<\/code><\/pre>\n\n\n\n<p>On peut faire exactement la m\u00eame chose avec les pointeurs. Si on d\u00e9clare : <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int16_t i = 0xF3D2;<\/code><\/pre>\n\n\n\n<p>alors l&rsquo;expression <em>&amp;i <\/em>est la valeur d\u2019un pointeur de type int*. On peut forcer la conversion de ce pointeur vers un type char* en \u00e9crivant <em>(char*)&amp;i<\/em>. Ce nouveau pointeur d\u00e9signe l&#8217;emplacement en m\u00e9moire de la variable i, <strong>qui se comporte comme un tableau de 2 char<\/strong>. Donc <em>((char*)&amp;i)[0]<\/em> est la valeur du premier octet de l\u2019entier i, soit 0xD2  et <em>((char*)&amp;i)[1]<\/em> est la valeur du second octet de l\u2019entier i, soit 0xF3. <\/p>\n\n\n\n<p>Autre exemple de code :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int32_t a = 0xF4E3D2C1;\nSerial.println(    ((char*)&amp;a)&#91;0]  ,HEX   ); \/\/ Retourne C1\nSerial.println(    ((char*)&amp;a)&#91;1]  ,HEX   ); \/\/ Retourne D2\nSerial.println(    ((char*)&amp;a)&#91;2]  ,HEX   ); \/\/ Retourne E3\nSerial.println(    ((char*)&amp;a)&#91;3]  ,HEX   ); \/\/ Retourne F4<\/code><\/pre>\n\n\n\n<p>C&rsquo;est exactement ce que nous cherchions \u00e0 obtenir ! \u00c0 savoir la d\u00e9composition d&rsquo;une valeur num\u00e9rique en ses octets constitutifs. Cela fonctionne quel que soit le type de la variable, 16, 32 ou 64 bits, enti\u00e8re ou d\u00e9cimale. Dernier exemple :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>double dbl = 123.45678912345678;\nSerial.println (dbl, 14); \/\/ Retourne 123.45678912345678\nfor (uint8_t i=0; i&lt;8; i++) {\n  Serial.print (((uint8_t*)&amp;dbl)&#91;i]);\n  Serial.print(\" - \");\n} \/\/ Retourne 150 - 154 - 114 - 8 - 60 - 221 - 94 - 64 -<\/code><\/pre>\n\n\n\n<p>Dans ce dernier exemple, nous avons d\u00e9compos\u00e9 une variable de type virgule flottante en double pr\u00e9cision, sur 64 bits, en ses 8 octets constitutifs, que nous avons transmis par la voie s\u00e9rie au terminal de l&rsquo;IDE Arduino. Nous allons maintenant voir comment r\u00e9aliser la man\u0153uvre inverse : reconstituer cette variable \u00e0 partir de ses 8 octets. Le code est le suivant :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>uint8_t liste&#91;8] = {150, 154, 114, 8, 60, 221, 94, 64};\ndouble varDouble;\nvarDouble = *(double*)liste;\nSerial.print (varDouble,14); \/\/ Retourne 123.45678912345678<\/code><\/pre>\n\n\n\n<p>L&rsquo;explication de ce code est tr\u00e8s simple. On a rempli un tableau de 8 octets avec les valeurs re\u00e7ues par la voie s\u00e9rie \u00e0 l&rsquo;\u00e9tape pr\u00e9c\u00e9dente. On d\u00e9clare une variable de type double, et on lui affecte la valeur cod\u00e9e par les 8 octets du tableau. Pour faire cela, on rappelle que <em>liste <\/em>est certes le nom du tableau, mais c&rsquo;est aussi un pointeur de type uint8_t, pointant sur l&rsquo;adresse du premier \u00e9l\u00e9ment du tableau. En \u00e9crivant (double*)liste, on force la conversion du type de ce pointeur en double. Et en faisant pr\u00e9c\u00e9der ce nouveau pointeur converti d&rsquo;une ast\u00e9risque, on obtient la valeur stock\u00e9e \u00e0 l&rsquo;adresse point\u00e9e par ce pointeur. On remarque que les 8 octets sont tr\u00e8s simples \u00e0 transmettre par un CAN bus, puisque c&rsquo;est la longueur d&rsquo;un message CAN standard.<\/p>\n\n\n\n<p>Cette m\u00e9thode r\u00e9pond donc en tous points au cahier des charges fix\u00e9 dans l&rsquo;introduction :  code compact et efficace, utilisable quel que soit le type de variable num\u00e9rique, quel que soit le type de transmission s\u00e9rie (UART ou CAN bus) et sans aucune perte de pr\u00e9cision des donn\u00e9es transmises. C&rsquo;est bien s\u00fbr la technique utilis\u00e9e dans nos sketches.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>(Page mise \u00e0 jour le 5\/12\/2021) Ce sujet est abord\u00e9 sur un grand nombre de forums Internet et de sites Web, bien souvent sans apporter de solution simple, claire et efficace. Cette probl\u00e9matique nous concerne en avionique, o\u00f9 des modules ind\u00e9pendants doivent communiquer et \u00e9changer des donn\u00e9es num\u00e9riques. C&rsquo;est par exemple le cas dans notre &hellip; <a href=\"https:\/\/avionicsduino.com\/index.php\/fr\/transmission-des-variables-numeriques-par-liaison-serie-uart-ou-can\/\" class=\"more-link\">Continuer la lecture<span class=\"screen-reader-text\"> de &laquo;&nbsp;Transmission des valeurs num\u00e9riques par liaison s\u00e9rie (UART ou CAN)&nbsp;&raquo;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"open","ping_status":"closed","template":"","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"class_list":["post-1431","page","type-page","status-publish","hentry"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/avionicsduino.com\/index.php\/wp-json\/wp\/v2\/pages\/1431","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/avionicsduino.com\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/avionicsduino.com\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/avionicsduino.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/avionicsduino.com\/index.php\/wp-json\/wp\/v2\/comments?post=1431"}],"version-history":[{"count":48,"href":"https:\/\/avionicsduino.com\/index.php\/wp-json\/wp\/v2\/pages\/1431\/revisions"}],"predecessor-version":[{"id":5046,"href":"https:\/\/avionicsduino.com\/index.php\/wp-json\/wp\/v2\/pages\/1431\/revisions\/5046"}],"wp:attachment":[{"href":"https:\/\/avionicsduino.com\/index.php\/wp-json\/wp\/v2\/media?parent=1431"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}