Utilisation de pointeur pour matrice led 8x8 et MAX7219

Bonjour à tous :slight_smile:

Je travaille actuellement sur un projet qui consiste en la création du jeu SNAKE.
Pour créer ce jeu, j'ai à ma disposition les éléments suivants:

  • une arduino nano
  • un multiplexeur MAX7219
  • une matrice LED 8x8 1588BS
  • un joystick

J'ai commencé à éditer un code qui sait afficher une LED aléatoirement sur la matrice.
Je cherche dans un premier temps à faire déplacer cette LED à l'aide d'un joystick. Pour cela, j'ai compris qu'il fallait que j'utilise des pointeurs.
Malgré le visionnage de plusieurs tutoriels sur ceux-ci, je n'y arrive toujours pas :confused:

Pourriez-vous m'aider s'il vous plait??

Voici le code en question:

int DIN_pin = 11;
int CS_pin = 13;
int CLK_pin = 10;

int BP7 = 7; // Bouton-poussoir en broche 7
int axeX = A2; // signal de l'axe X sur entrée A2
int axeY = A3; // signal de l'axe Y sur entrée A3

int x = 4; //adresse serpent
int y = 4; //colonne serpent


//données des lignes du tableau 8x8
int clean[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};//création du tableau clean qui met toutes les LED à zéro
int pomme[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
int serpent[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

//----------------------------------------------------------------------------------------*/
//-----------------------COMMUNICATION AVEC MATRICE---------------------------------------*/
//----------------------------------------------------------------------------------------*/

void write_pix(int data) { //data = hexadécimal à envoyer sur une ligne
  digitalWrite(CS_pin,LOW); //car data envoyée sur front montant de CS_pin donc éteint le pin CSpendant l'envoie des bits
  for (int i=0 ; i<8 ; i++) { //boucle allant de 0 à 8 permettant d'envoyer chaque bit de l'hexadécimal
    digitalWrite(CLK_pin,LOW);
    //digitalWrite(DIN_pin,data); //permet d'envoyer les données à DIN_pin
    digitalWrite(DIN_pin, data & 0x80);//data * 1000 0000
    data = data << 1; //décalage des bits vers la gauche
    digitalWrite(CLK_pin,HIGH);//prendre bit à bit les valeurs de l'hexadécimal, permet d'allumer les LED
    Serial.println(data);
  }
}

void write_line(int address, int data){
  digitalWrite(CS_pin,LOW);//car data envoyée sur front montant de CS_pin
  write_pix(address);//sur quelle adresse(ligne)on veut entrer la donnée
  write_pix(data);//envoyer la donnée
  digitalWrite(CS_pin,HIGH);
}

void write_matrix(int *tab) { // fonction qui se sert write_line pour compléter les lignes de la matrice
  for (int i=0 ; i<8 ; i++) write_line(i+1, tab[i]); //boucle jusqu'à 8 pour remplir chaque ligne
}

//--------------------------------------------------------------------------------------*/
//--------------------------------------------------------------------------------------*/


void init_MAX7219(){ //fonction permettant d'initialiser la matrice d'après la datasheet en envoyant des nombres spéciaux en hexa sur cetaines adresses
 //write_line(0x09, 0x00); //decode mode
  write_line(0x0A, 0x01); //luminosité
  write_line(0x0B, 0x07); //scan limit
  write_line(0x0C, 0x01); //shutdown
  write_line(0x0F, 0x00); //test display
}


void setup() {
  //initialisation des pins
  pinMode(CS_pin,OUTPUT);
  pinMode(DIN_pin,OUTPUT);
  pinMode(CLK_pin,OUTPUT);
  delay(50);//attente de 50ms
  
  init_MAX7219();//initialisation de la matrice et du multiplexeur

  pinMode (BP7, INPUT); // définition de BP7 comme une entrée
  digitalWrite(BP7, HIGH); //Résistance déjà intégrée au module du joystick
  pinMode (axeX, INPUT); // définition de A2 comme une entrée
  pinMode (axeY, INPUT); // définition de A3 comme une entrée
}


//void pomme_aleatoire() {
//  int Bouton;
//  Bouton = digitalRead (BP7);
//  if (Bouton==0){
//    pomme[random(8)]= 1 << random(8);
//    write_matrix(pomme);
//    for (int i=0 ; i<8 ; i++){
//    pomme[i]=clean[i];
//    delay(30);
//  }
// }
//} 

void start_snake() {
  int Bouton;
  Bouton = digitalRead (BP7);
  if (Bouton==0){
    serpent[x]= 1 <<y;
    write_matrix(serpent);
  }
} 


void deplacer_snake(){ 
  int X, Y;
   X = analogRead (axeX);
   Y = analogRead (axeY);

//  int *pointeurSurx = &x;
//  int *pointeurSury = &y;
  
    if (X>=900){//Si joystick vers la droite
      serpent[x]=1<<y-1;
      write_matrix(serpent);
      delay(500);//temps d'affichage
    }
    
    if(Y>=900){//Si joystick vers le bas
      serpent[x+1]=1<<y;
      write_matrix(serpent);
      delay(500);//temps d'affichage
    }

    if (Y<=100){//Si joystick vers le haut
      serpent[x-1]=1<<y;
      write_matrix(serpent);
      delay(500);
    }

    if (X<=100){//Si joystick vers la gauche
      serpent[x]=1<<y+1;
      write_matrix(serpent);
      delay(500);
    }  
    for (int i=0 ; i<8 ; i++){
      serpent[i]=clean[i];
      delay(30);
    }    
}


void loop(){
  start_snake();
  deplacer_snake();
}

benenuts64:
Pour cela, j'ai compris qu'il fallait que j'utilise des pointeurs.

Déjà tu fais de l'auto blocage. Tu t'imposes la forme avant d'avoir bien compris le fond.
Tu utilises des pointeurs si tu veux, et si tu as bien compris comment ils s'utilisent. Il n'y a en général pas d'obligation.

Malgré le visionnage de plusieurs tutoriels sur ceux-ci, je n'y arrive toujours pas :confused:

Un pointeur sur une variable est l'adresse de cette variable.

Les cases mémoire de l'ordinateur, les octets, sont numérotées, de 0 à ... ça dépend de la quantité de mémoire. Quand le programme tourne, il manipule des variables.
Une variable est localisée quelque part dans la mémoire. Le programmeur n' pas besoin de savoir où, il suffit dans le programme d'utiliser le nom de la variable, et le compilateur se charge de traduire ça en adresses mémoire.

Mais des fois ça peut être utile d'avoir une variable qui elle-même contient l'adresse d'un autre variable.
(oui ça devient compliqué)
On appelle ça un pointeur, car il pointe vers une variable.

int x = 1; // une variable x
int* px; // un pointeur qui pointe forcément vers un int ( car son type est int*)
// pour le moment px n'est pas initialisé, il pointe vers ... ??? (danger)
px = &x; // faire pointer px vers la variable x, de type int (ok)
*px = 2; // modifier la valeur pointée ( donc x )
Serial.println ( x ); // doit afficher 2

Ca , ça va ? si oui dis un peu ce qui coince, alors.

Bonsoir,

Je vous remercie pour vos explications, mais j'avais déjà vu et compris l'intérêt du pointeur!
J'ai vu différents exemples notamment celui qui permet d'échanger la valeur de deux nombre A et B.

Ce que je voudrais comprendre, c'est comment l'appliquer à mes tableaux?!

appliquer ?
tu poses encore le problème à l'envers.
Enfin tu nous poses le problème à l'envers.
Tu dis "je dois utiliser des pointeurs" : pourquoi ? et aussi, pourquoi faire ?

Décris ce que tu veux faire, et non pas comment tu voudrais faire qque chose que tu ne dis pas.

Je dis "je dois" car je ne connais pas d'autres moyens car c'est tout simplement le seul qui m'a été donné par mon professeur!

Je n'arrive pas à garder en mémoire la position à l'instant t de ma led sur la matrice ce qui fait qu'elle repart systématiquement depuis sa position initiale et bouge depuis celle-ci.

Dans mon code ma led est en position initiale (4,4) et se décale à droite si je le lui demande. Mais lorsque je lui demande de se décaler vers le haut ou vers le bas ou même vers la gauche, elle repart depuis la position (4,4).

Je voudrais connaitre une astuce qui me permettrait de garder en mémoire la position à l'instant t. Et si tu as une autre solution que les pointeurs à me fournir, je suis preneuse aussi. J'apprends!!!! Donc je ne connais pas tout.

PS: Je n'essaie pas de vous poser le problème à l'envers et je ne m'auto-bloque pas non plus!

C'est ton prof qui te bloque alors !

En C, il y a une équivalence entre les pointeurs et les tableaux.

Je pense que tu comprends bien ce qu'est un tableau ?

int Tableau[4] = { 0, 1 , 2 , 3 };

Les éléments de Tableau sont des int. Mais "Tableau" c'est quoi ?
Bin c'est le nom du tableau pardi. Il te sert à accéder aux élément contenus.

for ( int i=0; i<3; i++ )
  Tableau[i] = 0;

Facile, non ?
Mais Tableau peut aussi être vu comme l'adresse du tableau en mémoire, c-à-d comme un pointeur sur le tableau.
Et d'ailleurs quel est le type de "Tableau" ? Puisqu'il pointe vers le 1er élément du tableau, qui lui-même est un int, on dit que Tableau est un int*, ce qui veut dire : pointeur vers un int.
Donc :

 int x = Tableau[0]; // 1er élément dans x
int y = *Tableau; // accéder au tableau par pointeur
// ici x = y car Tableau[0] ou *Tableau, c'est pareil

Jusque là ça n'amène pas grand chose.
Mais on peut aussi faire de l'arithmétique avec les pointeurs.

int * p = Tableau; // p pointe sut Tableau[0]
p = p+1; // avancer le pointeur d'un élement (selon le type du pointeur, ici int*)
// maintenant p pointe sur Tableau[1]

Donc la boucle de mise à zéro de Tableau montrée plus haut peut aussi s'écrire

int *p = Tableau; // pointer sur le 1er élément
for ( int i=0; i<3; i++ )
  *p++ = 0; // en un seule ligne : mettre l'entier pointé à 0, puis ajouter 1 à p, c-àd avancer à l'élément suivant du tableau.

J'espère que ça t'ouvre des perspectives. Si tu butes sur les notations du C ( int*, *variable...), y'a pas à tortiller : faut réviser la syntaxe du C !

Je te remercie pour ta réponse !! :slight_smile:

Je devrais pouvoir m'en sortir avec ce que tu m'as donné.

Bonne journée à toi :smiley:

benenuts64:
Je n'arrive pas à garder en mémoire la position à l'instant t de ma led sur la matrice ce qui fait qu'elle repart systématiquement depuis sa position initiale et bouge depuis celle-ci.

Bonjour,

Il suffit simplement de faire varier x et y quand tu déplaces le point. La nouvelle coordonnée est automatiquement mémorisée.

void deplacer_snake() {
  int X, Y;
  X = analogRead (axeX);
  Y = analogRead (axeY);

  //  int *pointeurSurx = &x;
  //  int *pointeurSury = &y;

  if (X >= 900) { //Si joystick vers la droite
    if (x < 7)
      x++;
  }

  if (Y >= 900) { //Si joystick vers le bas
    if (y > 0)
      y--;
  }

  if (Y <= 100) { //Si joystick vers le haut
    if (y < 7)
      y++;
  }

  if (X <= 100) { //Si joystick vers la gauche
    if (x > 0)
      x--;
  }
  serpent[y] |= 1 << x;
  write_matrix(serpent);
  delay(500);
/*  for (int i = 0 ; i < 8 ; i++) {
    serpent[i] = clean[i];
    delay(30);
  }
*/
}