Pages: [1] 2 3 4   Go Down
Author Topic: I'm Confused DS1307 & LCD  (Read 4118 times)
0 Members and 1 Guest are viewing this topic.
Oregon USA
Offline Offline
Jr. Member
**
Karma: 0
Posts: 94
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I just received a DS1307 break-out board  from Sparkfun and decided to try it out.  So I downloaded Sjunnesson's library from the playground.  I hooked everything up and ran the example code.  That worked fine.  

I then decided to send the output to an LCD instead of the serial port.  So I mounted up a 16x2 LCD.  To test my hook up, I loaded up the LCD "Hello World" example and ran it.  It functioned fine.  

So then I sort of collided the two sketches like this:

Code:
#include <LiquidCrystal.h>
#include <WProgram.h>
#include <Wire.h>
#include <DS1307.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
int Hr=0;
int Mn=0;
int Sc=0;
int DD=0;
int MM=0;
int YY=0;

void setup() {
  lcd.begin(16, 2);
}

void loop() {

  Hr=RTC.get(DS1307_HR,true);
  Mn=RTC.get(DS1307_MIN,false);
  Sc=RTC.get(DS1307_SEC,false);
  DD=RTC.get(DS1307_DATE,false);
  MM=RTC.get(DS1307_MTH,false);
  YY=RTC.get(DS1307_YR,false);

  lcd.clear();
  lcd.print(MM);
  lcd.setCursor(2, 0);
  lcd.print("-");
  lcd.setCursor(3, 0);
  lcd.print(DD);
  lcd.setCursor(5, 0);
  lcd.print("-");
  lcd.setCursor(7, 0);
  lcd.print(YY);

  lcd.setCursor(0, 1);
  lcd.print(Hr);
  lcd.setCursor(2, 1);
  lcd.print(":");
  lcd.setCursor(3, 1);
  lcd.print(Mn);
  lcd.setCursor(5, 1);
  lcd.print(":");
  lcd.setCursor(6, 1);
  lcd.print(Sc);

  delay(1000);

}

When I run that, I get odd results.  Either the ":" and "-" characters do not show up and the time does not update or nothing shows at all.  So I altered the code to this:
Code:
#include <LiquidCrystal.h>
#include <WProgram.h>
#include <Wire.h>
#include <DS1307.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
int Hr=0;
int Mn=0;
int Sc=0;
int DD=0;
int MM=0;
int YY=0;

void setup() {
  lcd.begin(16, 2);
}

void loop() {

  Hr=RTC.get(DS1307_HR,true);
  Mn=RTC.get(DS1307_MIN,false);
  Sc=RTC.get(DS1307_SEC,false);
  DD=RTC.get(DS1307_DATE,false);
  MM=RTC.get(DS1307_MTH,false);
  YY=RTC.get(DS1307_YR,false);

  lcd.clear();
  lcd.print("Time:");
//  lcd.print(MM);
//  lcd.setCursor(2, 0);
//  lcd.print("-");
//  lcd.setCursor(3, 0);
//  lcd.print(DD);
//  lcd.setCursor(5, 0);
//  lcd.print("-");
//  lcd.setCursor(7, 0);
//  lcd.print(YY);

  lcd.setCursor(0, 1);
  lcd.print(Hr);
  lcd.setCursor(2, 1);
  lcd.print(":");
  lcd.setCursor(3, 1);
  lcd.print(Mn);
  lcd.setCursor(5, 1);
  lcd.print(":");
  lcd.setCursor(6, 1);
  lcd.print(Sc);

  delay(1000);

}

... and it functions as one would anticipate (after cycling the power).  The word "Time" shows up on the first line of the LCD and the time that updates every second on the second line.  What the heck am I missing?
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 615
Posts: 49388
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Does it work any better if you explicitly convert the numbers to strings before calling lcd.print?

Code:
char buffer[6];
sprintf(buffer, "%d", Hr);
lcd.print(buffer);
Logged

Oregon USA
Offline Offline
Jr. Member
**
Karma: 0
Posts: 94
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'll try that once I get home.
« Last Edit: November 16, 2009, 09:42:28 pm by ggutshal » Logged

Oregon USA
Offline Offline
Jr. Member
**
Karma: 0
Posts: 94
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Well I tried it.  It didn't work.  A bar of blocks was displayed on the first line of the LCD and nothing else.  After trying it, I couldn't get anything to display from the real time clock.  Even using the code that worked before.  The LCD "Hello World" app however still works.  Now I'm really confused.  The DS1307 example code also still works.

Any other suggestions?
Logged

Oregon USA
Offline Offline
Jr. Member
**
Karma: 0
Posts: 94
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

No one has any other ideas?
Logged

Sofia, Bulgaria
Offline Offline
Full Member
***
Karma: 0
Posts: 237
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

It would benefit anyone trying to help you if you post the "new" code you say you used without success
Logged

Oregon USA
Offline Offline
Jr. Member
**
Karma: 0
Posts: 94
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Right, sorry:

Code:
#include <LiquidCrystal.h>
#include <WProgram.h>
#include <Wire.h>
#include <DS1307.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

int Hr=0;
int Mn=0;
int Sc=0;
int DD=0;
int MM=0;
int YY=0;
char buffer[6];

void setup() {
  lcd.begin(16, 2);
}

void loop() {

  Hr=RTC.get(DS1307_HR,true);
  Mn=RTC.get(DS1307_MIN,false);
  Sc=RTC.get(DS1307_SEC,false);
  DD=RTC.get(DS1307_DATE,false);
  MM=RTC.get(DS1307_MTH,false);
  YY=RTC.get(DS1307_YR,false);

  lcd.clear();

  sprintf(buffer, "%d", Sc);
  lcd.print(buffer);  

  delay(1000);

}
Logged

Seattle, USA
Offline Offline
Full Member
***
Karma: 0
Posts: 248
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Some things to check, as I look at your code:
  • (Without having looked at the DS1307 library) Do you need any initialization calls to use the RTC.get() functions? I don't see anything in your setup () function.
  • Have you tried, in your loop () function, using Serial.println calls along with lcd.print in order to verify that you are getting good data and converting them to strings properly?
  • (Again without looking at libraries) Why do you have WProgram.h and Wire.h included in your program? Does DS1307 need them?
  • The fact that you say the LCD and RTC tests work independently of each other makes me suspect interference between them.
  • The boolean parameter passed to RTC.get seems to be for a refresh option. Why do you have some true and some false?
Hopefully, these questions might lead someplace useful in your investigation.

.andy
Logged

.andy

Oregon USA
Offline Offline
Jr. Member
**
Karma: 0
Posts: 94
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I am suspecting some kind of interference between the libraries as well.  The behavior is just too random and unpredictable and I'm too green to find it.

Quote
   * (Without having looked at the DS1307 library) Do you need any initialization calls to use the RTC.get() functions? I don't see anything in your setup () function.

There was none in the DS1307 example code.

Quote
   * Have you tried, in your loop () function, using Serial.println calls along with lcd.print in order to verify that you are getting good data and converting them to strings properly?

The example code uses serial.Print to send out the data gleaned from the DS1307.  I hadn't tried sending it both to the LCD & serial simultaneously.

Quote
   * (Again without looking at libraries) Why do you have WProgram.h and Wire.h included in your program? Does DS1307 need them?

I presume that it does because they were in the DS1307 example code.

Quote
   * The fact that you say the LCD and RTC tests work independently of each other makes me suspect interference between them.

My thoughts exactly, but where and how?

Quote
   * The boolean parameter passed to RTC.get seems to be for a refresh option. Why do you have some true and some false?

Because you don't want to update the data you're reading prior to reading all of it.  Imagine reading the time directly at 59 minutes, 59.9999 seconds.  You get the proper hour, but suddenly the minute value reads "00" because you've updated and it rolled and you're data is now erroneously an hour old.
Logged

Seattle, USA
Offline Offline
Full Member
***
Karma: 0
Posts: 248
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

More questions:

How is the RTC chip getting initialized? By that I mean, are you sure that it has valid time data in it and the battery powering it is good?

Are you getting the actual time from your computer and then loading that into the RTC ?

There are some RTC.set() functions in the library that you can use to load values into the clock chip, and there are RTC.start() and RTC.stop() calls to control it. The example I saw did use these.

Your latest test program only attempts to show the seconds; I assume that was just to test?

I don't know how the libraries might interact with each other and I don't know exactly which ones you have downloaded and are using, etc.

If I were trying to debug this, I would reduce it to the simplest case I could formulate, and try to get that working, then add in more stuff.

A simple case might be to push known values into the RTC (stop, set, set, set...) without starting it, and then verify you can get those values back and see them via serial and lcd output. Then put the values in and start the clock (stop, set, set, set... start) and see that you are getting updates. Do this without the sprintf buffer first.

Then once you know you are getting good data, add in the sprintf formatting and continue the verification.

I think you have too many floating unknowns right now and you need to reduce the problem to narrower test cases.

If I had one of those modules, I would happily play with it, as I plan to develop an RTC app soon myself.

.andy
Logged

.andy

Sofia, Bulgaria
Offline Offline
Full Member
***
Karma: 0
Posts: 237
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Two things to propose:
 - try outputing a constant integer, instead of the seconds.
 - try updating the LCD more slowly. put a delay_microsecodns in the loop, delay for half a second and output something.
Logged

Oregon USA
Offline Offline
Jr. Member
**
Karma: 0
Posts: 94
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

OK, I've taken your advice.  I altered the code to this:

Code:
#include <LiquidCrystal.h>
#include <WProgram.h>
#include <Wire.h>
#include <DS1307.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

int Hr=0;
int Mn=0;
int Sc=0;
int DD=0;
int MM=0;
int YY=0;
char buffer[6];

void setup() {
  lcd.begin(16, 2);
}

void loop() {

  Hr=1;
  Mn=2;
  Sc+=1;
  DD=3;
  MM=4;
  YY=2009;

  lcd.clear();
  lcd.print(MM);
  lcd.setCursor(2, 0);
  lcd.print("-");
  lcd.setCursor(3, 0);
  lcd.print(DD);
  lcd.setCursor(5, 0);
  lcd.print("-");
  lcd.setCursor(7, 0);
  lcd.print(YY);

  lcd.setCursor(0, 1);
  lcd.print(Hr);
  lcd.setCursor(2, 1);
  lcd.print(":");
  lcd.setCursor(3, 1);
  lcd.print(Mn);
  lcd.setCursor(5, 1);
  lcd.print(":");
  lcd.setCursor(6, 1);
  lcd.print(Sc);

  delay(1000);

}

It does not work.  If however I comment out the "#include <DS1307.h>" line, it functions as one would anticipate.  That pretty much localizes it.  Does anyone have an idea how to fix it?
« Last Edit: November 18, 2009, 02:16:36 am by ggutshal » Logged

Sofia, Bulgaria
Offline Offline
Full Member
***
Karma: 0
Posts: 237
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

How did you connect the LCD and the RTC? Can you post a schematic or at least a simple drawing? It might be a lines signal problem.
Logged

Oregon USA
Offline Offline
Jr. Member
**
Karma: 0
Posts: 94
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok, I've been playing some more with the code.  I followed the other DS1307 link on the playground and adapted the code I found there. The following functions just fine:

Code:
#include "Wire.h"
#define DS1307_I2C_ADDRESS 0x68  // This is the I2C address

// Global Variables
int second, minute, hour, dayOfWeek, dayOfMonth, month, year;

void setup() {
  Wire.begin();
  Serial.begin(57600);
}

void loop() {

    getDateDs1307();
  
    Serial.print(month);
    Serial.print("/");
    Serial.print(dayOfMonth);
    Serial.print("/");
    Serial.print(year);
    Serial.println();

    Serial.print(hour);
    Serial.print(":");
    Serial.print(minute);
    Serial.print(":");
    Serial.print(second);
    Serial.println();

    delay(500);
}

// 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) );
}

// Gets the date and time from the ds1307 and prints result
void getDateDs1307()
{
  // Reset the register pointer
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.send(0x00);
  Wire.endTransmission();

  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);

  // A few of these need masks because certain bits are control bits
  second     = bcdToDec(Wire.receive() & 0x7f);
  minute     = bcdToDec(Wire.receive());
  hour       = bcdToDec(Wire.receive() & 0x3f);  // Need to change this if 12 hour am/pm
  dayOfWeek  = bcdToDec(Wire.receive());
  dayOfMonth = bcdToDec(Wire.receive());
  month      = bcdToDec(Wire.receive());
  year       = bcdToDec(Wire.receive());

}

However as soon as I add the LCD library and declare an instance, things head south.

Code:
#include "Wire.h"
#include <LiquidCrystal.h>
#define DS1307_I2C_ADDRESS 0x68  // This is the I2C address

// Global Variables
int second, minute, hour, dayOfWeek, dayOfMonth, month, year;
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {
  Wire.begin();
  lcd.begin(16, 2);
}

void loop() {
    getDateDs1307();

    lcd.clear();
    lcd.print(month);
    lcd.setCursor(2,0);
    lcd.print("/");
    lcd.setCursor(3,0);
    lcd.print(dayOfMonth);
    lcd.setCursor(5,0);
    lcd.print("/");
    lcd.setCursor(6,0);
    lcd.print(year);

    lcd.setCursor(0, 1);
    lcd.print(hour);
    lcd.setCursor(2,1);
    lcd.print(":");
    lcd.setCursor(3,1);
    lcd.print(minute);
    lcd.setCursor(5,1);
    lcd.print(":");
    lcd.setCursor(6,1);
    lcd.print(second);

    delay(500);
}

// 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) );
}

// Gets the date and time from the ds1307 and prints result
void getDateDs1307()
{
  // Reset the register pointer
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.send(0x00);
  Wire.endTransmission();

  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);

  // A few of these need masks because certain bits are control bits
  second     = bcdToDec(Wire.receive() & 0x7f);
  minute     = bcdToDec(Wire.receive());
  hour       = bcdToDec(Wire.receive() & 0x3f);  // Need to change this if 12 hour am/pm
  dayOfWeek  = bcdToDec(Wire.receive());
  dayOfMonth = bcdToDec(Wire.receive());
  month      = bcdToDec(Wire.receive());
  year       = bcdToDec(Wire.receive());
}

If I leave the Serial.print statements in the code and comment out everything BUT the instantiation of the LCD instance ("LiquidCrystal lcd(12, 11, 5, 4, 3, 2);") then the code ceases to function.

Here is the schematic you've asked for:

Logged

Sofia, Bulgaria
Offline Offline
Full Member
***
Karma: 0
Posts: 237
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

OK, now you've shuffled some things around and you can repeat the same tests.
Does the LCD driver work by itself (as in the previous occasion). If so - does adding the DS1307 driver make things worse?
Because now you show the opposite behavior than before - the clock working, and adding the LCD "sends things south".
The connections seem OK to me.
I would check if the drivers in their initialization parts make some strange assumptions and initialize other ports and pins than the ones they need. Also if some strange and long delays are used.
Logged

Pages: [1] 2 3 4   Go Up
Jump to: