word clock RTC module

Hello
im working on a word clock project, iam a novice in world of coding so i have been googling around a actually got a word clock code to work, with some pieces here and there.

but i have learned that my clock is not accurate, it keep loosing a few ms over time and in a month some minutes, so i*am trying to add a RTC module like DS3231.

but i dont know how or where i should add it.
can
t really find any tutorials on how to use the hh and mm and sec from DS3231 to control my led strip or normal leds.

anyone?

PART 1

#include <Time.h>
#include <TimeLib.h>

/* 

  Arduino + Neopixel Word Clock Code
  by: Alex - Super Make Something
  date: August 16, 2015
  license: Public domain.  Please use, reuse, and modify this sketch!
  additional: modified from "simple.ino" NeoPixel example sketch by Shae Erisson of Adafruit Industries.  
  
  NOTE: REQUIRES NEOPIXEL & TIME LIBRARIES TO BE INSTALLED UNDER ...\Arduino\libraries
  NEOPIXEL LIBRARY AVAILABLE AT: https://github.com/adafruit/Adafruit_NeoPixel
  TIME LIBRARY AVAILABLE AT: https://github.com/PaulStoffregen/Time
  
  Explanation: This code lights up Neopixels corresponding to the current time.
  Time is kept using the time library.
  Neopixels are lit using the Adafruit Neopixel library.
  
  Depending on the current time, flags to light corresponding Neopixels are saved in an array
  After parsing the time, Neopixels are turned on/off according to the flags using a for loop

*/
/*
Dette er version 1.0
har 2 knapper som �ker � minsker tiden med 5min.
3x pot meter som forandrer fargene individuelt med � �ke / minske RGB komponentene.
photo sensor som automatisk �ker eller minsker brightness
m� nok justere den b�de i code i motstanden s� den wirke bedre.
er ikke brukt chrono dot elr s�nn time keeping chip.
arduino uno.
*/

#include <Adafruit_NeoPixel.h>
#include <avr/power.h>
#include "Time.h"

// Which pin on the Arduino is connected to the NeoPixels?
#define PIN           3

// How many NeoPixels are attached to the Arduino?
#define NUMPIXELS     32
#define LIGHT_SENSOR_PIN A4
#define RED_POT_PIN  A5
#define GREEN_POT_PIN  A2
#define BLUE_POT_PIN  A3

// When we setup the NeoPixel library, we tell it how many pixels, and which pin to use to send signals.
// Note that for older NeoPixel strips you might need to change the third parameter--see the strandtest
// example for more information on possible values.
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

// Declare integer array with size corresponding to number of Neopixels in chain
// int individualPixels[NUMPIXELS];

//Declare pins for decrementing/incrementing current time by 5 minutes
#define MINUSFIVEMINS 4
#define PLUSFIVEMINS  5

// Current and previous states for button pins -- in setup initialize all to HIGH
int minusPrevState=HIGH;
int minusCurrState=HIGH;
int plusPrevState=HIGH;
int plusCurrState=HIGH;


// Time variables
int h;
int m;
int s;

// RGB color variables
int red=0;
int green=0;
int blue=0;

void setup()
{

  pinMode(MINUSFIVEMINS, INPUT_PULLUP); //Define pin as input, enable pull-up resistor
  pinMode(PLUSFIVEMINS, INPUT_PULLUP); //Define pin as input, enable pull-up resistor

  setTime(12,0,0,31,8,2015); //Initialize current time as Midnight/noon 08/31/2015
  pixels.begin(); //Begin Neopixel string
  Serial.begin(9600); //Begin Serial for debugging purposes

  pinMode(RED_POT_PIN  , INPUT);
  pinMode(GREEN_POT_PIN  , INPUT);
  pinMode(BLUE_POT_PIN  , INPUT);
  
}

void loop()
{
  
  //Declare integer array with size corresponding to number of Neopixels in chain
  int individualPixels[NUMPIXELS]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  
  /* Check for button presses & reset time if necessary */
  minusCurrState=digitalRead(MINUSFIVEMINS); //Get current state of MINUSFIVEMINS button
  /* If current state is different from previous state and value is now LOW, subtract five minutes from current time */
  if ((minusCurrState!=minusPrevState) && (minusCurrState==LOW)){
    adjustTime(-5*60); //Shift time five minutes backwards
    minusPrevState=minusCurrState;
  }
  else{
   minusPrevState=minusCurrState; 
  }
  
  plusCurrState=digitalRead(PLUSFIVEMINS); //Get current state of PLUSFIVEMINS button
  /* If current state is different from previous state and value is now LOW, add five minutes from current time */
  if ((plusCurrState!=plusPrevState) && (plusCurrState==LOW)){
    adjustTime(5*60); //Shift time five minutes forwards
    plusPrevState=plusCurrState;
  }
    else{
   plusPrevState=plusCurrState; 
  }
    
  /* Get current time */
  h=hourFormat12();    // Returns the hour of current time between 1-12
  m=minute();        // Returns the minute of current time
  s=second();        // Returns the second of current time (not used, included for completeness)
  
  Serial.print(h);
  Serial.print(":");
  Serial.print(m);
  Serial.print(":");
  Serial.println(s);

PART 2

/* Parse time values to light corresponding pixels */
  individualPixels[0]=1; //Light "IT"
  individualPixels[1]=1; //Light "IS" 
  
  /* Minutes between 0-5 - Light "O CLOCK" */
  if ((m>=0 && m<5)){
    individualPixels[28]=1;
    individualPixels[29]=1;
  }
  
  /* Minutes between 5-10 or 55-60 - Light "FIVE," "MINUTES" */
  if ((m>=5 && m<10) || (m>=55 && m<60)){
    individualPixels[8]=1;
    individualPixels[9]=1;
    individualPixels[10]=1;
  }
  
  /* Minutes between 10-15 or 50-55 - Light "TEN," "MINUTES" */
  if ((m>=10 && m<15) || (m>=50 && m<55)){
    individualPixels[2]=1;
    individualPixels[9]=1;
    individualPixels[10]=1;
  }
  
  /* Minutes between 15-20 or 45-50 - Light "QUARTER" */
  if ((m>=15 && m<20) || (m>=45 && m<50)){
    individualPixels[6]=1;
    individualPixels[7]=1;
  }
  
  /* Minutes between 20-25 or 40-45 - Light "TWENTY," "MINUTES" */
  if ((m>=20 && m<25) || (m>=40 && m<45)){
    individualPixels[4]=1;
    individualPixels[5]=1;
    individualPixels[9]=1;
    individualPixels[10]=1;
  }  

  /* Minutes between 25-30 or 35-40 - Light "TWENTY," "FIVE," "MINUTES" */
  if ((m>=25 && m<30) || (m>=35 && m<40)){
    individualPixels[4]=1;
    individualPixels[5]=1;
    individualPixels[8]=1;
    individualPixels[9]=1;
    individualPixels[10]=1;
  }

  /* Minutes between 30-35 - Light "HALF" */
  if ((m>=30 && m<35)){
    individualPixels[3]=1;
  }
  
  /* Minutes between 5-35 - Light "PAST" */
  if ((m>=5) && (m<35)){
    individualPixels[14]=1;
  }
  
  /* Minutes between 35-60 - Light "TO" & MODIFY CURRENT HOUR VALUE */
  if (m>=35){
    individualPixels[13]=1;
    h++; //Add 1 from current hour
    /*Set time to twelve for hour around midnight, noon */
    if (h==0){
      h=12; 
    }
    /*Corner case for 12:35-12:59 */
    if (h==13){
      h=1;
    }
  }

  /* Hour=1 - Light "ONE" */
  if (h==1){
    individualPixels[12]=1;
  }
  
  /* Hour=2 - Light "TWO" */
  if (h==2){
    individualPixels[11]=1;
  }
  
  /* Hour=3 - Light "THREE" */
  if (h==3){
    individualPixels[15]=1;
    individualPixels[16]=1;    
  }
  
  /* Hour=4 - Light "FOUR" */
  if (h==4){
    individualPixels[17]=1;
  }
  
  /* Hour=5 - Light "FIVE" */
  if (h==5){
    individualPixels[18]=1;
  }
  
  /* Hour=6 - Light "SIX" */
  if (h==6){
    individualPixels[23]=1;
  }
  
  /* Hour=7 - Light "SEVEN" */
  if (h==7){
    individualPixels[21]=1;
    individualPixels[22]=1;
  }
  
  /* Hour=8 - Light "EIGHT" */
  if (h==8){
    individualPixels[19]=1;
    individualPixels[20]=1;
  }
  
  /* Hour=9 - Light "NINE" */
  if (h==9){
    individualPixels[24]=1;
  }
  
  /* Hour=10 - Light "TEN" */
  if (h==10){
    individualPixels[25]=1;
  }
  
  /* Hour=11 - Light "ELEVEN" */
  if (h==11){
    individualPixels[26]=1;
    individualPixels[27]=1;
  }
  
  /* Hour=12 - Light "TWELVE" */
  if (h==12){
    individualPixels[30]=1;
    individualPixels[31]=1;
  }
  
  /* Light pixels corresponding to current time */
  
  for (int i=0; i<sizeof(individualPixels); i++){
    if (individualPixels[i]==1){
      red =  map(analogRead(RED_POT_PIN  ),0,1024,0,255);
      green = map(analogRead(GREEN_POT_PIN  ),0,1024,0,255);
      blue = map(analogRead(BLUE_POT_PIN  ),0,1024,0,255);
      pixels.setPixelColor(i, pixels.Color(red,green,blue)); //Set Neopixel color
    }
    else{
      pixels.setPixelColor(i,pixels.Color(0,0,0));
    }
  }
int lightSensorValue = analogRead(LIGHT_SENSOR_PIN);
int brightness = map(lightSensorValue,0,4095,0,255); 
pixels.setBrightness(brightness);
  pixels.show(); //Display Neopixel color
  
//  /* Clear pixel values for re-assignment during next iteration */
//  for (int j=0; j<sizeof(individualPixels); j++){
//      individualPixels[j]=0; //Set array values to 0
//      pixels.setPixelColor(j, pixels.Color(0,0,0)); //Set Neopixel color to 0 brightness, i.e. off
//  }
  
}

If you are just starting out with programming, this project is way too ambitious.

You need to understand the basics first, so try out the example programs that come with the IDE (Blink without delay, analog read etc.) first and when you are comfortable, move on.

As a beginner, you should use an RTC library instead of writing code to access the RTC directly with the wire (I2C) library.

i*am trying to add a RTC module like DS3231.

Good idea. Get a module and learn how to use it without having anything to do with your word clock sketch.

The RTC module will connect on the I2C bus, and you will need the Wire.h library to manage the low level communication between the Arduino and the RTC. It will also help to use a library to manage the RTC. Most simply, you can use the standard DS1307 library which will manage the time functions perfectly well. If you feel comfortable with more complexity use Jack Christensen's library for the DS3232/3231 which will include the alarm and temperature functions.

You are currently using the Time library, and both RTC libraries I mentioned integrate well with it. There is an example in the Time Library called TimeRTC which synchronizes the Arduino's internal clock and the Time Library's use of that internal clock with the RTC time. The key function is

setSyncProvider(RTC.get);   // the function to get the time from the RTC

The synchronization means that on periodic intervals, the Time Library executes code to read the time from the RTC and adjusts it's internal time keeping accordingly.

Once you have the synchronization working, the current sketch using the time library's time variables will use continually synchronized values for them and you should not have to make any changes to it.

/* Get current time */
  h=hourFormat12();    // Returns the hour of current time between 1-12
  m=minute();        // Returns the minute of current time
  s=second();        // Returns the second of current time (not used, included for completeness)

Thank you guys for the replays.
i am working on learning the RTC modules and libraries with basics leds,
but i am a builder not a coder hehe =)

and to be honest i was hoping for someone to take a quick look
and just tell me

remove XXXXX

add XXXX

then change XXXXX to XXXXXXXX

  • cheers

remove: Nothing

add:

Wire.h,
RTC library(either Margolis DS1307, or Christensen DS3232),
setSynchProvider(rtc.get)

then change : Nothing

It really will be very simple.

If you can't work your way through this, I'm going to endorse jremington's assesment

If you are just starting out with programming, this project is way too ambitious.

You need to understand the basics first, so try out the example programs that come with the IDE (Blink without delay, analog read etc.) first and when you are comfortable, move on.

it feels like i am so close but still so far awey, and if i understand u guys right i only need to add a small piece of code(wich i don*t know how and where) to get the DS3232 to sync the internal time.

i have been reading your posts and suggestions over and over agien but i still can*t figuring this out.
and when you said i didnt have to change much in my wordclock program to make it work with the DS3232 time keeping chip so its accurate i got so very excited.

this is the only 3 line i have added / made some changes to.

##include <Wire.h>
#include <DS3232RTC.h>
setSyncProvider(rtc.get);   // the function to get the time from the RTC

but i get the error below

Arduino: 1.6.6 (Mac OS X), Board: "Arduino/Genuino Uno"

sketch_jan12o:6: error: expected constructor, destructor, or type conversion before '(' token
 setSyncProvider(rtc.get);   // the function to get the time from the RTC
                ^
exit status 1
expected constructor, destructor, or type conversion before '(' token

  This report would have more information with
  "Show verbose output during compilation"
  enabled in File > Preferences.

Post ALL your code, using code tags.

Isn't it obvious that you would use this function call:

setSyncProvider(rtc.get);   // the function to get the time from the RTC

at the place in the code where you actually want to fetch the current time?

@mikki1211

I had hoped that you would take a look at the Time library example TimeRTC which demonstrates the use of setSynchProvider().

The positioning of setSynchProvider(RTC.get) is in setup.

#include <TimeLib.h>
#include <Wire.h>
#include <DS1307RTC.h>  // a basic DS1307 library that returns time as a time_t

void setup()  {
  Serial.begin(9600);
  while (!Serial) ; // wait until Arduino Serial Monitor opens
  setSyncProvider(RTC.get);   // the function to get the time from the RTC
  if(timeStatus()!= timeSet) 
     Serial.println("Unable to sync with the RTC");
  else
     Serial.println("RTC has set the system time");      
}

void loop()
{
  if (timeStatus() == timeSet) {
    digitalClockDisplay();
  } else {
    Serial.println("The time has not been set.  Please run the Time");
    Serial.println("TimeRTCSet example, or DS1307RTC SetTime example.");
    Serial.println();
    delay(4000);
  }
  delay(1000);
}

void digitalClockDisplay(){
  // digital clock display of the time
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(" ");
  Serial.print(day());
  Serial.print(" ");
  Serial.print(month());
  Serial.print(" ");
  Serial.print(year()); 
  Serial.println(); 
}

void printDigits(int digits){
  // utility function for digital clock display: prints preceding colon and leading 0
  Serial.print(":");
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);
}

Now i finally got the the DS3231 to set the system time,
so thank you guys so much, but

however i think there is a small problem, i think the ds3231
just set the time once at startup and not continuesly adjusting it.

is there a way to check or make it adjust the internal time continuesly?

does anyone got a exemple / tutorial on how i can grab the hours / min / second from the DS3231 chronodot chip and use it to control some leds, like turn on / off leds at certain times.
i googled alot on the internet but i can*t find anything about it.

however i think there is a small problem, i think the ds3231
just set the time once at startup and not continuesly adjusting it.

Why do you think that? The default resynchronization period is every 5 minutes.

From the Time Library documentation

Internal system time is based on the standard Unix time_t.
The value is the number of seconds since Jan 1 1970.
System time begins at zero when the sketch starts.

The internal time can be automatically synchronized at regular intervals to an external time source.
This is enabled by calling the setSyncProvider(provider) function - the provider argument is
the address of a function that returns the current time as a time_t.
See the sketches in the examples directory for usage.

The default interval for re-syncing the time is 5 minutes but can be changed by calling the
setSyncInterval( interval) method to set the number of seconds between re-sync attempts.