Here are found the blank, you need to check how it works
/*
  PROJECT: MySensors / Scrolling Text display
  PROGRAMMER: AWI
  DATE: september 12, 2015/ last update: september 12, 2015
  FILE: AWI_scroll_MAX.ino
  LICENSE: Public domain
  Hardware: tbd ..Ceech - ATmega328p board w/ NRF24l01
    and MySensors 1.5 ()
  Special:
    Need to use MySensors development edition
  SUMMARY:
    3 S_xx devices for scrolling text
    - Displays a scrolling text from a "V_TEXT" variable
    - additional dimmer sensor for controlling display brightness
    - 'Alarm' switch. If "On", overrides the text display to display ALARM message
    - You can also input messages from the Serial monitor (testing)
    Uses excellent MD_MAX72XX library
  Remarks:
    Fixed node-id
*/
// Enable debug prints to serial monitor
#define MY_DEBUG
// Enable and select radio type attached
#define MY_RADIO_NRF24
//#define MY_RADIO_RFM69
#define  DEBUG 0   // Enable or disable (default) debugging output
// Use the MD_MAX72XX library to scroll text on the display with the use of the callback function
// to control what is scrolled on the display text.
// You need to set the used display in the library MD_MAX72XX.h
// User can enter text on the serial monitor and this will display as a
// Speed for the display is controlled by a pot on SPEED_IN analog in.
#include <MD_MAX72xx.h>                     // multipurpose library for MAX72xx diaplay driver  https://parola.codeplex.com/
#include <MySensor.h>                       // Mysensor network
#include <SPI.h>
#include <Time.h>                           //http://playground.arduino.cc/Code/Time
#define PRINT_CALLBACK  0
// Macro to simplify serial print
#define PRINT(s, v) { Serial.print(F(s)); Serial.print(v); }
#define  PRINTS(x) Serial.print(F(x))
#define PRINTD(x) Serial.println(x, DEC)
// Define the number of devices we have in the chain and the hardware interface
// need to be adapted to your setup
const int MAX_DEVICES = 8 ;                 // number of 8x8 displays
const int CLK_PIN = 7 ;                     // SPI like clock
const int DATA_PIN = 8 ;                    // SPI like data
const int CS_PIN = 6 ;                      // SPI like select
// Parola is able to use SPI hardware interface, not testted in combination with MySensors
// MD_MAX72XX mx = MD_MAX72XX(CS_PIN, MAX_DEVICES);
// now use Arbitrary pins
MD_MAX72XX mx = MD_MAX72XX(DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES); // instantiate one display chain
const int SCROLL_DELAY = 20 ;               // in milliseconds
const int CHAR_SPACING = 1 ;                // pixels between characters
int statetus_tame = 1;
char sdate[11];
char stime[9];
// MySensors constants & variables
//const byte nodeId = 51 ;                    // MySensors fixed node id
const byte messageCHILD = 8 ;               // Text from ControllerLCD
const byte brightnessChild = 9 ;            // Brightness of display
const byte alarmChild = 10 ;                // Display Alarm text (overrides normal text)
boolean timeReceived = false ;              // Flag to indicate time received
// Display constants & variables
byte textBrightness = 1 ;                   // brightness of display (between 0 - MAX_INTENSITY (0xF)
byte textOnOff = true ;                     // textOnOff = ! shutdown
boolean textAlarm = false ;                 // Alarm (switch S_BINARY)
// Global message buffers shared by MySensors and Scrolling functions
const int BUF_SIZE = 25 ;                   // max payload for MySensors(NRF24l01)
char curMessage[BUF_SIZE];                  // current displayed message
char newMessage[BUF_SIZE];                  // next message to be displayed if available
bool newMessageAvailable = false ;          // new message available flag
uint16_t    scrollDelay;                    // in milliseconds
// *** Definition and initialisation
// define the MySensor network (1.5)
// Initialize messages for sensor network
MyMessage textMsg(messageCHILD, V_TEXT);    // message for Sending Text to Controller
/* MD_MAX72XX functions: can be found in the documentation for the library,
   no need to customtize callback & scroll routines (unless you want to...)
*/
uint8_t scrollDataSource(uint8_t dev, MD_MAX72XX::transformType_t t)
// Callback function for data that is required for scrolling into the display
{
  static char       *p = curMessage;
  static uint8_t    state = 0;
  static uint8_t    curLen, showLen;
  static uint8_t    cBuf[8];
  uint8_t colData;
  // finite state machine to control what we do on the callback
  switch (state)
  {
    case 0: // Load the next character from the font table
      showLen = mx.getChar(*p++, sizeof(cBuf) / sizeof(cBuf[0]), cBuf);
      curLen = 0;
      state++;
      // if we reached end of message, reset the message pointer
      if (*p == '\0')
      {
        p = curMessage;         // reset the pointer to start of message
        if (newMessageAvailable)    // there is a new message waiting
        {
          strcpy(curMessage, newMessage);   // copy it in
          newMessageAvailable = false;
        }
      }
    // !! deliberately fall through to next state to start displaying
    case 1: // display the next part of the character
      colData = cBuf[curLen++];
      if (curLen == showLen)                // end of character insert interchar space
      {
        showLen = CHAR_SPACING;
        curLen = 0;
        state = 2;
      }
      break;
    case 2: // display inter-character spacing (blank column)
      colData = 0;
      curLen++;
      if (curLen == showLen)
        state = 0;
      break;
    default:
      state = 0;
  }
  return (colData);
}
void printText(uint8_t modStart, uint8_t modEnd, char *pMsg)
// Print the text string to the LED matrix modules specified.
// Message area is padded with blank columns after printing.
{
  uint8_t   state = 0;
  uint8_t    curLen;
  uint16_t  showLen;
  uint8_t   cBuf[8];
  int16_t   col = ((modEnd + 1) * COL_SIZE) - 1;
  mx.control(modStart, modEnd, MD_MAX72XX::UPDATE, MD_MAX72XX::OFF);
  do     // finite state machine to print the characters in the space available
  {
    switch (state)
    {
      case 0: // Load the next character from the font table
        // if we reached end of message, reset the message pointer
        if (*pMsg == '\0')
        {
          showLen = col - (modEnd * COL_SIZE);  // padding characters
          state = 2;
          break;
        }
        // retrieve the next character form the font file
        showLen = mx.getChar(*pMsg++, sizeof(cBuf) / sizeof(cBuf[0]), cBuf);
        curLen = 0;
        state++;
      // !! deliberately fall through to next state to start displaying
      case 1: // display the next part of the character
        mx.setColumn(col--, cBuf[curLen++]);
        // done with font character, now display the space between chars
        if (curLen == showLen)
        {
          showLen = CHAR_SPACING;
          state = 2;
        }
        break;
      case 2: // initialize state for displaying empty columns
        curLen = 0;
        state++;
      // fall through
      case 3: // display inter-character spacing or end of message padding (blank columns)
        mx.setColumn(col--, 0);
        curLen++;
        if (curLen == showLen)
          state = 0;
        break;
      default:
        col = -1;   // this definitely ends the do loop
    }
  } while (col >= (modStart * COL_SIZE));
  mx.control(modStart, modEnd, MD_MAX72XX::UPDATE, MD_MAX72XX::ON);
}
void scrollDataSink(uint8_t dev, MD_MAX72XX::transformType_t t, uint8_t col) {
  // Callback function for data that is being scrolled off the display
#if PRINT_CALLBACK
  Serial.print("\n cb ");
  Serial.print(dev);
  Serial.print(' ');
  Serial.print(t);
  Serial.print(' ');
  Serial.println(col);
#endif
}
// non-blocking text display to be used in loop (call frequently)
void scrollText(void) {
  static uint32_t prevTime = 0;
  if (millis() - prevTime >= scrollDelay) {               // Is it time to scroll the text?
    mx.transform(MD_MAX72XX::TSL);                      // scroll along - the callback will load all the data
    prevTime = millis();                                // starting point for next time
  }
}
// sets the scroll delay (read from potentiometer if enabled)
uint16_t getScrollDelay(void) {
  return (SCROLL_DELAY);
}
void setup() {
  // set up the display first
  mx.begin();                                             // initialize display chain
  mx.setShiftDataInCallback(scrollDataSource);            // define function to get the scrolldata (returned as int8)
  //mx.setShiftDataOutCallback(scrollDataSink);           // not used
  mx.control(MD_MAX72XX::INTENSITY, 0x01);
  scrollDelay = SCROLL_DELAY;
  strcpy(curMessage, "I \x03 MySensors ");                // first message on display
  newMessage[0] = '\0';                                   // new message initialized to empty
  // Setup MySensors
  //Serial in Sensor network = 115200
  //Send the sensor node sketch version information to the gateway
}
void presentation() {
  sendSketchInfo("AWI Scroll MAX 51", "1.1");
  present(messageCHILD, S_INFO, "Text line Scroll");   // new S_type 20150905 (not know by domoticz)
  present(alarmChild, S_BINARY, "Alarm display");      // to display alarm text
  present(brightnessChild, S_DIMMER, "Text brightness"); // new S_type 20150905 (not know by domoticz)
  //send(textMsg.set("-"));                            // initialize the V_TEXT at controller for sensor to none (trick for Domoticz)
  request(messageCHILD, V_TEXT, 0);                    // request value from controller
  // Initializations
  requestTime();                            // get the time from controller (handled by receiveTime)
}
// loop only uses non-blocking functions
void loop() {
  static unsigned long lastUpdate ;                       // Static hold the last update time
  static unsigned long lastUpdate2 ;                       // Static hold the last update time
  unsigned long now = millis();
  scrollDelay = getScrollDelay();                         // update scroll delay from potentiometer
  readSerial();
  // Check for new conditions & ask for new information from controller every 10 seconds
  if (now - lastUpdate > 30000 && statetus_tame == 0) {
    statetus_tame = 0;
    sprintf(sdate, "%02d-%02d-%d", day(), month(), year());
    printText(0, MAX_DEVICES - 1, sdate);
    lastUpdate = now;
  }
  if (textAlarm) {                                    // if alarmstatus: override all text and set max intensity
    //strcpy(curMessage, "   ALARM   ");
    mx.control(MD_MAX72XX::INTENSITY, MAX_INTENSITY);   // set current brightness
    mx.control(MD_MAX72XX::SHUTDOWN, false) ;
  } else {                                            // standard (non Alarm actions)
   /* 
      mx.control(MD_MAX72XX::INTENSITY, textBrightness);  // set current brightness
      mx.control(MD_MAX72XX::SHUTDOWN, textOnOff) ;
      request(messageCHILD, V_TEXT, 0);                // request new value from controller
    */
  }
  if (textAlarm) {
    scrollText();
  } else {
    //sprintf(stime, "%02d:%02d:%02d", hour(), minute(), second());
    if (statetus_tame == 1) {
      sprintf(stime, "%02d:%02d:%02d", hour(), minute(), second());
      printText(0, MAX_DEVICES - 3, stime);
      mx.setShiftDataOutCallback(scrollDataSink);
    }
    mx.control(MD_MAX72XX::INTENSITY, textBrightness);   // set current brightness
  }
  if (now - lastUpdate2 > 32000) {
    statetus_tame = 1;
    mx.clear();
    lastUpdate2 = now;
  }
if (now - lastUpdate >33000 ){
  requestTime();
  lastUpdate = now;
}
}
// This is called when a new time value was received
void receiveTime(unsigned long controllerTime) {
  Serial.print("Time value received: ");
  Serial.println(controllerTime);
  setTime(controllerTime);                                // time from controller
  timeReceived = true;
}
// This is called when a message is received
void receive(const MyMessage &message) {
  Serial.print("Message: "); Serial.print(message.sensor); Serial.print(", Message: "); Serial.println(message.getString());
  if (message.sensor == messageCHILD) {
    if (message.type == V_TEXT) {                   // Text content
      strcpy(newMessage, message.getString());        // copy it in
      newMessageAvailable = true ;
    }
  } else if (message.sensor == alarmChild) {
    if (message.type == V_STATUS) {                 // True/ false content
      textAlarm = message.getBool() ? true : false ; // set alarmflag
      Serial.print("TextAlarm: ");
      Serial.println(textAlarm);
    }
  } else if (message.sensor == brightnessChild) {
    if (message.type == V_PERCENTAGE) {             // Level 0..100  content
      textBrightness = map(message.getInt(), 0, 100, 0, MAX_INTENSITY ) ; // map to brightnesslevel
      Serial.print("TextBrightness: ");
      Serial.println(textBrightness);
    } else if (message.type == V_STATUS) {          // Display on/off
      textOnOff = message.getBool() ? false : true ;  // set shutdown/ !on/off
      Serial.print("Text on/off: ");
      Serial.println(textOnOff);
    }
  }
}
// Testing purposes: input routine character buffer. Reads serial characters in buffer newMessage.
// sets flag newMessageAvailable to true if completed
void readSerial(void)
{
  static uint8_t    putIndex = 0;
  while (Serial.available())
  {
    newMessage[putIndex] = (char)Serial.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;
      newMessageAvailable = true;
    }
    else
      // Just save the next char in next location
      newMessage[putIndex++];
  }
}