Smallest time clock chip? - SOLVED

Are you only looking at devices with the antique form with pins on the side of the package? There are other device forms that make a much smaller outline.
Paul

I'm looking at all. including QFN, TQFP packages.

Joseph

I see 22 possible QFN devices on Mouser. Their parameters do not include that ability to sort by size and I am not going to look at all the data sheets.
Paul

Hi @josephchrzempiec
I recently built a project that had little physical space for assembly.

For this project I use an ESP8266 and a watch quite accurately.
The project is powered by a battery and this battery is always being charged, and is only used in the event of a power failure.

In order not to waste space, I didn't use the RTC DS3xxx.

I figured ESP8266 could give me a good quality timebase.

To certify this quality, I decided to set up a project as follows:

I used an ESP8266, a DS3231 module and a "NTP" site access.

  1. In ESP8266 I used Tiker.h library with interrupt every 1 second and incremented the value of a variable named seG_ESP, counting from 0 to 59.

  2. Every second I also read the seconds of the RTC module and saved in a variable named seG_RTC,

  3. Access NTP reading the value of the second and saving it in a variable seG_NTP.

In setup() I synchronize the 3 clocks and in loop() after reading the 3 clocks I compare them.

I left it running in this way uninterruptedly for 20 days.
The result I got was the following:

Every 36 hours the DS3231 advanced 1 second and during these 20 days it advanced 13 seconds.

The clock using the ESP8266 oscillator during this 20 days remained unchanged, marking the same seconds as the NTC.

Looks like the DS3231 has a (complex) agging adjustment.

As the ESP8266 watch proved to be very reliable, it concludes that the use of an external RTC is unnecessary, besides saving space it saves $$$...

So I made my project without using external RTC,
and it's working very accurately.

RV - mineirin

Don't get me wrong a DS3231 is a great real time clock. However I'm limited on space. Because i added a lcd screen on the other end. I also added a temperature sensor, a 6 axis gyro, also the charging circuit. Also plan on adding one other thing. Leaving me with not much room for a full size Ds3231. Basically I'm building an IOT watch. Yes I can make the pcb Bigger, Myself this is what it'sfor I don't like large watches. Just fitting everyting to one pcb board is challenging.

Joseph

Are you already using a double sided board?
Paul

Hmmm. But the time library runs NTP sync in the background. Are you sure the system was not just constantly resynchronizing the time?

I asked previously, about internet access. I think it's really an important issue. How is a watch supposed to maintain network access as the wearer wanders aimlessly through their pointless existence?

Not yet . A Friend of mie is helping me to make one. One side is the screen the other side is everything else.

Joseph

Good plan!

There is nothing complex about the DS3231 aging adjustment. The data sheet specifies a nominal PPM offset for one digit change of the register value. You can adjust the register with a calibration routine referencing it to GPS PPS pulses. I haven't done it for that chip but I have done it for others, and it's not that hard. You can also do it manually, by providing settings for it in your clock applications.

The sun just set here. Cold dark pointlessly I wander existing. :expressionless:

a7

Yeah, well... do not go gentle into that good night... :wink:

Hi @anon57585045
The process is simple.
When I said that I synchronize the clocks in setup(), in reality what I do is the following.
I read the NTP, and when it reaches 0 I zero the seG_ESP and the RTC Ds3231.
From then on, each one runs independently of the other, and neither is affected by the other, only compared.
I asked a friend to check if I'm doing something wrong, and so far he hasn't helped me, (Lazy man). Hahahaha
I will post here the sketch I used.
If you can please help me identify where I might be going wrong.

Sorry but the comments of the lines are in Portuguese (Brazil).

RV - mineirin

#include <NTPClient.h>                  // Biblioteca do NTP   
#include <ESP8266WiFi.h>                // Biblioteca do WiFi  
#include <WiFiUdp.h>                    // Biblioteca do UDP   
WiFiUDP UDP;                            // Instancia UDP
NTPClient timeClient(UDP, "a.st1.ntp.br", -3 * 3600, 60000);  // Cria um objeto "NTP" e corrige fuso
#include <Wire.h>                       // I2C library
#include <LiquidCrystal_I2C.h>          // Biblioteca LCD I2C  
//LiquidCrystal_I2C lcd(0x39,  2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Endereco LCD I2C  (Invertido)
LiquidCrystal_I2C lcd(0x39,  2, 1, 0, 7, 6, 5, 4, 3, POSITIVE); // Endereco LCD I2C e pinos
#include <RTClib.h>                     // RTC library 
RTC_DS3231 rtc;                         // Instancia RTC
DateTime now;                           // variavel formato DateTime para RTC
#include <Ticker.h>                     // Biblioteca Tiker 
Ticker flipper;                         // Instancia Tiker
 
#define SDA 0                           // SDA do bus I2C
#define SCL 4                           // SCL do bus I2C
 
int segESP = 0;                         // Segundos gerados pelo ESP
int segNTP = 0;                         // Segundos gerados pelo NTP
int segRTC = 0;                         // Segundos gerados pelo RTC
bool newSeg = false;                    // Controle de comparacao
unsigned long horasTeste = 0;           // Contador de horas de teste
//--------------------------------------------------------------
void relogio()
{
  Serial.print("segNTP "); Serial.println(segNTP);    // Print
  Serial.print("segRTC "); Serial.println(segRTC);    // Print
  Serial.print("segESP "); Serial.println(segESP);    // Print
  Serial.println(" ");                                // Print
 
  lcd.setCursor(0, 1);                                // Posicao linha
  lcd.print(segNTP - segESP   );                      // Print diferenca entre segNTP e segESP
  lcd.print("  ");                                    // Print
  lcd.setCursor(4, 1);                                // Posicao linha
  lcd.print(segRTC - segNTP );                        // Print diferenca entre segRTC e segNTP
  lcd.setCursor(8, 1);                                // Posicao linha
  lcd.print(horasTeste / 60 );                        // Print time atualizado
  lcd.print("    ");                                  // Print
  lcd.setCursor(14, 1);                               // Posicao linha
  lcd.print(segNTP );                                 // Print Segundos do NTP
  lcd.print("  ");                                    // Print
}
//-----------------------------------------------------------------------
void flip() {
  String tempSeg;                                           // Varavel de trabalho
  ++segESP;                                                 // Incrementa segESP a cada segundo
  if (segESP == 60)                                         // Completou 1 minuto
  {
    segESP = 0;                                             // Reincia segESP
    horasTeste++;                                           // Incrementa contador (horas em minutos)
  }
  tempSeg = timeClient.getFormattedTime().substring(6);     // Busca segundo do NTP
  segNTP = tempSeg.toInt();                                 // Converte para inteiro
  newSeg = true;                                            // Informa que contou segundo;
}
//-----------------------------------------------------------------------
void setup() {
  Serial.begin(115200);                                     // Inicializa Serial
  Wire.begin(SDA, SCL);                                     // Inicializa I2C
  lcd.begin(16, 2);                                         // Inicializa LCD
  lcd.clear();                                              // Limpa LCD
 
  lcd.setCursor(0, 0);                                      // Posicao linha
  lcd.print("Synk relogios.");                              // Print time atualizado                                       
 
  lcd.setCursor(0, 1);                                      // Posicao linha
  WiFi.begin(ssid, password);                               // Conecta na rede (Digitie aqui suas credenciais)
  while ( WiFi.status() != WL_CONNECTED ) {                 // Enquanto nao conecta
    delay ( 500 );                                          // Aguarda nova tentativa
    Serial.print ( "." );                                   // Print
    lcd.print(".");                                         // Print
  }
  Serial.println(" ");                                      // Print
  Serial.print("Servidor iniciado com o IP \"");            // Print
  Serial.print(WiFi.localIP());                             // Informe IP obtido pelo DHCP
  Serial.println(" ");                                      // Print
  timeClient.begin();                                       // Inicializa NTP
  timeClient.update();                                      // Aguarda atualizacao
  timeClient.forceUpdate();                                 // Forca atualizacao
 
  rtc.begin();                                              // Inicializa RTC
 
  lcd.clear();                                              // Limpa LCD
  lcd.setCursor(0, 0);                                      // Posicao linha
  lcd.print("ESP");                                         // Print titulo
  lcd.print(" ");                                           // Print
  lcd.print("RTC");                                         // Print titulo
  lcd.print(" ");                                           // Print
  lcd.print("HTst");                                        // Print titulo
  lcd.print(" ");                                           // Print
  lcd.print("Seg");                                         // Print titulo
  lcd.print(" ");                                           // Print
 
  int oldTemp = 0;                                          // Variavel para ajudar na sincronizacao dos relogios
  String tempSeg;                                           // Varavel de trabalho
  flipper.attach(1, flip);                                  // Define tempo e nome da rotina de interrupt
 
  tempSeg = timeClient.getFormattedTime().substring(6);     // Busca segundo do NTP
  segNTP = tempSeg.toInt();                                 // Converte para inteiro
  oldTemp = segNTP;                                         // Salva o valor para comparacao
  while (segNTP == oldTemp)                                 // Quamdo forem diferentes mudou o segundo em NTP 
  {
    delay(10);                                              // Tempo para não travar o ESP
    tempSeg = timeClient.getFormattedTime().substring(6);   // Busca segundo do NTP
    segNTP = tempSeg.toInt();                               // Converte para inteiro
  }
 
  if (segNTP == 0)                                          // Verifica se é final de contagm de segundo
    segESP = 59;                                            // Recua 1 segundo para sincronizar 
  else                                                      // Ou em outros segundos
    segESP = segNTP - 1;                                    // Recua 1 segundo para sincronizar 
 
  rtc.adjust(DateTime(2021, 11, 01, 0, 0, segNTP));         // Atualiza os segundo do RTC3231
  now = rtc.now();                                          // Le o RTC
  tempSeg = now.second();                                   // Separa o segundo
  segRTC = tempSeg.toInt();                                 // Converte para numero inteiro
}
//-----------------------------------------------------------------------
void loop() {
  if (newSeg == true)                                       // Se passou 1 segundo
  {
    String tempSeg;                                         // Varavel de trabalho
    now = rtc.now();                                        // Le o RTC
    tempSeg = now.second();                                 // Separa o segundo
    segRTC = tempSeg.toInt();                               // Converte para numero inteiro
    relogio();                                              // Compara e mostra
    newSeg = false;                                         // Aguarda novo segundo
  }
}

It's not so much that you are "going wrong". The whole point is to keep your system time synchronized. But I think that it's actually difficult to disable the synch once you've invoked it.

Don't you consider it "suspicious" that a stock crystal is dead on after several days? That is almost supernatural if it's only due to the crystal.

OK Tks

I didn’t know my existence is pointless. Trying to wonder what I’m trying to do with my own watch. Make sense now I guess. Thanks for pointing that out to me I know I was missing something.

Joseph

Hello ruilviana, I’m not using anything WiFi as I stated before. Maybe Bluetooth to my phone or another devices once in a while but 95% of the time it will be a standalone watch.

Joseph

Hi @josephchrzempiec
My process doesn't use wifi either. I used wifi accessing NTP only to test if the ESP8266 crystal was accurate.
But in my final project I don't use wifi. Just the clock generated inside the ESP8266, which proved to be very accurate.

RV - mineirin

Hello Ruilviana, What happens if you not by the local wifi you set the SSID and password to update the time? But to be honest I wasn't thinking of wifi to set the time. More of the mobile app can do this through the bluetooth maybe is what I'm thinking?

Joseph

The DS3231 is nice but at $8+ a pop, it's pretty expensive. If the ESP32s built-in RTC can be clocked externally, then a cheaper accurate 32K oscillator would do the job.