#include <Wire.h> //For WiFi Network Connection
#include <MD_Parola.h> //For MAX7219 Matrix LED
#include <SPI.h> //For SPI Communication
#include "Fonts.h"
//=====MAX7219================================
#define HARDWARE_TYPE MD_MAX72XX::PAROLA_HW
#define MAX_DEVICES 4
#define CLK_PIN 19
#define DATA_PIN 18
#define CS_PIN 5
MD_Parola P = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);
//MD_MAX72xx display = MD_MAX72xx(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);
#define SPEED_TIME 75
#define MAX_MESG 20
// These are for the clock
#define DS1307_ADDRESS 0x68
int pinBuzzer = 3;
// Global variables
uint8_t wday, mday, month, year;
uint8_t hours, minutes, seconds;
char szTime[9]; // mm:ss\0
char szMesg[MAX_MESG + 1] = "";
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());
month = bcdToDec(Wire.read());
year = 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));
}
// Code for reading clock time
void getTime(char *psz, bool f = true)
{
sprintf(psz, "%02d%c%02d", hours, (f ? ':' : ' '), minutes);
}
// Code for reading clock date
void getDate(char *psz)
{
char szBuf[10];
sprintf(psz, "%d %s %04d", mday , mon2str(month, szBuf, sizeof(szBuf) - 1), (year + 2000));
}
// Get a label from PROGMEM into a char array
char *mon2str(uint8_t mon, char *psz, uint8_t len)
{
static const __FlashStringHelper* str[] =
{
F("Jan"), F("Feb"), F("Mar"), F("Apr"),
F("May"), F("Jun"), F("Jul"), F("Aug"),
F("Sep"), F("Oct"), F("Nov"), F("Dec")
};
strncpy_P(psz, (const char PROGMEM *)str[mon - 1], len);
psz[len] = '\0';
return (psz);
}
char *dow2str(uint8_t code, char *psz, uint8_t len)
{
static const __FlashStringHelper* str[] =
{
F("Sunday"), F("Monday"), F("Tuesday"),
F("Wednesday"), F("Thursday"), F("Friday"),
F("Saturday")
};
strncpy_P(psz, (const char PROGMEM *)str[code - 1], len);
psz[len] = '\0';
return (psz);
}
// Sprite Definitions
const uint8_t F_PMAN1 = 6;
const uint8_t W_PMAN1 = 8;
static const uint8_t PROGMEM pacman1[F_PMAN1 * W_PMAN1] = // gobbling pacman animation
{
0x00, 0x81, 0xc3, 0xe7, 0xff, 0x7e, 0x7e, 0x3c,
0x00, 0x42, 0xe7, 0xe7, 0xff, 0xff, 0x7e, 0x3c,
0x24, 0x66, 0xe7, 0xff, 0xff, 0xff, 0x7e, 0x3c,
0x3c, 0x7e, 0xff, 0xff, 0xff, 0xff, 0x7e, 0x3c,
0x24, 0x66, 0xe7, 0xff, 0xff, 0xff, 0x7e, 0x3c,
0x00, 0x42, 0xe7, 0xe7, 0xff, 0xff, 0x7e, 0x3c,
};
const uint8_t F_PMAN2 = 4;
const uint8_t W_PMAN2 = 18;
static const uint8_t PROGMEM pacman2[F_PMAN2 * W_PMAN2] = // ghost pursued by a pacman
{
0x00, 0x81, 0xc3, 0xe7, 0xff, 0x7e, 0x7e, 0x3c, 0x00, 0x00, 0x00, 0xfe, 0x7b, 0xf3, 0x7f, 0xfb, 0x73, 0xfe,
0x00, 0x42, 0xe7, 0xe7, 0xff, 0xff, 0x7e, 0x3c, 0x00, 0x00, 0x00, 0xfe, 0x7b, 0xf3, 0x7f, 0xfb, 0x73, 0xfe,
0x24, 0x66, 0xe7, 0xff, 0xff, 0xff, 0x7e, 0x3c, 0x00, 0x00, 0x00, 0xfe, 0x7b, 0xf3, 0x7f, 0xfb, 0x73, 0xfe,
0x3c, 0x7e, 0xff, 0xff, 0xff, 0xff, 0x7e, 0x3c, 0x00, 0x00, 0x00, 0xfe, 0x73, 0xfb, 0x7f, 0xf3, 0x7b, 0xfe,
};
const uint8_t F_WALKER = 5;
const uint8_t W_WALKER = 7;
const uint8_t PROGMEM walker[F_WALKER * W_WALKER] = // walking man
{
0x00, 0x48, 0x77, 0x1f, 0x1c, 0x94, 0x68,
0x00, 0x90, 0xee, 0x3e, 0x38, 0x28, 0xd0,
0x00, 0x00, 0xae, 0xfe, 0x38, 0x28, 0x40,
0x00, 0x00, 0x2e, 0xbe, 0xf8, 0x00, 0x00,
0x00, 0x10, 0x6e, 0x3e, 0xb8, 0xe8, 0x00,
};
const uint8_t F_HEART = 5;
const uint8_t W_HEART = 9;
const uint8_t PROGMEM heart[F_HEART * W_HEART] = // beating heart
{
0x0e, 0x11, 0x21, 0x42, 0x84, 0x42, 0x21, 0x11, 0x0e,
0x0e, 0x1f, 0x33, 0x66, 0xcc, 0x66, 0x33, 0x1f, 0x0e,
0x0e, 0x1f, 0x3f, 0x7e, 0xfc, 0x7e, 0x3f, 0x1f, 0x0e,
0x0e, 0x1f, 0x33, 0x66, 0xcc, 0x66, 0x33, 0x1f, 0x0e,
0x0e, 0x11, 0x21, 0x42, 0x84, 0x42, 0x21, 0x11, 0x0e,
};
const uint8_t F_BATEL = 2;
const uint8_t W_BATEL = 8;
const uint8_t PROGMEM batel[F_BATEL * W_BATEL] = // beating heart
{
//0x3E,0x41,0x3E,0xF2,0xF2,0x3E,0x41,0x3E,
//0x00,0x7F,0x3E,0xF2,0xF2,0x3E,0x7F,0x00,
//0x42,0xBD,0xBD,0xA5,0xA5,0xBD,0x5A,0x18,
//0x00,0x7E,0x7E,0x66,0x66,0x7E,0x18,0x18,
0x18,0x5A,0xBD,0xBD,0xA5,0xA5,0xBD,0x42,
0x18,0x5A,0x7E,0x7E,0x66,0x66,0x7E,0x42,
};
const uint8_t F_BATEL2 = 5;
const uint8_t W_BATEL2 = 18;
const uint8_t PROGMEM batel2[F_BATEL2 * W_BATEL2] = // beating heart
{
0x00, 0x48, 0x77, 0x1f, 0x1c, 0x94, 0x68,0x00, 0x00, 0x00,0x18,0x5A,0xBD,0xBD,0xA5,0xA5,0xBD,0x42,
0x00, 0x90, 0xee, 0x3e, 0x38, 0x28, 0xd0,0x00, 0x00, 0x00,0x18,0x5A,0x7E,0x7E,0x66,0x66,0x7E,0x42,
0x00, 0x00, 0xae, 0xfe, 0x38, 0x28, 0x40,0x00, 0x00, 0x00,0x18,0x5A,0xBD,0xBD,0xA5,0xA5,0xBD,0x42,
0x00, 0x00, 0x2e, 0xbe, 0xf8, 0x00, 0x00,0x00, 0x00, 0x00,0x18,0x5A,0x7E,0x7E,0x66,0x66,0x7E,0x42,
0x00, 0x10, 0x6e, 0x3e, 0xb8, 0xe8, 0x00,0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};
void setup(void)
{
pinMode(pinBuzzer, OUTPUT);
Wire.begin();
P.begin(2);
//P.setSpriteData(pacman1, W_PMAN1, F_PMAN1, pacman2, W_PMAN2, F_PMAN2);
//P.setSpriteData(walker, W_WALKER, F_WALKER, walker, W_WALKER, F_WALKER);
//P.setSpriteData(heart, W_HEART, F_HEART, heart, W_HEART, F_HEART);
//P.setSpriteData(batel, W_BATEL, F_BATEL, batel, W_BATEL, F_BATEL);
P.setInvert(false);
P.setZone(0, MAX_DEVICES - 4, MAX_DEVICES - 1);
P.setZone(1, MAX_DEVICES - 4, MAX_DEVICES - 1);
P.displayZoneText(1, szTime, PA_CENTER, SPEED_TIME, 0, PA_PRINT, PA_NO_EFFECT);
P.displayZoneText(0, szMesg, PA_CENTER, SPEED_TIME, 0, PA_PRINT , PA_NO_EFFECT);
}
void loop(void)
{
static uint32_t lastTime = 0; // Memory (ms)
static uint8_t display = 0; // Current display mode
static bool flasher = false; // Seconds passing flasher
beginDS1307();
P.displayAnimate();
if (P.getZoneStatus(0))
{
switch (display)
{
case 0: // Clock
P.setFont(0, GYD_PHP5X7);
P.setTextEffect(0, PA_PRINT, PA_NO_EFFECT);
P.setPause(0, 0);
if ((millis() - lastTime) >= 500)
{
lastTime = millis();
getTime(szMesg, flasher);
flasher = !flasher;
}
//if ((seconds == 00) && (seconds <= 30)) {
if ((seconds == 00) || (seconds == 30)) {
display++;
//PA_WIPE_CURSOR
//P.setTextEffect(0, PA_PRINT, PA_WIPE_CURSOR);
//PA_SPRITE
//P.setTextEffect(0, PA_PRINT, PA_SPRITE);
//P.setTextEffect(0, PA_SPRITE, PA_SPRITE);
P.setTextEffect(0, PA_PRINT, PA_SPRITE);
}
break;
case 1: // Day of week
P.setFont(0, nullptr);
P.setTextEffect(0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
display++;
dow2str(wday, szMesg, MAX_MESG);
break;
default: // Calendar
P.setTextEffect(0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
display = 0;
getDate(szMesg);
break;
}
P.displayReset(0); // Rest zone zero
}
// if ((minutes == 14) && (seconds = 00)) {
// long frequency = 300; //频率, 单位Hz
// //用tone()函数发出频率为frequency的波形
// tone(pinBuzzer, frequency );
// delay(1000); //等待1000毫秒
// noTone(pinBuzzer);//停止发声
// delay(2000); //等待2000毫秒
// }
}