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;
}