Problème de Changement de pin avec arduino

Bonjour, je travaille sur un projet qui consiste à contrôler des rubans de leds rgb via éthernet sur des armoires électriques, j’utilise comme leds rgb le WS2811. Pour ce projet plusieurs rubans sont branchés sur les pins de l’arduino et j’aimerai quitter d’un pin à un autre piloter les leds indépendamment via une interface graphique. J’utilisé la librairie Adafruit_Neopixel mais je rencontre un problème quand j’éssaie de changer de ports pour un autre la carte garde en mémoire l’état des leds du ruban précédent et l’attribue au nouveau port donc si les 3 premieres leds du ruban sur le port 6 était toutes en rouge, et sur le port 7 si je veux mettre les 3 second leds du ruban en vert, il me met d’abord les 3 premiers en rouge et maintenant les 3 second en vert. Je n’arrive pas à savoir où est le problème.

true_m.ino (45.1 KB)

Bonjour,

Et si tu déclares strip sur la pin 6 et strip1 sur la pin 7 (comme tu avais commencé à faire), ça ne te convient pas ?

clarvie: Bonjour, je travaille sur un projet qui consiste à contrôler des rubans de leds rgb via éthernet sur des armoires électriques, j'utilise comme leds rgb le WS2811. Pour ce projet plusieurs rubans sont branchés sur les pins de l'arduino et j'aimerai quitter d'un pin à un autre piloter les leds indépendamment via une interface graphique. J'utilisé la librairie Adafruit_Neopixel mais je rencontre un problème quand j'éssaie de changer de ports pour un autre la carte garde en mémoire l'état des leds du ruban précédent et l'attribue au nouveau port donc si les 3 premieres leds du ruban sur le port 6 était toutes en rouge, et sur le port 7 si je veux mettre les 3 second leds du ruban en vert, il me met d'abord les 3 premiers en rouge et maintenant les 3 second en vert. Je n'arrive pas à savoir où est le problème.

bonsoir Je ne comprend pas bien ce que tu cherche à faire, tu cherche à commander le meme ruban par 2 pins differents ou tu a 2 rubans que tu souhaiterait commander alternativement par 2 pins differents ? les rubans de neopixels sont géré en cascade de 1 à n , le rafraichissement se fait à frequence definie par le parametre NEO_KHZxxx (xxx=400 ou 800). toutes les leds doivent etre adréssées individuellement en partant de la N° 1 jusqu'à la N° n.

Artouste----->Je souhaite piloter alternativement les 2 rubans par 2 pins différents. J'ai une fonction qui allume les leds selon les caractères reçues et elle va être appeler à chaque fois sur chaque ruban pour les allumer. Je ne voulais pas créer pour chaque ruban un objet Adafruit_Neo donc j'en ai crée qu'un et tout ce que je veux faire c'est que quand je demande un changement de pin il ne doit pas me garder l'ancien état des leds sur le ruban 1 par exemple vu que c'est le même objet.

clarvie:

Je ne voulais pas créer pour chaque ruban un objet Adafruit_Neo

Pourquoi?
Si tu as deux objets le plus logique est de créer deux instances

Vu que le but est de piloter 20 rubans sur des armoires et sachant que je pilote la couleur de chaque led indépendamment cela me fera beaucoup de code pour 20 objets et je ne pense pas que le carte arduino Mega que j'utilise aura assez d'espace. Si tu as une solution à me proposer je serai ravi de le savoir :)

Multiplexeur Registre à décalage Expenseur I2c etc

clarvie: Vu que le but est de piloter 20 rubans sur des armoires et sachant que je pilote la couleur de chaque led indépendamment cela me fera beaucoup de code pour 20 objets et je ne pense pas que le carte arduino Mega que j'utilise aura assez d'espace. Si tu as une solution à me proposer je serai ravi de le savoir :)

Si tu crées 20 objets ça n'utilisera pas un seul octet de code supplémentaire. Par contre effectivement ça utilisera de la mémoire RAM pour chaque objet. D'après le compilateur ça prend 21 octet par objet.

Je persiste à penser (et je suis en plein accord avec moi même :) ) que en C++ pour gérer plusieurs objets physiques le plus simple est de créer plusieurs objets logiques (instances de classe)

clarvie: Vu que le but est de piloter 20 rubans sur des armoires et sachant que je pilote la couleur de chaque led indépendamment cela me fera beaucoup de code pour 20 objets et je ne pense pas que le carte arduino Mega que j'utilise aura assez d'espace. Si tu as une solution à me proposer je serai ravi de le savoir :)

bonjour pour resumer : tu veux gerer 20 rubans de 60 leds , chacun des rubans etant piloté par un pin distinct d'arduino ?

Oui c'est exactement ça, 20 rubans de 60 leds pilotés chacun par un pin distinct de l'arduino.

clarvie: Oui c'est exactement ça, 20 rubans de 60 leds pilotés chacun par un pin distinct de l'arduino.

ok Alors je crois comprendre d'où vient ton probleme si j'ai bien compris tu selectionne le ruban que tu veux adresser par un strip.setPin(); et la matrice du ruban est envoyé par un strip.show() si tu ne modifie la couleur que d'une (2 ou 3) led toutes les autres conservent la valeur precedente affectée à leur n° d'ordre dans le ruban et lors du strip.show tu te retrouve bien avec les leds que tu vient de modifier , mais aussi l'etat precedent de toutes les autres, qui peuvent venir de ce que tu a injecter sur le precedent ruban pour des led de meme n° d'ordre.

De plus une chose m'etonne , mais je n'ai pas de quoi verifier là sous la main lorsque tu passe d'un ruban à un autre par simple changement de pin , ton ruban precedent reste allumé avec son dernier etat ? il me semblait que les ws2812 se positionne en OFF si il n'y a pas d'activité sur le pin data au bout de x ms ?

Je pense qu'il faut que tu passe par la solution d'instances ou que tu gere à la mano un tableau de couleur par led soit 1200 postes mais dans un cas comme dans un autre il faut de la ram avec 24 bits par led (3 bytes) soit 3600 bytes.

Je suis d'accord avec toi Artouste. Il faut N instances de la classe Adafruit_NeoPixel (comme je le suggère depuis le début).

J'ai jeté un rapide coup d'oeil à la librairie Adafruit_Neopixel et cette classe mémorise l'état de toutes les leds. Ce qui explique que l'on affiche l'état de l'autre ruban quand on change de pin.

Effectivement et contrairement à ce que j'avais dit plus haut il faut beaucoup de ram (mais je ne vois pas le moyen de faire autrement).

kamill: Je suis d'accord avec toi Artouste. Il faut N instances de la classe Adafruit_NeoPixel (comme je le suggère depuis le début).

J'ai jeté un rapide coup d'oeil à la librairie Adafruit_Neopixel et cette classe mémorise l'état de toutes les leds. Ce qui explique que l'on affiche l'état de l'autre ruban quand on change de pin.

Effectivement et contrairement à ce que j'avais dit plus haut il faut beaucoup de ram (mais je ne vois pas le moyen de faire autrement).

pas beaucoup de solutions sauf si les rubans conservent leurs etats apres suppression de l'activité sur le pin data (mais perso de memoire j'y crois moyen) mais si c'est le cas , il "suffirait" juste lors d'un changement concernant un ruban de reacquerir/reformer les 60 valeurs de couleurs avant de le transferer au ruban qui garderait l'info. Je vais sonner Icare , qui a une tres bonne connaissance de ces bestioles :grin:

Bonjour, Voila un sujet intéressant ;) Le pilotage des WS2812 nécessite un timing relativement précis pour fonctionner, ce pilotage est assuré par la bibliothèque Adafruit. Le rafraichissement des diodes leds est également assuré par cette librairie. Pour commander plusieurs rubans leds, il faut une instance par rubans ou si tu préfères par pin data.

Les WS2812/B fonctionnent sur 1 seul file un peu comme les composants 1Wire de Dallas. Il faut générer un train série rapide à 800kbits/sec. C'est la forme du signal qui détermine s'il s'agit d'un 0 ou d'un 1 :

  ___
_|   |_______| pour un 0
ou
  _______
_|       |___| pour un 1

Sinon le principe de la lib c'est de créer un objet du type Adafruit_NeoPixel Dans la création de l'objet tu passes le nombre de leds de ta série, le numéro de la pin à laquelle est reliée la série de led, et des flags qui indiquent la vitesse Ensuite tu as des fonctions comme strip.setPixelColor( led, red, gree, blue ) pour régler la couleur d'un pixel ou bien strip.setPixelColor( led, color ) pour utiliser la forme compact ou color est un uint32_t qui contient les 3 octets (0x00RRGGBB) D'autres fonctions pour relire la valeur d'un pixel, etc ....

Ces fonctions ne font que mettre à jour en mémoire la valeur RGB du pixel

Ensuite il faut appeler strip.show() pour que la lib envoi le train série de configuration à la série de led. A 800khz, 24 bits par pixel, il faut 30µs par pixel.

Attention: 1200 leds (20x60) à 3 octets (RGB) par led ca fait 3,5KO. Un Atmega328 n'a que 2KO....

Note que bien qu'il faille NN ms pour envoyer les données à tous les pixels, le changement d'état est simultané sur tous les pixels dès que la liaison série ne change plus d'état pour 50µs. Donc pas d'effet de propagation des valeurs le long du bandeau

Par contre, tu rencontreras rapidement des problèmes de fonctionnement car la RAM disponible n'est plus suffisante pour commander toutes ces petites merveilles de led. Mais avec certitude, je peux te dire que tu n'arriveras pas à commander 20 rubans de 60 leds avec une carte Arduino UNO @+

icare: Bonjour, Voila un sujet intéressant ;) ... Note que bien qu'il faille NN ms pour envoyer les données à tous les pixels, le changement d'état est simultané sur tous les pixels dès que la liaison série ne change plus d'état pour 50µs. Donc pas d'effet de propagation des valeurs le long du bandeau

Bonsoir Icare N'est il pas ! :grin: Ma vraie question est : lorsqu'il n'y a plus d'activité sur la ligne de commande , le bandeau toujours alimenté reste en l'etat suivant le dernier strip.show() reçu ou le bandeau (toutes les led le composant) passent en "OFF" ?

Bonsoir Artouste, Oui, tant que la tension est présente la led reste allumée dans son état jusqu'à la prochaine programmation.

Icare Intéressant ce que tu dis

quand je fais un changement de pin par exemple, Je peux allumer les leds que je veux mais en plus de ça il m'allume aussi les leds qui étaient allumées sur le premier pin. Quand je quitte d'un pin à un autre, les bandeaux gardent leurs états c'est à dire si j'avais allumé 2 leds en rouge et que je change de pin pour contrôler un autre ruban, ces 2 leds reste toujours allumées

Bonjour, Je ne comprends pas bien ton problème. Il faut mettre ton code pour que je puisse faire un test. @+

icare:
Bonsoir Artouste,
Oui, tant que la tension est présente la led reste allumée dans son état jusqu’à la prochaine programmation.

Bonsoir Icare
J’ai recupéré une WS2812 (c’est pas beaucoup pour un ruban, mais suffisant pour une manip :grin: ) et je ne constate pas du tout le comportement “memoire”
avec le petit prog dessous
le pin 4 est selectionné pendant 5 secondes et affiche une couleur verte = pas de probleme
au bout de 5 secondes je passe en commande sur le pin5 avec un changement de couleur

  • normalement selon toi , je devrais conserver ma led allumée en vert tant que le data de la led ne reçoit pas d’autres infos ?

constat :
au bout de 5 secondes (swap entre 4 et 5) ma led est mise en OFF
et si je deplace le data en 5 j’ai bien ma nouvelle couleur (assez logique)

Je m…e où pour conserver la led avec sa memoire de couleur ?

#include <Adafruit_NeoPixel.h>
int p = 4;
int r = 0;
int  v = 255;
int  b = 0;
Adafruit_NeoPixel strip = Adafruit_NeoPixel(1, p, NEO_GRB + NEO_KHZ800);
unsigned long tact;
void setup() {

  strip.setPin(p);
   strip.show();
  tact = millis();

}

void loop() {
  strip.setPin(p);




  strip.setPixelColor(0, r, v, b); // N° led RVB 0--->x

  strip.show();

  if (millis() - tact > 5000) {
    p = 5;
    r = 255;
    v = 50;
    b = 100;
  }

}

Bonsoir Artouste, Le comportement que tu décris ne me surprend pas. Pour 2 rubans à 1 diode (;)), il faut 2 instances

int p1 = 4;
int p2 = 5;
Adafruit_NeoPixel strip1 = Adafruit_NeoPixel(1, p1, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip2 = Adafruit_NeoPixel(1, p2, NEO_GRB + NEO_KHZ800);

pour que cela fonctionne. Il faut que je me replonge dans la lib car il existe une routine de rafraichissement pour maintenir l'état de couleur des leds (un peu comme dans les anciennes RAM dynamiques). @+