Showing posts with label RTC. Show all posts
Showing posts with label RTC. Show all posts

Saturday, June 7, 2014

RTC Connection Code - Arduino Web Logger

Add the protocol to check and modify RTC time.

Get RTC Time

When you send "RTC0", it replies with T=<time stamp>
<time stamp> is only the sec part of POSIX time_t.

Set RTC Time

When you send "RTC<time stamp>", it replies with T=<time stamp>


Original Protocol

Get Last Data Block Number

When you send "GET0", it replies with N=<Data Block Number>

<Data Block Number>: "N=1" - "N=4294967295" unsigned 32 bit integer.
Of course, it will not get this big.

In the Data Log Code - Arduino Web Logger posting source code, SD_BASE_BLOCK becomes 0.

Get Data Block

When you send "GETn", it replies with
  • N = <Data Block Number>
  • T = <time stamp>
  • D = <data>
<time stamp> is only the sec part of POSIX time_t.  Do *1000 since we don't use millisecond part.  Of course it will be very difficult to see "T=4294967295" in our lifetime.

<data> is in +dd.ddd format.
  • "D=+12.345"
  • "D=" no data
  • "D=-99.999" termination.  That certain Data Block send is completely finished.

Digital Out

When turning on "DOn=ON",
when turning off "DOn=OFF".

n is channel number between 0 to 7.  There is no reply.

Digital In

When you send "DI", it replies with "bbbbbbbb".
b represents each input channel, and it becomes either '0' or '1'.

Analog In

When you send "AIn", it replies with "+dd.ddd".
n is channel number between 0 and 7, and "+dd.ddd" is from -10.000 to +10.000.


When you click [GetRTC] button display RTC time.



The incorrect RTC time gets set to current time when [SetRTC] button is clicked.




Now let's look at modified code.  ( Look at link below for complete code )

Fixed code from Arduino

#include <SPI.h>
#include <Ethernet.h>
#include <WebSocket.h>
#include <SoftwareSerial.h>
#include "Sd2Card.h"
#include <minWire.h> // use the modified library code from RTC Preparation posting
#include <minRTClib.h>

// ... OMIT ...

//-------------------------------------DS-1307
RTC_DS1307 rtc;

// ... OMIT ...

//------------------------------------------------ setup()
void setup() {
 Serial.begin(9600);
 Wire.begin();
 rtc.begin();

 // ... OMIT ...

//-----------------------------------------------
// Create DATA Logging Block
//-----------------------------------------------
void makeLogBlock(void) {
 byte i;
 byte *pB;
 float fdata;
 DateTime now;

 // ... OMIT ...

 //------------------------- buffer is full
 if(LogBlockSize >= LOG_BLOCK_SIZE) {
  pB = sdBuffer;
  *((uint32_t*)pB) = USED_MARK;  //Used Flag
  pB += 4;
  now = rtc.now();
  *((uint32_t*)pB) = now.unixtime(); //Time-stamp

  // ... OMIT ...

void printTOD(void) {
 DateTime now = rtc.now();
 Serial.print(now.year(), DEC);
 printProg(DASH_MSG);
 Serial.print(now.month(), DEC);
 printProg(DASH_MSG);
 Serial.print(now.day(), DEC);
 printProg(SPACE_MSG);
 Serial.print(now.hour(), DEC);
 printProg(COMMA_MSG);
 Serial.print(now.minute(), DEC);
 printProg(COMMA_MSG);
 Serial.println(now.second(), DEC);
}

// ... OMIT ...

void onData(WebSocket &socket, char* rxLn, byte rxSz) {
 uint32_t para;
 DateTime now;

 //-----------------------------------
 // GET
 //-----------------------------------
 if((rxLn[0] == 'G') && (rxLn[1] == 'E') && (rxLn[2] == 'T')) {
  *(rxLn + rxSz) = 0x00;
  para = atol(rxLn + 3);
  
  if(para) 
   upload_DataBlock(para + SD_BASE_BLOCK);
  else 
   upload_lastBlockNo();
 }

 //-----------------------------------
 // RTC
 //-----------------------------------
 else if((rxLn[0] == 'R') && (rxLn[1] == 'T') && (rxLn[2] == 'C')) {
  *(rxLn + rxSz) = 0x00;
  para = atol(rxLn + 3);

  // set RTC
  if(para) {
   rtc.adjust(DateTime(para));
   delay(100);
  }

  // send current RTC
  printLn[0] = 'T';
  printLn[1] = '=';
  now = rtc.now();
  ltoa((long int)(now.unixtime()), printLn+2, 10);
  WSsend(printLn, strlen(printLn));
 }
}


Fixed code from HTML/JS

        // ... OMIT ...
        
        // receive Time Stamp
        if(ar[0] == 'T') {
            timeStamp = ar[1];
            // Locale standard is GMT. 
            // In order to view as Korean time, we need to -9 hrs.
            tod.setTime((timeStamp - (9 * 3600)) * 1000); 
            
    // ... OMIT ...
    
    function getRTC() {
        clearDspPara();
        ws.send('RTC0');
    }
    
    function setRTC() {
        clearDspPara();
        var t = new Date();
        // GMT problem. Ths time +9 hrs.
        ws.send('RTC' + (t / 1000 + 9 * 3600));
    }
    
// ... OMIT ...

<button type="button" onclick="getRTC()">Get RTC</button>
<button type="button" onclick="setRTC()">Set RTC</button>

// ... OMIT ...



Full codes can be found in following links





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