Conflitto tra RGBmatrixPanel e RCSwitch

Sto sperimentando uno scoreboard per padel su uno scketch trovato online. Nell'originale il punteggio viene aggiornato tramite un telecomando a 433 mhz e visualizzato su display LCD e tutto funziona egregiamente. Vorrei sperimentare la visualizzazione su un LED RGB Matrix 63x32. Purtroppo non appena inserisco il paramentro "matrix.begin();" nel setup void, immediatamente viene bloccato il ricevitore a 433mhz. C'è conflitto tra le due librerie? come potrei ovviare al problema? grazie

/*More Tutorial Visit our 
  Youtube Channel: https://bit.ly/2DyLaeE
  FaceBook Group:  https://bit.ly/2ZCrK1S
  Blog  Link:      https://automationbd1.blogspot.com
 */

#include <Adafruit_GFX.h>
#include <RGBmatrixPanel.h> // Hardware-specific library
#include <FreeMonoBold24pt7b.h>
#include <kongtext4pt7b.h>

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,20,4); 
#include <RCSwitch.h>

RCSwitch mySwitch = RCSwitch();


#define CLK 11   // USE THIS ON ARDUINO MEGA
#define OE   9
#define LAT 10
#define A   A0
#define B   A1
#define C   A2
#define D   A3

// Last parameter = 'true' enables double-buffering, for flicker-free,
// buttery smooth animation.  Note that NOTHING WILL SHOW ON THE DISPLAY
// until the first call to swapBuffers().  This is normal.
//RGBmatrixPanel matrix(A, B, C, CLK, LAT, OE, true);
RGBmatrixPanel matrix(A, B, C, D, CLK, LAT, OE, true, 64);



uint16_t myRED = matrix.Color333(7,0,0);
uint16_t myGREEN = matrix.Color333(0,7,0);
uint16_t myBLUE = matrix.Color333(0,0,7);
uint16_t myWHITE = matrix.Color333(7, 7,7);
uint16_t myYELLOW = matrix.Color333(7,7,0);
uint16_t myCYAN = matrix.Color333(0,7,7);
uint16_t myMAGENTA = matrix.Color333(7,0,7);
uint16_t myShadow = matrix.Color333(4,0,7);
uint16_t myROSE = matrix.Color333(7,0,4);
uint16_t myBLACK = matrix.Color333(0,0,0);
uint16_t myCOLORS[10] = {myRED, myGREEN, myWHITE, myMAGENTA, myBLUE, myYELLOW, myCYAN, myShadow, myROSE, myBLACK};


const int  reset =9 ;

int buttonPushCounter = 0;    // counter for the number of button presses player 1
int buttonPushCounterPlayer2 = 0; // counter for the number of button presses player 2
int up_buttonState = 0;       // current state of the up button player 1
int up_buttonState2 = 0;      // current state of the up button player 2
int up_lastButtonState = 0;   //previous state of the button Player 1
int up_lastButtonState2 = 0; // previous state of the up button Player 2
int padelValue = 0;         //points player 1
int padelValuePlayer2 = 0;  //points player 2
int padelGamePlayer1 = 0;   // games player 1
int padelGamePlayer2 = 0;   //games Player 2
int padelSetPlayer1 = 0;    //sets Player 1
int padelSetPlayer2 = 0;    //sets player 2

boolean upPlayer1 = LOW;
boolean upPlayer2 = LOW;

void setup()
{
  matrix.begin();
  matrix.setTextWrap(false); // Allow text to run off right edge
  matrix.setTextSize(1);

  
  lcd.init();                      // initialize the lcd 
  // Print a message to the LCD.
    lcd.backlight();
  Serial.begin(9600);
  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
  lcd.print("Padel Score:");
  lcd.setCursor(2, 1);
  lcd.print(buttonPushCounter);
  mySwitch.enableReceive(0);  // Receiver on interrupt 0 => that is pin #2
}
void loop()
{

  if (mySwitch.available()) //433Mhz recognition code
    
    {
    unsigned long int num = mySwitch.getReceivedValue();
    Serial.print(num);
    switch(num)
    {
      case 5592332: 
                     
                     upPlayer1 = HIGH;
                     mySwitch.disableReceive();
                     
                     break;
 

      case 5592512:   
                      upPlayer2 = HIGH;
                      mySwitch.disableReceive();
                      
                    
                     break;
  }


  unsigned long time_now = millis();
  int ck = 500;
  while (millis() < time_now + ck)
  //{;}
  mySwitch.resetAvailable();
  mySwitch.enableReceive(0);
  
 
 }

  

  player1Points();
  player2Points();

  player1Set();
  player2Set();

  player1Games();
  player2Games();


 if ( upPlayer1 || upPlayer2)
  {
    lcd.setCursor(2, 1);
    lcd.print("               ");
    lcd.setCursor(2, 1);
    lcd.print(padelSetPlayer1);
    lcd.print(padelGamePlayer1);
    if(padelValue==60){
      lcd.print( "AD");} else
    {
    lcd.print(padelValue);}
    
    lcd.print ("-");
    if(padelValuePlayer2==60){
      lcd.print( "AD");} else
    {
    lcd.print(padelValuePlayer2);}
    lcd.print(padelGamePlayer2);
    lcd.print(padelSetPlayer2);
    Serial.print(buttonPushCounter);
    Serial.print(buttonPushCounterPlayer2);
  }
  upPlayer1 = LOW;
  upPlayer2 = LOW;

 }
 
void player1Points()
{
  up_buttonState = upPlayer1;
  if (up_buttonState != up_lastButtonState)    // compare the buttonState to its previous state
  {
    if (up_buttonState == LOW)   // if the state has changed, increment the counter
    {
    
      upPlayer1 = HIGH;
      buttonPushCounter++;
      
      switch (buttonPushCounter) {
        case 1:
        padelValue = 15;
        Serial.println(padelValue);
        break;
    
        case 2:
        padelValue = 30;
        Serial.println(padelValue);
        break;
  
        case 3:
        padelValue = 40;
        Serial.println(padelValue);
        break;

        
        case 4:
        if(padelValuePlayer2 == 40 && padelValue == 40){
        padelValue = 60;
        Serial.println("AD");
        break;
  
            } else if(padelValuePlayer2==60 && padelValue==40){
    
              padelValue=40;
              padelValuePlayer2=40;
              buttonPushCounter=3;
              buttonPushCounterPlayer2=3;
              break;}

              else{
                  padelValuePlayer2 = 0;
                  padelValue = 0;
                  padelGamePlayer1++;
                  buttonPushCounterPlayer2=0;
                  buttonPushCounter=0;
                  Serial.println(padelValue);
                  break;
            }

         case 5:
         if (padelValue==40){
         buttonPushCounter=3;
         }
         else if (padelValuePlayer2==60 && padelValue==40){
          padelValue = 40;
          padelValuePlayer2 = 40;
          buttonPushCounter = 4;}
    
        else{
            padelValuePlayer2 = 0;
            padelValue = 0;
            padelGamePlayer1++;
            buttonPushCounterPlayer2=0;
            buttonPushCounter=0;
          Serial.println(padelValue);
          break;
          }

  
        default:
        // if nothing else matches, do the default
        // default is optional
        break;
        }
    
      Serial.println("on");
      Serial.print("number of button pushes: ");
      //Serial.println(buttonPushCounter);
      
      
    }


    else {
      Serial.println("off"); // if the current state is LOW then the button went from on to off:
    }
    delay(50);  // Delay a little bit to avoid bouncing
  }

  up_lastButtonState = up_buttonState;   // save the current state as the last state, for next time through the loop
}





void player2Points()
{
  //up_buttonState2 = digitalRead(upPlayer2);
  up_buttonState2 = upPlayer2;
  if (up_buttonState2 != up_lastButtonState2)    // compare the buttonState to its previous state
  {
    if (up_buttonState2 == HIGH)   // if the state has changed, increment the counter
    {
      upPlayer2 = HIGH;
      //bPress = true;  // if the current state is HIGH then the button went from off to on:
      buttonPushCounterPlayer2++;
      
      switch (buttonPushCounterPlayer2) {
      case 1:
       padelValuePlayer2 = 15;
       Serial.println(padelValuePlayer2);
       break;
    
      case 2:
        padelValuePlayer2 = 30;
        Serial.println(padelValuePlayer2);
        break;
  
      case 3:
        padelValuePlayer2 = 40;
        Serial.println(padelValuePlayer2);
        break;
  
      case 4:
        if(padelValuePlayer2 == 40 && padelValue == 40){
          padelValuePlayer2 = 60;
          Serial.println("AD");}

        else if(padelValuePlayer2==40 && padelValue==60){
          padelValue=40;
          padelValuePlayer2=40;
          buttonPushCounterPlayer2=3;
          buttonPushCounter=3;
          break;}

       else{
          padelValuePlayer2 = 0;
          padelValue = 0;
          padelGamePlayer2++;
          buttonPushCounterPlayer2=0;
          buttonPushCounter=0;
          Serial.println(padelValuePlayer2);}
        break;
  

 
     case 5:
        if(padelValuePlayer2 == 40){
          buttonPushCounterPlayer2=3;
          }

          else if(padelValue==60 && padelValuePlayer2==40){
          padelValue = 40;
          padelValuePlayer2 = 40;
          buttonPushCounterPlayer2 = 4;
          break;
          }

          else{padelValuePlayer2 = 0;
            padelValue = 0;
            padelGamePlayer2++;
            buttonPushCounterPlayer2=0;
            buttonPushCounter=0;
            Serial.println(padelValuePlayer2);
            break;
           }

       default:
          // if nothing else matches, do the default
          // default is optional
          break;
        }
    
      Serial.println("on");
      Serial.print("number of button pushes: ");
      //Serial.println(buttonPushCounter);
        }
  else {
      Serial.println("off"); // if the current state is LOW then the button went from on to off:
    }
    delay(50);  // Delay a little bit to avoid bouncing
  }

  up_lastButtonState2 = up_buttonState2;   // save the current state as the last state, for next time through the loop
}

    void player1Set(){
      if (padelGamePlayer1 == 6 && padelGamePlayer2 <= 4){
        padelSetPlayer1++;
        padelGamePlayer1=0;
        padelGamePlayer2=0;
    }

    else if (padelGamePlayer1 == 7 && padelGamePlayer2 <= 5){
        padelSetPlayer1++;
        padelGamePlayer1=0;
        padelGamePlayer2=0;
        }
    }

    void player2Set(){
       if (padelGamePlayer2 == 6 && padelGamePlayer1 <= 4){
        padelSetPlayer2++;
        padelGamePlayer1=0;
        padelGamePlayer2=0;
        }

      else if (padelGamePlayer2 == 7 && padelGamePlayer1 <= 5){
        padelSetPlayer2++;
        padelGamePlayer1=0;
        padelGamePlayer2=0;
        }
     }

    void player1Games(){
     if(padelSetPlayer1 == 2){
          padelSetPlayer1 = 0;
          padelGamePlayer1 = 0;
          padelValue = 0;
          padelSetPlayer2 = 0;
          padelGamePlayer2 = 0;
          padelValuePlayer2=0;
          lcd.clear();
          lcd.println("Team 1 wins!");
          delay(1000);
          lcd.clear();
          
         }
     }

   void player2Games(){
     if(padelSetPlayer2 == 2){
        padelSetPlayer1 = 0;
        padelGamePlayer1 = 0;
        padelValue = 0;
        padelSetPlayer2 = 0;
        padelGamePlayer2 = 0;
        padelValuePlayer2=0;
        lcd.clear();
        lcd.println("Team 2 wins!");
        delay(1000);
        lcd.clear();
       
       }
     }

Scusa, ci dici quale Arduino stai usando e, senza che dobbiamo dedurlo dal codice, come (ossia a quali pin) hai connesso i vari componenti?
Perché vista così mi sembra un possibile conflitto di interrupt, ma senza sapere cosa stai usando e come è connesso...

Chiedo venia per la mia omissione. Sto usando un Arduino Mega. il pannello led 64x32 è collegato secondo lo schema che allego:


Mentre il ricevitore 433mhz alla porta 2.

Hm, vista così non mi sembra ci siano conflitti hardware particolari, anche se non avendo mai usato il matrix non so se la libreria faccia qualcosa di particolare e vada in conflitto con la RCSwitch.

Teoricamente bisognerebbe studiare cosa fa la matrix.begin() ed in che modo questa possa "danneggiare" il ricevitore RF (da una occhiata di sfuggita ovviamente definisce un interrupt, ma bisognerebbe approfondire).

L'unica cosa che mi "stona" però è quell'ultimo parametro "64" nel costruttore: perché lo hai aggiunto, se nel RGBmatrixPanel.h nei commenti leggo che è solo per SAMD (non per il Mega quindi) e soprattutto che dovrebbe essere un "uint8_t *" e non un semplice intero?
Prova intanto a toglierlo, e vedi che succede, hai visto mai...

Mi spiace non poterti aiutare più di questo, temo che bisognerà attendere qualcuno che abbia già usato quella libreria.

Mah ... dando un'occhiata ai sorgenti faccio solo un paio di osservazioni ...

  1. la RGBmatrixPanel, come spesso nello stile di Adafruit, è un gran "mattone" scarsamente ottimizzato e che pensa di poter prendere il controllo, quasi totale, della situazione ... non per nulla abbiamo il commento:

... It's a somewhat rude trick that ONLY works because the interrupt handler is set ISR_BLOCK, halting any other interrupts ...
... only needed for AVR's where you cannot set one bit in a single instruction.

  1. la RCSwitch usa un interrupt per ricevere i dati e ... se, come detto sopra, la RGBmatrixPanel ogni tot blocca gli interrupt ... ho idea che difficilmente riesce a decodificare quello che riceve.

Guglielmo

Grazie per il suggerimento. Credo che sia proprio un blocco degli interrupts da parte di RGBmatrixPanel. Ho provato a spostare il ricevitore sui piedini :
pin digitale 21: interrupt 2
pin digitale 20: interrupt 3
pin digitale 19: interrupt 4
pin digitale 18: interrupt 5
che sono quelli dell'Arduino Mega e tutti si bloccano aggiungendo semplicemente al void setup il parametro matrix.benig(). Ora c'è un modo per riattivare gli interrupts bloccati o almeno uno di essi?

Beh, la frase ...

... It's a somewhat rude trick that ONLY works because the interrupt handler is set ISR_BLOCK, halting any other interrupts ...

... lascia ben poche speranze. :roll_eyes:

Guglielmo

Ho raggirato il problema. Visto che Adafruit si è impossessata degli interrupts ho fatto gestire la parte Wireless del mio tablescore per padel da un Arduino uno (che si occupa di gestire la parte wireless con un telecomando da 433 mhz) collegato al Mega che si occupa invece di gestire la parte Led matrix. Funziona perfettamente. può essere gestito attraverso i pulsanti oppure un semplice telecomando (tipo quelli dei cancelli automatici) anche da lunga distanza (il giocatore col telecomando in tasca puo aggiornare il punteggio). Lo sketch elabora il punteggio in totale autonomia compresi i vantaggi, i sets che vanno oltre i 5 games (7-5) e persino i tie breaks. essendo alle prime armi magari è un pochino macchinoso, ma fa egregiamente il suo dovere!

2 Likes

È molto bello, mi piace

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.