There are four modules, from left to right:
1. A programming adapter from USB to Serial.
2. An Arduino Mini Controller.
3. A Bluetooth transmitterwith a Serial input. See how to use here.
4, A receiver module described separately see button.
It worked, but the bluetooth range was disappointing,
#include <SoftwareSerial.h>
#define fldLenMax 7
#define msgNum 6
#define fldsNum 24
#define picRx 2
#define CTS 4
#define blueLED 5
#define greenLED 6
#define btTxd 12
#define btRxd A0
#define btEn A1
#define btState 13
SoftwareSerial picaxeLink (picRx, CTS);
// SoftwareSerial btLink (btRxd, btTxd);
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 - 26 // 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
};
byte newMsgFlag;
char keyCode;
uint32_t currMillis;
void setup() {
pinMode(picRx, INPUT);
pinMode(CTS, OUTPUT);
pinMode(greenLED, OUTPUT);
pinMode(blueLED, OUTPUT);
pinMode(btRxd, OUTPUT);
pinMode(btEn, OUTPUT);
pinMode(btTxd,INPUT);
pinMode(btState,INPUT);
digitalWrite(CTS, HIGH);
digitalWrite(btEn, LOW);
picaxeLink.begin(19200);
// btLink.begin(9600);
Serial.begin(9600);
newMsgFlag = 0;
delay(10);
currMillis = millis();
for (int i = 0; i < msgNum; i++) {
msgs[i].prevMillis = currMillis;
}
if (picaxeLink.isListening() == true) {
Serial.print("RxPin ");
Serial.print(picRx, DEC);
Serial.println("=OK ");
}
}
void loop() {
char picChar;
byte rxCount;
byte msgInx;
byte fldInx;
byte fldCnt;
byte stoInx;
byte outsInx;
byte titleInx;
uint16_t ageGap;
while (picaxeLink.available() > 0) {
picChar = picaxeLink.read();
digitalWrite(blueLED, HIGH);
digitalWrite(CTS, LOW);
if (picChar == '>') {
digitalWrite(CTS, HIGH);
digitalWrite(blueLED, LOW);
}
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 == 1) {
newMsgFlag = 0;
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);
dispAgeing('t');
dispAgeing('s');
dispAgeing('r');
dispAgeing('n');
dispAgeing('z');
}
}
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 dispAgeing(char code) {
int index = getMsgInx(code);
int age = msgs[index].age;
if (msgs[index].age > 0) {
Serial.print("Message ");
Serial.print(code);
Serial.print(" was last upated ");
Serial.print(age, DEC);
Serial.println(" periods ago");
}
}