Go Down

Topic: Countdown until Christmas (Read 258 times) previous topic - next topic

MITLRpro

Hi All,

I'm having trouble getting this code to work...can anyone shed some light?

Code: [Select]
/*
* Christmas.ino
* countdown the days, hours and minutes till christmas.
*/

#include <Time.h>
#include <Wire.h>
#include "RTClib.h"
RTC_DS1307 rtc;

//Libraries for Dot Matrix
#include <SPI.h>
#include <DMD.h>
#include <TimerOne.h>
DMD dmd(1, 1);

#define SPEAKERPIN 4


byte handx[]={12,13,14,15,16,17,18,19,20,21,21,22,
  22,23,23,23,23,23,22,22,21,21,20,19,
  18,17,16,15,14,13,12,10,9,8,7,6,
  5,4,3,2,2,1,1,0,0,0,0,0,
  1,1,2,2,3,4,5,6,7,8,9,10};

byte handy[]={0,0,0,0,1,1,1,2,2,3,4,4,
  5,6,7,8,8,9,10,11,11,12,13,13,
  14,14,14,15,15,15,15,15,15,15,14,14,
  14,13,13,12,11,11,10,9,8,8,7,6,
  5,4,4,3,2,2,1,1,1,0,0,0};

int dmode=0;    //display mode
int brightness=2;   //display brightness
int bcount=0;   //variable used to keep track of pwm phase
#define BSTEPS 7

void ScanDMD(){       //also implements a basic pwm brightness control
  dmd.scanDisplayBySPI();
  bcount=bcount+brightness;
  if(bcount<BSTEPS){digitalWrite(9,LOW);}
  bcount=bcount%BSTEPS;
}

void setup () {
  Wire.begin();
     Serial.begin(9600);

  Timer1.initialize( 500 );           //period in microseconds to call ScanDMD. Anything longer than 5000 (5ms) and you can see flicker.
  Timer1.attachInterrupt( ScanDMD );   //attach the Timer1 interrupt to ScanDMD which goes to dmd.scanDisplayBySPI()
  dmd.clearScreen( true );     //clear/init the DMD pixels held in RAM
  digitalWrite(SPEAKERPIN,LOW);    //speaker off
  rtc.begin();
}
 


void loop () {
 
  setSyncProvider(RTC.get);
  time_t daysleft,christmasdate; // setup the fields needed.
       christmasdate = 1482670799; // December 25, 2016
       daysleft = christmasdate - now(); // subtract todays date from the christmas date to get the days left.


  // Display the days left before christmas.
  dmd.selectFont( SystemFont5x7 );
  dmd.drawString( 0,0, "Days,", 4, GRAPHICS_NORMAL );
  dmd.drawString( 2,9, displayDaysDigits(daysleft / SECS_PER_DAY);, 3, GRAPHICS_NORMAL );




The idea is for the Dot Matrix Display...

(http://www.freetronics.com.au/collections/display/products/dot-matrix-display-32x16-red#.WAMtG-B97cd)
(http://www.freetronics.com.au/pages/using-your-freetronics-dmd#.WAMtLOB97cc)

To countdown the days until Christmas. I'd like it to eventually display the days, hours, minutes, seconds. But should be able to figure that out when this piece of code works.

My current error messages are:

Code: [Select]
#warning CHANGE THESE TO SEMI-ADJUSTABLE PIN DEFS!

  ^

 In function 'void loop()':

Countdown:59: error: 'RTC' was not declared in this scope

   setSyncProvider(RTC.get);

                   ^

Countdown:59: error: 'setSyncProvider' was not declared in this scope

   setSyncProvider(RTC.get);

                          ^

Countdown:62: error: 'now' was not declared in this scope

        daysleft = christmasdate - now(); // subtract todays date from the christmas date to get the days left.

                                       ^

Countdown:66: error: 'SystemFont5x7' was not declared in this scope

   dmd.selectFont( SystemFont5x7 );

                   ^

Countdown:68: error: 'SECS_PER_DAY' was not declared in this scope

   dmd.drawString( 2,9, displayDaysDigits(daysleft / SECS_PER_DAY);, 3, GRAPHICS_NORMAL );

                                                     ^

Countdown:68: error: 'displayDaysDigits' was not declared in this scope

   dmd.drawString( 2,9, displayDaysDigits(daysleft / SECS_PER_DAY);, 3, GRAPHICS_NORMAL );

                                                                 ^

Countdown:68: error: expected primary-expression before ',' token

   dmd.drawString( 2,9, displayDaysDigits(daysleft / SECS_PER_DAY);, 3, GRAPHICS_NORMAL );

                                                                   ^

Countdown:68: error: expected '}' at end of input

   dmd.drawString( 2,9, displayDaysDigits(daysleft / SECS_PER_DAY);, 3, GRAPHICS_NORMAL );

                                                                                         ^

exit status 1
'RTC' was not declared in this scope




I'm using all of the following components
Nano Board
https://www.jaycar.com.au/duinotech-nano-board-arduino-compatible/p/XC4414

XC4621 Red LED Matrix
http://www.freetronics.com.au/collections/display/products/dot-matrix-display-32x16-red#.WAMtG-B97cd

XC4450 Real Time Clock Module
https://www.jaycar.com.au/arduino-compatible-real-time-clock-module/p/XC4450

Assistance is greatly appreciated

J-M-L

Any reason why you don't use the loop and update the display when 60sec (or 1 sec) have elapsed rather than update all the time as fast as you can?

dmd.drawString( 2,9, displayDaysDigits(daysleft / SECS_PER_DAY);, 3, GRAPHICS_NORMAL );

There is a wrong semicolon in there
Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums
Pas de messages privés SVP

pert

change
Code: [Select]
RTC_DS1307 rtc;
to
Code: [Select]
RTC_DS1307 RTC;
change:
Code: [Select]
  dmd.drawString( 2,9, displayDaysDigits(daysleft / SECS_PER_DAY);, 3, GRAPHICS_NORMAL );
to:
Code: [Select]
  dmd.drawString( 2,9, displayDaysDigits(daysleft / SECS_PER_DAY), 3, GRAPHICS_NORMAL );
Depending on which IDE version/Arduino AVR Boards version/operating system you're using you may also need to change:
Code: [Select]
#include <Time.h>
to:
Code: [Select]
#include <TimeLib.h>
There may still be some other errors after that. You should always post links to where you downloaded all libraries used in your sketch from, or if you installed them using Library Manager. Otherwise there's no way for us to test your code.

MITLRpro

Thaks Guys, the libraries are:

Time: http://www.pjrc.com/teensy/td_libs_Time.html

And in the code section here:
https://www.jaycar.com.au/diy-arduino-clock

Thanks!

pert

Change line 52 from:
Code: [Select]
rtc.begin();
to
Code: [Select]
RTC.begin();
change line 59 from
Code: [Select]
setSyncProvider(RTC.get);
to:
Code: [Select]
setSyncProvider(RTC.now);
(I'm actually not sure that's correct but it does compile)

Add:
Code: [Select]
#include <SystemFont5x7.h>
near the top of your sketch

That's as far as I can go because you didn't post your entire sketch. You are really going about this project in the wrong way. The right way is to get each part of your project working individually with small test sketches, the display, the RTC, etc. Only then do you start putting it all together. Instead you just mashed together a bunch of code without with lots of bugs which you would have already identified and solved in the test sketches.

J-M-L

#5
Oct 17, 2016, 10:24 am Last Edit: Oct 17, 2016, 02:27 pm by J-M-L
Thaks Guys, the libraries are:

Time: http://www.pjrc.com/teensy/td_libs_Time.html

And in the code section here:
https://www.jaycar.com.au/diy-arduino-clock

Thanks!
I suggest to stick to basics.
Here is a small code I put together that should help out.

it looks long because I tried to comment it as much as possible so that it's straightforward to grasp what are the 3 classes being used and their capabilities.

I've been using the RTClib library as modified by Adafruit  which will work with your set up. this library does not have the alarm or register management but you don't really need it.

The only thing you'll need to work out depending on where you live is how to handle Daylight Saving Time. RTCs don't know about those things. so I use a boolean that I set manually in my code (here to true because it's still summer time here). Because the clock does not know about DST it will get the difference between 2 dates wrong by 1 hour if the you are not yet with Christmas wintertime. hence the line in the code

TimeSpan timeToChristmas = (DST ? christmas - now + oneHour : christmas - now);

DST is maintained in my function call adjustForWesternEuropeDST(); that needs to be called at least once per hour to not miss the time to change clock.

if you are not in western Europe, you'll need to code that for your region as dates are not the same around the world.

On some of my physical gadgets I usually add a Dip switch so that I can read that dynamically when I reset the board instead of hardcoding it like I did here. if you plan to have your countdown clock in use every year I'd suggest you plan the same.





Code: [Select]
// import adafruit RTCLib library
#include "RTClib.h" // https://github.com/adafruit/RTClib

// the library defines the DateTime and TimeSpan class for time representation
// and RTC_DS1307, RTC_DS3231 or RTC_PCF8523 for the hardware

// ------------------------------------------------------
// RTC_DS1307 or  RTC_DS3231 RTC_PCF8523 objects
// ------------------------------------------------------
// There's pretty much only one way to get the time using the RTClib, which is to call now() on an instance
// now() returns a DateTime object that describes the current year, month, day, hour, minute and second

// This line sets the RTC with an explicit date & time, for example to set
// October,16 2016 at 17h40:25 you would call:
// rtc.adjust(DateTime(2016, 10, 16, 17, 40, 25));

// The following line sets the RTC to the date & time this sketch was compiled
// compile, upload and execute to setup your RTC Module, then comment out
// rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// if you are fast your clock still ends up about 5 seconds late... you might want to adjust that manually after

// ---------------------
// DateTime object : no TimeZone / DST / leap second handling
// ---------------------
// you can create a DateTime object by passing
// DateTime(uint16_t year, uint8_t month, uint8_t day,uint8_t hour =0, uint8_t min =0, uint8_t sec =0);
// a DateTime object offers time information methods
//    uint16_t year()
//    uint8_t month()
//    uint8_t day()
//    uint8_t hour()
//    uint8_t minute()
//    uint8_t second()
//    uint8_t dayOfTheWeek()
// days are represented as such
// const char *daysOfTheWeek[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
// a DateTime object can present a timestamp as a 32-bit uint32_t
// either time as seconds since 1/1/2000
// long secondstime();
// or time as seconds since midnight, January 1st 1970 not counting leapseconds
// uint32_t unixtime(void);

// ---------------------
// TimeSpan object
// ---------------------
// you can create a TimeSpan object with
// TimeSpan (int32_t seconds); or
// TimeSpan (int16_t days, int8_t hours, int8_t minutes, int8_t seconds);
// or by subtracting a DateTime object from another
// a TimeSpan object offers time information methods
//  int16_t days()
//  int8_t  hours()
//  int8_t  minutes()
//  int8_t  seconds()
//  int32_t totalseconds()

RTC_DS3231 rtc;
DateTime christmas;

const unsigned long updatePeriod = 1000UL; // UL for unsigned long. update display every updatePeriod ms


// --------------------------------------------------------------------------------------------------------------
// Daylight saving time (DST) or summer time is the practice of advancing clocks during summer
// months by one hour so that evening daylight lasts an hour longer, while sacrificing normal sunrise times.
// The EU has a guideline that determines the daylight saving time to start on the last Sunday of March
// and to end on the last Sunday of October. In the EU the hour to switch is at 01:00 UTC.
// --------------------------------------------------------------------------------------------------------------
boolean DST ; // true when DST starts and that false at the end of DST
const TimeSpan oneHour = TimeSpan((int32_t) 3600); // one hour that we use for DST caclulations

void  adjustForWesternEuropeDST() // switch times are 2 and 3 am (that is 1:00 UTC)
{
  DateTime now = rtc.now();
  if (now.dayOfTheWeek() == 1 && now.month() == 10 && now.day() >= 25 && now.day() <= 31 && now.hour() == 3 && DST == true)
  {
    // need to set the clock to 2 am;
    rtc.adjust(DateTime(now.year(), 10, now.day(), 2, now.minute(), now.second()));
    DST = false;
  }

  if (now.dayOfTheWeek() == 1 && now.month() == 3 && now.day() >= 25 && now.day()  <= 31 && now.hour() == 2 && DST == false)
  {
    // need to set the clock to 3 am;
    rtc.adjust(DateTime(now.year(), 3, now.day(), 3, now.minute(), now.second()));
    DST = true;
  }
}


// --------------------------------------------------------------------------------------------------------------
//
// --------------------------------------------------------------------------------------------------------------
void setup() {
  Serial.begin(115200);
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1); // can't go further
  }
  // rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // only if your clock is not set up
  DST = true; // when you launch the program you need to set this correctly because the clock can't know

  christmas = DateTime(rtc.now().year(), 12, 25, 0, 0, 0); // would be even better to check if we are after the 25th of december, then pick next year's one.
}


// --------------------------------------------------------------------------------------------------------------
//
// --------------------------------------------------------------------------------------------------------------
void loop() {
  static unsigned long previousMillis = 0;
  static DateTime now;

  if (millis() - previousMillis >= updatePeriod) {
    adjustForWesternEuropeDST();
    now = rtc.now();
    TimeSpan timeToChristmas = (DST ? christmas - now + oneHour : christmas - now);

    // not really necessary to get them into variables, just a convenience
    // in case you want to use them many times
    uint8_t nbDays = timeToChristmas.days();
    uint8_t nbHours = timeToChristmas.hours();
    uint8_t nbMinutes = timeToChristmas.minutes();
    uint8_t nbSeconds = timeToChristmas.seconds();

    Serial.print("Time remaning before Christmas = ");
    Serial.print(nbDays); Serial.print(nbDays > 1 ? F(" days ") : F(" day "));
    Serial.print(nbHours); Serial.print(F(":"));
    Serial.print(nbMinutes); Serial.print(F(":"));
    Serial.println(nbSeconds);
    previousMillis += updatePeriod;
  }
}


I've not tested this much - quickly hacked together - so use with caution

hope this helps
Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums
Pas de messages privés SVP

J-M-L

curious to know if you solved your issue with the above?
Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums
Pas de messages privés SVP

Go Up