DS3231 do not run when arduino board no power

/*
modified by varind in 2013
this code is public domain, enjoy!
 */
#include <Wire.h>
#include "DS3231RTC.h"
#include <DS3231.h>
DS3231  rtc(SDA, SCL);
#include <FastLED.h> 
#define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))
#include <LiquidCrystal.h>
#include <fix_fft.h>
#include <Servo.h> 
#define BUFF_MAX 128
#define LCHAN 0
#define RCHAN 1
int buttonPin = 0;    // momentary push button on pin 0
int oldButtonVal = 0;
const int channels = 2;
const int xres = 16;
const int yres = 8;
const int xres2 = 32;
const int yres2 = 8;
const int gain = 3;
int decaytest = 1;
char im[64], data[64];
char Rim[64], Rdata[64];
char data_avgs[32];
float peaks[32];
int i = 0,val,Rval;
int x = 0, y=0, z=0;
int load;
int nPatterns = 9 ;
int lightPattern = 1;
int   lmax[2];                                        // level max memory
int   dly[2];   // delay & speed for peak return
uint8_t time[8];
char recv[BUFF_MAX];
unsigned int recv_size = 0;
unsigned long prev, interval = 1000;


LiquidCrystal lcd(12, 11, 5, 4, 3, 2); //saves 5 pwm pins for servos, leds, etc


// VU METER CHARACTERS
byte v1[8] = {
  B00000,B00000,B00000,B00000,B00000,B00000,B00000,B11111};
byte v2[8] = {
  B00000,B00000,B00000,B00000,B00000,B00000,B11111,B11111};
byte v3[8] = {
  B00000,B00000,B00000,B00000,B00000,B11111,B11111,B11111};
byte v4[8] = {
  B00000,B00000,B00000,B00000,B11111,B11111,B11111,B11111};
byte v5[8] = {
  B00000,B00000,B00000,B11111,B11111,B11111,B11111,B11111};
byte v6[8] = {
  B00000,B00000,B11111,B11111,B11111,B11111,B11111,B11111};
byte v7[8] = {
  B00000,B11111,B11111,B11111,B11111,B11111,B11111,B11111};
byte v8[8] = {
  B11111,B11111,B11111,B11111,B11111,B11111,B11111,B11111};


void setup() {
    Wire.begin();
    DS3231_init(DS3231_INTCN);
    memset(recv, 0, BUFF_MAX);
    rtc.begin();
     pinMode(buttonPin, INPUT);
    digitalWrite(buttonPin, HIGH);  // button pin is HIGH, so it drops to 0 if pressed
    setTheTime("305622107112023");     // ssmmhhDDMMYYYY set time once in the given format
  lcd.begin(16, 2);
  lcd.clear();
  lcd.createChar(1, v1);
  lcd.createChar(2, v2);
  lcd.createChar(3, v3);
  lcd.createChar(4, v4);
  lcd.createChar(5, v5);
  lcd.createChar(6, v6);
  lcd.createChar(7, v7);
  lcd.createChar(8, v8);
 
 for (i=0;i<80;i++)
  {
    for (load = 0; load < i / 5; load++)
    {
      lcd.setCursor(load, 1);
      lcd.write(1);
    }
    if (load < 1)
    {
      lcd.setCursor(0, 1);
      lcd.write(7);
    }

    lcd.setCursor(load + 1, 1);
    lcd.write((i - i / 5 * 5) + 1);
    for (load = load + 2; load < 16; load++)
    {
      lcd.setCursor(load, 1);
      lcd.write(1);
    }
    lcd.setCursor(0, 0);
    lcd.print("  Mehmet KIRAN  ");
    delay(50);
  }
  lcd.clear();
  delay(500);
}
  


void vu() {
//  delay(10);
  for (i=0; i < 64; i++){    
    val = ((analogRead(LCHAN) / 4 ) - 128);  // chose how to interpret the data from analog in
    data[i] = val;                                      
    im[i] = 0;   
    if (channels ==2){
      Rval = ((analogRead(RCHAN) / 4 ) - 128);  // chose how to interpret the data from analog in
      Rdata[i] = Rval;                                      
      Rim[i] = 0;   
    }
  };

  fix_fft(data,im,6,0); // Send the data through fft
  if (channels == 2){
    fix_fft(Rdata,Rim,6,0); // Send the data through fft
  }

  // get the absolute value of the values in the array, so we're only dealing with positive numbers
  for (i=0; i< 32 ;i++){  
    data[i] = sqrt(data[i] * data[i] + im[i] * im[i]); 
  }
  if (channels ==2){
    for (i=16; i< 32 ;i++){  
      data[i] = sqrt(Rdata[i-16] * Rdata[i-16] + Rim[i-16] * Rim[i-16]); 
    }
  }

  // todo: average as many or as little dynamically based on yres
  for (i=0; i<32; i++) {
    data_avgs[i] = (data[i]);// + data[i*2+1]);// + data[i*3 + 2]);// + data[i*4 + 3]);  // add 3 samples to be averaged, use 4 when yres < 16
    data_avgs[i] = constrain(data_avgs[i],0,9-gain);  //data samples * range (0-9) = 9
    data_avgs[i] = map(data_avgs[i], 0, 9-gain, 0, yres);        // remap averaged values
  }

} // end loop








void decay(int decayrate){
  //// reduce the values of the last peaks by 1 
  if (decaytest == decayrate){
    for (x=0; x < 32; x++) {
      peaks[x] = peaks[x] - 1;  // subtract 1 from each column peaks
      decaytest = 0;
      
    }
  }
  decaytest++;

}



void Two16_LCD() {
  vu();
  decay(1); 
  lcd.setCursor(0, 0);
  lcd.print("L"); // Channel ID replaces bin #0 due to hum & noise
  lcd.setCursor(0, 1);
  lcd.print("R"); // ditto

  for (int x = 1; x < 16; x++) {  // init 0 to show lowest band overloaded with hum
    int y = x + 16; // second display line
    if (data_avgs[x] > peaks[x]) peaks[x] = data_avgs[x];
    if (data_avgs[y] > peaks[y]) peaks[y] = data_avgs[y];

    lcd.setCursor(x, 0); // draw first (top) row Left
    if (peaks[x] == 0) {
      lcd.print("_");  // less LCD artifacts than " "
    }
    else {
      lcd.write(peaks[x]);
    }

    lcd.setCursor(x, 1); // draw second (bottom) row Right
    if (peaks[y] == 0) {
      lcd.print("_");
    }
    else {
      lcd.write(peaks[y]);
    
    }
  }
}

void mono(){ 
  vu();
   decay(1); 
  lcd.setCursor(0, 0);
  lcd.print(" "); // Channel ID replaces bin #0 due to hum & noise
  lcd.setCursor(0, 1);
  lcd.print("M"); // ditto
  for (x=1; x < 16; x++) {  // repeat for each column of the display horizontal resolution
    y = data_avgs[x];  // get current column value 
        z= peaks[x];
    if (y > z){
      peaks[x]=y;
    }
    y= peaks[x]; 

    if (y <= 8){            
      lcd.setCursor(x,0); // clear first row
      lcd.print(" ");
      lcd.setCursor(x,1); // draw second row
      if (y == 0){
        lcd.print(" "); // save a glyph
      }
      else {
        lcd.write(y);
      }
    }
    else{
      lcd.setCursor(x,0);  // draw first row
      if (y == 9){
        lcd.write(" ");  
      }
      else {
        lcd.write(y-8);  // same chars 1-8 as 9-16
      }
      lcd.setCursor(x,1);
      lcd.write(8);  
    } // end display
  }  // end xres
}

void stereo8(){
  vu();
   decay(1); 
   lcd.setCursor(8, 1);
  lcd.print("R"); // Channel ID replaces bin #0 due to hum & noise
  for (x=1; x < 8; x++) {
    y = data_avgs[x];
        z= peaks[x];
    if (y > z){
      peaks[x]=y;
    }
    y= peaks[x]; 

    if (y <= 8){            
      lcd.setCursor(x,0); // clear first row
      lcd.print(" ");
      lcd.setCursor(x,1); // draw second row
      if (y == 0){
        lcd.print(" "); // save a glyph
      }
      else {
        lcd.write(y);
      }
    }
    else{
      lcd.setCursor(x,0);  // draw first row
      if (y == 9){
        lcd.write(" ");  
      }
      else {
        lcd.write(y-8);  // same chars 1-8 as 9-16
      }
      lcd.setCursor(x,1);
      lcd.write(8);  
    }
  }
  lcd.setCursor(0, 1);
  lcd.print("L"); // ditto
  for (x=17; x < 32; x++) {
    y = data_avgs[x];
       z= peaks[x];
    if (y > z){
      peaks[x]=y;
    }
    y= peaks[x]; 

    if (y <= 8){            
      lcd.setCursor(x-8,0); // clear first row
      lcd.print(" ");
      lcd.setCursor(x-8,1); // draw second row
      if (y == 0){
        lcd.print(" "); // save a glyph
      }
      else {
        lcd.write(y);
      }
    }
    else{
      lcd.setCursor(x-8,0);  // draw first row
      if (y == 9){
        lcd.write(" ");  
      }
      else {
        lcd.write(y-8);  // same chars 1-8 as 9-16
      }
      lcd.setCursor(x-8,1);
      lcd.write(8);  
    }
  }
}


void  bars  ()
{
  decay(1);
  vu();
//  lcd.createChar( i,block[i] );
  #define T_REFRESH    100            // msec bar refresh rate
  #define T_PEAKHOLD   5*T_REFRESH    // msec peak hold time before return
  long  lastT=0;
//  if( millis()<lastT )
//    return;
//  lastT += T_REFRESH;    
  int anL = map( sqrt( analogRead( LCHAN  )*16 ),0,128,0,80 );  // sqrt to have non linear scale (better was log)
  int anR = map( sqrt( analogRead( RCHAN )*16 ),0,128,0,80 );
  bar( 0,anL );
  bar( 1,anR );
}

void  bar  ( int rows,int levs )
{
  lcd.setCursor( 0,rows );
  lcd.write( rows ? 'R' : 'L' );
  for( int i=1 ; i<16 ; i++ )
  {
    int f=constrain( levs      -i*5,0,5 );
    int p=constrain( lmax[rows]-i*5,0,6 );
    if( f )
      lcd.write(8);
    else
      lcd.write(" ");
  }
  if( levs>lmax[rows] )
  {
    lmax[rows] = levs;
    dly[rows]  = -(T_PEAKHOLD)/T_REFRESH;                // Starting delay value. Negative=peak don't move
  }
  else
  {
    if( dly[rows]>0 )
      lmax[rows] -= dly[rows]; 

    if( lmax[rows]<0 )
      lmax[rows]=0;
    else
      dly[rows]++;
  }
}



void stereo16(){
  vu();
   decay(1); 
  lcd.setCursor(0, 0);
  lcd.print(" "); // Channel ID replaces bin #0 due to hum & noise
  
  for (x=1; x < 16; x++) {
    y = data_avgs[x];
         z= peaks[x];
    if (y > z){
      peaks[x]=y;
    }
    y= peaks[x]; 
    if (x < xres){            
      lcd.setCursor(x,0); // draw first row
      if (y == 0){
        lcd.print(" "); // save a glyph
      }
      else {
        lcd.write(y);
      }
    }
  }
lcd.setCursor(0, 1);
  lcd.print(" "); // Channel ID replaces bin #0 due to hum & noise
  for (x=17; x < 32; x++) {
    y = data_avgs[x];
        z= peaks[x];
    if (y > z){
      peaks[x]=y;
    }
    y= peaks[x]; 
    if (x-16 < xres){            
      lcd.setCursor(x-16,1); // draw second row
      if (y == 0){
        lcd.print(" "); // save a glyph
      }
      else {
        lcd.write(y);
      }
    }
  }
}


void thirtytwoband(){
   vu();
   decay(1); 
  for (x=0; x < 32; x++) {
    y = data_avgs[x];

        z= peaks[x];
    if (y > z){
      peaks[x]=y;
    }
    y= peaks[x]; 
    if (x < 16){            
      lcd.setCursor(x,0); // draw second row
      if (y == 0){
        lcd.print(" "); // save a glyph
      }
      else {
        lcd.write(y);
      }
    }
    else{
      lcd.setCursor(x-16,1);
      if (y == 0){
        lcd.print(" ");
      }
      else {
        lcd.write(y);
      }
    }
  }
}

void simple() {
 lcd.setCursor(0,0);
 lcd.print("  Mehmet KIRAN  ");
 lcd.setCursor(0,1);
 lcd.print(" Saat: ");
 lcd.print(rtc.getTimeStr());
 
}

void timedate()
{
   
char tempF[6]; 
    float temperature;
    char buff[BUFF_MAX];
    unsigned long now = millis();
    struct ts t;
    // show time once in a while
    if (now - prev > interval){
        DS3231_get(&t); //Get time
        temperature = DS3231_get_treg(); //Get temperature
        dtostrf(temperature, 5, 1, tempF);

        lcd.clear();
        lcd.setCursor(0,0);
        
        lcd.print(t.mday);
        
        printMonth(t.mon);
        
        lcd.print(t.year);
        
        lcd.setCursor(0,1); //Go to second line of the LCD Screen
        lcd.print(t.hour);
        lcd.print(":");
        if(t.min<10)
        {
          lcd.print("0");
        }
        lcd.print(t.min);
        lcd.print(":");
        if(t.sec<10)
        {
          lcd.print("0");
        }
        lcd.print(t.sec);
        
        lcd.print(' ');
        lcd.print(tempF);
        lcd.print((char)223);
        lcd.print("C ");
        prev = now;
    }

}

void setTheTime(char *cmd)
{
    struct ts t;

    // ssmmhhWDDMMYYYY  set time

        t.sec = inp2toi(cmd, 0);
        t.min = inp2toi(cmd, 2);
        t.hour = inp2toi(cmd, 4);
        t.wday = inp2toi(cmd, 6);
        t.mday = inp2toi(cmd, 7);
        t.mon = inp2toi(cmd, 9);
        t.year = inp2toi(cmd, 11) * 100 + inp2toi(cmd, 13);
        DS3231_set(t);
        Serial.println("OK");
}

void printMonth(int month)
{
  switch(month)
  {
    case 1: lcd.print(" Ocak ");break;
    case 2: lcd.print(" Subat ");break;
    case 3: lcd.print(" Mart ");break;
    case 4: lcd.print(" Nisan ");break;
    case 5: lcd.print(" Mayis");break;
    case 6: lcd.print(" Haziran ");break;
    case 7: lcd.print(" Temmuz ");break;
    case 8: lcd.print(" Agustos ");break;
    case 9: lcd.print(" Eylül ");break;
    case 10: lcd.print(" Ekim ");break;
    case 11: lcd.print(" Kasim ");break;
    case 12: lcd.print(" Aralik ");break;
    default: lcd.print(" Hata ");break;
  } 
}

// the loop routine runs over and over again forever;
void loop() {
  // read that state of the pushbutton value;
  int buttonVal = digitalRead(buttonPin);
  if (buttonVal == LOW && oldButtonVal == HIGH) {// button has just been pressed
    lightPattern = lightPattern + 1;
  }
  if (lightPattern > nPatterns) lightPattern = 1;
  oldButtonVal = buttonVal;
  
  switch(lightPattern) {


     case 1:
     simple();
     break;
     case 2:
     timedate();
     break;
     case 3:
     All();
      break;
      case 4:
     bars();
      break;
      case 5:
      mono();
      break;
    case 6:
     stereo8();
      break;
     case 7:
     stereo16();
      break;
      case 8:
    Two16_LCD();    
      break;
       case 9:
    lcd.clear();   
      break;
       
  }
}

// List of patterns to cycle through.  Each is defined as a separate function below.
typedef void (*SimplePatternList[])();
SimplePatternList gPatterns = {bars, mono, stereo8, stereo16, Two16_LCD };
uint8_t gCurrentPatternNumber = 0; // Index number of which pattern is current

void nextPattern()
{
  // add one to the current pattern number, and wrap around at the end
  gCurrentPatternNumber = (gCurrentPatternNumber + 1) % ARRAY_SIZE( gPatterns);
}
void All()
{
  // Call the current pattern function once, updating the 'leds' array
  gPatterns[gCurrentPatternNumber]();
  EVERY_N_SECONDS( 20 ) { nextPattern(); } // change patterns periodically
}
// second list

The problem for me is that when my arduino board has no power, the ds3231 rtc stops together.
For example, I upload the code to the arduino board at 20:20, I cut the power at 21:15, when I restore the power, the rtc time is 20:20.

From what I can see you forgot to put the battery in that that round thing on the back. They are not magic, they need power to run.

Battery on and installed

From a quick glance, your sketch is always resetting the time in setup().

I would be grateful if you could help me how to solve it

  1. Update the string to represent the current time (plus a few seconds)
  2. Upload and run the sketch so setTheTime executes and updates the DS3231
  3. Turn that statement into a comment so it will not execute again
  4. Upload and run the modified sketch
  5. Move on
1 Like

I've used this method in the past to set the clock to the time that the code was built:

// Set the time
void setClock(void)
{
  int d, h, m;
  int s;
  if (sscanf(__TIME__, "%d:%d:%d", &h, &m, &s) != 3)
      return;
  
  tmElements_t tm;
  tm.Hour = h;
  tm.Minute = m;
  tm.Second = s;
  tm.Wday= 1; // 1 is Sunday
  
  if (RTC.write(tm)) 
  {
  }
}

__TIME__ is a macro that represents the time that the code was last compiled. Just make sure you only run this once!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.