MajicDesigns / MD_Parola

Library for modular scrolling LED matrix text displays
GNU Lesser General Public License v2.1
428 stars 135 forks source link

Issue of using the library on a Arduino UNO Wifi Rev 2... #97

Closed Wettemark closed 2 years ago

Wettemark commented 2 years ago

I'm developing a scoreboard for a baseball club in the local town. For this I have used the Arduino UNO WiFi Rev 2 card as I'm going to connect the control and the board through WiFi.

I'm using the MD_Parola library verison 3.5.6 to control the matrixes. I'm using 4 matrixes split up into 4 zones to display one value for each of the zones.

I did a lot of the development on a normal UNO and everything worked good and still does when I'm running the code without WiFi parts. But as I shifted over to the UNO Wifi card I started to get problems.

Both the Wifi and the Parola library are using SPI interface. I have needed to shift the CS for the Parola library to a different pin. I'm running it over pins 11, 12 and 13.

But I still have issues. Right now I can get 3 of the four zones to work, but the last zone will not display what I send to it. Right now it's showing all elemets lighted up and quite bright. Does not matter what I push out to the display, will not show.

I have tried a couple of different pin setups but as soon as I run the code on the UNO Wifi it will not light up the 4th zone. All the other three works all the time.

I have a test program that works on a normal UNO but as soon as I upload this to a UNO Wifi this happens.

I have check the hardware and and all matrixes are working. Wireing is ok, using the same just shifting the feeding connector between them.

I honestly do not know what else to test. Please help!

Snippet of code:

define CS_PIN 12 //Pin for SPI interface - CS

define DIN_PIN 11 //Pin for SPI interface - DIN

define CLK_PIN 13 //Pin for SPI interface - CLK

// Configuration for matrixes

define HARDWARE_TYPE MD_MAX72XX::GENERIC_HW

define MAX_DEVICES 4

// Create a new instance of the matrix controller and also using SPI Interface MD_Parola matrix = MD_Parola(HARDWARE_TYPE, DIN_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);

viod setup(){ // Intialize the led matrix and setting up the 4 zones, one per zone matrix.begin(4); matrix.setZone(0, 0, 0); matrix.setZone(1, 1, 1); matrix.setZone(2, 2, 2); matrix.setZone(3, 3, 3);

// Set the intensity (brightness) of the display (0-15) matrix.setIntensity(brightness-1);

// Clear the display matrix.displayClear();

//Setting up the zones on the led matrix //matrix.setFont(_seg7_fixed_medium); matrix.setFont(_seg7_fixed_small); matrix.setCharSpacing(0); //Set for all zones matrix.setZoneEffect(0, true, PA_FLIP_UD); matrix.setZoneEffect(0, true, PA_FLIP_LR); matrix.setCharSpacing(1, 1); matrix.setZoneEffect(1, true, PA_FLIP_UD); matrix.setZoneEffect(1, true, PA_FLIP_LR); matrix.setCharSpacing(2, 0); //Set special handling for zone 2 matrix.setZoneEffect(2, true, PA_FLIP_UD); matrix.setZoneEffect(2, true, PA_FLIP_LR); matrix.setCharSpacing(3, 1); matrix.setZoneEffect(3, true, PA_FLIP_UD); matrix.setZoneEffect(3, true, PA_FLIP_LR);

//Connect the zones to char buffer matrix.displayZoneText(0, szInnings, PA_LEFT, 0, 0, PA_PRINT, PA_NO_EFFECT ); //2 matrix.displayZoneText(1, szHome, PA_LEFT, 0, 0, PA_PRINT, PA_NO_EFFECT ); //0 matrix.displayZoneText(2, szAway, PA_LEFT, 0, 0, PA_PRINT, PA_NO_EFFECT ); //1 matrix.displayZoneText(3, szBrightness, PA_LEFT, 0, 0, PA_PRINT, PA_NO_EFFECT ); //3 }

void loop() { sprintf(szInnings, ";%d", innings); sprintf(szHome, "%d", homeScore);
sprintf(szAway, "%d", awayScore);
sprintf(szBrightness, "%d", brightness);

//Updating the matrixes matrix.displayAnimate(); matrix.displayReset(0); matrix.displayReset(1); matrix.displayReset(2); matrix.displayReset(3); }

MajicDesigns commented 2 years ago

Snippets don't work too well because I cannot see what else your program is doing, which is often where the issues are.

As I understand your requirements: you have 4 matrices; each matrix is a zone; each matrix will display a single numeric digit; the only animation used is PA_PRINT.

From what you have given, I think the structure of your loop() may be causing a problem because you are continuously sending the data (hundreds of times a second) and erasing the data immediately with the displayReset(). This may be just in the snippet, but that is what I can see.

PA_PRINT will take one animation cycle to display, so I imagine this is a lot faster than your baseball score will change. I would make sure the loop only updates the display when the data changes, more like

matrix.displayAnimate()
if (any of the data has changed)
{
  sprintf(szInnings, ";%d", innings);
  sprintf(szHome, "%d", homeScore);
  sprintf(szAway, "%d", awayScore);
  sprintf(szBrightness, "%d", brightness);
  matrix.displayReset(0);
  matrix.displayReset(1);
  matrix.displayReset(2);
  matrix.displayReset(3);
}

You keep track of when the data changes either by setting an 'old' value for each and then comparing to the current or more easily (with such a small amount of data) by just setting a global boolean flag when you change any of the displayed values. This is then used to trigger the update and reset to false in the 'if' statement.

An alternative is to get rid of the zones altogether. You are using a fixed font, so the spacing will be constant and you can work out where things will land on the display easily. Then use

sprintf("%d %d %d %d", innings, homeScore, awayScore, brightness);

to format one string for the display. Using one zone you can just use the .print() method or the native displayAnimate() method (however, the same comments as above apply for updates in loop()).

Wettemark commented 2 years ago

Thanks for your reply.

I'm not to used to writing codce for the Arduino and I see your point about updating the matrixes to often. There is a bit of code where I today are updating the values to show in the matrixes so I will move the displayReset command to inside the if statements for the update. I will report the progress.

I would just lift one question, the code is working correctly on a normal Arduino UNO but it's only on a Uno Wifi I'm getting this issue. I can reconnect to a UNO and use the same hardware for the matrixes and buttons and I get it to work with the same test program. I understand that I got a collision on the UNO Wifi since the network also using the SPI interface so that I have fixed. But the last of the displays will not work on the UNO Wifi.

Are there some differences in the architecute between the two more than that it's a built in WiFi shield on the UNO Wifi?

Wettemark commented 2 years ago

Sorry, not used to Github... ;-)

Wettemark commented 2 years ago

Main code of the program

`/*****

include

include

include

include

include "score.h"

include "seg7_fixed_medium.h"

include "seg7_fixed_small.h"

//Definition of pins for input and output

define INNINGDOWN 2 //BUTTON

define INNINGUP 3 //BUTTON

define HOMEDOWN 4 //BUTTON

define HOMEUP 5 //BUTTON

define AWAYDOWN 6 //BUTTON

define AWAYUP 7 //BUTTON

define OUTS 8 //BUTTON

define BRIGHTNESSDOWN A5 //BUTTON

define BRIGHTNESSUP A4 //BUTTON

define RESET A3 //BUTTON

define OUT1 A2 //LED

define OUT2 A1 //LED

define OUT3 A0 //LED

define CS_PIN 12 //Pin for SPI interface - CS

define DIN_PIN 11 //Pin for SPI interface - DIN

define CLK_PIN 13 //Pin for SPI interface - CLK

// Configuration for matrixes

define HARDWARE_TYPE MD_MAX72XX::GENERIC_HW

define MAX_DEVICES 4

// Create a new instance of the matrix controller and also using SPI Interface MD_Parola matrix = MD_Parola(HARDWARE_TYPE, DIN_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);

// Declaring and instantiate Bounce2 objects for the buttons Bounce2::Button debInningUp = Bounce2::Button(); Bounce2::Button debInningDown = Bounce2::Button(); Bounce2::Button debHomeUp = Bounce2::Button(); Bounce2::Button debHomeDown = Bounce2::Button(); Bounce2::Button debAwayUp = Bounce2::Button(); Bounce2::Button debAwayDown = Bounce2::Button(); Bounce2::Button debBrightnessUp = Bounce2::Button(); Bounce2::Button debBrightnessDown = Bounce2::Button(); Bounce2::Button debOuts = Bounce2::Button(); Bounce2::Button debReset = Bounce2::Button();

//Declaration of variables //char arrays for the output text to matrixes char szHome[4] = {"0"}; //2 digit score char szAway[4] = {"0"}; //2 digit score char szBrightness[4] = {"4"}; //2 digit brightness char szInnings[4] = {":1"}; // arrow up or down and inning number char szMsgSend[30] = {""}; //Full message to send to clients

//Internal variables to handle status int debWait = 10; //Milliseconds to handle click detection for Bounce2 int innings = 1; //Variable to handle the current inning int inningPart = TOP; //Variable to handle TOP or BOTTOM in the inning int homeScore = 0; //Variable to handle the current home score int awayScore = 0; //Variable to handle the current away score int outs = 0; //Variable to handle the number of outs int brightness = 5; // Internally handled as 1-16. Will be calculated to a value before sending out to scoreboard through formula: (brightness - 1) * 17 (Value will be between 0-255) boolean reset = false; //Flag to check if double click for reset has been done

void setup() { // Intialize the led matrix and setting up the 4 zones, one per zone matrix.begin(4); matrix.setZone(0, 0, 0); matrix.setZone(1, 1, 1); matrix.setZone(2, 2, 2); matrix.setZone(3, 3, 3);

// Set the intensity (brightness) of the display (0-15) // matrix.setIntensity(brightness-1); matrix.setIntensity(2);

// Clear the display matrix.displayClear();

//Setting up the zones on the led matrix //matrix.setFont(_seg7_fixed_medium); matrix.setFont(_seg7_fixed_small); matrix.setCharSpacing(0); //Set for all zones matrix.setCharSpacing(1, 1); matrix.setCharSpacing(2, 0); //Set special handling for zone 2 matrix.setCharSpacing(3, 1);

//Connect the zones to char buffer matrix.displayZoneText(0, szInnings, PA_LEFT, 0, 0, PA_PRINT, PA_NO_EFFECT ); //2 matrix.displayZoneText(1, szHome, PA_RIGHT, 0, 0, PA_PRINT, PA_NO_EFFECT ); //0 matrix.displayZoneText(2, szAway, PA_RIGHT, 0, 0, PA_PRINT, PA_NO_EFFECT ); //1 matrix.displayZoneText(3, szBrightness, PA_RIGHT, 0, 0, PA_PRINT, PA_NO_EFFECT ); //3

//Declare the buttons for input pinMode(INNINGUP, INPUT); debInningUp.attach(INNINGUP); debInningUp.interval(debWait); pinMode(INNINGDOWN, INPUT); debInningDown.attach(INNINGDOWN); debInningDown.interval(debWait); pinMode(HOMEUP, INPUT); debHomeUp.attach(HOMEUP); debHomeUp.interval(debWait); pinMode(HOMEDOWN, INPUT); debHomeDown.attach(HOMEDOWN); debHomeDown.interval(debWait); pinMode(AWAYUP, INPUT); debAwayUp.attach(AWAYUP); debAwayUp.interval(debWait); pinMode(AWAYDOWN, INPUT); debAwayDown.attach(AWAYDOWN); debAwayDown.interval(debWait); pinMode(OUTS, INPUT); debOuts.attach(OUTS); debOuts.interval(debWait); pinMode(BRIGHTNESSUP, INPUT); debBrightnessUp.attach(BRIGHTNESSUP); debBrightnessUp.interval(debWait); pinMode(BRIGHTNESSDOWN, INPUT); debBrightnessDown.attach(BRIGHTNESSDOWN); debBrightnessDown.interval(debWait); pinMode(RESET, INPUT); debReset.attach(RESET); debReset.interval(debWait);

//Initiate the led outputs pinMode(OUT1, OUTPUT); digitalWrite(OUT1, LOW); pinMode(OUT2, OUTPUT); digitalWrite(OUT2, LOW); pinMode(OUT3, OUTPUT); digitalWrite(OUT3, LOW);

//Set initial state of buttons to LOW debInningUp.setPressedState(LOW); debInningDown.setPressedState(LOW); debHomeUp.setPressedState(LOW); debHomeDown.setPressedState(LOW); debAwayUp.setPressedState(LOW); debAwayDown.setPressedState(LOW); debOuts.setPressedState(LOW); debBrightnessUp.setPressedState(LOW); debBrightnessDown.setPressedState(LOW); debReset.setPressedState(LOW);

Serial.begin(9600); }

void loop() { //Variables to handle which button has been clicked boolean pushInningUp = false; boolean pushInningDown = false; boolean pushHomeUp = false; boolean pushHomeDown = false; boolean pushAwayUp = false; boolean pushAwayDown = false; boolean pushOuts = false; boolean pushBrightnessUp = false; boolean pushBrightnessDown = false; boolean pushReset = false; boolean sendMsg = false;

//Update the buttons to get info about press debInningUp.update(); debInningDown.update(); debHomeUp.update(); debHomeDown.update(); debAwayUp.update(); debAwayDown.update(); debOuts.update(); debBrightnessUp.update(); debBrightnessDown.update(); debReset.update();

//Read if buttons has been pressed pushInningUp = debInningUp.pressed(); pushInningDown = debInningDown.pressed(); pushHomeUp = debHomeUp.pressed(); pushHomeDown = debHomeDown.pressed(); pushAwayUp = debAwayUp.pressed(); pushAwayDown = debAwayDown.pressed(); pushOuts = debOuts.pressed(); pushBrightnessUp = debBrightnessUp.pressed(); pushBrightnessDown = debBrightnessDown.pressed(); pushReset = debReset.pressed();

//Animate the matrixes matrix.displayAnimate();

//Setting the innings value if pressed INNINGUP (: means TOP and ; means BOTTOM) if (pushInningUp == HIGH) { //Clearing out the reset flag reset = false;

//Mark that change has been made
sendMsg = true;

//Setting inning logic
//In TOP moving to BOTTOM
if (inningPart == TOP) {
  inningPart = BOTTOM;

  //Push out new value
  sprintf(szInnings, ";%d", innings); 
}
else {
  //BOTTOM of 9th moving to overtime inning
  if (innings == 9) {
    innings = 0;
    inningPart = TOP;

    //Push out new value
    sprintf(szInnings, ":%d", innings); 
  }
  //Max innings, do not change
  else if (innings == 0) {
    innings = 0;
    inningPart = BOTTOM;

    //Push out new value
    sprintf(szInnings, ";%d", innings); 
  }
  //Increase inning and move to top
  else {
    innings++;
    inningPart = TOP;

    //Push out new value
    sprintf(szInnings, ":%d", innings); 
  }
};

//Update matrix
matrix.displayReset(0);

//Resets the outs
outs = 0;
lightOuts(outs);

};

//Setting the innings value if pressed INNINGUP (: means TOP and ; means BOTTOM) if (pushInningDown == HIGH) { //Clearing out the reset flag reset = false;

//Mark that change has been made
sendMsg = true;

//Setting inning logic
if (inningPart == TOP) {
  //No more lower innings
  if (innings == 1) {
    innings = 1;
    inningPart = TOP;

    //Push out new value
    sprintf(szInnings, ":%d", innings); 
  }
  //Top inning and should go to 9
  else if (innings == 0) {
    innings = 9;
    inningPart = BOTTOM;

    //Push out new value
    sprintf(szInnings, ";%d", innings); 
  }
  //Otherwise decrease inning and move to bottom
  else {
    innings--;
    inningPart = BOTTOM;

    //Push out new value
    sprintf(szInnings, ";%d", innings); 
  }
}
//Moving to TOP
else {
  inningPart = TOP;

  //Push out new value
  sprintf(szInnings, ":%d", innings); 
};

//Update matrix
matrix.displayReset(0);

//Resets the outs
outs = 0;
lightOuts(outs);

};

//Setting the home score value if (pushHomeUp == HIGH) { //Clearing out the reset flag reset = false;

//Mark that change has been made
sendMsg = true;

//Protect against to high number
if (homeScore < 29) {
  homeScore++;
}

//Push out new value
sprintf(szHome, "%d", homeScore);  

//Update matrix
matrix.displayReset(1);

};

//Setting the home score value if (pushHomeDown == HIGH) { //Clearing out the reset flag reset = false;

//Mark that change has been made
sendMsg = true;

//Protect against low value
if (homeScore > 0) {
  homeScore--;
}

//Push out new value
sprintf(szHome, "%d", homeScore);  

//Update matrix
matrix.displayReset(1);

};

//Setting the away score value if (pushAwayUp == HIGH) { //Clearing out the reset flag reset = false;

//Mark that change has been made
sendMsg = true;

//Protect against to high number
if (awayScore < 29) {
  awayScore++;
}

//Push out new value
sprintf(szAway, "%d", awayScore);  

//Update matrix
matrix.displayReset(2);

};

//Setting the away score value if (pushAwayDown == HIGH) { //Clearing out the reset flag reset = false;

//Mark that change has been made
sendMsg = true;

//Protect against to low number    
if (awayScore > 0) {
  awayScore--;
}

//Push out new value
sprintf(szAway, "%d", awayScore);  

//Update matrix
matrix.displayReset(2);

};

//Setting the outs value if (pushOuts == HIGH) { //Clearing out the reset flag reset = false;

//Mark that change has been made
sendMsg = true;

//Setting the number of outs and lighting the leds
switch (outs) {
  //First out
  case 0:
    outs = 1;
    break;
  //Second out
  case 1:
    outs = 2;
    break;
  //Third out
  case 2:
    outs = 3;
    break;
  //Clearing outs
  case 3:
    outs = 0;
    break;           
};

//Setting the number of outs and lighting the leds
lightOuts(outs);

};

//Setting the brightness value if (pushBrightnessUp == HIGH) { //Clearing out the reset flag reset = false;

//Mark that change has been made
sendMsg = true;

//Protect against to high number
if (brightness < 16) {
  brightness++;
}

//Push out new value
sprintf(szBrightness, "%d", brightness);  

//Update matrix
matrix.displayReset(3);

};

//Setting the home score value if (pushBrightnessDown == HIGH) { //Clearing out the reset flag reset = false;

//Mark that change has been made
sendMsg = true;

//Check for limit values
if (brightness > 1) {
  brightness--;
}

//Push out new value    
sprintf(szBrightness, "%d", brightness);  

//Update matrix
matrix.displayReset(3);

};

//Setting the reset values if (pushReset == HIGH) { if (reset == true) { //Mark that change has been made sendMsg = true;

  //Innings
  innings = 1;
  inningPart = TOP;
  sprintf(szInnings, ":%d", innings); 

  //Home score
  homeScore = 0;
  sprintf(szHome, "%d", homeScore);  

  //Away score
  awayScore = 0;
  sprintf(szAway, "%d", awayScore);  

  //Outs
  outs = 0;
  lightOuts(outs);

  //Brightness
  brightness = 4;
  sprintf(szBrightness, "%d", brightness);  

  //Update matrix
  matrix.displayReset(3);
} 
else {
   //Set flag to check double click
  reset = true;
}

}; }

//Function to handle the outs diods void lightOuts(int o) { //Setting the number of outs and lighting the leds switch (o) { //Clearing outs case 0: digitalWrite(OUT1, LOW); digitalWrite(OUT2, LOW); digitalWrite(OUT3, LOW); break; //First out case 1: digitalWrite(OUT1, HIGH); break; //Second out case 2: digitalWrite(OUT2, HIGH); break; //Third out case 3: digitalWrite(OUT3, HIGH); break;
}; } `

Wettemark commented 2 years ago

I have continued testing and on a Arduino UNO it works with my orignial program, the rewritten one and with a one where I tried to remove the zones and just use the displayText instead and not having zones.

But on the Arduino UNO WiFi Rev 2 card it will never display the right information in the last matrix of the chain...

MajicDesigns commented 2 years ago

But on the Arduino UNO WiFi Rev 2 card it will never display the right information in the last matrix of the chain

Just to be clear , do you mean matrix number 0 (first one nearest the arduino connection) or number 3 (further from the Arduino connection).

Wettemark commented 2 years ago

The matrix number 3.

Wettemark commented 2 years ago

Here is the pictures of how it looks like for me. One with the UNO and one with the UNO WiFi..

UNO WiFi UNO .

woeperbe commented 2 years ago

My question is why o why are you using this kind of displays if you need 4 digits ?

[image0.jpeg]

Greetings, Marc Buffet

On 1 Feb 2022, at 16:32, Wettemark @.***> wrote:



Here is the pictures of how it looks like for me. One with the UNO and one with the UNO WiFi..

[UNO WiFi]https://user-images.githubusercontent.com/86567230/151998503-08bdc2ee-4d6f-4cc0-85bb-4f74995f8be4.jpg [UNO]https://user-images.githubusercontent.com/86567230/151998512-85daff4b-45d4-43d7-af37-3633d65f5bea.jpg .

— Reply to this email directly, view it on GitHubhttps://github.com/MajicDesigns/MD_Parola/issues/97#issuecomment-1026974001, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AKXOBGPGA7UHKEAHT7OAE5TUY74HDANCNFSM5NEI6TZA. You are receiving this because you are subscribed to this thread.Message ID: @.***>

MajicDesigns commented 2 years ago

I really can't see what could be causing this. BTW, I see no 'Wifi' code in the code you posted, just straight out code to handle switches and the display.?

Have you tried one of the examples from the Parola library on the Uno Wifi board? Does it manage to display on the last module?