View Single Post
Old 01-03-16, 02:23 PM   #19
Acuario
Apprentice EcoRenovator
 
Join Date: May 2011
Location: Tortosa, Spain
Posts: 221
Thanks: 2
Thanked 81 Times in 46 Posts
Default

5. BAC1000.ino
#include <Wire.h>

//For BAC1000 thermometer
#include "BAC1000.h"

NIL_THREAD(threadReadBAC1000, arg) {
while (TRUE) {
{
sendBAC1000Command(READALL, 0, 1, 0, 0, 0, 0);
// Sleep for 30 seconds.
nilThdSleepSeconds(30);
}
}
}

//Reset BAC time every hour
NIL_THREAD(threadSetBACTime, arg) {
while (TRUE) {
{
DEBUG_PRINTLN("Set BAC Time");
sendBAC1000Command(SETTIME, 0, 1, tm.Second, tm.Minute, tm.Hour, 1);
// Sleep for 1 hour
nilThdSleepSeconds(3600);
}
}
}

void setupRS485(void) {

//Setup for RS485
pinMode(RS485TxControl, OUTPUT);
digitalWrite(RS485TxControl, RS485Receive); // Init Transceiver
RS485Serial.begin(2540); // set the data rate
}

//Send command to BAC1000. Retry 5 times
// Command, Device ID low, ID high, Data(4)
bool sendBAC1000Command(int bacCmd, int idl, int idh, int data1, int data2, int data3, int data4) {
int retryCount = 0;
bool result;

//Wait for current read to end before trying to read again
do{
if (rtosStarted == TRUE)
nilThdSleepSeconds(2);
else
delay(2000);
}while (waitRead == TRUE);

waitRead = TRUE;
for (retryCount = 0; retryCount < 2; retryCount++) {
result = sendBAC1000Cmd(bacCmd, idl, idh, data1, data2, data3, data4);
if (result == FALSE)
{
DEBUG_PRINTLN("BAC command fail");
if (rtosStarted == TRUE)
nilThdSleepSeconds(5);
else
delay(5000);
}
else {
DEBUG_PRINTLN("BAC read ok");
break;
}
}
waitRead = FALSE;
return result;
}

bool sendBAC1000Cmd(int bacCmd, int idl, int idh, int data1, int data2, int data3, int data4) {
int byteReceived;
int byteSend;
int i = 0;
char checksum;
char frameRX[8];
char frameTX[7] = { bacCmd, idl, idh, data1, data2, data3, data4 };
//char frame[7] = { 0xA8, 0, 1, 0, 0x0, 9, 1 };

DEBUG_PRINTLN("Send BAC command frame");

digitalWrite(RS485TxControl, RS485Transmit); // Enable RS485 Transmit
for (int i = 0; i < 7; i++) {
RS485Serial.write(frameTX[i]); // Send bytes to thermostat
}

RS485Serial.write(bac1000Checksum(frameTX)); // Send byte to Remote
RS485Serial.flush(); //Wait for end of send before disabling RS485
digitalWrite(RS485TxControl, RS485Receive); // Disable RS485 Transmit

while (RS485Serial.available()) //Look for data
{
byteReceived = RS485Serial.read(); // Read received byte
frameRX[i] = byteReceived;
i++;
//Serial.print(byteReceived); // Show on Serial Monitor
//Serial.print(" ");
}

if (frameRX[0] == DATAACK) { //Data received ok
switch (bacCmd) {
case READALL:
char buf[20];
char checksum1;
checksum = frameRX[7];
frameRX[7] = '\0';
checksum1 = bac1000Checksum(frameRX);
if (checksum1 != checksum) {
//sprintf(buf, " Frame=%x %x %x %x %x %x %x %x", frameRX[0], frameRX[1], frameRX[2], frameRX[3], frameRX[4], frameRX[5], frameRX[6], frameRX[7]);
//Serial.println(buf);
//sprintf(buf, " o=%x n=%x", checksum, checksum1);
DEBUG_PRINTLN("BAC CS Failure");
//Serial.println(buf);
return FALSE;
}
bacRoomTemp = frameRX[6];
bacSetTemp = frameRX[5] / 2;
desiredRoomTemp = bacSetTemp;

//Read and update BAC power state if necessary
powerStateBAC = frameRX[3] & UNITONOFF;
if(operatingState != powerStateBAC){
operatingState = powerStateBAC;
EEPROM_write_byte(LASTSYSTEMSTATE, operatingState);
}

//Read and update operating mode if necessary
operatingModeBAC = (frameRX[3] & HEATCOOL) >> 5;
if (operatingMode != operatingModeBAC) {
operatingMode = operatingModeBAC;
EEPROM_write_byte(LASTSYSTEMMODE, operatingMode);
}

BACRead = TRUE; //Flag the BAC has been successfully read
//char buf[20];
//sprintf(buf, "Room temp: %d", frameRX[6]);
//Serial.println(buf);
//sprintf(buf, "Set temp: %d", frameRX[5] / 2);
//Serial.println(buf);
//sprintf(buf, "Thermometer power: %s", powerStateBAC == 0 ? "Off" : "On");
//Serial.println(buf);
//sprintf(buf, "Mode: %s", mode[operatingModeBAC]);
//Serial.println(buf);
break;
}
return TRUE;
}
else
{
return FALSE;
}
}

//CheckSum = (COMMAND + ID0 + ID1 + Data0 + Data1 + Data2 + Data3) & 0xFF ^ 0xA5;
unsigned char bac1000Checksum(char *ptr) {
unsigned char chk = 0;

for (int i = 0; i < 7; i++) {
chk += ptr[i];
}
chk = chk & 0xff;
chk = chk ^ 0xa5;
return chk;
}
Acuario is offline   Reply With Quote