Friday, June 6, 2014

RTC Preparation - Arduino Web Logger

This is somewhat out of order, BUT let's connect RTC.

I purchased RTC Shield from following site.
https://store.open-electronics.org/index.php?_route_=RTC%20shield

Then the following gets delivered.


They gave me extra connector! :)

Also it comes with manual that I cannot read.  Italian maybe...?


Fortunately, there is no problem reading the schematic.


After some soldering...




Now we have four story high building.
We have on the first floor Arduino, second floor Ethernet Shield, third floor RTC Shield, and finally on the fourth floor we have RS485 Shield.




The library for RTC can be downloaded in the following site.
You might have to modify the name of the folder after downloading it.  Arduino sketch won't let you import 'RTClib-master', thus fix the name to 'RTClib_master'.

However, there is a problem.  This library takes up too much memory.
This library brings our memory down to 170 bytes ( before this library we have 377 bytes ).  We are not able to use this like this.

Let's look through, and find who uses up the most memory.

1. We are only going to use IIC Master mode and not the Slave.  So let's get rid of all Slave part.


2. Reduce memory from writing to RTC part.


RTClib.cpp
void RTC_DS1307::adjust(const DateTime& dt) {
 WIRE.beginTransmission(DS1307_ADDRESS);
 WIRE.write(0);
 WIRE.write(bin2bcd(dt.second()));
 WIRE.write(bin2bcd(dt.minute()));
 WIRE.write(bin2bcd(dt.hour()));
 WIRE.write(bin2bcd(0));
 WIRE.write(bin2bcd(dt.day()));
 WIRE.write(bin2bcd(dt.month()));
 WIRE.write(bin2bcd(dt.year() - 2000));
 WIRE.write(0);
 WIRE.endTransmission();
} // The import thing is that the maximum length is 9 bytes

Wire.cpp
size_t TwoWire::write(uint8_t data) {
 // ... OMIT ...
 txBuffer[txBufferIndex] = data; // size of txBuffer[] is 
                                    // #define BUFFER_LENGTH 32 in
                                 // Wire.h
                                    // Reduce to size 9
 ++txBufferIndex;
 txBufferLength = txBufferIndex;

// ... OMIT ...

uint8_t TwoWire::endTransmission(uint8_t sendStop) {
 int8_t ret = twi_writeTo(txAddress, txBuffer, txBufferLength, 1, sendStop);

twi.c
uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait, uint8_t sendStop) {
 // ... OMIT ...

 for(i = 0; i < length; ++i) {
  // Because ISR sends actual IIC, it has it's own Buffer.
  // If you make sure that you won't send until it is
  // completely finished, then you don't need that Buffer.
  twi_masterBuffer[i] = data[i];
 }

 // ... OMIT ...


3. Reduce memory from reading from RTC part.


RTClib.cpp
DateTime RTC_DS1307::now() {
 WIRE.beginTransmission(DS1307_ADDRESS);
 WIRE.write(0); 
 WIRE.endTransmission();
 WIRE.requestFrom(DS1307_ADDRESS, 7); // Receiving 7 bytes
 uint8_t ss = bcd2bin(WIRE.read() & 0x7F);
 uint8_t mm = bcd2bin(WIRE.read());
 uint8_t hh = bcd2bin(WIRE.read());
 WIRE.read();
 uint8_t d = bcd2bin(WIRE.read());
 uint8_t m = bcd2bin(WIRE.read());
 uint16_t y = bcd2bin(WIRE.read()) + 2000;
 return DateTime (y, m, d, hh, mm, ss);
}

Wire.cpp
uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop) {
 // ... OMIT ...

 // Reduce the size of rxBuffer[] to 7
 uint8_t read = twi_readFrom(address, rxBuffer, quantity, sendStop);

 // ... OMIT ...
}

twi.c
uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sendStop) {
 //... OMIT ...

 for(i = 0; i < length; ++i){
  // Received from ISR. There is no actual benefits for
  // moving to pointer, so let's keep 2 buffer.
  // fix the size of twi_masterBuffer[] to 7
  data[i] = twi_masterBuffer[i];
 }

 // ... OMIT ...
}


We have reduced memory to 142 bytes.

I have uploaded the modified library with "min" added to the original name.
Import the attached library.

Full codes can be found in following links