// Program to demonstrate the MD_Parola library
//
// Demonstrates how UTF-8 multi-byte characters can be mapped to Extended ASCII
// characters that can be displayed with a suitable font file.
//
// MD_MAX72XX library can be found at https://github.com/MajicDesigns/MD_MAX72XX
//
#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <SPI.h>
#include "Parola_Fonts_data.h"
// 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 18
#define DATA_PIN 23
#define CS_PIN 5
// 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 uint16_t PAUSE_TIME = 2000;
// Turn on debug statements to the serial output
#define DEBUG 1
#if DEBUG
#define PRINT(s, x) { Serial.print(F(s)); Serial.print(x); }
#define PRINTS(x) Serial.print(F(x))
#define PRINTX(s, x) { Serial.print(F(s)); Serial.print(x, HEX); }
#else
#define PRINT(s, x)
#define PRINTS(x)
#define PRINTX(s, x)
#endif
// Global variables
char pc[][20] =
{
"abc…ABC",
// "äöüßÄÖÜ",
// "50€/kg³",
// "Español",
// "30m/s²",
// "Français",
// "20µs/°C",
};
uint8_t utf8Ascii(uint8_t ascii)
// Convert a single Character from UTF8 to Extended ASCII according to ISO 8859-1,
// also called ISO Latin-1. Codes 128-159 contain the Microsoft Windows Latin-1
// extended characters:
// - codes 0..127 are identical in ASCII and UTF-8
// - codes 160..191 in ISO-8859-1 and Windows-1252 are two-byte characters in UTF-8
// + 0xC2 then second byte identical to the extended ASCII code.
// - codes 192..255 in ISO-8859-1 and Windows-1252 are two-byte characters in UTF-8
// + 0xC3 then second byte differs only in the first two bits to extended ASCII code.
// - codes 128..159 in Windows-1252 are different, but usually only the €-symbol will be needed from this range.
// + The euro symbol is 0x80 in Windows-1252, 0xa4 in ISO-8859-15, and 0xe2 0x82 0xac in UTF-8.
//
// Modified from original code at http://playground.arduino.cc/Main/Utf8ascii
// Extended ASCII encoding should match the characters at http://www.ascii-code.com/
//
// Return "0" if a byte has to be ignored.
{
static uint8_t cPrev;
uint8_t c = '\0';
PRINTX("\nutf8Ascii 0x", ascii);
if (ascii < 0x7f) // Standard ASCII-set 0..0x7F, no conversion
{
cPrev = '\0';
c = ascii;
}
else
{
switch (cPrev) // Conversion depending on preceding UTF8-character
{
case 0xC2: c = ascii; break;
case 0xC3: c = ascii | 0xC0; break;
case 0x82: if (ascii==0xAC) c = 0x80; // Euro symbol special case
case 0xE2:
switch (ascii)
{
case 0x80: c = 133; break;// ellipsis special case
}
break;
default: PRINTS("!Unhandled! ");
}
cPrev = ascii; // save last char
}
PRINTX(" -> 0x", c);
return(c);
}
void utf8Ascii(char* s)
// In place conversion UTF-8 string to Extended ASCII
// The extended ASCII string is always shorter.
{
uint8_t c;
char *cp = s;
PRINT("\nConverting: ", s);
while (*s != '\0')
{
c = utf8Ascii(*s++);
if (c != '\0')
*cp++ = c;
}
*cp = '\0'; // terminate the new string
}
void setup(void)
{
#if DEBUG
Serial.begin(57600);
#endif
PRINTS("\n[Parola UTF-8 display Test]");
// Do one time in-place conversion of the strings to be displayed
for (uint8_t i=0; i<ARRAY_SIZE(pc); i++)
utf8Ascii(pc[i]);
// Initialise the Parola library
P.begin();
P.setInvert(false);
P.setPause(PAUSE_TIME);
P.setFont(ExtASCII);
}
void loop(void)
{
static uint32_t timeLast = PAUSE_TIME;
static uint16_t idx = 0;
static bool showMessage = true;
if (millis() - timeLast <= PAUSE_TIME)
return;
timeLast = millis();
if (showMessage)
{
// show the strings with the UTF-8 characters
PRINT("\nS:", idx);
PRINT(" - ", pc[idx]);
P.print(pc[idx]);
// Set the display for the next string.
idx++;
if (idx == ARRAY_SIZE(pc))
{
showMessage = false;
idx = 128;
}
}
else
{
// show the list of characters in order
char szMsg[20];
sprintf(szMsg, "%3d %c", idx, idx);
PRINT("\nC:", idx);
PRINT(" - ", szMsg);
P.print(szMsg);
// set up for next character
idx++;
if (idx == 256)
{
idx = 0;
showMessage = true;
}
}
}