#include <ArduinoJson.h>
#include <SD.h>
#include <SPI.h>
#include <MD_Parola.h>
#include <MD_MAX72xx.h>
//SDCARD to ESP-32 pin
//Vcc -> 3v3
//Gnd -> Gnd1
//CS -> D5 (VSPI_CS)
//SCK -> D18 (VSPI_CLK)
//DO -> D19 (VsPI_MISO)
//DI -> D23 (VSPI MOSI)
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 4
#define CS_SDcard 5
#define CLK_PIN 18
#define DATA_PIN 23
#define CS_PIN 2
//MD_Parola P = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);
MD_Parola P = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
struct TTextMsg { // Our configuration structure.
char Msg[20];
byte fXi;
byte fXo;
};
const char* filename = "/setting.json"; // <- SD library uses 8.3 filenames
TTextMsg TextMsg[3];
/*template <typename... T>
String strFormat(const char *str, T... args) {
int len = snprintf(NULL, 0, str, args...);
if (len) {
char buff[len+1];
snprintf(buff, len+1, str, args...);
return(buff);
}
} */
// Loads the configuration from a file
boolean loadConfig(const char* filename) {//, struct TTextMsg TextMsg[]) {//TTextMsg& TextMsg) {
Serial.print(F("Loading configuration... "));
File aFile = SD.open(filename); // Open file for reading
JsonDocument doc; // Allocate a temporary JsonDocument
DeserializationError error = deserializeJson(doc, aFile); // Deserialize the JSON document
if (error)
Serial.println(F("Failed to read file. It will using default configuration"));
// Copy values from the JsonDocument
int _size = doc["size"] | 3;
Serial.printf(" (%d lines) \n", _size);
if (_size == 0) { _size=3; }
for (int i=0; i<_size; ++i) {
strlcpy(TextMsg[i].Msg, // <- destination
doc["dt"][i]["msg"] | "theText", // <- source, default = "theText"
sizeof(TextMsg[i].Msg)); // <- destination's capacity
TextMsg[i].fXi = doc["dt"][i]["fXi"] | 0; // <- default effect in = 0
TextMsg[i].fXo = doc["dt"][i]["fXo"] | 0; // <- default effect out = 0
Serial.printf(" :> Msg%d: %s, fXin: %d, fXout: %d\n", i+1, TextMsg[i].Msg, TextMsg[i].fXi, TextMsg[i].fXo);
}
//serializeJsonPretty(doc, Serial);
aFile.close(); // Close the file (Curiously, File's destructor doesn't close the file)
Serial.println(F(" <OK>"));
return true;
}
// Saves the configuration to a file
boolean saveConfig(const char* filename) {//, const TTextMsg& TextMsg) {
boolean _result = true;
SD.remove(filename); // Delete existing file, otherwise the configuration is appended to the file
// Open file for writing
File file = SD.open(filename, FILE_WRITE);
if (!file) {
Serial.println(F("Failed to create file"));
return false;
}
JsonDocument doc; // Allocate a temporary JsonDocument
Serial.print(F(" writing Configuration ..."));
char buffer[20];
doc["size"] = 3;
for (int i=0; i<3; ++i) {
sprintf(buffer, "ini Text-%.2f", i+0.32);
doc["dt"][i]["msg"] = buffer; //strFormat("ini Text-%d%.3f", i, .321);
doc["dt"][i]["fXi"] = 1; //TextMsg[i].fXi;
doc["dt"][i]["fXo"] = 2; //TextMsg[i].fXo;
}
// Serialize JSON (write) to file
if (serializeJson(doc, file) == 0) {
Serial.println(F("Failed to write to file"));
_result = false;
}
file.close(); // Close the file
Serial.println(F(" <OK>"));
return _result;
}
// Prints the content of a file to the Serial
void printFile(const char* filename) {
// Open file for reading
File file = SD.open(filename);
if (!file) {
Serial.println(F("Failed to read file"));
return;
}
// Extract each characters by one by one
while (file.available()) {
Serial.print((char)file.read());
}
Serial.println();
file.close(); // Close the file
}
textEffect_t Text_fX[] = {
PA_SCROLL_LEFT,
PA_SCROLL_RIGHT,
PA_SCROLL_UP,
PA_SCROLL_DOWN,
PA_OPENING_CURSOR,
PA_CLOSING_CURSOR,
};
void setup() {
Serial.begin(11520); // Initialize serial port
while (!Serial) continue;
// Initialize SD library
while (!SD.begin(CS_SDcard)) {
Serial.println(F("Failed to initialize SD library"));
delay(1000);
}
// Should load default config if run for the first time
loadConfig(filename);//, TextMsg);
/*if (saveConfig(filename)) {
loadConfig(filename);
} */
// Dump config file
//Serial.println(F("Print config file...")); //printFile(filename);
Serial.println(F("Display Dot Matrix"));
P.begin();
P.displayClear();
//P.displayText("Selamat malam !", PA_CENTER, 70, 0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
}
int cnt=0;
void loop() {
if (P.displayAnimate()) {
P.displayText(TextMsg[cnt].Msg, PA_CENTER, 70, 0, Text_fX[TextMsg[cnt].fXi],
Text_fX[TextMsg[cnt].fXo]);
delay(500);
P.displayReset();
cnt += 1;
if (cnt==3) cnt=0;
}
}