News

Page 1 of 3  > >>

Oct 30, 2012
Category: General
Posted by: William Moritz

First I offer a .Net Windows App ecoXsaver.zip

Now here's the VS2010 CSharp Source Files, EcoXsaverSources.zip

.Net Windows App

Sep 23, 2012
Category: General
Posted by: William Moritz

A very simple, dirt-simple, shield see, x10 Controller Shield and Shield Wiring Diagram

 

Sep 21, 2012
Category: General
Posted by: William Moritz

 

CMS - 1.11.1 - Baltra
 

x10 Controller Sketch

////////////////////////////////////////////////////////////////////////////////////////////////////
// file:    EcoXsaverA.ino
//
// summary:    eco xsaver the class
////////////////////////////////////////////////////////////////////////////////////////////////////

#include <SoftwareSerial.h>
#include <x10constants.h>
#include <x10.h>
//#include <TW523.h>
#include <Arduino.h>
#include "Wire.h"
#include <EEPROM.h>
#include <DB.h>

////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
/// The revision[] history. One revision per day with a comment of why The older revision are
/// simply commented out. Every line of code needs a comment to be understood by others easily.
/// </summary>
////////////////////////////////////////////////////////////////////////////////////////////////////

char revision[]="20121001";            //Initial public code

//char revision[]="20120924";        //adding lots of line comments

//char revision[]="20120919";    //Added commenting system

#define DS1307_I2C_ADDRESS 0x68 //base address of the RTC, Real time Clock

#define ERR 255                    //byte size -1 ERROR code
#define MY_TBL 1                //Table of the Database DB

#define MAX_RECORDS 100            //Maximum records 16 more than ever used

DB db;                            //instance the database

////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>    Record. </summary>
/// First record idx=1 is the direct command location whereas the house letter is changed to '@' after activation
/// idx=2,100 are normal schedule executions on or off
/// <remarks>    Administrator, 9/24/2012. </remarks>
////////////////////////////////////////////////////////////////////////////////////////////////////

struct Record
{
    byte idx;            //record index, index=0 is the record header
    byte house;            //A-P House codes
    byte unit;            // 1-16, 0 = all off
    byte hour;            //1-23 hours
    byte minute;        //0-59 minutes
    byte day;            //1-7 day of week
    byte command;        // 0=Off, 1= on
    } record;            // instance neame

byte records=0;            //record count

int ledPin =  13;        // state LED connected to digital pin 13

int ledState = LOW;        // initally off state
int flashRateOn=500;    //inital flash rate with clock string being send on Serial

int flashRateOff=500;    //universal on/off rate 500 milliseconds

char Time[80];            //Time storage sting

byte second=0;            // 0-59 seconds
byte minute=0;            // 0-59 minutes
byte hour=0;            // 1-23 hours
byte dayOfWeek=0;        // 1-7 day of the week number
byte dayOfMonth=0;        // 1-28/29/30/31
byte month=0;            // 1-12
byte year=0;            // 0-99

int loop_ctr=0;            //just a testing varible

/* Arduino Interface to the TW523 X10 Receiver.                       BroHogan 3/24/09
* SETUP: X10 TW523/TW523 RJ11 to Arduino (timing for 60Hz)
* - RJ11 pin 1 (BLK) -> Pin 2 (Interrupt 0) = Zero Crossing
* - RJ11 pin 2 (RED) -> GND
* - RJ11 pin 3 (GRN) -> Pin 4 = Arduino receive
* - RJ11 pin 4 (YEL) -> Pin 5 = Arduino transmit (via X10 Lib)
* NOTES:
* - Must detach interrupt when transmitting with X10 Lib
* updated to use X10 library code by creatrope 3/24/10
*/

// x10 defines.
#define repeat 2                //x10 command repeat rate

#define ZCROSS_PIN        2        // BLK or Yel pin 1 of TW523
#define GND                3        // RED or GRN pin 2 of TW523
#define RCVE_PIN        4       // GRN or RED  pin 3 of TW523
#define TRANS_PIN        5       // YEL or BLK pin 4 of TW523
#define LED_PIN        13       // state pin for testing

x10 SX10= x10(ZCROSS_PIN,TRANS_PIN,RCVE_PIN,LED_PIN);// set up a x10 library instance:

int house,unit,cmd; //x10 global items

////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>    Setup </summary>
///
/// <remarks>    Administrator, 9/8/2012. </remarks>
////////////////////////////////////////////////////////////////////////////////////////////////////

void setup()
{
    Serial.begin(115200);        //set communictions rate
    pinMode(ledPin, OUTPUT);    //choose led light
    digitalWrite(ledPin, LOW);    // set the LED off
    Wire.begin();                //Commune with RTC
    db.open(MY_TBL);            //open DB
    if(checkDB()==ERR)            //check for garbage
    {
        CreateDB();                //init the data base and create header record
        Serial.println("DB Error");
    }
    SX10.reset();                //clear receive condition
    Serial.println(revision);    //last revision date code
}

/* add main program code here */
void loop()
{
    loop_ctr++;            //just a testing varible
    Flasher();            //main led controller
    Commands();            //Gets commands from the Serial input
    GetTime();            //get time of day
    ProcessX10();        //Checks for direct and hourly actions
}

////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>    Software reset. </summary>
///    Restarts program from beginning but does not reset the peripherals and registers
///    Called from the getSerial routine to reset the Arduino
/// <remarks>    Administrator, 9/8/2012. </remarks>
////////////////////////////////////////////////////////////////////////////////////////////////////

void software_Reset()
{
    asm("  jmp 0");  // Restarts program from beginning but does not reset the peripherals and registers
}

////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>    Gets the time. </summary>
/// Sets the global "Time" string for the Serial Transmission to Host Program
/// <remarks>    Administrator, 9/24/2012. </remarks>
////////////////////////////////////////////////////////////////////////////////////////////////////

void GetTime()
{
    getDateDs1307(&second,&minute,&hour,&dayOfWeek,&dayOfMonth,&month,&year);
    sprintf(Time,"%02d:%02d:%02d %02d/%02d/%02d Day=%d",hour,minute,second,month,dayOfMonth,year, dayOfWeek);
}

////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>    Flashers this object. </summary>
///
/// <remarks>    Administrator, 9/8/2012. </remarks>
////////////////////////////////////////////////////////////////////////////////////////////////////

void Flasher()
{
    unsigned long currentMillis = millis();    //get present milliseconds
    static long previousMillis = 0;        // will store last time LED was updated
    static long interval = 0;                // wiil save the interval at which to blink (milliseconds)

    if(currentMillis - previousMillis > interval)
    {
        previousMillis = currentMillis;        // save the last time you blinked the LED
        if (ledState == LOW)                // if the LED is off turn it on and vice-versa:
        {
            ledState = HIGH;                //Set the led state to on
            interval=flashRateOn;            //Set the present flash on rate
            if (flashRateOn==500&&flashRateOff==500)    //Send Global "Time" string the the rate is both 500 milliseconds?
                Serial.println(Time);        // Send to Host Computer
        }
        else
        {
            ledState = LOW;                //Set LED state off
            interval=flashRateOff;        //Save off time period
        }
        digitalWrite(ledPin, ledState);    // set the LED with the ledState of the variable:
    }
}

////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>    Commands from Serial Port. </summary>
///Serial Commands
///
/// No ascii characters like ‘A’ it must be the decimal code as ‘house A=65/ not A/
///
/// command 'B': //Direct command, >house code, >unit code, >command on=1 off=0
/// command 'T': //Send time string every second
/// command 'Q': //Quiet no sending time string or flashing led
/// command 'S':  //set seconds >value/ 0-59
/// command 'M': //set minutes >value/ 0-59
/// command 'H': //set hours >value/ 0-23
/// command 'D': //set day of week >value/ 1-7
/// command 'X': //set month >value/ 1-12
/// command 'Z': //set day of the month >value/ 1-31
/// command 'Y': // set year >value/ 0-99
/// command 'R': // reset Data Base >value/ 1= yes
/// command 'C': //check database okay
/// command 'A'://add record A/ >house code/ >unit code/ >hour/ >minute/ >day of week/ >command
/// command 'U': //dump data base records
/// command '*': //Controller Software Reset
///
///
/// <remarks>    Administrator, 9/8/2012. </remarks>
////////////////////////////////////////////////////////////////////////////////////////////////////

void Commands()
{
    if (Serial.available()>0)    //Character Available?
    {
        char c=Serial.read();    //Get it
        c&=0x5f;                // make upper case
        switch(c)                // a valid Command check it?
        {
        case 'B': //Direct command, >house code, >unit code, >command on=1 off=0
            {
                doMyRecord(1); //form index for direct command
                flashRateOn=flashRateOff=0; //stop led flashing
                digitalWrite(ledPin, HIGH); //Quiet mode led on
                break;
            }
        case 'T': //Send time string every second
            {
                flashRateOn=flashRateOff=500; //flash rate causes time string to be sent
                break;
            }
        case 'Q': //Quiet no sending time string or flashing led
            {
                flashRateOn=flashRateOff=0; //stop led flashing
                digitalWrite(ledPin, HIGH); //Quiet mode led on
                break;
            }
        case 'S':  //set seconds >value/ 0-59
            {
                digitalWrite(ledPin, LOW); //Quiet mode led
                second=getValue(0,59); //get numeric valiue
                if (second==ERR)    //byte error?
                    Serial.println("(Error Seconds)");
                else
                {
                    setDateDs1307(); //set in clock

                }
                break;
            }
        case 'M': //set minutes >value/ 0-59
            {
                minute=getValue(0,59); //get numeric valiue
                if (minute==ERR)
                    Serial.println("(Error Minutes)");
                else
                    setDateDs1307();
                break;
            }
        case 'H': //set hours >value/ 0-23
            {
                hour=getValue(0,23); //get numeric valiue
                if (hour==ERR)
                    Serial.println("(Error hour)");
                else
                    setDateDs1307();
                break;
            }
        case 'D': //set day of week >value/ 1-7
            {
                dayOfWeek=getValue(1,7); //get numeric valiue
                if (dayOfWeek==ERR)
                    Serial.println("(Error dayOfWeek)");
                else
                    setDateDs1307();
                break;        
            }
        case 'X': //set month >value/ 1-12
            {
                month=getValue(1,12); //get numeric valiue
                if (month==ERR)
                    Serial.println("(Error month)");
                else
                    setDateDs1307();
                break;
            }
        case 'Z': //set day of the month >value/ 1-31
            {
                dayOfMonth=getValue(1,31); //get numeric valiue
                if (dayOfMonth==ERR)
                    Serial.println("(Error dayOfMonth)");
                else
                    setDateDs1307();
                break;
            }
        case 'Y': // set year >value/ 0-99
            {
                year= getValue(0,99); //get numeric valiue
                if (year==ERR)
                    Serial.println("(Error year)");
                else
                    setDateDs1307();
                digitalWrite(ledPin, HIGH); //Quiet mode led
                break;
            }
        case 'R': // reset Data Base >value/ 1= yes
            {
                Serial.println("(1/)"); //request aformation
                byte ans=getSerial(); //ans
                if (ans==1) //ans=1
                {
                    CreateDB(); //init the data base and create header record

                }
                break;
            }
        case 'C': //check database okay
            {

                if(checkDB()==ERR)
                    Serial.println("(Bad)");
                else
                    Serial.println("(Okay)");
                break;
            }
        case 'A':    //append a record A/ >house code/ >unit code/ >hour/ >minute/ >day of week/ >command/
            {
                doMyRecord(db.nRecs()+1); //form index
                //Serial.println("DONE");    
                break;
            }
        case 'U': //dump data base records
            {
                flashRateOn=flashRateOff=0; //stop led flashing
                digitalWrite(ledPin, HIGH); //Quiet mode led on
                dump();

                break;
            }
        case '*': //Controller Software Reset
            {
                software_Reset(); // Restarts program from beginning but does not reset the peripherals and registers
                break;
            }

        default: //Bad code flashing
            {
                flashRateOn=flashRateOff=200; //Bad code Character flashitty flash
                software_Reset(); // Restarts program from beginning but does not reset the peripherals and registers
                break;
            }
        }
    }
}

////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>    Gets a value. </summary>
/// Looking for numeric value otherwise repeats '#' ready to host
/// <remarks>    Administrator, 9/9/2012. </remarks>
/// Range testing
/// <param name="low">     The low. </param>
/// <param name="high">    The high. </param>
/// Return either a good value or -1 byte as ERR
/// <returns>    The value. </returns>
////////////////////////////////////////////////////////////////////////////////////////////////////

long getValue(int low, int high)
{
    unsigned long currentMillis = millis();    //get present milliseconds
    static long previousMillis = 0;        // will store last time sent varible
    static long interval = 5;                // wiil save the interval at which to resend
    unsigned long value=0;

    Serial.println("#");
    previousMillis = currentMillis;        // save the last time you sent
    do
    {
        if(currentMillis - previousMillis > interval)
        {
            Serial.println("#"); //Ready is repeating until host sends something
            previousMillis = currentMillis;        // save the last time you sent
        }
    }
    while (Serial.available()==0);    //nothing yet?
    value=getSerial();            //get numeric valiue
    if (value<low||value>high)
    {
        value=-1;                //error
        flashRateOn=flashRateOff=200; //Bad code Character flashitty flash
    }
    return value ; //return with value
}

////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>    Gets the serial. </summary>
/// Builds a value byte by byte which exits on '/'
/// But it has a software reset if commanded by the host since it could be caught in this look
/// <remarks>    Administrator, 9/9/2012. </remarks>
///
/// <returns>    The serialdata value </returns>
////////////////////////////////////////////////////////////////////////////////////////////////////

long getSerial()
{
    unsigned long serialdata = 0; // the returned value
    int inbyte = 0; // the byte source

    do
    {
         while (Serial.available() == 0) ;
        if (inbyte=='*') // or rest the chip
            software_Reset(); // yes init the program
        inbyte = Serial.read(); // otherwise read a byte
        if (inbyte > 0 && inbyte != '/') //process the byte
        {
            serialdata = serialdata * 10 + inbyte - '0'; // built the value
        }
    }
    while (inbyte != '/'); // quit building?
    return serialdata; // return the built value
}

////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>    Sets the date ds 1307. </summary>
/// Generally the second, minute and hour, etc. are updated globally each loop pass
/// so only the changed varible, such as minute or hour, is updated by a Host computer
/// <remarks>    Administrator, 9/24/2012. </remarks>
////////////////////////////////////////////////////////////////////////////////////////////////////

void setDateDs1307()          
{
    Wire.beginTransmission(DS1307_I2C_ADDRESS); // Reset the register pointer
    Wire.write(0);                    //execute
    Wire.write(decToBcd(second));    // 0 to bit 7 starts the clock
    Wire.write(decToBcd(minute));
    Wire.write(decToBcd(hour));      // If you want 12 hour am/pm you need to set bit 6 not me...
    Wire.write(decToBcd(dayOfWeek));
    Wire.write(decToBcd(dayOfMonth));
    Wire.write(decToBcd(month));
    Wire.write(decToBcd(year));
    Wire.endTransmission();
}

////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>    Gets a date ds 1307. </summary>
///
/// <remarks>    Administrator, 9/25/2012. </remarks>
/// Little is known by me it just works...
/// <param name="second">         [in,out] If non-null, the second. </param>
/// <param name="minute">         [in,out] If non-null, the minute. </param>
/// <param name="hour">             [in,out] If non-null, the hour. </param>
/// <param name="dayOfWeek">     [in,out] If non-null, the day of week. </param>
/// <param name="dayOfMonth">    [in,out] If non-null, the day of month. </param>
/// <param name="month">         [in,out] If non-null, the month. </param>
/// <param name="year">             [in,out] If non-null, the year. </param>
////////////////////////////////////////////////////////////////////////////////////////////////////

void getDateDs1307(byte *second,
    byte *minute,
    byte *hour,
    byte *dayOfWeek,
    byte *dayOfMonth,
    byte *month,
    byte *year)
{
    Wire.beginTransmission(DS1307_I2C_ADDRESS); // Reset the register pointer
    Wire.write(0);                                //execute
    Wire.endTransmission();
    Wire.requestFrom(DS1307_I2C_ADDRESS, 7);
    *second     = bcdToDec(Wire.read() & 0x7f); // A few of these need masks because certain bits are control bits
    *minute     = bcdToDec(Wire.read());
    *hour       = bcdToDec(Wire.read() & 0x3f);  // Need to change bit 6 this if 12 hour am/pm not me...
    *dayOfWeek  = bcdToDec(Wire.read());
    *dayOfMonth = bcdToDec(Wire.read());
    *month      = bcdToDec(Wire.read());
    *year       = bcdToDec(Wire.read());
}

////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>    Process the x coordinate 10. </summary>
/// Gets each record and test new, house is not a used 'Direct Command'
/// <remarks>    Administrator, 9/25/2012. </remarks>
////////////////////////////////////////////////////////////////////////////////////////////////////
void ProcessX10()
{
    static byte Minute=0;        //Remember the last minute via static variable

    db.read(1, DB_REC record);    //get the direct command the first record
    if((Minute!=minute)||(record.house!='@')) //check every minute or a House code in first record
    {
        Minute=minute;                //save so not to repeat until not minute
        if (record.house!='@')        //Is there a house active?
        {
            processCommands();        //Do x10 command
            record.house='@';        //zero out house do only once
            db.write(1,DB_REC record); //Set used
        }
        for (int i = 2; i <= db.nRecs(); i++) //Scan thru record 2 thru 100 or less
        {
            db.read(i, DB_REC record);
            if ((record.day==0||record.day==dayOfWeek)&&record.hour==hour&&record.minute==minute) //daily or today and the hour and the minute
            {
                processCommands();
            }
        }
    }
}

////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>    Process the commands. </summary>
///
/// <remarks>    Administrator, 9/25/2012. </remarks>
////////////////////////////////////////////////////////////////////////////////////////////////////

void processCommands()
{
    byte Command=0;
    char str[80];
    char str1[5];
    char House[10];
    char Unit[10];
    char Cmd[10];

    
    if (record.command>0)    //command equal ON?
        Command=2;            //x10 On command
    if (record.command==0) //command equal OFF
        Command=3;            //x10 Off command
    sprintf(str1," %c%X%d",record.house,record.unit,Command); //form translate string
    if(translate(str1)!=-1) //translate do x10 values
    {
        itoa(house,House,2); //make integer ascii binary
        itoa(unit,Unit,16);    //make integer ascii hexidecimal
        itoa(cmd,Cmd,2);    //make integer ascii binary
        SX10.write(house,unit,repeat); //program will hang if the TW523 is disconnected
        SX10.write(house,cmd,repeat);    //program will hang if the TW523 is disconnected
        sprintf(str,"house=%b unit=%x cmd=%b",house,unit,cmd);
        Serial.println(str); //????
    }
    else //translate failed
    {
        itoa(house,House,2); //make integer ascii binary
        itoa(unit,Unit,16);    //make integer ascii hexidecimal
        itoa(cmd,Cmd,2);    //make integer ascii binary
        sprintf(str,"house=%s unit=%s cmd=%s",House,Unit,Cmd); //shows binary codes
    }
}

////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>    Translates the given string. </summary>
///
/// <remarks>    Administrator, 9/25/2012. </remarks>
///
/// <param name="str">    [in,out] If non-null, the. </param>
/// What is used:
///
/// House Codes
///        H1    H2    H4    H8
/// A    0    1    1    0
/// B    1    1    1    0
/// C    0    0    1    0
/// D    1    0    1    0
/// E    0    0    0    1
/// F    1    0    0    1
/// G    0    1    0    1
/// H    1    1    0    1
/// I    0    1    1    1
/// J    1    1    1    1
/// K    0    0    1    1
/// L    1    0    1    1
/// M    0    0    0    0
/// N    1    0    0    0
/// O    0    1    0    0
/// P    1    1    0    0
///
/// Key Codes (unit code)
///        D1    D2    D4    D8    D16
/// 1    0    1    1    0    0
/// 2    1    1    1    0    0
/// 3    0    0    1    0    0
/// 4    1    0    1    0    0
/// 5    0    0    0    1    0
/// 6    1    0    0    1    0
/// 7    0    1    0    1    0
/// 8    1    1    0    1    0
/// 9    0    1    1    1    0
/// 10    1    1    1    1    0
/// 11    0    0    1    1    0
/// 12    1    0    1    1    0
/// 13    0    0    0    0    0
/// 14    1    0    0    0    0
/// 15    0    1    0    0    0
/// 16    1    1    0    0    0
///
///
/// ON    0    0    1    0    1  // Of a specific unit code within a House code
/// OFF    0    0    1    1    1    // Of a specific unit code within a House code
///
/// <returns>    . </returns>
////////////////////////////////////////////////////////////////////////////////////////////////////

int translate(char *str) // Translate to x10 values
{
    switch(str[1]) //house code value
    {
    case 'A': house=HOUSE_A; break;
    case 'B': house=HOUSE_B; break;
    case 'C': house=HOUSE_C; break;
    case 'D': house=HOUSE_D; break;
    case 'E': house=HOUSE_E; break;
    case 'F': house=HOUSE_F; break;
    case 'G': house=HOUSE_G; break;
    case 'H': house=HOUSE_H; break;
    case 'I': house=HOUSE_I; break;
    case 'J': house=HOUSE_J; break;
    case 'K': house=HOUSE_K; break;
    case 'L': house=HOUSE_L; break;
    case 'M': house=HOUSE_M; break;
    case 'N': house=HOUSE_N; break;
    case 'O': house=HOUSE_O; break;
    case 'P': house=HOUSE_P;break;
    default : return(-1);
    }
    switch(str[2]) //do unit code value
    {
    case '1': unit=UNIT_1; break;
    case '2': unit=UNIT_2; break;
    case '3': unit=UNIT_3; break;
    case '4': unit=UNIT_4; break;
    case '5': unit=UNIT_5; break;
    case '6': unit=UNIT_6; break;
    case '7': unit=UNIT_7; break;
    case '8': unit=UNIT_8; break;
    case '9': unit=UNIT_9; break;
    case 'A': unit=UNIT_10;break;
    case 'B': unit=UNIT_11;break;
    case 'C': unit=UNIT_12;break;
    case 'D': unit=UNIT_13;break;
    case 'E': unit=UNIT_14;break;
    case 'F': unit=UNIT_15; break;
    case 'G': unit=UNIT_16;break;
    default : return(-1);
    }
    switch(str[3]) //do cmd value
    {
    case '2': cmd=ON; break;    // command 'ON' of a specific unit code within a House code
    case '3': cmd=OFF;break;    // command 'OFF' of a specific unit code within a House code
    default : return(-1);
    }
    return(0);
}

////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>    Dumps this Data Base to the serial port </summary>
///
/// <remarks>    Administrator, 9/26/2012. </remarks>
////////////////////////////////////////////////////////////////////////////////////////////////////

void dump()
{

    if (db.nRecs())
    {
        char str[80];
        char str1[20];
        char str2[20];

        Serial.println("--Controller Data Base Dump--");

        for (int i = 1; i <= db.nRecs(); i++)
        {
            db.read(i, DB_REC record);
            str2[0]=0;
            if (record.day&1)
                strcat(str2,"Su"); //Sunday stored
            if (record.day&2)
                strcat(str2,"M"); //Monday
            if (record.day&4)
                strcat(str2,"Tu"); //Tuesday
            if (record.day&8)
                strcat(str2,"W"); //Wednesday
            if (record.day&0x10)
                strcat(str2,"Th"); //Thursday
            if (record.day&0x20)
                strcat(str2,"F"); //Friday
            if (record.day&0x40)
                strcat(str2,"Sa"); //Saturday
            if (record.day==0)
                strcpy(str2,"Daily"); //Every day
            if (record.command==0)
                strcpy(str1,"OFF");
            else
                strcpy(str1,"ON");
            sprintf(str,"idx %d %c%d %02d:%02d %s %s",record.idx,record.house,record.unit,record.hour,record.minute,str2,str1);
            Serial.println(str);
        }
        Serial.println("-----Data Base Table End------");
    }
}

////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>    Decrement to bcd. </summary>
///
/// <remarks>    Administrator, 9/26/2012. </remarks>
///
/// <param name="val">    The value. </param>
/// Convert normal decimal numbers to binary coded decimal.
/// <returns>    . </returns>
////////////////////////////////////////////////////////////////////////////////////////////////////

byte decToBcd(byte val)
{
    return ( (val/10*16) + (val%10) );
}

 

////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>    Bcd to decrement. </summary>
///
/// <remarks>    Administrator, 9/26/2012. </remarks>
///
/// <param name="val">    The value. </param>
/// Convert binary coded decimal to normal decimal numbers.
/// <returns>    . </returns>
////////////////////////////////////////////////////////////////////////////////////////////////////

byte bcdToDec(byte val)
{
    return ( (val/16*10) + (val%16) );
}

////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>    Creates the database. </summary>
///
/// <remarks>    Administrator, 9/26/2012. </remarks>
////////////////////////////////////////////////////////////////////////////////////////////////////

void CreateDB() //write full table and fill with nulls
{
    int recno=1; //Direct Command storage

    db.create(MY_TBL,sizeof(record)); //init table
    db.open(MY_TBL); // open my table
    record.idx=recno;        //first index
    record.house=64;            //empty house @=direct command is done
    record.unit=0;    //all unit codes
    record.hour=0;    //midnight
    record.minute=0; //minutes at that time
    record.day=1;    //Sunday
    record.command=0; // turn off
    db.append(DB_REC record);
    Serial.println("DB Reset");
}

////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>    Executes my record operation. </summary>
///
/// <remarks>    Administrator, 9/25/2012. </remarks>
///
/// <param name="idx">    The index. </param>
////////////////////////////////////////////////////////////////////////////////////////////////////

void doMyRecord(int idx)

{
    char str[80];

    byte house=0;  //local house
    byte unit=0;    //local unit
    byte hour=0;    //local hour
    byte minute=0;    //local minutes
    byte day=0;        //local day of the week
    byte command=0;    //local command

    house=getValue(64,80); //get house code A=65/ @=64/ which is empty record
    if(house==ERR)            //Error from get routine?
    {
        Serial.println("(Error House Code)"); //fouled out
        return;                //quit we lose
    }
    //sprintf(str,"House Code %c", house);
    unit=getValue(1,16); //get unit code0/
    if (unit==ERR)            //Error from get routine?
    {
        Serial.println("(Error Unit Code)");    //fouled out    
        return;            //quit
    }
    //sprintf(str,"Unit Code %d", unit);
    if (idx!=1) //skip these items since they are used in a direct command
    {
        day=getValue(0,0x7f); //get numeric valiue
        if (day==ERR)                //Error from get routine?
        {
            Serial.println("(Error day)"); //fouled out
            return;    //quit
        }        
        hour=getValue(0,23); //get numeric valiue
        if (hour==ERR)            //Error from get routine?
        {
            Serial.println("(Error hour)"); //fouled out
            return; //quit
        }
        minute=getValue(0,59); //get numeric valiue
        if (hour==ERR)                //Error from get routine?
        {
            Serial.println("(Error minute)"); //fouled out
            return; //quit
        }        
    }
    command=getValue(0,100); //get numeric valiue
    if (command==ERR)        //Error from get routine?
    {
        Serial.println("(Error command)"); //fouled out
        return; //quit
    }
    record.idx=idx;     //Do the requested record
    record.house=house; //house code
    record.unit=unit; //unit code
    record.hour=hour;    //midnight=0
    record.minute=minute; //minutes at that time
    record.day=day; //day of the week;
    record.command=command; // turn off=0 on=1 to 100 percent
    if (idx==1)
    {
        db.write(1,DB_REC record); //write the direct command record
        Serial.println("Direct command!");
    }
    else
    {
        db.append(DB_REC record);    //Write a regular record 2-100
        Serial.println("#");        //(Ready) for the next record
    }
}

////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>    Byte 2bin. </summary>
///
/// <remarks>    Administrator, 9/8/2012. </remarks>
///
/// <param name="x">    The x coordinate. </param>
///
/// <returns>    null if it fails, else. </returns>
////////////////////////////////////////////////////////////////////////////////////////////////////

const char *byte2bin(int x)
{
    static char b[9];
    b[0] = '\0';

    int i;
    for (i = 128; i > 0; i >>= 1)
        strcat(b, ((x & i) == i) ? "1" : "0");
    return b;
}
byte checkDB()
{
    records=db.nRecs();        //number of records
    db.read(1,DB_REC record); //get the first record, a dummy record
    if ((records==0)||(db.DB_head.rec_size!=sizeof(record)))
        return(ERR);
    else
        return 0;
}