Problème matriçage LED

Bonjour,

Je me permet de venir vers vous car je rencontre un petit soucis.

Je récupère un buffer en hexadécimal des leds que je souhaite allumer via le protocole UDP.

Les leds fonctionnent bien comme il faut mais j’ai toujours une led de la deuxième ligne au même bit que la première ligne de mon tableau qui s’allume légèrement et même si je dis de ne pas s’allumer :

#define MAX_NUMBER_OF_LINES 8
uint8_t ledPreview2ME[MAX_NUMBER_OF_LINES]; // N lignes, un bit par ligne

J’ai fait le test de parcourir qu’une ligne de mon tableau, et la led en question ne s’allume pas, donc je considère que ce n’est pas une fuite de courant de mes sorties numériques.

Voici le code complet en question :

#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>


byte arduinoMac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress arduinoIP(192, 168, 1, 178); // desired IP for Arduino
unsigned int arduinoPort = 8888;      // port of Arduino

IPAddress receiverIP(192, 168, 1, 22); // IP of udp packets receiver
unsigned int receiverPort = 8080;      // port to listen on my PC

EthernetUDP _Udp;

uint8_t _packetBuffer[96];
int touches[8][8];

#define MAX_NUMBER_OF_LINES 8
uint8_t ledPreview2ME[MAX_NUMBER_OF_LINES]; // N lignes, un bit par ligne
uint8_t ledColor[MAX_NUMBER_OF_LINES]; // couleurs

uint8_t ports[8] = {B00000000, B00000001, B00000010, B00000011, B00000100, B00000101, B00000110, B00000111};

void setup() {
  Ethernet.begin(arduinoMac, arduinoIP);
  _Udp.begin(arduinoPort);

  // 1 == outputs, 0 == input
  DDRF = B00000000;  // Code binaire des lignes TMP IC11
  DDRC = B00000111; // Code binaire des colonnes TMP IC11
  DDRA = B11111111;
  pinMode(41, OUTPUT);
  reset();
}

void lecture() {
  digitalWrite(41, LOW);
  for (int t = 0; t < 8; t++) {
    PORTC = ports[t];
    delayMicroseconds(50);
    for (int i = 0; i < 8; i++) {
      touches[t][i] = bitRead(PINF, i);
    }
  }
  if (PINF != 0) {
    for (int col = 0; col < 8; col++) {
      for (int ligne = 0; ligne < 8; ligne++)
      {
        if (touches[col][ligne] == 0) {
          envoiUDPServer(3, col, ligne);
        }
      }
    }
  } else {
    //Serial.println("no connect");
  }
}

void envoiUDPServer(int tmp, int col, int ligne) {
  _Udp.beginPacket(receiverIP, receiverPort); //start udp packet
  _Udp.print(tmp);
  _Udp.print(col);
  _Udp.print(ligne);
  _Udp.endPacket();
}

void loop() {
  lecture();
  delay(1);
  ecriture();
}

void ecriture(){

  int packetSize = _Udp.parsePacket();
  if (packetSize)
  {
    _Udp.read(_packetBuffer, UDP_TX_PACKET_MAX_SIZE);

    uint8_t cmd = _packetBuffer[0];

    if (cmd == "test")
    {
      // on change la config des lignes
      for (int i = 0; i < MAX_NUMBER_OF_LINES; i++)
      {
        ports[i] = _packetBuffer[1 + i];
      }
    }
    else
    {
      // sinon ce n'est pas une config mais un ordre d'allumage
      uint8_t line = _packetBuffer[0];
   
      for (int i = 0; i < MAX_NUMBER_OF_LINES; i++)
      {
        ledPreview2ME[i] = _packetBuffer[0 + (2 * i)];
        ledColor[i] = _packetBuffer[1 + (2 * i)];
      }
    }
  }
  /// fin UDP wait
  for (int i = 0; i < 8; i++)
  {
    PORTC = ports[i];
    leds(ledPreview2ME[i], ledColor[i]);
    delay(1);
  }  
}
void leds(uint8_t line, uint8_t color)
{

  uint8_t l;
  digitalWrite(41, LOW); //20
  for (int i = 0; i < 8; i++)
  {
    uint8_t c = bitRead(color, i);
    digitalWrite(21, c ? HIGH : LOW);
    bitWrite(l, i, bitRead(line,i));
  }
  PORTA = l;

  delayMicroseconds(80);
  //Vérouiller les leds
  digitalWrite(41, HIGH);//20
  delayMicroseconds(500);
}

void reset()
{
  for (int i = 0; i < MAX_NUMBER_OF_LINES; i++)
  {
    ledPreview2ME[i] = 0;
  }
}

Je suis également preneur de proposition d’optimisation de code.

Merci d’avance pour vos réponses précieux.

Cordialement,

Vincent.

Elle est sur qu’elle pin celle qui brille un peu ?
Pouvez vous décrire en détail le montage, la carte, le shield ethernet, l’alimentation électrique et la puissance consommée, le type de leds, ce que vous avez en entrée, etc…

Sur cette boucle

 for (int i = 0; i < 8; i++) {
      touches[t][i] = bitRead(PINF, i);
    }

si le timing est important (vos 50 microsecondes) stockez juste PINF Dans un octet et faites le bitread au moment de l’utiliser. Vous gagnerez en mémoire et en efficacité

Je ne vois pas comment un uint8_t pourrait être égal à l’adresse d’une chaîne en mémoire

 uint8_t cmd = _packetBuffer[0];

    if (cmd == "test")

le compilateur a mon avis vous met un warning non ?

Bonjour J-M-L,

Merci de m'avoir répondu.

Je vais essayer de vous donner plus d'information. J'ai un arduino mega 2650 avec un shield ethernet Nanrun

J'ai actuellement le port C de 8bits dont seulement 4 utilisés pour le moments servant pour l'adressage des groupes:

PORTC = ports[t];

Il y a 8 adresses possible sur ce port :

uint8_t ports[8] = {B00000000, B00000001, B00000010, B00000011, B00000100, B00000101, B00000110, B00000111};

Le port C sert de lecture des boutons ainsi que l'éclairage des leds.

Par exemple, pour allumer la première led du premier groupe (une matrice de 8x8 leds avec colonnes et lignes), je dois faire ceci:

digitalWrite(41, LOW); // Déverrouiller les modifications 
PORTC = ports[0]; // envoyer l'adresse 1;
PORTA = B00000001; numéro de led du groupe (selon l'adresse)
digitalWrite(41, LOW); // Verrouiller les modifications de la led choisie

Hors je rencontre 2 soucis, le premier dont on parle actuellement, est que le même numéro de boutons de l'adresse suivant dans mon tableau ports s'allume légèrement.

Soit :

PORTC = ports[0]
PORTA = B00000001;

Alors 

PORTC = ports[1]
PORTA = B00000001; 

s’allume légèrement ou alors

 PORTC = ports[0]
PORTA = B00000010;

et

PORTC = ports[1]
PORTA = B00000010; 

également.

Ports[0] s'allume normalement et parfait. Mais ports[1] à bien B00000000 donc les leds doivent être éteints.

J'en profite également, vous me direz si je dois faire un autre sujet sur le forum.

Je ne reçois pas le message de l'UDP de temps en temps, je suppose que le message est envoyé au moment ou il est dans la fonction lecture(), y a-t'il une solution?

Merci d'avance de vos réponse en espérant avoir été clair dans mon explication.

N'hésitez pas de me demander d'autres explications si besoin;

Cordialement,

Vincent.

"avec un shield ethernet Nanrun"

Si c'est marqué "Hanrun" c'est le nom du fabricant de la prise ethernet équipée avec ses transformateurs, ce n'est pas celui de la carte.
Donnes le lien (cliquable) vers la carte que tu possèdes.

Un module de ce genre ?
ethernet.png

Les pins du Port C de l'Arduino MEGA sont décrites sur cette page

PC0-> Digital pin 37
PC1-> Digital pin 36
PC2-> Digital pin 35
PC3-> Digital pin 34
PC4-> Digital pin 33
PC5-> Digital pin 32
PC6-> Digital pin 31
PC7-> Digital pin 30

quand vous faites PORTC = ports[t];vous touchez donc toutes les pins de 30 à 37 sur votre Arduino.

Avez vous connecté quelque chose ailleurs que sur 30, 31 et 32 qui j'imagine correspondent à votre matrice ?

idem pour le port A

PA7-> Digital pin 29
PA6-> Digital pin 28
PA5-> Digital pin 27
PA4-> Digital pin 26
PA3-> Digital pin 25
PA2-> Digital pin 24
PA1-> Digital pin 23
PA0-> Digital pin 22

quand vous écrivez dans PORTA vous touchez toutes les pins de 22 à 29

Pour l'UDP, c'est un risque à courir. Le rôle de ce protocole est de permettre la transmission de données de manière très simple entre deux entités, chacune étant définie par une adresse IP et un numéro de port. Comme Il n'y a pas de mécanisme d'établissement de liaison (handshaking), ce protocole vous expose aux problèmes éventuels de fiabilité du réseau ==> il n'existe pas de garantie de protection quant à la livraison, l'ordre d'arrivée, ou la duplication éventuelle des messages

ethernet.png

Bonjour,

Je vous remercie de vos réponse.

Nous avons un shield ethernet W5100, lien en exemple : Ethernet W5100

Concernant le PORTC, nous avons pour l'instant que 30, 31 et 32 de connecter, il correspondent à des entrées d'un CMOS 3 To 8 LINE DECODER / DEMULTIPLEXEUR, un deuxième sera branché prochainement.

"quand vous écrivez dans PORTA vous touchez toutes les pins de 22 à 29"

Efectivement, c'est bien le cas.

Concernant l'UDP, y-il une solution alternative à me proposer, que sa soit sur le programme en lieu même ou la logique à mettre en place pour e^tre sur que l'information soit bien transmise au moins une fois?

Cordialement,

Vincent

Ce type de shield que vous enfichez sur votre Arduino

va utiliser certaines pins pour son alimentation, la gestion ethernet et la gestion de la SD.
êtes vous sûr qu'il n'y a pas d'incompatibilités ?

Si vous n'utilisez pas UDP vous pouvez passer par TCP, HTTP, ...

Oui, c'est bien ce type de shield que nous enfichons sur notre Arduino.

Nous n'utilisons pas les pins utiles pour ce shield.

Quel serait pour voir le meilleur choix de récupérer en ethernet nos données le plus stable possible par l'arduino, les données viennent de notre serveur nodejs en udp mais nous pouvons changer si besoin.

Après je ne suis pas sur que ceci change parce que sauf si je me trompe l'arduino perd des données en réception quand il n'est pas en train de lire la fonction "ecriture()" dans le loop sinon il le lit.

Dans l'attente.

Cordialement,

Vincent