Go Down

Topic: display time on MAX7219 base matrix display ??? (Read 6008 times) previous topic - next topic

tolisn63

Dec 30, 2013, 06:01 pm Last Edit: Dec 30, 2013, 06:03 pm by tolisn63 Reason: 1
Hi
I'm trying to get a dox matrix that uses 6 matrix displays driven by MAX7219 chips to display the time.
My setup also includes an RTC based on PCF 8563. Everything is connected to an arduino Mega 2560.
So far I got the matrix to display a 3 line string of characters and the RTC time displayed in the serial monitor.
Can someone help so I can display the time on the matrix display ?
The code is below and is based on parola library and a code for the RTC that I found online.

Code: [Select]
// Program to demonstrate the MD_Parola library
//
// For every string defined by pc[] iterate through all combinations
// of entry and exit effects.
//

#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <Wire.h>
#include <Rtc_Pcf8563.h>

//init the real time clock
Rtc_Pcf8563 rtc;

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

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

#if USE_UI_CONTROL
#define SPEED_IN A0
#endif // USE_UI_CONTROL

#define PAUSE_TIME 1000
#define SPEED_DEADBAND 5
uint8_t frameDelay = 25; // default frame delay value


MD_Parola P = MD_Parola(DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);

#define SPEED_TIME 10
#define PAUSE_TIME 1000
#define PRINT(s, x)
#define PRINTS(x)
#define PRINTX(x)

// Global variables
uint8_t  curText;
char *pc[] =
{
 "This is",
 "Just a",
 "Test",
};

uint8_t  inFX, outFX;
MD_Parola::textEffect_t effect[] =
{
 MD_Parola::PRINT,
 MD_Parola::SCROLL_LEFT,
 MD_Parola::WIPE,
 MD_Parola::SCROLL_UP,
 MD_Parola::OPENING_CURSOR,
 MD_Parola::BLINDS,
 MD_Parola::CLOSING,
 MD_Parola::WIPE_CURSOR,
 MD_Parola::DISSOLVE,
 MD_Parola::OPENING,
 MD_Parola::CLOSING_CURSOR,
 MD_Parola::SCROLL_RIGHT,
 MD_Parola::SCROLL_DOWN,
 MD_Parola::SLICE,
};


void setup(void)
{
 Serial.begin(57600);
 
 //clear out the registers
 //rtc.initClock();
 //set a time to start with.
 
 //day, weekday, month, century(1=1900, 0=2000), year(0-99)
 // uncomment to set
 //rtc.setDate(30, 1, 12, 0, 13);
 
 //hr, min, sec
 //uncomment to set
 //rtc.setTime(18, 42, 0);

 P.begin();
 P.setInvert(false);
 P.displayText(pc[curText], MD_Parola::CENTER, SPEED_TIME, PAUSE_TIME, effect[inFX], effect[outFX]);
}

void loop(void)
{
   Serial.print(rtc.formatTime());
   Serial.print("\r\n");
   
   
 if (P.displayAnimate()) // animates and returns true when an animation is completed
 {
   // Set the display for the next string.
   curText = (++curText) % ARRAY_SIZE(pc);
   P.setTextBuffer(pc[curText]);

   // When we have gone back to the first string, set a new exit effect
   // and when we have done all those set a new entry effect.
   if (curText == 0)
   {
     outFX = (++outFX) % ARRAY_SIZE(effect);
     if (outFX == 0)
 {
       inFX = (++inFX) % ARRAY_SIZE(effect);
if (inFX == 0)
P.setInvert(!P.getInvert());
 }
       
     P.setTextEffect(effect[inFX], effect[outFX]);
   }

   // Tell Parola we have a new animation
   P.displayReset();
 }
}

marco_c

#1
Dec 30, 2013, 08:46 pm Last Edit: Dec 30, 2013, 08:50 pm by marco_c Reason: 1
The code you have there is from the demo to show the different text effects, so you will get a whole lot of different in and out text. I am assuming that you managed to get the display of the test message working ok?

This only just displays the date & time to the serial monitor (why didn't you use Serial.println(), by the way?)
Code: [Select]
    Serial.print(rtc.formatTime());

You actually need to strcpy() the date and time to a character buffer (array of characters) and then pass that to the Parola library for display, instead of the test message. The rest should work ok.

You may want to consider showing the date on one pass of the display and the time on the next display (like the test code shows the sentence split up).
Arduino Libraries https://github.com/MajicDesigns?tab=Repositories
Parola for Arduino https://github.com/MajicDesigns/Parola
Arduino++ blog https://arduinoplusplus.wordpress.com

tolisn63

Hi Marco

Can you help me out on this, my coding skills are very limited ?

marco_c

#3
Dec 30, 2013, 09:13 pm Last Edit: Dec 30, 2013, 09:19 pm by marco_c Reason: 1
I don't have your RTC library and have not compiled tested this code, but it should display whatever was in the serial printout.

Code: [Select]

//
// Display current date and time using Parola library
//

#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <Wire.h>
#include <Rtc_Pcf8563.h>

//init the real time clock
Rtc_Pcf8563 rtc;

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

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

#if USE_UI_CONTROL
#define SPEED_IN A0
#endif // USE_UI_CONTROL

#define PAUSE_TIME 1000
#define SPEED_DEADBAND 5
uint8_t frameDelay = 25; // default frame delay value


MD_Parola P = MD_Parola(DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);

#define SPEED_TIME 10
#define PAUSE_TIME 1000

// Global variables
char szDateTime[20] = {""};

uint8_t  inFX, outFX;
MD_Parola::textEffect_t effect[] =
{
  MD_Parola::PRINT,
  MD_Parola::SCROLL_LEFT,
  MD_Parola::WIPE,
  MD_Parola::SCROLL_UP,
  MD_Parola::OPENING_CURSOR,
  MD_Parola::BLINDS,
  MD_Parola::CLOSING,
  MD_Parola::WIPE_CURSOR,
  MD_Parola::DISSOLVE,
  MD_Parola::OPENING,
  MD_Parola::CLOSING_CURSOR,
  MD_Parola::SCROLL_RIGHT,
  MD_Parola::SCROLL_DOWN,
  MD_Parola::SLICE,
};


void setup(void)
{
  Serial.begin(57600);
 
  //clear out the registers
  //rtc.initClock();
  //set a time to start with.
 
  //day, weekday, month, century(1=1900, 0=2000), year(0-99)
  // uncomment to set
  //rtc.setDate(30, 1, 12, 0, 13);
 
  //hr, min, sec
  //uncomment to set
  //rtc.setTime(18, 42, 0);

  P.begin();
  P.setInvert(false);
  P.displayText(szDateTime, MD_Parola::CENTER, SPEED_TIME, PAUSE_TIME, effect[inFX], effect[outFX]);
}

void loop(void)
{
  if (P.displayAnimate()) // animates and returns true when an animation is completed
  {
  strcpy(szDateTime, rtc.formatTime());
   P.setTextBuffer(szDateTime);

    outFX = (++outFX) % ARRAY_SIZE(effect);
    if (outFX == 0)
    {
      inFX = (++inFX) % ARRAY_SIZE(effect);
      if (inFX == 0)
P.setInvert(!P.getInvert());
    }
       
    P.setTextEffect(effect[inFX], effect[outFX]);

    // Tell Parola we have a new animation
    P.displayReset();
  }
}

Arduino Libraries https://github.com/MajicDesigns?tab=Repositories
Parola for Arduino https://github.com/MajicDesigns/Parola
Arduino++ blog https://arduinoplusplus.wordpress.com

tolisn63

Marco, your example works ok but it only shows the time. Is there any way to show text and then the time and then again the text ?

marco_c

Sure there is. What exactly are you trying to achieve?
Arduino Libraries https://github.com/MajicDesigns?tab=Repositories
Parola for Arduino https://github.com/MajicDesigns/Parola
Arduino++ blog https://arduinoplusplus.wordpress.com

tolisn63

Im trying to acheive the following.
Type in a required text,then the matrix shows the text. When the text is finished, the time is shown.when the time is finished the text is shown again and the cycle repeats.


marco_c

Same caveats as before.

Code: [Select]
//
// Display text on the matrix followed by the time and the cycle repeats.
//

#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <Wire.h>
#include <Rtc_Pcf8563.h>

//init the real time clock
Rtc_Pcf8563 rtc;

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

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

#if USE_UI_CONTROL
#define SPEED_IN A0
#endif // USE_UI_CONTROL

#define PAUSE_TIME 1000
#define SPEED_DEADBAND 5
uint8_t frameDelay = 25; // default frame delay value

MD_Parola P = MD_Parola(DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);

#define SPEED_TIME 10
#define PAUSE_TIME 1000

// Global variables
uint8_t  curText;
char  szDateTime[20];
char *pc[] =
{
  "This is",
  "Just a",
  "Test",
  szDateTime,
};

uint8_t  inFX, outFX;
MD_Parola::textEffect_t effect[] =
{
  MD_Parola::PRINT,
  MD_Parola::SCROLL_LEFT,
  MD_Parola::WIPE,
  MD_Parola::SCROLL_UP,
  MD_Parola::OPENING_CURSOR,
  MD_Parola::BLINDS,
  MD_Parola::CLOSING,
  MD_Parola::WIPE_CURSOR,
  MD_Parola::DISSOLVE,
  MD_Parola::OPENING,
  MD_Parola::CLOSING_CURSOR,
  MD_Parola::SCROLL_RIGHT,
  MD_Parola::SCROLL_DOWN,
  MD_Parola::SLICE,
};


void setup(void)
{
  Serial.begin(57600);
 
  //clear out the registers
  //rtc.initClock();
  //set a time to start with.
 
  //day, weekday, month, century(1=1900, 0=2000), year(0-99)
  // uncomment to set
  //rtc.setDate(30, 1, 12, 0, 13);
 
  //hr, min, sec
  //uncomment to set
  //rtc.setTime(18, 42, 0);

  P.begin();
  P.setInvert(false);
  P.displayText(pc[curText], MD_Parola::CENTER, SPEED_TIME, PAUSE_TIME, effect[inFX], effect[outFX]);
}

void loop(void)
{
  if (P.displayAnimate()) // animates and returns true when an animation is completed
  {
    strcpy(szDateTime, rtc.formatTime());
   
    // Set the display for the next string.
    curText = (++curText) % ARRAY_SIZE(pc);
    P.setTextBuffer(pc[curText]);

    // When we have gone back to the first string, set a new exit effect
    // and when we have done all those set a new entry effect.
    if (curText == 0)
    {
      outFX = (++outFX) % ARRAY_SIZE(effect);
      if (outFX == 0)
  {
        inFX = (++inFX) % ARRAY_SIZE(effect);
if (inFX == 0)
P.setInvert(!P.getInvert());
  }
       
      P.setTextEffect(effect[inFX], effect[outFX]);
    }

    // Tell Parola we have a new animation
    P.displayReset();
  }
}

Arduino Libraries https://github.com/MajicDesigns?tab=Repositories
Parola for Arduino https://github.com/MajicDesigns/Parola
Arduino++ blog https://arduinoplusplus.wordpress.com

tolisn63

Now it is working as required. Thanks for your help, much appreciated.
As a next step, I will try to add bluetooth input to add the text.

marco_c

When you do that you will need to change the strings from constants to character arrays, like for the datetime.

Good luck.
Arduino Libraries https://github.com/MajicDesigns?tab=Repositories
Parola for Arduino https://github.com/MajicDesigns/Parola
Arduino++ blog https://arduinoplusplus.wordpress.com

tolisn63

Hi,
Here is a new code that shows the time, date and reads the serial input so it can print a message. The problem is that the message is too long and cannot be displayed on the matrix. Only a part of it is displayed.
How do I go about showing all the message ?
Code: [Select]
//
// Display text on the matrix followed by the time and the cycle repeats.
//

#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <Wire.h>
#include <Rtc_Pcf8563.h>

//init the real time clock
Rtc_Pcf8563 rtc;

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

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

#if USE_UI_CONTROL
#define SPEED_IN A0
#endif // USE_UI_CONTROL

#define PAUSE_TIME 1000
#define SPEED_DEADBAND 5
uint8_t frameDelay = 25; // default frame delay value

MD_Parola P = MD_Parola(DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);

#define SPEED_TIME 10
#define PAUSE_TIME 1000

// Global message buffers shared by Serial and Scrolling functions
#define BUF_SIZE 75
char curMessage[BUF_SIZE];
char newMessage[BUF_SIZE];
bool newMessageAvailable = false;

void readSerial(void)
{
static uint8_t putIndex = 0;

while (Serial1.available())
{
newMessage[putIndex] = (char)Serial1.read();
if ((newMessage[putIndex] == '\n') || (putIndex >= BUF_SIZE-3)) // end of message character or full buffer
{
// put in a message separator and end the string
newMessage[putIndex++] = ' ';
newMessage[putIndex] = '\0';
// restart the index for next filling spree and flag we have a message waiting
putIndex = 0;
                       strcpy(curMessage, newMessage); // copy it in
       
}
else
// Just save the next char in next location
newMessage[putIndex++];
}
}

// Global variables
uint8_t  curText;
char  szTime[9];
char  szDate[11];
char  szYear[5];
char *pc[] =
{
 "The Time",
 "is",
 szTime,
 "The Date",
 "is",
 szDate,
 szYear,
 curMessage,
};

uint8_t  inFX, outFX;
MD_Parola::textEffect_t effect[] =
{
 MD_Parola::PRINT,
 MD_Parola::SCROLL_LEFT,
 MD_Parola::WIPE,
 MD_Parola::SCROLL_UP,
 MD_Parola::OPENING_CURSOR,
 MD_Parola::BLINDS,
 MD_Parola::CLOSING,
 MD_Parola::WIPE_CURSOR,
 MD_Parola::DISSOLVE,
 MD_Parola::OPENING,
 MD_Parola::CLOSING_CURSOR,
 MD_Parola::SCROLL_RIGHT,
 MD_Parola::SCROLL_DOWN,
 MD_Parola::SLICE,
};


void setup(void)
{
 Serial.begin(9600);
 Serial1.begin(9600); //bluesmirf default baud rate=9600
 
 //clear out the registers
 //rtc.initClock();
 //set a time to start with.
 
 //day, weekday, month, century(1=1900, 0=2000), year(0-99)
 // uncomment to set
 //rtc.setDate(2, 3, 1, 0, 14);
 
 //hr, min, sec
 //uncomment to set
 //rtc.setTime(13, 35, 0);

 P.begin();
 P.setInvert(false);
 P.displayText(pc[curText], MD_Parola::CENTER, SPEED_TIME, PAUSE_TIME, effect[inFX], effect[outFX]);
}

void loop(void)


{
  readSerial(); // read serial input
 
 if (P.displayAnimate()) // animates and returns true when an animation is completed
 {
   strcpy(szTime, rtc.formatTime()); //gets the complete time and stores the complete time in format 23:30:54
   strncpy(szDate, rtc.formatDate(RTCC_DATE_WORLD),5); //Gets the complete date in the format 15/12/2013 and stores only
   //the day and date in the format 15/12
   strncpy(szYear,&rtc.formatDate(RTCC_DATE_WORLD)[6],4); //Gets the complete date in the format 15/12/2013
   //and stores only the year in the format 2014
   
   // Set the display for the next string.
   curText = (++curText) % ARRAY_SIZE(pc);
   P.setTextBuffer(pc[curText]);

   // When we have gone back to the first string, set a new exit effect
   // and when we have done all those set a new entry effect.
   if (curText == 0)
   {
     outFX = (++outFX) % ARRAY_SIZE(effect);
     if (outFX == 0)
 {
       inFX = (++inFX) % ARRAY_SIZE(effect);
if (inFX == 0)
P.setInvert(false);
 }
       
     P.setTextEffect(effect[inFX], effect[outFX]);
   }

   // Tell Parola we have a new animation
   P.displayReset();
 }
}

marco_c

The software can scroll the message onto the screen so someone looking can read it. If that is not good enough then get a bigger matrix or make shorter messages.
Arduino Libraries https://github.com/MajicDesigns?tab=Repositories
Parola for Arduino https://github.com/MajicDesigns/Parola
Arduino++ blog https://arduinoplusplus.wordpress.com

tolisn63

As the code is now, If I type in a message "Hello Arduino" all I can see is a message "Hello Ard". The rest is cut. When the message scrolls not all the message is shown but only "Hello Ard"

marco_c

1. Check (by printing) that the message is what you think it is.
2. Set the animation to just scrolling and see if the message appears.

You are either cutting off the message in the buffer or you are not displaying the whole thing. No other possibilities that I can see.
Arduino Libraries https://github.com/MajicDesigns?tab=Repositories
Parola for Arduino https://github.com/MajicDesigns/Parola
Arduino++ blog https://arduinoplusplus.wordpress.com

tolisn63

#14
Jan 26, 2014, 01:19 pm Last Edit: Jan 26, 2014, 01:20 pm by tolisn63 Reason: 1
Hi
I have add some code to the sketch that uses a I2C temperature sensor to read the temperature.
The code as it it shows the temperature using the serial monitor.
How can I send the temperature reading to the matrix ?

Code: [Select]
//
// Display text on the matrix followed by the time and the cycle repeats.
//

#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <Wire.h>
#include <Rtc_Pcf8563.h>

//init the real time clock
Rtc_Pcf8563 rtc;

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

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

#if USE_UI_CONTROL
#define SPEED_IN A0
#endif // USE_UI_CONTROL

#define PAUSE_TIME 1000
#define SPEED_DEADBAND 5
uint8_t frameDelay = 25; // default frame delay value

MD_Parola P = MD_Parola(DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);

#define SPEED_TIME 10
#define PAUSE_TIME 1000

// Global message buffers shared by Serial and Scrolling functions
#define BUF_SIZE 100
char curMessage[BUF_SIZE];
char newMessage[BUF_SIZE];
bool newMessageAvailable = false;
int tmpAddress = B1001000;
int ResolutionBits = 10;

void readSerial(void)
{
  static uint8_t putIndex = 0;

  while (Serial1.available())
  {
    newMessage[putIndex] = (char)Serial1.read();
    if ((newMessage[putIndex] == '\n') || (putIndex >= BUF_SIZE-3)) // end of message character or full buffer
    {
      // put in a message separator and end the string
      newMessage[putIndex++] = ' ';
      newMessage[putIndex] = '\0';
      // restart the index for next filling spree and flag we have a message waiting
      putIndex = 0;
      strcpy(curMessage, newMessage); // copy it in

    }
    else
      // Just save the next char in next location
      newMessage[putIndex++];
  }
}

// Global variables
uint8_t  curText;
char  szTime[9];
char  szDate[11];
char  szYear[5];
char *pc[] =
{
  "The Time",
  "is",
  szTime,
  "The Date",
  "is",
  szDate,
  szYear,
  curMessage,
};

uint8_t  inFX, outFX;
MD_Parola::textEffect_t effect[] =
{
  //  MD_Parola::PRINT,
  MD_Parola::SCROLL_LEFT,
  //  MD_Parola::WIPE,
  //  MD_Parola::SCROLL_UP,
  //  MD_Parola::OPENING_CURSOR,
  //  MD_Parola::BLINDS,
  //  MD_Parola::CLOSING,
  //  MD_Parola::WIPE_CURSOR,
  //  MD_Parola::DISSOLVE,
  //  MD_Parola::OPENING,
  //  MD_Parola::CLOSING_CURSOR,
  //  MD_Parola::SCROLL_RIGHT,
  //  MD_Parola::SCROLL_DOWN,
  //  MD_Parola::SLICE,
};

float getTemperature(){
  Wire.requestFrom(tmpAddress,2);
  byte MSB = Wire.read();
  byte LSB = Wire.read();

  int TemperatureSum = ((MSB << 8) | LSB) >> 4;

  float celsius = TemperatureSum*0.0625;

  Serial.print("Celsius: ");
  Serial.println(celsius);

}
void SetResolution(){
  if (ResolutionBits < 9 || ResolutionBits > 12) exit;
  Wire.beginTransmission(tmpAddress);
  Wire.write(B00000001); //addresses the configuration register
  Wire.write((ResolutionBits-9) << 5); //writes the resolution bits
  Wire.endTransmission();

  Wire.beginTransmission(tmpAddress); //resets to reading the temperature
  Wire.write((byte)0x00);
  Wire.endTransmission();
}



void setup(void)
{
  Serial.begin(9600);
  Serial1.begin(9600); //bluesmirf default baud rate=9600
  SetResolution();

  //clear out the registers
  //rtc.initClock();
  //set a time to start with.

  //day, weekday, month, century(1=1900, 0=2000), year(0-99)
  // uncomment to set
  //rtc.setDate(2, 3, 1, 0, 14);

  //hr, min, sec
  //uncomment to set
  //rtc.setTime(13, 35, 0);

  P.begin();
  P.setInvert(false);
  P.displayText(pc[curText], MD_Parola::CENTER, SPEED_TIME, PAUSE_TIME, effect[inFX], effect[outFX]);
}

void loop(void)


{
  getTemperature();

  readSerial(); // read serial input

  if (P.displayAnimate()) // animates and returns true when an animation is completed
  {
    strcpy(szTime, rtc.formatTime()); //gets the complete time and stores the complete time in format 23:30:54
    strncpy(szDate, rtc.formatDate(RTCC_DATE_WORLD),5); //Gets the complete date in the format 15/12/2013 and stores only
    //the day and date in the format 15/12
    strncpy(szYear,&rtc.formatDate(RTCC_DATE_WORLD)[6],4); //Gets the complete date in the format 15/12/2013
    //and stores only the year in the format 2014

      // Set the display for the next string.
    curText = (++curText) % ARRAY_SIZE(pc);
    P.setTextBuffer(pc[curText]);

    // When we have gone back to the first string, set a new exit effect
    // and when we have done all those set a new entry effect.
    if (curText == 0)
    {
      outFX = (++outFX) % ARRAY_SIZE(effect);
      if (outFX == 0)
      {
        inFX = (++inFX) % ARRAY_SIZE(effect);
        if (inFX == 0)
          P.setInvert(false);
      }

      P.setTextEffect(effect[inFX], effect[outFX]);
    }

    // Tell Parola we have a new animation
    P.displayReset();
  }


}


Go Up