Auteur Sujet: Problème pour utiliser l'horloge externe du PCA9685  (Lu 1933 fois)

trimarco232

  • Jr. Member
  • **
  • Messages: 62
    • Voir le profil
Re : Problème pour utiliser l'horloge externe du PCA9685
« Réponse #30 le: janvier 10, 2021, 07:03:20 pm »
Bonjour,
merci pour le partage
pour mieux faire tu peux :
1) utiliser le spi hardware du méga, le but c'est que les hc595 soient renseignés sans monopoliser la cpu
2) utiliser le hardware d'un timer pour générer le latch, en mode ctc, et avec une interruption au front montant pour lancer le nouveau remplissage des hc595 - qui sera pris en comte au prochain front montant ; le but c'est d'avoir un découpage automatique et rigoureusement on time du découpage des crans du pwm, et toujours sans intervention de la cpu
je n'ai pas forcément été clair, fais moi le savoir

c'est quel modèle de teensy que tu attends  ? (on peut multiplier la fréquence du pwm par le nombre de spi hardware du mcu)

simontpellier

  • Jr. Member
  • **
  • Messages: 58
    • Voir le profil
Re : Problème pour utiliser l'horloge externe du PCA9685
« Réponse #31 le: janvier 10, 2021, 09:45:59 pm »
Bonsoir,

et merci pour la réponse !

J'avoue que non, tout n'est pas bien clair mais ça tient à moi. Je n'ai par exemple pas idée de ce qu'est un SPI hardware, pas plus que lent ou rapide)

Mais... on est tout de même assez bien synchronisés puisque pour cadencer le SPI des 74HC j'ai utilisé un timer (le 2), avec un réglage de la fréquence PWM par bascule du registre TCNT2
(mais pas en mode CTC... erreur ?

Je joins le code. Que j'ai pu greffer dans mon code principal sans occasionner le moindre souci ni ralentissement. Et avec un cahier des charges respecté :
- 40 PWM possiblement générées
- 125 pas de réglage (avec un talon à 53, valeur empirique personnelle, ce qui donne une plage de réglage effective entre 53 et 178 et par conséquent un pas de réglage plus fin)
Ainsi régulée, la fréquence "shiftPWM" est totalement indépendante du nombre de 74HC pilotés, du moins dans la limite du "cahier des charges" et dans la plage 30Hz-100Hz (et peut-être au delà ?)

Voici le code. Les variables consigne PWM sont fixes et auraient aussi bien pu être déclarées comme constantes... dans la réalité, c'est bien sûr au code de les déterminer en temps réel.
/* ARDUINO MEGA */

const int SS_PIN = 25;     // SS(slaveSelect)/slave - pin 14 (DS / Serial Data Input) on the 74hc595
const int MOSI_PIN = 26;   // MOSI (Master Out Slave Inv- The Master line for sending data to the peripherals) - pin 12 (ST_CP / Storage Register Clock Input (latch)) on the 74hc595
const int MISO_PIN = 29;   // MISO (Master In Slave Out - The Slave line for sending data to the master) - pin 11 (SH_CP / shift register clock input) on the 74hc595

const int8_t number_of_74hc595 = 1;
const int8_t numOfRegisterPins = number_of_74hc595 * 8;
boolean pin74hc[numOfRegisterPins] = { 0 };      // data-table, matching with the state of the 74HC595 ouputs

 // pseudos PWM à simuler - pour chaque PWM, le tableau donne le cran entre 20 et 120
uint8_t PWM[40] = { 54, 64, 105, 94, 70, 34, 73, 0, 54, 64, 105, 94, 109, 34, 73, 0, 54, 64, 105, 94, 109, 34, 73, 0, 54, 64, 105, 94, 109, 34, 73, 0, 54, 64, 105, 94, 109, 34, 73, 0 };   

byte tcnt = 192; // le timer commute tous les (256-tcnt) cycles
/*
  avec PRESCALER à 32 (TCCR2B = 0b00000011)
  tcnt=126 => 30Hz (les valeurs de tcnt sont empiriques faute de linéarité dans les valeurs de fréquence obtenues)
  tcnt=160 => 40Hz
  tcnt=180 => 50Hz
  tcnt=192 => 60Hz 
  tcnt=208 => 80Hz
  tcnt=218 => 100Hz
*/     
byte cran = 0;

void setup() {
  Serial.begin(115200);

  pinMode(SS_PIN, OUTPUT);
  pinMode(MOSI_PIN, OUTPUT);
  pinMode(MISO_PIN, OUTPUT);

  bitClear (TCCR2A, WGM20); // WGM20 = 0
  bitClear (TCCR2A, WGM21); // WGM21 = 0
  TCCR2B = 0b00000011;
  TIMSK2 = 0b00000001; // Interruption locale autorisée par TOIE2
}

void writeRegisters() {
  PORTA &= ~_BV(PA4);       // pin 26
  for (int8_t i((number_of_74hc595)*8-1) ; i>=0 ; i--) {
      PORTA &= ~_BV(PA7);   // pin 29
      if (pin74hc[i]==0) /*=>*/ PORTA &= ~_BV(PA3);   // pin 25
      else /*=>*/ PORTA |= _BV(PA3);
      PORTA |= _BV(PA7);    // pin 29
    }
  PORTA |= _BV(PA4);
}

void setRegisterPins(byte cran) {  //Place les pins du 74HC595 à l'état HAUT ou BAS
    for(uint8_t engine(0) ; engine<numOfRegisterPins ; engine++) {
      pin74hc[engine] = cran<PWM[engine];
    }
  writeRegisters();
}

ISR(TIMER2_OVF_vect) {
  TCNT2 = tcnt ;
  cran++;
  setRegisterPins(cran);
  if (cran==178) cran=53;
}

void loop() {

/* CODE PRINCIPAL ICI */
}

Le SPI dédié aux 74HC est maintenant sur les broches 26-29 du MEGA... parce que j'utilisais déjà les 50-52  pour le bus CAN et parce que je n'y ai vu aucune différence.
Mais voilà bien une zone d'ombre pour moi qui a résistée à mes questions à Google. Si quelqu'un peut m'indiquer le début de la piste, ça sera apprécié !

(Le Teensy à venir : un 3.5)
« Modifié: janvier 10, 2021, 09:51:51 pm par simontpellier »

trimarco232

  • Jr. Member
  • **
  • Messages: 62
    • Voir le profil
Re : Problème pour utiliser l'horloge externe du PCA9685
« Réponse #32 le: janvier 11, 2021, 10:05:15 pm »
cadencer en pwm avec réglage de la période c'est tout aussi bon que le ctc, j'ai oublié de le mentionner

c'est pas mal, mais il faut faire le spi par le hardware ; ton arduino arrive à s'en sortir car il lui reste un peu de temps entre la fin de l'émission des trames spi et l'interruption, mais si tu charges encore la bête, tu vas te retrouver avec des "unexpected behaviors"

on peut faire le spi de 2 manières :
soit en soft, comme toi, en faisant bagoter manuellement les pins en digital HIGH ou LOW (tu l'a fais en écrivant direct sur les registres, ça va aussi  (mais il y aurait aussi mieux comme méthode pour faire ça))
soit en utilisant le périphérique spi hardware de l'avr : une fois configuré, il n'y a plus qu'a écrire le byte à transmettre dans le périphérique, et celui-ci s'occupe tout seul de faire bagoter les pins MOSI et SCK, sans intervention de la cpu, qui reste disponible pour le reste du travail : c'est tout l'interrêt d'avoir des périphériques hardware, et en effet, souvent les programmateurs ignorent cela, je t'engage à te mettre au courant, c'est largement documenté et pas sorcier

pareil pour le latch (ou SS ou RCLK) : il vaut mieux configurer et utiliser une des 2 sorties pwm de ton timer2, plutôt que de l'écrire manuellement sur la pin 25

le spi hardware est sans doute déjà pris par le can sur l'avr, donc il faut débrancher le can si tu veux tester
le teensy a un can hardware, ce qui permet de libérer ses 3 spi hardwares pour piloter 3 branches de hc595 distinctes, et par là multiplier la fréquence du pwm par 3 ... tu vas pouvoir t'amuser !

je t'ai représenté le truc sur la pj

la 1ère ligne, c'est le signal pwm généré par l'arduino, et raccordé au(x) latch des hc595 ; la flèche vers le haut implique 2 choses :
1) le latch des hc595, qui prennent en compte, au front montant, les données qui viennent de leur être shiftés ; la durée de tes crans sera nickel
2) l'interruption provoquée par le timer du pwm

la 2ème ligne représente grossièrement les signaux MOSI (ou data ou SER) et SCK (ou SRCLK) envoyés par le spi hardware ; le déclenchement de cet envoi se fait dans la routine de l'interruption évoquée ci-dessus ; si tu fais ces signaux en soft, tu vois qu'il reste peu de temps à l'arduino pour faire autre chose ; si c'est automatique par le hardware, il aura tout son temps

les 3èmes et 4èmes lignes montrent les signaux obtenus (il n'y a que 6 crans dans l'exemple) sur 2 sections différentes
exemples : 1/6 3ème ligne : 3/6 4ème ligne
vbui fgazuityer ?
« Modifié: janvier 12, 2021, 10:07:22 am par trimarco232 »

simontpellier

  • Jr. Member
  • **
  • Messages: 58
    • Voir le profil
Re : Problème pour utiliser l'horloge externe du PCA9685
« Réponse #33 le: janvier 12, 2021, 10:14:30 pm »
wouah cette fois j'ai compris... le principe !
D'un côté le CPU dont le boulot est d'exécuter le code
de l'autre le hard qui offre des services gratuits... très improductif en effet de s'embêter à les reproduire dans du code !

le timer qui se charge de faire "bagoter" (chez moi ça "commute"... pas la même promo on dirait) plutôt qu'une instruction ça c'est grandiose ! (pas encore mis en œuvre mais va falloir !)
Et pour me documenter sur le SPI "harware" ?  pas besoin de Google... à priori tout est dans la datasheet.

Un grand merci pour cette explication, pour le temps que ça demande obligatoirement. Avec un schéma de plus ! (*)
Pour l'instant, en l'état, ça fonctionne déjà à merveille... au départ c'était "pour voir" mais l'élimination des PCA9685 semble en prime solutionner des problèmes de plantages du bus I2C, c'est bon à signaler au passage puisqu'il y a maintenant des milliers (presque) d'abonnés à cette chaîne !

Juste ça que je n'ai vraiment pas compris : la conclusion (... pas la même promo...)

(* une remarque sur le schéma : les deux sections sur lesquelles les pulses ne montent pas en même temps ne pourront pour le coup jamais être synchronisées ! Mais l'idée passe bien)

A nouveau : merci !

trimarco232

  • Jr. Member
  • **
  • Messages: 62
    • Voir le profil
Re : Problème pour utiliser l'horloge externe du PCA9685
« Réponse #34 le: janvier 13, 2021, 05:24:02 pm »
on peut fabriquer des signaux de toutes formes avec cette méthode
la 2ème ligne montre un décalage d'un cran avant l'application de la puissance : ce principe est utilisé dans des ic spécialisés pour répartir les appels de courant ; bien entendu, cette méthode ne nous convient pas, il faudra déterminer l'alim en conséquence
content de voir que tu suis  8)

hinano70

  • Newbie
  • *
  • Messages: 18
    • Voir le profil
Re : Re : Problème pour utiliser l'horloge externe du PCA9685
« Réponse #35 le: janvier 14, 2021, 02:05:00 pm »
j'ai réfléchi ... ! ... ?

il y a sans doute une solution beaucoup plus simple, tout dépend de la capacité de vos systèmes à la mettre en oeuvre, mais on est quand-même sur le forum locoduino, ça doit être possible !
l'idée, c'est de s'attaquer à la racine du problème, cad. à la transition entre deux pca9685, qui sont on l'a vu, forcément désynchronisés
on va prendre par exemple, pour fixer les idées, 31 sections, donc 2 pca :
- le 1er pca commande les sections 1 à 16, le 2ème pca commande les sections 16 à31
- donc la section 16 peut être, au choix, commandée par le 1er ou par le 2ème pca
- quand le train passe de la section 15 à la section 16, la section 16 est commandée par le 1er pca (pas par le 2ème) : la transition entre la section 15 et la section 16 se fait nickel
- quand le train passe de la section 16 à la section 17, la section 16 est commandée par le 2ème pca (plus par le 1er) : la transition entre la section 16 et la section 17 se fait chrome
- le choix duquel des 2 pca pour la section 16 se fait par un simple "ou câblé", avec 2 diodes et une résistance de pull down de 470R ; la sortie correspondante du pca qui ne commande pas la section 16 est simplement mise à 0%

que vous en pense-t-il ?

La voila ma solution !: commencer par alimenter une section par 1 PCA et finir de l'alimenter par un autre. Merci trimarco232.
Ca peut être fait logiciellement. Mais le montage avec 2 diodes ... m'intéresse et je n'ai pas bien compris. Peux tu me faire un petit schéma, merci.

trimarco232

  • Jr. Member
  • **
  • Messages: 62
    • Voir le profil
Re : Problème pour utiliser l'horloge externe du PCA9685
« Réponse #36 le: janvier 14, 2021, 06:52:25 pm »
voilà
dans l'exemple, je suis parti sur 40 sections, il faut 3 pca9685
il reste 6 sorties de libres
les 3 pca9685 sont spécialisés pour les signaux pwm ; tu peux choisir d'y mettre aussi les signaux dir1 et dir2, pour l'élégance du câblage : cela t'oblidera toutefois à disposer d'avantage d'ensembles diodes + résistance

hinano70

  • Newbie
  • *
  • Messages: 18
    • Voir le profil
Re : Problème pour utiliser l'horloge externe du PCA9685
« Réponse #37 le: janvier 14, 2021, 09:09:31 pm »
Merci, je teste ce week-end (il faut que je réadresse les sections ....)
Je viens de tester une version plus simple à modifier, pour voir (je ne suis pas un pro en électronique) :
sortie16 L298 > diode > section 16
sortie17 L298 > diode > section 17
J'ai rajouté 2 diodes donc.
Cette fois au lieu d'un ralentissement, il y a une très légère accélération au changement de section, mais plus de broutement.
Au risque de faire hurler Simontpellier, j'alimente encore les L298 qu'avec 2 fils sur In1 et In2 !

En fait j'utilise des PCA pour tout, j'en ai déjà installé 6 et je vais en rajouter au moins 2 pour les feux sur lesquels je travaille actuellement!
- commande des moteurs d'aiguillage SG90
- alimentation des sections
- commande des feux de signalisation (ce qui permet de moduler l'éclairement)
ça marche nickel sauf lorsqu'il y a changement de PCA sur 2 sections contigües, mais ça progresse !!!

trimarco232

  • Jr. Member
  • **
  • Messages: 62
    • Voir le profil
Re : Problème pour utiliser l'horloge externe du PCA9685
« Réponse #38 le: Aujourd'hui à 12:22:27 am »
les 2 diodes ne suffisent pas, il faut aussi y ajouter la résistance et la mettre à la masse
il faut commander la vitesse par les entrées enableA et enableB (pwm) du L298 ; les entrées 1, 2 et 3, 4 du L298 ne servent qu'à déterminer le sens de marche, 2 doit être l'inverse de 1 (et réciproquement ; et pareil pour 3 et 4)

mon devoir d'information m'oblige à dire ceci :
on peut se passer des diodes et des résistances, en utilisant les pca9685 en mode open-drain
l'inconvénient, c'est que par défaut les entrées pwm des L298 seraient HIGH, ce qui entraine la puissance maximale, pendant l'initialisation des pca9685 ; c'est pourquoi je préconise les résistances de pull-down

tu peux toutefois faire ceci dans le cadre d'un test (tu ne mets pas ta trix à 700€ sur les rails) :
- configurer les pca9685 en open-drain (trouver sur la toile comment faire)
- relier ensemble, sans autre forme de procès : (sortie 16 du 1er pca) - (sortie 1 du 2ème pca) - (entrée enable (pwm) correspondante du L298 correspondant)
- pour les 2 sorties qui sont sur la même entrée, mettre le pwm à 100% pour celle qui n'opère pas, et mettre le pwm à la valeur de la vitesse voulue, pour celle qui opère

une config de test pourrait avoir l'allure suivante :
« Modifié: Aujourd'hui à 07:41:21 am par trimarco232 »