Affichage des articles dont le libellé est max7219. Afficher tous les articles
Affichage des articles dont le libellé est max7219. Afficher tous les articles

mardi 16 juillet 2019

Arduino Episode 19 : Projet Reveil (tout va bien)

Arduino Episode 19 : Projet Reveil (tout va bien)

J'ajoute juste mon code où le superflu est supprimé, et les effets me conviennent.
Prochaine étape : Le tilt

// Date and time functions using a DS3231 RTC connected via I2C and Wire lib
#include <Wire.h>
#include "RTClib.h"
#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <SPI.h>
#include <stdint.h>

RTC_DS3231 rtc;
char str [20];
char joursemaine[12];
char daysOfTheWeek[7][12] = {"Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"};
char jourmois[12];
char anneefull[4];
char horaire[12];

#define HARDWARE_TYPE MD_MAX72XX::ICSTATION_HW
#define MAX_DEVICES 4
#define CLK_PIN 13
#define DATA_PIN 11
#define CS_PIN 10

// Hardware SPI connection
MD_Parola P = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
int j = 0;

void setup () {
P.begin();
P.setIntensity(0);
Serial.begin(9600);
delay(3000); // wait for console opening

if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1);
}

if (rtc.lostPower()) {
Serial.println("RTC lost power, lets set the time!");
// following line sets the RTC to the date & time this sketch was compiled
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// This line sets the RTC with an explicit date & time, for example to set
// January 21, 2014 at 3am you would call:
rtc.adjust(DateTime(2019, 7, 15, 10, 01, 0));
}
}

void loop () {
DateTime now = rtc.now();

int anneefull = now.year();
int annee= (now.year()-2000);
int mois = now.month();
int jour = now.day();
int heure = now.hour();
int minutes = now.minute();

if (P.displayAnimate())
{
sprintf(joursemaine,daysOfTheWeek[now.dayOfTheWeek()]);
sprintf(jourmois,"%02d/%02d",jour,mois);
sprintf(anneefull,"%02d",anneefull);
sprintf(horaire,"%02d:%02d",heure,minutes);

switch (j) {
case 0:
P.displayText(joursemaine, PA_CENTER, 25 , 2000, PA_DISSOLVE, PA_DISSOLVE);
break;
case 1:
P.displayText(jourmois, PA_CENTER, 25 , 2000, PA_DISSOLVE, PA_DISSOLVE);
break;
case 2:
P.displayText(anneefull, PA_CENTER, 25 , 2000, PA_DISSOLVE, PA_DISSOLVE);
break;
case 3:
P.displayText(horaire, PA_CENTER, 25 , 30000, PA_DISSOLVE, PA_DISSOLVE);
break;
default:
break;
}
j = j + 1;
if (j > 5) j = 0;
}

Serial.print(" (");
Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
Serial.print(") ");
Serial.print(now.day(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.year(), DEC);
Serial.print(' ');
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.println();
Serial.print(j);
Serial.println();
}

dimanche 7 avril 2019

Arduino Episode 18 : Projet Reveil

Voici un projet qui s'impose à moi,
après un achat sur le bon coin, je me retrouve avec quelques éléments qui ne m'interesse pas vraiment.
-arduino
-matrice 7219
-une horloge temps réel ds3231m


et l'idée à germée.
 Je vais faire un reveil,  juste ajouter un buzzer un tilt et je pourrais faire une horloge qui affiche l'heure, sonne, et s'éteint lorsqu'on lui met la tête en bas.
on pourra toujours changer l'arduino nano par un esp8266 pour le mettre sur Internet.

Voici rapidement les branchements
Max7219 - Nano
VCC - 5V
GND - GND
DIN - PIN 11
CS -  PIN 10
CLK - PIN 13

DS3231M - Nano
VCC - 3V
GND - GND
SCL - SCL or A5
SDA - SDA or A4


Pour la librairie du DS3231M, j'opte pour RTCLib, plus rapide que DS3231M  ou DS3231 ou DS3231F
Il configure l'heure tout seul, l'affiche, et fait meme un test de prévision (ici ca ne marche pas)

2019/4/8 (Monday) 18:10:47
 since midnight 1/1/1970 = 1554714647s = 17994d
 now + 7d + 30s: 2019/4/16 06:40:53

Voici la partie code pour le RTC :
// Date and time functions using a DS3231 RTC connected via I2C and Wire lib
#include
#include "RTClib.h"

RTC_DS3231 rtc;

char daysOfTheWeek[7][12] = {"Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"};

void setup () {

#ifndef ESP8266
  while (!Serial); // for Leonardo/Micro/Zero
#endif

  Serial.begin(9600);

  delay(3000); // wait for console opening

  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }

  if (rtc.lostPower()) {
    Serial.println("RTC lost power, lets set the time!");
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }
}

void loop () {
    DateTime now = rtc.now();

    Serial.print(" (");
    Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
    Serial.print(") ");

    Serial.print(now.day(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.year(), DEC);
    Serial.print(' ');
   
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();
   
    Serial.print(" Depuis le 1/1/1970 minuit = ");
    Serial.print(now.unixtime());
    Serial.print("s = ");
    Serial.print(now.unixtime() / 86400L);
    Serial.println("d");
   
    // calculate a date which is 7 days and 30 seconds into the future
    DateTime future (now + TimeSpan(7,12,30,6));
   
    Serial.print(" Maintenant + 7d + 12h + 30minutes +6s: ");
    Serial.print(future.day(), DEC);
    Serial.print('/');
    Serial.print(future.month(), DEC);
    Serial.print('/');
    Serial.print(future.year(), DEC);
    Serial.print(' ');
    Serial.print(future.hour(), DEC);
    Serial.print(':');
    Serial.print(future.minute(), DEC);
    Serial.print(':');
    Serial.print(future.second(), DEC);
    Serial.println();
   
    Serial.println();
    delay(5000);
}

vendredi 28 décembre 2018

NodeMCU Episode 6 :Matrice à LED 4x1088AS et Max7219


NodeMCU Episode 6 :Matrice à LED 4x1088AS et Max7219

Après l'arduino Nano, encore plus interessant avec l'ESP8266...
J'ai trouvé ce petit script, qui se connecte à un Wifi, lance un serveur, affiche l'ip sur l'afficheur LED, avec une page html et un formulaire qui inscrit sur l'affichage LED ce que l'on à saisi dans le formulaire.
Top tout est déjà fait :)

Branchements:

Max7219 - Nano
VCC - 3V
GND - G
DIN - D7
CS -  D8
CLK - D5


Librairie:(Croquis / Inclure une bibliothèque / Gérer les bibliothèques)
Ajoutez les librairies :
MD_MAX72XX by majicDesigns


Code:
Pour changer le sens du texte :

#define HARDWARE_TYPE MD_MAX72XX::ICSTATION_HW

 Sources:
http://www.etechpath.com/how-to-control-max7219-led-matrix-with-esp8266-wifi-module/

Code Adapté :
// IP address for the ESP8266 is displayed on the scrolling display
// after startup initialisation and connected to the WiFi network.
//
// Connections for ESP8266 hardware SPI are:
// Vcc 3v3 LED matrices seem to work at 3.3V
// GND GND GND
// DIN D7 HSPID or HMOSI
// CS or LD D8 HSPICS or HCS
// CLK D5 CLK or HCLK
//

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

#define PRINT_CALLBACK 0
#define DEBUG 0
#define LED_HEARTBEAT 0

#if DEBUG
#define PRINT(s, v) { Serial.print(F(s)); Serial.print(v); }
#define PRINTS(s) { Serial.print(F(s)); }
#else
#define PRINT(s, v)
#define PRINTS(s)
#endif


#if LED_HEARTBEAT
#define HB_LED D2
#define HB_LED_TIME 500 // in milliseconds
#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 MAX_DEVICES 4

#define CLK_PIN D5 // or SCK
#define DATA_PIN D7 // or MOSI
#define CS_PIN D8 // or SS

// SPI hardware interface
//MD_MAX72XX mx = MD_MAX72XX(CS_PIN, MAX_DEVICES);
#define HARDWARE_TYPE MD_MAX72XX::ICSTATION_HW //edit this as per your LED matrix hardware type
MD_MAX72XX mx = MD_MAX72XX(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
// Arbitrary pins
//MD_MAX72XX mx = MD_MAX72XX(DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);

// WiFi login parameters - network name and password
const char* ssid = "ssid_wifi"; // edit your wifi SSID here
const char* password = "mdp_wifi"; // edit your wifi password here

// WiFi Server object and parameters
WiFiServer server(80);

// Global message buffers shared by Wifi and Scrolling functions
const uint8_t MESG_SIZE = 255;
const uint8_t CHAR_SPACING = 1;
const uint8_t SCROLL_DELAY = 75;

char curMessage[MESG_SIZE];
char newMessage[MESG_SIZE];
bool newMessageAvailable = false;

char WebResponse[] = "HTTP/1.1 200 OK\nContent-Type: text/html\n\n";

char WebPage[] =
"<!DOCTYPE html>" \
"<html>" \
"<head>" \
"<title>ESP8266</title>" \
"<style>" \
"html, body" \
"{" \
"width: 600px;" \
"height: 400px;" \
"margin: 0px;" \
"border: 0px;" \
"padding: 10px;" \
"background-color: white;" \
"}" \
"#container " \
"{" \
"width: 100%;" \
"height: 100%;" \
"margin-left: 200px;" \
"border: solid 2px;" \
"padding: 10px;" \
"background-color: #b3cbf2;" \
"}" \
"</style>"\
"<script>" \
"strLine = \"\";" \
"function SendText()" \
"{" \
" nocache = \"/&nocache=\" + Math.random() * 1000000;" \
" var request = new XMLHttpRequest();" \
" strLine = \"&MSG=\" + document.getElementById(\"txt_form\").Message.value;" \
" request.open(\"GET\", strLine + nocache, false);" \
" request.send(null);" \
"}" \
"</script>" \
"</head>" \
"<body>" \
"<div id=\"container\">"\
"<H1><b>WiFi MAX7219 LED Matrix Display</b></H1>" \
"<form id=\"txt_form\" name=\"frmText\">" \
"<label>Msg:<input type=\"text\" name=\"Message\" maxlength=\"255\"></label><br><br>" \
"</form>" \
"<br>" \
"<input type=\"submit\" value=\"Send Text\" onclick=\"SendText()\">" \
"</div>" \
"</body>" \
"</html>";

char *err2Str(wl_status_t code)
{
switch (code)
{
case WL_IDLE_STATUS: return("IDLE"); break; // WiFi is in process of changing between statuses
case WL_NO_SSID_AVAIL: return("NO_SSID_AVAIL"); break; // case configured SSID cannot be reached
case WL_CONNECTED: return("CONNECTED"); break; // successful connection is established
case WL_CONNECT_FAILED: return("CONNECT_FAILED"); break; // password is incorrect
case WL_DISCONNECTED: return("CONNECT_FAILED"); break; // module is not configured in station mode
default: return("??");
}
}

uint8_t htoi(char c)
{
c = toupper(c);
if ((c >= '0') && (c <= '9')) return(c - '0');
if ((c >= 'A') && (c <= 'F')) return(c - 'A' + 0xa);
return(0);
}

boolean getText(char *szMesg, char *psz, uint8_t len)
{
boolean isValid = false; // text received flag
char *pStart, *pEnd; // pointer to start and end of text

// get pointer to the beginning of the text
pStart = strstr(szMesg, "/&MSG=");

if (pStart != NULL)
{
pStart += 6; // skip to start of data
pEnd = strstr(pStart, "/&");

if (pEnd != NULL)
{
while (pStart != pEnd)
{
if ((*pStart == '%') && isdigit(*(pStart+1)))
{
// replace %xx hex code with the ASCII character
char c = 0;
pStart++;
c += (htoi(*pStart++) << 4);
c += htoi(*pStart++);
*psz++ = c;
}
else
*psz++ = *pStart++;
}

*psz = '\0'; // terminate the string
isValid = true;
}
}

return(isValid);
}

void handleWiFi(void)
{
static enum { S_IDLE, S_WAIT_CONN, S_READ, S_EXTRACT, S_RESPONSE, S_DISCONN } state = S_IDLE;
static char szBuf[1024];
static uint16_t idxBuf = 0;
static WiFiClient client;
static uint32_t timeStart;

switch (state)
{
case S_IDLE: // initialise
PRINTS("\nS_IDLE");
idxBuf = 0;
state = S_WAIT_CONN;
break;

case S_WAIT_CONN: // waiting for connection
{
client = server.available();
if (!client) break;
if (!client.connected()) break;

#if DEBUG
char szTxt[20];
sprintf(szTxt, "%03d:%03d:%03d:%03d", client.remoteIP()[0], client.remoteIP()[1], client.remoteIP()[2], client.remoteIP()[3]);
PRINT("\nNew client @ ", szTxt);
#endif

timeStart = millis();
state = S_READ;
}
break;

case S_READ: // get the first line of data
PRINTS("\nS_READ");
while (client.available())
{
char c = client.read();
if ((c == '\r') || (c == '\n'))
{
szBuf[idxBuf] = '\0';
client.flush();
PRINT("\nRecv: ", szBuf);
state = S_EXTRACT;
}
else
szBuf[idxBuf++] = (char)c;
}
if (millis() - timeStart > 1000)
{
PRINTS("\nWait timeout");
state = S_DISCONN;
}
break;


case S_EXTRACT: // extract data
PRINTS("\nS_EXTRACT");
// Extract the string from the message if there is one
newMessageAvailable = getText(szBuf, newMessage, MESG_SIZE);
PRINT("\nNew Msg: ", newMessage);
state = S_RESPONSE;
break;

case S_RESPONSE: // send the response to the client
PRINTS("\nS_RESPONSE");
// Return the response to the client (web page)
client.print(WebResponse);
client.print(WebPage);
state = S_DISCONN;
break;

case S_DISCONN: // disconnect client
PRINTS("\nS_DISCONN");
client.flush();
client.stop();
state = S_IDLE;
break;

default: state = S_IDLE;
}
}

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
}

uint8_t scrollDataSource(uint8_t dev, MD_MAX72XX::transformType_t t)
// Callback function for data that is required for scrolling into the display
{
static enum { S_IDLE, S_NEXT_CHAR, S_SHOW_CHAR, S_SHOW_SPACE } state = S_IDLE;
static char *p;
static uint16_t curLen, showLen;
static uint8_t cBuf[8];
uint8_t colData = 0;

// finite state machine to control what we do on the callback
switch (state)
{
case S_IDLE: // reset the message pointer and check for new message to load
PRINTS("\nS_IDLE");
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;
}
state = S_NEXT_CHAR;
break;

case S_NEXT_CHAR: // Load the next character from the font table
PRINTS("\nS_NEXT_CHAR");
if (*p == '\0')
state = S_IDLE;
else
{
showLen = mx.getChar(*p++, sizeof(cBuf) / sizeof(cBuf[0]), cBuf);
curLen = 0;
state = S_SHOW_CHAR;
}
break;

case S_SHOW_CHAR: // display the next part of the character
PRINTS("\nS_SHOW_CHAR");
colData = cBuf[curLen++];
if (curLen < showLen)
break;

// set up the inter character spacing
showLen = (*p != '\0' ? CHAR_SPACING : (MAX_DEVICES*COL_SIZE)/2);
curLen = 0;
state = S_SHOW_SPACE;
// fall through

case S_SHOW_SPACE: // display inter-character spacing (blank column)
PRINT("\nS_ICSPACE: ", curLen);
PRINT("/", showLen);
curLen++;
if (curLen == showLen)
state = S_NEXT_CHAR;
break;

default:
state = S_IDLE;
}

return(colData);
}

void scrollText(void)
{
static uint32_t prevTime = 0;

// Is it time to scroll the text?
if (millis() - prevTime >= SCROLL_DELAY)
{
mx.transform(MD_MAX72XX::TSL); // scroll along - the callback will load all the data
prevTime = millis(); // starting point for next time
}
}

void setup()
{
#if DEBUG
Serial.begin(115200);
PRINTS("\n[MD_MAX72XX WiFi Message Display]\nType a message for the scrolling display from your internet browser");
#endif

#if LED_HEARTBEAT
pinMode(HB_LED, OUTPUT);
digitalWrite(HB_LED, LOW);
#endif

// Display initialisation
mx.begin();
mx.control(MD_MAX72XX::INTENSITY, 0);
mx.setShiftDataInCallback(scrollDataSource);
mx.setShiftDataOutCallback(scrollDataSink);

curMessage[0] = newMessage[0] = '\0';

// Connect to and initialise WiFi network
PRINT("\nConnecting to ", ssid);

WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED)
{
PRINT("\n", err2Str(WiFi.status()));
delay(500);
}
PRINTS("\nWiFi connected");

// Start the server
server.begin();
PRINTS("\nServer started");

// Set up first message as the IP address
sprintf(curMessage, "%03d:%03d:%03d:%03d", WiFi.localIP()[0], WiFi.localIP()[1], WiFi.localIP()[2], WiFi.localIP()[3]);
PRINT("\nAssigned IP ", curMessage);
}

void loop()
{
#if LED_HEARTBEAT
static uint32_t timeLast = 0;

if (millis() - timeLast >= HB_LED_TIME)
{
digitalWrite(HB_LED, digitalRead(HB_LED) == LOW ? HIGH : LOW);
timeLast = millis();
}
#endif

handleWiFi();
scrollText();
}

jeudi 27 décembre 2018

Arduino Episode 8 : Matrice à LED 4x1088AS et Max7219

Arduino Episode 8 : Matrice à LED et Max7219



Bonjour,
Le père Noël étant passé, je me suis précipité pour tester mon nouveau jouet, la matrice de LED 4x8x8 et le controlleur MAX7219
Un Arduino Nano, 5 câbles, et c'est parti.

Branchements:

Max7219 - Nano
VCC - 5V
GND - GND
DIN - PIN 11
CS -  PIN 10
CLK - PIN 13


Librairie:(Croquis / Inclure une bibliothèque / Gérer les bibliothèques)
Ajoutez les librairies :
MD_MAX72XX by majicDesigns
MD_Parola

Code:
Pour changer le sens du texte :

#define HARDWARE_TYPE MD_MAX72XX::ICSTATION_HW

Pour rendre moins lumineux:(de 0 à 15)
  P.begin();
  P.setIntensity(0);
 




Astuce:
Si besoin refermer la fenêtre SERIAL pour charger un texte

Sources:
Pour le mettre en place: https://www.youtube.com/watch?v=SIlLj4thyso

Pour approfondir : https://www.youtube.com/watch?v=mTJcrdIzBfs
https://www.youtube.com/watch?v=hH-m0LL_ZAs
https://www.youtube.com/watch?v=aTmaaruSUbw



Code Complet:
// Use the Parola library to scroll text on the display
//
// Demonstrates the use of the scrolling function to display text received
// from the serial interface
//
// User can enter text on the serial monitor and this will display as a
// scrolling message on the display.
// Speed for the display is controlled by a pot on SPEED_IN analog in.
// Scrolling direction is controlled by a switch on DIRECTION_SET digital in.
// Invert ON/OFF is set by a switch on INVERT_SET digital in.
//
// UISwitch library can be found at https://github.com/MajicDesigns/MD_UISwitch
// MD_MAX72XX library can be found at https://github.com/MajicDesigns/MD_MAX72XX
//

#include
#include
#include

int incomingByte = 0;

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

#if USE_UI_CONTROL
#include
#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::ICSTATION_HW
#define MAX_DEVICES 8
#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 = 8;
#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 = 1000; // in milliseconds

// Global message buffers shared by Serial and Scrolling functions
#define    BUF_SIZE    75
char curMessage[BUF_SIZE] = { "" };
char newMessage[BUF_SIZE] = { "Joyeuses Fetes" };
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.setIntensity(0);
  P.displayText(curMessage, scrollAlign, scrollSpeed, scrollPause, scrollEffect, scrollEffect);
}

void loop()
{

 if (Serial.available() > 0) {
                // read the incoming byte:
                incomingByte = Serial.read();

                // say what you got:
                Serial.print("I received: ");
                Serial.println(incomingByte, DEC);
        }
 
#if USE_UI_CONTROL
  doUI();
#endif // USE_UI_CONTROL

  if (P.displayAnimate())
  {
    if (newMessageAvailable)
    {
      strcpy(curMessage, newMessage);
      newMessageAvailable = false;
    }
    P.displayReset();
  }
  readSerial();
}