LED matrix display - MD_Parola, MD_MAX72xx and MD_MAXPanel

There is no way that it will switch between the temperature and humidity as the display variable never changes value. According to this code, it will always just show temperature. When you do a displayReset() is a good time to change the message

  if (P.displayAnimate())
  {
    display = (display + 1) % 2;
    switch (display)
    {
      case 0: // Temperature deg C
        dtostrf(h, 3, 0, szMesg);
        strcat(szMesg, " %");
        break;

      case 1: // Relative Humidity %
        dtostrf(t, 3, 1, szMesg);
        strcat(szMesg, " $");
        break;
    }

    P.displayReset();
  }

Thank you Marco! It works fine now:

static uint8_t  display = 0;  // current display mode
  if (P.displayAnimate()) {

    switch (display)
    {
      case 0:
        //P.setTextEffect(0, PA_SCROLL_DOWN, PA_SCROLL_DOWN);
        display++;
        dtostrf(h, 3, 0, szMesg);
        strcat(szMesg, " %");
        break;

      case 1:
        //P.setTextEffect(0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
        display = 0;
        dtostrf(t, 3, 1, szMesg);
        strcat(szMesg, " $");
        break;

    }
    P.displayReset();
  }

Hi, I'm using this code for monitoring Bitcoin price, but the scrolling effect is too slow. Could you help me to get more speed, please?

//PARTE BITCOIN TICKER
#include <Arduino.h>

#include <ArduinoJson.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>

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

const uint16_t WAIT_TIME = 1000;

// 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::FC16_HW
#define MAX_DEVICES 4
#define CLK_PIN   D5
#define DATA_PIN  D7
#define CS_PIN    D2
#define MAX_MESG  20
// Hardware SPI connection
MD_Parola P = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
// Arbitrary output pins
// MD_Parola P = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);
const char* ssid = "xx";
const char* password = "xx";
const char* host = "api.coindesk.com";

float previousValue = 0.00;
float threshold = 0.05;
// SOFTWARE SPI
//MD_Parola P = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);




uint8_t scrollSpeed = 10;    // default frame delay value
textEffect_t scrollEffect = PA_SCROLL_LEFT;
textPosition_t scrollAlign = PA_LEFT;
uint16_t scrollPause = 1000; // in milliseconds
char szMesg[MAX_MESG + 1] = "";




void setup()
{
  pinMode(D3, OUTPUT); //Price down
  pinMode(D4, OUTPUT); //Price up
 
 
  Serial.begin(115200);               
  delay(10);

  WiFi.begin(ssid, password);

  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  P.begin();
  P.displayText(szMesg, scrollAlign, scrollSpeed, scrollPause, scrollEffect, scrollEffect);

//  P.addChar('

, degC);
}

void loop() {

// Connect to API
  Serial.print("connecting to ");
  Serial.println(host);

// Use WiFiClient class to create TCP connections
  WiFiClient client;
  const int httpPort = 80;
  if (!client.connect(host, httpPort)) {
    Serial.println("connection failed");
    return;
  }

// We now create a URI for the request
  String url = "/v1/bpi/currentprice.json";

Serial.print("Requesting URL: ");
  Serial.println(url);

// This will send the request to the server
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
              "Host: " + host + "\r\n" +
              "Connection: close\r\n\r\n");
  delay(500); //geändert von 100

// Read all the lines of the reply from server and print them to Serial
  String answer;
  while(client.available()){
    String line = client.readStringUntil('\r');
    answer += line;
  }

client.stop();
  Serial.println();
  Serial.println("closing connection");

// Process answer
  Serial.println();
  Serial.println("Answer: ");
  Serial.println(answer);

// Convert to JSON
  String jsonAnswer;
  int jsonIndex;

for (int i = 0; i < answer.length(); i++) {
    if (answer[i] == '{') {
      jsonIndex = i;
      break;
    }
  }

// Get JSON data
  jsonAnswer = answer.substring(jsonIndex);
  Serial.println();
  Serial.println("JSON answer: ");
  Serial.println(jsonAnswer);
  jsonAnswer.trim();

// Get rate as float
  int rateIndex = jsonAnswer.indexOf("rate_float");
  String priceString = jsonAnswer.substring(rateIndex + 12, rateIndex + 18);
  priceString.trim();
  float price = priceString.toFloat();

// Print price
  Serial.println();
  Serial.println("Bitcoin price: ");
  Serial.println(price);

dtostrf(price, 3, 0, szMesg);
      strcat(szMesg, " $");

if (P.displayAnimate())
  {
    P.displayReset();
  }

}

You cannot have delay() in your loop() or any code that is called from your loop() because it blocks everything else from running.

You need to call the displayAnimate() function many times (really, every time through loop()) while you want the animation to happen as it checks the timer to see if it needs to move anything. This is covered in this blog article Parola A to Z – Frequently Asked Issues – Arduino++.

To code your application, you will need to change your application coding style to be more aligned to Finite State Machine principles (see this other blog for an explanation Finite State Machine Programming Basics – Part 1 – Arduino++ or many other sources online).

Hello,

Before asking for help about the following issue, I have searched online and this forum for a solution but have not found any addressing the issue herein.

I use this example code with the FC-16 variant of the LED matrix modules . . .

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

const uint16_t WAIT_TIME = 1000;


#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 4

#define CLK_PIN   13
#define DATA_PIN  11
#define CS_PIN    10

MD_Parola P = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);

void setup(void)
{
  P.begin();
  P.setIntensity(1);
}

void loop(void)
{
  P.print("HOME");
  delay(WAIT_TIME);
  P.print("OUT");
  delay(WAIT_TIME);
   
}

However, the function P.setIntensity() has no influence on the display. The display just stays at one very bright level of brightness.

The function seems also not to work with the "Generic" hardware variant but there is some control with with the "Parola" variant of the matrix modules.

I've coded much more sophisticated projects than the simple example from above but it's now become necessary to find a solution to the brightness (intensity) issue as I will be using these modules inside and in low light settings. I kept the code simple above as this applies even in densely coded scripts on more sophisticated projects where I've used the Parola library to express display information.

I'm reluctant to post a request for help as it seems such a trivial matter and one which I feel I'm obviously missing something and therefore wasting everyone's time. Yet this issue is pressing as it's difficult to look at the display without it becoming uncomfortable on the eyes, let alone ambient light in the room when working at night.

Thank you in advance.

Check the datasheet for the MAX7219. It discusses a resistor Rset and they give values for what it should be for certain current in the LEDs. Most of the modules sold have a value of 10k ohm which is way too low and does not allow for much brightness changes (ie, the LEDs are too bright ALL the time). You can also get some info from this blog post MAX7219 and LED matrix power requirements – Arduino++.

The only solution is to replace the resistor.

Thank you, Marco.

I'd anticipated this and ordered a stack of SMD resistors a couple of months ago, to alter each modules' current limiting parameter physically.

I'd rather hoped I'd missed something in the software but I guess that was wishful thinking.

I've no problem working with SMD's, it's just that there are so many in a long chain of these modules!

Auch well, out with the solder!

All the best.

M.

Hi Marco
Parola scrolling uploaded ok
Hello! Enter new message? is scrolling
Using HC05 Bluetooth module . This is paired successfully with my laptop.
Not sure if I’ve used correct pins on the UNO TXD on HC05 to Pin 0 (RX), RXD to Pin 1 ( TXD) at the moment
Standard Serial over Bluetooth link (COM8) and ( COM 9) showing in device manager.
Going into serial monitor with external power connected to arduino COM 8 appears at the top..
1/ Is there something else that needs to be added to the sketch to enable me to change the scrolling message from the serial monitor?
2/ Is there a special way that I have to enter the text in the serial monitor?
I have used arduinos successfully before ( not a coder - just a plug and play man!!) but this project is driving me mad as I feel I am so close to success.
Help please!

@Ryme_Extrinseca, Strangely enough, I'm using FC-16 modules with the function P.setIntensity() working just fine. Some of my modules are with 10k resistor, some with 47k. Regulating the brightness with LDR is working, but I have to figure out how to add some hysteresis...

Not sure if I've used correct pins on the UNO TXD on HC05 to Pin 0 (RX), RXD to Pin 1 ( TXD)

BT RX to Arduino TX and BT TX to Arduino RX (ie, Rx/Tx crossed over). Also you should be aware that the HC05 is a 3.3V signal and you should be providing a voltage converter or voltage divider for the signals going from the Arduino to the BT module. Lots on the web about this, so look it up.

1/ Is there something else that needs to be added to the sketch to enable me to change the scrolling message from the serial monitor?

Probably not if you are connected to the hardware serial. Does the BT module pair up properly? Have you tested with Arduino code to just echo what is being sent from the remote application to test the link works ok?

2/ Is there a special way that I have to enter the text in the serial monitor?

Make sure that the serial link speed rate is matched between the two ends of the link and that line ending from the sending application is set for a newline or it will not detect the end of the message.

Hello MArco!
I'm already read entire post, but still I don't know, where I wrong. Mentioned examples looks good, compiler not show any errors or warnings, but display show random characters :confused:
In example:

void dspl_tm() {
  String STime = hh + ":" + mm;
  char caTime[STime.length()];
  STime.toCharArray(caTime,STime.length()+1);
  P.displayText(caTime, PA_CENTER, 1, 0, PA_PRINT, PA_NO_EFFECT);
  Serial.println(STime);
}

Compilation is OK, programing too. In serial port I receive correct values, but in MAX display I see 5 random characters. Whan I change line to:

P.displayText("Test", PA_CENTER, 1, 0, PA_PRINT, PA_NO_EFFECT);

everything looks fine. I have not any idea, Maybe some hint, what is wrong?

Thanks in advance!

Kris

Your variable caTime is going out of scope and the buffer is being overwritten by random data. Either make it global scope or declared static in the function.

Perfect! It works fine! Thank you!
I declared as you suggest (global), it was sufficient to achieve wanted effect.
It is my very "calm" clock - no flasher, minimum animate :wink:

Thank you very much!

Kris

Hi Marco,
I have a suggestion for improve your excellent md_parola library.
In the mesh effect you can add the possibility of doing it horizontally and also with
variable acceleration / deceleration? in my opinion, it would be a nice effect.
thanks and congratulations for your work.

Please I'm still having issues to get the font work on MD Parola help me?

You are going to have to provide more specific details about your problem if you want help. You could read the library documentation for MD_Parola and MD_MAX72xx (in the docs folder of the libraries on your system), or the blog articles at Arduino++ – Arduino, CNC, software and other ramblings (search for "Parola A to Z").

I want to change the font of this strolling text but I haven't made any progress on it.i have tried several times. Can you assist me please?

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

// set to 1 if we are implementing the user interface pot, switch, etc
#define USE_UI_CONTROL 0

#if USE_UI_CONTROL
#include <MD_UISwitch.h>
#endif

// Turn on debug statements to the serial output
#define DEBUG 0

#if DEBUG
#define PRINT(s, x) { Serial.print(F(s)); Serial.print(x); }
#define PRINTS(x) Serial.print(F(x))
#define PRINTX(x) Serial.println(x, HEX)
#else
#define PRINT(s, x)
#define PRINTS(x)
#define PRINTX(x)
#endif

// 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 11
#define CLK_PIN   13
#define DATA_PIN  11
#define CS_PIN    10

// HARDWARE SPI
MD_Parola P = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
// SOFTWARE SPI
//MD_Parola P = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);

// Scrolling parameters
#if USE_UI_CONTROL
const uint8_t SPEED_IN = A5;
const uint8_t DIRECTION_SET = 8;  // change the effect
const uint8_t INVERT_SET = 9;     // change the invert

const uint8_t SPEED_DEADBAND = 5;
#endif // USE_UI_CONTROL

uint8_t scrollSpeed = 25;    // default frame delay value
textEffect_t scrollEffect = PA_SCROLL_LEFT;
textPosition_t scrollAlign = PA_LEFT;
uint16_t scrollPause = 2000; // in milliseconds

// Global message buffers shared by Serial and Scrolling functions
#define	BUF_SIZE	75
char curMessage[BUF_SIZE] = { "" };
char newMessage[BUF_SIZE] = { "Hello! Enter new message?" };
bool newMessageAvailable = true;

#if USE_UI_CONTROL

MD_UISwitch_Digital uiDirection(DIRECTION_SET);
MD_UISwitch_Digital uiInvert(INVERT_SET);

void doUI(void)
{
  // set the speed if it has changed
  {
    int16_t speed = map(analogRead(SPEED_IN), 0, 1023, 10, 150);

    if ((speed >= ((int16_t)P.getSpeed() + SPEED_DEADBAND)) ||
      (speed <= ((int16_t)P.getSpeed() - SPEED_DEADBAND)))
    {
      P.setSpeed(speed);
      scrollSpeed = speed;
      PRINT("\nChanged speed to ", P.getSpeed());
    }
  }

  if (uiDirection.read() == MD_UISwitch::KEY_PRESS) // SCROLL DIRECTION
  {
    PRINTS("\nChanging scroll direction");
    scrollEffect = (scrollEffect == PA_SCROLL_LEFT ? PA_SCROLL_RIGHT : PA_SCROLL_LEFT);
    P.setTextEffect(scrollEffect, scrollEffect);
    P.displayClear();
    P.displayReset();
  }

  if (uiInvert.read() == MD_UISwitch::KEY_PRESS)  // INVERT MODE
  {
    PRINTS("\nChanging invert mode");
    P.setInvert(!P.getInvert());
  }
}
#endif // USE_UI_CONTROL

void readSerial(void)
{
  static char *cp = newMessage;

  while (Serial.available())
  {
    *cp = (char)Serial.read();
    if ((*cp == '\n') || (cp - newMessage >= BUF_SIZE-2)) // end of message character or full buffer
    {
      *cp = '\0'; // end the string
      // restart the index for next filling spree and flag we have a message waiting
      cp = newMessage;
      newMessageAvailable = true;
    }
    else  // move char pointer to next position
      cp++;
  }
}

void setup()
{
  Serial.begin(57600);
  Serial.print("\n[Parola Scrolling Display]\nType a message for the scrolling display\nEnd message line with a newline");

#if USE_UI_CONTROL
  uiDirection.begin();
  uiInvert.begin();
  pinMode(SPEED_IN, INPUT);

  doUI();
#endif // USE_UI_CONTROL

  P.begin();
  P.displayText(curMessage, scrollAlign, scrollSpeed, scrollPause, scrollEffect, scrollEffect);
}

void loop()
{
#if USE_UI_CONTROL
  doUI();
#endif // USE_UI_CONTROL

  if (P.displayAnimate())
  {
    if (newMessageAvailable)
    {
      strcpy(curMessage, newMessage);
      newMessageAvailable = false;
    }
    P.displayReset();
  }
  readSerial();
}
  1. Please post code properly. You can read how to do this in the sicky note at the start of each forum (use the </> from the edit menu).
  2. Have you looked at the font examples in the library to see how it is done? Parola_Fonts is a good place to start, or Parola_UTF-8_display for non ASCII characters.
  3. Have you created/found new font data that you want to use?

Maybe also describe why you are trying to change the font, as it may not be the way to solve whatever problem you think you are having.

Okay.
I have a font that makes text bold but after applying it yet it still doesn't work. I don't know if I'm supposed to add anything in the code I posted above?
Firstly I created a new tab with the font inside it then call it out on the Parola tab.
#include "Font_bold.h"
But when I upload it into the arduino board I still get the default font in the strolling text.

So I am guessing that you have not read the documentation or looked at the examples for the library, as suggested.