/* http://www.bristolwatch.com/arduino/ds1307_lcd.htm Display Time/Date with Arduino, LCD Display, and DS1307 RTC Lewis Loflin lewis@bvu.net This code comes with no warranty. */ #include #define blinkPin 13 #define swIn 2 // square wave or pulse in #define SW0 4 #define SW1 5 #define SW2 6 volatile byte irq_flag = LOW; // declare IRQ flag // names can't have number as fist char. #define HOME 0x02 #define Line2 0x0c #define CL 0x10 // cursor left #define CR 0x14 // cursor right #define SL 0x18 // Shifts entire display left #define SR 0x1c // Shifts entire display right int j; void setup() { Wire.begin(); // join i2c bus (address optional for master) pinMode(blinkPin, OUTPUT); digitalWrite(blinkPin, 0); attachInterrupt(0, set_irq_flag0, FALLING); // interrupt 0 pin 2 pinMode(swIn, INPUT); // pull ups on connect to Ds1307 Square wave output pin pinMode(SW0, INPUT); // N.O. push button switch pinMode(SW1, INPUT); // N.O. push button switch pinMode(SW2, INPUT); // N.O. push button switch // activate internal pull ups: digitalWrite(swIn, HIGH); digitalWrite(SW0, HIGH); digitalWrite(SW1, HIGH); digitalWrite(SW2, HIGH); Wire.beginTransmission(0x20); // set mcp23016 output configuration: Wire.write(0x06); // pointer Wire.write(0x00); // DDR Port0 all output Wire.write(0x0F); // DDR 0-3 input 4-7 output Wire.endTransmission(); // setup port 1 D7 = E; D6 = RS Wire.beginTransmission(0x20); Wire.write(0x01); //pointer to port 1 Wire.write(B10000000); // setup for command mode Wire.endTransmission(); writeCommand(0x38); // 2 line mode writeCommand(0x0F); // blinking cursor CLR(); // clear display writeCommand(HOME); // optional } void loop() { if (irq_flag == HIGH) { displayTime(); // write time/date to display irq_flag = 0; // clear IRQ flag. } // end if if (digitalRead(SW0) != HIGH) set_time(); // hold the switch to set time } // end loop // output time to display void displayTime() { Wire.beginTransmission(0x68); // access ds1307 RTC Wire.write(0); Wire.endTransmission(); Wire.requestFrom(0x68, 7); byte secs = Wire.read(); byte mins = Wire.read(); byte hrs = Wire.read(); byte day = Wire.read(); byte date = Wire.read(); byte month = Wire.read(); byte year = Wire.read(); typeln("Time: \n", 1); typeBCD(hrs); type(':'); typeBCD(mins); type(':'); typeBCD(secs); // use MM-DD-YYYY typeln("Date: \n", 2); typeBCD(month); type('-'); typeBCD(date); type('-'); type('2'); type('0'); typeBCD(year); toggle(blinkPin); } // end display time // sets IRQ flag on interrupt from digital pin 2. void set_irq_flag0() { irq_flag = HIGH; // set flag } // set time subroutine void set_time() { byte minutes = 0; byte hours = 0; byte day_of_week = 0x03; byte day = 0x17; byte month = 0x02; byte year = 0x17; while (digitalRead(SW1) != 0) // set minutes { CLR(); if (digitalRead(SW2) == 0) minutes++; if ((minutes & 0x0f) > 9) minutes = minutes + 6; if (minutes > 0x59) minutes = 0; typeln("Minutes = \n", 1); typeBCD(minutes); delay(1000); } delay(1000); while (digitalRead(SW1) != 0) // set hours { CLR(); if (digitalRead(SW2) == 0) hours++; if ((hours & 0x0f) > 9) hours = hours + 6; if (hours > 0x23) hours = 0; typeln("Hours = \n", 1); typeBCD(hours); delay(1000); } Wire.beginTransmission(0x68); // activate Ds1307 Wire.write(0); // where to begin Wire.write(0x00); //seconds Wire.write(minutes); //minutes Wire.write(0x80 | hours); //hours (24hr time) Wire.write(day_of_week); // Day 01-07 Wire.write(day); // Date 0-31 Wire.write(month); // month 0-12 Wire.write(year); // Year 00-99 Wire.write(0x10); // Control 0x10 produces a 1 HZ square wave on pin 7. Wire.endTransmission(); } // end setime() // Below we pass a pointer to array1[0]. If no '\n' then the limit is 16. (0 - 15) void typeln(char *array1, int i) { delayMicroseconds(1000); if (i == 1) writeCommand(0x80); // begin on 1st line if (i == 2) writeCommand(0x80 + 0x40); // begin on 2nd line for (int j = 0; (array1[j] != '\n') && (j < 16); j++) type(array1[j]); } // send command to Hd44780 display // E High to Low transition write command or data to Hd44780 display // RS 0 for command, default 1 for data // setup port1 D7 = E; D6 = RS void writeCommand(char c) { Wire.beginTransmission(0x20); // mcp23016 Wire.write(0x00); // begin here Wire.write(c); // command code Wire.endTransmission(); Wire.beginTransmission(0x20); // mcp23016 Wire.write(0x01); // pointer Wire.write(B10000000); // command mode E high Wire.endTransmission(); Wire.beginTransmission(0x20); // mcp23016 Wire.write(0x01); // pointer Wire.write(B00000000); // char mode E low Wire.endTransmission(); delayMicroseconds(100); Wire.beginTransmission(0x20); // mcp23016 Wire.write(0x01); // pointer Wire.write(B10000000); // E high back to command mode Wire.endTransmission(); } // send char to Hd44780 display // E High to Low transition write command or data to Hd44780 display // RS 0 for command, default 1 for data // setup port1 D7 = E; D6 = RS void type(char c) { Wire.beginTransmission(0x20); // mcp23016 Wire.write(0x00); // begin here Wire.write(c); // data Wire.endTransmission(); Wire.beginTransmission(0x20); // mcp23016 Wire.write(0x01); // pointer Wire.write(B11000000); // char mode E high Wire.endTransmission(); Wire.beginTransmission(0x20); // mcp23016 Wire.write(0x01); // pointer Wire.write(B01000000); // char mode E low Wire.endTransmission(); delayMicroseconds(100); Wire.beginTransmission(0x20); // mcp23016 Wire.write(0x01); // pointer Wire.write(B10000000); // E high back to command mode Wire.endTransmission(); } // clear display void CLR() { writeCommand(0x01); // clear } // this routine types a Hex values to Hd44780 display // the value from be in BCD form void typeBCD(byte val) { byte n = val; n = (n >> 4) + 48; type(n); val = (val && B00001111) + 48; type(val); } // backspace on display void BS() { writeCommand(CL); } // toggle the state on a pin void toggle(int pinNum) { int pinState = digitalRead(pinNum); pinState = !pinState; digitalWrite(pinNum, pinState); }