chipKIT® Development Platform

Inspired by Arduino™

Real-Time Clock Library

Created Wed, 09 Nov 2011 18:55:41 +0000 by majenko


majenko

Wed, 09 Nov 2011 18:55:41 +0000

I have created a Real-Time Clock library for the Uno32. It's in beta at the moment, so please try it out and see what breaks.

It supports all the functions of the RTCC module, including alarm interrupt, output pin control, etc.

You will need to add a 32,768Hz crystal to the X2 footprint to the top-left of the PIC32 chip to get it to work.


avenue33

Wed, 09 Nov 2011 20:45:08 +0000

Thanks for sharing!

I wrote a basic library to manage the built-in RTC on the UNO32 board: set and get time and date.

Please find it at this GitHub :arrow: repository published Jun 19, 2011.


majenko

Wed, 09 Nov 2011 23:38:50 +0000

Yes, I saw yours after I had written mine... Ho hum, never mind.

I haven't followed any "standards" as regards the interface to my library. Maybe the two could merge one day...? Who knows...?


avenue33

Wed, 09 Nov 2011 23:59:08 +0000

Well, actually there's no standard for mine.

It's just consistent with my other libraries (begin, set, get, whoiam) and the functions are the same as for an external I2C RTC.

The alarm functions seem very promising.


avenue33

Mon, 21 Nov 2011 22:26:30 +0000

When powewing-up the UNO32 board, the time and date are erased.

Please find the :arrow: Double Clock sketch that reads the date and time from an DS1307 and update the internal PIC32 RTC.

The PIC32_RTC and I2C_Clock uses the same functions.


majenko

Sat, 24 Dec 2011 10:55:02 +0000

I have added a small fix to support the latest version of mpide. There was a problem with compiling the ISR:

RTCC.cpp:19:15: error: variable or field '__ISR' declared void
RTCC.cpp:19:30: error: 'ipl3' was not declared in this scope
RTCC.cpp:271:1: error: expected '}' at end of input

Simply adding:

#include <sys/attribs.h>

to the RTCC.cpp file fixes the issue.

Here is a new version for you.


avenue33

Sat, 24 Dec 2011 12:10:33 +0000

Ho majenko,

Thank you for maintaining the library :)

Actually, I'm rather conservative and haven't installed the latest release yet.

I'm more focused on finding a better IDE to play with my UNO32.


majenko

Sat, 24 Dec 2011 13:48:36 +0000

I hadn't either, but another user had and it wouldn't work, so I had to try it out and in the process fix it ;)


MGLSOFT

Sat, 24 Dec 2011 14:29:47 +0000

This library can be used in Chipkit MAX32?


majenko

Sat, 24 Dec 2011 14:36:49 +0000

I don't know. I don't have a MAX32 to try it on.

By all means try it out and let us know your results - it would be interesting to know if it does.

My guess is it probably will as the registers in use are more than likely named the same and working the same.

The only problem with the MAX32 is getting a 32.768KHz clock signal into it - you'll need an external clock generator by all accounts - there's another thread here somewhere about it.


MGLSOFT

Sat, 24 Dec 2011 14:39:52 +0000

Ok, thanks!!


Jacob Christ

Tue, 27 Dec 2011 13:15:54 +0000

The only problem with the MAX32 is getting a 32.768KHz clock signal into it - you'll need an external clock generator by all accounts - there's another thread here somewhere about it.

If I recall from the other thread, the Digilent Network Shield will inject this 32.768KHz clock if installed.

Jacob


majenko

Sun, 08 Jan 2012 23:40:06 +0000

I have written a little article on my site about getting the Uno32â„¢'s RTC up and running from scratch with my library:

[url]http://hacking.majenko.co.uk/node/33[/url]


Rob Drizzle

Tue, 10 Jan 2012 01:39:25 +0000

Has anyone figured out how to connect a coin cell so the RTCC does not lose time when the Uno32 is not powered?


majenko

Tue, 10 Jan 2012 08:45:07 +0000

As the RTCC is internal to the PIC32 and as far as I can see there is no battery pins on said PIC32 you will need to power the whole chip. Un the Uno32 this will mean powering the entire board. The PIC could be sent to sleep with some external power monitoring to save power.

Personally, in a situation like that, I would use a DS1306 or similar as it has a battery charge circuit built in.


avenue33

Tue, 10 Jan 2012 10:14:59 +0000

Another option, if the chipKIT board is connected to internet, is to retrieve time and date from an NTP server and update the internal clock accordingly.

I'm currently working on that.


avenue33

Tue, 10 Jan 2012 17:40:05 +0000

Hi :!:

This sketch :arrow: NTP_Clock works with a WiFly WiFi board, acquires NTP time, update the internal PIC32 RTC.

Additional library time is used to convert UNIX ticks into human readable date and time.

Enjoy :)


yoan150985

Mon, 23 Jan 2012 19:15:08 +0000

the sketch RTCC-0.1.2.zip works perfectly on chipkit max32. I tested it at the moment. Thank you for this great job ;) .


yoan150985

Mon, 23 Jan 2012 20:18:11 +0000

the ChipkitUdpNtpClient works great on max32 so you can associate it to the sketch RTCC-0.1.2


majenko

Mon, 23 Jan 2012 22:15:15 +0000

RTCC-0.1.2.zip works perfectly on chipkit max32.

Excellent! That's really great to know.


akmishra_99

Sun, 25 Mar 2012 05:09:51 +0000

Hello,

I have tried RTCC library with MAX32 with chipkit ehternet shield and it works

-Thanks akmishra_99


pablo

Wed, 25 Apr 2012 11:04:10 +0000

Has anyone figured out how to connect a coin cell so the RTCC does not lose time when the Uno32 is not powered?

Has anyone found out an answer? I would like to know if it is possible any possibility to avoid loosing time when the power goes off.


majenko

Wed, 25 Apr 2012 14:12:37 +0000

Has anyone found out an answer? I would like to know if it is possible any possibility to avoid loosing time when the power goes off.

The PIC32 chips don't have a backup-power facility like the external RTC chips (such as the DS1306/7). The best you can do is to arrange for an external switch-over from power to battery when the power goes and signal to the chip that it's no longer running on main power. When the chip receives that signal you will need to switch it into a low-power mode (turn off everything you can) to save power.


pablo

Thu, 26 Apr 2012 08:50:44 +0000

Thanks majenko!

I'm a dummie with this. I just want to supply power to the RTCC if the power goes off, not the whole max32.

I've been looking for an external switch-over and I found this. [url]http://focus.ti.com/paramsearch/docs/parametricsearch.tsp?family=analog&familyId=422&uiTemplateId=NODE_STRY_PGE_T[/url] Could that one be useful?

Is there any similar library to what I want to do or, perhaps, a book where to look at? As I said, I don't have much idea about it and it would help me a lot. If there isn`t, I'll try to figure it out looking at section 23 in the pic32mx data sheet.

regards


majenko

Thu, 26 Apr 2012 09:13:13 +0000

Could that one be useful?

It could, but I'd say it was overkill for what you're doing.

Most people just use a simple mosfet. Take a look at the schematics for the MAX32 and the UNO32 and take a look at how they switch between USB and Power Jack power inputs. It's a mosfet and a comparator - the comparator to see if there is power coming in through the jack, and the mosfet to switch the USB off if there is. Replace the USB with a battery and bob's your uncle.

Of course, the MAX32/UNO32 probably isn't the best system in the world for battery power as the rest of the board (linear voltage regulators, FT-232, etc) will consume power even when the chip is in really low power mode.

And as for switching to low power mode - that's a bit of a black art in itself and is specific to your application. Only you can decide which peripherals can be disabled and still maintain enough functionality within your system to operate. You will have to study the datasheet in detail. Sometimes it's enough to just tell the CPU to "sleep" until an interrupt (power resumed) is received on an interrupt pin, but depending on what else you're doing you may have to specifically disable other aspects of the chip as some peripherals can still operate during sleep mode.


pablo

Thu, 26 Apr 2012 11:30:54 +0000

Most people just use a simple mosfet. Take a look at the schematics for the MAX32 and the UNO32 and take a look at how they switch between USB and Power Jack power inputs. It's a mosfet and a comparator - the comparator to see if there is power coming in through the jack, and the mosfet to switch the USB off if there is. Replace the USB with a battery and bob's your uncle.

I looked at the schematics and It is a possibility. But, replacing the USB? I didn't expect so :? .If I did that, how would I connect to the IDE?

Could I use something like this https://www.adafruit.com/products/14 to supply power? Or using a battery and USB port in parallel?

I should write you PMs instead of asking so many questions in this post :)


majenko

Thu, 26 Apr 2012 12:44:40 +0000

Nah, keep it to the forum - the information is useful for many people.

By "replace the USB" I mean as a concept, not in reality. Take the system the MAX32/UNO32 uses and replace the USB in it with a battery supply in your own implementation of it. I don't mean remove the USB from the board or anything like that. Besides, you'll need extra signals to know if the main power is present or not (which I guess you could arrange external to the board).

At a pinch I guess you could use a USB plug-in power source (I have a solar powered li-po battery I use) as your battery system and unplug it to plug in your USB cable to the computer for programming. You'd have to ensure the main power is connected at the time, of course.

TBH your best bet for a good low-power system would be to get a blank PIC32 chip and mount it on a TQFP breakout board. You can then wire it up exactly as you need and miss out such things as the FT-232 chip, the voltage regulators (use a regulated 3.3v power supply) and such to reduce both the number of external components and the overall power consumption. You could burn the chipkit bootloader to the chip and program it as per normal using an off-board RS-232-to-TTL converter. Of course, this solution would require a PIC programmer to burn the bootloader on the chip in the first place.


pablo

Fri, 27 Apr 2012 10:34:52 +0000

Thanks for all the info!

Now I can focus on my project. I have read in section 29 that in RTCC we have alarms every half-second. I want to use an interrupt over the RTCC pulses. I mean I would like RTCC to send a pulse every 10 ms or 20 ms in order to compare the time with the desired time in the interrupt. Is this possible or there isn't enough accuracy? If not, what could I do?


majenko

Fri, 27 Apr 2012 15:03:18 +0000

The RTCC is more aimed at interrups in the order of 20s, 20m 20 days, etc, not 20ms. To get an interrupt of that kind of frequency you will have to use on of the timer modules. The fastest you can get from the RTCC is 0.5s.


pablo

Mon, 30 Apr 2012 09:34:56 +0000

Ok. I tried to compare 2 interrupts to see how accurate the board can be. I don't know if my code is right, but comparing 1s/50ms I got 19.61 pulses instead of 20. If this was true, I couldn't use a 20ms interrupt for what I want to do because I need accuracy. What alternatives do I have?I can probably count pulses every 50ms till 1sec or 0.5 sec and when RTCC interrupts, I reset the variable... :?

#if defined(PIC32MX) #include <p32xxxx.h> /* this gives all the CPU/hardware definitions / #include <plib.h> / this gives the i/o definitions */ #endif #define LED 13

volatile int value = 0; int prev_val, curr_val, interrupt2, interrupt3;

void setup() { Serial.begin(9600); OpenTimer2( T2_ON | T2_PS_1_1 | T2_SOURCE_INT, 0xFFFFFF); ConfigIntTimer2((T2_INT_ON | T2_INT_PRIOR_3));

pinMode(77, OUTPUT); OpenTimer3( T3_ON | T3_PS_1_1 | T3_SOURCE_INT, 0xFFFFFF); ConfigIntTimer3((T3_INT_ON | T3_INT_PRIOR_3));

} void loop() { curr_val = value; if(prev_val != curr_val) { Serial.println(prev_val); Serial.println( curr_val); prev_val = curr_val; // Serial.println("value togled");

//digitalWrite(LED, value); } }

#ifdef __cplusplus extern "C" { #endif

void __ISR(_TIMER_2_VECTOR,IPL3AUTO) comms_handler(void) { static int count; mT2ClearIntFlag(); // Clear interrupt flag count++; if(count > 1000 ) }

void __ISR(_TIMER_3_VECTOR,IPL3AUTO) Sample(void) { static int count; mT3ClearIntFlag(); // Clear interrupt flag count++; if(count > 50 ) }

#ifdef __cplusplus } #endif


majenko

Mon, 30 Apr 2012 10:27:34 +0000

There are various things to be aware of when working with interrupts.

Firstly, the code you write isn't all the code that gets executed.

When an ISR is triggered it must first push the state of important registers onto the stack. This is done as the first operation when the ISR is called, and can delay the execution of your code by a number of clock cycles. There is a set of "shadow" registers - an exact copy of the main registers - that can be switched to for extremely high priority interrupts. This takes just 1 Tcy in total instead of 1 Tcy per register. However, this can only be done once as there is only 1 set of shadow registers, so nesting multiple interrupts that all use the shadow registers is a big no-no.

Secondly, you should avoid doing anything heavy in an ISR. If an ISR takes longer to run than the period at which it is fired then you can get bad things happening. Your stack will overflow, and the whole system will go belly up. You should avoid such things as serial operations and the like as they are very time intensive and do things with their own interrupts that could cause problems with your interrupts.

The chipkit already has a "tick" counter which is incremented every millisecond (see the "millis()" function) which is pretty accurate as it is run from the PIC32's "core" timer (specifically designed for such things as tick timing and kernel scheduling, etc) so you might like to take a look at how accurate that is.

Alternatively, one of the timers (I think it is timer 1 - I'd need to check the data sheet to be sure) has the option of external timing. This takes a square-wave input to it to use as the timebase for its counting. If you really need extremely accurate timing then an external clock circuit which gives you a square wave at the exact count frequency you need (or a multiple thereof) could be a possibility.


alvesjc

Tue, 08 May 2012 18:41:36 +0000

the sketch RTCC-0.1.2.zip works perfectly on chipkit max32. I tested it at the moment. Thank you for this great job ;) .

Hi!

Can you explain how you have connected the crystal to pin75 on max32?

If I put the crystal between pin 75 and GND it works?

Thanks.

BR,

Joao


majenko

Tue, 08 May 2012 20:03:05 +0000

For the MAX32 you can't just connect a crystal.

You have to use some form of external clock signal generator.

This could be done with an ethernet shield, which has a 32KHz signal generator on board, or with a crystal and some clock generation circuitry - say a clock generator chip, or some NOT gates and resistors, etc.


pablo

Fri, 11 May 2012 08:02:30 +0000

This could be done with an ethernet shield.

I'm using it and it works perfect, but I could do it because I wanted ethernet aswell. If you don't need it, it isn't worthwhile.

Majenko, I guess I solved my problem. What do you think about it? Is it right?

#include <RTCC.h>

const int ledPin = 77; int ledState = LOW; long previousMillis = 0; long interval = 20; int myAlarmActive = 0; int dias[7]; int horas[12] = {10,10,10,10,10,10,10,10,10,10,10,10} ; int minutos[12] = {00,00,00,00,00,01,01,01,01,01,02,02}; int segundos[12] = {00,15,30,45,55,10,20,30,40,50,00,10};

void setup() { pinMode(ledPin, OUTPUT); Serial.begin(9600);

// Initialize the RTCC module RTCC.begin();

// Set the time to something sensible RTCC.hours(9); RTCC.minutes(59); RTCC.seconds(0); RTCC.year(12); RTCC.month(05); RTCC.day(10);

// Set the alarm to trigger every second RTCC.alarmMask(AL_HALF_SECOND); RTCC.chimeEnable(); RTCC.alarmEnable();

// Attach our routine to send the time through the serial port RTCC.attachInterrupt(&outputTime);

}

void loop() {

unsigned long currentMillis = millis();

if(currentMillis - previousMillis > interval) { // save the last time you blinked the LED previousMillis = currentMillis;

// if the LED is off turn it on and vice-versa:
if (ledState == LOW)
  ledState = HIGH;
else
  ledState = LOW;
// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
Serial.println(previousMillis);

if (myAlarmActive &gt; 12) return;
if (RTCC.year() != 12) return;
if (RTCC.month() != 05) return;
if (RTCC.day() != 10) return;
if (RTCC.hours() != horas[myAlarmActive]) return;
if (RTCC.minutes() != minutos[myAlarmActive]) return;
if (RTCC.seconds() != segundos[myAlarmActive]) return;

myAlarmActive++;

Serial.println("Do what I want");

} }

void outputTime() { char time[50];

// Format the time and print it. sprintf(time,"%02d/%02d/%02d %02d:%02d:%02d\n", RTCC.day(), RTCC.month(), RTCC.year(), RTCC.hours(), RTCC.minutes(), RTCC.seconds() ); Serial.println(time); Serial.println(previousMillis); }


majenko

Fri, 11 May 2012 09:23:44 +0000

How does the accuracy of that differ to setting an alarm on the chip with a mask of hours and using the interrupt to trigger your alarm function?

Also, for non-ethernet shield users on the MAX32, I find this circuit is easy to build and yields good enough results - it's one very common chip and a few resistors and capacitors along with your crystal:

or, if you want to do it with even more common NAND gates:


pablo

Tue, 15 May 2012 08:21:21 +0000

How does the accuracy of that differ to setting an alarm on the chip with a mask of hours and using the interrupt to trigger your alarm function?

I don't know because I didn't compare them. I tried this method because I wasn't sure about how to do it using interrupts :? . It seems to be accurate, but perhaps with interrupts is better.


sfeltan

Mon, 12 Nov 2012 18:20:15 +0000

HI,

I am using this library to get time from my DS1307 board, it works fine for something as 2h. After 2 hours, the function RTC.read() does not give anything. I have to reset the chipkit board and then, works again... for +/- 2 hours. When RTC.read() stops working, the chipkit program is still alive, processing other parts of the program. Is that a known issue?

I can post my code but it's quite big...


majenko

Mon, 12 Nov 2012 18:23:57 +0000

HI, I am using this library to get time from my DS1307 board, it works fine for something as 2h. After 2 hours, the function RTC.read() does not give anything. I have to reset the chipkit board and then, works again... for +/- 2 hours. When RTC.read() stops working, the chipkit program is still alive, processing other parts of the program. Is that a known issue? I can post my code but it's quite big...

Are you sure? I wasn't aware that I had written it to support anything other than the PIC32's internal RTCC module.