5

I have a few RTC modules with a batteries. All of them have this same issue with my project.

They work fine when connected via USB. But if I disconnect the power then reconnect they reset to Jan 1 2000.

I've read several posts about similar problems. But, none seem to apply.

Here is my code:

#include <SFE_MicroOLED.h>  // Include the SFE_MicroOLED library
#include <SPI.h>
#include <SD.h>
#include "Wire.h"
#include <RTClib.h>
RTC_DS1307 RTC;
#define BUTTON_PIN       0 // Button
#define LONGPRESS_LEN    25  // Min nr of loops for a long press
#define DELAY            20  // Delay per loop in ms

enum { EV_NONE=0, EV_SHORTPRESS, EV_LONGPRESS };

boolean button_was_pressed; // previous state
int button_pressed_counter; // press running duration

byte zero = 0x00; //workaround for issue #527

char* modes[]={"Walk", "Bike", "Subway", "Train", "Bus", "X-Bus", "Waiting", "Other"};
byte mode=0;
int modeRead;

// Chip Select for SD
#define chipSelect 10

//MicroOLED oled(PIN_RESET, PIN_DC, PIN_CS);
MicroOLED oled(9, 8, 5); // SPI declaration

void setup()  
{ 
    pinMode(BUTTON_PIN, INPUT);
    digitalWrite(BUTTON_PIN, HIGH); // pull-up
    Serial.begin(9600);
    button_was_pressed = false;
    button_pressed_counter = 0;

    SD.begin(chipSelect);

    Wire.begin();
    RTC.begin();
    //RTC.adjust(DateTime(__DATE__, __TIME__));

    oled.begin();    // Initialize the OLED   
    oled.clear(PAGE);     // Clear the screen
    oled.setFontType(1);  // Set font to type 0
    oled.setCursor(0, 0); // Set cursor to top-left
    oled.println(F("co'mute"));
    oled.display();  // Display what's in the buffer 
}

int handle_button()
{
    int event;
    int button_now_pressed = !digitalRead(BUTTON_PIN); // pin low -> pressed

    if (!button_now_pressed && button_was_pressed) {
        if (button_pressed_counter < LONGPRESS_LEN)
            event = EV_SHORTPRESS;
        else
            event = EV_LONGPRESS;
    }
    else
        event = EV_NONE;

    if (button_now_pressed)
        ++button_pressed_counter;
    else
        button_pressed_counter = 0;

    button_was_pressed = button_now_pressed;
    return event;
}

void printDate () 
{    
    oled.clear(PAGE);     // Clear the screen
    oled.setFontType(0);  // Set font to type 0
    oled.setCursor(0, 0); // Set cursor to top-left

    DateTime now = RTC.now();

    oled.print(now.year(), DEC);
    oled.print('/');
    oled.print(now.month(), DEC);
    oled.print('/');
    oled.print(now.day(), DEC);
    oled.print(' ');
    oled.print(now.hour(), DEC);
    oled.print(':');
    if (now.minute()<10) {
        oled.print("0");
    }
    oled.print(now.minute(), DEC);
    oled.print(':');
    if (now.second()<10) {
        oled.print("0");
    }
    oled.print(now.second(), DEC);
    oled.println();
    oled.setFontType(1);  // Set font to type 0
    oled.println(modes[mode]);
    oled.display();   // Display what's in the buffer (splashscreen)
}

void writeFile() 
{
    File dataFile = SD.open("datalog.txt", FILE_WRITE);
    // If the file is available, write to it:
    if (dataFile) {
        DateTime now = RTC.now();
        //print the date EG   3/1/11 23:59:59
        dataFile.print(now.year(), DEC);
        dataFile.print('/');
        dataFile.print(now.month(), DEC);
        dataFile.print('/');
        dataFile.print(now.day(), DEC);

        printDate ();
        oled.print("*SAVED*");
        oled.display();
        delay(3000);
    }
} 

void loop()          // run over and over again
{
    // handle button
    boolean event = handle_button();

    // do other things
    switch (event) {
        case EV_NONE:
        oled.print(".");
        break;

        case EV_SHORTPRESS:
        oled.print("S");
        //modeRead = analogRead(0);    // read the value from the sensor
        writeFile(); 
        break;

        case EV_LONGPRESS:
        oled.print("L");
        break;
    }

    static int counter = 0;
    if ((++counter & 0X016) == 0) {
        printDate ();
    }
    modeRead = analogRead(A0);    // read the value from the sensor
    delay(DELAY);

    int c=1020/(sizeof(modes)/sizeof(modes[0]));
    for (int i = 0; i < c; i++) { 
        if (i*c < modeRead && (i+1)*c < modeRead) {
            mode = i;
        }
    }     
}

enter image description here

In this diagram the "pressure sensor" is really a OLED that operates via MOSI and MISO.

9
  • 1
    Have you checked the voltage of the RTC battery? – Ignacio Vazquez-Abrams Aug 26 '15 at 8:14
  • Yes. I've also tried multiple RTC modules that I know work in other projects. – futurebird Aug 26 '15 at 8:15
  • 3
    Wow! Spaghetti! Is your ruler broken or something?! – Majenko Aug 26 '15 at 9:41
  • 2
    Your schematic doesn't match your code. Weirdness involving S1 shorting D0 to ground, MOSI/MISO/CLK on A1/A2/A3 vs D11/D12/D13, Code says D10 is chip select for SD board, while schematic shows D7 ... Uh... The RTCLib library will expect to use the chips TWI (I2C) pins (D11/D12/D13), which you're not hooked to. That would explain the constant zero results from the RTC. – lornix Mar 22 '16 at 10:35
  • 2
    First off, you should simplify your circuit to only keep the RTC and check if the problem is still here. Also, it would be useful if you could provide the exact reference of the RTC breakout(s) you use, or event just a picture. I am not sure all breakouts include a battery cell to keep time running when chip is not powered. – jfpoilpret Oct 28 '16 at 7:43
1

The RTC board has a battery holder and requires the button battery to be fitted in order to retain the time and date value. As shown in the Datasheet, this battery is for the RTC chip only.

DS1307 Circuit

The Adafruit board requires a CR1220 button battery.

Adafruit DS1307 board

The Adafruit webpage mentions the following:

Note: This product does not come with a CR1220 coin cell battery.

(Providing that it works when the Arduino is powered up) It sounds as if the battery for the RTC is either:

  • not present
  • not connected (not inserted correctly or not making proper connection)
  • inserted upside down
  • a track on the PCB is broken or shorted
  • the battery is flat

The battery should be inserted so that the flat + side is UP. I suggest that you use a DMM to measure the RTC battery voltage at the RTC IC. Place your +ve probe on pin 3 of the IC and the -ve probe on pin 4. It should read slightly above 3.0 Volts.

I also recommend that you disconnect all of the other periferals so that you just have the RCT connected to the Arduino. Then use a known working program such as the one in the Adafruit tutorial to verify that your RTC is working correctly. You should be able to disconnect the USB and then reconnect it and find that the RTC is still holding the correct time.

RTC DS1307 Datasheet
Adafruit RTC Product
Adafruit RTC Tutorial

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.