hai, salam kenal salam sejahtera.
sebelumnya saya minta maaf karena saya benar-bnar pemula.
semoga dikomunitas ini saya mendapatkan pelajaran baru dan bimbingan. Saya sedang mencoba belajar library SmartMatrix dengan esp32 dev modul. ingin menampilkan scrolling teks berganti pesan ,jam dengan RTC DS3231 dan pesan teks biasa bergantian di panel P5 64x32. Tampil secara bersamaan, cuman saya merasa kebingungan . semua tidak sesuai dengan keinginan. adakah yang sudi kiranya memberikan contoh kode.
dan apakah code yang saya ambil dari contoh smartMatrix salah. terimakasih
/*
SmartMatrix Features Demo - Louis Beaudoin (Pixelmatix)
This example code is released into the public domain
*/
#include <Wire.h>
#include <RtcDS3231.h>
RtcDS3231 Rtc(Wire);
//#include <SmartLEDShieldV4.h> // uncomment this line for SmartLED Shield V4 (needs to be before #include <SmartMatrix3.h>)
#include <SmartMatrix3.h>
//#include “colorwheel.c”
//#include “gimpbitmap.h”
#include <F1kM_Hisab.h>
#define COLOR_DEPTH 24 // known working: 24, 48 - If the sketch uses type rgb24
directly, COLOR_DEPTH must be 24
const uint8_t kMatrixWidth = 128; // known working: 32, 64, 96, 128
const uint8_t kMatrixHeight = 32; // known working: 16, 32, 48, 64
const uint8_t kRefreshDepth = 24; // known working: 24, 36, 48
const uint8_t kDmaBufferRows = 2; // known working: 2-4, use 2 to save memory, more to keep from dropping frames and automatically lowering refresh rate
const uint8_t kPanelType = SMARTMATRIX_HUB75_32ROW_MOD16SCAN; // use SMARTMATRIX_HUB75_16ROW_MOD8SCAN for common 16x32 panels
const uint8_t kMatrixOptions = (SMARTMATRIX_OPTIONS_NONE); // see SmartMatrix - Overview for options
const uint8_t kBackgroundLayerOptions = (SM_BACKGROUND_OPTIONS_NONE);
const uint8_t kScrollingLayerOptions = (SM_SCROLLING_OPTIONS_NONE);
const uint8_t kIndexedLayerOptions = (SM_INDEXED_OPTIONS_NONE);
SMARTMATRIX_ALLOCATE_BUFFERS(matrix, kMatrixWidth, kMatrixHeight, kRefreshDepth, kDmaBufferRows, kPanelType, kMatrixOptions);
SMARTMATRIX_ALLOCATE_BACKGROUND_LAYER(backgroundLayer, kMatrixWidth, kMatrixHeight, COLOR_DEPTH, kBackgroundLayerOptions);
SMARTMATRIX_ALLOCATE_SCROLLING_LAYER(scrollingLayer, kMatrixWidth, kMatrixHeight, COLOR_DEPTH, kScrollingLayerOptions);
SMARTMATRIX_ALLOCATE_INDEXED_LAYER(indexedLayer, kMatrixWidth, kMatrixHeight, COLOR_DEPTH, kIndexedLayerOptions);
const int defaultBrightness = (100 * 255) / 100; // full (100%) brightness
//const int defaultBrightness = (15*255)/100; // dim: 15% brightness
const int defaultScrollOffset = 6;
//const rgb24 defaultBackgroundColor = {0x40, 0, 0};
const rgb24 defaultBackgroundColor = {0, 0, 0};
// Teensy 3.0 has the LED on pin 13
const int ledPin = 13;
RtcDateTime now;
#define sdaPin 32
#define sclPin 33
char bulanMasehi[10] = { “”, “JANUARI”, “FEBRUARI”, “MARET”, “APRIL”, “MEI”, “JUNI”, “JULI”, “AGUSTUS”, “SEPTEMBER”, “OKTOBER”, “NOVEMBER”, “DESEMBER” };
char bulanHijriah[14] = { “”, “MUHARAM”, “SAFAR”, “RABIUL AWAL”, “RABIUL AKHIR”, “JUMADIL AWAL”, “JUMADIL AKHIR”, “RAJAB”, “SYA’BAN”, “RAMADAN”, “SYAWAL”, “ZULKAIDAH”, “ZULHIJAH” };
//char rhari[7] = {“”, “senin”, “selasa”, “rabu”, “kamis”, “jum’at”, “sabtu”, “minggu”};
uint8_t rJam;
uint8_t rMen;
uint8_t rDet;
uint8_t rTgl;
uint8_t rHar;
uint8_t rBul;
uint16_t rTah;
int celsius;
F1kM_Hisab HisabTanggal;
int Hjr_Date, Hjr_Month, Hjr_Year;
// Koordinat Tangerang
float latitud = -6.16;
float longitud = 108.61;
int hilal = -1;
/*
void drawBitmap(int16_t x, int16_t y, const gimp32x32bitmap* bitmap) {
for(unsigned int i=0; i < bitmap->height; i++) {
for(unsigned int j=0; j < bitmap->width; j++) {
rgb24 pixel = { bitmap->pixel_data[(i*bitmap->width + j)3 + 0],
bitmap->pixel_data[(ibitmap->width + j)3 + 1],
bitmap->pixel_data[(ibitmap->width + j)*3 + 2] };
backgroundLayer.drawPixel(x + j, y + i, pixel);
}
}
}
*/
// the setup() method runs once, when the sketch starts
void setup() {
// initialize the digital pin as an output.
pinMode(ledPin, OUTPUT);
Serial.begin(115200);
mulaiRTC();
matrix.addLayer(&backgroundLayer);
matrix.addLayer(&scrollingLayer);
matrix.addLayer(&indexedLayer);
matrix.begin();
matrix.setBrightness(defaultBrightness);
scrollingLayer.setOffsetFromTop(defaultScrollOffset);
UpdateWaktu();
jamBesar();
backgroundLayer.enableColorCorrection(true);
}
#define DEMO_INTRO 1
#define DEMO_DRAWING_CIRCLES 1
#define DEMO_SCROLL_MODES 1
// the loop() method runs over and over again,
// as long as the board has power
void loop() {
// int i, j;
unsigned long currentMillis;
// clear screen
// backgroundLayer.fillScreen(0);
backgroundLayer.fillScreen(defaultBackgroundColor);
backgroundLayer.swapBuffers();
UpdateWaktu();
#if (DEMO_INTRO == 1)
{
// “SmartMatrix Demo”
scrollingLayer.setColor({0xff, 0xff, 0xff});
scrollingLayer.setMode(wrapForward);
scrollingLayer.setSpeed(40);
scrollingLayer.setFont(font6x10);
scrollingLayer.start(“SmartMatrix Demo”, 1);
delay(5000);
}
#endif
// font options
#if (DEMO_DRAWING_CIRCLES == 1)
{
RtcDateTime now = Rtc.GetDateTime();
char jam[3];
char menit[3];
char detik[3];
//sprintf(jam, "%02d:%02d:%02d", rJam, rMen, rDet);
sprintf(jam, "%02d", now.Hour());
sprintf(menit, "%02d", now.Minute());
sprintf(detik, "%02d", now.Second());
unsigned long currentMillis;
// "Drawing Functions"
scrollingLayer.setColor({0xff, 0xff, 0xff});
scrollingLayer.setMode(wrapForward);
scrollingLayer.setOffsetFromTop(20);
scrollingLayer.setSpeed(40);
scrollingLayer.setFont(font8x13);
scrollingLayer.start("PRAYER SCHEDULE 5 TIMES", 1);
scrollingLayer.setColor(rgb24(200, 250, 0));
const uint transitionTime = 10000;
const int delayBetweenCharacters = 3000;
const int leftEdgeOffset = 1;
currentMillis = millis();
backgroundLayer.fillScreen({0, 0, 0});
backgroundLayer.swapBuffers();
backgroundLayer.setFont(font8x13);
scrollingLayer.setSpeed(40);
backgroundLayer.drawString(0, 0, {0xff, 0xff, 0xff}, jam);
backgroundLayer.setFont(font5x7);
backgroundLayer.drawString(21, 2, {0xff, 0xff, 0xff}, menit);
backgroundLayer.drawString(21, 10, {0xff, 0xff, 0xff}, detik);
backgroundLayer.swapBuffers();
backgroundLayer.swapBuffers(false);
backgroundLayer.setFont(font5x7);
backgroundLayer.fillScreen({0, 0, 0});
backgroundLayer.drawString(33, matrix.getScreenHeight() / 20, {0xff, 0, 0}, "SUBUH");
delay(delayBetweenCharacters);
backgroundLayer.swapBuffers();
backgroundLayer.setFont(font5x7);
backgroundLayer.fillScreen({0, 0, 0});
backgroundLayer.drawString(33, matrix.getScreenHeight() / 20, {0xff, 0, 0}, "DHUHUR");
delay(delayBetweenCharacters);
backgroundLayer.swapBuffers();
backgroundLayer.setFont(font5x7);
backgroundLayer.fillScreen({0, 0, 0});
backgroundLayer.drawString(33, matrix.getScreenHeight() / 20, {0xff, 0, 0}, "ASHAR");
delay(delayBetweenCharacters);
backgroundLayer.swapBuffers();
backgroundLayer.setFont(font5x7);
backgroundLayer.fillScreen({0, 0, 0});
backgroundLayer.drawString(33, matrix.getScreenHeight() / 20, {0xff, 0, 0}, "MAGRIB");
delay(delayBetweenCharacters);
backgroundLayer.swapBuffers();
backgroundLayer.setFont(font5x7);
backgroundLayer.fillScreen({0, 0, 0});
backgroundLayer.drawString(33, matrix.getScreenHeight() / 20, {0xff, 0, 0}, "ISYA'");
delay(delayBetweenCharacters);
backgroundLayer.swapBuffers();
while (millis() < currentMillis + transitionTime);
}
#endif
// different modes
#if (DEMO_SCROLL_MODES == 1)
{
uint transitionTime;
RtcDateTime now = Rtc.GetDateTime();
UpdateWaktu();
char jam[3];
char menit[3];
char detik[3];
//sprintf(jam, "%02d:%02d:%02d", rJam, rMen, rDet);
sprintf(jam, "%02d", now.Hour());
sprintf(menit, "%02d", now.Minute());
sprintf(detik, "%02d", now.Second());
backgroundLayer.fillScreen(defaultBackgroundColor);
backgroundLayer.swapBuffers();
scrollingLayer.setColor(rgb24(200, 250, 0));
backgroundLayer.setFont(font8x13);
scrollingLayer.setSpeed(40);
backgroundLayer.drawString(0, 0, {0xff, 0xff, 0xff}, jam);
backgroundLayer.setFont(font5x7);
backgroundLayer.drawString(21, 1, {0xff, 0xff, 0xff}, menit);
backgroundLayer.drawString(21, 10, {0xff, 0xff, 0xff}, detik);
backgroundLayer.swapBuffers();
backgroundLayer.setFont(font5x7);
backgroundLayer.fillScreen({0, 0, 0});
backgroundLayer.drawString(33, matrix.getScreenHeight() / 20, {0xff, 0, 0}, "SUBUH");
delay(2000);
backgroundLayer.swapBuffers();
backgroundLayer.setFont(font5x7);
backgroundLayer.fillScreen({0, 0, 0});
backgroundLayer.drawString(33, matrix.getScreenHeight() / 20, {0xff, 0, 0}, "DHUHUR");
delay(2000);
backgroundLayer.swapBuffers();
backgroundLayer.setFont(font5x7);
backgroundLayer.fillScreen({0, 0, 0});
backgroundLayer.drawString(33, matrix.getScreenHeight() / 20, {0xff, 0, 0}, "ASHAR");
delay(2000);
backgroundLayer.swapBuffers();
backgroundLayer.setFont(font5x7);
backgroundLayer.fillScreen({0, 0, 0});
backgroundLayer.drawString(33, matrix.getScreenHeight() / 20, {0xff, 0, 0}, "MAGRIB");
delay(2000);
backgroundLayer.swapBuffers();
backgroundLayer.setFont(font5x7);
backgroundLayer.fillScreen({0, 0, 0});
backgroundLayer.drawString(33, matrix.getScreenHeight() / 20, {0xff, 0, 0}, "ISYA'");
delay(2000);
backgroundLayer.swapBuffers();
scrollingLayer.setFont(font8x13);
scrollingLayer.setMode(wrapForward);
scrollingLayer.start("TEXT RUN RIGHT LEFT CONTINUE", 1);
while (scrollingLayer.getStatus());
// use this mode to start the scrolling from any position, instead of the right edge
scrollingLayer.setMode(wrapForward);
scrollingLayer.setOffsetFromTop(20);
scrollingLayer.start("SMARTMATRIX RUNNING TEXT AND CLOCK", 1);
while (scrollingLayer.getStatus());
scrollingLayer.setMode(wrapForward);
scrollingLayer.start("WINDA", 1);
while (scrollingLayer.getStatus());
scrollingLayer.setMode(wrapForward);
scrollingLayer.start("SMARTMATRIX 01", 1);
while (scrollingLayer.getStatus());
// this mode doesn't scroll, and the position is set through setScrollStartOffsetFromLeft()
scrollingLayer.setMode(stopped);
scrollingLayer.start("SMARTMATRIX 02", 1);
scrollingLayer.setStartOffsetFromLeft(0);
transitionTime = 3000;
currentMillis = millis();
// "stopped" will always have getScrollStatus() > 0, use time to transition)
while (millis() - currentMillis < transitionTime);
scrollingLayer.setMode(wrapForward);
scrollingLayer.start("SMARTMATRIX 03 TEXT", 1);
while (scrollingLayer.getStatus() > 1);
scrollingLayer.update("SMARTMATRIX 04");
while (scrollingLayer.getStatus());
scrollingLayer.setMode(wrapForward);
// setup text to scroll infinitely
scrollingLayer.start("SMARTMATRIX 05", -1);
transitionTime = 4500;
currentMillis = millis();
while (millis() - currentMillis < transitionTime);
scrollingLayer.stop();
currentMillis = millis();
transitionTime = 1000;
while (millis() - currentMillis < transitionTime);
backgroundLayer.fillScreen(defaultBackgroundColor);
backgroundLayer.swapBuffers();
}
#endif
}
/*
// fonts
void JamRunning()
{
//JadwalSholat();
RtcDateTime now = Rtc.GetDateTime();
//jamBesar();
// char tanggal[9];
char jam[3];
char menit[3];
char detik[3];
char tanggalhijriah[34];
char tanggalmasehi[16];
sprintf(jam, “%02d”, now.Hour());
sprintf(menit, “%02d”, now.Minute());
sprintf(detik, “%02d”, now.Second());
UpdateWaktu();
// sprintf(jam, “%02d:%02d:%02d”, rJam, rMen, rDet);
sprintf(tanggalmasehi, " %d %s %d ", rTgl, bulanMasehi[rBul], rTah);
sprintf(tanggalhijriah, “%d %s %d”, Hjr_Date, bulanHijriah[Hjr_Month], Hjr_Year);
backgroundLayer.setFont(font8x13);
backgroundLayer.drawString(0, matrix.getScreenHeight() / 20, {0xff, 0xff, 0xff}, jam);
backgroundLayer.setFont(font5x7);
backgroundLayer.drawString(21, matrix.getScreenHeight() / 20, {0xff, 0xff, 0xff}, menit);
backgroundLayer.setFont(font5x7);
backgroundLayer.drawString(21, matrix.getScreenHeight() / 4, {0xff, 0xff, 0xff}, detik);
backgroundLayer.swapBuffers();
scrollingLayer.setColor(rgb24(200, 250, 0));
// scrollingLayer.setColor({0xff, 0xff, 0xff});
scrollingLayer.setMode(wrapForward);
scrollingLayer.setSpeed(40);
scrollingLayer.setOffsetFromTop(20);
scrollingLayer.setFont(font8x13);
scrollingLayer.start(“WINDA JWS RUNNING TEXT SMART MATRIX P5”, 1);
while (scrollingLayer());
scrollingLayer.setFont(font8x13);
scrollingLayer.start(“UNTUK KEPENTINGAN SOSIAL, MASJID, MUSHOLA, SEKOLAH”, 1);
while (scrollingLayer.getStatus());
scrollingLayer.setFont(font8x13);
scrollingLayer.start(tanggalmasehi, 1);
while (scrollingLayer.getStatus());
scrollingLayer.setFont(font8x13);
scrollingLayer.start(tanggalhijriah, 1);
while (scrollingLayer.getStatus());
scrollingLayer.setOffsetFromTop(defaultScrollOffset);
}
*/
void jamBesar() {
RtcDateTime now = Rtc.GetDateTime();
char jam[3];
char menit[3];
char detik[3];
sprintf(jam, “%02d”, now.Hour());
sprintf(menit, “%02d”, now.Minute());
sprintf(detik, “%02d”, now.Second());
backgroundLayer.fillScreen({0, 0, 0});
backgroundLayer.swapBuffers();
backgroundLayer.setFont(font8x13);
//backgroundLayer.fillScreen({0, 0, 0});
backgroundLayer.drawString(0, matrix.getScreenHeight() / 20, {0xff, 0, 0}, jam);
backgroundLayer.setFont(font5x7);
// backgroundLayer.fillScreen({0, 0, 0});
backgroundLayer.drawString(21, matrix.getScreenHeight() / 20, {0xff, 0, 0}, menit);
backgroundLayer.setFont(font5x7);
// backgroundLayer.fillScreen({0, 0, 0});
backgroundLayer.drawString(21, matrix.getScreenHeight() / 4, {0xff, 0, 0}, detik);
backgroundLayer.setFont(font5x7);
backgroundLayer.swapBuffers();
}
// ------------------
// MULAI RTC DS3231
void mulaiRTC() {
//RTC D3231
int rtn = I2C_ClearBus(); // clear the I2C bus first before calling Wire.begin()
if (rtn != 0) {
Serial.println(F(“I2C bus error. Could not clear”));
if (rtn == 1) {
Serial.println(F(“SCL clock line held low”));
} else if (rtn == 2) {
Serial.println(F(“SCL clock line held low by slave clock stretch”));
} else if (rtn == 3) {
Serial.println(F(“SDA data line held low”));
}
} else { // bus clear, re-enable Wire, now can start Wire Arduino master
Wire.begin(sdaPin, sclPin);
}
Rtc.Begin();
if (!Rtc.GetIsRunning()) {
Rtc.SetIsRunning(true);
}
Rtc.Enable32kHzPin(false);
Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeNone);
Serial.println(“Setup RTC selesai”);
}
//--------------
// UPDATE WAKTU
void BacaRTC() {
RtcDateTime now = Rtc.GetDateTime();
RtcTemperature temp = Rtc.GetTemperature();
celsius = temp.AsFloatDegC();
rJam = now.Hour();
rMen = now.Minute();
rDet = now.Second();
rTgl = now.Day();
rHar = now.DayOfWeek();
rBul = now.Month();
rTah = now.Year();
}
// ----------------------
// UPDATE HISAB TANGGAL
void TanggalHijriah() {
HisabTanggal.setLocationOnEarth(latitud, longitud); //Latitude Longitude TANGERANG
HisabTanggal.setHilalVisibilityFactor(hilal);
HisabTanggal.Greg2HijrDate(rTgl, rBul, rTah, Hjr_Date, Hjr_Month, Hjr_Year);
}
//--------------
// UPDATE WAKTU
void UpdateWaktu() {
static long pM;
static uint16_t d;
if (millis() - pM > 1000) {
d++;
if (d < 2) {
BacaRTC();
TanggalHijriah();
} else if (d < 60) { // Update setiap 60 detik
rDet++;
if (rDet > 59) {
rMen++;
rDet = 0;
if (rMen > 59) {
rJam++;
rMen = 0;
}
}
} else {
d = 0;
}
pM = millis();
}
delay(1000);
}
//----------------------------------------------------------------------
// I2C_ClearBus menghindari gagal baca RTC (nilai 00 atau 165)
int I2C_ClearBus() {
#if defined(TWCR) && defined(TWEN)
TWCR &= ~(_BV(TWEN)); //Disable the Atmel 2-Wire interface so we can control the SDA and SCL pins directly
#endif
pinMode(sdaPin, INPUT_PULLUP); // Make SDA (data) and SCL (clock) pins Inputs with pullup.
pinMode(sclPin, INPUT_PULLUP);
delay(2500); // Wait 2.5 secs. This is strictly only necessary on the first power
// up of the DS3231 module to allow it to initialize properly,
// but is also assists in reliable programming of FioV3 boards as it gives the
// IDE a chance to start uploaded the program
// before existing sketch confuses the IDE by sending Serial data.
boolean SCL_LOW = (digitalRead(sclPin) == LOW); // Check is SCL is Low.
if (SCL_LOW) { //If it is held low Arduno cannot become the I2C master.
return 1; //I2C bus error. Could not clear SCL clock line held low
}
boolean SDA_LOW = (digitalRead(sdaPin) == LOW); // vi. Check SDA input.
int clockCount = 20; // > 2x9 clock
while (SDA_LOW && (clockCount > 0)) { // vii. If SDA is Low,
clockCount–;
// Note: I2C bus is open collector so do NOT drive SCL or SDA high.
pinMode(sclPin, INPUT); // release SCL pullup so that when made output it will be LOW
pinMode(sclPin, OUTPUT); // then clock SCL Low
delayMicroseconds(10); // for >5uS
pinMode(sclPin, INPUT); // release SCL LOW
pinMode(sclPin, INPUT_PULLUP); // turn on pullup resistors again
// do not force high as slave may be holding it low for clock stretching.
delayMicroseconds(10); // for >5uS
// The >5uS is so that even the slowest I2C devices are handled.
SCL_LOW = (digitalRead(sclPin) == LOW); // Check if SCL is Low.
int counter = 20;
while (SCL_LOW && (counter > 0)) { // loop waiting for SCL to become High only wait 2sec.
counter–;
delay(100);
SCL_LOW = (digitalRead(sclPin) == LOW);
}
if (SCL_LOW) { // still low after 2 sec error
return 2; // I2C bus error. Could not clear. SCL clock line held low by slave clock stretch for >2sec
}
SDA_LOW = (digitalRead(sdaPin) == LOW); // and check SDA input again and loop
}
if (SDA_LOW) { // still low
return 3; // I2C bus error. Could not clear. SDA data line held low
}
// else pull SDA line low for Start or Repeated Start
pinMode(sdaPin, INPUT); // remove pullup.
pinMode(sdaPin, OUTPUT); // and then make it LOW i.e. send an I2C Start or Repeated start control.
// When there is only one I2C master a Start or Repeat Start has the same function as a Stop and clears the bus.
/// A Repeat Start is a Start occurring after a Start with no intervening Stop.
delayMicroseconds(10); // wait >5uS
pinMode(sdaPin, INPUT); // remove output low
pinMode(sdaPin, INPUT_PULLUP); // and make SDA high i.e. send I2C STOP control.
delayMicroseconds(10); // x. wait >5uS
pinMode(sdaPin, INPUT); // and reset pins as tri-state inputs which is the default state on reset
pinMode(sclPin, INPUT);
return 0; // all ok
}