2012/12/21

Rikomagic MK802IIIs Now Available at Taipei, Taiwan


The new MK802 IIIs is still a tiny computer with a USB port on one end, an HDMI adapter on the other, and a Rockchip RK3066 dual core process in the middle.

But the new model adds two new features: Bluetooth support, an ESD circuit for better stability, and support for software apps that let you actually turn off the little computer without unplugging it.



The MK802IIIs with 8 Gb memory now is available at 4F, Guanghua Digital Plaza, Taipei, Taiwan.

Update: Also avalable at Jianguo 2nd Rd.,Kaohsiung City, Taiwan since Dec. 29, 2012

2012/11/16

Freeduino/Arduino Web Controlled (Configured) Automatic Switches

Inspired by Freeduino/Arduino Web Sensors And Switches on cheaphousetek blog on Oct. 20, 2012, go a step forward, automatically controll the switches by setting the sensors criteria. It comes out the sketch at the bottom of this post.
By setting the lower limits, upper limits and switch on/off using a browser, one can monitor the conditions of all switches  remotely.
To control the web server outside the local area network, the NAT function of IP router should be enabled. To secure your web server, the SSH or VNC connection should be established.

Pins Used

Sensors: A2, A3
Switches: D2, D3, D4, D5, D6, D7, D8, D9

Output


Sketch


// Freeduino/Arduino Web Controlled Automatic Switches version 1.0
// By Befun Hung on Nov. 16 2012
// Modified From Freeduino/Arduino Web Sensors And Switches At cheaphousetek Blog 
// The Sketch Works On Arduino IDE 1.02

#include <Ethernet.h>
#include <SPI.h>
//network NB: Pins 10, 11, 12 and 13 are reserved for Ethernet module. 
#define sensorPinStart 2
#define noOfSensors 2
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168, 1, 177 };
byte gateway[] = { 192, 168, 1, 1 };
byte subnet[] = { 255, 255, 255, 0 };
String inString = String(100);
String minValue, maxValue;
int defaultMinValue[] = {55, 56, 57, 58, 59, 60, 61, 62, 63};
int defaultMaxValue[] = {60, 61, 62, 63, 64, 65, 66, 67, 68};
String defaultOnValue[] = {"Low", "Low", "Low", "Low", "Low", "Low", "Low", "Low", "Low"};
String Led;
int led[] = {00, 2, 3, 4 ,5 ,6 ,7 ,8 ,9  }; //pin num 0 in arry is not used
int numofleds = 8; //number of switches
String value[] = {"off","off","off","off","off","off","off","off","off"}; //startup all led are off
EthernetServer server(80);

void setup()
{
  delay(250); 
  Serial.begin(9600);
  Ethernet.begin(mac, ip,gateway,subnet); 
  server.begin();
  //set pin mode
  for (int j = 1; j < (numofleds + 1); j++)
  {
    pinMode(led[j], OUTPUT);
  }
  Serial.println("Serial READY");
  Serial.println("Ethernet READY");
  Serial.println("Server READY");
}

void loop()
{
  EthernetClient client = server.available();  
  if (client)
  {
    // an http request ends with a blank line
    boolean current_line_is_blank = true;
    while (client.connected()) 
    {     
      if (client.available()) 
      {      
        char c = client.read();
        // if we've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so we can send a reply
        if (inString.length() < 35) 
        {
          inString.concat(c);
        } 
        if (c == '\n' && current_line_is_blank) 
        {                    
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();
          client.println("<html>");
          client.println("<meta http-equiv=\"refresh\" content=\"5\">");
          client.println("<body><form method=get>");
          client.println("<center><p><h1>Freeduino/Arduino Web Controlled Automatic Switches</h1></p><hr></center>"); 
          client.println("<h2>");
          // Sensor Reading and Setting -----------------------------------------------------------------------------
          client.println("Sensor Reading And Setting:<br>");
          for (int analogChannel = sensorPinStart ; analogChannel < sensorPinStart+noOfSensors ; analogChannel++)
          {
            minValue = String("Low") + analogChannel;
            // fixValue = String("Fix") + analogChannel;
            maxValue = String("High") + analogChannel;
            Led = String("RelayOn") + analogChannel;
            int sensorReading = analogRead(analogChannel);
            
            if (inString.indexOf(minValue+"=Dn") > 0) defaultMinValue[analogChannel] -= 1;
            if (inString.indexOf(minValue+"=Up") > 0) defaultMinValue[analogChannel] += 1;
            if (inString.indexOf(maxValue+"=Dn") > 0) defaultMaxValue[analogChannel] -= 1;
            if (inString.indexOf(maxValue+"=Up") > 0) defaultMaxValue[analogChannel] += 1; 
            if (inString.indexOf(Led+"=High") > 0)    defaultOnValue[analogChannel] = "Low";
            if (inString.indexOf(Led+"=Low") > 0)     defaultOnValue[analogChannel] = "High";
            client.print("Input A");
            client.print(analogChannel);
            client.print(":");
            client.print(sensorReading);
            client.print("  Low");
            // client.print(analogChannel);
            client.print(":");
            client.print(defaultMinValue[analogChannel]);
            client.print("<input type=submit name="+minValue+" value=Dn><input type=submit name="+minValue+" value=Fix><input type=submit name="+minValue+" value=Up>");
            client.print("  High");
            // client.print(analogChannel);
            client.print(":");
            client.print(defaultMaxValue[analogChannel]);
            client.print("<input type=submit name="+maxValue+" value=Dn><input type=submit name="+maxValue+" value=Fix><input type=submit name="+maxValue+" value=Up>");
            client.print("  On");
            // client.print(analogChannel);
            client.print(":");
            client.print("<input type=submit name="+Led+" value="+defaultOnValue[analogChannel]+">");
            client.println("<br>");
          }
          // Switch Monitoring -------------------------------------------------------------------------------------------
          client.println("<p></p>Switches Status:<br>"); 
          for (int i=1; i < (noOfSensors+1) ; i++)
          { 
            Led = String("Switch") + i;
            int sensorReading = analogRead(sensorPinStart+i-1);
            if ((sensorReading > defaultMaxValue[sensorPinStart+i-1]) && (defaultOnValue[sensorPinStart+i-1] == "High")) {
              digitalWrite(led[i], HIGH);
              value[i] = "on";
            }
            if ((sensorReading < defaultMinValue[sensorPinStart+i-1]) && (defaultOnValue[sensorPinStart+i-1] == "High")) {
              digitalWrite(led[i], LOW);
              value[i] = "off";
            }
            if ((sensorReading < defaultMinValue[sensorPinStart+i-1]) && (defaultOnValue[sensorPinStart+i-1] == "Low")) {
              digitalWrite(led[i], HIGH);
              value[i] = "on";
            }
            if ((sensorReading > defaultMaxValue[sensorPinStart+i-1]) && (defaultOnValue[sensorPinStart+i-1] == "Low")) {
              digitalWrite(led[i], LOW);
              value[i] = "off";
            }
            client.println(Led+"  <input type=submit name="+Led+" value="+value[i]+">"+"<br>");
          }
          client.println("</form><hr></h2>");
          client.println("<center>The web page will automatically refresh every 5 seconds.</center>");
          client.println("</html></body>");
          break;
        }
        if (c == '\n') 
        {
          // we're starting a new line
          current_line_is_blank = true;
        } 
        else if (c != '\r') 
        {
          // we've gotten a character on the current line
          current_line_is_blank = false;
        }
      }  // End of if (client.available)
    }  // End of while (client.connected())
    // give the web browser time to receive the data
    delay(1);
    inString = "";
    client.stop();
  } //End of if (client)
}

2012/11/14

GlobalSat EM-411 GPS Module Test Sketch Using Arduino 0022

Once buying an GPS module, the first idea is to check whether the module works as expect. To check the module using Arduino, first connecting the module and Arduino Uno/Duemilanove, then using the following sketch running on Arduino IDE 0022 (should also run on 0023 but not tested). The sketch should work for other GPS module, because GPS module usually need only VCC, GND to run and additional TX and RX to transmit/recive data.
As soon as checked the connections and powering the Arduino Uno/Duemilanove , one can monitor the NMEA sentenc output using Arduino serial monitor or any terminal emulator such as Putty. For me, I use SSCOM to test GPS and bluetooth modules on Windows XP.

Pin Used And Connection

Arduino - GPS Module
5V - Pin2(VIN)
GND - Pin1(GND) and Pin5(GND)
D2(SoftwareSerial RX) - Pin3(TX)
D3(SoftwareSerial TX) - Pin4(RX)

Output


Sketch 

// Test Code for GlobalSat EM-411 GPS Modules 
// Arduino 0022 Has Built-in SoftwareSerial.h Library
// Download the Library is not Needed
// The sketch works on Arduino IDE 0022

#include <SoftwareSerial.h>
SoftwareSerial GPS = SoftwareSerial(2, 3);

void setup()  
{
  Serial.begin(9600);
  Serial.println("GlobatSat EM-411 GPS Module NMEA Sentence Test!");

  // EM-411 factory default baud rate is 4800, the module used has been changed the baud rate
  GPS.begin(9600);
}

void loop()  // whatever read from GPS, sent to Arduino serial monitor or terminal emulator
{
  Serial.print(GPS.read(), BYTE);
}

2012/10/20

Freeduino/Arduino Web Sensors And Switches

Arduino Uno/Duemilanove is an useful gadget, combined with an W5100 Ethernet Shield , linked with some analog sensors and relays by wires, one can easily implements an simple remote web sensor monitoring and switch controlling system using an browser.

Pins Used

W5100 Ethernet Shield -- D10, D11, D12, D13
Analog Sensors -- A0, A1, A2, A3, A4, A5
Switches -- D2, D3, D4, D5, D6, D7, D8, D9

Output On Chrome Browser


Sketch


// modified from Instructables Arduino Led Server and Arduino Example WebServer 
// by Befun Hung on Oct. 20, 2012
// the sketch works on Arduino IDE 1.01

#include <Ethernet.h>
#include <SPI.h>
//network NB: Pins 10, 11, 12 and 13 are reserved for Ethernet module. 
#define sensorPinStart 0 //change to 2 if using Arduino Ethernet Shield 05 or 06
#define noOfSensors 2
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168, 1, 177 };
byte gateway[] = { 192, 168, 1, 1 };
byte subnet[] = { 255, 255, 255, 0 };
String inString = String(35);
String Led;
int led[] = {00, 2, 3, 4 ,5 ,6 ,7 ,8,9  }; //Led pins num 0 in arry is not used
int numofleds = 8; //numofleds
String value[] = {"off","off","off","off","off","off","off","off","off"}; //startup all led are off
EthernetServer server(80);
String data;

void setup()
{
  Serial.begin(9600);
  Ethernet.begin(mac, ip,gateway,subnet); 
  server.begin();
  //set pin mode
  for (int j = 1; j < (numofleds + 1); j++)
  {
    pinMode(led[j], OUTPUT);
  }
  Serial.println("Serial READY");
  Serial.println("Ethernet READY");
  Serial.println("Server READY");
}

void loop()
{
  EthernetClient client = server.available();  
  if (client)
  {
    // an http request ends with a blank line
    boolean current_line_is_blank = true;
    while (client.connected()) 
    {     
      if (client.available()) 
      {      
        char c = client.read();
        // if we've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so we can send a reply
        if (inString.length() < 35) 
        {
          inString.concat(c);
        } 
        if (c == '\n' && current_line_is_blank) 
        {                    
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();
          client.println("<html>");
          client.println("<meta http-equiv=\"refresh\" content=\"5\">");
          client.println("<body><form method=get>");
          client.println("<center><p><h1>Freeduino/Arduino Web Sensor And Switch</h1></p><hr></center>"); 
          client.println("<h2>");
          client.println("Sensor Reading:<br>");
          for (int analogChannel = sensorPinStart ; analogChannel < sensorPinStart+noOfSensors ; analogChannel++)
          {
            int sensorReading = analogRead(analogChannel);
            client.print("Analog Input ");
            client.print(analogChannel);
            client.print(" : ");
            client.print(sensorReading);
            client.println("<br>");
          }
          client.println("<p></p>Switches Status:<br>");
          for(int i=1;i < (numofleds + 1) ;i++) 
          { 
            Led = String("Switch") + i;
            if(inString.indexOf(Led+"=off")>0 || inString.indexOf("all=on")>0)
            {
              Serial.println(Led+"on");
              digitalWrite(led[i], HIGH);
              value[i] = "on"; 
            }
            else if(inString.indexOf(Led+"=on")>0 || inString.indexOf("all=off")>0 )
            {          
              Serial.println(Led+"off");
              digitalWrite(led[i], LOW);
              value[i] = "off";
            }
            client.println(Led+"  <input type=submit name="+Led+" value="+value[i]+">"+"<br>");
          }
          client.println("<p></p>Switches Action:<br>");
          client.println("All <input type=submit name=all value=on><input type=submit name=all value=off>");
          client.println("</form><hr></h2>");
          client.println("<center>The web page will automatically refresh every 5 seconds.</center>");
          client.println("</html></body>");
          break;
        }
        if (c == '\n') 
        {
          // we're starting a new line
          current_line_is_blank = true;
        } 
        else if (c != '\r') 
        {
          // we've gotten a character on the current line
          current_line_is_blank = false;
        }
      }  // End of if (client.available)
    }  // End of while (client.connected())
    // give the web browser time to receive the data
    delay(1);
    inString = "";
    client.stop();
  } //End of if (client)
}

2012/09/19

FT232RL USB To TTL Converter


This is a basic breakout board for the FTDI FT232RL USB to serial IC. The pinout of this board matches the FTDI cable to work with official Arduino and cloned Arduino boards. The major difference with this board is that it brings out the DTR pin as opposed to the RTS pin of the FTDI cable. The DTR pin allows an Arduino target to auto-reset when a new sketch is downloaded. This is a really nice feature to have and allows a sketch to be downloaded without having to hit the reset button. This board will auto reset any Arduino board that has the reset pin brought out to a 6-pin connector.

The pins labeled BLK and GRN correspond to the colored wires (black, brown, red, orange, yellow, green as the sequence of resistor color code from 0 to 5) on the FTDI cable.

You can see serial traffic on the TX and RX LEDs on the board to verify if the board is working.

This board was designed to decrease the cost of Arduino development and increase ease of use.

One of the nice features of this board is a jumper on the top of the board to be configured to either 3.3V or 5V. You can resolder the jumper if you need to switch between 3.3V and 5V.

2012/07/07

Freeduino/Arduino + Datalogger Shield + LCD Keypad Shield + Sensors Connecting To A1, A2 And A3

Dataloggers can be easily used to record sensor readings from analog inputs. With following sketch, anyone can easily record data read from analog input by just stacking Freeduino/Arduino, Datalogger Shield and LCD Keypad Shield and connecting analog ins from A1 to A3.

The data read is raw data, you have to adjust the sketch to do the conversion according the sensor specification. For example, LM35 sensor need to calculate the value of (raw data * 500 / 1023) .

With the data file, you can use data visualization software , such as Gnu Plot, to display data in graph.

Pins Used

cheaphousetek Datalogger Shield ---
RTC: A4 and A5
mSD: D10, D11, D12 and D13

cheaphousetek LCD Keypad Shield ---
LCD: D8, D9, D4, D5, D6 and D7
Keypad: A0

Sensors(LM35): A1, A2 and A3

Output Of LCD Keypad Shield



Contents Of Output File


Sketch

// File name: DataloggerFileNameMMDDHHMMLCD.pde
// The sketch works on Arduino IDE 0022

#include <SD.h>
#include <Wire.h>
#include <RTClib.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

File file;                // test file
const uint8_t SD_CS = 10; // SD chip select
RTC_DS1307 RTC;           // define the Real Time Clock object
String file_name = "", dataString;    // file name should not prefix with "prefix_word"
char fn[] = "MMDDHHMM.txt";
int i=0;
//------------------------------------------------------------------------------
// call back for file timestamps
void dateTime(uint16_t* date, uint16_t* time) {
  DateTime now = RTC.now();

  // return date using FAT_DATE macro to format fields
  *date = FAT_DATE(now.year(), now.month(), now.day());

  // return time using FAT_TIME macro to format fields
  *time = FAT_TIME(now.hour(), now.minute(), now.second());
}
//------------------------------------------------------------------------------
void setup() {
  Serial.begin(9600);
  Wire.begin();
  if (!RTC.begin()) {
    Serial.println("RTC failed");
    while(1);
  };
  lcd.begin(16, 2);
  // set date time callback function
  SdFile::dateTimeCallback(dateTime); 

  // following line sets the RTC to the date & time this sketch was compiled
  // RTC.adjust(DateTime(__DATE__, __TIME__));
  
  DateTime now = RTC.now();
  
  if (now.month() < 10) {
      file_name = String(file_name + '0' + String(now.month(), DEC));
    }
    else {
    file_name = String(file_name +String(now.month(), DEC));
    }

  if (now.day() < 10) {
      file_name = String(file_name + '0' + String(now.day(), DEC));
    }
    else {
    file_name = String(file_name +String(now.day(), DEC));
    }

  if (now.hour() < 10) {
      file_name = String(file_name + '0' + String(now.hour(), DEC));
    }
    else {
    file_name = String(file_name +String(now.hour(), DEC));
    }

  if (now.minute() < 10) {
      file_name = String(file_name + '0' + String(now.minute(), DEC));
    }
    else {
    file_name = String(file_name +String(now.minute(), DEC));
    }

  file_name = String(file_name + ".txt");
  // Serial.println(file_name);
  // Serial.println(file_name.length());
  
  for (i=0;i<=file_name.length();i++) {
    fn[i] = file_name.charAt(i); 
    // Serial.print(file_name.charAt(i));
  }
  // Serial.println(fn);
  
  if (!SD.begin(SD_CS)) {
    Serial.println("SD failed");
    while(1);
  }
  Serial.print("File Name: ");
  Serial.println(fn);
  
  //file = SD.open(fn, FILE_WRITE);
  //file.close();
  // Serial.println("Done");
  
}
//------------------------------------------------------------------------------
void loop() {
  
  DateTime now = RTC.now();
  
  String data_string = "";
  data_string = String(now.year(), DEC);
  data_string += "/";
  if (now.month() < 10) {
      data_string = String(data_string + '0' + String(now.month(), DEC));
    }
    else {
    data_string = String(data_string +String(now.month(), DEC));
    }
  data_string += "/";
  if (now.day() < 10) {
      data_string = String(data_string + '0' + String(now.day(), DEC));
    }
    else {
    data_string = String(data_string +String(now.day(), DEC));
    }
  data_string += " ";
  if (now.hour() < 10) {
      data_string = String(data_string + '0' + String(now.hour(), DEC));
    }
    else {
    data_string = String(data_string +String(now.hour(), DEC));
    }
  data_string += ":";
  if (now.minute() < 10) {
      data_string = String(data_string + '0' + String(now.minute(), DEC));
    }
    else {
    data_string = String(data_string +String(now.minute(), DEC));
    } 
  data_string += ":";   
  if (now.second() < 10) {
      data_string = String(data_string + '0' + String(now.second(), DEC));
    }
    else {
    data_string = String(data_string +String(now.second(), DEC));
    } 
  data_string += ",";
  
  //read sensor value from A1-A3 and append to the string
  delay(195);
  for (int analogPin = 1; analogPin <4; analogPin++) 
    {
    delay(200);
    int sensor = analogRead(analogPin);
    data_string += String(sensor);
    if (analogPin < 3) {
      data_string += ",";
      }
    }
  
  file = SD.open(fn, FILE_WRITE);
  if (file) {
    file.println(data_string);
    file.close();
    Serial.println(data_string);
    }
    else {
      Serial.print("error opening ");
      Serial.println(fn);
    }
  lcd.clear();
  lcd.setCursor(0,0);
  dataString = String(data_string);
  lcd.print(dataString.substring(5, 19)); 
  lcd.setCursor(0,1);
  lcd.print(dataString.substring(20));
  //Serial.println(data_string);
   
  // delay(195);
}

2012/06/03

Freeduino/Arduino + Real Time Clock Sensor Shield + LCD Keypad Shield + LM35 Temperature Sensor


Pins Used

cheaphousetek RTC Sensor Shield ---
Analog pins 4 and 5 are used for I2C protocol implemented by Maxim DS1307.

cheaphousetek LCD Keypad Shield ---
Digital pins 8, 9, 7, 6, 5 and 4 are used by LiquidCrystal.h to communicate with LCD Keypad.

LM35 Temperature Sensor ---
Analog pin 3 is used read temperature data from LM35 temperature sensor.

To save data to micro SD, follow the link below.

http://cheaphousetek.blogspot.tw/2012/07/freeduinoarduino-datalogger-shield-lcd.html

There is a new version using Time.h library and showing weekday.

RTClib.h download web page

http://www.ladyada.net/make/logshield/download.html



LCD Output

Sketch


// Date and time functions using a DS1307 RTC connected via I2C and Wire lib
// 2010-02-04 <jcw@equi4.com> http://opensource.org/licenses/mit-license.php
// $Id: ds1307.pde 4773 2010-02-04 14:09:18Z jcw $

// Added LCD display and LM35 temperature function by Befun Hung 2011-10-13
// File Name: LCDDS1307RTClibLM35A3.pde
// The sketch works on Arduino IDE 0022

#include <Wire.h>
#include <RTClib.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

RTC_DS1307 RTC;
int potPin = 3;
float temperature = 0;

void setup () {
    Serial.begin(9600);
    Wire.begin();
    RTC.begin();
    lcd.begin(16, 2);
    // lcd.print("*cheaphousetek*");
    
    // following line sets the RTC to the date & time this sketch was compiled
    // RTC.adjust(DateTime(__DATE__, __TIME__));
}

void printTenths(long value) {
  // prints a value of 123 as 12.3
  Serial.print(value / 10);
  Serial.print('.');
  Serial.print(value % 10);
  Serial.println();
  lcd.setCursor(10, 1);
  lcd.print(value / 10);
  lcd.setCursor(12, 1);
  lcd.print('.');
  lcd.setCursor(13, 1);
  lcd.print(value % 10);
}

void loop () {
    DateTime now = RTC.now();
    int span = 10;
    long aRead = 0;
    unsigned long tmp;
      
    tmp = now.year();
    Serial.print(now.year(), DEC);
    lcd.setCursor(0, 0);
    lcd.print(tmp);
    Serial.print('/');
    lcd.setCursor(4, 0);
    lcd.print("-");
    
    tmp = now.month();
    if (now.month() < 10) {
      Serial.print('0');
      Serial.print(now.month(), DEC);
      lcd.setCursor(5, 0);
      lcd.print('0');
      lcd.setCursor(6, 0);
      lcd.print(tmp);
    }
    else {
      Serial.print(now.month(), DEC);
      lcd.setCursor(5, 0);
      lcd.print(tmp);
    }
    Serial.print('/');
    lcd.setCursor(7, 0);
    lcd.print('-');
    
    tmp = now.day();
    if (now.day() < 10) {
      Serial.print('0');
      Serial.print(now.day());
      lcd.setCursor(8, 0);
      lcd.print('0');
      lcd.setCursor(9, 0);
      lcd.print(tmp);
    }
    else {
      Serial.print(now.day(), DEC);
      lcd.setCursor(8, 0);
      lcd.print(tmp);
    }
    Serial.print(' ');
    
    tmp = now.hour();
    if (now.hour() < 10) {
      Serial.print('0');
      Serial.print(now.hour(), DEC);
      lcd.setCursor(0, 1);
      lcd.print('0');
      lcd.setCursor(1, 1);
      lcd.print(tmp);
    }
    else {
      Serial.print(now.hour(), DEC);
      lcd.setCursor(0, 1);
      lcd.print(tmp);
    }
    Serial.print(':');
    lcd.setCursor(2, 1);
    lcd.print(':');
    
    tmp = now.minute();
    if (now.minute() < 10) {
      Serial.print('0');
      Serial.print(now.minute(), DEC);
      lcd.setCursor(3, 1);
      lcd.print('0');
      lcd.setCursor(4, 1);
      lcd.print(tmp);
    }
    else {
      Serial.print(now.minute(), DEC);
      lcd.setCursor(3, 1);
      lcd.print(tmp);
    }
    Serial.print(':');
    lcd.setCursor(5, 1);
    lcd.print(':');
    
    tmp = now.second();
    if (now.second() < 10) {
      Serial.print('0');
      Serial.print(now.second(), DEC);
      lcd.setCursor(6, 1);
      lcd.print('0');
      lcd.setCursor(7, 1);
      lcd.print(tmp);
    }
    else {
      Serial.print(now.second(), DEC);
      lcd.setCursor(6, 1);
      lcd.print(tmp);
    }
    Serial.print (' ');
    lcd.setCursor(8, 1);
    lcd.print(' ');
    // Serial.println();
    
    for (int i=0;i<span;i++) {
      aRead = aRead + analogRead(potPin);
      // Serial.print(aRead);
      // Serial.print(' ');
    }
    // aRead = aRead / span;
    temperature = (aRead / span * 500.0 / 1024.0);
    // Serial.print(aRead);
    // Serial.print(' ');
    // Serial.print(temperature);
    // Serial.print(' ');
    printTenths(long (temperature * 10));
    lcd.setCursor(14, 1);
    lcd.print(char(223));
    lcd.setCursor(15, 1);
    lcd.print('C');
        
    delay(968);
    
    // Serial.print(" since 2000 = ");
    // Serial.print(now.get());
    // Serial.print("s = ");
    // Serial.print(now.get() / 86400L);
    // Serial.println("d");
    
    // calculate a date which is 7 days and 30 seconds into the future
    // DateTime future (now.get() + 7 * 86400L + 30);
    
    // Serial.print(" now + 7d + 30s: ");
    // Serial.print(future.year(), DEC);
    // Serial.print('/');
    // Serial.print(future.month(), DEC);
    // Serial.print('/');
    // Serial.print(future.day(), DEC);
    // Serial.print(' ');
    // Serial.print(future.hour(), DEC);
    // Serial.print(':');
    // Serial.print(future.minute(), DEC);
    // Serial.print(':');
    // Serial.print(future.second(), DEC);
    // Serial.println();
    
    // Serial.println();
    // delay(3000);
}

2012/06/01

Freeduino/Arduino: Set/Sync Date and Time on DS1307 Real Time Clock Shield

When setting date and time on DS1307 real time clock sensor shield using RTClib.h, there will be some seconds delay between the time on the shield and the standard time, so I need a sketch to adjust the clock on  the shield. And here comes the sketch.

The sketch can be used on the Freeduino/Arduino side to manually set or automatically (using program) sync the date and time of DS1307 RTC (real time clock) sensor shield or breakout.

The sketch will check the range of values keyed in including second, minute, hour, date of the month, month, year, and automatically generate day of the week.

Update: The sketch is updated on May 3, 2013 to be more modular, readable and extendable.

Pins Used

Analog pins 4 and 5 are used for I2C protocol implemented by Maxim DS1307.


Serial Monitor Output

Before Pressing <Enter> Key:

After Pressing <Enter> Key:

Updated Sketch


//
// Maurice Ribble
// 4-17-2008
// http://www.glacialwanderer.com/hobbyrobotics

// This code tests the DS1307 Real Time clock on the Arduino board.
// The ds1307 works in binary coded decimal or BCD.  You can look up
// bcd in google if you aren't familior with it.  There can output
// a square wave, but I don't expose that in this code.  See the
// ds1307 for it's full capabilities.

// Revised by Befun Hung to set/sync date and time for DS1307 Real Time Clock on Freeduino/Arduino shield.
// June-01-2012
// Revised by Befun Hung to create terminalSync function to be more modular
// May-03-2013
// http://cheaphousetek.blogspot.com/
// Usage: After uploading to Freeduino/Arduino board, open the serial monitor.
// Input Format: YYYY-MM-DD hh:mm:ss <Enter>

#include <Wire.h>
#define DS1307_I2C_ADDRESS 0x68

String datetimeIn;
int TimeSet = 0;
int timeArray[19], checkStatus = 1;
int centuryCode = 6; // for year 2000-2099 (Wikipedia: determination of the day of the week)
int monTable[12] = {0,3,3,6,1,4,6,2,5,0,3,5};
int leapmonTable[12] = {6,2,3,6,1,4,6,2,5,0,3,5};

// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
  return ( (val/10*16) + (val%10) );
}

// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
  return ( (val/16*10) + (val%16) );
}

// Stops the DS1307, but it has the side effect of setting seconds to 0
// Probably only want to use this for testing
/*void stopDs1307()
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.send(0);
  Wire.send(0x80);
  Wire.endTransmission();
}*/

// 1) Sets the date and time on the ds1307
// 2) Starts the clock
// 3) Sets hour mode to 24 hour clock
// Assumes you're passing in valid numbers
void setDateDs1307(byte second,        // 0-59
                   byte minute,        // 0-59
                   byte hour,          // 1-23
                   byte dayOfWeek,     // 1-7
                   byte dayOfMonth,    // 1-28/29/30/31
                   byte month,         // 1-12
                   byte year)          // 0-99
{
   Wire.beginTransmission(DS1307_I2C_ADDRESS);
   Wire.send(0);
   Wire.send(decToBcd(second));    // 0 to bit 7 starts the clock
   Wire.send(decToBcd(minute));
   Wire.send(decToBcd(hour));      // If you want 12 hour am/pm you need to set
                                   // bit 6 (also need to change readDateDs1307)
   Wire.send(decToBcd(dayOfWeek));
   Wire.send(decToBcd(dayOfMonth));
   Wire.send(decToBcd(month));
   Wire.send(decToBcd(year));
   Wire.endTransmission();
}

// Gets the date and time from the ds1307
void getDateDs1307(byte *second,
          byte *minute,
          byte *hour,
          byte *dayOfWeek,
          byte *dayOfMonth,
          byte *month,
          byte *year)
{
  // Reset the register pointer
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.send(0);
  Wire.endTransmission();

  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);

  // A few of these need masks because certain bits are control bits
  *second     = bcdToDec(Wire.receive() & 0x7f);
  *minute     = bcdToDec(Wire.receive());
  *hour       = bcdToDec(Wire.receive() & 0x3f);  // Need to change this if 12 hour am/pm
  *dayOfWeek  = bcdToDec(Wire.receive());
  *dayOfMonth = bcdToDec(Wire.receive());
  *month      = bcdToDec(Wire.receive());
  *year       = bcdToDec(Wire.receive());
}

void printFormatError() {
  Serial.println("Format Error\n");
}
/*
void printValueError() {
  Serial.println("Value Error\n");
}
*/

void setup() {
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  Wire.begin();
  Serial.begin(9600);
  delay(100);
  Serial.print("Waiting for setting the date and time now.\n");
  Serial.print("Input Format: YYYY-MM-DD HH:MM:SS\n");
  // Change these values to what you want to set your clock to.
  // You probably only want to set your clock once and then remove
  // the setDateDs1307 call.
  // second = 45;
  // minute = 3;
  // hour = 7;
  // dayOfWeek = 5;
  // dayOfMonth = 17;
  // month = 4;
  // year = 8;
  // setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
}

void loop() {
  terminalSync();
}

void terminalSync() {
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  
  if (Serial.available() == 19 ) {
    for (int i=0;i<19;i++) {
      timeArray[i] = Serial.read();  // Serial.read() read int type ASCII code value 
    }
    // for digits subtract 48 ('0' ASCII code value)
    for (int j=0;j<19;j++) {
      if (timeArray[j] > 47 && timeArray[j] < 58) {
        timeArray[j] -= 48;
      }
      if (timeArray[j] <= 9) {
         Serial.print(timeArray[j]);
      } 
      else {
        Serial.print(char(timeArray[j]));
      }
    }
    Serial.println("");
    // check for digits range
    checkStatus = 1;
    if (timeArray[0] != 2) {
      printFormatError();
      checkStatus = 0;
    }
    if (timeArray[1] != 0) {
      printFormatError();
      checkStatus = 0;
    }
    if (timeArray[2] > 9) {
      printFormatError();
      checkStatus = 0;
    }
    if (timeArray[3] > 9) {
      printFormatError();
      checkStatus = 0;
    }
    if (timeArray[5] > 1) {
      printFormatError();
      checkStatus = 0;
    }
    if (timeArray[6] > 9) {
      printFormatError();
      checkStatus = 0;
    }
    if (timeArray[5]*10+timeArray[6] > 12) {
      // printValueError();
      checkStatus = 0;
    }
    if (timeArray[8] > 3) {
      printFormatError();
      checkStatus = 0;
    }
    if (timeArray[9] > 9) {
      printFormatError();
      checkStatus = 0;
    }
    if ((timeArray[5]*10+timeArray[6] == 1 || 
         timeArray[5]*10+timeArray[6] == 3 ||
         timeArray[5]*10+timeArray[6] == 5 ||
         timeArray[5]*10+timeArray[6] == 7 ||
         timeArray[5]*10+timeArray[6] == 8 ||
         timeArray[5]*10+timeArray[6] == 10 ||
         timeArray[5]*10+timeArray[6] == 12) && timeArray[8]*10+timeArray[9] > 31) {
      // printValueError();
      checkStatus = 0;
    }
    if ((timeArray[5]*10+timeArray[6] == 4 || 
         timeArray[5]*10+timeArray[6] == 6 ||
         timeArray[5]*10+timeArray[6] == 9 ||
         timeArray[5]*10+timeArray[6] == 11) && timeArray[8]*10+timeArray[9] > 30) {
      // printValueError();
      checkStatus = 0;
    }
    if ((timeArray[5]*10+timeArray[6] == 2 && year % 4 == 0) && timeArray[8]*10+timeArray[9] > 29) {
      // printValueError();
      checkStatus = 0;
    }
    if ((timeArray[5]*10+timeArray[6] == 2 && year % 4 != 0) && timeArray[8]*10+timeArray[9] > 28) {
      // printValueError();
      checkStatus = 0;
    }
    if (timeArray[11] > 2) {
      printFormatError();
      checkStatus = 0;
    }
    if (timeArray[12] > 9) {
      printFormatError();
      checkStatus = 0;
    }
    if (timeArray[11]*10+timeArray[12] > 23) {
      // printValueError();
      checkStatus = 0;
    }
    if (timeArray[14] > 5) {
      printFormatError();
      checkStatus = 0;
    }
    if (timeArray[15] > 9) {
      printFormatError();
      checkStatus = 0;
    }
    if (timeArray[14]*10+timeArray[15] > 59) {
      // printValueError();
      checkStatus = 0;
    }
    if (timeArray[17] > 5) {
      printFormatError();
      checkStatus = 0;
    }
    if (timeArray[18] > 9) {
      printFormatError();
      checkStatus = 0;
    }
    if (timeArray[17]*10+timeArray[18] > 59) {
      // printValueError();
      checkStatus = 0;
    }
    // Serial.println(checkStatus);
    if (checkStatus) {
      second = timeArray[17]*10+timeArray[18];
      minute = timeArray[14]*10+timeArray[15];
      hour = timeArray[11]*10+timeArray[12];
      // dayOfWeek = 5;
      dayOfMonth = timeArray[8]*10+timeArray[9];
      month = timeArray[5]*10+timeArray[6];
      year = timeArray[2]*10+timeArray[3];
      if ((year % 4) == 0) {
        dayOfWeek = (centuryCode + year + ((year - (year % 4)) / 4) + leapmonTable[month-1] + dayOfMonth) % 7;
      }
      else {
        dayOfWeek = (centuryCode + year + ((year - (year % 4)) / 4) + monTable[month-1] + dayOfMonth) % 7;
      }
      if (dayOfWeek == 0) {
        dayOfWeek += 7;
      }
      setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
    }
    getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
    Serial.print(hour, DEC);
    Serial.print(":");
    Serial.print(minute, DEC);
    Serial.print(":");
    Serial.print(second, DEC);
    Serial.print("  ");
    Serial.print(month, DEC);
    Serial.print("/");
    Serial.print(dayOfMonth, DEC);
    Serial.print("/");
    Serial.print(year, DEC);
    Serial.print("  Day_of_week:");
    Serial.println(dayOfWeek, DEC);
    // delay(1000);
  }
}


Original Sketch

//
// Maurice Ribble
// 4-17-2008
// http://www.glacialwanderer.com/hobbyrobotics

// This code tests the DS1307 Real Time clock on the Arduino board.
// The ds1307 works in binary coded decimal or BCD.  You can look up
// bcd in google if you aren't familior with it.  There can output
// a square wave, but I don't expose that in this code.  See the
// ds1307 for it's full capabilities.

// Revised by Befun Hung to set/sync date and time for DS1307 Real Time Clock on Freeduino/Arduino shield.
// 1 June 2012
// File Name: SetSyncDateTime.pde
// http://cheaphousetek.blogspot.com/
// Usage: After uploading to Freeduino/Arduino board, open the serial monitor.
// Input Format: YYYY-MM-DD hh:mm:ss <Enter>
// The sketch works on Arduino IDE 0022

#include <Wire.h>
#define DS1307_I2C_ADDRESS 0x68

String datetimeIn;
int TimeSet = 0;
int timeArray[19], checkStatus = 1;
int centuryCode = 6; // for year 2000-2099 (Wikipedia: determination of the day of the week)
int monTable[12] = {0,3,3,6,1,4,6,2,5,0,3,5};
int leapmonTable[12] = {6,2,3,6,1,4,6,2,5,0,3,5};

// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
  return ( (val/10*16) + (val%10) );
}

// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
  return ( (val/16*10) + (val%16) );
}

// Stops the DS1307, but it has the side effect of setting seconds to 0
// Probably only want to use this for testing
/*void stopDs1307()
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.send(0);
  Wire.send(0x80);
  Wire.endTransmission();
}*/

// 1) Sets the date and time on the ds1307
// 2) Starts the clock
// 3) Sets hour mode to 24 hour clock
// Assumes you're passing in valid numbers
void setDateDs1307(byte second,        // 0-59
                   byte minute,        // 0-59
                   byte hour,          // 1-23
                   byte dayOfWeek,     // 1-7
                   byte dayOfMonth,    // 1-28/29/30/31
                   byte month,         // 1-12
                   byte year)          // 0-99
{
   Wire.beginTransmission(DS1307_I2C_ADDRESS);
   Wire.send(0);
   Wire.send(decToBcd(second));    // 0 to bit 7 starts the clock
   Wire.send(decToBcd(minute));
   Wire.send(decToBcd(hour));      // If you want 12 hour am/pm you need to set
                                   // bit 6 (also need to change readDateDs1307)
   Wire.send(decToBcd(dayOfWeek));
   Wire.send(decToBcd(dayOfMonth));
   Wire.send(decToBcd(month));
   Wire.send(decToBcd(year));
   Wire.endTransmission();
}

// Gets the date and time from the ds1307
void getDateDs1307(byte *second,
          byte *minute,
          byte *hour,
          byte *dayOfWeek,
          byte *dayOfMonth,
          byte *month,
          byte *year)
{
  // Reset the register pointer
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.send(0);
  Wire.endTransmission();

  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);

  // A few of these need masks because certain bits are control bits
  *second     = bcdToDec(Wire.receive() & 0x7f);
  *minute     = bcdToDec(Wire.receive());
  *hour       = bcdToDec(Wire.receive() & 0x3f);  // Need to change this if 12 hour am/pm
  *dayOfWeek  = bcdToDec(Wire.receive());
  *dayOfMonth = bcdToDec(Wire.receive());
  *month      = bcdToDec(Wire.receive());
  *year       = bcdToDec(Wire.receive());
}

void printFormatError() {
  Serial.println("Format Error\n");
}
/*
void printValueError() {
  Serial.println("Value Error\n");
}
*/

void setup() {
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  Wire.begin();
  Serial.begin(9600);
  delay(100);
  Serial.print("Waiting for setting the date and time now.\n");
  Serial.print("Input Format: YYYY-MM-DD HH:MM:SS\n");
  // Change these values to what you want to set your clock to.
  // You probably only want to set your clock once and then remove
  // the setDateDs1307 call.
  // second = 45;
  // minute = 3;
  // hour = 7;
  // dayOfWeek = 5;
  // dayOfMonth = 17;
  // month = 4;
  // year = 8;
  // setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
}

void loop() {
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  
  if (Serial.available() == 19 ) {
    for (int i=0;i<19;i++) {
      timeArray[i] = Serial.read();  // Serial.read() read int type ASCII code value 
    }
    // for digits subtract 48 ('0' ASCII code value)
    for (int j=0;j<19;j++) {
      if (timeArray[j] > 47 && timeArray[j] < 58) {
        timeArray[j] -= 48;
      }
      if (timeArray[j] <= 9) {
         Serial.print(timeArray[j]);
      } 
      else {
        Serial.print(char(timeArray[j]));
      }
    }
    Serial.println("");
    // check for digits range
    checkStatus = 1;
    if (timeArray[0] != 2) {
      printFormatError();
      checkStatus = 0;
    }
    if (timeArray[1] != 0) {
      printFormatError();
      checkStatus = 0;
    }
    if (timeArray[2] > 9) {
      printFormatError();
      checkStatus = 0;
    }
    if (timeArray[3] > 9) {
      printFormatError();
      checkStatus = 0;
    }
    if (timeArray[5] > 1) {
      printFormatError();
      checkStatus = 0;
    }
    if (timeArray[6] > 9) {
      printFormatError();
      checkStatus = 0;
    }
    if (timeArray[5]*10+timeArray[6] > 12) {
      // printValueError();
      checkStatus = 0;
    }
    if (timeArray[8] > 3) {
      printFormatError();
      checkStatus = 0;
    }
    if (timeArray[9] > 9) {
      printFormatError();
      checkStatus = 0;
    }
    if ((timeArray[5]*10+timeArray[6] == 1 || 
         timeArray[5]*10+timeArray[6] == 3 ||
         timeArray[5]*10+timeArray[6] == 5 ||
         timeArray[5]*10+timeArray[6] == 7 ||
         timeArray[5]*10+timeArray[6] == 8 ||
         timeArray[5]*10+timeArray[6] == 10 ||
         timeArray[5]*10+timeArray[6] == 12) && timeArray[8]*10+timeArray[9] > 31) {
      // printValueError();
      checkStatus = 0;
    }
    if ((timeArray[5]*10+timeArray[6] == 4 || 
         timeArray[5]*10+timeArray[6] == 6 ||
         timeArray[5]*10+timeArray[6] == 9 ||
         timeArray[5]*10+timeArray[6] == 11) && timeArray[8]*10+timeArray[9] > 30) {
      // printValueError();
      checkStatus = 0;
    }
    if ((timeArray[5]*10+timeArray[6] == 2 && year % 4 == 0) && timeArray[8]*10+timeArray[9] > 29) {
      // printValueError();
      checkStatus = 0;
    }
    if ((timeArray[5]*10+timeArray[6] == 2 && year % 4 != 0) && timeArray[8]*10+timeArray[9] > 28) {
      // printValueError();
      checkStatus = 0;
    }
    if (timeArray[11] > 2) {
      printFormatError();
      checkStatus = 0;
    }
    if (timeArray[12] > 9) {
      printFormatError();
      checkStatus = 0;
    }
    if (timeArray[11]*10+timeArray[12] > 23) {
      // printValueError();
      checkStatus = 0;
    }
    if (timeArray[14] > 5) {
      printFormatError();
      checkStatus = 0;
    }
    if (timeArray[15] > 9) {
      printFormatError();
      checkStatus = 0;
    }
    if (timeArray[14]*10+timeArray[15] > 59) {
      // printValueError();
      checkStatus = 0;
    }
    if (timeArray[17] > 5) {
      printFormatError();
      checkStatus = 0;
    }
    if (timeArray[18] > 9) {
      printFormatError();
      checkStatus = 0;
    }
    if (timeArray[17]*10+timeArray[18] > 59) {
      // printValueError();
      checkStatus = 0;
    }
    // Serial.println(checkStatus);
    if (checkStatus) {
      second = timeArray[17]*10+timeArray[18];
      minute = timeArray[14]*10+timeArray[15];
      hour = timeArray[11]*10+timeArray[12];
      // dayOfWeek = 5;
      dayOfMonth = timeArray[8]*10+timeArray[9];
      month = timeArray[5]*10+timeArray[6];
      year = timeArray[2]*10+timeArray[3];
      if ((year % 4) == 0) {
        dayOfWeek = (centuryCode + year + ((year - (year % 4)) / 4) + leapmonTable[month-1] + dayOfMonth) % 7;
      }
      else {
        dayOfWeek = (centuryCode + year + ((year - (year % 4)) / 4) + monTable[month-1] + dayOfMonth) % 7;
      }
      if (dayOfWeek == 0) {
        dayOfWeek += 7;
      }
      setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
    }
    getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
    Serial.print(hour, DEC);
    Serial.print(":");
    Serial.print(minute, DEC);
    Serial.print(":");
    Serial.print(second, DEC);
    Serial.print("  ");
    Serial.print(month, DEC);
    Serial.print("/");
    Serial.print(dayOfMonth, DEC);
    Serial.print("/");
    Serial.print(year, DEC);
    Serial.print("  Day_of_week:");
    Serial.println(dayOfWeek, DEC);
    // delay(1000);
  }
}