// Use the MD_MAX72XX library to Print some text on the display
//
// Demonstrates the use of the library to print text.
//
// User can enter text on the serial monitor and this will display as a
// message on the display.
#include <TimeLib.h>
#include <MD_MAX72xx.h>
#include <SPI.h>
#include <Wire.h>
#include "Font7Seg.h"
#define PRINT(s, v) { Serial.print(F(s)); Serial.print(v); }
#define DS1307_ADDRESS 0x68
// 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 4
#define CLK_PIN 13 // or SCK
#define DATA_PIN 11 // or MOSI
#define CS_PIN 10 // or SS
#define MAX_MESG 20
// Global variables
uint8_t wday, mday, monthL, yearL;
uint8_t hours, minutes, seconds;
char szTime[9]; // mm:ss\0
char szMesg[MAX_MESG + 1] = "";
// SPI hardware interface
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);
// Text parameters
#define CHAR_SPACING 1 // pixels between characters
// Global message buffers shared by Serial and Scrolling functions
#define BUF_SIZE 75
char message[BUF_SIZE] = {"Hello!"};
bool newMessageAvailable = true;
bool newMsg = true;
unsigned char *msg;
uint8_t clear = 0x00;
void beginDS1307()
{
// Read the values (date and time) of the DS1307 module
Wire.beginTransmission(DS1307_ADDRESS);
Wire.write(clear);
Wire.endTransmission();
Wire.requestFrom(DS1307_ADDRESS, 0x07);
seconds = bcdToDec(Wire.read());
minutes = bcdToDec(Wire.read());
hours = bcdToDec(Wire.read() & 0xff);
wday = bcdToDec(Wire.read());
mday = bcdToDec(Wire.read());
monthL = bcdToDec(Wire.read());
yearL = bcdToDec(Wire.read());
}
uint8_t decToBcd(uint8_t value)
{
return ((value / 10 * 16) + (value % 10));
}
uint8_t bcdToDec(uint8_t value)
{
return ((value / 16 * 10) + (value % 16));
}
void showDigit(uint8_t digit, uint8_t font[], uint8_t width, uint8_t pos) {
for (uint8_t k = 0; k < width; k++) {
mx.setColumn(31 - pos - k, pgm_read_byte(font + digit * width + k));
}
}
void showTime() {
mx.control(0, 3, MD_MAX72XX::UPDATE, MD_MAX72XX::OFF);
showDigit(hours % 10, Font5x8, 5, 9);
if (hours / 10 > 0)showDigit(hours / 10, Font5x8, 5, 3);
showDigit(minutes % 10, Font5x8, 5, 24);
showDigit(minutes / 10, Font5x8, 5, 18);
mx.control(0, 3, MD_MAX72XX::UPDATE, MD_MAX72XX::ON);
}
// Code for reading clock time
void getTime(char *psz)
{
sprintf(psz, "%02d%s%02d", hours, " ", minutes);
}
void showDigit(uint8_t digit, uint8_t font[], uint8_t pos) {
uint8_t width = pgm_read_byte(font);
for (uint8_t k = 0; k < width; k++) {
mx.setColumn(31 - pos - k, pgm_read_byte(font + 1 + digit * width + k));
}
}
uint8_t getCharData(uint8_t digit, uint8_t font[], uint8_t buffer[]) {
uint8_t width = pgm_read_byte(font);
for (uint8_t k = 0; k < width; k++)
buffer[k] = pgm_read_byte(font + 1 + digit * width + k);
return width;
}
unsigned char utfConv(unsigned char *&c) {
unsigned char ch;
switch (*c) {
case 0xC3: ch = *++c + 64; break;
case 0xC5:
switch (*++c) {
case 0x90: case 0x91: ch = *c + 5; break;
case 0xB0: case 0xB1: ch = *c - 25;
} break;
default: ch = *c;
}
return ch;
}
void printText(uint8_t modStart, uint8_t modEnd, unsigned char *pMsg, byte pos)
// 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) - pos - 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
col = -1;
//state = 2;
break;
}
// retrieve the next character form the font file
if (*pMsg >= 48 && *pMsg <= 57) showLen = getCharData(*pMsg - 48, Font5x8, cBuf);
else showLen = mx.getChar(utfConv(pMsg), sizeof(cBuf) / sizeof(cBuf[0]), cBuf);
pMsg++;
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)
{
if (*pMsg == ' ') {
state = 0;
break;
}
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);
}
bool msgEnd = false;
uint8_t dataInCBEmpty(uint8_t dev, MD_MAX72XX::transformType_t t) {
return 0;
}
uint8_t dataInCB(uint8_t dev, MD_MAX72XX::transformType_t t) {
// Callback function for data that is required for scrolling into the display
{
static uint8_t state = 0;
static uint8_t curLen, showLen;
static uint8_t cBuf[8];
static unsigned char* c;
uint8_t colData = 0;
if (newMsg) {
c = msg;
newMsg = false;
state = 0;
}
// finite state machine to control what we do on the callback
switch (state)
{
case 0: // Load the next character from the font table
// if we reached end of message, reset the message pointer
if (*c == '\0')
{
msgEnd = true;
break;
}
//PRINT("", (char)c);
if (*c >= 48 && *c <= 57) showLen = getCharData(*c - 48, Font5x8, cBuf);
else showLen = mx.getChar(utfConv(c), sizeof(cBuf) / sizeof(cBuf[0]), cBuf);
c++;
curLen = 0;
state++;
// !! deliberately fall through to next state to start displaying
case 1: // display the next part of the character
colData = cBuf[curLen++];
if (curLen == showLen)
{
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 TSL(char *str, uint16_t del, uint8_t filler) {
msg = str;
newMsg = true;
if (str != nullptr)
while (!msgEnd) {
mx.transform(MD_MAX72XX::TSL);
delay(del);
}
msgEnd = false;
mx.setShiftDataInCallback(&dataInCBEmpty);
while (filler > 0) {
mx.transform(MD_MAX72XX::TSL);
delay(del);
filler--;
}
mx.setShiftDataInCallback(&dataInCB);
}
void setup()
{
mx.begin();
mx.setFont(numeric7Seg);
//mx.setShiftDataInCallback(&dataInCB);
Serial.begin(9600);
//hours=5;
//DS1307setTime();
}
unsigned char str[] = "üöóőúáéűí:";
unsigned char str1[] = "-32.5\x90\C";
unsigned char str2[] = "Pára:";
unsigned char str3[] = "25%";
void loop()
{
static uint32_t lastTime = 0; // Memory (ms)
static uint8_t lastMinTime = 100;
static uint8_t lastSec = 5;
static uint32_t lastDSUpdate = 0; // Memory (ms)
static bool flasher = false; // Seconds passing flasher
static uint8_t minMark = 4;
if (!lastDSUpdate || (millis() - lastDSUpdate) > 5000) {
lastDSUpdate = millis();
beginDS1307();
setTime(hours, minutes, seconds, mday, monthL, yearL);
}
else hours = hour(), minutes = minute(), seconds = second();
if (seconds == lastSec)return;
lastSec = seconds;
//if (seconds == 2) mx.setPoint(7, 30, false);
flasher ? (mx.setColumn(16, 54),mx.setColumn(15, 54)) : (mx.setColumn(16, 0),mx.setColumn(15, 0));
seconds <= 30 ? mx.setPoint(7, seconds == 0 ? mx.setPoint(7, 29, false), mx.setPoint(6, 30, false), 30 : 31 - seconds, true), mx.setPoint(7, 31 - seconds + 1, false) :
mx.setPoint(7, seconds == 31 ? 1 : seconds - 30, true), mx.setPoint(7, seconds - 30 - 1, false);
if (seconds > 55) mx.setColumn(30, 4 << seconds % 5);
if (seconds > 25 && seconds < 31) mx.setColumn(1, 4 << (seconds < 30 ? seconds % 5 : 5));
lastTime = millis();
flasher = !flasher;
if (lastMinTime != minutes) {
getTime(szMesg);
printText(0, 3, szMesg, 2);
//printText(0, MAX_DEVICES - 1, szMesg);
lastMinTime = minutes;
}
if (seconds % 15 != 0 || seconds == 0) return;
for (int i = 0; i < 8; i++) {
mx.transform(MD_MAX72XX::TSD);
delay(50);
}
TSL(nullptr, 10, 5);
TSL(str, 10, 10);
TSL(str1, 10, 2);
delay(2000);
for (int i = 0; i < 8; i++) {
mx.transform(MD_MAX72XX::TSU);
delay(50);
}
//TSL(nullptr, 15, 10);
TSL(str2, 15, 8);
TSL(nullptr, 15, 10);
TSL(str3, 15, 6);
delay(1000);
mx.clear();
getTime(szMesg);
printText(0, 3, szMesg, 2);
}