Bonjour,
Voici mon expérience en matière d'expansion des E/S sur Arduino (Uno).
Premier montage: Commande de 48 aiguillages par servos à mouvements lents
(par servo, 4 points de courses réglés individuellement et mémorisés en EEPROM, de façon à passer, dans chaque sens, par une position de course extrême, avec un bon forçage mécanique, puis placement dans une position de repos avec effort et conso réduits)
C'est une sorte de TCO, sans retour optique toutefois, les positions d'interrupteurs en tenant lieu. Ce retour aurait été possible, mais boff.
J'ai eu, au départ, de grosses difficultés avec ce montage comportant sur un bus I2C :
- 2 cartes d'expansion 16 voies d'E/S Sx1509 de Sparkfun (pour une bonne vingtaine d'interrupteurs),
- 3 cartes PWM Adafruit 16-Channel 12-bit PWM/Servo Driver - I2C interface - PCA9685 (pour alimenter 48 servos d'aiguillages)
- et un afficheur 2 lignes à LCD sur I2C.
- étape 1 : bus I2C comportant quelques mètres à l'extérieur du boîtier (cartes PWM à proximité des servos) ; perturbations immédiates et irréversibles du bus dès débit sur les alimentations analogiques (mais néanmoins hachées) des locos, sous seulement 6V -> solution à écarter impérativement
- étape 2: j'ai compris que les plus grosses perturbations étaient liées à l'écran LCD piloté par I2C; j'ai essayé plusieurs modèles, tous fautifs -> écran LCD piloté par I2C à écarter : il faut piloter l'écran en direct par des E/S tout ou rien; dommage, je n'ai pas compris pourquoi, mais c'est comme ça.
- étape 3: pour être sûr du résultat, comme je voulais passer l'alimentation des locos d'analogique continu à DCC, j'ai voulu mettre toutes les chances de réussite de mon côté et j'ai donc retenu toutes les précautions de blindage possibles :
. circuit I2C uniquement à l'intérieur des boîtiers (3 boîtiers Teko ou équivalents empilés), liaisons entre cartes par câble blindé et mise à la masse du blindage à une seule extrêmité du câble; longueur totale d'environ 60cm;
. boîtiers plastiques, mais blindés de l'intérieur avec un film d'aluminium auto collant (j'avais un rouleau de film prévu pour faire les joints entre rouleaux d'isolants thermiques domotiques - à placer sous les toits) : la continuité électrique entre bandes collées avec recouvrement (il en faut plusieurs pour couvrir toutes les surfaces) est très bonne et le blindage est solide et bien continu;
. isolement opto-galvanique + porte logique de remise en forme pour les sorties PWM (pilotage des servos); 12 câbles de liaisons vers les servos soigneusement blindés, avec mise à la masse du blindage côté boîtiers (cela représente une longueur cumulée considérable d'une trentaine de m);
. alimentations séparées pour, d'une part la partie Arduino et circuits logiques intérieurs aux boîtiers, d'autre part les circuits extérieurs aux boîtiers (puissance et pilotage des servos); un régulateur de tensions déporté au plus près des servos, pour chaque groupe de 4 servos.
Résultat : plus de problème de perturbations du bus I2C , ni même de vibrations résiduelles des servos au repos, même après être passé en DCC pour l'alimentation et le pilotage des locos du circuit (8 actuellement)
Conclusion pour ce montage :
Outre le circuit I2C trop long, la perturbation venait surtout de l'afficheur LCD piloté en I2C.
Dans un deuxième temps, j'ai pris les précautions maximales en terme de blindage. Non seulement le bus I2C n'est plus perturbé, mais il me semble que le fonctionnement des servos est plus net (plus de vibrations résiduelles au repos, avec les consignes de butées bien réglées).
Le montage permet de piloter 48 aiguillages dans un environnement de locos pilotées en DCC. On pourrait augmenter ce nombre car le nombre de cartes PWM pouvant être couplées est bien supérieur (...et il reste de la place dans les boîtiers).
Remarque : L'environnement d'un circuit ferroviaire est plutôt bruité électromagnétiquement, et les précautions de blindage ne sont certainement pas un luxe. Elles ne sont pas si difficiles que cela à mettre en oeuvre, avec les quelques 'astuces' indiquées. J'ai rétrospectivement un doute sur la nécessité impérative du découplage opto-galvanique des signaux PWM de pilotage des servos, mais c'est fait et ça ne peut nuire.
Deuxième montage: Commande individuelle de 8 locomotives en DCC, par encodeurs rotatifs et boutons-poussoirs
Un montage comportant 4 cartes d'expansion 16 voies d'E/S Sx1509 de Sparkfun (pour gérer des boutons de contacts tout ou rien et des encodeurs rotatifs [2 contacts TOR]); il y a 8 fois un encodeur + 4 contacts, soit 48 contacts ce qui permet de piloter en direct huit locomotives; il y a quelques autres contacts supplémentaires pour la programmation du couplage de locos entre elles et diverses fonctions.
Tenant compte de l'expérience précédente l'écran LCD 4 lignes est piloté directement en tout ou rien. Le montage comporte aussi le circuit LM18200 (cité sur Locoduino) pour mettre en forme les signaux DCC. A la différence du précédent montage, pour ne pas risquer de détériorer les fronts du signal DCC, je n'ai pas placé d'isolement opto-galvanique sur le signal de pilotage DCC (isolement entre bas niveau et puissance'). Bas niveau et puissance sont toutefois placés dans deux boîtiers distincts, alimentations comprises.
Les mêmes précautions de blindage que ci-dessus ont été prises pour les deux boîtiers superposés abritant le montage.
Résultat : Le montage fonctionne parfaitement, sans perturbations, et permet de piloter simultanément en DCC 8 locomotives, chacune ayant sa vitesse contrôlée par son propre encodeur rotatif. Affichage sur LCD des vitesses (cible et actuelle) des locos, témoin d'allumage des feux, etc...
Complément sur la carte d'expansion 16 voies d'E/S Sx1509 de Sparkfun:
La version que j'ai utilisée a été stoppée récemment et remplacée par un nouveau modèle (non testé) encore plus petit ce qui peut être intéressant.
On peut programmer chaque carte en entrée, en sortie, avec pull-up ou non, et avec ou sans traitement anti-rebond (plusieurs options).
Pour les entrées, on peut aussi programmer individuellement, pour chaque entrée, une interruption, sur montée, sur descente ou sur changement au choix. L'interruption est valable pour toute les entrées d'une carte, et doit être raccordée à une entrée Arduino sur laquelle on a défini une interruption.
Ensuite, il faut par I2C récupérer un mot d'état de la carte qui indique l'entrée ayant déclenché l'interruption puis lire l'état, si nécessaire (déjà traité anti-rebond, si on a choisi cette option). Ce processus est très réactif et très rapide. Pas besoin de polling permanent des E/S.
De la sorte, j'ai même pu traiter au travers de telles cartes les encodeurs rotatifs. Bien sûr, il faut modifier la bibliothèque de base fournie avec les encodeurs (notamment parce que le programme d'interruption ne peut, par construction, contenir de lecture I2C faisant elle-même appel à des interruptions), mais ça se fait assez facilement, et ça marche très bien.
Sur l'ancien modèle, compte tenu des possibilités de paramétrage des adresses, on pouvait utiliser 4 cartes sur le même bus, soit 4x16 E/S.
Pour le modèle de carte PWM, le nombre de cartes pouvant être mises en parallèle est encore bien plus grand.
Remarque d'ordre général concernant ces montages comportant beaucoup d'entrées-sorties:
J'ai été frappé par le temps d'assemblage de tels circuits. Pour garder la possibilité de démonter les différents circuits imprimés en cas de besoin, j'ai mis des connecteurs là où c'était indispensable. Cela fini par faire beaucoup de perçages, de soudures, de soudage de câbles sur connecteurs; bien de ces opérations sont assez délicates et fastidieuses, mais inévitables.
Photos et autres renseignements disponibles en cas de besoin.