En fait lors de la création de
cette classe qui permet de faire fonctionner le nRF24L01+, je me suis fixé plusieurs contraintes:
- N'utiliser que les broches spi (SS, MOSI, MISO, SCK) comme les autres périphériques en spi que j'ai l'habitude de programmer (pour rester cohérent).
- N'utiliser que du spi hardware (comme le reste de la bibliothèque).
- Le nRF24L01+ sera en mode réception tout le temps, sauf au moment d'envoyer une info.
- Tout le monde discute sur le même pipeline (pipe 0) (donc théoriquement (même si c'est pas vrai) pas de limite en nombre de nrf possibles), seul un tri est fait à l'arrivée pour distinguer qui s'adresse à qui.
C'est une façon de faire dont j'ai pris la décision pour que au niveau de la couche au dessus (l'utilisateur qui programme avec ma classe) cela soit très facile, et qu'il y ait toujours d'une façon transparente l'idée de toile (réseau de nrf) sans poser aucun soucis malgré que je n'utilise qu'un pipeline, et sans irq.
J'avais fini de programmer cette classe, j'essaye donc de tester à peu prêt tout ce qu'il est possible à ma portée pour voir la robustesse du code, montages loufoques (10ène de ping pong avant d'afficher une info sur un écran), communication sans antenne à travers des murs en béton, etc...
Lorsque j'ai souhaité tester une symétrique parfaite, 2 montages identiques avec le même programme mis sous tension simultanément; Comme quoi les cadences des microcontrôleurs et différents systèmes embarqués sont précises; la communication est alors devenue bien saccadée, voir impossible certains instants (les 2 (ou plus) nrf se retrouvant simultanément en réception ou en transmission).
J'ai essayé pas mal d'idées qui me sont venues en faisant des tests, l'accusé de réception notamment avec le registre 01 (auto acknowledgement), ou encore le nombre de retry lorsque le récepteur ne répond pas, mais aucun d'eux n'a fonctionné... sauf un: le registre 07 (STATUS) d'une grande aide.
Grâce au bit 6 (RX_DR) de ce registre:
Data Ready RX FIFO interrupt. Asserted when new data arrives RX FIFO cDonc, quand l'utilisateur décides dans son code de transmettre une information avec le nrf, la fonction fait d'abord une lecture de ce registre et de ce bit avant d'engager les blocs de code relatifs à la transmission.
//lecture du registre STATUS
if (//si le bit 6 est à 0)
{
//attendre 1 milliseconde
}
Cette attente (arbitraire) permet lorsque 2 montages sont à leur allumage parfaitement (avec une certaine tolérance je vous l'accorde) synchronisés, de les désynchroniser. Si besoin ce code reste la tout au long de l'utilisation, et donc même si on imagine qu'une resynchronisation qu'elle qu'elle soit referait surface (à 2 ou plus nrf), cette petite logique d'attente s'activerait et redésynchronisait les montages.
Cette attente peut être difficile à comprendre car elle est effective sur les 2 montages (ou plus) en symétrie, mais via la lecture du registre, elle vient en fait chercher (la petite bête) des chouillemes temporels pour créer une plus grosse différence d'1 millisecondes entre les montages. On peux dire que quelques micro ou nanosecondes se retrouvent (si besoin) affublés d'1 milliseconde pour créer de façon significative une différence (ou décalage) quelque part.
C'est pas compliqué du tout mais ça fonctionne super.
Encore une fois ceci n'est effectif que si besoin (lors du démarrage des montages la plupart du temps), le reste du temps ce petit bout de code est bypassé naturellement, et je dois vous avouer que c'est la seule et unique fois ou j'ai dû dans la programmation (de ma bibliothèque) rajouter un temps arbitraire qui ne soit pas clairement mentionné dans un datasheet de composant électronique...