[Résolu] PROJET ARDUINO (Aide pour simuler un volet roulant | Max7219)

Edit : Octobre 2019
La maquette KNX est finie, il y a :

Volet (merci Lesept ;D )
Eclairage
Porte de garage + capteur d'ouverture
Plancher chauffant électrique
Climatisation
Gestion de caméra
Scénario et événement météo
Alarme
Capteur de mouvement
Interrupteur crépusculaire
Envoi de mail selon notification

Le tout compatible IFTTT et Google Assistant :o

Avec une visualisation sur tablette et smartphone grâce à Openhab, solution open-source sur un raspberry pi 3

Photo maquette

Voila je reste dispo pour toutes questions

Le reste du projet ici

Merci le fofo pour votre aide.

See ya :sunglasses:


Bonjour la communauté,
Si je vous écrit c'est que je n'ai pas trouvé l'aide qu'il ma fallait.
J'aimerai avoir des axes de recherches pour mon projet.

Dans le cadre d'une réalisation d'une maquette domotique en KNX j'aimerai pouvoir simuler la monter et la descente a l'aide de deux bouton poussoir.

Pour "visualiser" le mouvement, je voudrais me servir de 4 afficheurs 8x8 max7219 à la verticale.

Pour la descente on allume les lignes un a une et pour la montée on les éteins.

J'aimerai aussi qu'au relâcher de la touche "l'animation" s'arrête.

Bien entendu je débute mais j'ai fait quelques tuto d'Eskimon et j'arrive à appréhender le code.

Pouvez vous m'orientez niveau bibliothèque et/ou tuto svp dans un premier temps.
je ferai évoluer le code ici après si je rencontre d'autres problèmes.

Est il possible d’adresser chaque ligne dans le code ou faut il une formule mathématique.

Pour les poussoir faut il que j'utilise une résistance ou celle de l'arduino uno/nano suffit

J'ai bien sur regarder du coté des textes défilant mais je ne vois pas comment adapter à mon projet.

Merci pour votre aide,

Je reste à votre disposition.

[Edit = Solution du problème]

Bonjour,

Bravo Lesept

Tu m'as fournis le code qu'il me fallait. :smiley:

Et j'ai appris aussi pas mal de chose grace à toi. :wink:

Merci beaucoup.

voici donc le code final :

/*
   Simulateur de volets roulants
   Lesept 04/08/2019
*/
#include <Bounce2.h>
#include <MD_MAX72xx.h>
#include <SPI.h>
#define HARDWARE_TYPE MD_MAX72XX::PAROLA_HW
#define MAX_DEVICES  4
#define CLK_PIN   13  // or SCK
#define DATA_PIN  11  // or MOSI
#define CS_PIN    10  // or SS

// SPI hardware interface
MD_MAX72XX mx = MD_MAX72XX(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);
const int btnHaut = 6;       // pin du boutton montée
const int btnBas = 5;        // pin du bouton descente
Bounce voletUp = Bounce();
Bounce voletDown = Bounce();

int btnHautState = 0;  // LOW = 0, HIGH = 1
int btnBasState = 0;   // LOW = 0, HIGH = 1
int etatVolet = 0;     // LOW = 0, HIGH = 1
int numCol = 8;
int numMat = 0;

void setup()
{
  mx.begin();
  Serial.begin(57600);
  // initialisation des boutons
  pinMode(btnHaut, INPUT);
  pinMode(btnBas, INPUT);
  voletUp.attach(btnHaut);
  voletUp.interval(100); // interval in ms
  voletDown.attach(btnBas);
  voletDown.interval(100); // interval in ms
   mx.control(MD_MAX72XX::INTENSITY, 1);
  
}

void monterVolets() {
  mx.setColumn(numCol + numMat * 8, 0);
  if (numMat == MAX_DEVICES - 1 && numCol == 0) return;
  numCol --;
  if (numCol < 0) {
    numCol = 7;
    numMat++;
  }
  delay(220);
}

void descendreVolets() {
 
  mx.setColumn(numCol + numMat * 8, 0xff);
  if (numMat == 0 && numCol == 7) return;
  numCol ++;
  if (numCol > 7) {
    numCol = 0;
    numMat--;
  }
  delay(200);
}

void loop() {
  // Update the Bounce instances :
  voletUp.update();
  voletDown.update();
  // Get the updated value :
  btnHautState = voletUp.read();
  btnBasState = voletDown.read();

  if (btnHautState == HIGH) monterVolets();   // On monte le volet
  if (btnBasState == HIGH) descendreVolets(); // On descend le volet
}

Du coup je me permet un petit H.S

Voici la maquette domotique que je suis en train de faire.

C'est un immeuble sur 3 niveaux ;

RDC cuisinie / Salon
1er SDB / Chambre
2eme Salle TV terrasse

Avec plancher chauffant et rafraîchissant pour le rdc et le 1er.

Le but est d'intégrer 3 volets entres les les fenêtre de chaque niveau afin de visualiser la montée et la descente.

La techno qui gère la domotique c'est le bus KNX et la supervision une solution Open source Openhab sur un rasberry pi 3 b+ avec influxDb et grafana pour la collect des données et la mise en page des données en graphique.

Le tableau "tourne" depuis 10 mois sans problème et les composants ont pour certain plus de 10 ans.

Quand j'aurai fini le posterai une vidéo avec différents scénarios.

Si le sujet vous intéresse je suis apte à répondre à vos question.

Encore merci Lesept

A bientôt.

Je te conseille la bibliothèque MD_MAX72XX qui possède la fonction setColumn qui fait ce que tu cherches

Pour le bouton poussoir, tu peux utiliser les résistances de pull-up internes, en le déclarant en INPUT_PULLUP. DigitalRead te renvoie LOW si enfoncé et HIGH sinon.

Bonjour
Merci pour votre message
J'ai survoler la bibliothèque
Force est de constater que l'investissement en temps sera plus grand que prévu
Du coup je pense juste afficher un texte en fonction du bouton actionner
Je reviens avec un bout de code des que possible

Ça dépend si tu as des notions de C ou pas.
Si tu débutes, lis les messages épinglés en haut du forum, ils te renverront vers des sites de tutos très bien faits.

Si tu connais un peu, tu peux te familiariser avec une bibliothèque en examinant et testant les exemples fournis. Pour cette bibliothèque, tu as l'exemple MD_MAX72xx_Test.ino. Il est un peu complexe mais cette partie ressemble à ce que tu veux faire :

void columns()
// Demonstrates the use of setColumn()
{
  PRINTS("\nCols 0->max");
  mx.clear();

  for (uint8_t col=0; col<mx.getColumnCount(); col++)
  {
    mx.setColumn(col, 0xff);
    delay(DELAYTIME/MAX_DEVICES);
    mx.setColumn(col, 0x00);
  }
}

Ça doit faire bouger une barre sur les colonnes de l'afficheur. Tu peux le modifier comme ceci :

void descendreVolets() {
  mx.clear();
  for (uint8_t col=mx.getColumnCount()-1; col>=0; col--)
  {
    mx.setColumn(col, 0xff);
    delay(150);
  }
}

et

void monterVolets() { 
  for (uint8_t col=0; col<mx.getColumnCount(); col++) mx.setColumn(col, 0xff);
  for (uint8_t col=0; col<mx.getColumnCount(); col++)
  {
    mx.setColumn(col, 0);
    delay(150);
  }
}

A tester, je n'ai pas vérifié...

Du coup, tu simplifies le code de l'exemple, en ne conservant que les définitions et le setup :

#include <MD_MAX72xx.h>
//#include <SPI.h>

// Define the number of devices we have in the chain and the hardware interface
// NOTE: These pin numbers will probably not work with your hardware and may
// need to be adapted
#define HARDWARE_TYPE MD_MAX72XX::PAROLA_HW
#define MAX_DEVICES	4

#define CLK_PIN   13  // or SCK
#define DATA_PIN  11  // or MOSI
#define CS_PIN    10  // or SS

// SPI hardware interface
MD_MAX72XX mx = MD_MAX72XX(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);

void setup()
{
  mx.begin();
  Serial.begin(57600);
}

void loop() {

}

Il te reste à déclarer tes boutons, et écrire le code dans la loop qui va appeler les fonctions des volets en fonction de l'appui sur les boutons.

Attention : il faut trouver la bonne valeur pour HARDWARE_TYPE (celle qui est indiquée plus haut n'est pas forcément la bonne) parmi cette liste :

  enum moduleType_t
  {
    PAROLA_HW,    ///< Use the Parola style hardware modules.
    GENERIC_HW,   ///< Use 'generic' style hardware modules commonly available.
    ICSTATION_HW, ///< Use ICStation style hardware module.
    FC16_HW       ///< Use FC-16 style hardware module.
  };

Au besoin pour t'aider, voir ici

Bonsoir lesept
merci pour votre aide
les boutons sont "PullDown"
Voici le code :

#include <MD_MAX72xx.h>
//#include <SPI.h>

// Define the number of devices we have in the chain and the hardware interface
// NOTE: These pin numbers will probably not work with your hardware and may
// need to be adapted
#define HARDWARE_TYPE MD_MAX72XX::PAROLA_HW
#define MAX_DEVICES  4

#define CLK_PIN   13  // or SCK
#define DATA_PIN  11  // or MOSI
#define CS_PIN    10  // or SS

// SPI hardware interface
MD_MAX72XX mx = MD_MAX72XX(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);

const int btnHaut = 6;     // pin du boutton montée
const int btnBas = 5;     // pin du bouton descente 


int btnHautState = 0;         // valeurs des boutons
int btnBasState = 0;


void setup()
{
  mx.begin();
  Serial.begin(57600);

   // initialisation des boutons
  pinMode(btnHaut, INPUT);
  pinMode(btnBas, INPUT);
}

void descendreVolets() {
  mx.clear();
  for (uint8_t col=mx.getColumnCount()-1; col>=0; col--)
  {
    mx.setColumn(col, 0xff);
    delay(150);
  }
}

void monterVolets() { 
  for (uint8_t col=0; col<mx.getColumnCount(); col++) mx.setColumn(col, 0xff);
  for (uint8_t col=0; col<mx.getColumnCount(); col++)
  {
    mx.setColumn(col, 0);
    delay(150);
  }
}

void loop() {

// read the state of the pushbutton value:
  btnHautState = digitalRead(btnHaut);
  btnBasState = digitalRead(btnBas);

  while (btnHautState == HIGH) {
    // On monte le volet
    monterVolets;
  } 

while (btnBasState == HIGH) {
    // On descent le volet
    descendreVolets;
  } 

exit(0);

}

Malheureusement rien ne ce passe

quand je met dans le loop uniqument monterVolets ou descendreVolets rien ne se passe non plus.

Force est de constater qu'après 3 ans sans arduino je suis dépassé.
Et encore je débutais juste :o

Pouvez juste me guider pour les boutons, je verrai ensuite pour la partie "animation"

Merci d'avance.

Est-ce que tu as réussi à faire fonctionner les exemples de la bibliothèque ? C'est ce qu'il fait faire au début pour savoir si la matrice est bien connectée et déclarée

Ensuite, change les while en if et ôte le exit (0)

oui pour les exemple liés a la bibliothèque MD_MAX72XX, j'arrive à les fonctionner sans problème

EDIT : j'avais oublié les parenthèses "()" après descendreVolets et monterVolets dans le loop

alors quand on actionne btnHaut j'ai une animation qui se répète mais des que j'actionne le bntBas impossible d'enchainer sur l'autre, tout les points rest allumé

Mais c'est un grand progrès merci.

ps le code :

#include <MD_MAX72xx.h>
#include <SPI.h>

// Define the number of devices we have in the chain and the hardware interface
// NOTE: These pin numbers will probably not work with your hardware and may
// need to be adapted
#define HARDWARE_TYPE MD_MAX72XX::PAROLA_HW
#define MAX_DEVICES  4

#define CLK_PIN   13  // or SCK
#define DATA_PIN  11  // or MOSI
#define CS_PIN    10  // or SS

// SPI hardware interface
//MD_MAX72XX mx = MD_MAX72XX(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
MD_MAX72XX mx = MD_MAX72XX(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);
const int btnHaut = 6;     // pin du boutton montée
const int btnBas = 5;     // pin du bouton descente 
const int ledPin =  13;      // the number of the LED pin
const int buttonPin = 6; 

int btnHautState = 0;         // variable for reading the pushbutton status
int btnBasState = 0;
 


void setup()
{
  mx.begin();
  Serial.begin(57600);

   // initialisation des boutons
  pinMode(btnHaut, INPUT);
  pinMode(btnBas, INPUT);
  pinMode(ledPin, OUTPUT);
}

void descendreVolets() {
  mx.clear();
  for (uint8_t col=mx.getColumnCount()-1; col>=0; col--)
  {
    mx.setColumn(col, 0xff);
    delay(150);
  }
}

void monterVolets() { 
  for (uint8_t col=0; col<mx.getColumnCount(); col++) mx.setColumn(col, 0xff);
  for (uint8_t col=0; col<mx.getColumnCount(); col++)
  {
    mx.setColumn(col, 0);
    delay(150);
  }
}

void loop() {

// read the state of the pushbutton value:
  btnHautState = digitalRead(btnHaut);
  btnBasState = digitalRead(btnBas);
  

 if (btnHautState == HIGH) {
    // On monte le volet
    monterVolets();
    digitalWrite(ledPin, HIGH);
    
  } 

  
if (btnBasState == HIGH) {
    // On descent le volet
    descendreVolets();
    digitalWrite(ledPin, LOW);
    
  } 

}

As-tu testé si les animations fonctionnent correctement ?
À la fin du setup, ajoute ceci :

Serial.println ("montee") ;
monterVolets() ;
delay(10000);
Serial.println ("descente") ;
descendreVolets();
while (1);

Ça devrait jouer les deux animations et arrêter l'exécution.

Est-ce que les animations sont correctes ?

Ensuite, pour le code essaye ceci

#include <MD_MAX72xx.h>
#include <SPI.h>

// Define the number of devices we have in the chain and the hardware interface
// NOTE: These pin numbers will probably not work with your hardware and may
// need to be adapted
#define HARDWARE_TYPE MD_MAX72XX::PAROLA_HW
#define MAX_DEVICES  4

#define CLK_PIN   13  // or SCK
#define DATA_PIN  11  // or MOSI
#define CS_PIN    10  // or SS

// SPI hardware interface
//MD_MAX72XX mx = MD_MAX72XX(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
MD_MAX72XX mx = MD_MAX72XX(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);
const int btnHaut = 6;     // pin du boutton montée
const int btnBas = 5;     // pin du bouton descente 
const int ledPin =  13;      // the number of the LED pin
// const int buttonPin = 6; 

int btnHautState = 0;         // variable for reading the pushbutton status
int btnBasState = 0;
int etatVolet = 0;  // LOW = 0, HIGH = 1


void setup()
{
  mx.begin();
  Serial.begin(57600);

   // initialisation des boutons
  pinMode(btnHaut, INPUT);
  pinMode(btnBas, INPUT);
  pinMode(ledPin, OUTPUT);
}

void descendreVolets() {
  mx.clear();
  for (int col=mx.getColumnCount()-1; col>=0; col--)
  {
    mx.setColumn(col, 0xff);
    delay(150);
  }
}

void monterVolets() { 
  for (uint8_t col=0; col<mx.getColumnCount(); col++) mx.setColumn(col, 0xff);
  for (uint8_t col=0; col<mx.getColumnCount(); col++)
  {
    mx.setColumn(col, 0);
    delay(150);
  }
}

void loop() {

// read the state of the pushbutton value:
  btnHautState = digitalRead(btnHaut);
  btnBasState = digitalRead(btnBas);
  

 if (btnHautState == HIGH && etatVolet == LOW) {
    // On monte le volet
    monterVolets();
    digitalWrite(ledPin, HIGH);
    etatVolet = HIGH ;
  } 

  
if (btnBasState == HIGH && etatVolet == HIGH) {
    // On descent le volet
    descendreVolets();
    digitalWrite(ledPin, LOW);
    etatVolet = LOW;
  } 

}

Bonjour,
Clairement votre code est ce qu'il me fallait :grinning:
Connaitre l'état du volet permet de changer l'animation fallait y penser

Par contre si je peux me permettre, est ce qu'il est possible de changer le sens de l'animation des leds
je m'explique
quand je descend le volet les 4 écrans s'allume 1 a 1 de hat en bas, par contre à l’intérieur des écrans les pixel font un mouvement de montée.
Et inversement pour la montée.

Je ne saisie pas ou on peut changer ça

Merci d'avance

Essaye

void descendreVolets() {
  mx.clear();
  for (byte mat = 0; mat < MAX_DEVICES; mat ++) {
  for (int col=7; col>=0; col--)
  {
    mx.setColumn(col+mat *8, 0xff);
    delay(150);
  }
}

Si ça ne prend pas les matrices dans le bon sens, change
col+mat *8 en col+(MAX_DEVICES-mat-1)*8

lesept:
Essaye

void descendreVolets() {

mx.clear();
  for (byte mat = 0; mat < MAX_DEVICES; mat ++) {
  for (int col=7; col>=0; col--)
  {
    mx.setColumn(col+mat *8, 0xff);
    delay(150);
  }
}

Bonsoir avec ce code j'ai exactement ce que je veux pour la descente, par contre pour la montée en changeant le mx.setColumn(col+mat *8, 0xff) par mx.setColumn(col+mat *8, 0
ça s'efface mais dans la même direction que la descente

Ayant essayé de multiples combinaisons je dois dire que je suis coincé

le dernier code est le suivant :

#include <MD_MAX72xx.h>
#include <SPI.h>

// Define the number of devices we have in the chain and the hardware interface
// NOTE: These pin numbers will probably not work with your hardware and may
// need to be adapted
#define HARDWARE_TYPE MD_MAX72XX::PAROLA_HW
#define MAX_DEVICES  4

#define CLK_PIN   13  // or SCK
#define DATA_PIN  11  // or MOSI
#define CS_PIN    10  // or SS

// SPI hardware interface
//MD_MAX72XX mx = MD_MAX72XX(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
MD_MAX72XX mx = MD_MAX72XX(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);
const int btnHaut = 6;       // pin du boutton montée
const int btnBas = 5;        // pin du bouton descente 
//const int ledPin =  13;      // the number of the LED pin


int btnHautState = 0;  // LOW = 0, HIGH = 1
int btnBasState = 0;   // LOW = 0, HIGH = 1
int etatVolet = 0;     // LOW = 0, HIGH = 1


void setup()
{
  mx.begin();
  Serial.begin(57600);

   // initialisation des boutons
  pinMode(btnHaut, INPUT);
  pinMode(btnBas, INPUT);
//  pinMode(ledPin, OUTPUT);



}

void descendreVolets() {
  
  for (byte mat = 0; mat < MAX_DEVICES; mat ++)
  for (int col=7; col>=0; col--)
  {
    mx.setColumn(col+mat*8, 0xff);
    delay(150);
  }

}

void monterVolets() {
  mx.control(MD_MAX72XX::INTENSITY, 1);
 
 for (byte mat = 0; mat < MAX_DEVICES; mat ++)
  for (int col=7; col>=0; col--)
  {
    mx.setColumn(col+mat*8, 0);
    delay(150);
  }

}

void loop() {

// read the state of the pushbutton value:
  btnHautState = digitalRead(btnHaut);
  btnBasState = digitalRead(btnBas);
  

 if (btnHautState == HIGH && etatVolet == LOW) {
    // On monte le volet
    monterVolets();
//    digitalWrite(ledPin, HIGH);
    etatVolet = HIGH ;
  } 

  
if (btnBasState == HIGH && etatVolet == HIGH) {
    // On descent le volet
    descendreVolets();
//    digitalWrite(ledPin, LOW);
    etatVolet = LOW;
  } 

}

Merci

Si ça convient pour la descente, alors pour la montée il suffit d'inverser l'ordre.

void descendreVolets() {
  
  for (byte mat = 0; mat < MAX_DEVICES; mat ++)
  for (int col=7; col>=0; col--)
  {
    mx.setColumn(col+mat*8, 0xff);
    delay(150);
  }

}

void monterVolets() {
  mx.control(MD_MAX72XX::INTENSITY, 1);
 
 for (int mat = MAX_DEVICES-1; mat >=0; mat -- )
  for (int col=0; col<8; col++)
  {
    mx.setColumn(col+mat*8, 0);
    delay(150);
  }

}

Merci pour ton aide
Voici le code

#include <MD_MAX72xx.h>
#include <SPI.h>

// Define the number of devices we have in the chain and the hardware interface
// NOTE: These pin numbers will probably not work with your hardware and may
// need to be adapted
#define HARDWARE_TYPE MD_MAX72XX::PAROLA_HW
#define MAX_DEVICES  4

#define CLK_PIN   13  // or SCK
#define DATA_PIN  11  // or MOSI
#define CS_PIN    10  // or SS

// SPI hardware interface
//MD_MAX72XX mx = MD_MAX72XX(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
MD_MAX72XX mx = MD_MAX72XX(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);
const int btnHaut = 6;       // pin du boutton montée
const int btnBas = 5;        // pin du bouton descente 



int btnHautState = 0;  // LOW = 0, HIGH = 1
int btnBasState = 0;   // LOW = 0, HIGH = 1
int etatVolet = 0;     // LOW = 0, HIGH = 1


void setup()
{
  mx.begin();
  Serial.begin(57600);

   // initialisation des boutons
  pinMode(btnHaut, INPUT);
  pinMode(btnBas, INPUT);



}

void descendreVolets() {
  
  for (byte mat = 0; mat < MAX_DEVICES; mat ++)
  for (int col=7; col>=0; col--)
  {
    mx.setColumn(col+mat*8, 0xff);
    delay(150);
  }

}

void monterVolets() {
  mx.control(MD_MAX72XX::INTENSITY, 1);
 
  for (byte mat = 0; mat < MAX_DEVICES; mat ++)
  for (int col=-8; col<=0; col++)
  {
    mx.setColumn(col+(MAX_DEVICES-mat)*8, 0);
    delay(150);
  }
}

void loop() {

// read the state of the pushbutton value:
  btnHautState = digitalRead(btnHaut);
  btnBasState = digitalRead(btnBas);
  

 if (btnHautState == HIGH && etatVolet == LOW) {
    // On monte le volet
    monterVolets();
    etatVolet = HIGH ;
  } 

  
if (btnBasState == HIGH && etatVolet == HIGH) {
    // On descent le volet
    descendreVolets();
    etatVolet = LOW;
  } 

}

Ca fonctionne :smiley:
Par contre à la montée j'ai un léger temps d’arrêt à la fin de chaque écran

Je pense qu'il faut que la boucle commence à -7 au lieu de -8

Bonjour,
La page web n'a pas était rafraîchit et je n'ai pas vu le post #12
La solution était la. :o

Du coup ca fonctionne impeccable.

Encore merci, 8)

Maintenant ce serait bien de de pouvoir animer que quand le bouton est appuyé et pouvoir repartir dans l'autre sens même si le volet n'est pas arrivé dans sa position finale

Tu veux dire que le volet doit bouger uniquement si le bouton est enfoncé ? Ce serait un appui long et le volet monterait ou descendrait uniquement à ce moment là ?

lesept:
Tu veux dire que le volet doit bouger uniquement si le bouton est enfoncé ? Ce serait un appui long et le volet monterait ou descendrait uniquement à ce moment là ?

Oui exactement
Comme sur un vrai volet filaire

Poste le code que tu as maintenant et qui marche afin que je parte de la même version que toi

Le volet doit s'arrêter lorsqu'on relâche le bouton ?
Que doit-il se passer si les deux boutons sont enfoncés en même temps ?

Voici une première tentative : pour gérer les rebonds des boutons poussoirs, je te suggère d'utiliser la bibliothèque bounce2. Installe la, relance l'IDE et essaye ce code:

/*
   Simulateur de volets roulants
   Lesept 04/08/2019
*/
#include <Bounce2.h>
#include <MD_MAX72xx.h>
#include <SPI.h>
#define HARDWARE_TYPE MD_MAX72XX::PAROLA_HW
#define MAX_DEVICES  4
#define CLK_PIN   13  // or SCK
#define DATA_PIN  11  // or MOSI
#define CS_PIN    10  // or SS

// SPI hardware interface
MD_MAX72XX mx = MD_MAX72XX(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);
const int btnHaut = 6;       // pin du boutton montée
const int btnBas = 5;        // pin du bouton descente
Bounce voletUp = Bounce();
Bounce voletDown = Bounce();

int btnHautState = 0;  // LOW = 0, HIGH = 1
int btnBasState = 0;   // LOW = 0, HIGH = 1
int etatVolet = 0;     // LOW = 0, HIGH = 1
int numCol = 7;
int numMat = 0;

void setup()
{
  mx.begin();
  Serial.begin(57600);
  // initialisation des boutons
  pinMode(btnHaut, INPUT);
  pinMode(btnBas, INPUT);
  voletUp.attach(btnHaut);
  voletUp.interval(10); // interval in ms
  voletDown.attach(btnBas);
  voletDown.interval(10); // interval in ms
}

void monterVolets() {
  if (numMat == MAX_DEVICES - 1 && numCol == 0) return;
  numCol --;
  if (numCol < 0) {
    numCol = 7;
    numMat++;
  }
  mx.setColumn(numCol + numMat * 8, 0);
}

void descendreVolets() {
  if (numMat == 0 && numCol == 7) return;
  numCol ++;
  if (numCol > 7) {
    numCol = 0;
    numMat--;
  }
  mx.setColumn(numCol + numMat * 8, 0);
}

void loop() {
  // Update the Bounce instances :
  voletUp.update();
  voletDown.update();
  // Get the updated value :
  btnHautState = voletUp.read();
  btnBasState = voletDown.read();

  if (btnHautState == HIGH) monterVolets();   // On monte le volet
  if (btnBasState == HIGH) descendreVolets(); // On descend le volet
}

Je n'ai pas essayé... Il est possible que je me sois emmêlé avec les numéros de colonnes et de matrices...