I have an I2C RTC connected to the arduino which outputs the time over the serial port using serial.print(second, DEC) and also a 4 bit LCD that I can print characters or strings to.
My problem is, when I try to write the time to the LCD it just comes up as garbage. Its printing out from the ascii table and not the actual numbers like I want.
The code is in part borrowed from tutorials across the internet and I understand how most of it works, but I dont know why print(second,DEC) converts the number for serial output but the bcdToDec() function in the code doesn
t seem to work.
/* RW tied to gnd
*
*
*
*
*/
#include "Wire.h"
#define RTC_I2C_ADDRESS 0x51
#define LCD_RS 8 // Register select
#define LCD_EN 9 // Enable
#define LCD_D4 10 // Data bits
#define LCD_D5 11 // Data bits
#define LCD_D6 12 // Data bits
#define LCD_D7 13 // Data bits
// RTC functions
// 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) );
}
void setDateDs1307(byte second, // 0-59
byte minute, // 0-59
byte hour, // 1-23
byte dayOfMonth, // 1-31
byte dayOfWeek, // 1-7
byte month, // 1-12
byte year) // 0-99
{
Wire.beginTransmission(RTC_I2C_ADDRESS);
Wire.send(0);
Wire.send(0x00);
Wire.send(0x00);
Wire.send(decToBcd(second)); // 0 to bit 7 starts the clock
Wire.send(decToBcd(minute));
Wire.send(decToBcd(hour)); // If you want 12 hour am/pm you need to set
// bit 6 (also need to change readDateDs1307)
Wire.send(decToBcd(dayOfMonth));
Wire.send(decToBcd(dayOfWeek));
Wire.send(decToBcd(month));
Wire.send(decToBcd(year));
Wire.endTransmission();
}
void getDateDs1307(byte *second,
byte *minute,
byte *hour,
byte *dayOfMonth,
byte *dayOfWeek,
byte *month,
byte *year)
{
// Reset the register pointer
Wire.beginTransmission(RTC_I2C_ADDRESS);
Wire.send(0);
Wire.endTransmission();
Wire.requestFrom(RTC_I2C_ADDRESS, 9);
// A few of these need masks because certain bits are control bits
*second = bcdToDec(Wire.receive());
*second = bcdToDec(Wire.receive());
*second = bcdToDec(Wire.receive() & 0x7f);
*minute = bcdToDec(Wire.receive() & 0x7f);
*hour = bcdToDec(Wire.receive() & 0x3f); // Need to change this if 12 hour am/pm
*dayOfMonth = bcdToDec(Wire.receive() & 0x3f);
*dayOfWeek = bcdToDec(Wire.receive() & 0x07);
*month = bcdToDec(Wire.receive() & 0x1f);
*year = bcdToDec(Wire.receive());
}
// end RTC
void lcd_strobe()
{
digitalWrite(LCD_EN,HIGH);
digitalWrite(LCD_EN,LOW);
}
/* write a byte to the LCD in 4 bit mode */
void lcd_write(byte c)
{
if(c & 0x80) digitalWrite(LCD_D7,HIGH); else digitalWrite(LCD_D7,LOW);
if(c & 0x40) digitalWrite(LCD_D6,HIGH); else digitalWrite(LCD_D6,LOW);
if(c & 0x20) digitalWrite(LCD_D5,HIGH); else digitalWrite(LCD_D5,LOW);
if(c & 0x10) digitalWrite(LCD_D4,HIGH); else digitalWrite(LCD_D4,LOW);
lcd_strobe();
if(c & 0x08) digitalWrite(LCD_D7,HIGH); else digitalWrite(LCD_D7,LOW);
if(c & 0x04) digitalWrite(LCD_D6,HIGH); else digitalWrite(LCD_D6,LOW);
if(c & 0x02) digitalWrite(LCD_D5,HIGH); else digitalWrite(LCD_D5,LOW);
if(c & 0x01) digitalWrite(LCD_D4,HIGH); else digitalWrite(LCD_D4,LOW);
lcd_strobe();
delayMicroseconds(40);
}
/*
* Clear and home the LCD
*/
void
lcd_clear(void)
{
digitalWrite(LCD_RS,LOW);
lcd_write(0x1);
delay(2);
}
/* write a string of chars to the LCD */
void
lcd_puts(const char * s)
{
digitalWrite(LCD_RS,HIGH); // write characters
while(*s) lcd_write(*s++);
}
/* write one character to the LCD */
void
lcd_putch(byte c)
{
digitalWrite(LCD_RS,HIGH); // write characters
lcd_write(c);
}
/*
* Go to the specified position
*/
void
lcd_goto(byte pos)
{
digitalWrite(LCD_RS,0);
lcd_write(0x80 + pos);
}
/* initialise the LCD - put into 4 bit mode */
void
lcd_init(void)
{
pinMode(LCD_D7,OUTPUT);
pinMode(LCD_D6,OUTPUT);
pinMode(LCD_D5,OUTPUT);
pinMode(LCD_D4,OUTPUT);
pinMode(LCD_EN,OUTPUT);
pinMode(LCD_RS,OUTPUT);
digitalWrite(LCD_RS, LOW); // write control bytes
delay(15);// power on delay
digitalWrite(LCD_D4, HIGH); // init!
digitalWrite(LCD_D5, HIGH); //
lcd_strobe();
delay(5);
lcd_strobe();// init!
delayMicroseconds(100);
lcd_strobe();// init!
delay(5);
digitalWrite(LCD_D4, LOW); // set 4 bit mode
lcd_strobe();
delayMicroseconds(40);
lcd_write(0x28);// 4 bit mode, 1/16 duty, 5x8 font, 2lines
lcd_write(0x0C);// display on
lcd_write(0x06);// entry mode advance cursor
lcd_write(0x01);// clear display and reset cursor
}
void setup() {
lcd_init();
byte second, minute, hour, dayOfMonth, dayOfWeek, month, year;
Wire.begin();
Serial.begin(9600);
// Change these values to what you want to set your clock to.
// You probably only want to set your clock once and then remove
// the setDateDs1307 call.
second = 45;
minute = 50;
hour = 10;
dayOfWeek = 3;
dayOfMonth = 16;
month = 12;
year = 8;
setDateDs1307(second, minute, hour, dayOfMonth, dayOfWeek, month, year);
}
void loop() {
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
getDateDs1307(&second, &minute, &hour, &dayOfMonth, &dayOfWeek, &month, &year);
Serial.print(hour,DEC);
Serial.print(":");
Serial.print(minute,DEC);
Serial.print(":");
Serial.print(second,DEC);
Serial.print(" ");
Serial.print(dayOfMonth,DEC);
Serial.print("/");
Serial.print(month,DEC);
Serial.print("/");
Serial.print(year,DEC);
Serial.print(" Day_of_week:");
Serial.println(dayOfWeek,DEC);
lcd_clear();
lcd_putch(bcdToDec(second));
delay(1000);
}