Bonjour,
Je bute sur la durée (... estimée trop longue à 15ms) du cycle de passation des commandes des états des 16 ports du PCA9685 par le bus I2C:
. Arduino Due
. bus I2C à 400kHz
. modules PCA9685 Adafruit (6 par Arduino Due)
. bibliothèque utilisée: celle sur Github "Adafruit_PWMServoDriver.h"
Pour mémoire, notre réseau de club en analogique est actuellement cantonné par 8 Arduino Due pilotant chacun 8 cantons.
Les PCA9685 servent d'interface tout ou rien avec des relais pour commuter les sources de traction et, à piloter pour l'instant en tout ou rien les feux des signaux et des pupitres (... les fonctions de clignotement et de "fading": ... allumage et extinction progressive viendront se rajouter ultérieurement).
Je n'ai rien trouvé sur internet comme "truc", comme bibliothèque plus rapide, comme commande particulière à envoyer aux PCA9685 pour les forcer ni, aucun sujet sur ces 15ms (... ce qui est étonnant vu qu'on peut théoriquement chaîner en I2C jusqu'à 62 PCA9685 ce qui prendrait donc environ 1s de cycle, ce qui est énorme et occupe abusivement l'Arduino Due).
Auriez-vous déjà rencontré ce problème et comment l'avez vous résolu ?
On ne va quand même pas doubler chacun des 8 Arduino Due de Block System par un autre (... Due ou Teensy) pour prendre en charge ces PCA9685 en dehors du programme du Due de Block System. Si ?
J'ai regardé s'il y avait moyen de transmettre les commandes par Bytes vers des registres des PCA9685 (... comme je le fais depuis les modules GPIO 23017 pour les entrées d'information: 3 modules I2C 23017 par Arduino Due de Block System).
J'ai regardé s'il existait un "sous programme en Python" qui pourrait être plus "efficace" mais, je n'ai pas trouvé.
Pour mémoire, il est prévu de relier les Arduino de Block System par un Bus CAN.
Question accessoire: devrait on utiliser la possibilité des Arduino Due d'avoir un second Bus Can qui transférerait à fort débit les tableaux de bits à envoyer vers l'Arduino d'interface I2C ? (pour décharger le Due de cette tâche afin de revenir à un temps total de traitement permettant un rafraîchisement des entrées-sorties au moins 10 fois par seconde).
Pour info, voici les lignes de code concernant les ordres envoyés aux PCA9685:
...
PCA9685_11.begin();
// PORT A
if (tabOutputsPortS11A[0]==0) {
PCA9685_11.setPWM(1, 0, 4096); }
else {
PCA9685_11.setPWM(1, 4096, 0); }
if (tabOutputsPortS11A[1]==0) {
PCA9685_11.setPWM(2, 0, 4096); }
else {
PCA9685_11.setPWM(2, 4096, 0); }
if (tabOutputsPortS11A[2]==0) {
PCA9685_11.setPWM(3, 0, 4096); }
else {
PCA9685_11.setPWM(3, 4096, 0); }
if (tabOutputsPortS11A[3]==0) {
PCA9685_11.setPWM(4, 0, 4096); }
else {
PCA9685_11.setPWM(4, 4096, 0); }
if (tabOutputsPortS11A[4]==0) {
PCA9685_11.setPWM(5, 0, 4096); }
else {
PCA9685_11.setPWM(5, 4096, 0); }
if (tabOutputsPortS11A[5]==0) {
PCA9685_11.setPWM(6, 0, 4096); }
else {
PCA9685_11.setPWM(6, 4096, 0); }
if (tabOutputsPortS11A[6]==0) {
PCA9685_11.setPWM(7, 0, 4096); }
else {
PCA9685_11.setPWM(7, 4096, 0); }
if (tabOutputsPortS11A[7]==0) {
PCA9685_11.setPWM(8, 0, 4096); }
else {
PCA9685_11.setPWM(8, 4096, 0); }
// PORT B
...
Bon, je suis dans la panade et j'espère que l'un d'entre vous pourra m'indiquer "une piste" pour diminuer le temps "processeur" pris pour gérer ces sorties.
Enfin:
. l'objectif est de gagner un facteur 10, pas 10% !
. je ne tiens pas à passer le bus I2C en 1MHz (longueur physique du bus, sensibilité aux parasites, alimentation des PCA9685 en 3,3V l'interdisant)
On pourrait discuter d'une autre architecture ou toutes les liaisons s'opérent par l'intermédiaire de bus CAN (... ce que vous faîtes, je crois: ce n'a pas été retenu parce que ça oblige dès le départ à prévoir un Arduino supplémentaire en tête de tout interface). Quoi que s'il fallait rajouter un Arduino accessoire à chaque Due, on en serait là.
Bonne soirée,
Patrick