arduino with a ds1307 rtc and lcd display quotation

I hate to say it but PaulS is correct, albeit he can be somewhat brash with his comments but it is a valuable lesson to learn as a new comer to any forum. Have you posted any code that someone else can copy and paste to get their project up and running? Have you spent years developing a library for anyone to use for free (Andrew Rapp)? Do you have a blog with all of your problems, pitfalls, and actively working code that has taken you the last 5 years to create, out there for anyone to copy and paste (draythomp)? If you cannot take 5 minutes to do a simple google search of something, say "sprintf()" to learn the basics of a subject you are having a problem with, then why should an experianced programmer like PaulS, Nick Gammon, grumpy Mike, AWOL, draythomp, rappa, etc spend 5 minutes of their time to help you out. You should know the problem subject well enough to properly communicate the issue you have along with the deficiencies in what you are trying to accomplish.
Also if you are not contributing anything to the community you shouldn"t expect anything from it, this is why I seldom post. I"m trying to change my behavior and become more active. Basically try to give as much as you take, ask for help not for someone that"s better to do the work for you so you can take the credit. And for god"s sake be concise and complete! if you don"t post the code, the whole code and nothing but the code, how is someone going to try to compile it and possibly modify your code to HELP YOU fix the errors!? Most important: all of the best programmers (most helpful, knowledgeable) on this forum keep track of who you are and if you get sh*tty with them right off the bat you"ll never get any help from them EVER!
Look through the forum. All of the "what"s going on with my crazy nonsense!" "help me please ASAP!" "Getting error blah" chaff that you have to sift through is way less helpful than
You can"t possibly have researched sprintf() in the time between my post and your reply. This is not the "do my homework for me" hotline. You are expected to make some attempt to actually learn how to do things with the Arduino beyond borrowing other people"s code.
Just to help you out, I think this quote translates into "look it up yourself it"s pretty self explanatory." Don"t know what %d or %s mean? Google %d C++ and %s C++ maybe take a look at printf() and/or studio.h. Try asking some specific question like. I don"t fully understand the part "...a format specifier in the format string (or a pointer to a storage location, for n)..." or what it exactly means, could someone please give me a simple example or break it down for me? http://www.cplusplus.com/reference/cstdio/sprintf/ I did a little search and it took about 15 minutes and I didn"t know jack about sprintf() before now which is why I"m on this banter filled thread in the first place. BTW I think sprintf() is a way to print out strings reusing a defined buffer saving SRAM from using a normal .print(" ") function and/or also flash from using a .print(F(" ")) function. Seems really useful when using an ATtiny 45 or something with little SRAM or flash.

I just happen to be playing around with RTC chips and I use a 16x2 LCD all the time for my testing. I have a little breadboard that I have wired up with a Nano, 16x2 LCD and currently a PCF8563 RTC. A couple days ago it was a DS1307. I think next I will play with a DS1302.
I use a modified version of the Time library. It has most of the functions that I need. I added the strftime() function to make it easier to format time in different ways.
Here is a little sketch I wrote to check for clock drift. I wanted to know how much the Arduino time drifted when compared to the DS1307. I also check the time with time.gov.
I also added the "secs()" function to the Arduino system. I proposed to the powers that be that it would be a good addition to go along with the millis() and micros() functions. I also added a way to set the seconds so you could count the number of seconds from a known starting point like 1970/1/1. I was testing that as well.

Along 3 years I have been trying several leg mechanism, at first I decided to do a simple desing with tibial motor where placed on femur joint.This design had several problems, like it wasn"t very robust and the most importat is that having the motor (with big mass) that far from the rotating axis, caused that in some movements it generate unwanted dynamics to the robot body, making controlability worse.New version have both motors of femur/tibial limb at coxa frame, this ends with a very simple setup and at the same time, the heaviest masses of the mechanism are centered to the rotating axis of coxa limb, so even though the leg do fast movements, inertias won"t be strong enough to affect the hole robot mass, achieving more agility.Inverse Kinematics of the mechanismAfter building it I notice that this mechanism was very special for another reason, at the domain the leg normally moves, it acts as a diferential mecanism, this means that torque is almost all the time shared between both motor of the longer limbs. That was an improvent since with the old mechanism tibial motor had to hold most of the weight and it was more forced than the one for femur.To visualize this, for the same movement, we can see how tibial motor must travel more arc of angel that the one on the new version.In order to solve this mechanism, just some trigonometry is needed. Combining both cosine and sine laws, we can obtain desired angle (the one between femur and tibia) with respect to the angle the motor must achieve.Observing these equations, with can notice that this angle (the one between femur and tibia) depends on both servos angles, which means both motors are contributing to the movement of the tibia.Calibration of servosAnother useful thing to do if we want to control servo precisely is to print a calibration tool for our set up. As shown in the image below, in order to know where real angles are located, angle protactor is placer just in the origin of the rotating joint, and choosing 2 know angles we can match PWM signal to the real angles we want to manipulate simply doing a lineal relation between angles and PWM pulse length.Then a simple program in the serial console can be wrtten to let the user move the motor to the desired angle. This way the calibration process is only about placing motor at certain position and everything is done and we won"t need to manually introduce random values that can be a very tedious task.With this I have achieved very good calibrations on motors, which cause the robot to be very simetrial making the hole system more predictable. Also the calibration procedure now is very easy to do, as all calculations are done automatically. Check Section 1 for the example code for calibration.More about this can be seen in the video below, where all the building process is shown as well as the new leg in action.SECTION 1:In the example code below, you can see how calibration protocol works, it is just a function called calibrationSecuence() which do all the work until calibration is finished. So you only need to call it one time to enter calibration loop, for example by sending a "c" character thought the serial console.Also some useful function are used, like moving motor directly with analogWrite functions which all the calculations involved, this is a good point since no interrupts are used.This code also have the feature to calibrate the potentiometer coming from each motor.#define MAX_PULSE 2500 #define MIN_PULSE 560 /*---------------SERVO PIN DEFINITION------------------------*/ int m1 = 6;//FR int m2 = 5; int m3 = 4; int m4 = 28;//FL int m5 = 29; int m6 = 36; int m7 = 3;//BR int m8 = 2; int m9 = 1; int m10 = 7;//BL int m11 = 24; int m12 = 25; int m13 = 0;//BODY /*----------------- CALIBRATION PARAMETERS OF EACH SERVO -----------------*/ double lowLim[13] = {50, 30, 30, 50, 30, 30, 50, 30, 30, 50, 30, 30, 70}; double highLim[13] = {130, 150, 150, 130, 150, 150, 130, 150, 150, 130, 150, 150, 110}; double a[13] = { -1.08333, -1.06667, -1.07778, //FR -1.03333, 0.97778, 1.01111, //FL 1.03333, 1.05556, 1.07778, //BR 1.07500, -1.07778, -1.00000, //BL 1.06250 }; double b[13] = {179.0, 192.0, 194.5, //FR 193.0, 5.5, -7.5, //FL 7.0, -17.0, -16.0, //BR -13.5, 191.5, 157.0, //BL -0.875 }; double ae[13] = {0.20292, 0.20317, 0.19904 , 0.21256, -0.22492, -0.21321, -0.21047, -0.20355, -0.20095, -0.20265, 0.19904, 0.20337, -0.20226 }; double be[13] = { -18.59717, -5.70512, -2.51697, -5.75856, 197.29411, 202.72169, 185.96931, 204.11902, 199.38663, 197.89534, -5.33768, -32.23424, 187.48058 }; /*--------Corresponding angles you want to meassure at in your system-----------*/ double x1[13] = {120, 135, 90, 60, 135 , 90, 120, 135, 90, 60, 135, 90, 110}; //this will be the first angle you will meassure double x2[13] = {60, 90, 135, 120, 90, 135, 60, 90, 135, 120, 90, 135, 70};//this will be the second angle you will meassure for calibration /*--------You can define a motor tag for each servo--------*/ String motorTag[13] = {"FR coxa", "FR femur", "FR tibia", "FL coxa", "FL femur", "FL tibia", "BR coxa", "BR femur", "BR tibia", "BL coxa", "BL femur", "BL tibia", "Body angle" }; double ang1[13] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; double ang2[13] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; float xi[500]; float yi[500]; float fineAngle; float fineL; float fineH; int motorPin; int motor = 0; float calibrationAngle; float res = 1.0; float ares = 0.5; float bres = 1.0; float cres = 4.0; float rawAngle; float orawAngle; char cm; char answer; bool interp = false; bool question = true; bool swing = false; int i; double eang; int freq = 100; // PWM frecuency can be choosen here. void connectServos() { analogWriteFrequency(m1, freq); //FR coxa digitalWrite(m1, LOW); pinMode(m1, OUTPUT); analogWriteFrequency(m2, freq); //femur digitalWrite(m2, LOW); pinMode(m2, OUTPUT); analogWriteFrequency(m3, freq); //tibia digitalWrite(m3, LOW); pinMode(m3, OUTPUT); analogWriteFrequency(m4, freq); //FL coxa digitalWrite(m4, LOW); pinMode(m4, OUTPUT); analogWriteFrequency(m5, freq); //femur digitalWrite(m5, LOW); pinMode(m5, OUTPUT); analogWriteFrequency(m6, freq); //tibia digitalWrite(m6, LOW); pinMode(m6, OUTPUT); analogWriteFrequency(m7, freq); //FR coxa digitalWrite(m7, LOW); pinMode(m7, OUTPUT); analogWriteFrequency(m8, freq); //femur digitalWrite(m8, LOW); pinMode(m8, OUTPUT); analogWriteFrequency(m9, freq); //tibia digitalWrite(m9, LOW); pinMode(m9, OUTPUT); analogWriteFrequency(m10, freq); //FR coxa digitalWrite(m10, LOW); pinMode(m10, OUTPUT); analogWriteFrequency(m11, freq); //femur digitalWrite(m11, LOW); pinMode(m11, OUTPUT); analogWriteFrequency(m12, freq); //tibia digitalWrite(m12, LOW); pinMode(m12, OUTPUT); analogWriteFrequency(m13, freq); //body digitalWrite(m13, LOW); pinMode(m13, OUTPUT); } void servoWrite(int pin , double angle) { float T = 1000000.0f / freq; float usec = float(MAX_PULSE - MIN_PULSE) * (angle / 180.0) + (float)MIN_PULSE; uint32_t duty = int(usec / T * 4096.0f); analogWrite(pin , duty); } double checkLimits(double angle , double lowLim , double highLim) { if ( angle >= highLim ) { angle = highLim; } if ( angle <= lowLim ) { angle = lowLim; } return angle; } int motorInfo(int i) { enc1 , enc2 , enc3 , enc4 , enc5 , enc6 , enc7 , enc8 , enc9 , enc10 , enc11 , enc12 , enc13 = readEncoders(); if (i == 0) { rawAngle = enc1; motorPin = m1; } else if (i == 1) { rawAngle = enc2; motorPin = m2; } else if (i == 2) { rawAngle = enc3; motorPin = m3; } else if (i == 3) { rawAngle = enc4; motorPin = m4; } else if (i == 4) { rawAngle = enc5; motorPin = m5; } else if (i == 5) { rawAngle = enc6; motorPin = m6; } else if (i == 6) { rawAngle = enc7; motorPin = m7; } else if (i == 7) { rawAngle = enc8; motorPin = m8; } else if (i == 8) { rawAngle = enc9; motorPin = m9; } else if (i == 9) { rawAngle = enc10; motorPin = m10; } else if (i == 10) { rawAngle = enc11; motorPin = m11; } else if (i == 11) { rawAngle = enc12; motorPin = m12; } else if (i == 12) { rawAngle = enc13; motorPin = m13; } return rawAngle , motorPin; } void moveServos(double angleBody , struct vector anglesServoFR , struct vector anglesServoFL , struct vector anglesServoBR , struct vector anglesServoBL) { //FR anglesServoFR.tetta = checkLimits(anglesServoFR.tetta , lowLim[0] , highLim[0]); fineAngle = a[0] * anglesServoFR.tetta + b[0]; servoWrite(m1 , fineAngle); anglesServoFR.alpha = checkLimits(anglesServoFR.alpha , lowLim[1] , highLim[1]); fineAngle = a[1] * anglesServoFR.alpha + b[1]; servoWrite(m2 , fineAngle); anglesServoFR.gamma = checkLimits(anglesServoFR.gamma , lowLim[2] , highLim[2]); fineAngle = a[2] * anglesServoFR.gamma + b[2]; servoWrite(m3 , fineAngle); //FL anglesServoFL.tetta = checkLimits(anglesServoFL.tetta , lowLim[3] , highLim[3]); fineAngle = a[3] * anglesServoFL.tetta + b[3]; servoWrite(m4 , fineAngle); anglesServoFL.alpha = checkLimits(anglesServoFL.alpha , lowLim[4] , highLim[4]); fineAngle = a[4] * anglesServoFL.alpha + b[4]; servoWrite(m5 , fineAngle); anglesServoFL.gamma = checkLimits(anglesServoFL.gamma , lowLim[5] , highLim[5]); fineAngle = a[5] * anglesServoFL.gamma + b[5]; servoWrite(m6 , fineAngle); //BR anglesServoBR.tetta = checkLimits(anglesServoBR.tetta , lowLim[6] , highLim[6]); fineAngle = a[6] * anglesServoBR.tetta + b[6]; servoWrite(m7 , fineAngle); anglesServoBR.alpha = checkLimits(anglesServoBR.alpha , lowLim[7] , highLim[7]); fineAngle = a[7] * anglesServoBR.alpha + b[7]; servoWrite(m8 , fineAngle); anglesServoBR.gamma = checkLimits(anglesServoBR.gamma , lowLim[8] , highLim[8]); fineAngle = a[8] * anglesServoBR.gamma + b[8]; servoWrite(m9 , fineAngle); //BL anglesServoBL.tetta = checkLimits(anglesServoBL.tetta , lowLim[9] , highLim[9]); fineAngle = a[9] * anglesServoBL.tetta + b[9]; servoWrite(m10 , fineAngle); anglesServoBL.alpha = checkLimits(anglesServoBL.alpha , lowLim[10] , highLim[10]); fineAngle = a[10] * anglesServoBL.alpha + b[10]; servoWrite(m11 , fineAngle); anglesServoBL.gamma = checkLimits(anglesServoBL.gamma , lowLim[11] , highLim[11]); fineAngle = a[11] * anglesServoBL.gamma + b[11]; servoWrite(m12 , fineAngle); //BODY angleBody = checkLimits(angleBody , lowLim[12] , highLim[12]); fineAngle = a[12] * angleBody + b[12]; servoWrite(m13 , fineAngle); } double readEncoderAngles() { enc1 , enc2 , enc3 , enc4 , enc5 , enc6 , enc7 , enc8 , enc9 , enc10 , enc11 , enc12 , enc13 = readEncoders(); eang1 = ae[0] * enc1 + be[0]; eang2 = ae[1] * enc2 + be[1]; eang3 = ae[2] * enc3 + be[2]; eang4 = ae[3] * enc4 + be[3]; eang5 = ae[4] * enc5 + be[4]; eang6 = ae[5] * enc6 + be[5]; eang7 = ae[6] * enc7 + be[6]; eang8 = ae[7] * enc8 + be[7]; eang9 = ae[8] * enc9 + be[8]; eang10 = ae[9] * enc10 + be[9]; eang11 = ae[10] * enc11 + be[10]; eang12 = ae[11] * enc12 + be[11]; eang13 = ae[12] * enc13 + be[12]; return eang1 , eang2 , eang3 , eang4 , eang5 , eang6 , eang7 , eang8 , eang9 , eang10 , eang11 , eang12 , eang13; } void calibrationSecuence( ) { //set servos at their middle position at firstt for (int i = 0; i <= 12; i++) { rawAngle , motorPin = motorInfo(i); servoWrite(motorPin , 90); } // sensorOffset0 = calibrateContacts(); Serial.println(" "); Serial.println("_________________________________SERVO CALIBRATION ROUTINE_________________________________"); Serial.println("___________________________________________________________________________________________"); Serial.println("(*) Don"t send several caracter at the same time."); delay(500); Serial.println(" "); Serial.println("Keyboard: "x"-> EXIT CALIBRATION. "c"-> ENTER CALIBRATION."); Serial.println(" "i"-> PRINT INFORMATION. "); Serial.println(" "); Serial.println(" "n"-> CHANGE MOTOR (+). "b" -> CHANGE MOTOR (-)."); Serial.println(" "m"-> START CALIBRATION."); Serial.println(" "q"-> STOP CALIBRATION."); Serial.println(" "); Serial.println(" "r"-> CHANGE RESOLUTION."); Serial.println(" "p"-> ADD ANGLE. "o"-> SUBTRACT ANGLE. "); Serial.println(" "s"-> SAVE ANGLE."); delay(500); Serial.println(" "); Serial.println("---------------------------------------------------------------------------------------------------"); Serial.print("SELECTED MOTOR: "); Serial.print(motorTag[motor]); Serial.print(". SELECTED RESOLUTION: "); Serial.println(res); while (CAL == true) { if (Serial.available() > 0) { cm = Serial.read(); if (cm == "x") { Serial.println("Closing CALIBRATION program..."); CAL = false; secuence = false; startDisplay(PAGE); angleBody = 90; anglesIKFR.tetta = 0.0; anglesIKFR.alpha = -45.0; anglesIKFR.gamma = 90.0; anglesIKFL.tetta = 0.0; anglesIKFL.alpha = -45.0; anglesIKFL.gamma = 90.0; anglesIKBR.tetta = 0.0; anglesIKBR.alpha = 45.0; anglesIKBR.gamma = -90.0; anglesIKBL.tetta = 0.0; anglesIKBL.alpha = 45.0; anglesIKBL.gamma = -90.0; } else if (cm == "i") { // + Serial.println(" "); Serial.println("---------------------------------------------------------------------------------------------------"); Serial.println("---------------------------------------------------------------------------------------------------"); Serial.println("(*) Don"t send several caracter at the same time."); delay(500); Serial.println(" "); Serial.println("Keyboard: "x"-> EXIT CALIBRATION. "c"-> ENTER CALIBRATION."); Serial.println(" "i"-> PRINT INFORMATION. "); Serial.println(" "); Serial.println(" "n"-> CHANGE MOTOR (+). "b" -> CHANGE MOTOR (-)."); Serial.println(" "m"-> START CALIBRATION."); Serial.println(" "q"-> STOP CALIBRATION."); Serial.println(" "); Serial.println(" "r"-> CHANGE RESOLUTION."); Serial.println(" "p"-> ADD ANGLE. "o"-> SUBTRACT ANGLE. "s"-> SAVE ANGLE."); Serial.println(" "); delay(500); Serial.println(" "); Serial.println("---------------------------------------------------------------------------------------------------"); Serial.println(" "); Serial.print("SELECTED MOTOR: "); Serial.print(motorTag[motor]); Serial.print(". SELECTED RESOLUTION: "); Serial.println(res); Serial.println("Actual parameters of the motor: "); Serial.print("High limit: "); Serial.print(highLim[motor]); Serial.print(" Low limit: "); Serial.print(lowLim[motor]); Serial.print(" Angle 1: "); Serial.print(ang1[motor]); Serial.print(" Angle 2: "); Serial.println(ang2[motor]); Serial.println("---------------------------------------------------------------------------------------------------"); } else if (cm == "m") { // + secuence = true; } else if (cm == "s") { // + } else if (cm == "n") { // + motor++; if (motor >= 13) { motor = 0; } Serial.print("SELECTED MOTOR: "); Serial.println(motorTag[motor]); } else if (cm == "b") { // + motor--; if (motor < 0) { motor = 13 - 1; } Serial.print("SELECTED MOTOR: "); Serial.println(motorTag[motor]); } else if (cm == "r") { // + if (res == ares) { res = bres; } else if (res == bres) { res = cres; } else if (res == cres) { res = ares; } Serial.print("SELECTED RESOLUTION: "); Serial.println(res); } } if (secuence == true) { Serial.print("Starting secuence for motor: "); Serial.println(motorTag[motor]); for (int i = 0; i <= 30; i++) { delay(20); Serial.print("."); } Serial.println("."); while (question == true) { unsigned long currentMicros = micros(); if (currentMicros - previousMicros >= 100000) { previousMicros = currentMicros; if (Serial.available() > 0) { answer = Serial.read(); if (answer == "y") { question = false; interp = true; secuence = true; } else if (answer == "n") { question = false; interp = false; secuence = true; } else { Serial.println("Please, select Yes(y) or No(n)."); } } } } answer = "t"; question = true; if (interp == false) { Serial.println("___"); Serial.println(" | Place motor at 1ts position and save angle"); Serial.println(" | This position can be the higher one"); rawAngle , motorPin = motorInfo(motor); calibrationAngle = 90; //start calibration at aproximate middle position of the servo. while (secuence == true) { /* find first calibration angle */ if (Serial.available() > 0) { cm = Serial.read(); if (cm == "p") { // + Serial.print(" | +"); Serial.print(res); Serial.print(" : "); calibrationAngle = calibrationAngle + res; servoWrite(motorPin , calibrationAngle); Serial.println(calibrationAngle); } else if (cm == "o") { // - Serial.print(" | -"); Serial.print(res); Serial.print(" : "); calibrationAngle = calibrationAngle - res; servoWrite(motorPin , calibrationAngle); Serial.println(calibrationAngle); } else if (cm == "r") { // + if (res == ares) { res = bres; } else if (res == bres) { res = cres; } else if (res == cres) { res = ares; } Serial.print("SELECTED RESOLUTION: "); Serial.println(res); } else if (cm == "q") { // quit secuence secuence = false; Serial.println(" | Calibration interrupted!!"); } else if (cm == "s") { // save angle ang1[motor] = calibrationAngle; secuence = false; Serial.print(" | Angle saved at "); Serial.println(calibrationAngle); } } } if (cm == "q") { Serial.println(" |"); } else { secuence = true; Serial.println("___"); Serial.println(" | Place motor at 2nd position and save angle"); Serial.println(" | This position can be the lower one"); } while (secuence == true) { /* find second calibration angle */ if (Serial.available() > 0) { cm = Serial.read(); if (cm == "p") { // + Serial.print(" | +"); Serial.print(res); Serial.print(" : "); calibrationAngle = calibrationAngle + res; servoWrite(motorPin , calibrationAngle); Serial.println(calibrationAngle); } else if (cm == "o") { // - Serial.print(" | -"); Serial.print(res); Serial.print(" : "); calibrationAngle = calibrationAngle - res; servoWrite(motorPin , calibrationAngle); Serial.println(calibrationAngle); } else if (cm == "r") { // + if (res == ares) { res = bres; } else if (res == bres) { res = cres; } else if (res == cres) { res = ares; } Serial.print("SELECTED RESOLUTION: "); Serial.println(res); } else if (cm == "q") { // quit secuence secuence = false; Serial.println(" | Calibration interrupted!!"); } else if (cm == "s") { // save angle ang2[motor] = calibrationAngle; secuence = false; Serial.print(" | Angle saved at "); Serial.println(calibrationAngle); } } } /*--------------------start calibration calculations------------------*/ if (cm == "q") { Serial.println("___|"); Serial.println("Calibration finished unespected."); Serial.println(" Select another motor."); Serial.print("SELECTED MOTOR: "); Serial.print(motorTag[motor]); Serial.print(". SELECTED RESOLUTION: "); Serial.println(res); } else { Serial.println("___"); Serial.println(" |___"); Serial.print( " | | Interpolating for motor: "); Serial.println(motorTag[motor]); secuence = true; //real angle is calculated interpolating both angles to a linear relation. a[motor] = (ang2[motor] - ang1[motor]) / (x2[motor] - x1[motor]); b[motor] = ang1[motor] - x1[motor] * (ang2[motor] - ang1[motor]) / (x2[motor] - x1[motor]); Serial.println(" | |"); } interp = true; } /*---------------------------make swing movement to interpolate motor encoder-----*/ if (interp == true and secuence == true) { delay(200); double x; int k = 0; int stp = 180; swing = true; i = 0; orawAngle , motorPin = motorInfo(motor); previousMicros = 0; while (swing == true) { // FIRST unsigned long currentMicros = micros(); if (currentMicros - previousMicros >= 10000) { // save the last time you blinked the LED previousMicros = currentMicros; x = x2[motor]; calibrationAngle = a[motor] * x + b[motor]; servoWrite(motorPin , calibrationAngle); rawAngle , motorPin = motorInfo(motor); if ((i % 3) == 0) { yi[k+1] = x; xi[k] = rawAngle; Serial.print(" | | Real ang: "); Serial.print(x); Serial.print(" -> Servo ang: "); Serial.print(calibrationAngle); Serial.print(" Enc: "); Serial.println(rawAngle); k++; } if (i >= stp) { swing = false; } i++; } } swing = true; i = 0; while (swing == true) { // moving unsigned long currentMicros = micros(); if (currentMicros - previousMicros >= 10000) { // save the last time you blinked the LED previousMicros = currentMicros; x = x2[motor] + float(i) * (x1[motor] - x2[motor]) / stp; calibrationAngle = a[motor] * x + b[motor]; servoWrite(motorPin , calibrationAngle); rawAngle , motorPin = motorInfo(motor); if ((i % 6) == 0) { yi[k+1] = x; xi[k] = rawAngle; Serial.print(" | | Real ang: "); Serial.print(x); Serial.print(" -> Servo ang: "); Serial.print(calibrationAngle); Serial.print(" Enc: "); Serial.println(rawAngle); k++; } if (i >= stp) { swing = false; } i++; } } swing = true; i = 0; while (swing == true) { // SECOND unsigned long currentMicros = micros(); if (currentMicros - previousMicros >= 10000) { // save the last time you blinked the LED previousMicros = currentMicros; x = x1[motor]; calibrationAngle = a[motor] * x + b[motor]; servoWrite(motorPin , calibrationAngle); rawAngle , motorPin = motorInfo(motor); if ((i % 3) == 0) { yi[k+1] = x; xi[k] = rawAngle; Serial.print(" | | Real ang: "); Serial.print(x); Serial.print(" -> Servo ang: "); Serial.print(calibrationAngle); Serial.print(" Enc: "); Serial.println(rawAngle); k++; } if (i >= stp) { swing = false; } i++; } } swing = true; i = 0; while (swing == true) { // moving unsigned long currentMicros = micros(); if (currentMicros - previousMicros >= 10000) { // save the last time you blinked the LED previousMicros = currentMicros; x = x1[motor] + float(i) * (x2[motor] - x1[motor]) / stp; calibrationAngle = a[motor] * x + b[motor]; servoWrite(motorPin , calibrationAngle); rawAngle , motorPin = motorInfo(motor); if ((i % 6) == 0) { yi[k+1] = x; xi[k] = rawAngle; Serial.print(" | | Real ang: "); Serial.print(x); Serial.print(" -> Servo ang: "); Serial.print(calibrationAngle); Serial.print(" Enc: "); Serial.println(rawAngle); k++; } if (i >= stp) { swing = false; } i++; } } swing = true; i = 0; while (swing == true) { // FIRST unsigned long currentMicros = micros(); if (currentMicros - previousMicros >= 10000) { // save the last time you blinked the LED previousMicros = currentMicros; x = x2[motor]; calibrationAngle = a[motor] * x + b[motor]; servoWrite(motorPin , calibrationAngle); rawAngle , motorPin = motorInfo(motor); if ((i % 3) == 0) { yi[k+1] = x; xi[k] = rawAngle; Serial.print(" | | Real ang: "); Serial.print(x); Serial.print(" -> Servo ang: "); Serial.print(calibrationAngle); Serial.print(" Enc: "); Serial.println(rawAngle); k++; } if (i >= stp) { swing = false; } i++; } } swing = true; i = 0; while (swing == true) { // moving unsigned long currentMicros = micros(); if (currentMicros - previousMicros >= 10000) { // save the last time you blinked the LED previousMicros = currentMicros; x = x2[motor] + float(i) * (x1[motor] - x2[motor]) / stp; calibrationAngle = a[motor] * x + b[motor]; servoWrite(motorPin , calibrationAngle); rawAngle , motorPin = motorInfo(motor); if ((i % 6) == 0) { yi[k+1] = x; xi[k] = rawAngle; Serial.print(" | | Real ang: "); Serial.print(x); Serial.print(" -> Servo ang: "); Serial.print(calibrationAngle); Serial.print(" Enc: "); Serial.println(rawAngle); k++; } if (i >= stp) { swing = false; } i++; } } swing = true; i = 0; while (swing == true) { // SECOND unsigned long currentMicros = micros(); if (currentMicros - previousMicros >= 10000) { // save the last time you blinked the LED previousMicros = currentMicros; x = x1[motor]; calibrationAngle = a[motor] * x + b[motor]; servoWrite(motorPin , calibrationAngle); rawAngle , motorPin = motorInfo(motor); if ((i % 3) == 0) { yi[k+1] = x; xi[k] = rawAngle; Serial.print(" | | Real ang: "); Serial.print(x); Serial.print(" -> Servo ang: "); Serial.print(calibrationAngle); Serial.print(" Enc: "); Serial.println(rawAngle); k++; } if (i >= stp) { swing = false; } i++; } } Serial.println(" | | Interpolation finished!"); /*-------Calculate linear interpolation of the encoder from 60 meassures done in swing------*/ double sx = 0; double sy = 0; double sx2 = 0; double sy2 = 0; double sxy = 0; double xmean = 0; double ymean = 0; int n = 300; for (int i = 0 ; i < n ; i++) { sx += xi[i+10]; sy += yi[i+10]; sx2 += xi[i+10] * xi[i+10]; sy2 += yi[i+10] * yi[i+10]; sxy += xi[i+10] * yi[i+10]; } ae[motor] = (n * sxy - sx * sy) / (n * sx2 - sx * sx); //sxy / sx2; // be[motor] = (sy - ae[motor] * sx) / n; //ymean - ae[motor] * xmean; Serial.println(" | | Moving back to ZERO position."); // turn the motor back to middle position swing = true; i = 0; while (swing == true) { unsigned long currentMicros = micros(); if (currentMicros - previousMicros >= 10000) { // save the last time you blinked the LED previousMicros = currentMicros; x = x1[motor] + float(i) * (90 - x1[motor]) / 60; calibrationAngle = a[motor] * x + b[motor]; servoWrite(motorPin , calibrationAngle); rawAngle , motorPin = motorInfo(motor); eang = ae[motor] * rawAngle + be[motor]; if ((i % 4) == 0) { Serial.print(" | | Servo ang: "); Serial.print(calibrationAngle); Serial.print(" -> Real ang: "); Serial.print(x); Serial.print(" -> Encoder ang: "); Serial.println(eang); } if (i >= 60) { swing = false; } i++; } } Serial.println("___|___|"); Serial.println(" | "); Serial.println("___"); Serial.println(" | Calibration finished satisfactory. Results data:"); Serial.print(" | HIGH lim: "); Serial.print(highLim[motor]); Serial.print(" LOW lim: "); Serial.println(lowLim[motor]); Serial.print(" | angle 1: "); Serial.print(ang1[motor]); Serial.print(" angle 2 "); Serial.println(ang2[motor]); Serial.print(" | Regression Motor a: "); Serial.print(a[motor], 5); Serial.print(" b: "); Serial.println(b[motor], 5); Serial.print(" | Regression Encoder a: "); Serial.print(ae[motor], 5); Serial.print(" b: "); Serial.println(be[motor], 5); Serial.println(" |"); Serial.println(" | ______________________________________________________________"); Serial.println(" | | |"); Serial.println(" | | This code won"t be able to save the updated parameters |"); Serial.println(" | | once the robot is shutted down. |"); Serial.println(" | | |"); Serial.println(" | | Please, write down the results |"); Serial.println(" | | and save them in the definition of each variable. |"); Serial.println(" | |_____________________________________________________________|"); Serial.println(" |"); Serial.println("___|"); Serial.println(" Select another motor."); Serial.print("SELECTED MOTOR: "); Serial.print(motorTag[motor]); Serial.print(". SELECTED RESOLUTION: "); Serial.println(res); } interp = false; secuence = false; } } SAFE = false; Serial.println("Calibration killed"); } // END OF CALIBRATION

This website is using a security service to protect itself from online attacks. The action you just performed triggered the security solution. There are several actions that could trigger this block including submitting a certain word or phrase, a SQL command or malformed data.

The Serial Monitor is a convenient way to view data from an Arduino, but what if you want to make your project portable and view sensor values without access to a computer? Liquid crystal displays (LCDs) are excellent for displaying a string of words or sensor data.
This guide will help you in getting your 16×2 character LCD up and running, as well as other character LCDs (such as 16×4, 16×1, 20×4, etc.) that use Hitachi’s LCD controller chip, the HD44780.
When activated by an electric current, these liquid crystals become opaque, blocking the backlight that is located behind the screen. As a result, that area will be darker than the rest. By activating the liquid crystal layer in specific pixels, characters can be generated.
As the name suggests, these LCDs are ideal for displaying only characters. A 16×2 character LCD, for example, can display 32 ASCII characters across two rows.
If you look closely, you can see tiny rectangles for each character on the screen as well as the pixels that make up a character. Each of these rectangles is a grid of 5×8 pixels.
Character LCDs are available in a variety of sizes and colors, including 16×1, 16×4, 20×4, white text on a blue background, black text on a green background, and many more.
One advantage of using any of these displays in your project is that they are “swappable,” meaning that you can easily replace them with another LCD of a different size or color. Your code will need to be tweaked slightly, but the wiring will remain the same!
Before we get into the hookup and example code, let’s check out the pinout. A standard character LCD has 16 pins (except for an RGB LCD, which has 18 pins).
Vo (LCD Contrast) pin controls the contrast of the LCD. Using a simple voltage divider network and a potentiometer, we can make precise contrast adjustments.
RS (Register Select) pin is used to separate the commands (such as setting the cursor to a specific location, clearing the screen, etc.) from the data. The RS pin is set to LOW when sending commands to the LCD and HIGH when sending data.
R/W (Read/Write) pin allows you to read data from or write data to the LCD. Since the LCD is only used as an output device, this pin is typically held low. This forces the LCD into WRITE mode.
E (Enable) pin is used to enable the display. When this pin is set to LOW, the LCD ignores activity on the R/W, RS, and data bus lines; when it is set to HIGH, the LCD processes the incoming data.
D0-D7 (Data Bus) pins carry the 8 bit data we send to the display. To see an uppercase ‘A’ character on the display, for example, we set these pins to 0100 0001 (as per the ASCII table).
The LCD has two separate power connections: one for the LCD (pins 1 and 2) and one for the LCD backlight (pins 15 and 16). Connect LCD pins 1 and 16 to GND and 2 and 15 to 5V.
Depending on the manufacturer, some LCDs include a current-limiting resistor for the backlight. It is located on the back of the LCD, close to pin 15. If your LCD does not contain this resistor or if you are unsure whether it does, you must add one between 5V and pin 15. It should be safe to use a 220 ohm resistor, although a value this high may make the backlight slightly dim. For better results, check the datasheet for the maximum backlight current and choose an appropriate resistor value.
Let’s connect a potentiometer to the display. This is necessary to fine-tune the contrast of the display for best visibility. Connect one side of the 10K potentiometer to 5V and the other to Ground, and connect the middle of the pot (wiper) to LCD pin 3.
That’s all. Now, turn on the Arduino. You will see the backlight light up. As you turn the potentiometer knob, you will see the first row of rectangles appear. If you have made it this far, Congratulations! Your LCD is functioning properly.
We know that data is sent to the LCD via eight data pins. However, HD44780-based LCDs are designed so that we can communicate with them using only four data pins (in 4-bit mode) rather than eight (in 8-bit mode). This helps us save 4 I/O pins!
8-bit mode is significantly faster than 4-bit mode. This is because in 8-bit mode, data is written in a single operation, whereas in 4-bit mode, a byte is split into two nibbles and two write operations are performed.
Therefore, 4-bit mode is commonly used to save I/O pins. 8-bit mode, on the other hand, is best suited when speed is a priority in the application and at least 10 I/O pins are available.
The sketch begins by including the LiquidCrystal library. This library comes with the Arduino IDE and allows you to control Hitachi HD44780 driver-based LCD displays.
Next, an object of the LiquidCrystal class is created by passing as parameters the pin numbers to which the LCD’s RS, EN, and four data pins are connected.
In the setup, two functions are called. The first function is begin(). It is used to initialize the interface to the LCD screen and to specify the dimensions (columns and rows) of the display. If you’re using a 16×2 character LCD, you should pass 16 and 2; if you’re using a 20×4 LCD, you should pass 20 and 4.
In the loop, the print() function is used to print “Hello world!” to the LCD. Please remember to use quotation marks " " around the text. There is no need for quotation marks when printing numbers or variables.
The function setCursor() is then called to move the cursor to the second row. The cursor position specifies where you want the new text to appear on the LCD. It is assumed that the upper left corner is col=0 and row=0.
There are many useful functions you can use with LiquidCrystal Object. Some of them are listed below:lcd.home() function positions the cursor in the upper-left of the LCD without clearing the display.
lcd.scrollDisplayRight() function scrolls the contents of the display one space to the right. If you want the text to scroll continuously, you have to use this function inside a for loop.
lcd.scrollDisplayLeft() function scrolls the contents of the display one space to the left. Similar to the above function, use this inside a for loop for continuous scrolling.
lcd.display() function turns on the LCD display, after it’s been turned off with noDisplay(). This will restore the text (and cursor) that was on the display.
If you find the default font uninteresting, you can create your own custom characters (glyphs) and symbols. They come in handy when you need to display a character that isn’t in the standard ASCII character set.
As previously discussed in this tutorial, a character is made up of a 5×8 pixel matrix; therefore, you must define your custom character within this matrix. You can define a character by using the createChar() function.
To use createChar(), you must first create an 8-byte array. Each byte in the array corresponds to a row in a 5×8 matrix. In a byte, the digits 0 and 1 indicate which pixels in a row should be ON and which should be OFF.
CGROM is non-volatile memory that retains data even when the power is removed, whereas CGRAM is volatile memory that loses data when the power is removed.
The CGROM stores the font that appears on a character LCD. When you instruct a character LCD to display the letter ‘A’, it needs to know which dots to turn on so that we see an ‘A’. This data is stored in the CGROM.
CGRAM is an additional memory for storing user-defined characters. This RAM is limited to 64 bytes. Therefore, for a 5×8 pixel LCD, only 8 user-defined characters can be stored in CGRAM, whereas for a 5×10 pixel LCD, only 4 can be stored.
Creating custom characters has never been easier! We’ve developed a small application called Custom Character Generator. Can you see the blue grid below? You can click on any pixel to set or clear that pixel. And as you click, the code for the character is generated next to the grid. This code can be used directly in your Arduino sketch.
There’s no limit to what you can create. The only limitation is that the LiquidCrystal library only supports eight custom characters. But don’t be sad, look at the bright side; at least we have eight characters.
After including the library and creating the LCD object, custom character arrays are defined. The array consists of 8 bytes, with each byte representing a row in a 5×8 matrix.
This sketch contains eight custom-characters. Take, for example, the Heart[8] array. You can see that the bits (0s and 1s) are forming the shape of a heart. 0 turns the pixel off, and 1 turns it on.
In the setup, we use the createChar() function to create a custom character. This function accepts two parameters: a number between 0 and 7 to reserve one of the eight supported custom characters, and the name of the array.

Hi, and welcome to this tutorial, it’s about another RTC (Real Time Clock) module, it’s the DS1307, previously I did a tutorial about the DS1302, and a project where I set it up using a keypad, then an Alarm Clock project based on that module, I also did a tutorial about the DS3132.
But today we’re about the DS1307, and I’m gonna use it with Arduino UNO board and I’ll also use a LCD i²c screen and OLED display, to show time and date in different formats.
“The DS1307 serial real-time clock (RTC) is a lowpower, full binary-coded decimal (BCD) clock/calendar plus 56 bytes of NV SRAM. Address and data are transferred serially through an I2C, bidirectional bus. The clock/calendar provides seconds, minutes, hours, day, date, month, and year information. The end of the month date is automatically adjusted for months with fewer than 31 days, including corrections for leap year.”
OLED libraries: – Download here Adafruit OLED SSD1306 library – Download here Adafruit GFX Library
Important !! First time you must wire the module and upload the “SetTime” example, it sets the module to the compiling time of the code which is technically your real time and date.
N.B: If you are testing the module with multiple things it’s better to close the “SetTime” example, open it again and upload to the board, otherwise your module will be programmed with the first time the “SetTime” example was compiled, and you may think that your module doesn’t work well !!

Sometimes it may be necessary to use a display while making a hardware project, but the size and the type of the display may vary according to the application. In a previous project, we used a 0.96″ I2C OLED display, and in this project we will have an I2C 20×4 character display.
This liquid crystal display has 4 lines, 20 character in each line and cannot be used to display graphics. The main feature of this display that it uses I2C interface, which means that you will need only two wires to connect with Arduino. At the back side of the screen there is a small PCB soldered in the display, this circuit is a serial LCD 20 x 4 module and it also has a small trimpot to adjust the contrast of the LCD.
Display’s backlight is blue and the text is white. It is fully compatible with Arduino and has 5V input voltage. Its I2C address could be 0x27 or 0x3F. You can get it for about $7 from Bangood store.
DS3231 is a low-cost, accurate I2C real-time clock (RTC), with an integrated temperature-compensated crystal oscillator (TCXO) and crystal. The device incorporates a battery input, so that if power is disconnected it maintains accurate time.
RTC maintains seconds, minutes, hours, day, date, month, and year information. Less than 31 days of the month, the end date will be automatically adjusted, including corrections for leap year. The clock operates in either the 24 hours or band / AM / PM indication of the 12-hour format. Provides two configurable alarm clock and a calendar can be set to a square wave output. Address and data are transferred serially through an I2C bidirectional bus.
This RTC module operates at input voltage range between 3.3V and 5.5V, so it can be connected with 3.3V or 5V pins. It is available on Banggood store for about $2.
First we need to download the library of the display, which includes all required functions to configure and write on the display. You can find it here.
Unzip the library and add it to the Arduino libraries folder, then run Arduino IDE and copy the following code. The first two lines are to include both of I2C and LCD libraries.
lcd.setCursor(3,0) will set the cursor of the LCD in the specified location, the first argument for the column and the second for the row starting form 0.
Here we will use a small breadboard to connect the RTC module and display with the Arduino’s I2C pins (A4 and A5). The SCL pins are connected with analog 5 pin and the SDA pins with analog 6 pin. The top rail of the breadboard used as I2C bus and the bottom one is power bus.
In addition to setup and loop function, we will create four other functions to organize the code. As the corners and vertical lines of the frame are special characters, we have to create them manually. So we will use a function to create them and another one to print them on the LCD.
Inside the loop function the time will be read from the real time clock module and the printed to the LCD using a custom function for each of time and date.
At first, we have to include the three libraries, I2C, LCD, and RTC and set the LCD address. Inside the setup function the display is initialized, then we will call createCustomCharacters() function and print them.
Each character can be 5-pixel long in width and 8-pixel in height. So to create a custom character we need to create a new byte. We need 5 characters, the vertical line and the four corners. The yellow pattern shows you how the character will be displayed on the LCD.
Inside createCustomCharacters() function, we called lcd.createChar(#, byte array) function. The LCD supports up to 8 custom characters numbered from 0 to 7. It will assign the index in the first argument to the character given by the byte array. To print this character we can use lcd.write(byte(#)) function.
This function is very simple, it uses lcd.setCursor(#,#) to move the cursor and lcd.print(“”) to print the given string. The function will print the top and bottom horizontal lines, then printing other custom characters.
As we discussed earlier, the loop function will get the current time and date every second and refresh them on the display. First we defined a time element “tm” which has current time data, then if the time is correct and the RTC module working fine the time and date will be printed.
We can add some instructions so, if the DS1307 is stopped or there is a circuit error,we can light a LED to indicate the problem. The loop will wait for 1 second before starting the next iteration.
PrintTime function uses three arguments, the column and line where it will print the time, and the time element. lcd.print(tm.Hour) will print the hour, then if the minutes and seconds are less than 10 we will add 0 to the left. And the same method is used to print the date.
Now everything is ready, upload the code to your Arduino and enjoy watching your new clock. You can find the full Arduino sketches and libraries in the attachment below.

In many electronic projects, particulary IoT (Internet of Things) projects, you will need to log data (store or keep) like temperature, time, humidity, current, power, light intensity, and many more. With this data logger shield, you can do it easily because the hardware connection is ready with proper SD card socket, Real Time Clock, level shifter for Arduino. It is plug and use shield for data logging.
And with Arduino library, you can start saving data to files on any FAT16 or FAT32 formatted SD card. The included RTC (Real Time Clock) IC, DS1307, can be used to timestamp all your data with the current time, so that you know precisely what happened when!

A digital clock is a great invention in electronics science. Nowadays, digital clocks are used everywhere. The analog clocks are quite old-fashioned. So the digital clock takes its place day by day. The Arduino digital clock is looking very modern. It has many additional features also like temperature, alarm, timer, etc.
In this electronics project, we are going to build an Arduino digital clock with or without an RTC (Real Time Clock) module. The first circuit represents without RTC module and the second circuit represents with RTC module. The components we used in this project are quite basic and a little expensive. The circuit connection is very easy.
We build this digital clock with an Arduino, RTC module, and LCD display in this project. Here the clock we made is 24 hours clock. This means the time shows by the clock is 00.00 AM to 23.59. After 23.59 it resets to 0 again.
Arduino is one of the most popular electronics prototyping boards based on the ATmega328P microcontroller. ATmega328P is an AVR architecture based 8-bit microcontroller. Here I am using Arduino Nano for this project to give it a compact look.
A 16×2 LCD display is the most commonly used display unit for microcontroller-based applications. It supports 16 characters in a row with two such rows. It also supports special characters and even custom characters.
I2C Module has an inbuilt PCF8574 I2C chip that converts I2C serial data to parallel data for the 16 pins LCD display. It is currently available with a default I2C address of either 0x27 or 0x3F. With this I2C LCD module, we can able to show data via only 2 wires that are SDA and SCL pins.
The DS1307 real-time clock (RTC) is a low power, full binary-coded decimal (BCD) clock plus 56 bytes of NV SRAM. Address and data are transferred serially through an I2C bus. This clock provides seconds, minutes, hours, days, dates, months, and years.
A serial I2C bidirectional bus made a communication between the Arduino and the DS1307 RTC module. The I2C protocol is a technique for communicating a faster device (master mode) and a slower device (slave mode).
To make the circuit compact and give a professional look, I have designed the PCB after testing all the features of the Arduino Digital Clock Circuit PCB on the breadboard. I will explain in detail how we can design and order PCB for our project.
This project is sponsored by PCBWay.com. PCBWay is a Chinese-based PCB (printed circuit board) prototype, PCB assembly, SMD Stencil, and Flexible PCB manufacturer. They ship to more than 170 countries worldwide and process more than 2100 PCB orders a day. It feels like PCBWay gives an excellent price and customer service factor in one single serving. The quality of the PCB is awesome and its thickness is really great. What is also spectacular about PCBWay to me, as a maker and customer, is their service. From their friendly support staff to their intuitive, user-friendly website features, it all counts towards what makes PCBWay an ideal company and brand for any electronic hobbyists In this article, I will state that how can we order PCB from PCBWay with step by step guide.
They are not only producing FR-4 and Aluminum boards, but also advanced PCB like Rogers, HDI, Flexible and Rigid-Flex boards, at a very reasonable price.
SMT & THT assembly starts from only $30 with a free stencil and free worldwide shipping. The components can be sourced and provided by PCBWay, or by clients themselves.
With a real-time clock module, this circuit is working in automatic mode. Although we can manually set the time as our requirements through Arduino code. As we say that this is an automatic clock so the system can set time and date itself like a computer.
First of all, connect all two push buttons’ any one terminal to the ground. Then other terminals of the two buttons are connected to analog pins D8 and D9 of the Arduino respectively.
To make the circuit compact and give a professional look, I have designed the PCB after testing all the features of the Arduino Digital Clock on the breadboard. I will explain in detail how we can design and order PCB for our project.
The first button is for setting up the hour by sending a signal to the D8 pin. The second button is for setting up the minutes by sending a signal to the D9 pin of the Arduino.
The whole circuit is working as a continuous sequence. When the power goes out, the circuit will reset to its initial position. Then we need to again set the time via the push button. So this is a major drawback for this circuit.
For this project, it needs to set the real-time into Arduino code when uploading. But after that, we need not set the time every time when better die. Just remove the old battery and put the new one that’s it.
Yes, there is a few Arduino real-time clock (RTC) libraries in the library manager of the Arduino IDE software. These help to compile Arduino code and upload it into the Arduino board.
To make this clock is too easy. But the only drawback of this clock is when the power cut down, we need to set the time again from the beginning. To build this clock go to this blog and check out the second circuit.
The main purpose of using an RTC or a real-time clock is to provide a precise time and date which is very accurate. RTC is an electronic device in the form of an Integrated Chip (IC) available in various packaging options. It is powered by an internal lithium-ion battery.
An RTC maintains its clock by counting the cycles of an oscillator (32.768KHz Crystal Oscillator) circuit, an internal capacitor-based oscillator, or even an embedded quartz crystal. Some RTCs maintain the oscillator setting at the last known point before it went out of the lock with the power input.

In the Arduino Real Time Clock Tutorial, we will learn about Real Time Clock (RTC) and how Arduino and Real Time Clock IC DS1307 are interfaced as a time keeping device. If you ...

In this project I have created a digital clock. we can watch the current date and time on the lcd display this project uses DS1307 based RTC module to to maintain the time and date value.
this module is build around DS1307 chip which is a real time clock that means we can get hour, second, minutes, day, date, month and year value fromitthis module require external power source so that it can power the module during power failure so if we remove the power supply of our clock it would not lost its time for this we uses a 3V li-ion battery this module support I2C (two wire interface) to talk to master device Like Arduino in this case once we store the current time value of second hour minute day date month and year into their corresponding registers and and then ds1307 maintains the time and updates the register values to know more about ds1307 you can have a look at he datasheet ds1307 stores the data in BCD(binary coded decimal) format
to display time and date I have used used 16*2 lcd because it is easy to control it by Arduino in comparison to 7 segment display we can interface with lcd by the help of LiquidCrystal library of arduino
these resistors are necessary for I2C interface because I2C devices have open collector configuration these pullup resistors pull the SDA and SCL line high
Ms.Josey
Ms.Josey