Connect with us

DS1307 can not read and write time in arduino.

Discussion in 'Microcontrollers, Programming and IoT' started by Ninjia Chen, Dec 3, 2014.

Scroll to continue with content
  1. Ninjia Chen

    Ninjia Chen

    10
    0
    Nov 7, 2014
    hello everyone
    In mid-November, I have designed a shield based on arduino.I have wrote two posts https://www.electronicspoint.com/th...netometer-clock-and-oled.271203/#post-1633487 and https://www.electronicspoint.com/th...tes-a-variety-of-sensors.271379/#post-1631633 I have to debug a week.However, it does not work.The OLED display and bluetooth is ok.
    Here is my sch,
    20141202175414.jpg
    Here is my pcb
    IMG_0492.JPG
    You can see in my schematic,I use IIC to connects two devices,they are not wroking properly.First, I tested the DS1307.I found the DS1307 has no answer.
    Here is my code base on arduino.
    Code:
    #include <Wire.h>
    
    int clockAddress = 0x68;  // This is the I2C address
    int command = 0;  // This is the command char, in ascii form, sent from the serial port    
    long previousMillis = 0;  // will store last time Temp was updated
    byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
    byte test;
    
    // Convert normal decimal numbers to binary coded decimal
    byte decToBcd(byte val)
    {
      return ( (val/10*16) + (val%10) );
    }
    
    // Convert binary coded decimal to normal decimal numbers
    byte bcdToDec(byte val)
    {
      return ( (val/16*10) + (val%16) );
    }
    
    // 1) Sets the date and time on the ds1307
    // 2) Starts the clock
    // 3) Sets hour mode to 24 hour clock
    // Assumes you're passing in valid numbers,
    // Probably need to put in checks for valid numbers.
    void setDateDs1307()               
    {
      // Use of (byte) type casting and ascii math to achieve result. 
    second = (byte) ((Serial.read() - 48) * 10 + (Serial.read() - 48));
      minute = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
      hour  = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
      dayOfWeek = (byte) (Serial.read() - 48);
      dayOfMonth = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
      month = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
      year= (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
      /*second = 50;
      minute = 56;
      hour  = 9;
      dayOfWeek = 2;
      dayOfMonth = 2;
      month = 12;
      year= 14;*/
      Wire.beginTransmission(clockAddress);
      Wire.write(byte(0x00));
      Wire.write(decToBcd(second));  // 0 to bit 7 starts the clock
      Wire.write(decToBcd(minute));
      Wire.write(decToBcd(hour));    // If you want 12 hour am/pm you need to set
      // bit 6 (also need to change readDateDs1307)
      Wire.write(decToBcd(dayOfWeek));
      Wire.write(decToBcd(dayOfMonth));
      Wire.write(decToBcd(month));
      Wire.write(decToBcd(year));
      Wire.endTransmission();
    }
    
    
    // Gets the date and time from the ds1307 and prints result
    void getDateDs1307() {
      // Reset the register pointer
      Wire.beginTransmission(clockAddress);
      Wire.write(byte(0x00));
      Wire.endTransmission();
    
      Wire.requestFrom(clockAddress, 7);
    
      // A few of these need masks because certain bits are control bits
      second     = bcdToDec(Wire.read() & 0x7f);
      minute     = bcdToDec(Wire.read());
     
      // Need to change this if 12 hour am/pm
      hour       = bcdToDec(Wire.read() & 0x3f); 
      dayOfWeek  = bcdToDec(Wire.read());
      dayOfMonth = bcdToDec(Wire.read());
      month      = bcdToDec(Wire.read());
      year       = bcdToDec(Wire.read());
    
      Serial.print(hour, DEC);
      Serial.print(":");
      Serial.print(minute, DEC);
      Serial.print(":");
      Serial.print(second, DEC);
      Serial.print("  ");
      Serial.print(month, DEC);
      Serial.print("/");
      Serial.print(dayOfMonth, DEC);
      Serial.print("/");
      Serial.print(year, DEC);
    
    }
    
    
    void setup() {
      Wire.begin();
      Serial.begin(57600);
    }
    
    void loop() {
      if (Serial.available()) {  // Look for char in serial que and process if found
        command = Serial.read();
        if (command == 84) {      //If command = "T" Set Date
          setDateDs1307();
          getDateDs1307();
          Serial.println(" ");
        }
        else if (command == 81) {  //If command = "Q" RTC1307 Memory Functions
          delay(100);    
          if (Serial.available()) {
            command = Serial.read();
           
            // If command = "1" RTC1307 Initialize Memory - All Data will be set to 255 (0xff). 
            // Therefore 255 or 0 will be an invalid value. 
            if (command == 49) {
             
              // 255 will be the init value and 0 will be cosidered an error that
              // occurs when the RTC is in Battery mode.
              Wire.beginTransmission(clockAddress);
             
              // Set the register pointer to be just past the date/time registers.
              Wire.write(byte(0x08)); 
              for (int i = 1; i <= 27; i++) {
                Wire.write(byte(0xff));
                delay(100);
              }  
              Wire.endTransmission();
              getDateDs1307();
              Serial.println(": RTC1307 Initialized Memory");
            }
            else if (command == 50) {      //If command = "2" RTC1307 Memory Dump
              getDateDs1307();
              Serial.println(": RTC 1307 Dump Begin");
              Wire.beginTransmission(clockAddress);
              Wire.write(byte(0x00));
              Wire.endTransmission();
              Wire.requestFrom(clockAddress, 64);
              for (int i = 1; i <= 64; i++) {
                test = Wire.read();
                Serial.print(i);
                Serial.print(":");
                Serial.println(test, DEC);
              }
              Serial.println(" RTC1307 Dump end");
            }
          } 
        }
        Serial.print("Command: ");
        Serial.println(command);  // Echo command CHAR in ascii that was sent
      }
    
      command = 0;  // reset command                 
      delay(100);
    }
    Time is always parked in the 45:85:85,I know this is the wrong data.I use two leonardo to test.Unfortunately, I still did not get the correct data.Then,I suspect that the IIC on my leonardo is broken.
    I've used other IIC devices, I put GY-30 connected to leonardo, and the code I‘ve been used,it can't work.I borrowed a Duemilanove from others.The GY-30 can work,and the DS1307 in my shield doesn't work.Now I have no idea.anyone can help me,and anyone can upload code about DS1307 base on arduino,In order to confirm the problem in my code or on my PCB.
    Thanks
    Ninjia
     
  2. (*steve*)

    (*steve*) ¡sǝpodᴉʇuɐ ǝɥʇ ɹɐǝɥd Moderator

    25,505
    2,849
    Jan 21, 2010
    Have you tried to communicate with the DS1307 when it alone is on the I2C bus?

    Are you using code you've written yourself or a library you've obtained from elsewhere?

    Have you tried setting the time then reading it back?
     
  3. KrisBlueNZ

    KrisBlueNZ Sadly passed away in 2015

    8,393
    1,272
    Nov 28, 2011
    Can you provide a link to the data sheet for the AP2306 devices that you're using to convert the I2C signals between 3.3V and 5V? I can't find a data sheet for it anywhere.

    If you can't post a link to it, upload it as an attachment to your post.

    If you don't have a data sheet for it, post a link to the article that showed you how to use it to level-shift an I2C bus.
     
  4. Ninjia Chen

    Ninjia Chen

    10
    0
    Nov 7, 2014
    yeah,thanks you.I find it on http://www.amobbs.com/thread-4856717-1-1.html,
    You can use the Google translator to read.
     
  5. Ninjia Chen

    Ninjia Chen

    10
    0
    Nov 7, 2014
    Thanks,I will test it again on Saturday as you said.
     
  6. KrisBlueNZ

    KrisBlueNZ Sadly passed away in 2015

    8,393
    1,272
    Nov 28, 2011
  7. Ninjia Chen

    Ninjia Chen

    10
    0
    Nov 7, 2014
  8. KrisBlueNZ

    KrisBlueNZ Sadly passed away in 2015

    8,393
    1,272
    Nov 28, 2011
  9. Ninjia Chen

    Ninjia Chen

    10
    0
    Nov 7, 2014
    Thanks,Moderator,I know what the problem.If there is no AP2306, DS1307 can work properly.
    I should not be free to use the circuit which has not been proven.I did not find the relevant datasheet, only a discussion.
     
  10. Harald Kapp

    Harald Kapp Moderator Moderator

    12,328
    2,930
    Nov 17, 2011
    KrisBlueNZ likes this.
Ask a Question
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.
Electronics Point Logo
Continue to site
Quote of the day

-