Cloud Wifi Hub compile error
Posted: Mon Feb 05, 2018 8:29 pm
I'm starting the initial setup of my Cloud Wifi hub using the Wizard.
I'm getting the following error when trying to compile the generated code:
---------
Compiling code for RA_CLOUD board
Extra Temperature Probes
D:\Arduino\libraries\PubSubClient\PubSubClient.cpp:9:21: fatal error: avr/wdt.h: No such file or directory
#include
^
compilation terminated.
exit status 1
Progress: 55.17%
Your code has some errors and couldn't be compiled.
Please fix the errors above and try again.
--------
Wizard generated code:
What am I doing wrong?
I'm getting the following error when trying to compile the generated code:
---------
Compiling code for RA_CLOUD board
Extra Temperature Probes
D:\Arduino\libraries\PubSubClient\PubSubClient.cpp:9:21: fatal error: avr/wdt.h: No such file or directory
#include
^
compilation terminated.
exit status 1
Progress: 55.17%
Your code has some errors and couldn't be compiled.
Please fix the errors above and try again.
--------
Wizard generated code:
Code: Select all
#include <Wire.h>
#include <SPI.h>
#include <WiFi101.h>
#include <PubSubClient.h>
#include <RA_CustomSettings.h>
#include <CloudGlobals.h>
#include <OneWire.h>
// ***********************************************************************
// Change fallback ports below
// Fallback ports will be turned on when cloud connection is lost
// Add each port separated by a |
// For example, if you would like for port 1 and port 5 of Relay Box 1 to be turned on when cloud connection is lost,
// you should add Port1Bit | Port5Bit
// It would look like this:
// #define Relay1FallBack Port1Bit | Port5Bit
#define Relay1FallBack 0
#define Relay2FallBack 0
#define Relay3FallBack 0
#define Relay4FallBack 0
#define Relay5FallBack 0
#define Relay6FallBack 0
#define Relay7FallBack 0
#define Relay8FallBack 0
// Redirect expansion modules to another custom expansion field.
// This is only required if you have multiple modules of the same parameter.
// For example, if you have one Cloud module with an existing salinity module already and wants to add another Cloud module
// with anoter salinity module and report those readings as a Custom Expansion Module 1
// In this case you have to change the CloudCustomModule1 to CUSTOM_SALINITY.
// The values that can be entered are:
// CUSTOM_NONE 0
// CUSTOM_SALINITY 1
// CUSTOM_ORP 2
// CUSTOM_PHEXP 3
// CUSTOM_WL 4
// CUSTOM_MULTI_WL1 5
// CUSTOM_MULTI_WL2 6
// CUSTOM_MULTI_WL3 7
// CUSTOM_MULTI_WL4 8
#define CloudCustomModule1 CUSTOM_NONE
#define CloudCustomModule2 CUSTOM_NONE
#define CloudCustomModule3 CUSTOM_NONE
#define CloudCustomModule4 CUSTOM_NONE
#define CloudCustomModule5 CUSTOM_NONE
#define CloudCustomModule6 CUSTOM_NONE
#define CloudCustomModule7 CUSTOM_NONE
#define CloudCustomModule8 CUSTOM_NONE
// Assign Temperature probes ID
// Only assign temperature probes IDs that you currently are not using in the head unit.
// If you have a total of more than 3 probes, make sure to add the following line on the setup section of the head unit code:
// ReefAngel.AddExtraTempProbes();
// For example, if you only have 1 probe connected to the head unit, assign IDs 2 and 3.
// If you have 2 probes in the head unit and 2 probes in the Cloud Wifi Hub, you must add the above line and you would assign
// IDs 3 and 4.
// Assign ID 0 to unused probes in the Hub.
byte TempProbeIDs[] = {2, 0};
// Do not change anything below
// ***********************************************************************
#define LED_GREEN 7
#define LED_BLUE 6
#define LED_RED 0
#define TempPin 5
unsigned long wifi_connection = millis();
int status = WL_IDLE_STATUS;
byte data[2];
byte data2[12];
byte addr[8];
byte addr1[8];
byte addr2[8];
OneWire ds(TempPin);
void MQTTSubCallback(char* topic, byte* payload, unsigned int length);
PubSubClient MQTTClient(MQTTServer, MQTTPORT, MQTTSubCallback, mqttclient);
void setup()
{
pinMode(LED_GREEN, OUTPUT);
pinMode(LED_BLUE, OUTPUT);
pinMode(LED_RED, OUTPUT);
digitalWrite(LED_GREEN, HIGH);
digitalWrite(LED_BLUE, LOW);
digitalWrite(LED_RED, LOW);
wdt_initialize();
wdt_enable();
randomSeed(analogRead(0));
Serial.begin(57600);
Serial.setTimeout(100);
delay(1500);
Serial.println("Init");
Wire.begin();
FoundIP = false;
MQTTReconnectmillis = millis();
MQTTSendmillis = millis();
SalinityFound = false;
ORPFound = false;
PHExpFound = false;
WLFound = false;
MultiWLFound = false;
HumidityFound = false;
sprintf(pub_salinity, "sal");
sprintf(pub_orp, "orp");
sprintf(pub_phexp, "phe");
sprintf(pub_wl, "wl");
sprintf(pub_multiwl, "wl");
sprintf(pub_humidity, "hum");
// Temperature
byte count = 0;
while (ds.search(addr))
{
if (addr[0] == 0x28)
{
count++;
if (count == 1) memcpy(addr1, addr, 8);
if (count == 2) memcpy(addr2, addr, 8);
}
}
ds.reset_search();
Serial.print(count);
Serial.println(" temperature probe(s) found");
// Relay
for ( byte EID = 0; EID < MAX_RELAY_EXPANSION_MODULES; EID++ )
{
RelayDataE[EID] = 0;
RelayMaskOnE[EID] = 0;
RelayMaskOffE[EID] = 0xff;
}
RelayFallBackE[0] = Relay1FallBack;
RelayFallBackE[1] = Relay2FallBack;
RelayFallBackE[2] = Relay3FallBack;
RelayFallBackE[3] = Relay4FallBack;
RelayFallBackE[4] = Relay5FallBack;
RelayFallBackE[5] = Relay6FallBack;
RelayFallBackE[6] = Relay7FallBack;
RelayFallBackE[7] = Relay8FallBack;
// Dimming
lastcrc = -1;
for ( byte a = 0; a < PWM_EXPANSION_CHANNELS; a++ )
{
ExpansionChannel[a] = 0;
ExpansionChannelOverride[a] = 255;
}
// IO
Params.IO = 63;
OldParams.IO = 63;
// Leak
Params.Leak = 0;
OldParams.Leak = 0;
// ORP
Params.ORP = 0;
OldParams.ORP = 0;
ORPCal = false;
ORPMin = memory_read_int(Mem_I_ORPMin);
if (ORPMin==65535) ORPMin=0;
ORPMax = memory_read_int(Mem_I_ORPMax);
// Salinity
Params.Salinity = 0;
OldParams.Salinity = 0;
SalCal = false;
SalMax = memory_read_int(Mem_I_SalMax);
// pH Exp
Params.PHExp = 0;
OldParams.PHExp = 0;
PHExpCal = false;
PHExpMin = memory_read_int(Mem_I_PHExpMin);
if (PHExpMin==65535) PHExpMin=0;
PHExpMax = memory_read_int(Mem_I_PHExpMax);
// Humidity
Params.Humidity = 0;
OldParams.Humidity = 0;
// Water Level
for (int a = 0; a < WL_CHANNELS; a++)
{
Params.WL[a] = 0;
OldParams.WL[a] = 0;
WLCal[a] = false;
}
WLMin[0] = memory_read_int(Mem_I_WaterLevelMin);
WLMax[0] = memory_read_int(Mem_I_WaterLevelMax);
WLMin[1] = memory_read_int(Mem_I_WaterLevel1Min);
WLMax[1] = memory_read_int(Mem_I_WaterLevel1Max);
WLMin[2] = memory_read_int(Mem_I_WaterLevel2Min);
WLMax[2] = memory_read_int(Mem_I_WaterLevel2Max);
WLMin[3] = memory_read_int(Mem_I_WaterLevel3Min);
WLMax[3] = memory_read_int(Mem_I_WaterLevel3Max);
WLMin[4] = memory_read_int(Mem_I_WaterLevel4Min);
WLMax[4] = memory_read_int(Mem_I_WaterLevel4Max);
for (int a=0; a<5; a++)
{
if (WLMin[a]==65535) WLMin[a]=0;
}
ApplyCalibration(1, CloudCustomModule1);
ApplyCalibration(2, CloudCustomModule2);
ApplyCalibration(3, CloudCustomModule3);
ApplyCalibration(4, CloudCustomModule4);
ApplyCalibration(5, CloudCustomModule5);
ApplyCalibration(6, CloudCustomModule6);
ApplyCalibration(7, CloudCustomModule7);
ApplyCalibration(8, CloudCustomModule8);
sprintf(clientid, "%s%02d", CLOUD_USERNAME, random(10000));
sprintf(pub_buffer, "%s/in", CLOUD_USERNAME);
sprintf(sub_buffer, "%s/out/#", CLOUD_USERNAME);
Serial.println("Start");
}
void loop()
{
wdt_reset();
status = WiFi.status();
while ( status != WL_CONNECTED) {
digitalWrite(LED_BLUE, LOW);
if (millis() - wifi_connection > 1000)
{
wifi_connection = millis();
Serial.print("Attempting to connect to Network named: ");
Serial.println(WIFI_SSID); // print the network name (SSID);
if (WiFi.begin(WIFI_SSID, WIFI_PASS) == WL_CONNECTED)
{
status = WiFi.status();
server.begin(); // start the web server on port 2000
printWifiStatus(); // you're connected now, so print out the status
digitalWrite(LED_BLUE, HIGH);
}
}
}
MQTTClient.loop();
if (millis() - MQTTReconnectmillis > 5000)
{
MQTTReconnectmillis = millis();
if (!MQTTClient.connected())
{
digitalWrite(LED_RED, LOW);
Serial.println(F("MQTT Connecting..."));
wdt_reset();
if (MQTTClient.connect(clientid, CLOUD_USERNAME, CLOUD_PASSWORD))
{
Serial.println(F("MQTT succeeded"));
digitalWrite(LED_RED, HIGH);
MQTTClient.subscribe(sub_buffer);
Publish(pub_buffer, "all:0");
wdt_reset();
}
else
{
Serial.println(F("MQTT failed"));
MQTTClient.disconnect();
}
}
}
// Relay
for ( byte EID = 0; EID < MAX_RELAY_EXPANSION_MODULES; EID++ )
{
byte TempRelay = RelayDataE[EID];
TempRelay &= RelayMaskOffE[EID];
TempRelay |= RelayMaskOnE[EID];
if (!MQTTClient.connected())
TempRelay = RelayFallBackE[EID];
Wire.beginTransmission(I2CExpModule + EID);
Wire.write(~TempRelay); // MSB
Wire.endTransmission();
}
// Dimming
byte thiscrc = 0;
for ( byte a = 0; a < PWM_EXPANSION_CHANNELS; a++ )
{
thiscrc += ExpansionChannel[a] * (a + 1);
thiscrc += ExpansionChannelOverride[a] * (a + 1);
}
if (millis() % 60000 < 200) lastcrc = -1;
if (lastcrc != thiscrc || millis() < 5000)
{
lastcrc = thiscrc;
// setup PCA9685 for data receive
// we need this to make sure it will work if connected ofter controller is booted, so we need to send it all the time.
Wire.beginTransmission(I2CPWM_PCA9685);
Wire.write((uint8_t)0);
Wire.write(0xa1);
Wire.endTransmission();
for ( byte a = 0; a < PWM_EXPANSION_CHANNELS; a++ )
{
int data;
if (ExpansionChannelOverride[a] <= 100)
data = ExpansionChannelOverride[a] * 40.96;
else
data = ExpansionChannel[a] * 40.96;
Wire.beginTransmission(I2CPWM_PCA9685);
Wire.write(0x8 + (4 * a));
Wire.write(data & 0xff);
Wire.write(data >> 8);
Wire.endTransmission();
}
}
if (MQTTClient.connected())
{
digitalWrite(LED_RED, HIGH);
// IO
Wire.requestFrom(I2CIO_PCF8574, 1);
if (Wire.available())
Params.IO = Wire.read();
if (Params.IO != OldParams.IO)
{
OldParams.IO = Params.IO;
sprintf(buffer, "io:%d", Params.IO);
Publish(pub_buffer, buffer);
}
// Leak
int iLeak = 0;
Wire.requestFrom(I2CLeak, 2);
if (Wire.available())
{
iLeak = Wire.read();
iLeak = iLeak << 8;
iLeak += Wire.read();
Params.Leak = iLeak > 2000;
}
if (Params.Leak != OldParams.Leak)
{
OldParams.Leak = Params.Leak;
sprintf(buffer, "leak:%d", Params.Leak);
Publish(pub_buffer, buffer);
}
if (millis() - Paramsmillis > 1000)
{
Paramsmillis = millis();
// Temperature
if (addr1[0] != 0)
{
ds.reset();
ds.select(addr1);
ds.write(0xBE); // Read Scratchpad
for (byte i = 0; i < 2; i++)
{
data[i] = ds.read();
}
Params.Temp[1] = (data[1] << 8) + data[0]; //take the two bytes from the response relating to temperature
Params.Temp[1] = Params.Temp[1] / 1.6;
if (Params.Temp[1] == 0) Params.Temp[1] = 0;
if (Params.Temp[1] > 850) Params.Temp[1] = 0;
Params.Temp[1] = Params.Temp[1] * 1.8 + 320;
if (Params.Temp[1] != OldParams.Temp[1])
{
OldParams.Temp[1] = Params.Temp[1];
sprintf(buffer, "t:%d:%d",TempProbeIDs[0], Params.Temp[1]);
if (TempProbeIDs[0]!=0) Publish(pub_buffer, buffer);
}
}
if (addr2[0] != 0)
{
ds.reset();
ds.select(addr2);
ds.write(0xBE); // Read Scratchpad
for (byte i = 0; i < 2; i++)
{
data[i] = ds.read();
}
Params.Temp[2] = (data[1] << 8) + data[0]; //take the two bytes from the response relating to temperature
Params.Temp[2] = Params.Temp[2] / 1.6;
if (Params.Temp[2] == 0) Params.Temp[2] = 0;
if (Params.Temp[2] > 850) Params.Temp[2] = 0;
Params.Temp[2] = Params.Temp[2] * 1.8 + 320;
if (Params.Temp[2] != OldParams.Temp[2])
{
OldParams.Temp[2] = Params.Temp[2];
sprintf(buffer, "t:%d:%d",TempProbeIDs[1], Params.Temp[2]);
if (TempProbeIDs[1]!=0) Publish(pub_buffer, buffer);
}
}
// ORP
unsigned long temporp = 0;
int iORP = 0;
for (int a = 0; a < 20; a++)
{
Wire.requestFrom(I2CORP, 2);
if (Wire.available())
{
iORP = Wire.read();
iORP = iORP << 8;
iORP += Wire.read();
}
temporp += iORP;
}
temporp = temporp / 20;
if (temporp != 0)
{
Params.ORP = map(temporp, ORPMin, ORPMax, 0, 470); // apply the calibration to the sensor reading
Params.ORP = constrain(Params.ORP, 0, 550);
if (pub_orp[0] == 'o') ORPFound = true;
}
if (ORPCal)
{
sprintf(buffer, "%sc:%d", pub_orp, temporp);
Publish(pub_buffer, buffer);
}
else
{
if (Params.ORP != OldParams.ORP)
{
OldParams.ORP = Params.ORP;
sprintf(buffer, "%s:%d", pub_orp, Params.ORP);
Publish(pub_buffer, buffer);
}
}
// Salinity
unsigned long tempsal = 0;
int iSAL = 0;
for (int a = 0; a < 20; a++)
{
Wire.requestFrom(I2CSalinity, 2);
if (Wire.available())
{
iSAL = Wire.read();
iSAL = iSAL << 8;
iSAL += Wire.read();
}
tempsal += iSAL;
}
tempsal = tempsal / 20;
if (tempsal != 0)
{
Params.Salinity = map(tempsal, 0, SalMax, 60, 350); // apply the calibration to the sensor reading
if (pub_salinity[0] == 's') SalinityFound = true;
}
if (SalCal)
{
sprintf(buffer, "%sc:%d", pub_salinity, tempsal);
Publish(pub_buffer, buffer);
}
else
{
if (Params.Salinity != OldParams.Salinity)
{
OldParams.Salinity = Params.Salinity;
sprintf(buffer, "%s:%d", pub_salinity, Params.Salinity);
Publish(pub_buffer, buffer);
}
}
// pH Exp
unsigned long tempphexp = 0;
int iPHExp = 0;
for (int a = 0; a < 20; a++)
{
Wire.requestFrom(I2CPH, 2);
if (Wire.available())
{
iPHExp = Wire.read();
iPHExp = iPHExp << 8;
iPHExp += Wire.read();
}
tempphexp += iPHExp;
}
tempphexp = tempphexp / 20;
if (tempphexp != 0)
{
Params.PHExp = map(tempphexp, PHExpMin, PHExpMax, 700, 1000); // apply the calibration to the sensor reading
Params.PHExp = constrain(Params.PHExp, 100, 1400);
if (pub_phexp[0] == 'p') PHExpFound = true;
}
if (PHExpCal)
{
sprintf(buffer, "%sc:%d", pub_phexp, tempphexp);
Publish(pub_buffer, buffer);
}
else
{
if (Params.PHExp != OldParams.PHExp)
{
OldParams.PHExp = Params.PHExp;
sprintf(buffer, "%s:%d", pub_phexp, Params.PHExp);
Publish(pub_buffer, buffer);
}
}
// PAR
unsigned long temppar = 0;
int iPAR = 0;
for (int a = 0; a < 20; a++)
{
Wire.requestFrom(I2CPAR, 2);
if (Wire.available())
{
iPAR = Wire.read();
iPAR = iPAR << 8;
iPAR += Wire.read();
}
temppar += iPAR;
}
temppar = temppar / 20;
if (temppar != 0)
{
temppar *= 5000; // apply the calibration to the sensor reading
temppar /= 8192;
Params.PAR = temppar;
}
if (Params.PAR != OldParams.PAR)
{
OldParams.PAR = Params.PAR;
sprintf(buffer, "par:%d", Params.PAR);
Publish(pub_buffer, buffer);
}
// Humidity
int iHumidity = 0;
int reply[10];
Wire.beginTransmission(I2CHumidity);
Wire.endTransmission(); // For some reason, it needs this to work??? Bug with sensor??
Wire.beginTransmission(I2CHumidity);
Wire.write(0x3); // 0x3 for read 0x10 for write to registers
Wire.write((byte)0x0); // start at address 0x0 for humidity
Wire.write(2); // request 2 bytes data for humidity or 4 bytes for temperature+humidity
Wire.endTransmission();
Wire.requestFrom(I2CHumidity, 6); // Request 6 bytes
for (int i=0;i<6;i++)
if(Wire.available()) reply[i] = Wire.read();
if (reply[0]==0x3 && reply[1]==0x2) // The response need to contain function (0x3) and length of data (0x2)
{
int crc=reply[5];
crc<<=8;
crc+=reply[4];
if (crc == crc16(reply,4))
{
iHumidity=reply[2];
iHumidity<<=8;
iHumidity+=reply[3];
}
}
Params.Humidity=iHumidity;
if (Params.Humidity != OldParams.Humidity)
{
OldParams.Humidity = Params.Humidity;
sprintf(buffer, "hum:%d", Params.Humidity);
Publish(pub_buffer, buffer);
}
// Water Level
for (int i = 0; i < WL_CHANNELS; i++)
{
unsigned long tempwl = 0;
int iWL = 0;
for (int a = 0; a < 20; a++)
{
if (i == 0)
{
Wire.requestFrom(I2CWaterLevel, 2);
if (Wire.available())
{
iWL = Wire.read();
iWL = iWL << 8;
iWL += Wire.read();
}
tempwl += iWL;
if (tempwl != 0 && pub_wl[0] == 'w') WLFound = true;
}
else
{
Wire.beginTransmission(I2CMultiWaterLevel);
Wire.write(1); // Config Pointer
byte addr = (0xb + i) << 4; // Select which channel to read
addr += 0x03; // Programmable Gain
Wire.write(addr);
Wire.write(0x83);
Wire.endTransmission();
delay(10); // It takes 10ms for conversion to be completed
Wire.beginTransmission(I2CMultiWaterLevel);
Wire.write((uint8_t)0); // Convert Pointer
Wire.endTransmission();
Wire.requestFrom(I2CMultiWaterLevel, 2); // Request converted value
if (Wire.available())
{
iWL = Wire.read();
iWL = iWL << 8;
iWL += Wire.read();
}
tempwl += iWL >> 4;
if (tempwl != 0 && pub_multiwl[0] == 'w') MultiWLFound = true;
}
}
tempwl = tempwl / 20;
if (tempwl != 0)
{
Params.WL[i] = map(tempwl, WLMin[i], WLMax[i], 0, 100); // apply the calibration to the sensor reading
Params.WL[i] = constrain(Params.WL[i], 0, 255);
}
if (WLCal[i])
{
if (i == 0)
{
if (pub_wl[0] == 'c')
sprintf(buffer, "%s%d", pub_custom_wl, tempwl);
else
sprintf(buffer, "%sc:%d", pub_wl, tempwl);
}
else
{
if (pub_multiwl[0] == 'c')
sprintf(buffer, "%s%d", pub_custom_multiwl, tempwl);
else
sprintf(buffer, "%sc:%d", pub_multiwl, tempwl);
}
Publish(pub_buffer, buffer);
}
else
{
if (Params.WL[i] != OldParams.WL[i])
{
OldParams.WL[i] = Params.WL[i];
if (i == 0)
{
if (pub_wl[0] == 'c')
sprintf(buffer, "%s%d", pub_wl, Params.WL[i]);
else
sprintf(buffer, "%s:%d:%d", pub_wl, i, Params.WL[i]);
}
else
{
if (pub_multiwl[0] == 'c')
sprintf(buffer, "%s%d", pub_multiwl, Params.WL[i]);
else
sprintf(buffer, "%s:%d:%d", pub_multiwl, i, Params.WL[i]);
}
Publish(pub_buffer, buffer);
}
}
}
ds.reset();
ds.select(addr1);
ds.write(0x44, 0);
ds.reset();
ds.select(addr2);
ds.write(0x44, 0);
}
}
}
void MQTTSubCallback(char* topic, byte* payload, unsigned int length) {
boolean data_found = false;
int payload_data = 0;
byte data_index = 0;
if (payload[0] == 'R' && payload[1] == 'O' && payload[2] == 'F' && payload[3] == 'F' && payload[5] == ':')
{
data_found = true;
data_index = payload[4] - '0' - 1;
for (byte a = 6; a < length; a++)
{
if (payload[a] != 10 && payload[a] != 13)
{
payload_data *= 10;
payload_data += payload[a] - '0';
}
}
RelayMaskOffE[data_index] = payload_data;
}
else if (payload[0] == 'R' && payload[1] == 'O' && payload[2] == 'N' && payload[4] == ':')
{
data_found = true;
data_index = payload[3] - '0' - 1;
for (byte a = 5; a < length; a++)
{
if (payload[a] != 10 && payload[a] != 13)
{
payload_data *= 10;
payload_data += payload[a] - '0';
}
}
RelayMaskOnE[data_index] = payload_data;
}
else if (payload[0] == 'R' && payload[2] == ':')
{
data_found = true;
data_index = payload[1] - '0' - 1;
for (byte a = 3; a < length; a++)
{
if (payload[a] != 10 && payload[a] != 13)
{
payload_data *= 10;
payload_data += payload[a] - '0';
}
}
RelayDataE[data_index] = payload_data;
}
else if (payload[0] == 'P' && payload[1] == 'W' && payload[2] == 'M' && payload[3] == 'E' && payload[5] == ':')
{
data_found = true;
data_index = payload[4] - '0';
for (byte a = 6; a < length; a++)
{
if (payload[a] != 10 && payload[a] != 13)
{
payload_data *= 10;
payload_data += payload[a] - '0';
}
}
ExpansionChannel[data_index] = payload_data;
}
else if (payload[0] == 'P' && payload[1] == 'W' && payload[2] == 'M' && payload[3] == 'E' && payload[5] == 'O' && payload[6] == ':')
{
data_found = true;
data_index = payload[4] - '0';
for (byte a = 7; a < length; a++)
{
if (payload[a] != 10 && payload[a] != 13)
{
payload_data *= 10;
payload_data += payload[a] - '0';
}
}
ExpansionChannelOverride[data_index] = payload_data;
}
else if (payload[0] == 'O' && payload[1] == 'R' && payload[2] == 'P' && payload[3] == 'C' && payload[4] == ':' && ORPFound)
{
Serial.println(F("ORP calibration"));
data_found = true;
if (payload[5] == '0')
ORPCal = false;
else if (payload[5] == '1')
ORPCal = true;
else if (payload[5] == '2')
{
for (byte a = 7; a < length; a++)
{
if (payload[a] != 10 && payload[a] != 13)
{
payload_data *= 10;
payload_data += payload[a] - '0';
}
}
CalVal1 = payload_data;
}
else if (payload[5] == '3')
{
for (byte a = 7; a < length; a++)
{
if (payload[a] != 10 && payload[a] != 13)
{
payload_data *= 10;
payload_data += payload[a] - '0';
}
}
memory_write_int(Mem_I_ORPMin, CalVal1);
memory_write_int(Mem_I_ORPMax, payload_data);
ORPMin = CalVal1;
ORPMax = payload_data;
ORPCal = false;
}
}
else if (payload[0] == 'S' && payload[1] == 'A' && payload[2] == 'L' && payload[3] == 'C' && payload[4] == ':' && SalinityFound)
{
Serial.println(F("Sal calibration"));
data_found = true;
if (payload[5] == '0')
SalCal = false;
else if (payload[5] == '1')
SalCal = true;
else if (payload[5] == '2')
{
for (byte a = 7; a < length; a++)
{
if (payload[a] != 10 && payload[a] != 13)
{
payload_data *= 10;
payload_data += payload[a] - '0';
}
}
memory_write_int(Mem_I_SalMax, payload_data);
SalMax = payload_data;
SalCal = false;
}
}
else if (payload[0] == 'P' && payload[1] == 'H' && payload[2] == 'E' && payload[3] == 'C' && payload[4] == ':' && PHExpFound)
{
Serial.println(F("PH Exp calibration"));
data_found = true;
if (payload[5] == '0')
PHExpCal = false;
else if (payload[5] == '1')
PHExpCal = true;
else if (payload[5] == '2')
{
for (byte a = 7; a < length; a++)
{
if (payload[a] != 10 && payload[a] != 13)
{
payload_data *= 10;
payload_data += payload[a] - '0';
}
}
CalVal1 = payload_data;
}
else if (payload[5] == '3')
{
for (byte a = 7; a < length; a++)
{
if (payload[a] != 10 && payload[a] != 13)
{
payload_data *= 10;
payload_data += payload[a] - '0';
}
}
memory_write_int(Mem_I_PHExpMin, CalVal1);
memory_write_int(Mem_I_PHExpMax, payload_data);
PHExpMin = CalVal1;
PHExpMax = payload_data;
PHExpCal = false;
}
}
else if (payload[0] == 'W' && payload[1] == 'L' && payload[3] == 'C' && payload[4] == ':' && (WLFound || MultiWLFound))
{
Serial.println(F("WL calibration"));
data_found = true;
data_index = payload[2] - '0';
if (payload[5] == '0')
WLCal[data_index] = false;
else if (payload[5] == '1')
{
if (data_index == 0 && WLFound)
WLCal[data_index] = true;
if (data_index > 0 && MultiWLFound)
WLCal[data_index] = true;
}
else if (payload[5] == '2')
{
for (byte a = 7; a < length; a++)
{
if (payload[a] != 10 && payload[a] != 13)
{
payload_data *= 10;
payload_data += payload[a] - '0';
}
}
CalVal1 = payload_data;
}
else if (payload[5] == '3')
{
for (byte a = 7; a < length; a++)
{
if (payload[a] != 10 && payload[a] != 13)
{
payload_data *= 10;
payload_data += payload[a] - '0';
}
}
if (data_index == 0)
{
memory_write_int(Mem_I_WaterLevelMin, CalVal1);
memory_write_int(Mem_I_WaterLevelMax, payload_data);
}
if (data_index > 0 && data_index < 5)
{
memory_write_int(Mem_I_WaterLevel1Min + (data_index * 2) - 2, CalVal1);
memory_write_int(Mem_I_WaterLevel1Max + (data_index * 2) - 2, payload_data);
}
WLMin[data_index] = CalVal1;
WLMax[data_index] = payload_data;
WLCal[data_index] = false;
}
}
else if (payload[0] == 'C' && payload[1] == 'E' && payload[2] == 'X' && payload[3] == 'P' && payload[5] == 'C' && payload[6] == ':')
{
Serial.println(F("Custom Exp calibration"));
data_found = true;
data_index = payload[4] - '0';
if (payload[7] == '0')
{
if (pub_salinity[0] == 'c' && CustomExpansion[data_index] == CUSTOM_SALINITY) SalCal = false;
if (pub_orp[0] == 'c' && CustomExpansion[data_index] == CUSTOM_ORP) ORPCal = false;
if (pub_phexp[0] == 'c' && CustomExpansion[data_index] == CUSTOM_PHEXP) PHExpCal = false;
if (pub_wl[0] == 'c' && CustomExpansion[data_index] == CUSTOM_WL) WLCal[0] = false;
for (int a = 1; a < WL_CHANNELS; a++)
if (pub_multiwl[0] == 'c' && CustomExpansion[data_index] >= CUSTOM_MULTI_WL1 && CustomExpansion[data_index] <= CUSTOM_MULTI_WL4) WLCal[a] = false;
}
else if (payload[7] == '1')
{
if (pub_salinity[0] == 'c' && CustomExpansion[data_index] == CUSTOM_SALINITY) SalCal = true;
if (pub_orp[0] == 'c' && CustomExpansion[data_index] == CUSTOM_ORP) ORPCal = true;
if (pub_phexp[0] == 'c' && CustomExpansion[data_index] == CUSTOM_PHEXP) PHExpCal = true;
if (pub_wl[0] == 'c' && CustomExpansion[data_index] == CUSTOM_WL) WLCal[0] = true;
if (pub_multiwl[0] == 'c' && CustomExpansion[data_index] == CUSTOM_MULTI_WL1) WLCal[1] = true;
if (pub_multiwl[0] == 'c' && CustomExpansion[data_index] == CUSTOM_MULTI_WL2) WLCal[2] = true;
if (pub_multiwl[0] == 'c' && CustomExpansion[data_index] == CUSTOM_MULTI_WL3) WLCal[3] = true;
if (pub_multiwl[0] == 'c' && CustomExpansion[data_index] == CUSTOM_MULTI_WL4) WLCal[4] = true;
}
else if (payload[7] == '2')
{
for (byte a = 9; a < length; a++)
{
payload_data *= 10;
payload_data += payload[a] - '0';
}
CalVal1 = payload_data;
}
else if (payload[7] == '3')
{
for (byte a = 9; a < length; a++)
{
payload_data *= 10;
payload_data += payload[a] - '0';
}
if (pub_salinity[0] == 'c')
{
memory_write_int(Mem_I_SalMax, payload_data);
SalMax = payload_data;
SalCal = false;
}
if (pub_orp[0] == 'c')
{
memory_write_int(Mem_I_ORPMin, CalVal1);
memory_write_int(Mem_I_ORPMax, payload_data);
ORPMin = CalVal1;
ORPMax = payload_data;
ORPCal = false;
}
if (pub_phexp[0] == 'c')
{
memory_write_int(Mem_I_PHExpMin, CalVal1);
memory_write_int(Mem_I_PHExpMax, payload_data);
PHExpMin = CalVal1;
PHExpMax = payload_data;
PHExpCal = false;
}
if (pub_wl[0] == 'c')
{
memory_write_int(Mem_I_WaterLevelMin, CalVal1);
memory_write_int(Mem_I_WaterLevelMax, payload_data);
WLMin[0] = CalVal1;
WLMax[0] = payload_data;
WLCal[0] = false;
}
for (int a = 1; a < WL_CHANNELS; a++)
if (pub_multiwl[0] == 'c' && WLCal[a] == true)
{
memory_write_int(Mem_I_WaterLevel1Min + (a * 2) - 2, CalVal1);
memory_write_int(Mem_I_WaterLevel1Max + (a * 2) - 2, payload_data);
WLMin[a] = CalVal1;
WLMax[a] = payload_data;
WLCal[a] = false;
}
}
}
if (data_found)
{
blink_data_led(30);
for (int a = 0; a < length; a++)
Serial.write(payload[a]);
Serial.println();
}
}
const char* ip_to_str(const uint8_t* ipAddr)
{
static char buf[16];
sprintf(buf, "%d.%d.%d.%d", ipAddr[0], ipAddr[1], ipAddr[2], ipAddr[3]);
return buf;
}
void ApplyCalibration(byte module, byte type)
{
CustomExpansion[module - 1] = type;
switch (type)
{
case CUSTOM_SALINITY:
sprintf(pub_salinity, "cexp:%d:", module - 1);
break;
case CUSTOM_ORP:
sprintf(pub_orp, "cexp:%d:", module - 1);
break;
case CUSTOM_PHEXP:
sprintf(pub_phexp, "cexp:%d:", module - 1);
break;
case CUSTOM_WL:
sprintf(pub_wl, "cexp:%d:", module - 1);
sprintf(pub_custom_wl, "cexpc:%d:", module - 1);
break;
case CUSTOM_MULTI_WL1:
case CUSTOM_MULTI_WL2:
case CUSTOM_MULTI_WL3:
case CUSTOM_MULTI_WL4:
sprintf(pub_multiwl, "cexp:%d:", module - 1);
sprintf(pub_custom_multiwl, "cexpc:%d:", module - 1);
break;
case CUSTOM_NONE:
break;
}
}
void blink_data_led(byte timer)
{
digitalWrite(LED_RED, LOW);
delay(timer);
digitalWrite(LED_RED, HIGH);
}
void Publish(char* pub_buffer, char* buffer)
{
MQTTClient.publish(pub_buffer, buffer);
Serial.println(buffer);
blink_data_led(50);
}
byte memory_read_byte(int address)
{
byte rdata = 0xFF;
Wire.beginTransmission(I2CEEPROM1);
Wire.write((int)(address >> 8)); // MSB
Wire.write((int)(address & 0xFF)); // LSB
Wire.endTransmission();
Wire.requestFrom(I2CEEPROM1,1);
if (Wire.available())
rdata = Wire.read();
return rdata;
}
void memory_write_byte(int address, const byte data)
{
if (memory_read_int(address) != data)
{
Wire.beginTransmission(I2CEEPROM1);
Wire.write((int)(address >> 8)); // MSB
Wire.write((int)(address & 0xFF)); // LSB
Wire.write(data);
Wire.endTransmission();
delay(10);
}
}
int memory_read_int(int address)
{
int rdata = 0xFFFF;
Wire.beginTransmission(I2CEEPROM1);
Wire.write((int)(address >> 8)); // MSB
Wire.write((int)(address & 0xFF)); // LSB
Wire.endTransmission();
Wire.requestFrom(I2CEEPROM1,2);
if (Wire.available())
{
rdata = Wire.read();
rdata += (Wire.read())<<8;
}
return rdata;
}
void memory_write_int(int address, const int data)
{
if (memory_read_int(address) != data)
{
Wire.beginTransmission(I2CEEPROM1);
Wire.write((int)(address >> 8)); // MSB
Wire.write((int)(address & 0xFF)); // LSB
Wire.write(data%256);
Wire.write(data>>8);
Wire.endTransmission();
delay(10);
}
}
void printWifiStatus() {
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
}
unsigned int crc16(int *ptr, byte len)
{
unsigned int crc=0xFFFF;
byte i;
byte temp=0;
int test;
while(len--)
{
crc^=*ptr++;
for(i=0;i<8;i++)
{
if(crc & 0x01)
{
crc>>=1;
crc^=0xA001;
}
else
{
crc>>=1;
}
}
}
return crc;
}
void wdt_initialize()
{
GCLK->GENDIV.reg = GCLK_GENDIV_ID(2) | GCLK_GENDIV_DIV(4);
GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(2) |
GCLK_GENCTRL_GENEN |
GCLK_GENCTRL_SRC_OSCULP32K |
GCLK_GENCTRL_DIVSEL;
while (GCLK->STATUS.bit.SYNCBUSY); // Syncronize write to GENCTRL reg.
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID_WDT |
GCLK_CLKCTRL_CLKEN |
GCLK_CLKCTRL_GEN_GCLK2;
}
void wdt_enable()
{
WDT->CTRL.reg &= ~WDT_CTRL_ENABLE;
while (WDT->STATUS.bit.SYNCBUSY); // Syncronize write to CTRL reg.
WDT->CONFIG.reg = WDT_CONFIG_PER(0xA); // 0xA = 8192 ms
while (WDT->STATUS.bit.SYNCBUSY); // Syncronize write to CONFIG reg.
WDT->INTENCLR.reg |= WDT_INTENCLR_EW;
WDT->CTRL.reg |= WDT_CTRL_ENABLE;
while (WDT->STATUS.bit.SYNCBUSY); // Syncronize write to CTRL reg.
}
void wdt_disable()
{
WDT->CTRL.reg &= ~WDT_CTRL_ENABLE;
while (WDT->STATUS.bit.SYNCBUSY); // Syncronize write to CTRL reg.
}
void wdt_reset()
{
WDT->CLEAR.reg = WDT_CLEAR_CLEAR_KEY;
while (WDT->STATUS.bit.SYNCBUSY); // Syncronize write to CLEAR reg.
}
// RA_STRING1=U2FsdGVkX1+v9maD6sR7lmfrBMXYH2hY/h8++Itviz0=
// RA_STRING2=U2FsdGVkX192Np27NDkaa73OUwJfOKtJ7zvgIZ/mfZo=
// RA_STRING3=netgearcannon
// RA_LABEL LABEL_ACTINIC=Blues
// RA_LABEL LABEL_ACTINIC2=Cool Whites
// RA_LABEL LABEL_DAYLIGHT=Daylight
// RA_LABEL LABEL_DAYLIGHT2=Daylight 2
// RA_LABEL LABEL_PORT11=Heater 1
// RA_LABEL LABEL_PORT12=Return
// RA_LABEL LABEL_PORT13=Port 13
// RA_LABEL LABEL_PORT14=Skimmer
// RA_LABEL LABEL_PORT15=Port 15
// RA_LABEL LABEL_PORT16=Port 16
// RA_LABEL LABEL_PORT17=Port 17
// RA_LABEL LABEL_PORT18=Port 18