#include <Wire.h> //I2C library
#define I2Caddr 0x07
#define fldLenMax 7
#define msgNum 6
#define fldsNum 24
#define sync A6
#define blueLED 8
#define greenLED 9
#define btTxd 12
#define btRxd A0
#define btEn A1
#define btState 13
#define buffLen 24
struct msg_t {
char keyCode;
uint8_t fldQty;
uint8_t period; // in seconds
uint8_t age; // in periods
uint32_t prevMillis; // in milliseconds
};
msg_t msgs[msgNum] = {
{'t', 4, 62, 0, 0}, {'s', 4, 74, 0, 0}, {'r', 4, 74, 0, 0}, {'n', 3, 153, 0, 0}, {'z', 2, 153, 0, 0}, {'u', 4, 255, 0, 0}
};
struct fld_t {
char fldData[fldLenMax];
uint8_t len;
uint8_t areaInx;
uint8_t typeInx;
uint8_t unitsInx;
byte dp; //Decimal Point: 0 = none, 1 = after 1 digit , 2 = after 2 digits, etc
};
const char*titles[] = {
" ", ":", "/", "%", "MA", "V", "`F", "inHg", "MAH", "Kohm", // 0 - 9
"p", "own", "door is ", "fan is ", "ot", "unning", "topped", "Outside", "Garage", "Air Quality", // 10 - 19
"Inside", "Temperature = ", "Humidity = ", "Solar", "Current = ", "Battery = ", "Barometric Pressure = ", // 20 - 24
"Charging = ", "Previous = ", "level = ", "High = ", "Low = ", "Light = ", "\n\r", " ", // 27 - 34
"Daily = ", ",\t", "29.", "30.", "Status", "Network", "is", "ool", "Environment", " ----------- ", // 35 - 44
};
fld_t flds[fldsNum] = {
//t Month Date Hour Minute // 0 - 3
{"11", 2, 255, 255, 2, 0}, {"06", 2, 255, 255, 0, 0}, {"19", 2, 255, 255, 1, 0}, {"07", 2, 255, 255, 255, 0},
//s Outside Temperature Humidity Solar Current Battery Voltage // 4 - 7
{"063", 3, 17, 21, 6, 0}, {"064", 3, 17, 22, 3, 0}, {"001", 3 , 23, 24, 4, 0}, {"538", 4, 17, 25, 5, 1},
//r Barometric Pressure Charging Voltage Current charge for day Yesterday's charge // 8 - 11
{"006", 3, 26, 37, 7, 0}, {"049", 4, 23, 27, 5, 2}, {"0369", 4, 23, 35, 8, 0}, {"0402", 4, 23, 28, 8, 0},
//n Air Quality Alarm High Reading Low Reading ageing & last // 12 - 15
{"A", 1, 19, 29, 255, 0}, {"09.847", 6, 19, 31, 9, 0}, {"09.066", 6, 19, 30, 9, 0}, {" ", 1, 255, 255, 255, 0},
//z Inside Temperature Inside Light begin heading end heading // 16 - 19
{"0087.8", 6, 20, 21, 6, 0}, {"00265", 5, 20, 32, 255, 0}, {" ", 1, 255, 255, 34, 0}, {" ", 1, 34, 255, 255, 0},
//u Garage Temperature Garage Door Status Garage temp Status Garage Fan Status // 20 - 23
{"078", 3, 18, 21, 6, 0}, {"D", 1, 18, 12, 10, 0}, {"H", 1, 18, 21, 14, 0}, {"S", 1, 18, 13, 15, 0}
};
const uint8_t outputs[] = {
//Environment
133, 144, 143, 144, 133, 4, 136, 16, 133, 8, 136, 5, 133, 17, 136, 20, 133, 13, 136, 14, 133,
// Status
144, 139, 144, 133, 21, 133, 22, 136, 23, 133, 6, 136, 9, 133, 10, 136, 11, 133, 7, 133,
// Time and Date
144, 0, 1, 2, 3, 144, 133,
// Ageing
15
};
bool newMsgFlag;
char keyCode;
char picBuf[buffLen];
uint32_t currMillis;
}
void setup() {
pinMode(greenLED, OUTPUT);
pinMode(blueLED, OUTPUT);
pinMode(sync, INPUT);
pinMode(A4, INPUT);
pinMode(A5, INPUT);
pinMode(btRxd, OUTPUT);
pinMode(btEn, OUTPUT);
pinMode(btTxd, INPUT);
pinMode(btState, INPUT);
digitalWrite(btEn, LOW);
Wire.begin(I2Caddr);
Wire.onReceive(receiveEvent);
attachInterrupt(digitalPinToInterrupt(sync), gotRcvrMsg, RISING);
Serial.begin(9600);
newMsgFlag = false;
delay(10);
currMillis = millis();
for (int i = 0; i < msgNum; i++) {
msgs[i].prevMillis = currMillis;
}
}
void loop() {
char picChar;
byte rxCount;
byte msgInx;
byte fldInx;
byte fldCnt;
byte stoInx;
byte outsInx;
byte titleInx;
uint16_t ageGap;
if (newMsgFlag) {
rxCount = 1;
do {
picChar = picBuf[rxCount++];
Serial.print(picChar);
} while ((picChar != '>') && (rxCount < buffLen));
Serial.println();
newMsgFlag = false;
digitalWrite(blueLED,LOW);
}
delay(10);
}
if (picChar == '<') {
rxCount = 0;
}
if (rxCount == 1) {
keyCode = picChar;
msgInx = getMsgInx(keyCode);
fldCnt = 0;
stoInx = 0;
if (keyCode == 't') {
newMsgFlag = 1;
}
currMillis = millis();
ageGap = (currMillis - msgs[msgInx].prevMillis) / 1000;
msgs[msgInx].age = ageGap / msgs[msgInx].period;
msgs[msgInx].prevMillis = currMillis;
}
if (rxCount > 2) {
fldInx = (4 * msgInx) + fldCnt;
if ((stoInx == flds[fldInx].dp) && (flds[fldInx].dp > 0)) {
flds[fldInx].fldData[stoInx++] = '.';
}
if ((picChar > 44) && (stoInx < flds[fldInx].len)) {
flds[fldInx].fldData[stoInx++] = picChar;
}
if (picChar == 44) {
fldCnt++;
stoInx = 0;
}
}
if (rxCount < 97) {
rxCount++;
}
}
if (newMsgFlag) {
newMsgFlag = false;
digitalWrite(blueLED, LOW);
receiveEvent();
}
editPressure();
editGarageDoor();
editGarageTemp();
editGarageFan();
outsInx = 0;
Serial.write(27); // does not work
Serial.write(51);
Serial.write(74);
do {
if (outputs[outsInx] >= 100) {
titleInx = outputs[outsInx] - 100;
Serial.print(titles[titleInx]);
}
else {
fldInx = outputs[outsInx];
titleInx = flds[fldInx].areaInx;
if (titleInx < 255) {
Serial.print(titles[titleInx]);
Serial.print(' ');
}
titleInx = flds[fldInx].typeInx;
if (titleInx < 255) {
Serial.print(titles[titleInx]);
}
Serial.print(flds[fldInx].fldData);
if (flds[fldInx].len > 1) {
Serial.print(" ");
}
titleInx = flds[fldInx].unitsInx;
if (titleInx < 255) {
Serial.print(titles[titleInx]);
}
}
outsInx++;
delay(1);
} while (outputs[outsInx] != 15);
}
}
byte getMsgInx(char code) {
int inx;
for (inx = 0; inx < msgNum; inx++) {
if (msgs[inx].keyCode == code) break;
}
return (inx);
}
void editPressure(void) {
if (flds[8].fldData[0] > 53) {
flds[8].typeInx = 37;
}
else {
flds[8].typeInx = 38;
}
}
void editGarageDoor(void) {
if (flds[21].fldData[0] == 68) {
flds[21].unitsInx = 11;
}
else {
flds[21].unitsInx = 10;
}
}
void editGarageTemp(void) {
if (flds[22].fldData[0] == 67) {
flds[22].unitsInx = 42;
}
else {
flds[22].unitsInx = 14;
}
}
void editGarageFan(void) {
if (flds[23].fldData[0] == 84) {
flds[23].unitsInx = 15;
}
else {
flds[23].unitsInx = 16;
}
}
void gotRcvrMsg(void) {
digitalWrite(blueLED, HIGH);
//newMsgFlag = true;
}
int num_byte;
void receiveEvent(int rty) {
char rcvChar = 0;
num_byte = Wire.available();
for(int i = 0; i < num_byte; i++) {
rcvChar = Wire.read();
if ((rcvChar > 13) && (rcvChar <= 'z')) {
picBuf[i] = rcvChar;
}
}
newMsgFlag = true;
}