بسم الله

با سلام و عرض تبریک به مناسبت میلاد بهترین و مهربانترین و اشرف انسانها پیامبر خاتم محمد مصطفی صل الله علیه و اله وسلم

دو برنامه جدا هست از اساتیدی که براشون امکان داره میخواهم که این 2 برنامه را باهم تلفیق کنن
به نحوی که همزمان ساعت روی 4 عدد 7segment ،و نمایش تاریخ روی ماژول 6 رقمی max7219 قابل نمایش باشد.
در ضمن این برنامه تاریخ میلادی و شمسی را بدون خطا نشون میده اما اگه گسی میتونه تاریخ قمری هم بهش اضافه کنه کاملتر میشه.
قطعات مور استفاده:
1-ESP32
2-چهار عدد 7segment آند مشترک
3- مازول 6رقمی max7219
4- ماژول ds3231
5- شیفت رجیستر 74HC595
..

1- نمایش ساعت روی 4 عدد 7segment آند مشترک
کد:
//Four-Digit 7 Segments Multiplexing using Arduino: Display time in HH:MM
//CIRCUIT DIGEST




#include <Wire.h>    //Library for SPI communication
#include <DS3231.h>   //Library for RTC module 

#define latchPin 7
#define clockPin 5
#define dataPin 6
#define dot 27

DS3231 RTC;         //Declare object RTC for class DS3231

int h;              //Variable declared for hour
int m;              //Variable declared for minute

int thousands;
int hundreds;
int tens;
int unit;

bool h24;
bool PM;

void setup ()
{
  Wire.begin();
  pinMode(A0, OUTPUT);
  pinMode(A1, OUTPUT);
  pinMode(A2, OUTPUT);
  pinMode(A3, OUTPUT);
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  pinMode(dot, OUTPUT);
}

void loop ()
{
  digitalWrite(dot, HIGH);
  int h = RTC.getHour(h24, PM); //To get the Hour from DS3231
  int m = RTC.getMinute();      //TO get the minute from DS3231
  int number = h * 100 + m;     //Converts hour and minute in 4-digit

  int t = unit;
  int u = tens;
  int v = hundreds;
  int w = thousands;

  Serial.begin(115200);
  Serial.print(thousands);
  Serial.println(hundreds);
  Serial.print(tens);
  Serial.println(unit);

  //Converting the individual digits into corresponding number for passing it through the shift register so LEDs are turned ON or OFF in seven segment
  // Up at the top:
  const byte SevenSegmentDigits[10] = {192, 249, 164, 176, 153, 146, 130, 248, 128, 144};

  // then your four big switch statements become:
  unit = SevenSegmentDigits[t];
  tens =  SevenSegmentDigits[u];
  hundreds =  SevenSegmentDigits[v];
  thousands = SevenSegmentDigits[w];

  digitalWrite(A0, HIGH);
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, SevenSegmentDigits[(number / 1000) % 10]); // Getting thousand digit from 4 digit & sent it
  digitalWrite(latchPin, HIGH);  // Set latch pin HIGH to store the inputs
  delay(500);                        // delay for multiplexing  
  digitalWrite(A0, LOW);         // Turinig on that thousands digit


  digitalWrite(A1, HIGH);
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, SevenSegmentDigits[(number / 100) % 10]); // Getting hundreds digit from 4 digit & sent it
  digitalWrite(latchPin, HIGH);
  delay(500);
  digitalWrite(A1, LOW);
  

  digitalWrite(A2, HIGH);
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, SevenSegmentDigits[(number / 10) % 10]); // Getting tens digit from 4 digit & sent it
  digitalWrite(latchPin, HIGH);
  delay(500);
  digitalWrite(A2, LOW);
  

  digitalWrite(A3, HIGH);
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, SevenSegmentDigits[number % 10]);  // Getting last uint digit from 4 digit & sent it
  digitalWrite(latchPin, HIGH);
  delay(500                                                                  );
  digitalWrite(A3, LOW);
  

}
2- نمایش تاریخ میلادی و شمسی و ساعت روی ماژول 6 رقمی با چیپ max7219
کد:
// CONNECTIONS:
// DS3231 SDA --> SDA
// DS3231 SCL --> SCL
// DS3231 VCC --> 3.3v or 5v
// DS3231 GND --> GND

/* for software wire use below
  #include <SoftwareWire.h>  // must be included here so that Arduino library object file references work
  #include <RtcDS3231.h>

  SoftwareWire myWire(SDA, SCL);
  RtcDS3231<SoftwareWire> Rtc(myWire);
  for software wire use above */

/* for normal hardware wire use below */
#include <Wire.h> // must be included here so that Arduino library object file references work
#include <RtcDS3231.h>
RtcDS3231<TwoWire> Rtc(Wire);
/* for normal hardware wire use above */

/*NEW for normal hardware wire use below */
//#include <NTPClient.h>
//#include <WiFi.h>
//#include <WiFiUdp.h>
// NTP
//WiFiUDP ntpUDP;

// RTC Libraries
//#include <RtcDateTime.h>
//#include "RTClib.h"
//RTC_DS3231 rtc;
#include <JDateLib.h>
/*NEW for normal hardware wire use above */
// WiFi details
//const char *ssid     = "mik";
//const char *password = "123";


String jdate;            // Jalali Date String
int JY, JM, JD;          // Jalali Year & Month & Day Intiger
char t[30];
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// define pins attached to MAX7219 (and also see notes above)
#define MAX7219_DIN           23
#define MAX7219_CS            5
#define MAX7219_CLK           18

// enumerate the MAX7219 registers
// See MAX7219 Datasheet, Table 2, page 7
enum {  MAX7219_REG_DECODE    = 0x09,
        MAX7219_REG_INTENSITY = 0x0A,
        MAX7219_REG_SCANLIMIT = 0x0B,
        MAX7219_REG_SHUTDOWN  = 0x0C,
        MAX7219_REG_DISPTEST  = 0x0F
     };

// enumerate the SHUTDOWN modes
// See MAX7219 Datasheet, Table 3, page 7
enum  { OFF = 0,
        ON  = 1
      };

const byte DP = 0b10000000;
const byte C  = 0b01001110;
const byte F  = 0b01000111;
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
/*
void WiFi_Setup() {
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  //  while (WiFi.status() != WL_CONNECTED) {
  delay(500);
  Serial.print(".");
  //  }
  Serial.println("");
  Serial.println("WiFi connected!");
}
*/
// ************************************


void setup ()
{
  Serial.begin(115200);

  Serial.print("compiled: ");
  Serial.print(__DATE__);
  Serial.println(__TIME__);
  // Farakhani dastorate Wifi jahat ejra
  //WiFi_Setup();

  //+++++++++++++++++++++++++
  //moarefi khoroji  esp32 be max7219
  Serial.println("max7219_7segment_date_time_temp");

  // define type of pin
  pinMode(MAX7219_DIN, OUTPUT);   // serial data-in
  pinMode(MAX7219_CS, OUTPUT);    // chip-select, active low
  pinMode(MAX7219_CLK, OUTPUT);   // serial clock
  digitalWrite(MAX7219_CS, HIGH);

  resetDisplay();                 // reset the MAX2719 display

  //+++++++++++++++++++++++++

  //--------RTC SETUP ------------
  // if you are using ESP-01 then uncomment the line below to reset the pins to
  // the available pins for SDA, SCL
  // Wire.begin(0, 2); // due to limited pins, use pin 0 and 2 for SDA, SCL

  Rtc.Begin();
  // This Below line sets the DS3231 time to the exact date and time the sketch was compiled:
  RtcDateTime compiled = RtcDateTime(__DATE__, __TIME__);
  printDateTime(compiled);
  Serial.println();

  if (!Rtc.IsDateTimeValid())
  {
    if (Rtc.LastError() != 0)
    {
      // we have a communications error
      // see https://www.arduino.cc/en/Reference/WireEndTransmission for
      // what the number means
      Serial.print("RTC communications error = ");
      Serial.println(Rtc.LastError());
    }
    else
    {
      // Common Causes:
      //    1) first time you ran and the device wasn't running yet
      //    2) the battery on the device is low or even missing

      Serial.println("RTC lost confidence in the DateTime!");

      // following line sets the RTC to the date & time this sketch was compiled
      // it will also reset the valid flag internally unless the Rtc device is
      // having an issue

      Rtc.SetDateTime(compiled);
    }
  }

  if (!Rtc.GetIsRunning())
  {
    Serial.println("RTC was not actively running, starting now");
    Rtc.SetIsRunning(true);
  }

  RtcDateTime now = Rtc.GetDateTime();
  if (now < compiled)
  {
    Serial.println("RTC is older than compile time!  (Updating DateTime)");
    Rtc.SetDateTime(compiled);
  }
  else if (now > compiled)
  {
    Serial.println("RTC is newer than compile time. (this is expected)");
  }
  else if (now == compiled)
  {
    Serial.println("RTC is the same as compile time! (not expected but all is fine)");
  }

  // never assume the Rtc was last configured by you, so
  // just clear them to your needed state
  Rtc.Enable32kHzPin(false);
  Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeNone);


}





void loop ()
{
  if (!Rtc.IsDateTimeValid())
  {
    if (Rtc.LastError() != 0)
    {
      // we have a communications error
      // see https://www.arduino.cc/en/Reference/WireEndTransmission for
      // what the number means
      Serial.print("RTC communications error = ");
      Serial.println(Rtc.LastError());
    }
    else
    {
      // Common Causes:
      //    1) the battery on the device is low or even missing and the power line was disconnected
      Serial.println("RTC lost confidence in the DateTime!");
    }
  }


  String str;                   // scratch or working string
  RtcDateTime now = Rtc.GetDateTime();
  printDateTime(now);
  Serial.println();

  // ... display Time, hh-mm-ss
  for ( int i = 0; i < 60; i++ ) {
    // read the time as a string from the RTC
    RtcDateTime now = Rtc.GetDateTime();
    sprintf(t, "%02d:%02d:%02d",   now.Hour(), now.Minute(), now.Second());

    //Serial.println(t);        // debug
    displayTime(t);           // display on the 7-segment
    delay(1000);
  }

  // ... display Date Miladi, yyyy.mm.dd
  sprintf(t, "%04d/%02d/%02d",   now.Year(), now.Month(), now.Day());

  Serial.print(F("Date miladi: "));
  Serial.println(t);
  displayDate(t);               // display on the 7-segment
  delay(5000);

  //....display Date, yyyy.mm.dd convert Miladi To Shamsi and print
  {
    //Read From Class  RtcDateTime now = Rtc.GetDateTime();
    int y = now.Year();
    int m = now.Month();
    int d = now.Day();
    //Send To Jdate Lib
    Date now(y, m, d);
    jdate = now.JDate();
    JY = now.JYear();
    JM = now.JMonth();
    JD = now.JDay();
    //Serial.println(JY);
    //Serial.println(JM);
    //Serial.println(JD);
    sprintf(t, "%04d/%02d/%02d",   now.JYear(), now.JDay(), now.JMonth());
    Serial.print(F("Date shamsi: "));
    Serial.println(t);
    //Serial.println(jdate);
    displayDate2(t);               // display on the 7-segment
    delay(6000);

  }


  // ... display Temperature in Celsius, xx.xx C
  // read the temperature, as a float, from the RTC
  RtcTemperature temp = Rtc.GetTemperature();
  str = String(temp.AsFloatDegC(), 2);             // format that value
  //Serial.println(str);            // debug
  displayTemp(str, C);            // display on the 7-segment
  delay(4000);

  // ... display Temperature in Fahrenheit, xx.xx F
  //t = t * 1.8 + 32.0;             // convert the value to Fahrenheit
  str = String(temp.AsFloatDegF(), 1);             // format that value
  //Serial.println(str);            // debug
  displayTemp(str, F);            // display on the 7-segment
  delay(1000);
}



// Utility print function
#define countof(a) (sizeof(a) / sizeof(a[0]))

void printDateTime(const RtcDateTime& dt)
{
  char datestring[20];

  snprintf_P(datestring,
             countof(datestring),
             PSTR("%04u/%02u/%02u %02u:%02u:%02u"),
             dt.Year(),
             dt.Month(),
             dt.Day(),
             dt.Hour(),
             dt.Minute(),
             dt.Second() );
  Serial.print(datestring);
}




// ... write a value into a max7219 register
// See MAX7219 Datasheet, Table 1, page 6
void set_register(byte reg, byte value)
{
  digitalWrite(MAX7219_CS, LOW);
  shiftOut(MAX7219_DIN, MAX7219_CLK, MSBFIRST, reg);
  shiftOut(MAX7219_DIN, MAX7219_CLK, MSBFIRST, value);
  digitalWrite(MAX7219_CS, HIGH);
}


// ... reset the max7219 chip
void resetDisplay()
{
  set_register(MAX7219_REG_SHUTDOWN, OFF);   // turn off display
  set_register(MAX7219_REG_DISPTEST, OFF);   // turn off test mode
  set_register(MAX7219_REG_INTENSITY, 0x0D); // display intensity
}


// ... display the DATE miladi on the 7-segment display
void displayDate(String dateString)
{
  set_register(MAX7219_REG_SHUTDOWN, OFF);  // turn off display
  set_register(MAX7219_REG_SCANLIMIT, 7);   // scan limit 8 digits
  set_register(MAX7219_REG_DECODE, 0b11111111); // decode all digits

  set_register(1, dateString.charAt(9));
  set_register(2, dateString.charAt(8));
  set_register(3, dateString.charAt(6) | DP);
  set_register(4, dateString.charAt(5));
  set_register(5, dateString.charAt(3) | DP); // plus decimal point
  set_register(6, dateString.charAt(2));
  set_register(7, dateString.charAt(1));
  set_register(8, dateString.charAt(0));

  set_register(MAX7219_REG_SHUTDOWN, ON);   // Turn on display
}

// ... display the DATE shamsi on the 7-segment display
void displayDate2(String dateString)
{
  set_register(MAX7219_REG_SHUTDOWN, OFF);  // turn off display
  set_register(MAX7219_REG_SCANLIMIT, 7);   // scan limit 8 digits
  set_register(MAX7219_REG_DECODE, 0b11111111); // decode all digits

  set_register(1, dateString.charAt(9));
  set_register(2, dateString.charAt(8));
  set_register(3, dateString.charAt(6) | DP);
  set_register(4, dateString.charAt(5));
  set_register(5, dateString.charAt(3) | DP); // plus decimal point
  set_register(6, dateString.charAt(2));
  set_register(7, dateString.charAt(1));
  set_register(8, dateString.charAt(0));

  set_register(MAX7219_REG_SHUTDOWN, ON);   // Turn on display
}


// ... display the TIME on the 7-segment display
void displayTime(String timeString)
{
  set_register(MAX7219_REG_SHUTDOWN, OFF);  // turn off display
  set_register(MAX7219_REG_SCANLIMIT, 7);   // scan limit 8 digits
  set_register(MAX7219_REG_DECODE, 0b11111111); // decode all digits

  set_register(1, timeString.charAt(7));
  set_register(2, timeString.charAt(6));
  set_register(3, timeString.charAt(5));
  set_register(4, timeString.charAt(4));
  set_register(5, timeString.charAt(3));
  set_register(6, timeString.charAt(2));
  set_register(7, timeString.charAt(1));
  set_register(8, timeString.charAt(0));

  set_register(MAX7219_REG_SHUTDOWN, ON);   // Turn on display
}


// ... display the TEMP on the 7-segment display
void displayTemp(String tempString, char C_or_F )
{
  set_register(MAX7219_REG_SHUTDOWN, OFF);  // turn off display
  set_register(MAX7219_REG_SCANLIMIT, 5);   // scan limit 6 digits
  set_register(MAX7219_REG_DECODE, 0b00111100); // decode 4 digits

  set_register(1, C_or_F);
  set_register(2, 0);                       // blank
  set_register(3, tempString.charAt(4));
  set_register(4, tempString.charAt(3));
  set_register(5, tempString.charAt(1) | DP); // plus decimal point
  set_register(6, tempString.charAt(0));

  set_register(MAX7219_REG_SHUTDOWN, ON);   // Turn On display
}