Hardware components | ||||||
| × | 1 | ||||
![]() |
| × | 6 | |||
![]() |
| × | 1 | |||
![]() |
| × | 2 |
A simple easy WiFi clock using "google" HTTP timestamp, with temperature, humidity, automatic dimmer and summertime. In the code insert you WiFi SSID, Password and Timezone. Included the SLT for the case and PCB double face. Use the included library.
Components:
1. NodeMCU ESP 8266 (suggested D1 Mini Lite)
2. 6 x Max7219
3. 1 x DHT 22
4. 2 x 10 Kohm resistor
5. 1 x Photocell LDR
// V.3 - Date converted to a number and daylight saving time calculation
// V.4 - Localized date
// V.6 - Temperature and humidity
// V.7 - Corrected animated clock + seconds +1.5
// V.8 - Calibration of thermometer and hygrometer
// V.9 - Corrected daylight saving time
// V.10 - Corrected date change at 00:00 -> May 4, 2020
// V.11 - Corrected daylight saving time for last Sundays
// V.12 - Code optimized and commented
#include "Arduino.h"
#include <ArduinoJson.h>
#include <ESP8266WiFi.h> // ESP8266 Core WiFi Library
WiFiClient client;
#define NUM_MAX 6
// for NodeMCU 1.0
#define DIN_PIN 13 // D7
#define CS_PIN 15 // D8
#define CLK_PIN 14 // D5
#include "max7219.h"
#include "fonts.h"
#include "DHT.h" // DHT sensor
// DHT sensor
#define DHTPIN 12 // GPIO 12 = D6
#define DHTTYPE DHT22 // DHT 22 (AM2302)
DHT dht(DHTPIN, DHTTYPE, 11); // for ESP8266
// DHT data
float temperature = 0;
int temp = 0;
byte minus = 0;
int humidity = 0;
int poz, poz2;
int mult = 0;
float temp_offset = -1.04; // Thermometer calibration
float rh_offset = +1; // Hygrometer calibration
char TempLabel[] = " Temperatura: "; // Fixed text
char UmiLabel[] = " Umidita': "; // Fixed text
// Test IP modification
const char ssid[] = "XXXXXXXX"; // Your network SSID
const char password[] = "XXXXXXXX"; // Your network password
// Localized months and days of the week
//String M_arr[13] = {" ", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
//String Dow_arr[8] = {" ", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"};
String M_arr[13] = {" ", "Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"};
String Dow_arr[8] = {" ", "Lunedi", "Martedi", "Mercoledi", "Giovedi", "Venerdi", "Sabato", "Domenica"};
void setup()
{
Serial.begin(115200);
initMAX7219();
sendCmdAll(CMD_SHUTDOWN, 1);
sendCmdAll(CMD_INTENSITY, 1); // Brightness from 1 to 5
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
printStringWithShift("Connecting", 30);
delay(1000);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.print("IP number assigned by DHCP is ");
Serial.println(WiFi.localIP());
printStringWithShift((String(" IP:") + WiFi.localIP().toString()).c_str(), 30);
delay(1000);
// DHT initialization
dht.begin();
temperature = dht.readTemperature();
humidity = dht.readHumidity();
Serial.print(temperature);
Serial.println(" C");
Serial.print(humidity);
Serial.println(" %RH");
if (temperature < 0) {
temp = -10 * temperature;
minus = 1;
} else {
minus = 0;
temp = 10 * temperature;
}
}
// =============================DEFINE VARS==============================
#define MAX_DIGITS 20
byte dig[MAX_DIGITS] = {0};
byte digold[MAX_DIGITS] = {0};
byte digtrans[MAX_DIGITS] = {0};
int updCnt = 0;
int dots = 0;
long dotTime = 0;
long clkTime = 0;
int dx = 0;
int dy = 0;
byte del = 0;
int h, m, s;
float utcOffset = +1; // Your timezone
long localEpoc = 0;
long localMillisAtUpdate = 0;
int day, month, year, dayOfWeek;
int monthnum = 0;
int downum = 0;
int summerTime = 0;
String date;
String dayloc;
String monthloc;
// =======================================================================
void loop()
{
if (updCnt <= 0) { // Every 10 scrolls, ~450s = 7.5m
updCnt = 60;
Serial.println("Getting data ...");
printStringWithShift(" Get Time...", 30);
getTime();
Serial.println("Data loaded");
clkTime = millis();
}
contrast(); // Auto-brightness
// Print data
if (millis() - clkTime > 30000 && !del && dots) { // Clock for 30s, then scrolls for about 30s
printStringWithShift(" ", 30); // Space before
printStringWithShift(date.c_str(), 30); // Date
// Reading temperature and humidity
int humidity = dht.readHumidity();
float temperature = dht.readTemperature();
humidity = humidity + rh_offset;
temperature = temperature + temp_offset;
Serial.println("Corrected Temp and Humidity");
Serial.println(temperature);
Serial.println(humidity);
int t2 = 10 * temperature;
// Print temperature
char c[3], d[2];
String str1, str2;
int t2z = t2 / 10;
int t2u = t2 - t2z * 10;
str1 = String(t2z);
str1.toCharArray(c, 3);
str2 = String(t2u);
str2.toCharArray(d, 2);
printStringWithShift(TempLabel, 30); // Send scrolling text
printStringWithShift("+", 30);
printStringWithShift(c, 30);
printStringWithShift(",", 30);
printStringWithShift(d, 30);
printStringWithShift(" C^", 30);
// Print humidity
char b[3];
String str;
str = String(humidity);
str.toCharArray(b, 3);
printStringWithShift(UmiLabel, 30); // Send scrolling text
printStringWithShift(b, 30);
printStringWithShift(" %", 30);
printStringWithShift(" ", 30); // Space after
delay(200);
updCnt--;
clkTime = millis();
}
if (millis() - dotTime > 500) {
dotTime = millis();
dots = !dots;
}
updateTime(); // Get time
// Print clock
showAnimClock();
}
// =======================================================================
void showSimpleClock()
{
dx = dy = 0;
clr();
showDigit(h / 10, 0, dig6x8);
showDigit(h % 10, 8, dig6x8);
showDigit(m / 10, 17, dig6x8);
showDigit(m % 10, 25, dig6x8);
showDigit(s / 10, 34, dig6x8);
showDigit(s % 10, 42, dig6x8);
setCol(15, dots ? B00100100 : 0);
setCol(32, dots ? B00100100 : 0);
refreshAll();
}
// =======================================================================
void showAnimClock()
{
byte digPos[6] = {0, 8, 17, 25, 34, 42};
int digHt = 12;
int num = 6;
int i;
if (del == 0) {
del = digHt;
for (i = 0; i < num; i++) digold[i] = dig[i];
dig[0] = h / 10 ? h / 10 : 10;
dig[1] = h % 10;
dig[2] = m / 10;
dig[3] = m % 10;
dig[4] = s / 10;
dig[5] = s % 10;
for (i = 0; i < num; i++) digtrans[i] = (dig[i] == digold[i]) ? 0 : digHt;
} else {
del--;
}
clr();
for (i = 0; i < num; i++) {
if (digtrans[i] == 0) {
dy = 0;
showDigit(dig[i], digPos[i], dig6x8);
} else {
dy = digHt - digtrans[i];
showDigit(digold[i], digPos[i], dig6x8);
dy = -digtrans[i];
showDigit(dig[i], digPos[i], dig6x8);
digtrans[i]--;
}
}
dy = 0;
setCol(15, dots ? B00100100 : 0);
setCol(32, dots ? B00100100 : 0);
refreshAll();
delay(10); // Default 30
}
// =======================================================================
void showDigit(char ch, int col, const uint8_t *data)
{
if (dy < -8 || dy > 8) return;
int len = pgm_read_byte(data);
int w = pgm_read_byte(data + 1 + ch * len);
col += dx;
for (int i = 0; i < w; i++)
if (col + i >= 0 && col + i < 8 * NUM_MAX) {
byte v = pgm_read_byte(data + 1 + ch * len + 1 + i);
if (!dy) scr[col + i] = v; else scr[col + i] |= dy > 0 ? v >> dy : v << -dy;
}
}
// =======================================================================
void setCol(int col, byte v)
{
if (dy < -8 || dy > 8) return;
col += dx;
if (col >= 0 && col < 8 * NUM_MAX)
if (!dy) scr[col] = v; else scr[col] |= dy > 0 ? v >> dy : v << -dy;
}
// =======================================================================
int showChar(char ch, const uint8_t *data)
{
int len = pgm_read_byte(data);
int w = pgm_read_byte(data + 1 + ch * len);
for (int i = 0; i < w; i++)
scr[NUM_MAX * 8 + i] = pgm_read_byte(data + 1 + ch * len + 1 + i);
scr[NUM_MAX * 8 + w] = 0;
return w;
}
// =======================================================================
// Function to print characters with shift
void printCharWithShift(unsigned char c, int shiftDelay) {
if (c < ' ' || c > '~'+25) return;
c -= 32;
int w = showChar(c, font);
for (int i = 0; i < w + 1; i++) {
delay(shiftDelay);
scrollLeft();
refreshAll();
}
}
// =======================================================================
void printStringWithShift(const char* s, int shiftDelay) {
while (*s) {
printCharWithShift(*s, shiftDelay);
s++;
}
}
// =======================================================================
void getTime()
{
WiFiClient client;
if (!client.connect("www.google.com", 80)) {
Serial.println("Connection to Google failed");
return;
}
client.print(String("GET / HTTP/1.1\r\n") +
String("Host: www.google.com\r\n") +
String("Connection: close\r\n\r\n"));
int repeatCounter = 0;
while (!client.available() && repeatCounter < 10) {
delay(500);
repeatCounter++;
}
String line;
client.setNoDelay(false);
while (client.connected() && client.available()) {
line = client.readStringUntil('\n');
line.toUpperCase();
if (line.startsWith("DATE: ")) {
date = line.substring(6, 22);
date.toUpperCase();
Serial.println(date); // Check
int day = atoi(date.substring(5, 7).c_str()); // Day number
int year = 2000 + atoi(date.substring(13, 16).c_str()); // Year number
monthnum = month2index(date.substring(8, 11)); // Convert month to number
month = monthnum;
downum = dow2index(date.substring(0, 3)); // Convert day of week to number
dayOfWeek = downum;
Serial.println(day); // Check
Serial.println(month); // Check
Serial.println(year); // Check
Serial.println(dayOfWeek); // Check
monthloc = M_arr[month]; // Localize month
dayloc = Dow_arr[dayOfWeek]; // Localize day of week
date = dayloc + " " + day + " " + monthloc + " " + year;
Serial.println(date); // Check
h = line.substring(23, 25).toInt();
m = line.substring(26, 28).toInt();
s = line.substring(29, 31).toInt() + 1.5; // Correct time
// Calculate daylight saving time (DST)
if (month > 3 && month < 10) {
summerTime = 1; // Between April and September is always DST
} else if (month == 3) {
if (day >= 31 - (((5 * year / 4) + 4) % 7)) {
summerTime = 1; // DST starts on the last Sunday of March
}
} else if (month == 10) {
if (day < 31 - (((5 * year / 4) + 1) % 7)) {
summerTime = 0; // DST ends on the last Sunday of October
}
}
Serial.print("Summertime: ");
Serial.println(summerTime);
if (h + utcOffset + summerTime > 23) {
h = h - 24;
dayOfWeek = (dayOfWeek % 7) + 1;
day += 1;
// Check for month and year rollover
unsigned short Tage_Monat[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
if (day > Tage_Monat[month - 1]) {
day = 1;
month += 1;
if (month > 12) {
month = 1;
year += 1;
}
}
}
monthloc = M_arr[month]; // Localize month
dayloc = Dow_arr[dayOfWeek]; // Localize day of week
date = dayloc + ", " + day + " " + monthloc + " " + year;
Serial.println(date); // Check
localMillisAtUpdate = millis();
localEpoc = (h * 60 * 60 + m * 60 + s);
}
}
client.stop();
}
// =======================================================================
// Convert month string to month number
int month2index(String month)
{
String months[12] = {"JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"};
for (int i = 0; i < 12; i++) {
if (months[i] == month)
return i + 1;
}
return 0;
}
// =======================================================================
// Convert day of week string to day number
int dow2index(String dayOfWeek)
{
String dows[7] = {"MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"};
for (int i = 0; i < 7; i++) {
if (dows[i] == dayOfWeek)
return i + 1;
}
return 0;
}
// =======================================================================
void updateTime()
{
long curEpoch = localEpoc + ((millis() - localMillisAtUpdate) / 1000);
long epoch = round(curEpoch + 3600 * (utcOffset + summerTime) + 86400L);
h = ((epoch % 86400L) / 3600) % 24;
m = (epoch % 3600) / 60;
s = epoch % 60;
}
// =======================================================================
void contrast()
{
int brightness = analogRead(A0); // Auto-brightness (+3.3V ---|==10k==|---A0---|GND)
brightness = map(brightness, 0, 1023, 0, 4); // Brightness 0-4
sendCmdAll(CMD_INTENSITY, brightness);
}
const uint8_t dig3x8[] PROGMEM = { 4,
0x03, 0xFF, 0x81, 0xFF,
0x02, 0x02, 0xFF, 0x00,
0x03, 0xF9, 0x89, 0x8F,
0x03, 0x81, 0x89, 0xFF,
0x03, 0x1F, 0x10, 0xFC,
0x03, 0x8F, 0x89, 0xF9,
0x03, 0xFF, 0x89, 0xF9,
0x03, 0x01, 0xF1, 0x0F,
0x03, 0xFF, 0x89, 0xFF,
0x03, 0x9F, 0x91, 0xFF,
};
const uint8_t dig6x8[] PROGMEM = { 7,
0x06, 0x7E, 0xFF, 0x81, 0x81, 0xFF, 0x7E,
0x06, 0x00, 0x82, 0xFF, 0xFF, 0x80, 0x00,
0x06, 0xC2, 0xE3, 0xB1, 0x99, 0x8F, 0x86,
0x06, 0x42, 0xC3, 0x89, 0x89, 0xFF, 0x76,
0x06, 0x38, 0x3C, 0x26, 0x23, 0xFF, 0xFF,
0x06, 0x4F, 0xCF, 0x89, 0x89, 0xF9, 0x71,
0x06, 0x7E, 0xFF, 0x89, 0x89, 0xFB, 0x72,
0x06, 0x01, 0x01, 0xF1, 0xF9, 0x0F, 0x07,
0x06, 0x76, 0xFF, 0x89, 0x89, 0xFF, 0x76,
0x06, 0x4E, 0xDF, 0x91, 0x91, 0xFF, 0x7E,
6, 0,0,0,0,0,0
};
const uint8_t dig4x8[] PROGMEM = { 5,
0x04, 0xFF, 0x81, 0x81, 0xFF,
0x04, 0x04, 0x02, 0xFF, 0x00,
0x04, 0xF9, 0x89, 0x89, 0x8F,
0x04, 0x81, 0x89, 0x89, 0xFF,
0x04, 0x1F, 0x10, 0x10, 0xFE,
0x04, 0x8F, 0x89, 0x89, 0xF9,
0x04, 0xFF, 0x89, 0x89, 0xF8,
0x04, 0x01, 0xC1, 0x31, 0x0F,
0x04, 0xFF, 0x89, 0x89, 0xFF,
0x04, 0x1F, 0x91, 0x91, 0xFF,
};
const uint8_t dig3x7[] PROGMEM = { 4,
0x03, 0xFE, 0x82, 0xFE,
0x03, 0x08, 0x04, 0xFE,
0x03, 0xF2, 0x92, 0x9E,
0x03, 0x82, 0x92, 0xFE,
0x03, 0x3E, 0x20, 0xFC,
0x03, 0x9E, 0x92, 0xF2,
0x03, 0xFE, 0x92, 0xF2,
0x03, 0x02, 0xE2, 0x1E,
0x03, 0xFE, 0x92, 0xFE,
0x03, 0x9E, 0x92, 0xFE,
};
const uint8_t dig3x6[] PROGMEM = { 4,
0x03, 0xFC, 0x84, 0xFC,
0x03, 0x10, 0x08, 0xFC,
0x03, 0xF4, 0x94, 0x9C,
0x03, 0x84, 0x94, 0xFC,
0x03, 0x3C, 0x20, 0xF8,
0x03, 0x9C, 0x94, 0xF4,
0x03, 0xFC, 0x94, 0xF4,
0x03, 0x04, 0xE4, 0x1C,
0x03, 0xFC, 0x94, 0xFC,
0x03, 0xBC, 0xA4, 0xFC,
};
const uint8_t dig3x5[] PROGMEM = { 4,
0x03, 0xF8, 0x88, 0xF8,
0x02, 0x10, 0xF8, 0x00,
0x03, 0xE8, 0xA8, 0xB8,
0x03, 0x88, 0xA8, 0xF8,
0x03, 0x38, 0x20, 0xF8,
0x03, 0xB8, 0xA8, 0xE8,
0x03, 0xF8, 0xA8, 0xE8,
0x03, 0x08, 0x08, 0xF8,
0x03, 0xF8, 0xA8, 0xF8,
0x03, 0xB8, 0xA8, 0xF8,
};
const uint8_t dig5x8rn[] PROGMEM = { 6,
0x05, 0x7E, 0x81, 0x81, 0xFF, 0x7E,
0x05, 0x04, 0x02, 0xFF, 0xFF, 0x00,
0x05, 0xF1, 0x89, 0x89, 0x8F, 0x86,
0x05, 0x81, 0x89, 0x89, 0xFF, 0x76,
0x05, 0x1F, 0x10, 0x10, 0xFE, 0xFE,
0x05, 0x8F, 0x89, 0x89, 0xF9, 0x71,
0x05, 0x7E, 0x89, 0x89, 0xF9, 0x70,
0x05, 0x01, 0xC1, 0xF1, 0x3F, 0x0F,
0x05, 0x76, 0x89, 0x89, 0xFF, 0x76,
0x05, 0x0E, 0x91, 0x91, 0xFF, 0x7E,
};
const uint8_t dig5x8sq[] PROGMEM = { 6,
0x05, 0xFF, 0x81, 0x81, 0xFF, 0xFF,
0x04, 0x04, 0x02, 0xFF, 0xFF, 0x00,
0x05, 0xF9, 0x89, 0x89, 0x8F, 0x8F,
0x05, 0x81, 0x89, 0x89, 0xFF, 0xFF,
0x05, 0x1F, 0x10, 0x10, 0xFE, 0xFE,
0x05, 0x8F, 0x89, 0x89, 0xF9, 0xF9,
0x05, 0xFF, 0x89, 0x89, 0xF9, 0xF9,
0x05, 0x01, 0x01, 0x01, 0xFF, 0xFF,
0x05, 0xFF, 0x89, 0x89, 0xFF, 0xFF,
0x05, 0x9F, 0x91, 0x91, 0xFF, 0xFF,
};
const uint8_t dweek_pl[] PROGMEM = { 11,
0x0A, 0xFC, 0x08, 0x10, 0xFC, 0x00, 0xFC, 0x00, 0xFC, 0x94, 0x84,
0x09, 0xFC, 0x24, 0x24, 0x3C, 0x00, 0xFC, 0x84, 0x84, 0xFC, 0x00,
0x09, 0xFC, 0x80, 0xF0, 0x80, 0xFC, 0x00, 0x04, 0xFC, 0x04, 0x00,
0x09, 0xDC, 0x94, 0x96, 0xF5, 0x00, 0xFC, 0x24, 0x64, 0xBC, 0x00,
0x09, 0xFC, 0x84, 0x84, 0xCC, 0x00, 0xC4, 0xA4, 0x94, 0x8C, 0x00,
0x0A, 0xFC, 0x24, 0x24, 0x3C, 0x00, 0xFC, 0x00, 0xFC, 0x24, 0xFC,
0x09, 0xDC, 0x94, 0x94, 0xF4, 0x00, 0xFC, 0x84, 0x84, 0xFC, 0x00,
0x09, 0x07, 0x05, 0x07, 0x00, 0xFF, 0xFF, 0x81, 0x81, 0x81, 0x00,
};
const uint8_t dweek_en[] PROGMEM = { 11,
0x09, 0x9C, 0x94, 0x94, 0xF4, 0x00, 0xFC, 0x80, 0x80, 0xFC, 0x00,
0x0A, 0xFC, 0x04, 0x3C, 0x04, 0xFC, 0x00, 0xFC, 0x84, 0x84, 0xFC,
0x0A, 0x04, 0x04, 0xFC, 0x04, 0x04, 0x00, 0xFC, 0x80, 0x80, 0xFC,
0x0A, 0xFC, 0x80, 0xF0, 0x80, 0xFC, 0x00, 0xFC, 0x94, 0x94, 0x84,
0x0A, 0x04, 0x04, 0xFC, 0x04, 0x04, 0x00, 0xFC, 0x10, 0x10, 0xFC,
0x09, 0xFC, 0x24, 0x24, 0x04, 0x00, 0xFC, 0x24, 0x64, 0xBC, 0x00,
0x09, 0x9C, 0x94, 0x94, 0xF4, 0x00, 0xFC, 0x24, 0x24, 0xFC, 0x00,
0x09, 0x07, 0x05, 0x07, 0x00, 0xFF, 0xFF, 0x81, 0x81, 0x81, 0x00,
};
const uint8_t font[] PROGMEM = {6,
2, B00000000, B00000000, B00000000, B00000000, B00000000, // space
1, B01011111, B00000000, B00000000, B00000000, B00000000, // !
3, B00000011, B00000000, B00000011, B00000000, B00000000, // "
5, B00010100, B00111110, B00010100, B00111110, B00010100, // #
4, B00100100, B01101010, B00101011, B00010010, B00000000, // $
5, B01100011, B00010011, B00001000, B01100100, B01100011, // %
5, B00110110, B01001001, B01010110, B00100000, B01010000, // &
1, B00000011, B00000000, B00000000, B00000000, B00000000, // '
3, B00011100, B00100010, B01000001, B00000000, B00000000, // (
3, B01000001, B00100010, B00011100, B00000000, B00000000, // )
5, B00101000, B00011000, B00001110, B00011000, B00101000, // *
5, B00001000, B00001000, B00111110, B00001000, B00001000, // +
2, B10110000, B01110000, B00000000, B00000000, B00000000, // ,
4, B00001000, B00001000, B00001000, B00001000, B00000000, // -
1, B01000000, B00000000, B00000000, B00000000, B00000000, // .
3, B01100000, B00011100, B00000011, B00000000, B00000000, // /
4, B00111110, B01000001, B01000001, B00111110, B00000000, // 0
3, B01000010, B01111111, B01000000, B00000000, B00000000, // 1
4, B01100010, B01010001, B01001001, B01000110, B00000000, // 2
4, B00100010, B01000001, B01001001, B00110110, B00000000, // 3
4, B00011000, B00010100, B00010010, B01111111, B00000000, // 4
4, B00100111, B01000101, B01000101, B00111001, B00000000, // 5
4, B00111110, B01001001, B01001001, B00110010, B00000000, // 6
4, B01100001, B00010001, B00001001, B00000111, B00000000, // 7
4, B00110110, B01001001, B01001001, B00110110, B00000000, // 8
4, B00100110, B01001001, B01001001, B00111110, B00000000, // 9
1, B01000100, B00000000, B00000000, B00000000, B00000000, // :
2, B10000000, B01010000, B00000000, B00000000, B00000000, // ;
3, B00010000, B00101000, B01000100, B00000000, B00000000, // <
3, B00010100, B00010100, B00010100, B00000000, B00000000, // =
3, B01000100, B00101000, B00010000, B00000000, B00000000, // >
4, B00000010, B01011001, B00001001, B00000110, B00000000, // ?
5, B00111110, B01001001, B01010101, B01011101, B00001110, // @
4, B01111110, B00010001, B00010001, B01111110, B00000000, // A
4, B01111111, B01001001, B01001001, B00110110, B00000000, // B
4, B00111110, B01000001, B01000001, B00100010, B00000000, // C
4, B01111111, B01000001, B01000001, B00111110, B00000000, // D
4, B01111111, B01001001, B01001001, B01000001, B00000000, // E
4, B01111111, B00001001, B00001001, B00000001, B00000000, // F
4, B00111110, B01000001, B01001001, B01111010, B00000000, // G
4, B01111111, B00001000, B00001000, B01111111, B00000000, // H
3, B01000001, B01111111, B01000001, B00000000, B00000000, // I
4, B00110000, B01000000, B01000001, B00111111, B00000000, // J
4, B01111111, B00001000, B00010100, B01100011, B00000000, // K
4, B01111111, B01000000, B01000000, B01000000, B00000000, // L
5, B01111111, B00000010, B00001100, B00000010, B01111111, // M
5, B01111111, B00000100, B00001000, B00010000, B01111111, // N
4, B00111110, B01000001, B01000001, B00111110, B00000000, // O
4, B01111111, B00001001, B00001001, B00000110, B00000000, // P
4, B00111110, B01000001, B01000001, B10111110, B00000000, // Q
4, B01111111, B00001001, B00001001, B01110110, B00000000, // R
4, B00100110, B01001001, B01001001, B00110010, B00000000, // S
5, B00000001, B00000001, B01111111, B00000001, B00000001, // T
4, B00111111, B01000000, B01000000, B00111111, B00000000, // U
5, B00001111, B00110000, B01000000, B00110000, B00001111, // V
5, B00111111, B01000000, B00111000, B01000000, B00111111, // W
5, B01100011, B00010100, B00001000, B00010100, B01100011, // X
5, B00000111, B00001000, B01110000, B00001000, B00000111, // Y
4, B01100001, B01010001, B01001001, B01000111, B00000000, // Z
2, B01111111, B01000001, B00000000, B00000000, B00000000, // [
4, B00000001, B00000110, B00011000, B01100000, B00000000, // \ backslash
2, B01000001, B01111111, B00000000, B00000000, B00000000, // ]
3, B00000010, B00000001, B00000010, B00000000, B00000000, // hat
4, B01000000, B01000000, B01000000, B01000000, B00000000, // _
2, B00000001, B00000010, B00000000, B00000000, B00000000, // `
4, B00100000, B01010100, B01010100, B01111000, B00000000, // a
4, B01111111, B01000100, B01000100, B00111000, B00000000, // b
4, B00111000, B01000100, B01000100, B00101000, B00000000, // c
4, B00111000, B01000100, B01000100, B01111111, B00000000, // d
4, B00111000, B01010100, B01010100, B00011000, B00000000, // e
3, B00000100, B01111110, B00000101, B00000000, B00000000, // f
4, B10011000, B10100100, B10100100, B01111000, B00000000, // g
4, B01111111, B00000100, B00000100, B01111000, B00000000, // h
3, B01000100, B01111101, B01000000, B00000000, B00000000, // i
4, B01000000, B10000000, B10000100, B01111101, B00000000, // j
4, B01111111, B00010000, B00101000, B01000100, B00000000, // k
3, B01000001, B01111111, B01000000, B00000000, B00000000, // l
5, B01111100, B00000100, B01111100, B00000100, B01111000, // m
4, B01111100, B00000100, B00000100, B01111000, B00000000, // n
4, B00111000, B01000100, B01000100, B00111000, B00000000, // o
4, B11111100, B00100100, B00100100, B00011000, B00000000, // p
4, B00011000, B00100100, B00100100, B11111100, B00000000, // q
4, B01111100, B00001000, B00000100, B00000100, B00000000, // r
4, B01001000, B01010100, B01010100, B00100100, B00000000, // s
3, B00000100, B00111111, B01000100, B00000000, B00000000, // t
4, B00111100, B01000000, B01000000, B01111100, B00000000, // u
5, B00011100, B00100000, B01000000, B00100000, B00011100, // v
5, B00111100, B01000000, B00111100, B01000000, B00111100, // w
5, B01000100, B00101000, B00010000, B00101000, B01000100, // x
4, B10011100, B10100000, B10100000, B01111100, B00000000, // y
3, B01100100, B01010100, B01001100, B00000000, B00000000, // z
3, B00001000, B00110110, B01000001, B00000000, B00000000, // {
1, B01111111, B00000000, B00000000, B00000000, B00000000, // |
3, B01000001, B00110110, B00001000, B00000000, B00000000, // }
4, B00001000, B00000100, B00001000, B00000100, B00000000, // ~
5, B00100000, B01010100, B01010100, B11111000, B10000000, // a
4, B00111000, B01000100, B01000110, B00101001, B00000000, // c
4, B00111000, B01010100, B11010100, B10011000, B00000000, // e
3, B01010001, B01111111, B01000100, B00000000, B00000000, // l
4, B01111100, B00000100, B00000110, B01111001, B00000000, // n
4, B00111000, B01000100, B01000110, B00111001, B00000000, // o
4, B01001000, B01010100, B01010110, B00100101, B00000000, // s
3, B01100100, B01010110, B01001101, B00000000, B00000000, // z
3, B01100100, B01010101, B01001100, B00000000, B00000000, // z
5, B01111110, B00010001, B00010001, B11111110, B10000000, // A
4, B00111100, B01000010, B01000011, B00100101, B00000000, // C
5, B01111111, B01001001, B01001001, B11000001, B10000000, // E
4, B01111111, B01001000, B01000100, B01000000, B00000000, // L
5, B01111110, B00000100, B00001010, B00010001, B01111110, // N
4, B00111100, B01000110, B01000011, B00111100, B00000000, // O
4, B00100100, B01001010, B01001011, B00110000, B00000000, // S
4, B01100010, B01010110, B01001011, B01000110, B00000000, // Z
4, B01101001, B01011001, B01001101, B01001011, B00000000, // Z
5, B00111110, B01010101, B01100001, B01010101, B00111110, // :)
5, B00111110, B01100101, B01010001, B01100101, B00111110, // :(
5, B00111110, B01000101, B01010001, B01000101, B00111110, // :o
5, 0x06, 0x1F, 0x7E, 0x1F, 0x06, // heart
5, 0x04, 0x02, 0x7F, 0x02, 0x04, // arrow up
5, 0x10, 0x20, 0x7F, 0x20, 0x10, // arrow down
3, B00000010, B00000101, B00000010, B00000000, B00000000, // deg
};
// MAX7219 functions by Pawel A. Hernik
// 2016.12.10 updated for rotated LED Martices, define ROTATE below (0,90 or 270)
// MAX7219 commands:
#define CMD_NOOP 0
#define CMD_DIGIT0 1
#define CMD_DIGIT1 2
#define CMD_DIGIT2 3
#define CMD_DIGIT3 4
#define CMD_DIGIT4 5
#define CMD_DIGIT5 6
#define CMD_DIGIT6 7
#define CMD_DIGIT7 8
#define CMD_DECODEMODE 9
#define CMD_INTENSITY 10
#define CMD_SCANLIMIT 11
#define CMD_SHUTDOWN 12
#define CMD_DISPLAYTEST 15
byte scr[NUM_MAX*8 + 8]; // +8 for scrolled char
void sendCmd(int addr, byte cmd, byte data)
{
digitalWrite(CS_PIN, LOW);
for (int i = NUM_MAX-1; i>=0; i--) {
shiftOut(DIN_PIN, CLK_PIN, MSBFIRST, i==addr ? cmd : 0);
shiftOut(DIN_PIN, CLK_PIN, MSBFIRST, i==addr ? data : 0);
}
digitalWrite(CS_PIN, HIGH);
}
void sendCmdAll(byte cmd, byte data)
{
digitalWrite(CS_PIN, LOW);
for (int i = NUM_MAX-1; i>=0; i--) {
shiftOut(DIN_PIN, CLK_PIN, MSBFIRST, cmd);
shiftOut(DIN_PIN, CLK_PIN, MSBFIRST, data);
}
digitalWrite(CS_PIN, HIGH);
}
void refresh(int addr) {
for (int i = 0; i < 8; i++)
sendCmd(addr, i + CMD_DIGIT0, scr[addr * 8 + i]);
}
void refreshAllRot270() {
byte mask = 0x01;
for (int c = 0; c < 8; c++) {
digitalWrite(CS_PIN, LOW);
for(int i=NUM_MAX-1; i>=0; i--) {
byte bt = 0;
for(int b=0; b<8; b++) {
bt<<=1;
if(scr[i * 8 + b] & mask) bt|=0x01;
}
shiftOut(DIN_PIN, CLK_PIN, MSBFIRST, CMD_DIGIT0 + c);
shiftOut(DIN_PIN, CLK_PIN, MSBFIRST, bt);
}
digitalWrite(CS_PIN, HIGH);
mask<<=1;
}
}
void refreshAllRot90() {
byte mask = 0x80;
for (int c = 0; c < 8; c++) {
digitalWrite(CS_PIN, LOW);
for(int i=NUM_MAX-1; i>=0; i--) {
byte bt = 0;
for(int b=0; b<8; b++) {
bt>>=1;
if(scr[i * 8 + b] & mask) bt|=0x80;
}
shiftOut(DIN_PIN, CLK_PIN, MSBFIRST, CMD_DIGIT0 + c);
shiftOut(DIN_PIN, CLK_PIN, MSBFIRST, bt);
}
digitalWrite(CS_PIN, HIGH);
mask>>=1;
}
}
#define ROTATE 90
void refreshAll() {
#if ROTATE==270
refreshAllRot270();
#elif ROTATE==90
refreshAllRot90();
#else
for (int c = 0; c < 8; c++) {
digitalWrite(CS_PIN, LOW);
for(int i=NUM_MAX-1; i>=0; i--) {
shiftOut(DIN_PIN, CLK_PIN, MSBFIRST, CMD_DIGIT0 + c);
shiftOut(DIN_PIN, CLK_PIN, MSBFIRST, scr[i * 8 + c]);
}
digitalWrite(CS_PIN, HIGH);
}
#endif
}
void clr()
{
for (int i = 0; i < NUM_MAX*8; i++) scr[i] = 0;
}
void scrollLeft()
{
for(int i=0; i < NUM_MAX*8+7; i++) scr[i] = scr[i+1];
}
void invert()
{
for (int i = 0; i < NUM_MAX*8; i++) scr[i] = ~scr[i];
}
void initMAX7219()
{
pinMode(DIN_PIN, OUTPUT);
pinMode(CLK_PIN, OUTPUT);
pinMode(CS_PIN, OUTPUT);
digitalWrite(CS_PIN, HIGH);
sendCmdAll(CMD_DISPLAYTEST, 0);
sendCmdAll(CMD_SCANLIMIT, 7);
sendCmdAll(CMD_DECODEMODE, 0);
sendCmdAll(CMD_INTENSITY, 0); // minimum brightness
sendCmdAll(CMD_SHUTDOWN, 0);
clr();
refreshAll();
}
Thanks to Nat .
Comments
Please log in or sign up to comment.