Bonjour. Comprendre les microcontrôleurs, c'est aussi être capable de développer des applications avec les microcontrôleurs, et aujourd'hui nous allons réaliser une petite application. Elle va nous donner l'occasion d'exercer la lecture de valeurs analogiques, et également la connexion à une liaison série. Il s'agira d'un testeur et chargeur d'accumulateur, très simple. Pour simplifier nous allons utiliser dans ce projet un accumulateur avec une tension de 1,2 Volts, en particulier la technologie M i M h qui est encore très utilisée. La première chose qui nous intéresse c'est d'être capable de mesurer la tension à vide de notre accumulateur, on le fait habituellement avec un voltmètre, en mesurant la tension aux bornes de l'accumulateur. Ce sera facile à faire avec une entrée analogique d'un microcontrôleur. On a besoin évidemment de charger l'accumulateur, pour le charger il faut faire passer un courant depuis l'alimentation, qui va ici charger l'accumulateur, une résistance de limitation sera utilisée pour régler le courant. Evidemment ce qui nous intéressera c'est de connaitre l'intégrale du courant, qui va représenter l'énergie qu'on a donné en charge qui s'exprime donc en ampères heure ou évidemment plus souvent en milliampères heure. Ensuite si on a envie de connaitre les caractéristiques de cet accumulateur il faut pouvoir le décharger. Pour le décharger on fera passer du courant cette fois vers la masse. Donc, comme ceci. Et cette fois l'intégrale du courant va représenter la capacité de l'accumulateur. Ce que l'accumulateur a réellement pu conserver comme énergie électrique qu'on lui a fourni au moment de la charge. Comment réaliser ces 3 montages avec un microcontrôleur? Voici une solution: nous allons utiliser une entrée analogique pour mesurer en permanence la tension aux bornes de notre accumulateur, et on va utiliser ici notre résistance, celle qui se trouve ici, celle qui se trouve là , il n'y en aura qu'une. Et on pourra utiliser cette patte pour demander la charge si on met l'état 1, pour demander la décharge si on met l'état 0. Et évidemment au moment où on lit la tension, on va utiliser la la haute impédance pour qu'il n'y ait aucun courant qui passe à travers cette résistance. Evidemment il faut bien choisir cette résistance, il ne faut pas dépasser le courant de sortie. Rappelez-vous un microcontrôleur est capable de fournir environ 30 milliampères. J'aurais même tendance à dire que, il faudrait être inférieur à cette valeur-là pour que la chute de tension dans la résistance du transistor reste négligeable pour ne pas influencer la mesure du courant qu'on verra tout à l'heure. Commençons alors à écrire un petit programme de test, qui va faire la mesure et l'affichage de la tension, regardons si c'est vraiment la tension, alors on a donc notre setup où on va simplement enclencher la ligne série pour pouvoir dialoguer avec le pc pour pouvoir afficher les messages sur l'écran. Dans notre loop principal, on va lire ce qui est à analogique qui s'appelle dans ce cas-là A5 qui est donc l'entrée de l'accumulateur, et ensuite on va directement afficher la valeur lue, envoyer les caractères correspondants sur la ligne série, on met ensuite un délai d'une seconde pour éviter que les messages n'arrivent trop vite sur l'écran. Est-ce qu'on a véritablement affiché la tension? Certainement pas, on a affiché une valeur entre 0 et 1023 qui correspond à une valeur de tension entre 0 volts et, et quoi? Eh bien et la tension d'alimentation Vcc qu'on ne connait pas forcément très bien, admettons pour le moment qu'il soit égal à 3,5 volts. Ce programme ne fait évidemment pas encore ce qu'on fait mais c'est très important de faire des programmes de test, pour tester les fonctions de bas niveau, avec ce programme on peut se convaincre que la ligne série fonctionne, que la lecture analogique fonctionne, c'est déjà très intéressant. Et, n'oubliez pas prenez l'habitude de conserver ces programmes de test ils peuvent toujours être utiles à un moment ou à un autre de la suite du développement. La première modification de ce programme, c'est de souhaiter d'afficher la tension en volts. Est-ce que vous vous souvenez de la fonction map que nous avions vue il y a quelque temps? On va lui donner le départ pour l'entrée et pour la sortie. On va donner l'arrivée pour l'entrée et pour la sortie. Alors ici MaxConv c'est bien le 1023, c'est la valeur maximale qui peut être lue par le convertisseur, et ici, les 2500 ça ne correspond pas à la tension d'alimentation dont je vous ai parlé tout à l'heure. Mais c'est bien ce que j'ai voulu choisir, en effet j'ai rajouté dans le setup cette ligne qui demande d'utiliser en interne une référence, une référence de tension interne au microcontrôleur, il y en a 2 sur le msp 430, celle qu'on utilise à 2,5 volts. donc après avoir écrit cette instruction, les valeurs qu'on lit elles correspondent à des fractions de cette tension-là . Si, par exemple, je lis la valeur 700, j'aurai 700 deux mille sept-centièmes de millivolts. Remarquez effectivement que j'ai utilisé des millivolts en permanence quand bien même on l'affichera, on va le voir, en volts. Alors ici la routine de lecture tension, j'ai bien la lecture comme tout à l'heure, mais j'applique directement le map pour avoir une valeur exprimée en millivolts. Ensuite il est nécessaire d'afficher la tension, voilà la procédure : alors je vais afficher, non pas les valeurs en millivolts, parce que je préfère voir les volts avec le point décimal, donc je prend ici la valeur de la tension que je divise par mille, c'est à dire les volts eux-mêmes. J'écris ensuite un point. Je n'ai pas envie d'avoir ensuite les 3 valeurs décimales, 2 me suffisent largement. Donc je divise la valeur par 10, et je prend le module O pour avoir exactement la valeur que je souhaite. On pourrait faire un petit essai, on a la valeur 1230 millivolts qui vient. J'affiche ici cette valeur divisée par mille, je rappelle c'est une division entière ça m'affiche bien le 1. J'affiche ensuite le point décimal et j'affiche ensuite la valeur divisée par 10, c'est à dire 123, module O 100, c'est à dire 23. Au final, j'ai bien affiché 1 point 23, cette procédure semble marcher. Oh, j'ai quand même un doute. Essayons encore avec une autre valeur. Admettons que notre accumulateur s'est un peu déchargé, et que la valeur que je lis est cette fois de 1090 millivolts. Comment est-ce que je vais afficher ça? Alors la valeur divisée par 1000 ça va me donner 1. Le point décimal qui s'écrit. La valeur divisée par 10, ça me fait 109 module O 100, ça me fait 9 et il m'affiche 1 point 9, c'est faux. Voilà un piège qu'on a tous fait une fois ou l'autre. Voilà la version corrigée, je dois bien afficher séparément chacun des digits pour qu'il n'y ait pas la suppression du digit non-significatif. Occupons-nous maintenant de la charge et de la décharge de notre accumulateur. Le programme a 3 modes de fonctionnement, le mode mesure, le mode charge ou recharge et le mode décharge. Et on va définir ici, ce qu'il faut mettre sur la patte correspondante, la patte PinCharge. Elle doit être en sortie à 1 pour la charge. Elle doit être en sortie à 0 pour la décharge et elle doit rester à haute impédance, donc elle doit être en entrée pour le mode mesure. Dans l'initialisation, on passe en mode mesure, c'est le mode par défaut. Je profite ici d'ajouter les deux procédures qui vont me permettre d'afficher le courant et d'afficher la charge. Je signale que cette charge est une valeur qu'on va exprimer en mAs puisqu'on va faire les mesures toutes les secondes et par conséquent ces, les valeurs vont devenir importantes. On ne pourra pas utiliser un entier, on devra utiliser un mot de 32 bits. Il faut faire extrêmement attention quand on écrit des applications de bien regarder la taille des variables dont nous avons besoin, un byte ou un char pour 8 bits, un int pour 16 bits ou un long en 32 bits. Alors commençons d'écrire la boucle principale. Elle est précédée par l'initialisation du mode en mode mesure, qui est le mode par défaut. Et ici, en fonction du mode, si on est en recharge ou si on est en décharge, on a un certain nombre de choses spécifiques à faire, en particulier faire la mesure du courant de charge, ou du courant de décharge, on a utilisé la même variable, ce sera la tension mesurée divisée par la résistance lorqu'on est en décharge. Par contre, le courant qui passera dans la résistance lorsqu'on est en charge, ce sera la tension d'alimentation moins la tension aux bornes de l'accumulateur et, pour obtenir le courant, je divise toujours par la résistance. Donc ici, dans les deux, dans ces deux lignes-là , on applique la loi d'Ohm mais en regardant le schéma correspondant qu'on utilise pour bien utiliser la bonne tension, sachant évidemment que la résistance reste toujours la même. Dans les deux cas, on va afficher la valeur de ce courant de charge ou de décharge, on va ensuite calculer la charge en intégrant le courant. En fait, je dois multiplier par le temps mais comme le temps, je vais m'arranger que ce soit une seconde, je fais en fait l'intégration de la recharge et j'obtiens bien l'unité mAs, et cette valeur est affichée. Print ln c'est juste pour passer à la ligne suivante. Alors, continuons d'écrire cette boucle principale, il faut évidemment attendre une seconde, ça correspondra à cette intégration pour avoir la mesure de la charge. Et ensuite il va falloir gérer la ligne série. Est-ce qu'un caractère est arrivé depuis la ligne série? Voilà la question que l'on pose. Si c'est le cas, on lit ce caractère et on se sélectionne en fonction du caractère. Est-ce qu'on veut passer en charge? Est-ce qu'on veut passer en décharge? Ou est-ce qu'on veut revenir au mode par défaut, qui est le mode mesure? On n'oublie pas les break liés à la structure switch case. Posons-nous une petite question. Voilà le programme que nous avons écrit, il mesure et affiche la tension, il mesure et affiche la charge et la décharge, il attend une seconde et il gère les caractères en entrée. Est-ce que je gère correctement le temps pour l'application que nous avons? Je rappelle que si une seconde n'est pas une seconde, notre charge en mAh et donc en mAs sera fausse. La réponse est non. Il faut que ma boucle dure une seconde. Or, cette instruction dure une seconde. Il faudrait donc que tout ce que j'ai écrit en bleu prenne un temps négligeable par rapport à la seconde. Alors la mesure, ce n'est pas trop long, ça peut aller. Mais l'affichage de la tension de la charge, avec les petits textes que l'on a prévus dans nos procédures et qu'on a vus tout à l'heure, en tout une soixantaine de caractères. Un caractère à 9600 bits par seconde ça correspond à environ une milliseconde. Je rappelle en effet qu'un caractère, c'est 8 bits plus le start bit plus le stop bit, donc c'est 10, éventuellement 11 bits si on a deux stop bits. Et, si on a 9600 bits par seconde, ça correspond donc bien à environ 1 ms pour un caractère. Si j'ai maintenant 60 caractères, ça va correspondre à 60 ms, ce n'est donc pas tout à fait négligeable par rapport à une seconde et il faudrait donc tenir compte du correctement de la valeur du temps en lisant la procédure millis qui est disponible avec Arduino. Vous allez me dire que ce montage n'est pas très intéressant parce que charger un accumulateur avec 20 mA, par exemple, ça va prendre beaucoup, beaucoup de temps. Alors si on veut un montage qui est capable d'envoyer plus de courant, il faudrait évidemment un, une amplification et ça, ça nécessiterait des transistors et en particulier, on utiliserait ce qu'on appelle un demi-pont en H de telle manière qu'on puisse imposer un 1, imposer un 0 ou ne rien imposer pour la lecture. Il y aurait une autre solution, c'est d'utiliser plusieurs pattes du microcontrôleur mais je mets bien en évidence le fait qu'on a une résistance pour chacune des pattes et que le fait de re, de mettre une seule résistance et connecter les trois pattes ensemble, c'est possible mais c'est relativement dangereux. Si votre programme a une petite faute et que deux pattes de chargement n'ont pas la même valeur, ce sera le court-circuit avec un sérieux risque de destruction de votre microcontrôleur. Encore un point qui pourrait être amélioré dans ce montage. Dans notre programme, on avait écrit que la tension d'alimentation était de 3,5V. Si on a effectivement une alimentation bien stabilisée à 3,5V, c'est parfait. Si cette tension n'est pas égale à 3,5V, il faudra corriger le programme, c'est ennuyeux. Et si la tension n'est pas si bien stabilisée que ça, on aura des valeurs fausses. Alors une solution consiste à mesurer l'alimentation. On prend ici le VCC, on ne peut pas directement le mettre sur une patte de lecture puisque la tension sera trop proche, puisqu'elle sera identique au VCC et on ne pourra plus mesurer. Donc on va ici utiliser un diviseur de tension et la tension qu'on aura ici sera une fraction de la tension d'alimentation. Si on part de l'idée qu'on fait une lecture entre 0 et 2,5V, et que la valeur de l'alimentation est de l'ordre de 3,5V, on pourra utiliser deux résistances identiques et on mesurera la tension d'alimentation et on la multipliera par deux pour obtenir un résultat correct. Plus exactement, on corrigera les paramètres donnés à la procédure map qu'on a vue tout à l'heure. Le problème qui se pose c'est, ces deux résistances devraient être relativement précises si on veut avoir une mesure aussi précise que possible. Est-ce qu'on va être obligé d'acheter des résistances de précision pour R1 et R2? Il existe une autre solution très élégante. Avec votre multimètre, qui n'est peut-être pas de très bonne qualité, qui n'est peut-être pas très précis, vous avez une résolution qui est largement suffisante. Vous pouvez donc prendre dans la petite boîte des résistances plusieurs résistances notées comme ayant la même valeur mais avec des variations, par exemple, de 5% possibles puisque les résistances les plus courantes sont effectivement données avec une imprécision de 5%. Mais si vous avez un stock suffisant de résistances, vous trouverez facilement deux résistances qui ont la même valeur vue par votre multimètre. Et si elles ont la même valeur, peu importe cette valeur exacte, vous saurez que votre diviseur de tension divisera par deux et vous pourrez, ici, faire le calcul correct pour la mesure d'alimentation. Que pourrait-on rajouter encore à ce montage? Est-ce qu'il est possible de mesurer la résistance interne du condensateur? A priori, ça semble facile, il faut faire une mesure de la tension à vide, faire une mesure avec la charge, on constate une chute de tension entre ces deux mesures et on calcule la résistance interne en appliquant la loi d'Ohm puisqu'on connait la résistance. Le problème, c'est que cette résistance interne est extrêmement faible et qu'on risque d'avoir une variation trop faible pour être mesurée fiablement avec l'installation que nous avons. Je rappelle que nous avons un convertisseur 10 bits, il est censé donner le pour 1000 mais en réalité, les bruits, si on ne fait pas extrêmement attention à la réalisation du montage euh, vont faire qu'on a une imprécision beaucoup plus grande que le pour 1000 et, par conséquent, on ne pourra pas facilement mesurer cette résistance interne. Il y aurait tout de même une possibilité, ce serait de faire ce qu'on appelle du suréchantillonnage. On pourrait, par exemple, dire : je mesure successivement la tension à vide puis la tension avec une charge, je répète mille fois cette opération, j'obtiens, je totalise chacune des deux valeurs et on aura peut-être à ce moment-là une différence entre ces deux moyennes, en quelque sorte, mesurée qui pourrait être significative et nous indiquer la résistance interne de l'accumulateur, qui d'ailleurs pourrait aussi indiquer la, l'état de l'accumulateur. Un accumulateur en bon état aura une résistance interne relativement faible, dans la technologie NiMH en tout cas. Quelles sont encore les améliorations possibles de ce montage? On pourrait par exemple détecter la fin de la charge, approximativement à 1,5 ou 1,6V. On pourrait détecter la fin de la décharge, autour de 1V. On pourrait aussi gérer plusieurs accumulateurs, des tensions plus élevées. On pourrait aussi utiliser le Trickle charging. Oui, c'est une technique qui permet de compenser la décharge naturelle de l'accumulateur lorsqu'il a terminé de se charger en envoyant un signal PWM, qu'on connait bien, qui corresponde justement à cette décharge naturelle de telle manière que si le, l'accumulateur reste dans le chargeur pendant un certain temps, même un temps relativement long, il restera chargé de manière optimale. Bien entendu on pourrait aussi ajouter des LED, des boutons, un afficheur, que sais-je, pour faire un appareil autonome et à ce moment-là il n'aurait plus besoin de la ligne série que nous avons utilisée jusqu'à maintenant. Voilà , nous avons donc réalisé cette petite application qui avait l'avantage d'être un montage extrêmement simple puisque nous avons eu besoin d'une seule résistance en plus de notre microcontrôleur. Nous avons pu voir comment faire les lectures analogiques. Nous avons pu voir comment utiliser la ligne série et nous avons pu aussi voir un certain nombre de pièges à éviter.