TOP03 – LED Matrix Display

In this example the TOP03 board drives 4pcs. of 8×8 LED Matrix for an overall display size of 32×8.
Using a LED modules based on the driver max7219, the connections between the TOP03 and the display module are reduced to only 5 wires. Moreover, it is possible to add in other LED modules to increase the overall display size without increasing the number of connections.

 

Hardware

  • TOP03 Arduino Compatible Wi-Fi Board
  • Power supply (for example a 5V smartphone charger with micro-USB jack)
  • 4pcs. of LED Matrix module based on max7219 led driver.
  • wires for connections
Supply the TOP03 Board from its usb connector OR the RAW pin (5Volt)
Example of LED Matrix module based on max7219 driver.

µPanel definition 

Using the Online Panel Simulator you can easily design and check the panel layout before loading it on Arduino.

D!DDDw;/#000*9{^Tfib*22:SMART DISPLAY;}{*12W0M:1:4.40,4.41;}/{.1^%90!EEEM0fc*30:ON;}/{T*15:Enter Your Text;}{%80E0-1~1%100p20*12:;}/{n3*12^r10%85p10#888-Tfb#000*12:Text options;=_{%100|#444<Tfb:SLIDING-TEXT;|>W1O*6:1;}_{%100|#444<Tfb:Speed;_|^R0%95:0:100:1:50:250;}_{%100|#444<Tfb:Brightness;_|^R1%95:0:5:1:0:100;}}

TOP03 Code (Arduino Lilypad USB)

To build in Arduino IDE this project, you have to install the LedControl.zip library. You can find both library and complete sketch for TOP03 in the following zipped folder:

TOP03 and LED Matrix PROJECT.zip

IMPORTANT: before loading your sketch, please select the board “LilyPad Arduino USB” in the boards menu.
If you have accidentally selected another board, and already tried loading your sketch, read here: 

www.arduino.cc/en/Guide/ArduinoLilyPadUSB

Arduino Code

//=================================================================================================
// LCD 8x8 Matrix
//
// Ref: https://brainy-bits.com/tutorials/how-to-control-max7219-led-matrix/
//
// Install lybrary LED LedControl.zip - https://brainy-bits.com/wp-content/uploads/2015/01/LedControl.zip
//
// Connection LED module - TOP03 wifi board: VCC raw - GND - CS pin 10 - DIN pin 14 - CLK pin 16
//=================================================================================================

#include <LedControl.h>

#define NDISP 4

#define PIN_GPIO_0   12
#define PIN_CH_PD    13
#define PIN_RESET    22

#define INITIAL_MSG   "uPanel - www.miuPanel.com "
#define INIT_SPEED  100


//LedControl lc=LedControl(12,11,10,NDISP);  // Pin and # of Displays ---> ARDUINO UNO

LedControl lc=LedControl(14,16,10,NDISP);  // Pin and # of Displays ---> Cactus

unsigned char LCD_OnOffState = 1;  // Off;
unsigned char LCD_Sliding = 1;
unsigned short LCD_SlidingDelay_ms = INIT_SPEED;
unsigned char LCD_Brightness = 0;
unsigned short LCD_CurrentSlidingOffset = 0;
String SLCD = INITIAL_MSG;
char CustomMsg = 0;

long LastChange = 0;

String Msg = "";

char font8x8_basic[128][8] = {
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0000 (nul)
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0001
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0002
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0003
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0004
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0005
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0006
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0007
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0008
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0009
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+000A
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+000B
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+000C
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+000D
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+000E
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+000F
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0010
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0011
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0012
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0013
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0014
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0015
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0016
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0017
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0018
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0019
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+001A
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+001B
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+001C
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+001D
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+001E
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+001F
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0020 (space)
    { 0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00},   // U+0021 (!)
    { 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0022 (")
    { 0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00},   // U+0023 (#)
    { 0x0C, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x0C, 0x00},   // U+0024 ($)
    { 0x00, 0x63, 0x33, 0x18, 0x0C, 0x66, 0x63, 0x00},   // U+0025 (%)
    { 0x1C, 0x36, 0x1C, 0x6E, 0x3B, 0x33, 0x6E, 0x00},   // U+0026 (&)
    { 0x06, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0027 (')
    { 0x18, 0x0C, 0x06, 0x06, 0x06, 0x0C, 0x18, 0x00},   // U+0028 (()
    { 0x06, 0x0C, 0x18, 0x18, 0x18, 0x0C, 0x06, 0x00},   // U+0029 ())
    { 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00},   // U+002A (*)
    { 0x00, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x00, 0x00},   // U+002B (+)
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x06},   // U+002C (,)
    { 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00},   // U+002D (-)
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00},   // U+002E (.)
    { 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00},   // U+002F (/)
    { 0x3E, 0x63, 0x73, 0x7B, 0x6F, 0x67, 0x3E, 0x00},   // U+0030 (0)
    { 0x0C, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x3F, 0x00},   // U+0031 (1)
    { 0x1E, 0x33, 0x30, 0x1C, 0x06, 0x33, 0x3F, 0x00},   // U+0032 (2)
    { 0x1E, 0x33, 0x30, 0x1C, 0x30, 0x33, 0x1E, 0x00},   // U+0033 (3)
    { 0x38, 0x3C, 0x36, 0x33, 0x7F, 0x30, 0x78, 0x00},   // U+0034 (4)
    { 0x3F, 0x03, 0x1F, 0x30, 0x30, 0x33, 0x1E, 0x00},   // U+0035 (5)
    { 0x1C, 0x06, 0x03, 0x1F, 0x33, 0x33, 0x1E, 0x00},   // U+0036 (6)
    { 0x3F, 0x33, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x00},   // U+0037 (7)
    { 0x1E, 0x33, 0x33, 0x1E, 0x33, 0x33, 0x1E, 0x00},   // U+0038 (8)
    { 0x1E, 0x33, 0x33, 0x3E, 0x30, 0x18, 0x0E, 0x00},   // U+0039 (9)
    { 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00},   // U+003A (:)
    { 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x06},   // U+003B (//)
    { 0x18, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x18, 0x00},   // U+003C (<)
    { 0x00, 0x00, 0x3F, 0x00, 0x00, 0x3F, 0x00, 0x00},   // U+003D (=)
    { 0x06, 0x0C, 0x18, 0x30, 0x18, 0x0C, 0x06, 0x00},   // U+003E (>)
    { 0x1E, 0x33, 0x30, 0x18, 0x0C, 0x00, 0x0C, 0x00},   // U+003F (?)
    { 0x3E, 0x63, 0x7B, 0x7B, 0x7B, 0x03, 0x1E, 0x00},   // U+0040 (@)
    { 0x0C, 0x1E, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x00},   // U+0041 (A)
    { 0x3F, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3F, 0x00},   // U+0042 (B)
    { 0x3C, 0x66, 0x03, 0x03, 0x03, 0x66, 0x3C, 0x00},   // U+0043 (C)
    { 0x1F, 0x36, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x00},   // U+0044 (D)
    { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x7F, 0x00},   // U+0045 (E)
    { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x06, 0x0F, 0x00},   // U+0046 (F)
    { 0x3C, 0x66, 0x03, 0x03, 0x73, 0x66, 0x7C, 0x00},   // U+0047 (G)
    { 0x33, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x33, 0x00},   // U+0048 (H)
    { 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00},   // U+0049 (I)
    { 0x78, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E, 0x00},   // U+004A (J)
    { 0x67, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x67, 0x00},   // U+004B (K)
    { 0x0F, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7F, 0x00},   // U+004C (L)
    { 0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63, 0x00},   // U+004D (M)
    { 0x63, 0x67, 0x6F, 0x7B, 0x73, 0x63, 0x63, 0x00},   // U+004E (N)
    { 0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x00},   // U+004F (O)
    { 0x3F, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x0F, 0x00},   // U+0050 (P)
    { 0x1E, 0x33, 0x33, 0x33, 0x3B, 0x1E, 0x38, 0x00},   // U+0051 (Q)
    { 0x3F, 0x66, 0x66, 0x3E, 0x36, 0x66, 0x67, 0x00},   // U+0052 (R)
    { 0x1E, 0x33, 0x07, 0x0E, 0x38, 0x33, 0x1E, 0x00},   // U+0053 (S)
    { 0x3F, 0x2D, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00},   // U+0054 (T)
    { 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0x00},   // U+0055 (U)
    { 0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00},   // U+0056 (V)
    { 0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00},   // U+0057 (W)
    { 0x63, 0x63, 0x36, 0x1C, 0x1C, 0x36, 0x63, 0x00},   // U+0058 (X)
    { 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x0C, 0x1E, 0x00},   // U+0059 (Y)
    { 0x7F, 0x63, 0x31, 0x18, 0x4C, 0x66, 0x7F, 0x00},   // U+005A (Z)
    { 0x1E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1E, 0x00},   // U+005B ([)
    { 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00},   // U+005C (\)
    { 0x1E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1E, 0x00},   // U+005D (])
    { 0x08, 0x1C, 0x36, 0x63, 0x00, 0x00, 0x00, 0x00},   // U+005E (^)
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF},   // U+005F (_)
    { 0x0C, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0060 (`)
    { 0x00, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x6E, 0x00},   // U+0061 (a)
    { 0x07, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3B, 0x00},   // U+0062 (b)
    { 0x00, 0x00, 0x1E, 0x33, 0x03, 0x33, 0x1E, 0x00},   // U+0063 (c)
    { 0x38, 0x30, 0x30, 0x3e, 0x33, 0x33, 0x6E, 0x00},   // U+0064 (d)
    { 0x00, 0x00, 0x1E, 0x33, 0x3f, 0x03, 0x1E, 0x00},   // U+0065 (e)
    { 0x1C, 0x36, 0x06, 0x0f, 0x06, 0x06, 0x0F, 0x00},   // U+0066 (f)
    { 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x1F},   // U+0067 (g)
    { 0x07, 0x06, 0x36, 0x6E, 0x66, 0x66, 0x67, 0x00},   // U+0068 (h)
    { 0x0C, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00},   // U+0069 (i)
    { 0x30, 0x00, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E},   // U+006A (j)
    { 0x07, 0x06, 0x66, 0x36, 0x1E, 0x36, 0x67, 0x00},   // U+006B (k)
    { 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00},   // U+006C (l)
    { 0x00, 0x00, 0x33, 0x7F, 0x7F, 0x6B, 0x63, 0x00},   // U+006D (m)
    { 0x00, 0x00, 0x1F, 0x33, 0x33, 0x33, 0x33, 0x00},   // U+006E (n)
    { 0x00, 0x00, 0x1E, 0x33, 0x33, 0x33, 0x1E, 0x00},   // U+006F (o)
    { 0x00, 0x00, 0x3B, 0x66, 0x66, 0x3E, 0x06, 0x0F},   // U+0070 (p)
    { 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x78},   // U+0071 (q)
    { 0x00, 0x00, 0x3B, 0x6E, 0x66, 0x06, 0x0F, 0x00},   // U+0072 (r)
    { 0x00, 0x00, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x00},   // U+0073 (s)
    { 0x08, 0x0C, 0x3E, 0x0C, 0x0C, 0x2C, 0x18, 0x00},   // U+0074 (t)
    { 0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x00},   // U+0075 (u)
    { 0x00, 0x00, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00},   // U+0076 (v)
    { 0x00, 0x00, 0x63, 0x6B, 0x7F, 0x7F, 0x36, 0x00},   // U+0077 (w)
    { 0x00, 0x00, 0x63, 0x36, 0x1C, 0x36, 0x63, 0x00},   // U+0078 (x)
    { 0x00, 0x00, 0x33, 0x33, 0x33, 0x3E, 0x30, 0x1F},   // U+0079 (y)
    { 0x00, 0x00, 0x3F, 0x19, 0x0C, 0x26, 0x3F, 0x00},   // U+007A (z)
    { 0x38, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, 0x38, 0x00},   // U+007B ({)
    { 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00},   // U+007C (|)
    { 0x07, 0x0C, 0x0C, 0x38, 0x0C, 0x0C, 0x07, 0x00},   // U+007D (})
    { 0x6E, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+007E (~)
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}    // U+007F
};


void SendPanel()
{
   Serial1.println("");
   Serial1.print("$P:");
   Serial1.println(F("D!DDD;/#000*9{^Tfib*22:SMART DISPLAY;}{*12W0M:1:4.40,4.41;}/{.1^%90!EEEM0fc*30:ON;}/{T*15:Enter Your Text;}{%80E0-1~1%100p20*12:;}/{*12^r10%85p10#888-Tfb#000*12:Text options;=_{%100|#444<Tfb:SLIDING TEXT;|>W1O*6:1;}_{%100|#444<Tfb:Speed;_|^R0%95:0:100:1:50:250;}_{%100|#444<Tfb:Brightness;_|^R1%95:0:5:1:0:100;}}"));
}

void setup()
{
  int n;

  for(n=0; n< NDISP; n++)
  {
    lc.shutdown(n,false);  // Wake up displays
    lc.setIntensity(n,LCD_Brightness);  // Set intensity levels
    lc.clearDisplay(n);    
  }

  WriteString("Wait",0);

  pinMode(PIN_GPIO_0, OUTPUT);
  pinMode(PIN_CH_PD,  OUTPUT);
  pinMode(PIN_RESET,  OUTPUT); 
  
  digitalWrite(PIN_GPIO_0,1);
  digitalWrite(PIN_CH_PD,1);
  digitalWrite(PIN_RESET,0);  // Reset
  
  Serial.begin(57600);
  
  delay(250);
  
  digitalWrite(PIN_RESET,1);  // Release Reset
  
  delay(5000);
  Serial1.begin(57600);  
  
  SendPanel();
}

int WaitMessage(int timeout_ms)
{
  int c;                                // the received byte
  unsigned long entrytime = millis();   // Read the time at the function entry
  static char KeepBuffer = 0;           // This tells if we have a partial message in the buffer

  if (!KeepBuffer) Msg = "";            // If Keepbuffer is false than clear the old message
  KeepBuffer = 0;                       // in any case set now the keep buffer to false
  
  do
  {
    while ((c = Serial1.read()) > '\n') Msg += (char) c;  // Read incoming chars, if any, until new line
    if (c == '\n')                                       // is message complete?
    {
      if (Msg.substring(0,1).equals("#")) return 1;      // if it is a data message return 1
      Msg = "";                                          // otherwise, wait for another one
    }
  } while ((timeout_ms < 0) || (millis()-entrytime < timeout_ms));  // has max time passed?
  
  KeepBuffer = 1;                                                   // Keep the partial buffer content
  return 0;                                                         // if time passed, return 0
}



//  Take values in Arrays and Display them
void SetChar(int nd, int a)
{
  char *p;
 
  unsigned char x = 0;
  unsigned w = 0;
  unsigned q = 0;
 
  p = font8x8_basic[a & 127];
  
  q = 1;
  for (int i = 0; i < 8; i++)  
  {
    w = 1;
    x = 0;
    for(int j=0; j<8; j++)
    {
      x |= p[j] & q ? w : 0;
      w = w << 1;
    }
    
      lc.setRow(nd,i,x);
      q = q << 1;
  }
}

void SetCharMixed(int nd, unsigned int a, unsigned int b, char px)
{

  char *p,*p2;
 
  unsigned char x = 0, y = 0;
  unsigned w = 0;
  unsigned q = 0;
 
  if (a > 127) {Serial.println(a); a=0;}
  if (b > 127) b = 0;
 
  p = font8x8_basic[a & 127];
  p2 = font8x8_basic[b & 127];
  
  q = 1;
  for (int i = 0; i < 8; i++)  
  {
    w = 1;
    x = 0;
    y = 0;
    for(int j=0; j<8; j++)
    {
      y = (p[j] >> px) | (p2[j] << (8-px));

      x |= y & q ? w : 0;
      w = w << 1;
    }
      lc.setRow(nd,i,x);
      q = q << 1;
  }
}


void WriteString(char *s, int offp)
{
  int n;
  char k;
  int L;
  
  L = strlen(s);
  
  if (offp < L) L = offp;
  
  s += offp;
  
  L = strlen(s);
  
  for(n=0; n<NDISP; n++)
  {
    if (n < L) k=s[n]; else k = 0; 
    SetChar(n,k);
    //SetCharMixed(n, k, s[n+1], 2);
  }
}


void WriteStringMixed(char *s, int offp, int px)
{
   
  int n;
  char k,k2;
  int L;
  
  L = strlen(s);
  if (offp < L) L = offp;
  s += offp;
  L = strlen(s);
  
  for(n=0; n<NDISP; n++)
  {
    if (n < L) k=s[n]; else k = 0;
    if (n+1 < L) k2 = s[n+1]; else k2 = 0;
    //SetChar(n,k);
    SetCharMixed(n, k, k2, px); 
  }
}


void UpdateLCD(int ts)
{
      int z = SLCD.length()+5;
  
      char b[z];
      String Q;
      
      if (LCD_OnOffState == 0)
      {
         WriteString("        ",0);
         return; 
      }
      
      if (LCD_Sliding) Q = "    "+SLCD; else Q=SLCD;
      
      Q.toCharArray(b,z-1);
      Q[z-1] = 0;

      LCD_CurrentSlidingOffset += ts;
      
      if ((LCD_CurrentSlidingOffset/8 >= strlen(b)+1) || (LCD_Sliding == 0)) LCD_CurrentSlidingOffset = 0;
  
      WriteStringMixed(b,LCD_CurrentSlidingOffset/8,LCD_CurrentSlidingOffset & 7);
}

void UpdateBrightness()
{  
  for(int n=0; n< NDISP; n++)
  {
    lc.setIntensity(n,LCD_Brightness);  // Set intensity levels
  } 
}


void loop()
{
// Put #1 frame on both Display

    static unsigned long LastRefresh = millis();
    unsigned long nw = millis();
    char toRefresh = 0;
    unsigned short toStep = 1;
    
    if (nw - LastRefresh >= LCD_SlidingDelay_ms) {toRefresh=1; if (LCD_SlidingDelay_ms < 80) toStep = 2; if (LCD_SlidingDelay_ms < 70) toStep = 3;}
   
    if (WaitMessage(1)) while(1)
    {
      
     if (Msg.substring(0,4).equals("#E0:")) 
      {
         SLCD = ""+Msg.substring(4,80)+" ";
         SLCD.replace("è","e'");
         SLCD.replace("à","a'");
         SLCD.replace("é","e'");
         SLCD.replace("ò","o'");
         LCD_CurrentSlidingOffset = 0;
         toRefresh = 1;
         LastChange = nw;
         CustomMsg = 1;
         break;
      }     
      
      Msg.toUpperCase();  
      
      if (Msg.equals("#W00"))
      {
            LCD_OnOffState = 0;
            toRefresh = 1;
            Serial1.println("#M0OFF");
      }
      
      if (Msg.equals("#W01"))
      {
            LCD_OnOffState = 1;
            LCD_CurrentSlidingOffset = 0;
            toRefresh = 1;
            Serial1.println("#M0ON");
      }

      if (Msg.equals("#.EVT:1:1"))
      {
            Serial1.println("#C3:S:_t(1,'')");
      }

      
      if (Msg.equals("#W10"))
      {
            LCD_Sliding = 0;
            toRefresh = 1; 
      }
      
      if (Msg.equals("#W11"))
      {
            LCD_Sliding = 1;
            toRefresh = 1;
      }
      
      if (Msg.substring(0,4).equals("#R1:")) 
      {
         LCD_Brightness = Msg.substring(4).toInt(); 
         UpdateBrightness();
      }
      
      if (Msg.substring(0,4).equals("#R0:")) 
      {
         LCD_SlidingDelay_ms = 250-(Msg.substring(4).toInt())*2;  
      }
      
      break;
      
    }

   if (toRefresh) { UpdateLCD(toStep); LastRefresh = nw;};
  
   int c = 0;
  
   while(c >= 0) { c = Serial.read();  if (c >= 0) Serial1.write(c); }  
}