Auteur Sujet: PWM Bit Banging ISR  (Lu 6422 fois)

laurentr

  • Hero Member
  • *****
  • Messages: 648
    • Voir le profil
PWM Bit Banging ISR
« le: mars 01, 2023, 02:51:21 pm »
Bonjour


On peut utiliser la fonction analoguWrite(à pour utiliser du PWM sur certaines pins de nos CPU qui en sont capable d un point de vue Hardware.

Lorsque le besoin de plus de pins devant générer du PWM on peut soit changer de CPU soit... utiliser une technique nommé PWM Bit Banging qui consiste à passer successivement à intervalles réguliers (rapides) les sorties digital soit à l état haut soit à l état bas.
On évite d'utiliser la fonction delay() entre chaque changement pour permettre l'exécution du reste du code.( mais un exemple trivial avec delay pour s'approprier le phénomène est possible)

Selon cette fréquence de bascule ON/OFF sur une durée donnée (intervalle) on à une tension moyenne qui est perçue et donc simule un niveau de PWM. ( duty cycle)
Pour gérer du PWM sur toutes les sorties de nos CPU nous avons donc cette solution.

On va confier les fonctions millis() et micros() à un Timer hardware ce qui les rendra régulières et non bloquante puisque nous veillerons à ce que ce timer ne soit pas sollicité pour d autres taches autres que de compter pour millis(à et micros().

Oui mais.... selon la charge de traitement du CPU  on peut avoir des "ratés" dans la bonne exécution des instructions du bit banging et donc ne pas avoir précisement le résultat escompté.
Si on veut garantir la bonne exécution de ces bascules ON/OFF je pense que l'on a "tout" intérêt à baser sur une brique hardware (un autre Timer) la gestion de ce PWM.

Malheureusement je ne vois pas comment articuler cette mise en place notamment en utilisant par exemple les très bonnes librairies de Khoih Hoang pour de nombreux CPU:

https://github.com/khoih-prog

(rechercher les repositories avec comme mot clé SLOW_PWM )

Si on peut m'aiguiller sur la bonne voie... d'avance merci.

Le souhait est donc de mettre en œuvre un PWM Bit Banging sur un Timer dédié de façon "simple" et de partager cette réalisation utile au plus grand nombre. ( peut être une via une librairie Locoduino dediée?)

Laurent



trimarco232

  • Sr. Member
  • ****
  • Messages: 345
    • Voir le profil
Re : PWM Bit Banging ISR
« Réponse #1 le: mars 11, 2023, 12:49:21 am »
Bonjour Laurent,
pèle même :
- si possible diminuer la fréquence ou le nombre de crans, ou du moins éliminer les crans correspondant aux duty les plus courts
- oublier les bibliothèques : ou bien tu ne sais pas au juste ce qu'elles font : c'est casse gueule, ou bien tu sait comment elle fonctionne, donc tu peux réécrire en optimisant pour ton appli
- choisir un mcu + rapide, genre arm, ce qui te permet de prioriser tes interruptions, voire d'en accélérer le traitement
- choisir un pi pico : il a 8 timer ayant chacun 2 sorties pwm ; de plus tu peux programmer le périphérique pio pour te donner 8 pwm supplémentaires, ça fait 24 ; et les pwm peuvent fonctionner avec la dma, donc sans interventions des cpu ; car il y a 2 cpu à 133MHz chacune ...

laurentr

  • Hero Member
  • *****
  • Messages: 648
    • Voir le profil
Re : PWM Bit Banging ISR
« Réponse #2 le: mars 14, 2023, 10:41:18 am »
Hello Marc


Merci pour les info

J'ai en grande partie resolu certains des "sauts" visuel dans la gestion de mes effects lumineux en adoptant pour tous les timings utilises dans mon code l usage de micros()
J avais constaté que lorsque certains blocs tournent sur millis() et d autres sur micros() j avais parfois des "sauts" disgracieux.

Cette ajustement semble avoir au moins visuellement fortement estompé ce qui etait visuellement percu.

Pour le moment la loop génère le PWM BIT BANGING, les timings sont basés sur micros() qui est affecté à un timer hardware spécifique selon le modèle de CPU. Cela tourne bien avec en moteur pour la trame DCC la lib de AIKO PRA qui est lui aussi sur un timer hardware dédié.
La cohabitation tourne bien!

Grosso modo il y a une 20 aine de steps entre l'effet FULL OFF et FULL ON et 18 canaux en parallèle tournent bien. ( PWM, effet lumineux différencies)
Avec des effets de fondus lumineux ( UP ou DOWN) il y a de léger décalages ( pas de synchro inter canaux)  mais rien de gênant à ce que j'en perçois.

Je dois faire des essais pour aller au delà de ce nombre et voir si des limites perturbatrices apparaissent. ( je pense plus à une extension de latence visuelle sur les effets de fondus)

J ai réglé mes "AVR" pour tourner à 20MHz( parfois 16) . Certains peuvent aller encore au delà (24Mhz) de façon stable ce qui apporte quelques ressources en "overclocking" si cette piste devait être considérée. ( et on reste loin des 120Mhz et au delà de CPU plus véloces!)


Pour ce qui est de quitter les AVR pour des ARM... l'idée est plaisante mais il y a encore peu de bibliothèque pour les exploiter ( traitement du signal DCC hormis la lib DCCNMRA,...)

Disposer de plus de ressources est toujours un gage de solution et d'ouverture vers des solutions enrichies ( la fuite en avant!)

J'ai néanmoins lu avec attention les dernières réalisation de Geoff BUNZA...

https://forum.mrhmag.com/post/sma47-wild1-wireless-onboard-for-dc-and-dcc-locos-and-devices-from-any-browser-12570559?pid=1334570851

Conceptuel! Et sur une base "frenchie"! Cocorico!!

Base ESP32 TINY PICO. Chapeau l'artiste!

Une mine d'inspiration.

Il va falloir que je me penche sur les ESP32 car je n'y ai pas consacré de temps jusqu'ici.
J'avais déjà dessiné ce qui était "utile" pour intégrer le RP2040 comme alternative mais une customisation vers de l'ESP32 embarqué m'ouvre quelques idées et perspectives :)

Laurent





laurentr

  • Hero Member
  • *****
  • Messages: 648
    • Voir le profil
Re : PWM Bit Banging ISR
« Réponse #3 le: novembre 09, 2023, 02:32:23 pm »
Bonjour

Pour ceux qui apprecieraient en savoir plus sur ce sujet je vasi apporter quelques elements de reponse pour avoir conduit une version de projet en ce sens.

Je me suis appuyé pour cela sur la librairie SLOW_PWM pour AVR0 ou celle pour AVR Dx.

lien megaAVR_slow_PWM:
https://github.com/khoih-prog/megaAVR_Slow_PWM

lien Dx SLOW PWM:
https://github.com/khoih-prog/Dx_Slow_PWM

J obtiens de fabuleux effets customisable à souhait qui se réalisent via une ISR sur le TIMER B sélectionné.

Oui! Cool? en fait pas tt à fait! Pourquoi??

Explication, l idée est d associer ces éléments comme "esclave" d un code principal pour appliquer les changements d état! Idée brillante sauf que...
une ISR a pour but d interrompe la boucle principale qui elle gère le décodage DCC et l'attribution des états selon les instructions DCC retenues.
On réalise donc des ISR avec des traitements brefs.
A notre quel IRS réalise ici le niveau PWM ( dutycycle), et la requence.

Du coup quand on combine le tout… Décodage DCC et effets lumineux sous ISR  ca ne tourne pas comme attendu.

Je pensais " naïvement" résoudre le cas en plaçant le décodage DCC avec un niveau de priorité d ISR supérieur.
Ca ne résout pas le problème car dans ce cas on passe de l ISR de transcodage du DCC en instructions aux ISR générant les effet lumineux et donc la trame initiale du code ne s applique pas.

Je n y suis toutefois pas parvenu.

CQFD c est en l état une impasse technique ( au moins sur AVR)

J en reviens donc a une solution sous base de BIT BANGING général plus simple à réaliser

Maintenant à voir comment porter ce BIT BANGING sur un timer dédié sera peut être le compromis idéal.

Laurent