2nd Salinity module w/Cloud Wifi Hub

Expansion modules and attachments
User avatar
Loose
Posts: 90
Joined: Fri Sep 01, 2017 8:15 am
Location: Severna Park, MD

2nd Salinity module w/Cloud Wifi Hub

Post by Loose »

Hello Roberto,

I know it's not possible to have two salinity probes with a single RA* but is it possible to directly program my Cloud Wifi Hub to directly read a salinity module/probe? Like many others, I'd like to use it at my remote mixing station which I'm trying to automate.

When we were setting up a 2nd dimming module with my Cloud WiFi Hub (used with an RA*) in the below thread,

https://forum.reefangel.com/viewtopic.p ... 2&start=30

You mentioned that I'd have to program the Cloud wifi hub code itself to get lightening effects to work with it - not trying this just yet as my lights are functioning correctly and the room is not setup for that kind of show :D .
Try to learn something about everything and everything about something... Thomas Huxley
210gal DT | 50gal sump/refug | Jebao DCP 10000 pump | RO 200-int skimmer | DIY built stand | DIY 160 led, 12 channel, 458 watt, on MakersLED 72" heatsink
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: 2nd Salinity module w/Cloud Wifi Hub

Post by rimai »

Yes, each cloud wifi hub can be used to have an additional salinity module.
Roberto.
User avatar
Loose
Posts: 90
Joined: Fri Sep 01, 2017 8:15 am
Location: Severna Park, MD

Re: 2nd Salinity module w/Cloud Wifi Hub

Post by Loose »

Nice! Could you please help me set it up?

I generated the following code with the Wizard:

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 30
#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/i5QS5BGZK5riC7X8v1MxE964GYStk988=
// RA_STRING2=U2FsdGVkX19Lc9oWoOxRrp/GbHgXXsr2gDQc6rBkTKk=
// RA_STRING3=K2GVR

and I changed this section to:

Code: Select all

// 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_SALINITY
#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
but as I read the comments, don't think it was necessary.
Try to learn something about everything and everything about something... Thomas Huxley
210gal DT | 50gal sump/refug | Jebao DCP 10000 pump | RO 200-int skimmer | DIY built stand | DIY 160 led, 12 channel, 458 watt, on MakersLED 72" heatsink
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: 2nd Salinity module w/Cloud Wifi Hub

Post by rimai »

Can you post a photo of the board?
I need to see the revision number.
Roberto.
User avatar
Loose
Posts: 90
Joined: Fri Sep 01, 2017 8:15 am
Location: Severna Park, MD

Re: 2nd Salinity module w/Cloud Wifi Hub

Post by Loose »

The board is a Cloud Wifi Expansion v 1.4. I'll take a picture later today if needed.
Try to learn something about everything and everything about something... Thomas Huxley
210gal DT | 50gal sump/refug | Jebao DCP 10000 pump | RO 200-int skimmer | DIY built stand | DIY 160 led, 12 channel, 458 watt, on MakersLED 72" heatsink
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: 2nd Salinity module w/Cloud Wifi Hub

Post by rimai »

No need for photo.
This is the newest Could wifi hub and it doesn't work with the webwizard.
We will need to compile the code and upload it on your computer using the Arduino IDE.
It uses ESP8266 chip.

Start Arduino and open Preferences window.
Enter http://arduino.esp8266.com/stable/packa ... index.json into Additional Board Manager URLs field. You can add multiple URLs, separating them with commas.
Open Boards Manager from Tools > Board menu and find esp8266 platform.
Select the version you need from a drop-down box.
Click install button.

After it is installed, just to be sure, close Arduino and start it again to load everything it needs.
Then, go to menu Tools->Boards and you will see a bunch of ESP8266 boards. Pick the Adafruit HUZZAH ESP8266.
Try to compile this code:

Code: Select all

#include <FS.h>
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <ESP8266httpUpdate.h>
#include <WiFiManager.h>
#include <ArduinoJson.h>
#include <EEPROM.h>
#include <Ticker.h>
#include <Wire.h>
#include <OneWire.h>
#include <CloudGlobals.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[] = {4, 5};

// Do not change anything below
// ***********************************************************************
// solid green - factory reset
// blink green - connecting wifi
// blink blue - configuration required (SoftAP)
// blink magenta - connecting to cloud server
// solid cyan - connected to cloud server
// blinking cyan - transmitting/receiving data
// solid yellow - firmware update

#define LED_GREEN 2
#define LED_BLUE 0
#define LED_RED 16
#define RESET_ALL A0
#define INPUT1  12
#define INPUT2  13
#define TEMP_PIN  14

#define version "1.0.1"

#define MQTTServer "cloud.reefangel.com"

#define MQTTPORT 1883 // MQTT server port

WiFiManager wifiManager;
WiFiClient espClient;
PubSubClient CloudClient(espClient);
Ticker ticker;
OneWire ds(TEMP_PIN);

byte data[2];
byte addr[8];
byte addr1[8];
byte addr2[8];

boolean first_connection = true;
boolean shouldSaveConfig = false;
boolean updating = false;

unsigned long cloudmillis = millis();
unsigned long client_timeout = millis();
unsigned long serial_timeout = millis();

String currentLine = "";                // make a String to hold incoming data from the client

char mqtt_username[32];
char mqtt_password[32];

void APtick()
{
  //toggle state
  int state = digitalRead(LED_BLUE);  // get the current state of GPIO1 pin
  digitalWrite(LED_BLUE, !state);     // set pin to the opposite state
}

void Wifitick()
{
  //toggle state
  int state = digitalRead(LED_GREEN);  // get the current state of GPIO1 pin
  digitalWrite(LED_GREEN, !state);     // set pin to the opposite state
}

void Cloudtick()
{
  //toggle state
  int state = digitalRead(LED_BLUE);  // get the current state of GPIO1 pin
  digitalWrite(LED_RED, !state);     // set pin to the opposite state
  digitalWrite(LED_BLUE, !state);     // set pin to the opposite state
}

void Datatick()
{
  //toggle state
  int state = digitalRead(LED_BLUE);  // get the current state of GPIO1 pin
  digitalWrite(LED_GREEN, !state);     // set pin to the opposite state
  digitalWrite(LED_BLUE, !state);     // set pin to the opposite state
}

void LED_Color(int Red, int Green, int Blue)
{
  analogWrite(LED_RED, 1023 - Red);
  analogWrite(LED_GREEN, 1023 - Green);
  analogWrite(LED_BLUE, 1023 - Blue);
}

int memory_read_int(int address)
{
  return EEPROM.read(address);
}

void memory_write_int(int address, const int data)
{
  if (memory_read_int(address) != data)
  {
    EEPROM.write(address, data);
    EEPROM.commit();
  }
}

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 blink_data_led(byte timer)
{
  digitalWrite(LED_RED, LOW);
  delay(timer);
  digitalWrite(LED_RED, HIGH);
}

void Publish(char* pub_buffer, char* buffer)
{
  CloudClient.publish(pub_buffer, buffer);
  Serial.print(pub_buffer);
  Serial.print(": ");
  Serial.println(buffer);
  blink_data_led(50);
}

void reconnect() {
  // Loop until we're reconnected
  if (!CloudClient.connected()) {
    cloudmillis = millis();
    //    Serial.print(F("Username: "));
    //    Serial.println(CLOUD_USERNAME);
    Serial.println("Connecting to cloud server...");
    // Attempt to connect
    //Serial.println(sub_buffer);
    if (CloudClient.connect(clientid, mqtt_username, mqtt_password)) {
      Serial.println("Connected");
      // Once connected, publish an announcement...
      Serial.print("Subscribing to ");
      Serial.println(sub_buffer);
      CloudClient.subscribe(sub_buffer);
      Publish(pub_buffer, "all:0");
      ticker.detach();
      LED_Color(0, 1023, 1023);

      //Serial.swap();
    } else {
      Serial.print("Failed, rc=");
      Serial.print(CloudClient.state());
      Serial.println(" try again in 30 seconds");
    }
  }
}

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 saveConfigCallback () {
  Serial.println("Should save config");
  shouldSaveConfig = true;
}

void configModeCallback (WiFiManager *myWiFiManager) {
  LED_Color(0, 0, 0);
  ticker.detach();
  Serial.println("Entered config mode");
  WiFi.softAPIP();
  ticker.attach(0.5, APtick);
}

void WifiCheckCallback () {
  WiFi.softAPdisconnect(true);
  LED_Color(0, 0, 0);
  ticker.detach();
  Serial.println("Checking Wifi Credentials");
  ticker.attach(0.5, Wifitick);
}

void callback(char* topic, byte* payload, unsigned int length) {

  boolean data_found = false;
  int payload_data = 0;
  byte data_index = 0;

  Serial.print("cloud:");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();
  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] == 'P' && payload[1] == 'W' && payload[2] == 'M' && payload[3] == '1' && payload[4] == '6' && payload[5] == 'E' && payload[8] == ':')
  {
    data_found = true;
    data_index = (payload[6] - '0') * 10;
    data_index += (payload[7] - '0');
    for (byte a = 9; a < length; a++)
    {
      if (payload[a] != 10 && payload[a] != 13)
      {
        payload_data *= 10;
        payload_data += payload[a] - '0';
      }
    }
    Expansion16Channel[data_index] = payload_data;
  }
  else if (payload[0] == 'P' && payload[1] == 'W' && payload[2] == 'M' && payload[3] == '1' && payload[4] == '6' && payload[5] == 'E' && payload[6] == 'O' && payload[9] == ':')
  {
    data_found = true;
    data_index = (payload[7] - '0') * 10;
    data_index += (payload[8] - '0');
    for (byte a = 10; a < length; a++)
    {
      if (payload[a] != 10 && payload[a] != 13)
      {
        payload_data *= 10;
        payload_data += payload[a] - '0';
      }
    }
    Expansion16ChannelOverride[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();
  }
}

void setup() {
  pinMode(LED_GREEN, OUTPUT);
  pinMode(LED_BLUE, OUTPUT);
  pinMode(LED_RED, OUTPUT);
  pinMode(INPUT1, INPUT_PULLUP);
  pinMode(INPUT2, INPUT_PULLUP);
  digitalWrite(LED_GREEN, LOW);
  digitalWrite(LED_BLUE, HIGH);
  digitalWrite(LED_RED, HIGH);
  randomSeed(analogRead(0));
  wifi_station_set_hostname( "ReefAngelCloudHub" );
  Serial.begin(57600);
  Serial.setRxBufferSize(2048);
  EEPROM.begin(512);
  Wire.begin();

  wifiManager.setDebugOutput(true);

  Serial.println("");
  Serial.print("Current version: ");
  Serial.println(version);

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

  // 16 Channel Dimming
  lastcrc16 = -1;
  for ( byte a = 0; a < PWM16_EXPANSION_CHANNELS; a++ )
  {
    Expansion16Channel[a] = 0;
    Expansion16ChannelOverride[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);

  if (analogRead(RESET_ALL) < 50)
  {
    //    updating=true;
    Serial.println("Resetting");
    EEPROM.write(128, 0);
    EEPROM.commit();
    ESP.reset();
    while (1);
  }

  wifiManager.setVersion(version);
  if (EEPROM.read(128) != 1)
  {
    wifiManager.resetSettings();
    SPIFFS.format();
    EEPROM.write(128, 1);
    EEPROM.commit();
  }

  if (SPIFFS.begin()) {
    Serial.println("mounted file system");
    if (SPIFFS.exists("/config.json")) {
      //file exists, reading and loading
      Serial.println("reading config file");
      File configFile = SPIFFS.open("/config.json", "r");
      if (configFile) {
        Serial.println("opened config file");
        size_t size = configFile.size();
        // Allocate a buffer to store contents of the file.
        std::unique_ptr<char[]> buf(new char[size]);

        configFile.readBytes(buf.get(), size);
        DynamicJsonBuffer jsonBuffer;
        JsonObject& json = jsonBuffer.parseObject(buf.get());
        json.printTo(Serial);
        if (json.success()) {
          Serial.println("\nparsed json");

          strcpy(mqtt_username, json["mqtt_username"]);
          strcpy(mqtt_password, json["mqtt_password"]);

        } else {
          Serial.println("failed to load json config");
        }
      }
    }
  } else {
    Serial.println("failed to mount FS");
  }

  WiFiManagerParameter custom_mqtt_username("Cloud Username", "Cloud Username", mqtt_username, 40);
  WiFiManagerParameter custom_mqtt_password("Cloud Password", "Cloud Password", mqtt_password, 40);
  wifiManager.addParameter(&custom_mqtt_username);
  wifiManager.addParameter(&custom_mqtt_password);
  wifiManager.setSaveConfigCallback(saveConfigCallback);
  wifiManager.setAPCallback(configModeCallback);
  wifiManager.setCheckWifiCallback(WifiCheckCallback);

  LED_Color(0, 0, 0);
  ticker.attach(0.5, Wifitick);
  wifiManager.autoConnect("ReefAngelCloudHub");
  ticker.detach();
  LED_Color(900, 0, 1023);

  CloudClient.setServer(MQTTServer, MQTTPORT);
  CloudClient.setCallback(callback);

  strcpy(mqtt_username, custom_mqtt_username.getValue());
  strcpy(mqtt_password, custom_mqtt_password.getValue());
  Serial.print("username: ");
  Serial.println(mqtt_username);
  //  Serial.print("password: ");
  //  Serial.println(mqtt_password);
  sprintf(clientid, "%s%02d", mqtt_username, random(10000));
  sprintf(pub_buffer, "%s/in", mqtt_username);
  sprintf(sub_buffer, "%s/out/#", mqtt_username);
  Serial.println("Start");

  if (shouldSaveConfig) {
    Serial.println("saving config");
    DynamicJsonBuffer jsonBuffer;
    JsonObject& json = jsonBuffer.createObject();
    json["mqtt_username"] = mqtt_username;
    json["mqtt_password"] = mqtt_password;

    File configFile = SPIFFS.open("/config.json", "w");
    if (!configFile) {
      Serial.println("failed to open config file for writing");
    }

    json.printTo(Serial);
    Serial.println("");
    json.printTo(configFile);
    configFile.close();
    //end save
  }

  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

}

void loop() {
  if ((analogRead(RESET_ALL) < 50) && !updating)
  {
    if (WiFi.status() == WL_CONNECTED)
    {
      updating = true;
      ticker.detach();
      LED_Color(1023, 900, 0);
      Serial.println("Updating...");
      ESPhttpUpdate.update("forum.reefangel.com", 80, "/firmware/CloudWifiESP8266Hub.ino.bin");
    }
    else
    {
      Serial.println("Resetting");
      EEPROM.write(128, 0);
      EEPROM.commit();
      ESP.reset();
      while (1);
    }
  }
  if (!CloudClient.connected() && (((millis() - cloudmillis) > 30000) || first_connection)) {
    first_connection = false;
    LED_Color(0, 0, 0);
    ticker.detach();
    ticker.attach(0.5, Cloudtick);
    reconnect();
  }
  CloudClient.loop();

  // Relay
  for ( byte EID = 0; EID < MAX_RELAY_EXPANSION_MODULES; EID++ )
  {
    byte TempRelay = RelayDataE[EID];
    TempRelay &= RelayMaskOffE[EID];
    TempRelay |= RelayMaskOnE[EID];
    if (!CloudClient.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();
    }
  }

  // 16 Channel Dimming
  int thiscrc16 = 0;
  for ( byte a = 0; a < PWM16_EXPANSION_CHANNELS; a++ )
  {
    thiscrc16 += Expansion16Channel[a] * (a + 1);
    thiscrc16 += Expansion16ChannelOverride[a] * (a + 1);
  }
  if (millis() % 60000 < 200) lastcrc16 = -1;
  if (lastcrc16 != thiscrc16 || millis() < 5000)
  {
    lastcrc16 = thiscrc16;
    // 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_16CH_PCA9685);
    Wire.write((uint8_t)0);
    Wire.write(0xa1);
    Wire.endTransmission();
    for ( byte a = 0; a < PWM16_EXPANSION_CHANNELS; a++ )
    {
      int data;
      if (Expansion16ChannelOverride[a] <= 100)
        data = Expansion16ChannelOverride[a];
      else
        data = Expansion16Channel[a];
      Wire.beginTransmission(I2CPWM_16CH_PCA9685);
      Wire.write(0x8 + (4 * a));
      Wire.write(data & 0xff);
      Wire.write(data >> 8);
      Wire.endTransmission();
    }
  }

  if (CloudClient.connected())
  {
    // IO
    Params.IO = 63;
    Wire.requestFrom(I2CIO_PCF8574, 1);
    if (Wire.available())
      Params.IO = Wire.read();
    if (digitalRead(INPUT1) == HIGH) Params.IO += 64;
    if (digitalRead(INPUT2) == HIGH) Params.IO += 128;
    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);
    }
  }
}
This is the code we previously loaded with the 16ch Dimming feature enabled.
Roberto.
User avatar
Loose
Posts: 90
Joined: Fri Sep 01, 2017 8:15 am
Location: Severna Park, MD

Re: 2nd Salinity module w/Cloud Wifi Hub

Post by Loose »

Open Boards Manager from Tools > Board menu and find esp8266 platform.
Select the version you need from a drop-down box.
Click install button.

After it is installed, just to be sure, close Arduino and start it again to load everything it needs.
Then, go to menu Tools->Boards and you will see a bunch of ESP8266 boards. Pick the Adafruit HUZZAH ESP8266.
Try to compile this code:
Having problems with the version. On the esp8266 select version drop down, I see the following:

1.6.5 and 2.0 thru 2.5.0 versions. When I select 2.4 and 2.5 versions, the board closest available is Adafruit feather HUZZAH esp8266. The others that I tried 1.6.5 and 2.0.0 version have the Adfruit HUZZAH ESP8266 board but in all cases, the code would not compile with errors.
Try to learn something about everything and everything about something... Thomas Huxley
210gal DT | 50gal sump/refug | Jebao DCP 10000 pump | RO 200-int skimmer | DIY built stand | DIY 160 led, 12 channel, 458 watt, on MakersLED 72" heatsink
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: 2nd Salinity module w/Cloud Wifi Hub

Post by rimai »

Ok, so I am compiling on version 2.3.
If it does give you compile errors, can you paste the errors here?
Roberto.
User avatar
Loose
Posts: 90
Joined: Fri Sep 01, 2017 8:15 am
Location: Severna Park, MD

Re: 2nd Salinity module w/Cloud Wifi Hub

Post by Loose »

I get an error with 2.3 but it's different from the others.

Sorry, I'm a beginner with this language and haven't been able to figure out how to fix this missing WiFiManager.h file error.

I used the verbose option when I compiled.

Code: Select all

Arduino: 1.8.5 (Windows 10), Board: "Adafruit HUZZAH ESP8266, 80 MHz, 115200, 4M (3M SPIFFS)"

C:\Arduino\arduino-builder -dump-prefs -logger=machine -hardware C:\Arduino\hardware -hardware C:\Users\Loose\AppData\Local\Arduino15\packages -tools C:\Arduino\tools-builder -tools C:\Arduino\hardware\tools\avr -tools C:\Users\Loose\AppData\Local\Arduino15\packages -built-in-libraries C:\Arduino\libraries -libraries C:\Users\Loose\Documents\Arduino\libraries -fqbn=esp8266:esp8266:huzzah:CpuFrequency=80,UploadSpeed=115200,FlashSize=4M3M -ide-version=10805 -build-path C:\Users\Loose\AppData\Local\Temp\arduino_build_558683 -warnings=all -build-cache C:\Users\Loose\AppData\Local\Temp\arduino_cache_59280 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.xtensa-lx106-elf-gcc.path=C:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\1.20.0-26-gb404fb9-2 -prefs=runtime.tools.mkspiffs.path=C:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\tools\mkspiffs\0.1.2 -prefs=runtime.tools.esptool.path=C:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\tools\esptool\0.4.9 -verbose C:\Users\Loose\Documents\Arduino\Cloud_Wifi_Hub_Salinity\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal.ino
C:\Arduino\arduino-builder -compile -logger=machine -hardware C:\Arduino\hardware -hardware C:\Users\Loose\AppData\Local\Arduino15\packages -tools C:\Arduino\tools-builder -tools C:\Arduino\hardware\tools\avr -tools C:\Users\Loose\AppData\Local\Arduino15\packages -built-in-libraries C:\Arduino\libraries -libraries C:\Users\Loose\Documents\Arduino\libraries -fqbn=esp8266:esp8266:huzzah:CpuFrequency=80,UploadSpeed=115200,FlashSize=4M3M -ide-version=10805 -build-path C:\Users\Loose\AppData\Local\Temp\arduino_build_558683 -warnings=all -build-cache C:\Users\Loose\AppData\Local\Temp\arduino_cache_59280 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.xtensa-lx106-elf-gcc.path=C:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\1.20.0-26-gb404fb9-2 -prefs=runtime.tools.mkspiffs.path=C:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\tools\mkspiffs\0.1.2 -prefs=runtime.tools.esptool.path=C:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\tools\esptool\0.4.9 -verbose C:\Users\Loose\Documents\Arduino\Cloud_Wifi_Hub_Salinity\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal.ino
Using board 'huzzah' from platform in folder: C:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0
Using core 'esp8266' from platform in folder: C:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0
Detecting libraries used...

"C:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\1.20.0-26-gb404fb9-2/bin/xtensa-lx106-elf-g++" -D__ets__ -DICACHE_FLASH -U__STRICT_ANSI__ "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0/tools/sdk/include" "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0/tools/sdk/lwip/include" "-IC:\Users\Loose\AppData\Local\Temp\arduino_build_558683/core" -c -w -Os -g -mlongcalls -mtext-section-literals -fno-exceptions -fno-rtti -falign-functions=4 -std=c++11  -ffunction-sections -fdata-sections -w -x c++ -E -CC -DF_CPU=80000000L -DLWIP_OPEN_SRC   -DARDUINO=10805 -DARDUINO_ESP8266_ESP12 -DARDUINO_ARCH_ESP8266 -DARDUINO_BOARD="ESP8266_ESP12"  -DESP8266 "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266" "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\variants\adafruit" "C:\Users\Loose\AppData\Local\Temp\arduino_build_558683\sketch\Cloud_Wifi_Hub_Sal.ino.cpp" -o "nul"

"C:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\1.20.0-26-gb404fb9-2/bin/xtensa-lx106-elf-g++" -D__ets__ -DICACHE_FLASH -U__STRICT_ANSI__ "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0/tools/sdk/include" "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0/tools/sdk/lwip/include" "-IC:\Users\Loose\AppData\Local\Temp\arduino_build_558683/core" -c -w -Os -g -mlongcalls -mtext-section-literals -fno-exceptions -fno-rtti -falign-functions=4 -std=c++11  -ffunction-sections -fdata-sections -w -x c++ -E -CC -DF_CPU=80000000L -DLWIP_OPEN_SRC   -DARDUINO=10805 -DARDUINO_ESP8266_ESP12 -DARDUINO_ARCH_ESP8266 -DARDUINO_BOARD="ESP8266_ESP12"  -DESP8266 "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266" "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\variants\adafruit" "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266WiFi\src" "C:\Users\Loose\AppData\Local\Temp\arduino_build_558683\sketch\Cloud_Wifi_Hub_Sal.ino.cpp" -o "nul"

"C:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\1.20.0-26-gb404fb9-2/bin/xtensa-lx106-elf-g++" -D__ets__ -DICACHE_FLASH -U__STRICT_ANSI__ "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0/tools/sdk/include" "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0/tools/sdk/lwip/include" "-IC:\Users\Loose\AppData\Local\Temp\arduino_build_558683/core" -c -w -Os -g -mlongcalls -mtext-section-literals -fno-exceptions -fno-rtti -falign-functions=4 -std=c++11  -ffunction-sections -fdata-sections -w -x c++ -E -CC -DF_CPU=80000000L -DLWIP_OPEN_SRC   -DARDUINO=10805 -DARDUINO_ESP8266_ESP12 -DARDUINO_ARCH_ESP8266 -DARDUINO_BOARD="ESP8266_ESP12"  -DESP8266 "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266" "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\variants\adafruit" "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266WiFi\src" "-IC:\Users\Loose\Documents\Arduino\libraries\PubSubClient" "C:\Users\Loose\AppData\Local\Temp\arduino_build_558683\sketch\Cloud_Wifi_Hub_Sal.ino.cpp" -o "nul"

"C:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\1.20.0-26-gb404fb9-2/bin/xtensa-lx106-elf-g++" -D__ets__ -DICACHE_FLASH -U__STRICT_ANSI__ "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0/tools/sdk/include" "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0/tools/sdk/lwip/include" "-IC:\Users\Loose\AppData\Local\Temp\arduino_build_558683/core" -c -w -Os -g -mlongcalls -mtext-section-literals -fno-exceptions -fno-rtti -falign-functions=4 -std=c++11  -ffunction-sections -fdata-sections -w -x c++ -E -CC -DF_CPU=80000000L -DLWIP_OPEN_SRC   -DARDUINO=10805 -DARDUINO_ESP8266_ESP12 -DARDUINO_ARCH_ESP8266 -DARDUINO_BOARD="ESP8266_ESP12"  -DESP8266 "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266" "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\variants\adafruit" "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266WiFi\src" "-IC:\Users\Loose\Documents\Arduino\libraries\PubSubClient" "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries\DNSServer\src" "C:\Users\Loose\AppData\Local\Temp\arduino_build_558683\sketch\Cloud_Wifi_Hub_Sal.ino.cpp" -o "nul"

"C:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\1.20.0-26-gb404fb9-2/bin/xtensa-lx106-elf-g++" -D__ets__ -DICACHE_FLASH -U__STRICT_ANSI__ "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0/tools/sdk/include" "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0/tools/sdk/lwip/include" "-IC:\Users\Loose\AppData\Local\Temp\arduino_build_558683/core" -c -w -Os -g -mlongcalls -mtext-section-literals -fno-exceptions -fno-rtti -falign-functions=4 -std=c++11  -ffunction-sections -fdata-sections -w -x c++ -E -CC -DF_CPU=80000000L -DLWIP_OPEN_SRC   -DARDUINO=10805 -DARDUINO_ESP8266_ESP12 -DARDUINO_ARCH_ESP8266 -DARDUINO_BOARD="ESP8266_ESP12"  -DESP8266 "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266" "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\variants\adafruit" "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266WiFi\src" "-IC:\Users\Loose\Documents\Arduino\libraries\PubSubClient" "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries\DNSServer\src" "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266WebServer\src" "C:\Users\Loose\AppData\Local\Temp\arduino_build_558683\sketch\Cloud_Wifi_Hub_Sal.ino.cpp" -o "nul"

"C:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\1.20.0-26-gb404fb9-2/bin/xtensa-lx106-elf-g++" -D__ets__ -DICACHE_FLASH -U__STRICT_ANSI__ "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0/tools/sdk/include" "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0/tools/sdk/lwip/include" "-IC:\Users\Loose\AppData\Local\Temp\arduino_build_558683/core" -c -w -Os -g -mlongcalls -mtext-section-literals -fno-exceptions -fno-rtti -falign-functions=4 -std=c++11  -ffunction-sections -fdata-sections -w -x c++ -E -CC -DF_CPU=80000000L -DLWIP_OPEN_SRC   -DARDUINO=10805 -DARDUINO_ESP8266_ESP12 -DARDUINO_ARCH_ESP8266 -DARDUINO_BOARD="ESP8266_ESP12"  -DESP8266 "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266" "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\variants\adafruit" "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266WiFi\src" "-IC:\Users\Loose\Documents\Arduino\libraries\PubSubClient" "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries\DNSServer\src" "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266WebServer\src" "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266httpUpdate\src" "C:\Users\Loose\AppData\Local\Temp\arduino_build_558683\sketch\Cloud_Wifi_Hub_Sal.ino.cpp" -o "nul"

"C:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\1.20.0-26-gb404fb9-2/bin/xtensa-lx106-elf-g++" -D__ets__ -DICACHE_FLASH -U__STRICT_ANSI__ "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0/tools/sdk/include" "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0/tools/sdk/lwip/include" "-IC:\Users\Loose\AppData\Local\Temp\arduino_build_558683/core" -c -w -Os -g -mlongcalls -mtext-section-literals -fno-exceptions -fno-rtti -falign-functions=4 -std=c++11  -ffunction-sections -fdata-sections -w -x c++ -E -CC -DF_CPU=80000000L -DLWIP_OPEN_SRC   -DARDUINO=10805 -DARDUINO_ESP8266_ESP12 -DARDUINO_ARCH_ESP8266 -DARDUINO_BOARD="ESP8266_ESP12"  -DESP8266 "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266" "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\variants\adafruit" "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266WiFi\src" "-IC:\Users\Loose\Documents\Arduino\libraries\PubSubClient" "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries\DNSServer\src" "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266WebServer\src" "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266httpUpdate\src" "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266HTTPClient\src" "C:\Users\Loose\AppData\Local\Temp\arduino_build_558683\sketch\Cloud_Wifi_Hub_Sal.ino.cpp" -o "nul"

"C:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\1.20.0-26-gb404fb9-2/bin/xtensa-lx106-elf-g++" -D__ets__ -DICACHE_FLASH -U__STRICT_ANSI__ "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0/tools/sdk/include" "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0/tools/sdk/lwip/include" "-IC:\Users\Loose\AppData\Local\Temp\arduino_build_558683/core" -c -w -Os -g -mlongcalls -mtext-section-literals -fno-exceptions -fno-rtti -falign-functions=4 -std=c++11  -ffunction-sections -fdata-sections -w -x c++ -E -CC -DF_CPU=80000000L -DLWIP_OPEN_SRC   -DARDUINO=10805 -DARDUINO_ESP8266_ESP12 -DARDUINO_ARCH_ESP8266 -DARDUINO_BOARD="ESP8266_ESP12"  -DESP8266 "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266" "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\variants\adafruit" "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266WiFi\src" "-IC:\Users\Loose\Documents\Arduino\libraries\PubSubClient" "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries\DNSServer\src" "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266WebServer\src" "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266httpUpdate\src" "-IC:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266HTTPClient\src" "C:\Users\Loose\AppData\Local\Temp\arduino_build_558683\sketch\Cloud_Wifi_Hub_Sal.ino.cpp" -o "C:\Users\Loose\AppData\Local\Temp\arduino_build_558683\preproc\ctags_target_for_gcc_minus_e.cpp"

C:\Users\Loose\Documents\Arduino\Cloud_Wifi_Hub_Salinity\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal.ino:7:25: fatal error: WiFiManager.h: No such file or directory

 #include <WiFiManager.h>

                         ^

compilation terminated.

Using library ESP8266WiFi at version 1.0 in folder: C:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266WiFi 
Using library PubSubClient in folder: C:\Users\Loose\Documents\Arduino\libraries\PubSubClient (legacy)
Using library DNSServer at version 1.1.0 in folder: C:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries\DNSServer 
Using library ESP8266WebServer at version 1.0 in folder: C:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266WebServer 
Using library ESP8266httpUpdate at version 1.1 in folder: C:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266httpUpdate 
Using library ESP8266HTTPClient at version 1.1 in folder: C:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266HTTPClient 
exit status 1
Error compiling for board Adafruit HUZZAH ESP8266.

Try to learn something about everything and everything about something... Thomas Huxley
210gal DT | 50gal sump/refug | Jebao DCP 10000 pump | RO 200-int skimmer | DIY built stand | DIY 160 led, 12 channel, 458 watt, on MakersLED 72" heatsink
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: 2nd Salinity module w/Cloud Wifi Hub

Post by rimai »

Ahh.
You need the latest dev branch of the libraries.
Replace the contents of /Documents/Arduino/libraries with these ones: https://github.com/reefangel/Libraries/archive/dev.zip
Roberto.
User avatar
Loose
Posts: 90
Joined: Fri Sep 01, 2017 8:15 am
Location: Severna Park, MD

Re: 2nd Salinity module w/Cloud Wifi Hub

Post by Loose »

Thank you, libraries updated and recompiling.

Lot's of warnings/notes (I took it off verbose) but it did compile (used 2.3.).

Code: Select all

Build options changed, rebuilding all
C:\Users\Loose\Documents\Arduino\Cloud_Wifi_Hub_Salinity\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal.ino: In function 'unsigned int crc16(int*, byte)':

C:\Users\Loose\Documents\Arduino\Cloud_Wifi_Hub_Salinity\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal.ino:172:8: warning: unused variable 'temp' [-Wunused-variable]

   byte temp = 0;

        ^

C:\Users\Loose\Documents\Arduino\Cloud_Wifi_Hub_Salinity\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal.ino:173:7: warning: unused variable 'test' [-Wunused-variable]

   int test;

       ^

C:\Users\Loose\Documents\Arduino\Cloud_Wifi_Hub_Salinity\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal.ino: In function 'void reconnect()':

C:\Users\Loose\Documents\Arduino\Cloud_Wifi_Hub_Salinity\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal.ino:224:34: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]

       Publish(pub_buffer, "all:0");

                                  ^

C:\Users\Loose\Documents\Arduino\Cloud_Wifi_Hub_Salinity\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal.ino: At global scope:

C:\Users\Loose\Documents\Arduino\Cloud_Wifi_Hub_Salinity\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal.ino:272:6: warning: unused parameter 'myWiFiManager' [-Wunused-parameter]

 void configModeCallback (WiFiManager *myWiFiManager) {

      ^

C:\Users\Loose\Documents\Arduino\Cloud_Wifi_Hub_Salinity\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal.ino: In function 'void callback(char*, byte*, unsigned int)':

C:\Users\Loose\Documents\Arduino\Cloud_Wifi_Hub_Salinity\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal.ino:295:23: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]

   for (int i = 0; i < length; i++) {

                       ^

C:\Users\Loose\Documents\Arduino\Cloud_Wifi_Hub_Salinity\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal.ino:632:25: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]

     for (int a = 0; a < length; a++)

                         ^

C:\Users\Loose\Documents\Arduino\Cloud_Wifi_Hub_Salinity\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal.ino: At global scope:

C:\Users\Loose\Documents\Arduino\Cloud_Wifi_Hub_Salinity\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal.ino:288:6: warning: unused parameter 'topic' [-Wunused-parameter]

 void callback(char* topic, byte* payload, unsigned int length) {

      ^

C:\Users\Loose\Documents\Arduino\Cloud_Wifi_Hub_Salinity\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal.ino: In function 'void setup()':

C:\Users\Loose\Documents\Arduino\Cloud_Wifi_Hub_Salinity\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal.ino:859:59: warning: format '%d' expects argument of type 'int', but argument 4 has type 'long int' [-Wformat=]

   sprintf(clientid, "%s%02d", mqtt_username, random(10000));

                                                           ^

C:\Users\Loose\Documents\Arduino\Cloud_Wifi_Hub_Salinity\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal.ino:859:59: warning: format '%d' expects argument of type 'int', but argument 4 has type 'long int' [-Wformat=]

C:\Users\Loose\Documents\Arduino\Cloud_Wifi_Hub_Salinity\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal.ino: In function 'void loop()':

C:\Users\Loose\Documents\Arduino\Cloud_Wifi_Hub_Salinity\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal.ino:897:94: warning: 't_httpUpdate_return ESP8266HTTPUpdate::update(const String&, uint16_t, const String&, const String&)' is deprecated (declared at C:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0\libraries\ESP8266httpUpdate\src/ESP8266httpUpdate.h:100) [-Wdeprecated-declarations]

       ESPhttpUpdate.update("forum.reefangel.com", 80, "/firmware/CloudWifiESP8266Hub.ino.bin");

                                                                                              ^

C:\Users\Loose\Documents\Arduino\Cloud_Wifi_Hub_Salinity\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal.ino:1098:51: warning: format '%d' expects argument of type 'int', but argument 4 has type 'long unsigned int' [-Wformat=]

         sprintf(buffer, "%sc:%d", pub_orp, temporp);

                                                   ^

C:\Users\Loose\Documents\Arduino\Cloud_Wifi_Hub_Salinity\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal.ino:1098:51: warning: format '%d' expects argument of type 'int', but argument 4 has type 'long unsigned int' [-Wformat=]

C:\Users\Loose\Documents\Arduino\Cloud_Wifi_Hub_Salinity\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal.ino:1133:56: warning: format '%d' expects argument of type 'int', but argument 4 has type 'long unsigned int' [-Wformat=]

         sprintf(buffer, "%sc:%d", pub_salinity, tempsal);

                                                        ^

C:\Users\Loose\Documents\Arduino\Cloud_Wifi_Hub_Salinity\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal.ino:1133:56: warning: format '%d' expects argument of type 'int', but argument 4 has type 'long unsigned int' [-Wformat=]

C:\Users\Loose\Documents\Arduino\Cloud_Wifi_Hub_Salinity\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal.ino:1169:55: warning: format '%d' expects argument of type 'int', but argument 4 has type 'long unsigned int' [-Wformat=]

         sprintf(buffer, "%sc:%d", pub_phexp, tempphexp);

                                                       ^

C:\Users\Loose\Documents\Arduino\Cloud_Wifi_Hub_Salinity\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal.ino:1169:55: warning: format '%d' expects argument of type 'int', but argument 4 has type 'long unsigned int' [-Wformat=]

C:\Users\Loose\Documents\Arduino\Cloud_Wifi_Hub_Salinity\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal.ino:1230:34: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]

         if (crc == crc16(reply, 4))

                                  ^

In file included from sketch\Cloud_Wifi_Hub_Sal.ino.cpp:1:0:

C:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0\cores\esp8266/Arduino.h:136:44: warning: comparison is always false due to limited range of data type [-Wtype-limits]

 #define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))

                                            ^

C:\Users\Loose\Documents\Arduino\Cloud_Wifi_Hub_Salinity\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal.ino:1292:26: note: in expansion of macro 'constrain'

           Params.WL[i] = constrain(Params.WL[i], 0, 255);

                          ^

C:\Users\Loose\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0\cores\esp8266/Arduino.h:136:64: warning: comparison is always false due to limited range of data type [-Wtype-limits]

 #define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))

                                                                ^

C:\Users\Loose\Documents\Arduino\Cloud_Wifi_Hub_Salinity\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal.ino:1292:26: note: in expansion of macro 'constrain'

           Params.WL[i] = constrain(Params.WL[i], 0, 255);

                          ^

C:\Users\Loose\Documents\Arduino\Cloud_Wifi_Hub_Salinity\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal.ino:1299:60: warning: format '%d' expects argument of type 'int', but argument 4 has type 'long unsigned int' [-Wformat=]

               sprintf(buffer, "%s%d", pub_custom_wl, tempwl);

                                                            ^

C:\Users\Loose\Documents\Arduino\Cloud_Wifi_Hub_Salinity\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal.ino:1299:60: warning: format '%d' expects argument of type 'int', but argument 4 has type 'long unsigned int' [-Wformat=]

C:\Users\Loose\Documents\Arduino\Cloud_Wifi_Hub_Salinity\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal.ino:1301:55: warning: format '%d' expects argument of type 'int', but argument 4 has type 'long unsigned int' [-Wformat=]

               sprintf(buffer, "%sc:%d", pub_wl, tempwl);

                                                       ^

C:\Users\Loose\Documents\Arduino\Cloud_Wifi_Hub_Salinity\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal.ino:1301:55: warning: format '%d' expects argument of type 'int', but argument 4 has type 'long unsigned int' [-Wformat=]

C:\Users\Loose\Documents\Arduino\Cloud_Wifi_Hub_Salinity\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal.ino:1306:65: warning: format '%d' expects argument of type 'int', but argument 4 has type 'long unsigned int' [-Wformat=]

               sprintf(buffer, "%s%d", pub_custom_multiwl, tempwl);

                                                                 ^

C:\Users\Loose\Documents\Arduino\Cloud_Wifi_Hub_Salinity\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal.ino:1306:65: warning: format '%d' expects argument of type 'int', but argument 4 has type 'long unsigned int' [-Wformat=]

C:\Users\Loose\Documents\Arduino\Cloud_Wifi_Hub_Salinity\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal.ino:1308:60: warning: format '%d' expects argument of type 'int', but argument 4 has type 'long unsigned int' [-Wformat=]

               sprintf(buffer, "%sc:%d", pub_multiwl, tempwl);

                                                            ^

C:\Users\Loose\Documents\Arduino\Cloud_Wifi_Hub_Salinity\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal.ino:1308:60: warning: format '%d' expects argument of type 'int', but argument 4 has type 'long unsigned int' [-Wformat=]

In file included from C:\Users\Loose\Documents\Arduino\Cloud_Wifi_Hub_Salinity\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal\Cloud_Wifi_Hub_Sal.ino:13:0:

C:\Users\Loose\Documents\Arduino\libraries\CloudGlobals/CloudGlobals.h: At global scope:

C:\Users\Loose\Documents\Arduino\libraries\CloudGlobals/CloudGlobals.h:96:13: warning: 'username' defined but not used [-Wunused-variable]

 static char username[16];

             ^

C:\Users\Loose\Documents\Arduino\libraries\CloudGlobals/CloudGlobals.h:97:13: warning: 'password' defined but not used [-Wunused-variable]

 static char password[16];

             ^

C:\Users\Loose\Documents\Arduino\libraries\CloudGlobals/CloudGlobals.h:154:16: warning: 'FoundIP' defined but not used [-Wunused-variable]

 static boolean FoundIP=false;

                ^

C:\Users\Loose\Documents\Arduino\libraries\PubSubClient\PubSubClient.cpp: In member function 'boolean PubSubClient::subscribe(const char*, uint8_t)':

C:\Users\Loose\Documents\Arduino\libraries\PubSubClient\PubSubClient.cpp:492:15: warning: comparison is always false due to limited range of data type [-Wtype-limits]

     if (qos < 0 || qos > 1) {

               ^

C:\Users\Loose\Documents\Arduino\libraries\WiFiManager\WiFiManager.cpp: In member function 'boolean WiFiManager::isIp(String)':

C:\Users\Loose\Documents\Arduino\libraries\WiFiManager\WiFiManager.cpp:780:34: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]

   for (int i = 0; i < str.length(); i++) {

                                  ^

C:\Users\Loose\Documents\Arduino\libraries\OneWire\OneWire.cpp: In member function 'uint8_t OneWire::reset()':

C:\Users\Loose\Documents\Arduino\libraries\OneWire\OneWire.cpp:145:24: warning: unused variable 'reg' [-Wunused-variable]

  volatile IO_REG_TYPE *reg IO_REG_ASM = baseReg;

                        ^

C:\Users\Loose\Documents\Arduino\libraries\OneWire\OneWire.cpp: In member function 'void OneWire::write_bit(uint8_t)':

C:\Users\Loose\Documents\Arduino\libraries\OneWire\OneWire.cpp:179:24: warning: unused variable 'reg' [-Wunused-variable]

  volatile IO_REG_TYPE *reg IO_REG_ASM = baseReg;

                        ^

C:\Users\Loose\Documents\Arduino\libraries\OneWire\OneWire.cpp: In member function 'uint8_t OneWire::read_bit()':

C:\Users\Loose\Documents\Arduino\libraries\OneWire\OneWire.cpp:207:24: warning: unused variable 'reg' [-Wunused-variable]

  volatile IO_REG_TYPE *reg IO_REG_ASM = baseReg;

                        ^

Archiving built core (caching) in: C:\Users\Loose\AppData\Local\Temp\arduino_cache_555022\core\core_esp8266_esp8266_huzzah_xtal_80,vt_flash,exception_disabled,eesz_4M,ip_lm2f,dbg_Disabled,lvl_None____,wipe_none,baud_115200_af310de3343d0ab5be8a323c884dd04a.a
Sketch uses 403348 bytes (38%) of program storage space. Maximum is 1044464 bytes.
Global variables use 36972 bytes (45%) of dynamic memory, leaving 44948 bytes for local variables. Maximum is 81920 bytes.
Try to learn something about everything and everything about something... Thomas Huxley
210gal DT | 50gal sump/refug | Jebao DCP 10000 pump | RO 200-int skimmer | DIY built stand | DIY 160 led, 12 channel, 458 watt, on MakersLED 72" heatsink
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: 2nd Salinity module w/Cloud Wifi Hub

Post by rimai »

Good.
So, in that code, replace this:

Code: Select all

#define CloudCustomModule1  CUSTOM_NONE
With this:

Code: Select all

#define CloudCustomModule1  CUSTOM_SALINITY
Roberto.
User avatar
Loose
Posts: 90
Joined: Fri Sep 01, 2017 8:15 am
Location: Severna Park, MD

Re: 2nd Salinity module w/Cloud Wifi Hub

Post by Loose »

Modified and compiled successfully.
Try to learn something about everything and everything about something... Thomas Huxley
210gal DT | 50gal sump/refug | Jebao DCP 10000 pump | RO 200-int skimmer | DIY built stand | DIY 160 led, 12 channel, 458 watt, on MakersLED 72" heatsink
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: 2nd Salinity module w/Cloud Wifi Hub

Post by rimai »

Ok, upload to your cloud expansion and plug in the salinity module to it.
It should start sending data as custom expansion 1. You may need to calibrate.
Roberto.
User avatar
Loose
Posts: 90
Joined: Fri Sep 01, 2017 8:15 am
Location: Severna Park, MD

Re: 2nd Salinity module w/Cloud Wifi Hub

Post by Loose »

Code has been uploaded but once finished it it did reconnect to my local Wifi but it seems to be having trouble connecting to the cloud server (Blinking Magenta).

I can get it to fully connect with the reset/setup procedure (paper clip) and I can control my lights with the web uapp and the Android app on my phone but, if I take power away and then plug it back in, it will not reconnect to the server automatically.

Also, once connected how/where can I see the data from the salinity probe/custom expansion 1? I enabled Custom variables on the Android app but nothing is registering on Custom 0-7.
Try to learn something about everything and everything about something... Thomas Huxley
210gal DT | 50gal sump/refug | Jebao DCP 10000 pump | RO 200-int skimmer | DIY built stand | DIY 160 led, 12 channel, 458 watt, on MakersLED 72" heatsink
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: 2nd Salinity module w/Cloud Wifi Hub

Post by rimai »

Sorry.
I forgot that we need to edit the cloud settings.
Open the file RA_CustomSettings.h and change the CLOUD_USERNAME and CLOUD_PASSWORD.
The Custom expansion 1 will show up on the screen of RA* only :(
We don't have any app that can display it too.
You can as a work around, assign a custom variable to have the 2nd salinity, but it will not have the decimal point. It would show for example 350 instead of 35.0
To do that, add this to your loop():

Code: Select all

ReefAngel.CustomVar[0]=ReefAngel.CustomExpansionValue[0];
Roberto.
User avatar
Loose
Posts: 90
Joined: Fri Sep 01, 2017 8:15 am
Location: Severna Park, MD

Re: 2nd Salinity module w/Cloud Wifi Hub

Post by Loose »

RA_CustomSettings.h modified. Do I need to upload directly to the Cloud Wifi hub again or will changing the file be sufficient?

"ReefAngel.CustomVar[0]=ReefAngel.CustomExpansionValue[0];" added to my loop()

Now, I'm sorry but, decimal points, LOL! The old Naval aviator here can translate that little dot on the fly :D.

The only problem I've got is the RA* rebooting when I touch the screen and move from one screen to the other; annoying but not a show stopper.
Try to learn something about everything and everything about something... Thomas Huxley
210gal DT | 50gal sump/refug | Jebao DCP 10000 pump | RO 200-int skimmer | DIY built stand | DIY 160 led, 12 channel, 458 watt, on MakersLED 72" heatsink
User avatar
Loose
Posts: 90
Joined: Fri Sep 01, 2017 8:15 am
Location: Severna Park, MD

Re: 2nd Salinity module w/Cloud Wifi Hub

Post by Loose »

Readings are odd. I put the second probe in the display tank next to the DT probe (which is stable @30.3) and am getting values from 215 to 8; currently averaging 80.

Thoughts?
Try to learn something about everything and everything about something... Thomas Huxley
210gal DT | 50gal sump/refug | Jebao DCP 10000 pump | RO 200-int skimmer | DIY built stand | DIY 160 led, 12 channel, 458 watt, on MakersLED 72" heatsink
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: 2nd Salinity module w/Cloud Wifi Hub

Post by rimai »

Did you try calibrating it?
Roberto.
User avatar
Loose
Posts: 90
Joined: Fri Sep 01, 2017 8:15 am
Location: Severna Park, MD

Re: 2nd Salinity module w/Cloud Wifi Hub

Post by Loose »

So, I tried calibrating Custom Expansion Module 1 about 5 times from the RA* screen.

#1 - First 35ppt then RODI - Calibration value for both was 0. RA* Custom Expansion Module 1 showed 00.-29 <--- that is not a typo. ;)

#2 - First RODI then 35ppt - Calibration value for both was 0. Android app showed constant 61; can't tell you what the RA* showed as it displayed overlapping numbers from top to bottom in that column, screen went blank, and it rebooted.

#3 - I cancelled this attempt because I started with RODI and then the next message was new as it said to put the probe in RODI and press OK.

#4 - 35ppt then RODI then 35ppt - Calibration value for both was 0. RA* went blank and rebooted when I tried to change menu pages, Android app showed 84, 88, then 224.

#5 - RODI then RODI then 35ppt - Calibration value for both was 0. App shows 0 with the probe in my DT.

It's late so I'm done for the evening.
Try to learn something about everything and everything about something... Thomas Huxley
210gal DT | 50gal sump/refug | Jebao DCP 10000 pump | RO 200-int skimmer | DIY built stand | DIY 160 led, 12 channel, 458 watt, on MakersLED 72" heatsink
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: 2nd Salinity module w/Cloud Wifi Hub

Post by rimai »

If you open Serial monitor on Arudino, it should start displaying the log.
Can you record the log of when you start the salinity calibrating and post here?
Roberto.
User avatar
Loose
Posts: 90
Joined: Fri Sep 01, 2017 8:15 am
Location: Severna Park, MD

Re: 2nd Salinity module w/Cloud Wifi Hub

Post by Loose »

Sure thing.

I did the full cal but am only posting from the start (35ppt solution) to the RODI to just putting the probe back into the 35ppt.

Code: Select all

cloud:PWMD:52
cloud:PWMD2:92
cloud:WL1:96
cloud:T3:768
cloud:PWMD:50
cloud:PWMD2:94
cloud:WL1:93
cloud:T3:766
cloud:CEXP0C:1
Custom Exp calibration
CEXP0C:1
cloud:PWMD:49
cloud:PWMD2:95
cloud:WL1:96
Loose/in: cexp:0:c:1828
cloud:PWMD:46
cloud:PWMD2:98
cloud:C0:84
cloud:CEXP0:-12460
Loose/in: cexp:0:c:1827
cloud:C0:83
cloud:CEXP0:-12461
Loose/in: cexp:0:c:1829
cloud:PWMD:45
cloud:PWMD2:99
cloud:C0:85
cloud:CEXP0:-12459
Loose/in: cexp:0:c:1828
cloud:C0:84
Loose/in: cexp:0:c:1829
cloud:CEXP0:-12460
cloud:C0:85
Loose/in: cexp:0:c:1829
cloud:T3:768
cloud:PH:821
cloud:CEXP0:-12459
cloud:PWME1:20
PWME1:20
Loose/in: cexp:0:c:1830
cloud:PWMD:46
Loose/in: cexp:0:c:1829
cloud:PWMD2:98
cloud:WL1:97
cloud:C0:86
cloud:PH:820
cloud:CEXP0:-12458
cloud:PWMD:47
cloud:PWMD2:97
cloud:WL1:96
cloud:C0:85
cloud:T3:766
cloud:PH:821
cloud:CEXP0:-12459
Loose/in: cexp:0:c:1829
cloud:PWMD:48
Loose/in: cexp:0:c:1829
cloud:PWMD2:96
cloud:T1:719
cloud:T3:768
cloud:PH:820
cloud:PWMD:49
Loose/in: cexp:0:c:1829
cloud:PWMD2:95
cloud:WL1:97
cloud:PWMD:51
cloud:PWMD2:93
cloud:WL1:96
cloud:T3:766
Loose/in: cexp:0:c:1829
cloud:PWMD:53
cloud:PWMD2:91
cloud:T3:768
Loose/in: cexp:0:c:1828
cloud:PWMD:55
Loose/in: cexp:0:c:1828
cloud:PWMD2:89
cloud:WL1:97
cloud:C0:84
cloud:T1:717
cloud:CEXP0:-12460
cloud:PWMD:57
Loose/in: cexp:0:c:1829
cloud:PWMD2:87
cloud:WL1:95
cloud:T1:719
Loose/in: cexp:0:c:1829
cloud:PWMD:59
cloud:PWMD2:85
cloud:WL1:97
cloud:C0:85
cloud:CEXP0:-12459
Loose/in: cexp:0:c:1827
cloud:PWMD:62
cloud:PWMD2:82
cloud:WL1:95
cloud:C0:83
cloud:T3:766
cloud:PH:821
cloud:SAL:306
cloud:CEXP0:-12461
Loose/in: cexp:0:c:1829
cloud:PWMD:64
cloud:PWMD2:80
cloud:WL1:94
cloud:T3:768
cloud:PH:820
cloud:SAL:305
cloud:CEXP0:-12459
Loose/in: cexp:0:c:1829
cloud:PWMD:67
cloud:PWMD2:77
cloud:WL1:96
cloud:C0:85
cloud:T1:717
cloud:T3:766
Loose/in: cexp:0:c:1829
cloud:PWMD:69
cloud:PWMD2:75
cloud:WL1:95
cloud:T1:719
cloud:SAL:306
Loose/in: cexp:0:c:1829
cloud:PWMD:72
cloud:PWMD2:72
cloud:WL1:96
cloud:T3:768
Loose/in: cexp:0:c:1828
cloud:PWMD:75
cloud:PWMD2:69
cloud:C0:84
cloud:SAL:305
cloud:CEXP0:-12460
Loose/in: cexp:0:c:1828
cloud:PWMD:77
cloud:PWMD2:67
Loose/in: cexp:0:c:1829
cloud:PWMD:80
cloud:PWMD2:64
cloud:WL1:95
cloud:C0:85
cloud:SAL:306
cloud:CEXP0:-12459
Loose/in: cexp:0:c:1829
cloud:PWMD:82
cloud:PWMD2:62
cloud:WL1:96
cloud:SAL:305
Loose/in: cexp:0:c:1829
cloud:PWMD:85
cloud:PWMD2:59
cloud:PH:821
cloud:SAL:306
Loose/in: cexp:0:c:1829
cloud:PWMD:87
cloud:PWMD2:57
cloud:WL1:95
cloud:PH:820
cloud:SAL:305
Loose/in: cexp:0:c:1830
cloud:PWMD:89
cloud:PWMD2:55
cloud:C0:86
cloud:CEXP0:-12458
Loose/in: cexp:0:c:1830
cloud:PWMD:91
cloud:PWMD2:53
cloud:WL1:97
cloud:T3:766
Loose/in: cexp:0:c:1829
cloud:PWMD:93
cloud:R1:193
R1:193
cloud:PWMD2:51
cloud:WL1:0
cloud:WL2:0
cloud:WL3:0
cloud:WL4:0
cloud:C0:85
cloud:PH:821
cloud:SAL:60
cloud:CEXP0:-12459
Loose/in: cexp:0:c:1829
cloud:PWMD:95
cloud:PWMD2:49
cloud:PH:820
Loose/in: cexp:0:c:1829
cloud:PWMD:96
cloud:PWMD2:48
Loose/in: cexp:0:c:1828
cloud:PWMD:98
cloud:PWMD2:46
cloud:C0:84
cloud:CEXP0:-12460
Loose/in: cexp:0:c:1829
cloud:PWMD:99
cloud:PWMD2:45
cloud:C0:85
cloud:CEXP0:-12459
Loose/in: cexp:0:c:1828
cloud:C0:84
cloud:PH:821
cloud:CEXP0:-12460
Loose/in: cexp:0:c:1829
cloud:C0:85
cloud:CEXP0:-12459
Loose/in: cexp:0:c:1829
Loose/in: cexp:0:c:1829
cloud:PWMD:98
cloud:PWMD2:46
cloud:PH:820
Loose/in: cexp:0:c:1828
cloud:C0:84
cloud:PH:821
cloud:CEXP0:-12460
Loose/in: cexp:0:c:1828
cloud:PWMD:97
cloud:R1:195
R1:195
cloud:PWMD2:47
cloud:WL1:96
cloud:WL2:90
cloud:WL3:3
cloud:WL4:1
cloud:PH:820
cloud:SAL:305
Loose/in: cexp:0:c:1829
cloud:PWMD:95
cloud:PWMD2:49
cloud:WL1:95
cloud:WL2:87
cloud:C0:85
cloud:SAL:306
cloud:CEXP0:-12459
Loose/in: cexp:0:c:1827
cloud:PWMD:94
cloud:PWMD2:50
cloud:WL1:96
cloud:WL2:90
cloud:C0:83
cloud:CEXP0:-12461
Loose/in: cexp:0:c:1827
cloud:PWMD:92
cloud:PWMD2:52
cloud:WL1:98
cloud:WL2:92
cloud:PH:821
cloud:SAL:305
Loose/in: cexp:0:c:1826
cloud:PWMD:90
cloud:PWMD2:54
cloud:WL1:100
Loose/in: cexp:0:c:1826
cloud:WL2:93
cloud:C0:82
cloud:CEXP0:-12462
cloud:PWMD:88
Loose/in: cexp:0:c:1826
cloud:PWMD2:56
cloud:WL1:97
cloud:WL2:94
cloud:PH:820
cloud:PWMD:86
Loose/in: cexp:0:c:1825
cloud:PWMD2:58
cloud:WL1:101
cloud:WL2:95
cloud:PWMD:84
Loose/in: cexp:0:c:1825
cloud:PWMD2:60
cloud:WL2:96
cloud:C0:81
cloud:CEXP0:-12463
cloud:PWMD:81
cloud:PWMD2:63
cloud:WL1:103
cloud:WL2:97
cloud:SAL:306
Loose/in: cexp:0:c:1826
cloud:PWMD:79
Loose/in: cexp:0:c:1825
cloud:PWMD2:65
cloud:WL2:96
cloud:C0:82
cloud:T1:721
cloud:SAL:305
cloud:CEXP0:-12462
cloud:PWMD:76
Loose/in: cexp:0:c:1715
cloud:PWMD2:68
cloud:WL1:101
cloud:C0:81
cloud:CEXP0:-12463
cloud:PWMD:73
Loose/in: cexp:0:c:781
cloud:PWMD2:71
cloud:WL1:103
cloud:WL2:95
cloud:C0:227
cloud:T1:719
cloud:CEXP0:-12573
Loose/in: cexp:0:c:363
cloud:PWMD:71
cloud:PWMD2:73
cloud:WL1:100
cloud:WL2:94
cloud:C0:69
cloud:CEXP0:-14173
Loose/in: cexp:0:c:173
cloud:PWMD:68
cloud:PWMD2:76
cloud:C0:163
cloud:PH:819
cloud:CEXP0:-14363
Loose/in: cexp:0:c:85
cloud:PWMD:65
cloud:PWMD2:79
cloud:WL1:99
cloud:WL2:93
cloud:C0:229
cloud:PH:820
cloud:SAL:306
cloud:CEXP0:5185
Loose/in: cexp:0:c:43
cloud:PWMD:63
cloud:PWMD2:81
cloud:WL2:92
cloud:C0:23
cloud:T1:721
cloud:SAL:305
cloud:CEXP0:5143
Loose/in: cexp:0:c:23
cloud:PWMD:60
cloud:PWMD2:84
cloud:WL1:96
cloud:WL2:91
cloud:PH:821
cloud:CEXP0:5123
Loose/in: cexp:0:c:13
cloud:PWMD:58
cloud:PWMD2:86
cloud:WL1:98
cloud:C0:249
cloud:PH:820
cloud:CEXP0:5113
Loose/in: cexp:0:c:8
cloud:PWMD:56
cloud:PWMD2:88
cloud:WL1:93
cloud:WL2:89
cloud:C0:6
cloud:T1:719
cloud:CEXP0:518
Loose/in: cexp:0:c:6
cloud:PWMD:54
cloud:PWMD2:90
cloud:WL1:95
cloud:C0:4
cloud:T1:721
cloud:CEXP0:516
Loose/in: cexp:0:c:4
cloud:PWMD:52
cloud:PWMD2:92
cloud:WL2:88
cloud:C0:2
cloud:CEXP0:514
Loose/in: cexp:0:c:3
cloud:PWMD:50
cloud:PWMD2:94
cloud:WL1:93
cloud:WL2:87
cloud:C0:1
cloud:T1:719
cloud:CEXP0:513
Loose/in: cexp:0:c:3
cloud:PWMD:49
cloud:PWMD2:95
cloud:WL1:91
cloud:WL2:86
cloud:T1:721
Loose/in: cexp:0:c:2
cloud:PWMD:47
cloud:PWMD2:97
cloud:WL1:88
cloud:WL2:85
cloud:C0:0
cloud:CEXP0:512
Loose/in: cexp:0:c:2
cloud:PWMD:46
cloud:PWMD2:98
cloud:WL1:99
cloud:WL2:84
cloud:PWME0:18
PWME0:18
cloud:PH:821
Loose/in: cexp:0:c:2
cloud:PWMD:45
cloud:PWMD2:99
cloud:WL1:98
cloud:PH:820
Loose/in: cexp:0:c:1
cloud:WL1:93
cloud:WL2:83
cloud:C0:255
cloud:CEXP0:511
Loose/in: cexp:0:c:1
cloud:WL1:97
cloud:WL2:82
Loose/in: cexp:0:c:1
cloud:WL1:94
cloud:WL2:81
cloud:PH:821
Loose/in: cexp:0:c:1
cloud:PWMD:46
cloud:PWMD2:98
cloud:WL1:97
cloud:PH:820
Loose/in: cexp:0:c:1
cloud:PWMD:47
cloud:PWMD2:97
cloud:WL1:95
Loose/in: cexp:0:c:1
cloud:PWMD:48
cloud:PWMD2:96
cloud:WL1:97
Loose/in: cexp:0:c:1
cloud:PWMD:49
cloud:PWMD2:95
Loose/in: cexp:0:c:1
cloud:PWMD:51
cloud:PWMD2:93
cloud:WL1:96
Loose/in: cexp:0:c:1
cloud:PWMD:53
cloud:PWMD2:91
cloud:WL1:97
cloud:WL2:82
Loose/in: cexp:0:c:163
cloud:PWMD:55
cloud:PWMD2:89
cloud:WL1:96
cloud:C0:219
cloud:CEXP0:-14373
Loose/in: cexp:0:c:1066
cloud:PWMD:57
cloud:PWMD2:87
cloud:WL1:94
cloud:C0:90
cloud:CEXP0:-13222
Loose/in: cexp:0:c:1470
cloud:PWMD:59
cloud:PWMD2:85
cloud:WL1:96
cloud:C0:238
cloud:CEXP0:-12818
Loose/in: cexp:0:c:1662
cloud:PWMD:62
cloud:PWMD2:82
cloud:WL1:95
cloud:WL2:81
cloud:C0:174
cloud:PH:821
cloud:CEXP0:-12626
Loose/in: cexp:0:c:1753
cloud:PWMD:64
cloud:PWMD2:80
cloud:C0:9
cloud:PH:820
cloud:CEXP0:-12535
Loose/in: cexp:0:c:1797
cloud:PWMD:67
cloud:PWMD2:77
cloud:WL1:96
cloud:C0:53
cloud:CEXP0:-12491
Loose/in: cexp:0:c:1818
cloud:PWMD:69
cloud:PWMD2:75
cloud:WL1:97
cloud:C0:74
cloud:CEXP0:-12470
Loose/in: cexp:0:c:1828
Try to learn something about everything and everything about something... Thomas Huxley
210gal DT | 50gal sump/refug | Jebao DCP 10000 pump | RO 200-int skimmer | DIY built stand | DIY 160 led, 12 channel, 458 watt, on MakersLED 72" heatsink
User avatar
Loose
Posts: 90
Joined: Fri Sep 01, 2017 8:15 am
Location: Severna Park, MD

Re: 2nd Salinity module w/Cloud Wifi Hub

Post by Loose »

Roberto,

While I had the serial monitor, I wanted to see why it wouldn't auto connect back to the cloud server when power was removed. Does the inability to open the config file for saving have something to do with it?

Code: Select all

*WM: DIRECT-6C-HP ENVY 7640 series
*WM: -93
*WM: Sent config page
*WM: Request redirected to captive portal
*WM: Handle root
*WM: WiFi save
*WM: Parameter
*WM: Cloud Username
*WM: Loose
*WM: Parameter
*WM: Cloud Password
*WM: ##########
*WM: Sent wifi save page
*WM: Connecting to new AP
Checking Wifi Credentials
*WM: Connecting as wifi client...
*WM: Connection result: 
*WM: 3
Should save config
username: Loose
Start
saving config
failed to open config file for writing
{"mqtt_username":"Loose","mqtt_password":"#######"}
IP address: 192.168.1.22
Connecting to cloud server...
Connected
Try to learn something about everything and everything about something... Thomas Huxley
210gal DT | 50gal sump/refug | Jebao DCP 10000 pump | RO 200-int skimmer | DIY built stand | DIY 160 led, 12 channel, 458 watt, on MakersLED 72" heatsink
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: 2nd Salinity module w/Cloud Wifi Hub

Post by rimai »

I can see that the hub is reading fine. It does report numbers around 1828.
There may be something wrong with the calibration process and storing that number into the memory.
Let me dig it up and see what I can find out.
Roberto.
User avatar
Loose
Posts: 90
Joined: Fri Sep 01, 2017 8:15 am
Location: Severna Park, MD

Re: 2nd Salinity module w/Cloud Wifi Hub

Post by Loose »

Good evening Roberto,

I tried doing all of the steps again and still have the two main issues.

1) Cloud wifi Hub will no longer auto-connect to cloud server if power is disconnected. I have to use a paper clip to enter setup mode.

2) Information from attached salinity module doesn't make sense.
- shows as 227 on android app
- RA* screen shows:
Attachments
RA Star custom0.jpg
RA Star custom0.jpg (35.99 KiB) Viewed 6527 times
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: 2nd Salinity module w/Cloud Wifi Hub

Post by rimai »

Load this code and send me the log.

Code: Select all

// Example: storing JSON configuration file in flash file system
//
// Uses ArduinoJson library by Benoit Blanchon.
// https://github.com/bblanchon/ArduinoJson
//
// Created Aug 10, 2015 by Ivan Grokhotkov.
//
// This example code is in the public domain.

#include <ArduinoJson.h>
#include "FS.h"

bool loadConfig() {
  File configFile = SPIFFS.open("/config.json", "r");
  if (!configFile) {
    Serial.println("Failed to open config file");
    return false;
  }

  size_t size = configFile.size();
  if (size > 1024) {
    Serial.println("Config file size is too large");
    return false;
  }

  // Allocate a buffer to store contents of the file.
  std::unique_ptr<char[]> buf(new char[size]);

  // We don't use String here because ArduinoJson library requires the input
  // buffer to be mutable. If you don't use ArduinoJson, you may as well
  // use configFile.readString instead.
  configFile.readBytes(buf.get(), size);

  StaticJsonBuffer<200> jsonBuffer;
  JsonObject& json = jsonBuffer.parseObject(buf.get());

  if (!json.success()) {
    Serial.println("Failed to parse config file");
    return false;
  }

  const char* serverName = json["serverName"];
  const char* accessToken = json["accessToken"];

  // Real world application would store these values in some variables for
  // later use.

  Serial.print("Loaded serverName: ");
  Serial.println(serverName);
  Serial.print("Loaded accessToken: ");
  Serial.println(accessToken);
  return true;
}

bool saveConfig() {
  StaticJsonBuffer<200> jsonBuffer;
  JsonObject& json = jsonBuffer.createObject();
  json["serverName"] = "api.example.com";
  json["accessToken"] = "128du9as8du12eoue8da98h123ueh9h98";

  File configFile = SPIFFS.open("/config.json", "w");
  if (!configFile) {
    Serial.println("Failed to open config file for writing");
    return false;
  }

  json.printTo(configFile);
  return true;
}

void setup() {
  Serial.begin(57600);
  Serial.println("");
  delay(1000);
  Serial.println("Mounting FS...");

  if (!SPIFFS.begin()) {
    Serial.println("Failed to mount file system");
    return;
  }


  if (!saveConfig()) {
    Serial.println("Failed to save config");
  } else {
    Serial.println("Config saved");
  }

  if (!loadConfig()) {
    Serial.println("Failed to load config");
  } else {
    Serial.println("Config loaded");
  }
}

void loop() {
}
Roberto.
User avatar
Loose
Posts: 90
Joined: Fri Sep 01, 2017 8:15 am
Location: Severna Park, MD

Re: 2nd Salinity module w/Cloud Wifi Hub

Post by Loose »

Log below:

Code: Select all

SDK:3.0.0-dev(c0f7b44)/Core:2.5.0=20500000/lwIP:STABLE-2_1_2_RELEASE/glue:1.1/BearSSL:6778687

scandone
state: 0 -> 2 (b0)
state: 2 -> 3 (0)
state: 3 -> 5 (10)
add 0
aid 1
cnt 

connected with K2GVR, channel 6
dhcp client start...
Mounting FS...
Failed to mount file system
ip:192.168.1.16,mask:255.255.255.0,gw:192.168.1.1
pm open,type:2 0
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: 2nd Salinity module w/Cloud Wifi Hub

Post by rimai »

Are you sure you loaded the code.
It is supposed to have a different log.
There is nothing related to wifi on that code.
Roberto.
User avatar
Loose
Posts: 90
Joined: Fri Sep 01, 2017 8:15 am
Location: Severna Park, MD

Re: 2nd Salinity module w/Cloud Wifi Hub

Post by Loose »

Yes but I guess I need to confirm something. I uploaded that code to the Cloud Wifi Hub. Was I supposed to upload it to the RA*?
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: 2nd Salinity module w/Cloud Wifi Hub

Post by rimai »

Yes. Cloud hub.
Roberto.
Post Reply