DS1307 RTC Emulator – The Arduino library

header_ds_emul.jpg

Things must come to an end. I decided to make a new library experiment, putting an ending mark to the DS1307 Real Time Clock hacking project, because the project was born as an encapsulation of a real RTC in a PIC microcontroller, wrapping an RTC hardware engine to emulate the DS1307; then a subsequent development on a “multiple” library was developed with an Atmega, but the firmware was emulating also the RTC core engine, since the Atmegas don’t embed it in hardware. And now, it is refined and integrated in an Arduino library, making it possible thanks to the HardWire library.

What is it all this emulation thing?

I like to say that is a manifestation of my lack of fantasy while having too much creativity. The DS1307 Emulator is, as stated by its name, a mere emulation of the omonym chip. It is a firmware, that can be put in any microcontroller based systems – like in many Arduinos – and let the board behave like such a chip, without actually having a DS1307 lying around. Since it is really keeping the time, this library is pre-tuned (you can adjust it in the code) to work with a quartz crystal of the system clock, running at 16MHz. Like the one on the Arduino Duemilanove or Uno.

A paint masterpiece picture can show basically what I said, where the emulator is running and what can be done with it:

ds1307_emu_scheme.png

And as shown above in picture, other tasks in the Sketch can be executed (blue circle), and they can actually communicate with the emulator (orange circle). The self-styled “not-so-fake” RTC can also be configured and read back from an external real master through the I2C bus, like a real DS1307 (Raspberry Pi, and other boards in the picture). So the emulator can be used, by definition, with all the already available DS1307 master libraries that you can find.

How it works?

While keeping up-to-date this article with the README GitHub page, this library can be easily explained with the listing of its APIs.

Init and I2C bus handling APIs.

  • DS1307Emulator.init(pin number) -> initialize the whole emulator, wiping all the non-volatile data and the timekeeping registers. Initialize also the I2C bus.
  • DS1307Emulator.softInit(pin number) -> the same as the init, but will keep the data in the time registers.
  • DS1307Emulator.busDisconnect() -> detach the RTC from the I2C bus without alterating the current RTC functionality. Useful if the the bus shall be used/shared with other tasks on the same sketch. After this call, the emulator will work only inside the sketch.
  • DS1307Emulator.busConnect() -> attach the RTC to the I2C bus without alterating the RTC functionality.

The real DS1307 has an output pin, called pin number in the emulator’s APIs. Let’s say we have an Arduino Uno and we want to use the default LED in the port 13. The sketcher shall import the library and call the init in the setup(), with the pin number 13. Then, if the emulator is connected to the I2C bus, any master can interact with the Arduino. The only thing required is to call the init(pin number) first.

Physical master interfaced with the board running the emulator.

  • Reading/Writing sequence  from/to the sketch through the I2C bus:
    1. Be sure that the emulator software is connected to the bus. If not, issue the DS1307Emulator.busConnect().
    2. Use a master (very nice would be a second Arduino running an RTC library, or a Raspberry Pi) to talk with the Arduino running the DS1307 emulator, AKA the slave. If the master have the right RTC software, it will issue the commands for which the emulator (slave) will answer accordingly. See the picture below.
rd_wr_rtc.PNG
Read and write sequence protocol (from the DS1307 datasheet)

But if the real-time clock shall be read or write within the current sketch, so without the I2C bus, the standard sequence will be the following, which basically replicates within the sketch the steps that would be taken on the I2C bus:

On-board sketch interfacing with the emulator.

  • Writing sequence to the emulator from the sketch:
    1. DS1307Emulator.bufferUserData() -> save the current time to a temporary     buffer to avoid time wrapping issues (as the DS1307 chip does).
    2. DS1307Emulator.writeToRTC(address) -> write the current address byte. In this step, is the RTC internal address set to address value.
    3. Issuing again the step 2 will write now RTC data from the previously set address – it will auto-increment the internal address from the one set in step 2. Repeat for as many bytes shall be written.
    4. DS1307Emulator.setUserData() -> apply the adjusted configuration to the RTC registers and close the writing sequence.
  • Reading sequence from the emulator from the sketch:
    1. DS1307Emulator.bufferUserData() -> save the current time to a temporary     buffer to avoid time wrapping issues (as the DS1307 chip does).
    2. DS1307Emulator.writeToRTC(address) -> write the current address byte.
      Note that the step 2 is not mandatory, provided that the address currently set is the right one.
    3. (char) DS1307Emulator.readUserData() -> read a char from the current         address set in the previous point – it will auto-increment the internal address from the one set in step 2. Repeat for as many bytes shall be read.
    4. There is no need to close a reading sequence.

 

A working sketch – setting up the DS1307 emulator

This simply starts the DS1307 emulator in the default state, the same of the DS1307 chip after the power up, associating the RTC pin to the pin 13 of the Arduino.

#include "DS1307Emulator.h"

void setup()
{
  DS1307Emulator.init(13);
}

void loop()
{}

Pretty darn simple eh? Even boring. Let’s play with another example.

A working sketch – testing all the functionalities

Through a serial interface (like the Arduino serial monitor, with the NL character active), sending a certain commands (like “h”, “m”, “M”, “D”, “y”, “1”, “2” ecc) will increase any kind of value of the emulator. With a “p”, the current content of the emulator is printed out. This is present on GitHub example folder, or in the example folder if you have found the library worthful to be downloaded.

A working sketch – “blinking” LED, the most memory consuming way

In the example folder there is also the LED blink example, outputting the half second ticking on the pin 13. It is not just a toggling port: the sketch  will start the RTC, configure it to have the pin 13 connected, the I2C bus connected, and 1Hz toggling on the output pin. Since the RTC default reset is with the clock frozen, it will configure it also to start the ticking, in order to see the LED proudly blink and keeping the time. So, it can be said that to blink an LED we are now using the entire emulator library.  NOTE: This blink configuration can be achieved also when testing the functionalities with the previous example.

Again, can be downloaded from GitHub or can be found in the example folder if the library is downloaded.

Microcontroller requirements

atmega328_fun_res.jpgThis software need to control in parallel the I2C bus, the timer, the crystal and some pins. This means that few peripherals are not available to the Sketch for other parallel tasks.

Here are listed the hardware and software resources required when using the library.

 

 

  • Timer1 hardware
    • Timer1 related hardware is normally not available. Pin 9 and pin 10 of Arduino cannot be used for the PWM (analog write), without having to stop the RTC.
  • I2C bus
    •  This is shearable because can be temporarily reassigned to other pieces of software through the previously listed APIs.
  • RTC output pin
    •  This is shearable because with a softInit can be reassigned to another pin, or even a fake one (outside the Arduino boundaries).
  • Flash memory
    • About 4kB
  • RAM
    • About 600B
  • Library dependencies
    • Requires having installed the HardWire (available from Arduino repository), therefore uses the Wire library resources.

Download

Everything is available at the GitHub page and from the official Arduino repository.

There is still a lot that can be done to having it actually identical to the chip, even also the power handling. Sometimes I like when I have a non completely closing scene on a project, because sometimes, it keeps motivation to improve. (Hopefully as much as I did in developing and play with it) Enjoy!

Annunci

Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...