mercredi 8 juillet 2020

ARDUINO : Stockage en Flash SPI



ARDUINO : Stockage en Flash SPI


Lorsque l'on travaille sur un projet ARDUINO et que l'on désire disposer d'un support de stockage de données, le réflexe est souvent le même :
  • EEPROM
  • carte SD
Sur un ESP8266 ou un ESP32 on dispose de beaucoup plus de moyens. Il existe des possibilités de stockage en FLASH :
  • librairie EEPROM
  • système de fichiers SPIFFS
  • système de fichiers FATFS (ESP32 uniquement)

1. Les supports natifs

1.1. ARDUINO

Sur un ARDUINO la taille de la mémoire EEPROM est de :
  • 1Kb sur un ATMEGA328P
  • 4Kb sur un ATMEGA2560
C'est une mémoire I2C assez lente.

1.2. ESP8266

Sur un ESP8266 la librairie EEPROM autorise la création d'un espace de 4096 octets maximum.

Le système de fichiers SPIFFS peut être configuré à l'aide des options de partitionnement (voir menu Outils/Flash Size).
Sur un classique D1 mini possédant 4Mo de FLASH on pourra réserver jusqu'à 3Mo pour le stockage des données.

Cette partition SPIFFS sera plutôt réservée au stockage de fichiers non modifiables, chargés une fois pour toutes à l'aide du menu Outils/Sketch Data Upload :
  • fichiers de paramètres
  • fichiers HTML, CSS, JS, etc.
Il n'est pas interdit à l'application d'y stocker des données mais il faut savoir que le système de fichiers sera écrasé à chaque rechargement des ressources HTML.
Il faut faire un choix. Il sera difficile de combiner les deux.

1.3. ESP32

Sur un ESP32 l'espace EEPROM est réduit à 512 octets maximum.

Le système de fichier SPIFFS ou FATFS peut être configuré à l'aide des options de partitionnement (voir menu Outils/Flash Size).

Comme pour l'ESP8266 la partition SPIFFS sera plutôt réservée au stockage de fichiers non modifiables, chargés une fois pour toutes à l'aide du menu Outils/Sketch Data Upload :
  • fichiers de paramètres
  • fichiers HTML, CSS, JS, etc.
Une partition FATFS sera plutôt réservée au stockage de fichiers générés par l'application :
  • fichiers logs
  • fichiers de données divers (base de données clients par exemple)
Gros avantage par rapport à l'ESP8266, il est possible d'adopter un schéma de partition combinant les deux systèmes de fichiers SPIFFS et FATFS.
Il sera ainsi possible de séparer les ressources HTML et les fichiers de données.

2. Les supports additionnels

2.1. La carte SD

Dans tous les cas, un support de carte SD sera capable de stocker beaucoup plus de données que l'EEPROM d'un ARDUINO ou la FLASH d'un ESP8266 ou ESP32.

Par contre il faut bien reconnaître que la fiabilité n'est pas toujours au rendez-vous. Outre le fait que certaines SD refusent de fonctionner, il arrive que certains modèles soient source de problèmes.
Voir le paragraphe 9.3. Générer le JAVASCRIPT  à l'aide d'une template sur SD

Après de multiples déboires avec d'autres modèles, j'ai retenu les Sandisk Extreme SDHC (le prix tourne aux alentours de 10€ pour une 16Go).

2.2. L'EEPROM I2C

Les EEPROM I2C ont des capacités faibles et sont lentes. On trouvera des composants allant jusqu'à 256Kbits (32Ko). C'est peu.

2.3. La FRAM

La mémoire FRAM offre des capacité allant jusuqu'à 4Mbits (512Ko). Son prix est très élevé : une trentaine d'euros.

2.4. La flash SPI

Il s'agit du même type de FLASH que sur un ESP8266 ou un ESP32. Ces composants à 8 pattes ont des capacités allant de 512Kbits (64Ko) à 2Gbits (256 Mo).

Comme on peut le voir le choix est large et peut sérieusement augmenter l'espace de stockage d'un ARDUINO ou même d'un ESP32.
Les capacités sont bien moindres que celles des cartes SD mais cela reste tout de même très intéressant.

Il existe des modèles CMS, DIP et même des modules :
Un module comme celui-ci équipé d'une W25Q128 coûte 2€, loin du prix d'une SD de qualité.
Quand à la version CMS, on peut trouver des lots de 10 pièces pour un peu plus de 6€ :
Une W25Q16 en bôtier DIP coûte 4€ les 10 pièces, de quoi stocker 2Mo de fichiers pour 40 centimes.
Ce composant est directement utilisable sur breadboard :
Autre avantage, leur faible consommation : 4mA en activité et 1μA au repos.

J'ai choisi de tester le modèle WINBOND W25Q128 (16Mo).

3. Le câblage


Ces mémoires sont des modèles 3.3V. elles nécessitent une adaptation de niveau :

Sur un ESP8266 ou un ESP32 les résistances ne seront pas nécessaires.

4. Les librairies

Il existe différentes librairies :

SPIMemory de Marzogh :

SPIFlash de LowPowerLab :

Ces deux librairies ont une interface analogue à celle de la librairie EEPROM, rien de bien intéressant sauf si l'on envisage de stocker des données sans notion de fichiers, à des adresses connues.

4.1. La librairie AdaFruit

https://github.com/adafruit/Adafruit_SPIFlash

La librairie AdaFruit repose sur la librairie SDFat. Elle hérite donc de l'inerface de cette dernière. Il faut une quantité de mémoire RAM d'au moins 5Ko pour pouvoir l'utiliser. Elle n'est donc pas adaptée aux petits ARDUINOs.

Le programme exemple SdFat_Format requiert 10.5Ko de mémoire RAM, donc une carte MEGA sera incapable de formater la FLASH.

Il faut adopter une ARDUINO DUE pour formater la FLASH, ensuite elle pourra être utilisée sur une MEGA. Cela suppose une organisation lourde, et la MEGA est une carte sans grand intérêt que je n'utilise quasiment jamais.

Quelques remarques pour ceux qui voudraient néanmoins tenter l'expérience :

Dans le fichier Adafruit_SPIFlashBase.cpp la liste des devices supportés ne contient pas la W25Q128. Je l'ai ajouté :

static const SPIFlash_Device_t possible_devices[] = {
    // Main devices used in current Adafruit products
    GD25Q16C,
    GD25Q64C,
    S25FL116K,
    S25FL216K,

    // Only a handful of production run
    W25Q16FW,
    W25Q64JV_IQ,
    W25Q128JV_SQ,

    // Nordic PCA10056
    MX25R6435F,

    // Other common flash devices
    W25Q16JV_IQ,
};

Pour info la liste complète des FLASH se trouve dans le fichier flash_devices.h.
Il est parfaitement possible d'ajouter des descripteurs. La W25Q128 est définie comme suit :

#define W25Q128JV_SQ                                                           \
  {                                                                            \
    .total_size = (1 << 24), /* 16 MiB */                                      \
        .start_up_time_us = 5000, .manufacturer_id = 0xef,                     \
    .memory_type = 0x40, .capacity = 0x18, .max_clock_speed_mhz = 133,         \
    .quad_enable_bit_mask = 0x02, .has_sector_protection = false,              \
    .supports_fast_read = true, .supports_qspi = true,                         \
    .supports_qspi_writes = true, .write_status_register_split = false,        \
    .single_status_byte = false,                                               \
  }

Ajouter la W25Q256 ou W25Q512 ne devrait pas être bien complexe. Il suffit de lire la datasheet.

Pour une W25Q256 :

    .memory_type = 0x40, .capacity = 0x19, .max_clock_speed_mhz = 133,         \

Pour une W25Q512 :

    .memory_type = 0x71, .capacity = 0x19, .max_clock_speed_mhz = 133,         \

J'ai tout de même essayé de formater la FLASH avec un ARDUINO DUE :

Adafruit SPI Flash FatFs Format Example
Flash chip JEDEC ID: 0xEF4015
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
This sketch will ERASE ALL DATA on the flash chip and format it with a new filesystem!
Type OK (all caps) and press enter to continue.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Creating and formatting FAT filesystem (this takes ~60 seconds)...
Setting disk label to: EXT FLASH
Formatted flash!
Error, failed to mount newly formatted filesystem!

Comme on le voit l'identifiant 0xEF4015 (W25Q16) est bien lu, donc la communication SPI se fait bien, mais la suite échoue. Une W25Q128 donne le même résultat.

Abandon de la librairie AdaFruit.


4.2. La librairie de Paul Stoffregen

https://github.com/PaulStoffregen/SerialFlash.git

La librairie de Paul Stoffregen offre une interface du type système de fichiers :
  • création ou ouverture d'un fichier
  • écriture / lecture / effacement
  • positionnement
  • parcours de la liste des fichiers
Parmi les inconvénients on peut citer :
  • il n'y a pas de répertoires
  • les fichiers sont créés avec une taille fixe
J'ai décidé d'adopter cette librairie car elle est légère et adaptée aux petits ARDUINOs.

4.2.1. Les fichiers de données

Si l'application crée un fichier pour y stocker des données, la taille fixe est un handicap.
En effet le fichier est créé au départ avec un contenu effacé (une suite de bytes ayant la valeur 0xFF).
Il sera assez difficile d'en faire un fichier de données, à moins d'effectuer pas mal d'opérations manuellement :
  • ouvrir le fichier
  • se positionner à la fin des données écrites précédemment (il faut mémoriser cet index)
  • écrire les données
  • sauvegarder le nouvel index
  • fermer le fichier
Où stocker l'index ? en EEPROM ?
Ce n'est pas d'une élégance démesurée.

Bien entendu il est impossible de réécrire par dessus des données déjà écrites. La mémoire FLASH s'efface par bloc. Si l'on souhaitait réécrire une partie du fichier il faudrait :
  • mémoriser le bloc
  • l'effacer
  • le réécrire en incorporant les nouvelles données
Or sur ce type de FLASH on ne effacer que par blocs de mémoire d'au minum 4Ko (16 pages de 256 octets). Il est donc impossible de sauvegarder un bloc dans la mémoire RAM d'un ARDUINO, à moins qu'il ne s'agisse d'un MEGA2560.

4.2.2. Les fichiers ressources

Nous allons aborder ici la gestion des fichiers ressources :
  • fichiers de paramètres
  • fichiers HTML, CSS, JS
  • fichiers images, logos
  • etc.
Ce cas est plus facile à traiter :
  • création du fichier à la bonne taille
  • ouverture du fichier
  • écriture les données
  • fermeture du fichier
Pour faire cela, que nous manque t'il ?
Il nous faut un logiciel de transfert de fichiers. Il en existe un certain nombre :
  • FTP
  • XMODEM, ZMODEM
  • etc.
Malheureusement ils sont assez peu compatibles avec la taille mémoire d'un ARDUINO.

4.2.3. Le logiciel de transfert

J'ai développé une librairie permettant le transfert de fichiers par le câble USB entre le PC et l'ARDUINO. Elle utilise la librairie de Paul Stoffregen.

Côté PC, un script PYTHON se charge de l'envoi des commandes.

Il est possible de transférer des fichiers texte ou binaires.
A la fin du transfert le contenu du fichier est vérifié.

4.2.3.1. Les commandes

Pour être à même de transférer un fichier il faut charger l'exemple upload dans l'ARDUINO.

Il faut également installer PYTHON 2.7 et PYSERIAL sur le PC.

L'utilitaire serflash.py est un logiciel en ligne de commande.

usage: serflash.py [-h] [-s] [-e] [-l] [-d] [-g] device file [file...]

Les commandes du logiciel PYTHON sont les suivantes :

Option Rôle
device    Port de communication
file
Fichier à transférer
-h
Aide
-s
Affiche la taille de la FLASH en Mo
-b
Affiche la taille d'un bloc en octets
-e
Efface la FLASH
L'effacement d'une W25Q128 prend 40 secondes
-l
Affiche la liste les fichiers dans la FLASH
-d
Affiche un dump du contenu du ou des fichiers
-g récupère de fichier sur le disque (avec l'extension .dump)

Voici des exemples. 3 fichiers (text, bin, big) sont présents dans le répertoire python :

Les 2 premières commandes affichent la taille totale et la taille d'un bloc.
La 3ème commande efface la FLASH.
Les 3 commandes suivantes transfèrent les fichiers.
La 7ème commande liste les fichiers.
La 8ème commande fait un dump des fichiers text et bin.
La 9ème commande récupère les fichiers text et bin.

$ ./serflash.py -s /dev/ttyUSB1
16 Mbytes (16777216 bytes)
$ ./serflash.py -b /dev/ttyUSB1
65536 bytes
$ ./serflash.py -e /dev/ttyUSB1

$ ./serflash.py /dev/ttyUSB1 text
Uploading 1 file(s) ...
text (26 bytes)
26 bytes sent
End of transfer
verified: OK
Files:
text : 26 bytes
$ ./serflash.py /dev/ttyUSB1 bin
Uploading 1 file(s) ...
bin (17 bytes)
19 bytes sent
End of transfer
verified: OK
Files:
text : 26 bytes
bin : 17 bytes
$ ./serflash.py /dev/ttyUSB1 big
Uploading 1 file(s) ...
big (3026 bytes)
128 bytes sent
128 bytes sent
128 bytes sent
128 bytes sent
128 bytes sent
128 bytes sent
128 bytes sent
128 bytes sent
128 bytes sent
128 bytes sent
128 bytes sent
128 bytes sent
128 bytes sent
128 bytes sent
128 bytes sent
128 bytes sent
128 bytes sent
128 bytes sent
128 bytes sent
128 bytes sent
128 bytes sent
128 bytes sent
128 bytes sent
82 bytes sent
End of transfer
verified: OK
Files:
text : 26 bytes
bin : 17 bytes
big : 3026 bytes
$ ./serflash.py -l /dev/ttyUSB1
Files:
text : 26 bytes
bin : 17 bytes
big : 3026 bytes
$ ./serflash.py -d /dev/ttyUSB1 text bin
text:
0000 61 7a 65 72 74 79 75 69 6f 70 71 73 64 66 67 68    azertyuiopqsdfgh
0010 6a 6b 6c 6d 77 78 63 76 62 6e                                  jklmwxcvbn
bin:
0000 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10     ................
0010 11                                                 .
$ ./serflash.py -g /dev/ttyUSB1 text bin
text.dump: Done
bin.dump: Done


Sur un PC Windows il faudra remplacer /dev/ttyUSB1 par COMX.

4.2.3.2. Le sketch

La librairie de transfert de fichiers peut être intégrée facilement dans un sketch :

#include <SerialFlash.h>
#include <serial-flash-upload.h>

#define CSPIN 10
#define LED 2 // Optional (can be set to ZERO)

Uploader uploader(CSPIN);

void setup()
{
Serial.begin(115200);
if (uploader.begin(LED) == false) {
Serial.println("ERR_FLASH");
}
}

void loop()
{
if (Serial.available()) {
uploader.shell();
}
}

Le sketch d'exemple upload est peu volumineux.

12216 octets (39%) de l'espace de stockage de programmes.
281 octets (13%) de mémoire dynamique.

Il suffit d'ajouter le code pour ses propres besoins dans les fonctions setup() et loop(), avec les précautions habituelles (pas d'attentes bloquantes, de delay() dans la fonction loop()).

On peut également utiliser le sketch exemple upload uniquement pour le transfert des fichiers, et écrire un sketch sans cette librairie, pour l'application.
Il faudra simplement recharger le sketch upload avant chaque transfert.

On peut enfin disposer de deux cartes ARDUINO, dont une dédiée au transfert, chargée avec le sketch upload. Dans ce cas la FLASH SPI peut être soudée sur une carte amovible.
Pour cet usage les modules du commerce sont particulièrement adaptés :


La librairie SerialFlash n'est pas très gourmande. Un sketch simple d'écriture de données occupe peu de place :

7726 octets (25%) de l'espace de stockage de programmes.
204 octets (9%) de mémoire dynamique.

Comparativement un sketch exemple ReadWrite de la librairie SDFat occupe :

9374 octets (30%) de l'espace de stockage de programmes.
1057 octets (51%) de mémoire dynamique

La librairie SerialFlash de SerialFlash est donc nettement plus économique en RAM que la librairie SDFat.


5. Téléchargements

Ce projet est téléchargeable ici :


6. Conclusion

Les FLASH SPI me permettront à l'avenir de remplacer avantageusement les cartes SD, et ceci pour un coût très avantageux.


Cordialement
Henri

dimanche 5 juillet 2020

Porte Motorisée de Poulailler (le bilan)




Porte Motorisée de Poulailler (4ème Partie)


Il est temps de faire le bilan de ce projet et de donner quelques chiffres.

1. Configuration retenue

1.1. Moteur continu

Voici le moteur utilisé :
Moteur JGA25-370 60 tours / minute

La configuration est la suivante :
  • alimentation : 2 batteries 18650 (2000mAH au total)
  • panneau solaire 18V 4W
  • moteur à courant continu 12V 60 tours / minute
  • pas de contact de fin de course
  • module radio NRF24L01 + liaison serveur DOMOTICZ
  • module RTC DS3231
  • ouverture et fermeture par calcul de l'heure de lever et de coucher du soleil
  • module SHT31D
  • temps de sommeil : 5 minutes
  • demande de l'heure au serveur DOMOTICZ : une fois par mois

1.2. ServoMoteur

Le fait que j'aie adopté une solution à moteur continu ne veut pas dire qu'une configuration à base de servomoteur n'est pas viable, bien au contraire.
Entre le 24 avril et le 20 juin celle-ci a donné entière satisfaction.

On utilisera de préférence un contact de fin de course haut, un contact REED + aimant par exemple :


En cas de besoin on trouve des servomoteurs ayant un couple plus élevé que le MG996R, le TD-8120MG (20kg.cm) par exemple :
TD-8120MG


2. Problème

La valeur du PWM appliqué au moteur a été réduite car la puissance moteur est encore trop importante. La courroie est soumise à une tension trop importante et a tendance à sauter.

Il est possible que la courroie se soit légèrement détendue du fait que la température est plus élevée qu'en avril. J'ai donc ajouté un tendeur réalisé dans un morceau de fil d'acier galvanisé d'un diamètre de 3mm et un petit morceau de tube aluminium :


La courroie passe à 1mm de la poulie de renvoi située plus bas. Il est préférable qu'elle ne la touche pas, afin d'éviter toute usure.

Avec ce dispositif, outre le fait que la courroie est tendue, le nombre de dents en prise sur le pignon est légèrement supérieur. Le comportement est excellent.
Reste à voir ce que cette solution donnera en fonction de la saison.

3. Comportement

Avec un rapport PWM de 150 les temps d'ouverture et de fermeture sont de 18 et 16 secondes.
L'arrêt moteur est réglé sur 300mA, car en pilotant le moteur en PWM le courant est irrégulier et il y a des pics allant  jusqu'à 220mA.
Le fonctionnement est optimal.

Remarque :
On pourrait filtrer ces pics en ajoutant un condensateur en parallèle sur la résistance shunt du L293D (R8).
Pour filtrer un PWM à 500Hz sur une résistance de 1Ω ou 1.5Ω il faudrait une capacité de 1000µF à 2000µF.

4. Mesure du courant du panneau solaire

Le module de mesure du courant du panneau a été ajouté. Il s'agit d'un module équipé d'un INA138 décrit ici :


Il est enfiché sur un connecteur DUPONT femelle 7 points soudé sur la carte afin de pouvoir être retiré après la phase de tests.


L'information est remontée au serveur DOMOTICZ, c'est à dire que celui-ci sera capable d'afficher un graphique de la puissance fournie par le panneau solaire.

Ce qui m'intéresse est de connaître le courant et le temps de charge en fonction de la météo.

Voici les premières données affichées :


Pour réaliser ces premiers essais j'ai déchargé la batterie à plusieurs reprises avec une résistance de 10Ω. La puissance maximale débitée par le panneau est de 1.7W.

Le module de mesure ne sera utile que pendant la phase de test du système. Il sera retiré au printemps, quand la puissance journalière sera connue sur une période suffisamment longue, hiver compris, et éventuellement neige comprise.
Il sera remplacé par un cavalier entre les broches 5 et 6 afin que le courant du panneau puisse passer directement.

4. Consommation

Avec cette configuration la consommation totale est de 1mA, essentiellement due au DS3231.
La consommation est donc d'une dizaine de mAH pendant la nuit en été. Cette perte est compensée le matin aussitôt que le soleil se lève par le chargeur.

La capacité des batteries étant d'environ 2000mAH l'autonomie sans recharge sera de 2000 heures, donc 2.7 mois.
Cette capacité peut paraître disproportionnée, mais pendant l'hiver l'efficacité des batteries sera amoindrie, par conséquent je préfère surdimensionner.

Enfin, durant l'hiver il se peut que de la neige recouvre le panneau solaire. La batterie ne sera donc pas rechargée pendant des périodes plus ou moins longues.

5. DOMOTICZ

Le serveur DOMOTICZ permet de récupérer des informations sous forme de graphiques :


Ce matin la porte s'est ouverte à 05:49:26.


La tension du panneau solaire commence à augmenter à 5H25.


A 5H30 le chargeur TP4056 absorbe 0.4W fournis par le panneau solaire pendant une courte période. La consommation de la nuit est donc compensée en très peu de temps.

La porte s'ouvre à 05:49. Le chargeur TP4056 ne juge pas nécessaire de recharger la batterie, car la tension de celle-ci n'est probablement pas descendue suffisamment bas.

Entre 5H30 et 7H25 le système continue à consommer : 1mA.

Ensuite à 7H25 une phase de recharge démarre. La tension de la batterie est donc descendue en dessous du seuil déclenchant la recharge. La puissance absorbée varie entre 0.1W et 0.2W. La charge se termine à 8H45.

A 8H45 la tension du panneau est de 5.65V. Elle monte ensuite brutalement à 16.5V, ce qui est normal car le TP4056 n'absorbe plus de courant et le panneau ne débite donc plus rien.

Les conditions météo ce matin : temps couvert.
Le panneau est à l'ombre jusqu'à environ 10H30.

Comme on le voit le panneau solaire n'a aucun mal à recharger la batterie, même par temps couvert et à l'ombre. La consommation est faible et par conséquent la quantité d'énergie nécessaire est faible également.

Le panneau solaire est utilisé au maximum à 10% de ses capacités. Tout ceci est extrêmement satisfaisant. Un panneau de 1W suffirait probablement.

6. Téléchargements

Cette version finale est disponible ici :

https://bitbucket.org/henri_bachetti/mysensors-gate/src/v1.0/

7. Conclusion

Ce projet est certes complexe du fait de ses nombreuses possibilités :
  • moteur
    • courant continu
    • servomoteur
  • alimentation
    • secteur
    • batterie + panneau
  • méthode d'ouverture / fermeture
    • grâce à la luminosité
      • LDR : idéal en cas d'alimentation secteur
      • panneau solaire
    • à l'aide d'un calcul de l'heure de lever et de coucher du soleil
      • RTC DS3231 avec saisie manuelle de l'heure
      • RTC DS3231 avec demande d'heure au serveur DOMOTICZ
A partir du moment où l'on a fait les choix principaux le paramétrage est relativement simple. Le fichier options.h regroupe toutes les options et les commentaires sont nombreux.
Les paramètre liés au moteur continu sont expliqués en 4ème partie :
Voir 3. Le logiciel

J'espère que cette suite d'articles apportera des réponses suffisantes à qui souhaite mener à bien un projet analogue, qu'il s'agisse de piloter une porte de poulailler ou simplement d'automatiser le pilotage d'un moteur en fonction de l'heure, avec une alimentation autonome ou non.


Cordialement
Henri

jeudi 2 juillet 2020

INA138 et MAX4372 : Current Monitoring



INA138 et MAX4372

Current Monitoring


Nous allons aujourd'hui mettre en œuvre L'INA138 et le MAX4372, deux amplificateurs de courant.

Ces composants permettent d'amplifier la tension présente aux bornes d'un shunt de mesure afin d'envoyer une tension mesurable sur l'entrée analogique d'un microcontrôleur.

La sortie de l'INA138 est un générateur de courant. Le gain est donc réglable à l'aide d'une simple résistance.

La sortie du MAX4372 est un générateur de tension. Le gain est fixe et dépend du modèle :
  • MAX4372T : 20
  • MAX4372F : 50
  • MAX4372H : 100
La première question que l'on peut se poser : pourquoi utiliser un amplificateur analogique alors que des modèles numériques existent ? :
  • INA219 (12 bits)
  • INA226 (16 bits)
Ces composants nous apporteraient une précision supérieure, mais ils ont un inconvénient majeur : leur temps de conversion est élevé, 140µS au minimum. Si l'on désire s'affranchir du bruit il est même recommandé d'adopter un temps de conversion supérieur : 1.1ms ou 8.244ms.
Deuxièmement le dialogue se fait en I2C, ce qui n'améliore pas les choses.
Bref le handicap est important si l'on a des variations de courant rapides à observer.

D'autre part, lorsque l'on mesure un courant, la précision n'est pas le critère principal. Il s'agit souvent de mesurer la consommation d'un montage ou d'un composant et de tracer sa variation dans le temps. Une précision de 0.1% ou 0.5% est totalement inutile.

Le montage suivant pourra être utilisé pour mesurer un courant avec une rapidité qui dépendra uniquement de celle de l'ADC du microcontrôleur.
On peut facilement obtenir plus de 38000 échantillons par seconde avec un ATMEGA328 :
Certains gros STM32 peuvent offrir plus d'un million d'échantillons par seconde !

La deuxième question que l'on peut se poser : un simple AOP monté en amplificateur ne pourrait-il pas faire le même travail ?
La réponse est non, car l'INA138 et le MAX4372 peuvent accepter sur leurs entrée des tensions largements supérieures à leur tension d'alimentation, ce que ne pourra pas tolérer un AOP.

1. L'INA138

Ce composant est capable de mesurer un courant côté "high side" (rail positif) uniquement. Il peut être alimenté entre 2.7 V à 36 V.
Un autre modèle, l'INA168, peut être alimenté entre 2.7 V à 60 V.


La résistance shunt RS produit une chute de tension proportionnelle au courant traversant la charge. Il convient donc de choisir sa valeur judicieusement, afin de ne pas perturber la charge.
Pour une mesure précise, il est recommandé également de ne pas dépasser 0.5V entre les entrées de l'INA138.

La résistance RL permet de fixer le gain de l'amplificateur (voir figure 9 de la datasheet) :
  • RL=50KΩ pour un gain de 10
  • RL=100KΩ pour un gain de 20
  • RL=250KΩ pour un gain de 50
  • etc.
Imaginons que l'on désire mesurer un courant maximal d'un ampère.
Si l'on admet 100mV de chute de tension dans le shunt, celui-ci aura une valeur de :

RS = 0.1V / 1A = 0.1Ω

Si l'on fixe le gain à 20, la résistance RL doit avoir une valeur de 100KΩ.

La tension maximale en sortie de l'INA138 vaudra :

Vo = Is * RS * RL / 5KΩ = 1A * 0.1Ω * 100KΩ / 5kΩ = 2V

L'entrée analogique du microcontrôleur mesurera donc 2V à pleine échelle.

On peut utiliser différentes références de tension (VREF) pour l'ADC :
  • référence par défaut : 5V ou 3.3V suivant la tension d'alimentation
  • référence interne 1.1V
  • référence interne 2.56V (ARDUINO MEGA)
Si l'on utilise la référence par défaut, la précision s'en ressentira légèrement.
Avec une référence 3.3V, la perte de précision sera faible.
Avec une référence 5V on perdra un bit sur les 10 de l'ADC. On peut augmenter le gain à 50 avec une résistance RL de 200KΩ. La tension maximale à mesurer sera de 5V. C'est limite.

Si l'on utilise la référence interne 1.1V l'ADC sera saturé. Il conviendra de diminuer la valeur du gain. On le fixera à 10 avec une résistance de 50KΩ. La tension maximale à mesurer sera de 1V.
Enfin, avec la référence interne 1.1V, si l'on conserve le gain de 20, le courant maximal que l'on pourra mesurer sera de 0.55A.

Sur une MEGA, la référence 2.56V sera le meilleur choix.

Il faut également tenir compte de la puissance dissipée par le shunt. La modèle que j'ai utilisé est une résistance 100mΩ CMS 2010 pouvant dissiper 1W.
Le courant maximal qu'elle pourra supporter est de :

I = √(P / R) = 3.16A

Comme c'est une limite absolue à ne pas dépasser, si l'on veut éviter un échauffement excessif, il serait bon d'appliquer une marge de sécurité.
Dans le cas où l'on dépasse le courant maximal admissible, il faudra adopter une résistance de puissance plus importante, mais cela se fera au détriment de la chute de tension dans RS :

U = R * I = 0.1 * 3.16 = 0.316V

On est loin des 100mV que l'on s'était fixé au départ. Il serait plus judicieux d'adopter un shunt de plus faible valeur, et d'augmenter le gain.

On peut résumer avec un petit tableau :

VREF
RS RL Gain Courant maxi Résolution
(ADC 10 bits)
5V 0.1Ω 200KΩ 50 1A 0.97mA
5V 0.1Ω 100KΩ 20 2.5A 2.44mA
5V
0.1Ω (*) 50KΩ 10 5A 4.88mA
5V
0.02Ω 200KΩ 50 6.25A 6.1mA
3.3V 0.1Ω 200KΩ 50 0.66A 0.64mA
3.3V 0.1Ω 100KΩ 20 1.65A 1.61mA
3.3V
0.1Ω (*) 50KΩ 10 3.3A 3.22mA
3.3V
0.02Ω 200KΩ 50 4.125A 4mA
1.1V 0.1Ω 200KΩ 50 0.22A 0.21mA
1.1V 0.1Ω 100KΩ 20 0.55A 0.53mA
1.1V 0.1Ω 50KΩ 10 1.1A 1.07mA
2.56V 0.1Ω 100KΩ 20 1.28A 1.07mA

(*) Ces deux configurations nécessiteront l'adoption d'un shunt d'au moins 3W, ou de diminuer sa valeur et d'augmenter le gain (voir ligne suivante dans le tableau).

Bien entendu avec d'autres microcontrôleurs possédant par exemple un ADC 12 bits ou des références internes de valeurs différentes ces paramètres seront différents.

On peut utiliser une référence de tension externe si l'on désire une plus grande précision ou une stabilité en température supérieure.


2. Le MAX4372

Le MAX4372 est plus simple. Il n'y a aucune résistance de réglage, mais les calculs restent les mêmes, et le tableau précédent reste valable.


3. Les schémas

3.1. L'INA138

Voici le schéma que j'utilise :
La sortie de l'INA138 est redirigée vers l'entrée d'un AOP OPA363 monté en suiveur (gain = 1), ceci afin de diminuer fortement l'impédance de sortie.
Cet étage est nécessaire si l'on désire faire des mesures de courant subissant des variations rapides ou utiliser plusieurs canaux ADC simultanément. Voir cet article :

Un condensateur de 100nF permet de découpler l'alimentation.

3.2. Le MAX4372

Voici le schéma que j'utilise :
Le MAX4372 a une impédance de sortie très faible, il n'a nul besoin d'un AOP suiveur pour abaisser celle-ci.

Ici aussi un condensateur de 100nF permet de découpler l'alimentation.

Que dire de plus ? Il est temps de passer aux essais.

3.3. Les branchements

Le connecteur IN-OUT des deux modules a le brochage suivant :
  • 1 : sortie
  • 2 : alimentation 5V ou 3.3V (l'OPA363 supporte au maxi 5.5V)
  • 3 : GND
  • 4 et 5 : V-
  • 6 et 7 : V+
La tension d'alimentation pour la charge doit être appliquée sur les broches 6-7. La charge est câblée entre les broches 4-5 et GND.

Les broches 4-5 et 6-7 sont doublées afin d'augmenter le courant admissible.

Sur ce schéma la charge est une résistance de 47Ω, elle consommera donc environ 100mA sous 5V.

On pourrait imaginer remplacer cette charge par un microcontrôleur quelconque pour en mesurer la consommation. Il est facilement imaginable également que le microcontrôleur reçoive lui-même l'information à mesurer sur une de ses propres entrées analogiques. Il pourra donc mesurer sa propre consommation en temps réel.

Un module de ce type peut être mis en place pendant la phase de test d'un projet et retiré ensuite, une fois que la consommation est connue.
On peut par exemple prévoir un connecteur femelle à 7 points sur la carte pour enficher le module, et le remplacer ensuite par un cavalier entre les pins 5 et 6.

4. Le sketch

4.2. L'INA138

Voici un petit sketch pour un ARDUINO :

#define VREF          1.073
#define SHUNT         0.100
#define INA138_GAIN   19

void setup()
{
  Serial.begin(115200);
  analogReference(INTERNAL);
}

void loop()
{
  unsigned int adc = analogRead(A0);
  Serial.print(F("ADC: ")); Serial.println(adc);
  float voltage = adc * VREF / 1023;
  Serial.print(F("voltage: ")); Serial.print(voltage, 3);  Serial.println(" V");
  float current = voltage / SHUNT / INA138_GAIN;
  Serial.print(F("current: ")); Serial.print(current, 3); Serial.println(" A");
  delay(2000);
}


On voit que la tension de référence vaut 1.073V. Cette tension est mesurée sur la sortie AREF de l'ARDUINO.

Sur une PRO MINI cette broche n'existe pas, mais on pourra la fixer à 1.1V sans problème. On ajustera la valeur du gain dans le code afin de compenser.

Dans ce sketch la valeur du gain est de 19. Pourquoi cette valeur alors que sa valeur théorique est de 20 ?
Ce n'est qu'une histoire de précision de composants. Le shunt de 0.1Ω a été acheté chez un fournisseur sérieux. Il a une précision de 1%. La résistance RL que j'ai utilisé fait partie d'un jeu de résistances CMS dont j'ignore la précision (AliExpress).

J'ai donc ajusté la valeur du gain dans le code afin que le résultat affiché soit identique à la valeur du courant mesuré par mon multimètre.
Si l'on utilise une résistance RL à 1% la correction à réaliser sera plus faible.

L'ARDUINO, après avoir ajusté ces constantes affiche ceci :

ADC: 168
voltage: 0.176 V
current: 0.099 A
ADC: 167
voltage: 0.175 V
current: 0.098 A
ADC: 167
voltage: 0.175 V
current: 0.098 A
ADC: 166
voltage: 0.174 V
current: 0.098 A

Le voltage affiché est celui lu sur l'entrée A0. Comme le gain de l'INA138 est fixé à 20, la tension aux bornes du shunt est donc 20 fois inférieure.

La mesure est très stable.

4.2. Le MAX4372

Le sketch est légèrement différent (j'ai utilisé un MAX4372F avec donc un gain de 50) :

#define VREF          1.073
#define SHUNT         0.100
#define MAX4372_GAIN  50

void setup()
{
  Serial.begin(115200);
  analogReference(INTERNAL);
}

void loop()
{
  unsigned int adc = analogRead(A0);
  Serial.print(F("ADC: ")); Serial.println(adc);
  float voltage = adc * VREF / 1023;
  Serial.print(F("voltage: ")); Serial.print(voltage, 3);  Serial.println(" V");
  float current = voltage / SHUNT / MAX4372_GAIN;
  Serial.print(F("current: ")); Serial.print(current, 3); Serial.println(" A");
  delay(2000);
}

Ici il n'y a aucun besoin d'ajuster quoi que ce soit, mis à part la tension VREF.
Voici le résultat :

voltage: 0.514 V
current: 0.103 A
ADC: 487
voltage: 0.511 V
current: 0.102 A
ADC: 505
voltage: 0.530 V
current: 0.106 A
ADC: 490
voltage: 0.514 V
current: 0.103 A


La mesure est un peu moins stable, ceci étant dû probablement au gain plus élevé. Le modèle MAX4372T avec un gain de 20 serait probablement moins bruité.
Mais cela reste tout à fait exploitable.

5. Photos

Voici une photo des 2 modules :

INA138

MAX4372

Les 2 cartes font respectivement 23mm x 20mm et 20mm x 15mm.

On peut donc les utiliser comme des module ARDUINO classique, y compris sur une breadboard si le courant à mesurer est faible.

Si le courant à mesurer est supérieur à 1 ou 2 ampères il serait plus convenable d'opter pour un connecteur plus approprié.

6. Téléchargements

Ces deux projets sont téléchargeables ici :


7. Liens utiles

Les amplificateurs de courants.
Chez TEXAS :
Chez MAXIM :

8. Conclusion

La mesure de courant est largement facilitée par ces petits composants, avec un peit avantage pour le MAX4372, plus simple à mettre en oeuvre.
Il ne reste plus qu'à les exploiter sur une vraie application.

Une dernière chose : le MAX4372, l'INA138 et l'OPA363 se trouvent facilement sur AliExpress.
Le module INA138 a coûté 1.60€, le MAX4372 1.10€.


Cordialement
Henri

9. Mises à jour

03/07/2020 : le MAX4372

mercredi 1 juillet 2020

Juin 2020 : Actualité des Blogs du Mois



Actualité des Blogs du Mois


Sur le blog d'Yves Pelletier :
Sur  Framboise 314 :
Sur  MCHobby :

Cordialement
Henri

samedi 20 juin 2020

Porte Motorisée de Poulailler (4ème Partie)




Porte Motorisée de Poulailler (4ème Partie)



Aujourd'hui nous allons étudier la version à moteur continu et poulie crantée.

1. Mécanique

Le schéma de principe et les cotes sont ceux vus en première partie :

Le seule différence est que la poulie intermédiaire (sous la poulie de renvoi qui se trouve immédiatement sous le moteur) disparaît. En effet vu la taille réduite du moteur, elle n'a aucun intérêt.

Le montage a pris quelques heures :

Vue d'ensemble (la hauteur est de 1.20m)

Support moteur

Poulie de renvoi (porte ouverte)

Poulie inférieure

Poulie inférieure (porte fermée)

Les supports de poulies ainsi que le support moteur sont réalisés dans une feuille d'aluminium de 1mm d'épaisseur, à l'aide d'une cisaille, une perceuse et une lime. Le pliage est réalisé à l'étau.

Comme prévu (voir première partie) un profilé plat (10mm x 2mm x 40cm) en acier est fixé sur la porte à l'aide d'un petit boulon (photo 3) et à la poulie à l'aide d'une pince (photo 2 et 4).
La pièce plate de la pince (côté gauche) est un morceau du même profilé (10mm x 2mm) de 40mm de longueur percé en son centre (diamètre 4mm).
Un trou de 4mm est pratiqué dans la courroie afin de laisser passer la vis de fixation.

Comme on le voit sur les photos 2 et 4 la pince doit pouvoir évoluer entre les deux supports de poulie sans les rencontrer. L'écartement entre les deux supports est d'au minimum 32cm + la longueur de la pince (40mm). J'ai donc prévu 40cm.

La courroie fait 1m de long et 10mm de large (pitch 2mm) : GKTOOLS
La partie crantée de la pince est ce modèle (pitch 2mm, 10mm de large) :
La poulie moteur est un modèle 4mm 16 dents : GKTOOLS
Les 2 autres poulies sont des modèles 4mm 20 dents : GKTOOLS

Le moteur adopté est le suivant : JGA25-370
J'avais choisi un modèle 36 tours par minute mais le modèle 60 tours / minute s'avère plus intéressant. Ceci est expliqué plus loin.

2. L'électronique

Je rappelle le schéma publié en 3ème partie :

Les composants suivants ont été ajoutés à la carte de puissance :
  • le L293D avec son condensateur de découplage (à droite)
  • son transistor de commutation d'alimentation Q1 AOI403 (en bas à droite)
  • le convertisseur SX1308 (à gauche)
  • le connecteur P4 (en haut à droite)

Quelques essais préliminaires montrent que le MT3608 et le SX1308 ont un fonctionnement assez équivalent. On peut utiliser l'un ou l'autre. La carte de puissance est capable d’accueillir l'un ou l'autre modèle.

Le convertisseur FP6293-5V et le connecteur P3 dédiés à la version à servomoteur deviennent bien évidemment inutiles. Je ne les ai pas retirés pour l'instant.

Le moteur 30 tours / minute a beaucoup trop de couple et la courroie a tendance à sauter de quelques crans avant l'arrêt moteur. Le risque de dégrader la courroie est important. De plus l'arrêt moteur est difficile à détecter à l'aide de la mesure de courant.

Il a été changé pour un modèle 60 tours / minute. Le nouveau moteur met 11 secondes à ouvrir ou fermer la porte et consomme deux fois moins de courant (120mA maximum au lieu de 200mA).

Il sera facile avec ce moteur d'augmenter le temps d'ouverture et de fermeture de la porte en agissant sur la valeur du rapport PWM appliqué au L293D.
Il y a fort à parier que même un modèle 130 tours / minute convienne, avec un rapport PWM adapté.

La résistance shunt (R8) est de 1.5Ω. Ce shunt provoque une chute de tension de 180mV quand le moteur tourne (il consomme 120mA), négligeable par rapport aux 12V de l'alimentation.
La puissance supportée par cette résistance est faible : 20mW. Un modèle 1/4W peut convenir.
Celle que j'avais prévue (2W) était surdimensionnée au cas où j'utiliserais un moteur plus puissant.

Le contact de fin de course n'est pas utilisé. Lors du démarrage du logiciel, si la porte est ouverte et qu'il fait jour, une commande d'ouverture est envoyée. Comme le moteur se bloque immédiatement, le logiciel l'arrête aussitôt.

3. Le logiciel

Le sketch a évolué :
Le courant moteur est mesuré pendant l'ouverture et la fermeture. Lorsque la porte arrive en fin de course, le courant dépasse la consigne et le moteur est arrêté.

Les paramètres (options.h) sont plus nombreux :

#define PWM       255
#define IMOTOR_SHUNT      1.5

#define MOTOR_MAX_ONTIME  15000
#define MOTOR_CURRENT     0.12

PWM désigne le rapport de modulation de largeur d'impulsion du signal appliqué à la pin EN du L293D. Le maximum est de 255 (pleine vitesse).
IMOTOR_SHUNT est la valeur de la résistance shunt de mesure du courant moteur (R8 sur le schéma).
MOTOR_MAX_ONTIME est le temps de fonctionnement maximal autorisé pour le moteur. Le moteur est coupé si ce temps est dépassé. Cela pourrait se produire par exemple en cas de problème :
  • courroie détendue
  • courroie rompue
  • problème électronique
MOTOR_CURRENT est le courant maximal autorisé pour le moteur.

Il est bien évident que ces paramètres sont directement dépendants du moteur et des poulies utilisées.

Il est facile de les régler. Au départ la courroie est laissée libre, c'est à dire que la pince de fixation au profilé de manœuvre de la porte n'est pas mise en place.

Le premier paramètre à régler est le PWM. On pourra fixer ainsi le temps d'ouverture et de fermeture de la porte.
On peut chronométrer le temps que met un trait à la craie sur la courroie pour parcourir les 32cm nécessaires.
Par exemple, avec le matériel que j'ai utilisé un PWM de 150 permet d'ouvrir la porte en 17s.

Lors de l'ouverture et de la fermeture de la porte le sketch affiche le courant moteur en temps réel sur la console. Il suffit d'utiliser les boutons pour ouvrir et fermer la porte et de donner à MOTOR_CURRENT une valeur supérieure de 10% à la valeur maximale affichée.

Le temps d'ouverture ou de fermeture peut facilement être estimé en connaissant la vitesse de rotation du moteur et le diamètre de la poulie moteur.
On peut également chronométrer le temps que met un trait à la craie sur la courroie pour parcourir les 32cm nécessaires.
On donnera à MOTOR_MAX_ONTIME une valeur supérieure.

4. Remarques

4.1. Le chargeur

Le TP4056 a tendance a entrer en protection en fin de course si le moteur utilisé est trop puissant. C'était assez souvent le cas avec le moteur 30 tours / minute.

Il existe deux modèles de chargeur TP4056 :
Avec protection

Sans protection

On peut adopter le modèle sans protection.

Si l'on utilise le modèle avec protection et que celle-ci se déclenche on peut relier les bornes OUT- et B-, ce qui la désactivera.

4.2. Le convertisseur 12V

Les modules MT3608 et SX1308 fonctionnent moins bien avec une tension de batterie proche de 3V. Leur tension de sortie chute à environ 8V. Cela n'empêche pas la porte de s'ouvrir et de se fermer, mais le déplacement est plus lent.
Normalement ce genre de situation ne devrait pas arriver, sauf si la batterie arrive en fin de vie.

5. Téléchargements

Cette quatrième version est disponible ici : 

Le paramétrage correspond à un moteur du type JGA25-370 et un temps d'ouverture de 17 secondes (PWM = 150).

6. Conclusion

Ce montage offre pas mal d'avantages par rapport à celui équipé d'un servomoteur :
  • le moteur peut soulever une porte de plusieurs kilos
  • aucun contact de fin de course n'est nécessaire
  • la porte fermée est plaquée avec force au sol
Le montage mécanique ne m'a pas pris plus de temps, malgré la fabrication des supports de moteur et de poulies. La version à servomoteur nécessitait un levier pas très facile à fabriquer.


Cordialement
Henri

jeudi 4 juin 2020

Mai 2020 : Actualité des Blogs du Mois


Actualité des Blogs du Mois


Sur le blog d'Yves Pelletier :
Sur  Framboise 314 :
Sur  MCHobby :
Sur Framboise au potager :
Sur Papsoid :

Cordialement
Henri

mercredi 27 mai 2020

MAX7219 : affichage matriciel




MAX7219 : affichage matriciel



Nous allons parler aujourd'hui de modules MAX7219 permettant de réaliser un afficheur matriciel à 64 LEDs.
Nous allons examiner certains aspects que l'on ne voit pas dans les nombreux tutoriels qui foisonnent sur le WEB :
  • alimentation et découplage
  • affichage de caractères accentués
  • affichage clignotant
  • utilisation avec un ESP32 (y compris les touches capacitives)
  • éviter certains pièges
Ces modules existent sous forme unitaire comme ceci :
Module DIP

Module CMS


Dans le premier cas le circuit MAX7219 est un modèle DIP apparent.

Le deuxième module est équipé d'un circuit CMS situé sous l'afficheur, plus facile à organiser en panneau multi-modules jointifs.

Ils existent aussi sous forme de panneaux de 4 modules CMS ou plus :

Module quadruple


1. Le matériel

1.1. Pilotage

Ces modules se pilotent en SPI. ils sont équipés de 5 broches d'entrée (VCC, GND, DIN, CS, CLK).
Il peuvent être chaînés, ils possèdent donc également 5 broches de sortie (VCC, GND, DOUT, CS, CLK) que l'on reliera aux broches d'entrée du module suivant:


1.2. Alimentation

En fonction du nombre de modules et de la luminosité prévue il faut compter environ 250mA pour 4 modules alimentés affichant du texte avec la luminosité maximale.
La consommation dépendra aussi de la police de caractères utilisées (certaines polices allument plus de LEDs que d'autres).

Le câblage devra donc être réalisé avec des fils de section suffisante.

Bien entendu si les afficheurs sont amenés à afficher des bitmaps plus ou moins pleins, cette consommation sera également supérieure.

Le courant maximal par module (ce courant correspond à l'affichage de 4 carrés pleins à luminosité maximale) dépend de l'implémentation du constructeur, en particulier de la valeur d'une résistance ISET (voir la datasheet) qui fixe ce courant.

1.2.1. Alimentation par USB
Si l'on alimente un ARDUINO ou un ESP32 par son connecteur USB il faudra tenir compte de deux contraintes :
  • le courant maximal fourni par l'alimentation ou le port USB de l'ordinateur
  • la courant maximal admissible par la diode ou le fusible de protection de la carte
La diode de protection d'une carte ARDUINO ou ESP32 admet en général assez peu de courant :
  • ESP32 DEV-KIT : diode 1A
  • ARDUINO NANO : diode 1A
  • ARDUINO MEGA : fusible 500mA
On voit que la limite est assez vite atteinte si l'on désire utiliser plusieurs afficheurs.

1.2.2. Alimentation par VIN
Il est pratiquement impossible de piloter un grand nombre de ces afficheurs en alimentant un ARDUINO par VIN pour ensuite alimenter les afficheurs par la broche 5V.
Je vous renvoie à cet article :
Voir le paragraphe 3.2. Broche VIN.

Si l’on alimente l'ARDUINO en 7.5V, le courant maximal disponible sur la broche 5V sera de 480mA.

1.2.3. Alimentation dédiée
Pour piloter un grand nombre d'afficheurs il serait préférable d'alimenter les afficheurs directement en 5V à l'aide d'une alimentation dédiée de puissance suffisante. Le microcontrôleur pourra également être alimenté directement en 5V à l'aide de la même alimentation.

Sur les modules quadruples (256 LEDs) en ma possession le courant maximal (toutes les LEDs allumées à luminosité maximale) est égal à 650mA, c'est à dire 160mA par module, donc 2.5mA par LED. Pendant la phase de maquettage j'alimente les afficheurs avec une alimentation 5V séparée, afin d'éviter de surcharger le port USB sur lequel est branché l'ESP32.

Pour un projet définitif il faut faire un bilan sérieux des consommations. Exemple avec 2 afficheurs quadruples + ESP32 :
  • connexion WIFI ESP32 : 450mA maxi
  • ESP32 connecté : 120mA maxi
  • affichage plein sur un seul afficheur (test des LEDs au démarrage) :
    • 1 afficheur : 650mA
    • ESP32 : 120mA
  • affichage de texte sur deux afficheurs
    • 2 afficheurs : 500mA
    • ESP32 : 120mA
La consommation ne devrait pas excéder 770mA au démarrage pendant quelques secondes, et retomber à 620mA ensuite. Une alimentation 5V 1A sera nécessaire.
Si toutes les LEDs des deux afficheurs étaient allumés simultanément au démarrage il faudrait plutôt opter pour une alimentation pouvant débiter au minimum 1.5A.

Attention : une alimentation à découpage ne se comporte pas comme une alimentation linéaire.
Une alimentation linéaire peut encaisser une surcharge de faible durée sans problème car la protection de son régulateur est souvent thermique, donc lente.
Une alimentation à découpage provoque une coupure de sa sortie au moindre dépassement de son courant maximal, même bref.

1.3. Découplage

Il arrive qu'aléatoirement un ou plusieurs afficheurs n'affichent plus rien si la luminosité devient élevée, dans le cas où l'on conçoit un logiciel capable de régler celle-ci par exemple. Il s'agit probablement de pics de courant générant des baisses de tension d'alimentation et qui plantent le MAX7219.

Après différents essais, pour 8 afficheurs j'obtiens de bons résultats avec une luminosité moyenne en connectant un condensateur de 220µF en parallèle sur l'alimentation des afficheurs, entre VCC et GND.
La valeur de ce condensateur monte à 3300µF si je veux afficher sans problème des carrés pleins à luminosité maximale sur seulement 4 afficheurs.

Cette valeur est bien entendu à ajuster en fonction :
  • du nombre d'afficheurs
  • du type d'alimentation, de sa puissance
  • de la longueur des câbles d'alimentation, de leur section
Il est également possible de placer plusieurs condensateurs de plus faible valeur sur chaque afficheur ou chaque groupe d'afficheurs.

Après mise en place des condensateurs il faut tester le montage avec un petit sketch qui affiche des informations suffisamment représentatives de ce que l'on compte afficher.

2. Le logiciel

2.1. Orientation

Il faut faire attention lors de l'achat à choisir les modules en fonction de ce que l'on désire afficher. Classiquement lorsque l'on chaîne plusieurs modules en ayant l'intention d'y afficher du texte on a tendance à les aligner horizontalement, sur une ou plusieurs lignes.

On constate assez vite que l'on va se retrouver confrontés à deux problèmes :
  • un problème d'orientation de chaque module
  • un problème d'ordre des modules entre eux
La plupart des librairies considèrent que le pixel 0:0 se trouve dans le coin supérieur gauche, lorsque les broches d'entrée sont situées sur le dessus du module.
Mais il est parfaitement possible qu'un constructeur puisse choisir une orientation différente, et comme les vendeurs ne précisent pas ce genre de détail il est donc difficile de savoir comment orienter les modules sans les essayer.

Les librairies considèrent également que les modules sont chaînés de la droite vers la gauche. Si cet ordre est inversé, la chaîne ABCD sera affichée DCBA.

Pour résumer, lorsque l'on chaîne plusieurs modules ensemble, il est plus que probable que l'on obtienne un affichage mal orienté ou inversé.

Lorsque l'on dispose de modules unitaires il est facile de les disposer côte à côte et de les chaîner pour obtenir un affichage correct des caractères.

A noter que les modèles CMS offriront 4 possibilités d'orientation, ce qui ne sera pas le cas des modèles DIP. Les modèles DIP ne permettront pas non plus d'accoler les afficheurs sur plus d'une ligne, à moins de tolérer un interligne.

On ne peut donc que recommander l'achat de modules CMS simples et de les combiner selon la librairie utilisée.

Mais que se passe t-il avec un module quadruple ? Là aussi tout dépend du constructeur, et de la librairie choisie. Si ces modules sont chaînés de droite à gauche et que la librairie ne permet pas de changer l'orientation, le résultat sera celui-ci :


Il peut probablement arriver que la combinaison modules / librairie ne donne pas de résultat satisfaisant.

Il existe un certain nombre de librairies permettant de gérer ces afficheurs. Malgré tout la seule qui permette de choisir l'orientation des modules est celle-ci :

Cette autre librairie sera nécessaire :

La librairie MD_PAROLA permet de choisir entre 4 orientations :
  • PAROLA_HW : chaînage horizontal affichage inversé (en miroir)
  • GENERIC_HW : chaînage vertical
  • ICSTATION_HW : chaînage horizontal gauche-droite
  • FC16_HW : chaînage horizontal droite-gauche
La majeure partie des blocs de 4 afficheurs vendus sur ALIEXPRESS se pilotent en utilisant le paramètre FC16_HW :

La librairie possède pas mal de fonctionnalités utiles :
  • scrolling horizontal et vertical
  • justification à gauche, à droite, au centre
  • réglage de l'espace inter-caractères
  • gestion de zones d'affichage séparées
  • etc.
Une autre librairie fonctionne avec les blocs de 4 afficheurs chaînés de droite à gauche, celle de Nick Gammon :

D'autres librairies ne fonctionneront qu'avec des afficheurs simples chaînés de bas en haut avec des fils :

Il faut avouer que dans le monde des librairies MAX7219 c'est un peu la jungle.
Il est important d'évaluer les possibilités de quelques unes afin de ne pas s'engager dans une voie sans issue qui ne permettrait pas d'obtenir le résultat escompté.

2.2. Le bus SPI

La librairie MD_PAROLA permet de piloter l'afficheur en utilisant soit le bus SPI natif du microcontrôleur soit un bus SPI émulé (bitbanged SPI).
Dans le premier cas on reliera l'afficheur aux pins SPI du microcontrôleur :
  • DIN : MOSI (D11 sur un ARDUINO)
  • CLK : CLK (D13 sur un ARDUINO)
  • CS : SS (D10 sur un ARDUINO) ou un autre choix
Dans le deuxième cas, le choix des broches est libre, mais la communication sera moins rapide.

Exemple :
// Hardware SPI connection
MD_Parola P = MD_Parola(MD_MAX72XX::FC16_HW, CS_PIN, MAX_DEVICES);

// Arbitrary output pins
MD_Parola P = MD_Parola(MD_MAX72XX::FC16_HW, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);

MAX_DEVICES représente le nombre d'afficheurs à chaîner.

Dernière chose, cette librairie fonctionne aussi bien avec un ARDUINO qu'avec un ESP8266 ou un ESP32.

2.3. Afficher des messages

La librairie MD_PAROLA, comme beaucoup d'autres d'ailleurs, ne recopie pas les messages qu'on lui demande d'afficher. Il s'en suit que ces chaînes de caractères doivent être impérativement stockées dans des variables globales ou statiques.
Une variable locale à une fonction ne conviendra pas, car son contenu n'est pas persistant.

2.4. L'UTF8

Moyennant la création d'une police de caractères adaptée et d'une petite fonction de conversion il est parfaitement possible d'afficher des caractères accentués.
Cette police est fournie dans l'exemple Parola_UFT-8_Display.

Le code de conversion :

2.5. Affichage clignotant

On pourrait bêtement penser qu'il suffit d'afficher un espace à la place des deux points d'une horloge toutes les deux secondes pour obtenir 2 points clignotants.
Il n'en est rien.
Cela marcherait avec une police de largeur fixe, celle de la librairie est à largeur variable.
Le caractère ':' fait 1 pixel de large, l'espace en fait deux. On obtiendrait donc un affichage dont la largeur change toutes les secondes, peu esthétique.

Il faut donc créer un espace simple dans notre police de caractères. J'ai utilisé le caractère 31 (0x1F) pour cet usage (l'espace étant le 32).

  1, 0,      // 31 - 'Small space'
  2, 0, 0,        // 32 - 'Space'


Il suffit donc d'utiliser ce caractère pour afficher un espace étroit à la place des 2 points, toutes les 2 secondes :

  static char timeString[10];
  struct tm timeinfo;
      // ...
      getLocalTime(&timeinfo);
      if (timeinfo.tm_sec % 2) {
        strftime(timeString, sizeof(timeString), "%H:%M", &timeinfo);
      }
      else {
        strftime(timeString, sizeof(timeString), "%H\x1f%M", &timeinfo);
      }
      hDisplay.displayText(timeString, PA_CENTER, 0, 0, PA_PRINT, PA_NO_EFFECT);


3. Le projet

Le petit projet exemple se propose d'implémenter une horloge sur la base d'un ESP32, avec les fonctionnalités suivantes :
  • affichage heure + minutes avec 2 points clignotants.
  • affichage de la date configurable :
    • jour de la semaine + jour du mois
    • jour + mois
    • jour + mois + année + saint du jour (avec scrolling)
  • luminosité réglable
  • gestion de l'heure par NTP avec changement d'heure été / hiver
  • configuration par 2 touches sensitives
  • configuration sauvegardée en FLASH
  • serveur WEB (brouillon)
La totalité des LEDs des deux afficheurs (afficheur de l'heure puis l'afficheur de la date) sont allumées au démarrage pendant une seconde chacun.

Le saint du jour est obtenu grâce au même moyen que sur le projet Afficheur TFT pour ESP8266 :
Voir paragraphe 5.1. Le service PHP.

Il conviendra d'adapter l'URL dans le fichier ephemeris.cpp si cette option est utilisée, sinon on la remplacera par une chaîne vide.

Le serveur WEB de l'ESP32 (vide pour le moment) pourra servir de page de configuration :
  • URL du serveur NTP
  • URL du serveur saint du jour
  • heure de réveil, d'alarme, etc.
  • etc.
Les deux afficheurs 4x8x8 sont câblés comme suit :
  • CLK : GPIO18
  • DIN : GPIO23
  • CS : GPIO26 et GPIO25
Les deux blocs d'afficheurs ne sont pas chaînés, ils sont simplement pilotés en parallèle avec deux pins CS différentes.

L'ESP32 est un classique DEV-KIT mais n'importe quel modèle peut convenir.

4. Téléchargement

Ce projet est disponible ici : 

5. Conclusion

Il faut bien avouer que ces afficheurs matriciel sont très attrayants. Ils permettent de réaliser des affichages visibles de loin et des animations intéressantes.

Il va sans dire que ce projet n'est qu'une première version appelée à évoluer.


Cordialement
Henri