2023年7月17日 星期一

ESP32 I2C Bus Scanner - DS3231 RTC section

DS3231-I2C 高精度時鐘模組

DS3231 RTC Module

The DS3231 is a low-cost, extremely accurate I²C real-time clock (RTC) with an integrated temperature-compensated crystal oscillator (TCXO) and crystal. The device incorporates a battery input and maintains accurate timekeeping when the main power to the device is interrupted.

Purpose:

In this project, We will use DS3231 Real Time Clock (RTC) module to keep track of the correct Time and Date value and display it on Serial Monitor using ESP32 as our microcontroller.

Circuit:
RTC Library:
YouTube Video:

Code Introduce:
#include <Wire.h>
#include <BluetoothSerial.h>
#include "RTClib.h"

BluetoothSerial SerialBT;
//----RTC-----------------------
RTC_DS3231 rtc;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
//--------- Flag structure --------------------------------------
typedef struct _vFlag
{
  uint8_t BTFlag = 0;
  uint8_t DC_Flag = 0;
  uint8_t CANFlag = 0;
  uint8_t I2C_Flag = 0;
  uint8_t BMP180Flag = 0;
  uint8_t MPU6050Flag = 0;
  uint8_t RTCFlag = 0;
  uint8_t JSONFlag = 0;
  uint8_t Radar_L_Flag = 0;
  uint8_t Radar_R_Flag = 0;
  uint8_t sensor_Flag = 0;
  uint8_t sensor1_Flag = 0;
  uint8_t initial_Flag = 0;
  uint8_t Tone_Flag = -1;
  uint8_t IR_RECV_Flag=0;
  uint8_t IR_SEND_Flag=0;
  uint8_t FunctionFlag = 3;
  uint8_t SendFlag = 0;
  uint8_t BMPCnt = 0;
} vFlag;
vFlag *flag_Ptr;
vFlag flag;
//----------uart--------------
#define LINE_BUFFER_LENGTH 64
//--------- uart structure --------------------------------------
typedef struct _vUart
{
  char c;
  int lineIndex = 0;
  int line1Index = 0;
  int BTlineIndex = 0;
  bool lineIsComment;
  bool lineSemiColon;
  //char *line;
  char line[128];
  //char line1[128];
  char BTline[20];
  //char R_line[20];
  //char L_line[20];
  String inputString;
  String BTinputString;
  String S1inputString;
  int V[16];
  char ctemp[30];
  char I2C_Data[80];
  int DC_Spped = 50;
  float Voltage[16];
  int Buffer[128];
  int StartCnt = 0;
  int ReadCnt = 0;
  int sensorValue = 0;
} vUart;
vUart *Uart_Ptr;
vUart Uart;

//-------------------------------------------------
void setup()
{
  Serial.begin(9600);
  Serial.println(F("init"));
  SerialBT.begin("BT_Node12");// BTName為藍芽廣播名稱

  Wire.begin(); //--i2c scanner
  //Wire.begin(21 , 22);//SCL DSDA
  Wire.setClock(400000); // 400千赫I2C時鐘。如果有編譯困難,請註釋這一行
  if (! rtc.begin())
  {
    Serial.println("Couldn't find RTC");
  }
  if (rtc.lostPower())
  {
    Serial.println("RTC lost power, let's set the time!");
    rtc.adjust(DateTime(2023, 7, 17, 10, 44, 39));
  }
}
//-----------------------------------------
void loop()
{
  Serial.print(F("Main at core:"));
  Serial.println(xPortGetCoreID());
  while(1)
  {
    while (Serial.available() > 0)
    {
      Uart.c = Serial.read();

      if ((Uart.c == '\n') || (Uart.c == '\r'))
      { // End of line reached
        if (Uart.lineIndex > 0)
        { // Line is complete. Then execute!
          Uart.line[Uart.lineIndex] = '\0'; // Terminate string
          //Serial.println( F("Debug") );
          //Serial.println( Uart.inputString );
          processCommand(Uart.line); // do something with the command
          //傳輸給藍芽
         
          Uart.lineIndex = 0;
          Uart.inputString = "";
        }
        else
        {
          // Empty or comment line. Skip block.
        }
        Uart.lineIsComment = false;
        Uart.lineSemiColon = false;
        Serial.println(F("ok>"));
      }
      else
      {
        //Serial.println( c );
        if ((Uart.lineIsComment) || (Uart.lineSemiColon))
        {
          if (Uart.c == ')')
            Uart.lineIsComment = false; // End of comment. Resume line.
        }
        else
        {
          if (Uart.c == '/')
          { // Block delete not supported. Ignore character.
          }
          else if (Uart.c == '~')
          { // Enable comments flag and ignore all characters until ')' or EOL.
            Uart.lineIsComment = true;
          }
          else if (Uart.c == ';')
          {
            Uart.lineSemiColon = true;
          }
          else if (Uart.lineIndex >= LINE_BUFFER_LENGTH - 1)
          {
            Serial.println("ERROR - lineBuffer overflow");
            Uart.lineIsComment = false;
            Uart.lineSemiColon = false;
          }
          else if (Uart.c >= 'a' && Uart.c <= 'z')
          { // Upcase lowercase
            Uart.line[Uart.lineIndex] = Uart.c - 'a' + 'A';
            Uart.lineIndex = Uart.lineIndex + 1;
            Uart.inputString += (char)(Uart.c - 'a' + 'A');
          }
          else
          {
            Uart.line[Uart.lineIndex] = Uart.c;
            Uart.lineIndex = Uart.lineIndex + 1;
            Uart.inputString += Uart.c;
          }
        }
      }
    } //while (Serial.available() > 0)
    while (SerialBT.available())
    {
      //讀取藍芽資料
      String BTdata = SerialBT.readString();
      //顯示在序列視窗
      Serial.println(BTdata);
      //char charBuf[BTdata.length() + 1];
      //BTdata.toCharArray(charBuf, BTdata.length());
      BTprocessCommand(BTdata); // do something with the command
      //processCommand(charBuf); // do something with the command
    }//while (BT.available())
    if(flag.I2C_Flag == 1)
    {
      vI2C_0_Task();
    }
    if(flag.RTCFlag == 1)
    {
      vRTCTask();
    }
 
  }
}
void BTprocessCommand(String data)
{
 
}
//----------------------------------------
void processCommand(char *data)
{
  int len, xlen, ylen, zlen, alen;
  int tempDIO;
  String stemp;

  len = Uart.inputString.length();
  //---------------------------------------
  if (strstr(data, "VER") != NULL)
  {
    Serial.println(F("ESP32_20230710"));
  }
 

  //-------------- I2C --------------------
  if (strstr(data, "I2C_SCAN") != NULL)
  {
    flag.I2C_Flag = 1;
    Serial.println(F("I2C_SCAN"));

  }

  if (strstr(data, "I2C_SCAN_OFF")!= NULL)
  {
    flag.I2C_Flag = 0;
    Serial.println(F("I2C_SCAN_OFF"));
  }
  //
  if (strstr(data, "MPU6050_ON")!= NULL)
  {
    flag.MPU6050Flag = 1;
    Serial.println(F("MPU6050_ON"));
  }
  if (strstr(data, "MPU6050_OFF")!= NULL)
  {
    flag.MPU6050Flag = 0;
    Serial.println(F("MPU6050_OFF"));
  }
  if (strstr(data, "RTC_ON")!= NULL)
  {
    flag.RTCFlag = 1;
    Serial.println(F("RTC_ON"));
  }
  if (strstr(data, "RTC_OFF")!= NULL)
  {
    flag.RTCFlag = 0;
    Serial.println(F("RTC_OFF"));
  }
}
//-----------------------------------------
void vI2C_0_Task()
{
  byte count = 0;

  Serial.println(F("I2C scanner. Scanning ..."));
  for (byte i = 1; i < 127; i++) //---scan address
  {
    Wire.beginTransmission(i);
    if (Wire.endTransmission() == 0)
    {
      Serial.print("Found_address:" + String(count + 1) + "_");
      Serial.print(i, DEC);
      Serial.print("_(0x");
      Serial.print(i, HEX);
      Serial.println(F(")"));
      count++;
      delay(5);
    }
    else
    {
      continue;
    }
  }
  Serial.println(F("Done."));
  Serial.print(F("Found: "));
  Serial.print(count, DEC);
  Serial.println(F(" device(s)."));
  flag.I2C_Flag = 0;
}
//-------------------------------------
void vRTCTask()
{
  DateTime now = rtc.now();
 
  Serial.print(now.hour(), DEC);
  Serial.print(":");
  Serial.print(now.minute(), DEC);
  Serial.print(":");
  Serial.print(now.second(), DEC);
  Serial.print(" -- ");
  Serial.print(now.day(), DEC);
  Serial.print("/");
  Serial.print(now.month(), DEC);
  Serial.print("/");
  Serial.println(now.year(), DEC);
 
  Serial.println(daysOfTheWeek[now.dayOfTheWeek()]);
  delay(1000);

}

沒有留言:

張貼留言