[Aide] MAXIM max7219CGN

Bonjour à tous, Comme indiquer dans le titre j’ai commander la puce qui porte le nom de se topic (MAXIM max7219CGN),
Je l’ai donc reçu aujourd’hui !
étant la premier puce autre que l’Arduino que j’utilise j’aimerais profiter de l’expérience du forum pour l’utiliser,
je me suis procuré cet puce pour l’utiliser avec une matrice led 8x8 red en évidant le phénomène IEM,
je me suis procuré le datasheet (http://www.hatokuro.comuf.com/datasheet.pdf) de la puce et je l’ai lu et relu et étant mon premier datasheet j’ai beaucoup de mal à savoir de manière précise se que l’on me demande de faire,

j’ai brancher correctement ma matrice led au bon pin de la puce (ce fus relativement facile a comprendre),
par contre niveau programmation je bloque un peu, je vais donc écrire se que j’ai compris,
J’ai compris que le protocole utiliser pour communiquer de l’Arduino uno a la puce étais le protocole spi j’ai donc inclu la libraire spi fournie avec l’ide de l’Arduino,
En fouillent bien sur le net j’ai pu trouver une libraire qui permet d’utiliser la puce http://www.idreammicro.com/post/Arduino-Uno-MAX7219(mais il est hors de question de me faciliter le travaille donc je m’inspire juste du code) sa ma permis de trouver facilement les paramètres d’initiation du spi par contre il faut envoyer une adresse et une valeur et la je bloque car je ne suis pas certain a 100% de se que je doit envoyer,

je vais vous mettre le code que j’ai actuellement pour pouvoir m’aider plus facilement,

#include <SPI.h>

byte address;
byte value;
void setup()
{
delay(1);
SPI.begin();
SPI.setBitOrder(MSBFIRST);
SPI.setDataMode(SPI_MODE0);
SPI.setClockDivider(SPI_CLOCK_DIV4);
SPI.transfer(address); //???
SPI.transfer(value); //???
}
void loop()
{

}

Salut,

En effet la communication avec un MAX7219 se fait en deux temps : 1- envoi de l'adresse du registre dans lequel on souhaite écrire ; 2- envoi de la valeur à écrire dans le registre.

L'adresse que tu dois envoyer est celle du registre du MAX7219 dans lequel tu souhaites écrire. Ces adresses sont données par la documentation technique du composant et vont de 0x00 à 0x0F. Par exemple le registre 0x01 contient la valeur du digit n°1.

Ensuite tu envoies la valeur à écrire dans le registre.

PS : je suis l'auteur de la bibliothèque que tu cites, si tu as des questions n'hésite pas...

++

Bonjour, J'utilise le MAX7219 avec la Librairie LedControl: http://www.arduino.cc/playground/Main/LedControl pour piloter une matrice de 8x8. C'est extrêmement simple à utiliser.

Je me suis même amusé à faire scroller un texte avec :grin: : http://breizhmakers.over-blog.com/article-un-peu-d-animation-ou-le-scrolling-a-base-de-max7219-105669349.html

patg_:

Je regarderais a sa en dernier recoure, merci .

SesechXP:

Beau travail pour la librairie, ton commentaire ma aider a mieux comprendre tout c'est tableaux, un petit morceau de code m'orrais d’autan plus aider,

Imaginons que je mettre du courent au pin du digit 7 je doit donc faire ceci ?

SPI.transfer(0x08); //digit 7
SPI.transfer(0x01); //Normal Operation

si je me trompe signale le moi.

Merci lacolombenoir ;)

Tout à fait, avec ces deux lignes de code tu vas allumer, sur le digit 7, la led connectée sur la sortie SEG_G du MAX7219. Avant d'écrire la bibliothèque j'avais décortiqué le fonctionnement du MAX7219 dans cet article.

++

Dans les tableaux avec les registres du datasheet, je vois l'adresse des DIG mais pas des SEG, car vu que j'utilise une matrice led pour pouvoir allumer un point préci il faut que je mette du courent a un dig (axe x) et que le seg (axe y) que serve de gnd pour faire fonctionner la led (je sais pas si se que je dit est claire car pour l'instant je n'ai pas réussi à allumer de led dans ma matrice)?

Puisque tu as une matrice de LEDs, le tableau qui t’intéresse dans la datasheet est le tableau n°6 qui se trouve page 8. La valeur des bits D0 à D7 déterminera les LEDs allumées ou éteintes.

Peux-tu poster ton schéma de câblage ?

je vais faire un état du câblage via fritzing.

C'est un peu fais a la va vite j’espère juste que sa pique pas les yeux.

Sinon pour le tableau 6 l'adresse des segment sont des lettres,comment les transférés correctement via la fonction SPI.transfer('A'); //??? car je n'ai encore obtenu aucun résultat je commence a me poser des questions sur si ma puce fonctionne.

Halenuya j’ai su faire fonctionner le Display Test (le résultat est si beau =( ) reste plus qu’a contrôler manuellement l’ensemble des led

#include <SPI.h>

int cs = 10;
byte address;
byte value;
void setup()
{
pinMode(cs,OUTPUT);
delay(1);
SPI.begin();
SPI.setBitOrder(MSBFIRST);
SPI.setDataMode(SPI_MODE0);
SPI.setClockDivider(SPI_CLOCK_DIV4);


}
void loop()
{
digitalWrite(cs,LOW);
SPI.transfer(0x0F); 
SPI.transfer(0x01);
digitalWrite(cs,HIGH);
}

Bonjour Pour l’instant j’arrive uniquement a utiliser le mode display test,
Je n’arrive pas a faire s’allumer une led en particulier sur ma matrice,
si l’on pouvais m’aider à complété mon code sa serais gentil,

#include <SPI.h>

int cs = 10;
byte address;
byte value;
void setup()
{
pinMode(cs,OUTPUT);
delay(1);
SPI.begin();
SPI.setBitOrder(MSBFIRST);
SPI.setDataMode(SPI_MODE0);
SPI.setClockDivider(SPI_CLOCK_DIV4);


}
void loop()
{
digitalWrite(cs,LOW);
SPI.transfer(0x01);
SPI.transfer(0x01);
digitalWrite(cs,HIGH);
digitalWrite(cs,LOW);
SPI.transfer(adress); // segment A ???
SPI.transfer(value);  // valeur
digitalWrite(cs,HIGH);
}

J’ai lu le tableau 6 pour connaitre les adresses des segments, mais je n’arrive pas a obtenir de résultat donc je ne suis pas certain de la façon de les envoyer ?

Tu oublies de configurer le MAX7219 au démarrage... Comme l'indique la datasheet, il est dans son état initial :

Initial Power-Up On initial power-up, all control registers are reset, the display is blanked, and the MAX7219/MAX7221 enter shutdown mode. Program the display driver prior to display use. Otherwise, it will initially be set to scan one digit, it will not decode data in the data registers, and the intensity register will be set to its minimum value.

Il faut donc : - configurer le nombre de digits ; - régler la luminosité ; - allumer l'affichage ; - envoyer les valeurs des digits pour allumer les LEDs.

Je maitrise très mal l’anglais donc sa ma échapper j’ai donc suivi ton conseille et voici le code que j’ai obtenu

#include <SPI.h>

int cs = 10;
byte address;
byte value;
void setup()
{
pinMode(cs,OUTPUT);
delay(1);
SPI.begin();
SPI.setBitOrder(MSBFIRST);
SPI.setDataMode(SPI_MODE0);
SPI.setClockDivider(SPI_CLOCK_DIV4);

}
void loop()
{
initiation();
digitalWrite(cs,LOW);
SPI.transfer(0x01);
SPI.transfer(0x01);
digitalWrite(cs,HIGH);

}

void initiation()
{
digitalWrite(cs,LOW);//scan limite 0 a 7
SPI.transfer(0x0B);
SPI.transfer(0x07);
digitalWrite(cs,HIGH);
digitalWrite(cs,LOW);//intensity 27/32
SPI.transfer(0x0A);
SPI.transfer(0x0D);
digitalWrite(cs,HIGH);
digitalWrite(cs,LOW);//shutdown 1
SPI.transfer(0x0C);
SPI.transfer(0x01);
digitalWrite(cs,HIGH);
}

J’ai donc écrit une fonction initiation qui me permet d’allumer des led, par contre ce qui s’affiche est totalement aléatoire esse parce-que je doit crée une boucle qui remets a zéro chaque l’adresse des digits et des segments, ou alors j’ai encore oublier quelque chose d’important ?

L'initialisation n'a besoin d'être effectuée qu'une seule fois. Il faut que tu mettes l'appel de la fonction d'initialisation dans la fonction setup et non loop.

Quand je met ma fonction initiation dans setup plus aucune led ne s'allume.

J'ai repris ton code, avec l'initialisation dans le setup comme je te l'ai indiqué et ça fonctionne. Par contre il me faut parfois faire plusieurs reset.

Je vient décrire ce code qui me permet d’initialiser le registre de l’état des digits et segments, par contre j’ai tenter d’initialiser uniquement dans le setup et rien a faire sa veut pas fonctionner, le résultat de se code me permet d’afficher exactement le point que je veut.

#include <SPI.h>

#define MODE_O 0x00
#define MODE_I 0x01
const byte digit[8] = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};
const byte seg[8] = {'DP','A','B','C','D','E','F','G'};

const int cs = 10;
byte address;
byte value;
int i=0, j=0;
void setup()
{
pinMode(cs,OUTPUT);
delay(1);
SPI.begin();
SPI.setBitOrder(MSBFIRST);
SPI.setDataMode(SPI_MODE0);
SPI.setClockDivider(SPI_CLOCK_DIV4);
initiation();
matrice_init();
}
void loop()
{
initiation();
  digitalWrite(cs,LOW);
  SPI.transfer(seg[1]);
  SPI.transfer(MODE_O);
  digitalWrite(cs,HIGH);
  digitalWrite(cs,LOW);
  SPI.transfer(digit[1]);
  SPI.transfer(MODE_I);
  digitalWrite(cs,HIGH);


}

void initiation()
{
digitalWrite(cs,LOW);//shutdown 1
SPI.transfer(0x0C);
SPI.transfer(0x01);
digitalWrite(cs,HIGH);
digitalWrite(cs,LOW);//scan limite 0 a 7
SPI.transfer(0x0B);
SPI.transfer(0x07);
digitalWrite(cs,HIGH);
digitalWrite(cs,LOW);//intensity 27/32
SPI.transfer(0x0A);
SPI.transfer(0x00);
digitalWrite(cs,HIGH);
}

void matrice_init()
{
 for(i=0;i<8;i++)
 {
  digitalWrite(cs,LOW);
  SPI.transfer(seg[i]);
  SPI.transfer(MODE_O);
  digitalWrite(cs,HIGH);
  for(j=0;j<8;j++)
  {
  digitalWrite(cs,LOW);
  SPI.transfer(digit[j]);
  SPI.transfer(MODE_O);
  digitalWrite(cs,HIGH);
  }
 }
}

PS: apparemment il y a un petit problème au niveau du seg qui n’a pas l’ère de contenir les bonne adresse par contre dig fonctionne correctement.

Après quelque teste j’ai pu comprendre que apparemment je suis bloquer sur la partie digit donc vertical de la 6 ème ranger horizontal, pas moyen de modifier autre chose que les digits,
Pourtant je suis en mode non décode donc je devrais techniquement pouvoirs modifier les segments,
voici mon code si quelqu’un pouvais m’indiquer d’où vient le problème sa m’aiderais,

#include <SPI.h>

#define MODE_O 0x00
#define MODE_I 0x01
const byte digit[8] = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};
const byte seg[8] = {'DP','A','B','C','D','E','F','G'};

const int cs = 10;
byte address;
byte value;
int i=0, j=0;
void setup()
{
pinMode(cs,OUTPUT);
delay(1);
SPI.begin();
SPI.setBitOrder(MSBFIRST);
SPI.setDataMode(SPI_MODE0);
SPI.setClockDivider(SPI_CLOCK_DIV4);
initiation();
matrice_init();
}
void loop()
{
initiation();
digitalWrite(cs,LOW);
SPI.transfer(digit[3]);
SPI.transfer(MODE_I);
digitalWrite(cs,HIGH);

digitalWrite(cs,LOW);
SPI.transfer(0x41); //A en valeur exadecimal  si jenvois la valeur 0x01 il alumera le digit alord que théoriquement ladresse doit alumer le segments
SPI.transfer(MODE_O);
digitalWrite(cs,HIGH);

}

void initiation()
{
digitalWrite(cs,LOW);//shutdown 1
SPI.transfer(0x0C);
SPI.transfer(0x01);
digitalWrite(cs,HIGH);
digitalWrite(cs,LOW);//scan limite 0 a 7
SPI.transfer(0x0B);
SPI.transfer(0x07);
digitalWrite(cs,HIGH);
digitalWrite(cs,LOW);//intensity 27/32
SPI.transfer(0x0A);
SPI.transfer(0x0F);
digitalWrite(cs,HIGH);
digitalWrite(cs,LOW);//no decode
SPI.transfer(0x09);
SPI.transfer(0x00);
digitalWrite(cs,HIGH);
}

void matrice_init() // fonction doit servire tecniquement a initialiser toute la matric mais vu mon probleme il initalise uniquement les digit
{
 for(i=0;i<8;i++)
 {
  digitalWrite(cs,LOW);
  SPI.transfer(seg[i]);
  SPI.transfer(MODE_O);
  digitalWrite(cs,HIGH);
  for(j=0;j<8;j++)
  {
  digitalWrite(cs,LOW);
  SPI.transfer(digit[j]);
  SPI.transfer(MODE_O);
  digitalWrite(cs,HIGH);
  }
 }
}

Salut,

Pour commencer, es-tu capable d'allumer une LED en particulier ? A mon sens c'est un impératif avant d'écrire un programme plus conséquent tel que le dernier que tu as posté. Plus c'est complexe, plus c'est difficile à déboguer...

Ensuite je vois des choses pas claires :

digitalWrite(cs,LOW);
SPI.transfer(0x41); //A en valeur exadecimal  si jenvois la valeur 0x01 il alumera le digit alord que théoriquement ladresse doit alumer le segments
SPI.transfer(MODE_O);
digitalWrite(cs,HIGH);

Il n'y a pas de registre à l'adresse 0x41. Même si le MAX7219 va tout de même comprendre qu'il s'agit du digit 0. Pour rappel le premier octet passé est toujours l'adresse d'un registre. Ici tu mets à 0 tous les segments du digit 0. Un segment n'a pas de registre, mais un bit dans le registre d'un digit.

Aussi tu appelles toujours ta fonction "initiation" dans la fonction loop... Peut-être que ça te permet de contourner un problème et de le masquer mais ça ne le résout pas.

Concernant ta fonction "matrice_init", ta seconde boucle d'initialisation des segments est inutile. Ecrire la valeur 0x00 dans chaque digit est suffisante et met les 8 segments à 0 en une seule fois...