Arduino Cayenne bypass Offline

Hello friends :slight_smile:
I have a problem with my Arduino Uno R3 + Ethernet Shield W5100 + Cayenne.
I using Arduino as my home heating controller (controlling circulation pumps, boiler valves etc.)
But sometimes my arduino goes offline, freezes, then not working my LCD display, not changing temperature value on LCD, just freezed and need to restart it.
I think when Arduino trying connect to Cayenne for long long time then it freezes.
So my question can I bypass arduino connection to cayenne if he cant connect for eg. five times. Or maybe possible to make connection every five minutes and other code (control valves and pumps) to work continuously.
In short i need to make that connection to Cayenne could not to stop running other my code or freeze Arduino. (if he cant connect, or no internet, or LAN cable unplugged).
Cayenne I using only for information display, not for controlling. Main code for controlling devices is
unrelated to Cayenne.
I using static IP, becouse if I using DHCP and if unpluged LAN cable or internet at home disconnected arduino freezes at startup.
Other question maybe this problem can be solved if arduino will restart himself automatically for eg. two times in day. Or it is not possible?
Sorry for my bad English, if some of my expressions unclear I will try to explain more :slight_smile:

Hi @cemasss, welcome to the Cayenne Community.

While I am not sure whether it is our attempting to connect to Cayenne that’s causing your Arduino to occasionally freeze, it should be easy enough to delay this to once every 5 minutes so you can test to see if you’re getting better behavior.

You can add a delay to your sketch code with the delay() command.
It works in milliseconds so delay(300000) would be 5 minutes.

try adding it to your loop section like this:

void loop()
{
 Cayenne.run();
 delay(300000)
}

Programmatically resetting the Arduino can be a bit trickier but here is how some other users have accomplished it: Arduino Playground - ArduinoReset

Hello, thank you for reply.
But if I add delay in loop it will stop all my program and then pumps and valves will be uncontrolled.
Maybe my code will help:

//#define CAYENNE_PRINT Serial  // Kad sutaupyti atminties galima uzkomentuoti.
#include <OneWire.h>
#include <DallasTemperature.h>
#include <CayenneEthernet.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <max6675.h>



// Aprasyti virtualus PIN'ai rysiui su Cayenne
//-------------------------------------------------------------------------------------------------------------------------//
#define AkumTempV1 V1
#define AkumTempV2 V2
#define AkumTempV3 V3
#define AkumTempV4 V4
#define katilo_isejimasV5 V5
#define katilo_griztamasV6 V6
#define katilo_siurblysV7 V7
#define boilerio_tempV8 V8
#define lauko_tempV9 V9
#define boilerio_voztuvasV10 V10
#define kambario_siurblysV11 V11
#define kamino_pavaraV12 V12
#define dumu_tempV13 V13
#define svetaines_tempV14 V14
//-------------------------------------------------------------------------------------------------------------------------//


// Aprasyti reliu PIN'ai, valdomi per Analog
//-------------------------------------------------------------------------------------------------------------------------//
#define katilo_siurblys A0
#define boilerio_voztuvas A1
#define kambario_siurblys A2
#define boilerio_tenas A3 //laisvas portas releje tono valdymui
//-------------------------------------------------------------------------------------------------------------------------//


// Aprasyti temperaturu davikliu PIN'ai
//-------------------------------------------------------------------------------------------------------------------------//
#define TempDavikliai 2 //DS18B20 davikliu PIN

//-------------------------------------------------------------------------------------------------------------------------//


// TESTAVIVUI APRASYTA KAMINO PAVAROS PIN'AS
//-------------------------------------------------------------------------------------------------------------------------//
#define kamino_pavara 3
//int pavara = 3;
//-------------------------------------------------------------------------------------------------------------------------//


// Aprasyti temperaturu kintamieji
//-------------------------------------------------------------------------------------------------------------------------//
float katilo_isejimas;  // apsirasomas kintamasis reliu valdymo if salygai
float katilo_griztamas;
float dumu_temp;

float boilerioTemp;

float svetaines_temp;

float akum_temp1;
float akum_temp2;
float akum_temp3;
float akum_temp4;

float laukoTemp;

//-------------------------------------------------------------------------------------------------------------------------//


// Aprasyti dumu daviklio konkatu PIN'ai
//-------------------------------------------------------------------------------------------------------------------------//
int ktcSO = 7;
int ktcCS = 6;
int ktcCLK = 5;

MAX6675 ktc(ktcCLK, ktcCS, ktcSO);
//-------------------------------------------------------------------------------------------------------------------------//


// Aprasyti LCD meniu mygtuko PIN'aa ir meniu kintamieji
//-------------------------------------------------------------------------------------------------------------------------//
int menu_button = 8;  //ant ground naudojama 10kO varza.
int lcd_menu = 0;
//-------------------------------------------------------------------------------------------------------------------------//


// Aprasytas LCD ekranas
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address


// DS18B20 davikliams ant OneWire
OneWire oneWire(TempDavikliai);
DallasTemperature sensors(&oneWire);


//DS18B20 davikliu adresu aprasymas
//-------------------------------------------------------------------------------------------------------------------------//
DeviceAddress AkumT1 = { 0x28, 0xFF, 0xE9, 0x68, 0x80, 0x16, 0x03, 0x2B };
DeviceAddress AkumT2 = { 0x28, 0xFF, 0x7B, 0x0A, 0x80, 0x16, 0x04, 0x0B };
DeviceAddress AkumT3 = { 0x28, 0xFF, 0xAD, 0x2C, 0x80, 0x16, 0x04, 0xB0 };
DeviceAddress AkumT4 = { 0x28, 0xFF, 0xFE, 0x65, 0x80, 0x16, 0x03, 0x9B };

DeviceAddress svetainesT = { 0x28, 0xF8, 0x6A, 0x49, 0x01, 0x00, 0x00, 0xB9 }; //nera dar daviklio

DeviceAddress katilo_isejimo_temp = { 0x28, 0xFF, 0x1E, 0x0E, 0x80, 0x16, 0x04, 0xC6 };
DeviceAddress katilo_griztamo_temp = { 0x28, 0xFF, 0xC4, 0x18, 0x80, 0x16, 0x04, 0x14 };
DeviceAddress boilerio_temp = { 0x28, 0xFF, 0xD2, 0x0C, 0x80, 0x16, 0x04, 0xC2 };
DeviceAddress lauko_temp = { 0x28, 0xFF, 0x24, 0x18, 0x80, 0x16, 0x04, 0xCE };
//-------------------------------------------------------------------------------------------------------------------------//



// Cayenne authentication token. This should be obtained from the Cayenne Dashboard.
char token[] = "xxxxxxxx";

//Cayenne LAN nustatymai
//-------------------------------------------------------------------------------------------------------------------------//

byte arduino_mac[] = { 0xXX, 0xXX, 0xXX, 0xXX, 0xXX,, 0xXX };
IPAddress arduino_ip(xxx, xxx, xxx, xxx);
IPAddress dns_ip(xxx, xxx, xxx, xxx);
IPAddress gateway_ip(xxx, xxx, xxx, xxx);
IPAddress subnet_mask(xxx, xxx, xxx, xxx);
//-------------------------------------------------------------------------------------------------------------------------//



// Setup pradzia
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------//
void setup()
{



  Serial.begin(9600);

  Cayenne.begin(token, arduino_ip, dns_ip, gateway_ip, subnet_mask, arduino_mac);

  // lcd startas
  lcd.begin(20, 4);

  pinMode(katilo_siurblys, OUTPUT); //katilo siurblio reles valdymo tipas OUTPUT
  pinMode(boilerio_voztuvas, OUTPUT); //boilerio voztuvo reles valdymo tipas OUTPUT
  pinMode(kambario_siurblys, OUTPUT);
  pinMode(boilerio_tenas, OUTPUT);

  // Persikrovus valdikliui siurbliai isjungiami.
  digitalWrite(katilo_siurblys, HIGH);
  digitalWrite(boilerio_voztuvas, HIGH);
  digitalWrite(kambario_siurblys, HIGH);
  digitalWrite(boilerio_tenas, HIGH);
  

  sensors.begin(); // Uzkuriam DS18B20 daviklius

  sensors.setResolution(AkumT1, 9); //Rezoliucija: 9 - 0.5°C; Rezoliucija: 10 - 0.25°C; Rezoliucija: 11 - 0.125°C;
  sensors.setResolution(AkumT2, 9);
  sensors.setResolution(AkumT3, 9);
  sensors.setResolution(AkumT4, 9);
  sensors.setResolution(svetainesT, 9);
  sensors.setResolution(katilo_isejimo_temp, 9);
  sensors.setResolution(katilo_griztamo_temp, 9);
  sensors.setResolution(boilerio_temp, 9);
  sensors.setResolution(lauko_temp, 9);


   //lcd meniu valdymui
  pinMode(menu_button, INPUT);
  // digitalWrite(menu_button, LOW);      // turn on pullup resistor



  //pinMode(pavara, OUTPUT);

}
// Setup pabaiga
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------//



// Loop pradzia
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------//
void loop()
{

  Cayenne.run();

  sensors.requestTemperatures();

  katilo_isejimas = (sensors.getTempC(katilo_isejimo_temp));
  katilo_griztamas = (sensors.getTempC(katilo_griztamo_temp));
  dumu_temp = ktc.readCelsius();

  boilerioTemp = (sensors.getTempC(boilerio_temp));

  akum_temp1 = (sensors.getTempC(AkumT1));
  akum_temp2 = (sensors.getTempC(AkumT2));
  akum_temp3 = (sensors.getTempC(AkumT3));
  akum_temp4 = (sensors.getTempC(AkumT4));
  
  svetaines_temp = (sensors.getTempC(svetainesT));

  laukoTemp = (sensors.getTempC(lauko_temp));


  // Katilo siurblio valdymo salyga
  //---------------------------------------------------------------------------------//
  if (katilo_isejimas > 80 or katilo_isejimas == -127 or dumu_temp > 130) {
    digitalWrite(katilo_siurblys, LOW);
  } else if (katilo_isejimas < 79 and katilo_isejimas != -127 and dumu_temp < 125) {
    digitalWrite(katilo_siurblys, HIGH);
  }
  //---------------------------------------------------------------------------------//


  // Boilerio voztuvo valdymo salyga
  //---------------------------------------------------------------------------------//
  if (katilo_isejimas > boilerioTemp and katilo_isejimas > 65) {
    digitalWrite(boilerio_voztuvas, LOW);
  } else if (katilo_isejimas < 64 or katilo_isejimas < boilerioTemp) {
    digitalWrite(boilerio_voztuvas, HIGH);
  }
  //---------------------------------------------------------------------------------//


  // Kambario siurblio valdymo salyga (apsauga nuo katilo perkaitimo)
  //---------------------------------------------------------------------------------//
  if (katilo_isejimas > 95) {
    digitalWrite(kambario_siurblys, LOW);
  } else if (katilo_isejimas < 92) {
    digitalWrite(kambario_siurblys, HIGH);
  }
  //---------------------------------------------------------------------------------//



  // LCD meniu
  //---------------------------------------------------------------------------------//
  if (digitalRead(menu_button) == LOW) {
    delay(100);                        // delay to debounce switch

    lcd_menu = lcd_menu + 1;
    lcd.clear();
    if (lcd_menu > 3) {
      lcd_menu = 0;
    }
  }

  if (lcd_menu > 0) {
    lcd.backlight();
  }
  else {
    lcd.noBacklight();
    lcd.clear();
  }

  if (lcd_menu == 1) {

    // lcd.clear();
    lcd.setCursor(1, 0);
    lcd.print("Katilo temperatura");
    lcd.setCursor(0, 1);
    lcd.print("Paduodamas: ");
    lcd.setCursor(12, 1);
    if (katilo_isejimas == -127) {
      lcd.print("Er");
    }
    else {
      lcd.print(katilo_isejimas, 0);
    }
    lcd.setCursor(15, 1);
    lcd.print("C");
    lcd.setCursor(0, 2);
    lcd.print("Griztamas: ");
    lcd.setCursor(12, 2);
    if (katilo_griztamas == -127) {
      lcd.print("Er");
    }
    else {
      lcd.print(katilo_griztamas, 0);
    }

    lcd.setCursor(15, 2);
    lcd.print("C");
    lcd.setCursor(0, 3);
    lcd.print("Dumu temp: ");

    if (dumu_temp < 100) {
      lcd.setCursor(12, 3);
      lcd.print("       ");
      if (dumu_temp == -127) {
        lcd.setCursor(12, 3);
        lcd.print("Er");
        lcd.setCursor(15, 3);
        lcd.print("C");
      }
      else {
        lcd.setCursor(12, 3);
        lcd.print("       ");
        lcd.setCursor(12, 3);
        lcd.print(dumu_temp, 0);
        lcd.setCursor(15, 3);
        lcd.print("C");
      }
    }

    if (dumu_temp > 99) {
      if (dumu_temp == -127) {
        lcd.setCursor(12, 3);
        lcd.print("       ");
        lcd.setCursor(12, 3);
        lcd.print("Er");
        lcd.setCursor(15, 3);
        lcd.print("C");
      }
      else {
        lcd.setCursor(12, 3);
        lcd.print("       ");
        lcd.setCursor(12, 3);
        lcd.print(dumu_temp, 0);
        lcd.setCursor(16, 3);
        lcd.print("C");
      }
    }


 }

  else if (lcd_menu == 2) {

    //  lcd.clear();
    lcd.setCursor(1, 0);
    lcd.print("Akumuliacines temp");
    lcd.setCursor(0, 1);
    lcd.print("T1: ");
    lcd.setCursor(4, 1);
    if (akum_temp1 == -127) {
      lcd.print("Er");
    }
    else {
      lcd.print(akum_temp1, 0);
    }

    lcd.setCursor(7, 1);
    lcd.print("C");
    lcd.setCursor(12, 1);
    lcd.print("T2: ");
    lcd.setCursor(16, 1);
    if (akum_temp2 == -127) {
      lcd.print("Er");
    }
    else {
      lcd.print(akum_temp2, 0);
    }
    lcd.setCursor(19, 1);
    lcd.print("C");
    lcd.setCursor(0, 2);
    lcd.print("T3: ");
    lcd.setCursor(4, 2);
    if (akum_temp3 == -127) {
      lcd.print("Er");
    }
    else {
      lcd.print(akum_temp3, 0);
    }
    lcd.setCursor(7, 2);
    lcd.print("C");
    lcd.setCursor(12, 2);
    lcd.print("T4: ");
    lcd.setCursor(16, 2);
    if (akum_temp4 == -127) {
      lcd.print("Er");
    }
    else {
      lcd.print(akum_temp4, 0);
    }
    lcd.setCursor(19, 2);
    lcd.print("C");
    lcd.setCursor(0, 3);
    lcd.print("Griztamas: ");
    lcd.setCursor(11, 3);
    lcd.print("???");
  }


  else if (lcd_menu == 3) {

    //  lcd.clear();
    lcd.setCursor(6, 0);
    lcd.print("Boileris");
    lcd.setCursor(0, 1);
    lcd.print("Temperatura: ");
    lcd.setCursor(13, 1);
    if (boilerioTemp == -127) {
      lcd.print("Er");
    }
    else {
      lcd.print(boilerioTemp, 0);
    }
    lcd.setCursor(16, 1);
    lcd.print("C");
    lcd.setCursor(0, 2);
    lcd.print("Voztuvas: ");


    if (!digitalRead(boilerio_voztuvas)) {

      lcd.setCursor(10, 2);
      lcd.print("atidarytas");
    }
    else {

      lcd.setCursor(10, 2);
      lcd.print("uzdarytas ");
    }
    
  }

  //---------------------------------------------------------------------------------//


}
// Pabaiga void loop
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------//



// Cayenne funkcijos duomenu perdavimui ir gavimui

CAYENNE_IN(kamino_pavaraV12)
{
  // get value sent from dashboard
  int currentValue = getValue.asInt() / 1023; // 0 to 1023
  Serial.println(currentValue);
  if (currentValue == 0) {
    analogWrite(kamino_pavara, 255);
  }
  else if (currentValue == 1) {
    analogWrite(kamino_pavara, 230);
  }
  else if (currentValue == 2) {
    analogWrite(kamino_pavara, 205);
  }
  else if (currentValue == 3) {
    analogWrite(kamino_pavara, 180);
  }
  else if (currentValue == 4) {
    analogWrite(kamino_pavara, 155);
  }
  else if (currentValue == 5) {
    analogWrite(kamino_pavara, 130);
  }
  else if (currentValue == 6) {
    analogWrite(kamino_pavara, 105);
  }
  else if (currentValue == 7) {
    analogWrite(kamino_pavara, 80);
  }
  else if (currentValue == 8) {
    analogWrite(kamino_pavara, 55);
  }
  else if (currentValue == 9) {
    analogWrite(kamino_pavara, 30);
  }
  else if (currentValue == 10) {
    analogWrite(kamino_pavara, 0);
  }
}

//Katilo siurblio busenos indikacijai webe
CAYENNE_OUT(katilo_siurblysV7)
{
  if (!digitalRead(katilo_siurblys))
  {
    Cayenne.virtualWrite(katilo_siurblysV7, 100);
  }
  else {
    Cayenne.virtualWrite(katilo_siurblysV7, 0);
  }
}

CAYENNE_OUT(boilerio_voztuvasV10)
{
  if (!digitalRead(boilerio_voztuvas))
  {
    Cayenne.virtualWrite(boilerio_voztuvasV10, 100);
  }
  else {
    Cayenne.virtualWrite(boilerio_voztuvasV10, 0);
  }
}

CAYENNE_OUT(kambario_siurblysV11)
{
  if (!digitalRead(kambario_siurblys))
  {
    Cayenne.virtualWrite(kambario_siurblysV11, 100);
  }
  else {
    Cayenne.virtualWrite(kambario_siurblysV11, 0);
  }
}



// This function is called when the Cayenne widget requests data for the Virtual Pin.
CAYENNE_OUT(AkumTempV1)
{
  // Send the command to get temperatures.
  sensors.requestTemperatures();
  // This command writes the temperature in Celsius to the Virtual Pin.
  Cayenne.celsiusWrite(AkumTempV1, sensors.getTempC(AkumT1));
}

CAYENNE_OUT(AkumTempV2)
{
  // Send the command to get temperatures.
  sensors.requestTemperatures();
  // This command writes the temperature in Celsius to the Virtual Pin.
  Cayenne.celsiusWrite(AkumTempV2, sensors.getTempC(AkumT2));
}

CAYENNE_OUT(AkumTempV3)
{
  // Send the command to get temperatures.
  sensors.requestTemperatures();
  // This command writes the temperature in Celsius to the Virtual Pin.
  Cayenne.celsiusWrite(AkumTempV3, sensors.getTempC(AkumT3));
}

CAYENNE_OUT(AkumTempV4)
{
  // Send the command to get temperatures.
  sensors.requestTemperatures();
  // This command writes the temperature in Celsius to the Virtual Pin.
  Cayenne.celsiusWrite(AkumTempV4, sensors.getTempC(AkumT4));
}

CAYENNE_OUT(katilo_isejimasV5)
{
  // Send the command to get temperatures.
  sensors.requestTemperatures();
  // This command writes the temperature in Celsius to the Virtual Pin.
  Cayenne.celsiusWrite(katilo_isejimasV5, sensors.getTempC(katilo_isejimo_temp));
}

CAYENNE_OUT(katilo_griztamasV6)
{
  // Send the command to get temperatures.
  sensors.requestTemperatures();
  // This command writes the temperature in Celsius to the Virtual Pin.
  Cayenne.celsiusWrite(katilo_griztamasV6, sensors.getTempC(katilo_griztamo_temp));
}

CAYENNE_OUT(boilerio_tempV8)
{
  // Send the command to get temperatures.
  sensors.requestTemperatures();
  // This command writes the temperature in Celsius to the Virtual Pin.
  Cayenne.celsiusWrite(boilerio_tempV8, sensors.getTempC(boilerio_temp));
}

CAYENNE_OUT(lauko_tempV9)
{
  // Send the command to get temperatures.
  sensors.requestTemperatures();
  // This command writes the temperature in Celsius to the Virtual Pin.
  Cayenne.celsiusWrite(lauko_tempV9, sensors.getTempC(lauko_temp));
}

CAYENNE_OUT(dumu_tempV13)
{
  // Send the command to get temperatures.
  // sensors.requestTemperatures();
  // This command writes the temperature in Celsius to the Virtual Pin.
  Cayenne.celsiusWrite(dumu_tempV13, ktc.readCelsius());
}

CAYENNE_OUT(svetaines_tempV14)
{
  // Send the command to get temperatures.
  sensors.requestTemperatures();
  // This command writes the temperature in Celsius to the Virtual Pin.
  Cayenne.celsiusWrite(svetaines_tempV14, sensors.getTempC(svetainesT));
}

Ah yes of course, that was a bad idea on my part, sorry.

This may not be the most elegant solution but I think it will accomplish what you want. Here is a proof of concept, credit to this post.

unsigned long previousMillis = 0; // last time update
long interval = 300000; // interval at which to do something (milliseconds)

void setup()
{
	Serial.begin(9600);
}

void loop()
{
	unsigned long currentMillis = millis();

  if(currentMillis - previousMillis > interval) {
     previousMillis = currentMillis;  

     // do something
     Serial.println("This should only be seen once every 5 minutes");
  }

  delay(1000);
	Serial.println("This should be seen every loop.");
}

This uses the millis() command to time things based on the number of milliseconds since the program began. You should be able to put Cayenne.run(); in the every 5 minute segment, and the rest of your code where my ‘every loop’ text is.

The delay is unnecessary and only there to slow down the amount of output to the serial monitor so you can find the ‘every 5 minutes’ text more easily :slight_smile:

Thank you for your help, I think tomorrow I can try this code. Maybe you see in my code bugs which can cause freeze of arduino?
I noticed that freeze happens randomly, arduino can run four days without restart and not freeze, or it can freeze only few hours after restart, because this I was saying that I think its problem on connection to cayenne. Freeze is dangerous for my project, it can cause overheating :frowning:
Another thought I have, maybe for security I can use two arduino controllers? One for communication with cayenne and second for getting temperatures, controlling valves and pumps?

@cemasss,

In any application where you depend on remote decision making for critical stuff, like the potential for overheating, you should always have a local fail safe.

You cannot depend on your network always being there for a number of reasons.

Cheers,

Craig

Hello :slight_smile:
@rsiegel I trying to input your code with millis, unfortunately its not working, with your code arduino wont connect to cayenne at all. When Cayenne.run placed into millis my arduino allways was offline and didnt connected to cayenne.
Maybe is the another way to set cayenne sync interval? Or its impossible?

@kreggly Hi, yes I understand what always need to have local fail safe. Therefore I did in cayenne only read temperatures and no controlling main system. But was few times when my arduino freezed, for this reason I searching for help in this forum :slight_smile:
Maybe reason of freeze is in my code?
Or maybe someone has ideas how to make my project more safe?
How about using two arduinos? One for communicating with cayenne, and second for main code for controlling valves and pumps?
Or maybe arduino uno to weak and I should use more powerful controller like Raspberry pi?

Thank you all for help :slight_smile:

My guess is that you are reading the temperature sensors far too much. Each CAYENNE_OUT reads them, as does the main loop.

Since your temp variables are global, I would leave the sensors.requestTemperatures(); in your main loop and remove it everywhere else. The values read and returned to Cayenne will be the latest that was read into the sensors class instance.

Also, I would go further and just return the current globals for akum_temp1, akum_temp2, etc, and not call sensors.getTempC in the OUT functions.

Furthermore (already used, ‘Also’ :P), looks like you are doing a digital read of a pin to decide what to display to Cayenne, it might be more efficient to set this state in a global when you make the decision to turn on the output in the main loop, then just output the saved state in your OUT function.

I think what is going on is your sensors.ReadTemperatures(); is getting overwhelmed by constant requests and hangs. You could put debug statements around all of them and see if this is true, but I don’t think that function returns until the bus read cycle is complete.

I suggest you try the above fixes, and let us know.

Cheers,

Craig

ps. You could do a sensors.getDeviceCount() in a loop and see if all your devices are reliably returning. I don’t know what happens if you try and access an array with no data. This could also easily be the source of a hang.

Hello @kreggly
I am beginner on arduino and not everything understood :slight_smile:
Maybe you can write few examples what to do with code? If I ask not too much…
So I need to remove sensors.requestTemperatures(); from whole code and leave only in one place? In beginning of loop?

This advice I didnt understood :frowning: I dont know other way to send temperatures to cayenne. :

Hi @cemasss,

I had a little time… try the following code.

This does not compile for me as the LCD library you are using seems to be non-standard.

//#define CAYENNE_PRINT Serial  // Kad sutaupyti atminties galima uzkomentuoti.
#include <OneWire.h>
#include <DallasTemperature.h>
#include <CayenneEthernet.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <max6675.h>

// Aprasyti virtualus PIN'ai rysiui su Cayenne
//-------------------------------------------------------------------------------------------------------------------------//
#define AkumTempV1 V1
#define AkumTempV2 V2
#define AkumTempV3 V3
#define AkumTempV4 V4
#define katilo_isejimasV5 V5
#define katilo_griztamasV6 V6
#define katilo_siurblysV7 V7
#define boilerio_tempV8 V8
#define lauko_tempV9 V9
#define boilerio_voztuvasV10 V10
#define kambario_siurblysV11 V11
#define kamino_pavaraV12 V12
#define dumu_tempV13 V13
#define svetaines_tempV14 V14
//-------------------------------------------------------------------------------------------------------------------------//


// Aprasyti reliu PIN'ai, valdomi per Analog
//-------------------------------------------------------------------------------------------------------------------------//
#define katilo_siurblys A0
#define boilerio_voztuvas A1
#define kambario_siurblys A2
#define boilerio_tenas A3 //laisvas portas releje tono valdymui
//-------------------------------------------------------------------------------------------------------------------------//


// Aprasyti temperaturu davikliu PIN'ai
//-------------------------------------------------------------------------------------------------------------------------//
#define TempDavikliai 2 //DS18B20 davikliu PIN

//-------------------------------------------------------------------------------------------------------------------------//


// TESTAVIVUI APRASYTA KAMINO PAVAROS PIN'AS
//-------------------------------------------------------------------------------------------------------------------------//
#define kamino_pavara 3
//int pavara = 3;
//-------------------------------------------------------------------------------------------------------------------------//


// Aprasyti temperaturu kintamieji
//-------------------------------------------------------------------------------------------------------------------------//
float katilo_isejimas;  // apsirasomas kintamasis reliu valdymo if salygai
float katilo_griztamas;
float dumu_temp;

float boilerioTemp;

float svetaines_temp;

float akum_temp1;
float akum_temp2;
float akum_temp3;
float akum_temp4;

float laukoTemp;

//some states to hold decisions in
int katilo_siurblys_state = 0;
int boilerio_voztuvas_state = 0;
int kambario_siurblys_state = 0;
int boilerio_tenas_state = 0;

//-------------------------------------------------------------------------------------------------------------------------//


// Aprasyti dumu daviklio konkatu PIN'ai
//-------------------------------------------------------------------------------------------------------------------------//
int ktcSO = 7;
int ktcCS = 6;
int ktcCLK = 5;

MAX6675 ktc(ktcCLK, ktcCS, ktcSO);
//-------------------------------------------------------------------------------------------------------------------------//


// Aprasyti LCD meniu mygtuko PIN'aa ir meniu kintamieji
//-------------------------------------------------------------------------------------------------------------------------//
int menu_button = 8;  //ant ground naudojama 10kO varza.
int lcd_menu = 0;
//-------------------------------------------------------------------------------------------------------------------------//


// Aprasytas LCD ekranas
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address


// DS18B20 davikliams ant OneWire
OneWire oneWire(TempDavikliai);
DallasTemperature sensors(&oneWire);


//DS18B20 davikliu adresu aprasymas
//-------------------------------------------------------------------------------------------------------------------------//
DeviceAddress AkumT1 = { 0x28, 0xFF, 0xE9, 0x68, 0x80, 0x16, 0x03, 0x2B };
DeviceAddress AkumT2 = { 0x28, 0xFF, 0x7B, 0x0A, 0x80, 0x16, 0x04, 0x0B };
DeviceAddress AkumT3 = { 0x28, 0xFF, 0xAD, 0x2C, 0x80, 0x16, 0x04, 0xB0 };
DeviceAddress AkumT4 = { 0x28, 0xFF, 0xFE, 0x65, 0x80, 0x16, 0x03, 0x9B };

DeviceAddress svetainesT = { 0x28, 0xF8, 0x6A, 0x49, 0x01, 0x00, 0x00, 0xB9 }; //nera dar daviklio

DeviceAddress katilo_isejimo_temp = { 0x28, 0xFF, 0x1E, 0x0E, 0x80, 0x16, 0x04, 0xC6 };
DeviceAddress katilo_griztamo_temp = { 0x28, 0xFF, 0xC4, 0x18, 0x80, 0x16, 0x04, 0x14 };
DeviceAddress boilerio_temp = { 0x28, 0xFF, 0xD2, 0x0C, 0x80, 0x16, 0x04, 0xC2 };
DeviceAddress lauko_temp = { 0x28, 0xFF, 0x24, 0x18, 0x80, 0x16, 0x04, 0xCE };
//-------------------------------------------------------------------------------------------------------------------------//



// Cayenne authentication token. This should be obtained from the Cayenne Dashboard.
char token[] = "xxxxxxxx";

//Cayenne LAN nustatymai
//-------------------------------------------------------------------------------------------------------------------------//

byte arduino_mac[] = { 0xXX, 0xXX, 0xXX, 0xXX, 0xXX,, 0xXX };
IPAddress arduino_ip(xxx, xxx, xxx, xxx);
IPAddress dns_ip(xxx, xxx, xxx, xxx);
IPAddress gateway_ip(xxx, xxx, xxx, xxx);
IPAddress subnet_mask(xxx, xxx, xxx, xxx);
//-------------------------------------------------------------------------------------------------------------------------//



// Setup pradzia
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------//
void setup()
{



  Serial.begin(9600);

  Cayenne.begin(token, arduino_ip, dns_ip, gateway_ip, subnet_mask, arduino_mac);

  // lcd startas
  lcd.begin(20, 4);

  pinMode(katilo_siurblys, OUTPUT); //katilo siurblio reles valdymo tipas OUTPUT
  pinMode(boilerio_voztuvas, OUTPUT); //boilerio voztuvo reles valdymo tipas OUTPUT
  pinMode(kambario_siurblys, OUTPUT);
  pinMode(boilerio_tenas, OUTPUT);

  // Persikrovus valdikliui siurbliai isjungiami.
  digitalWrite(katilo_siurblys, HIGH);
  digitalWrite(boilerio_voztuvas, HIGH);
  digitalWrite(kambario_siurblys, HIGH);
  digitalWrite(boilerio_tenas, HIGH);
  

  sensors.begin(); // Uzkuriam DS18B20 daviklius

  sensors.setResolution(AkumT1, 9); //Rezoliucija: 9 - 0.5°C; Rezoliucija: 10 - 0.25°C; Rezoliucija: 11 - 0.125°C;
  sensors.setResolution(AkumT2, 9);
  sensors.setResolution(AkumT3, 9);
  sensors.setResolution(AkumT4, 9);
  sensors.setResolution(svetainesT, 9);
  sensors.setResolution(katilo_isejimo_temp, 9);
  sensors.setResolution(katilo_griztamo_temp, 9);
  sensors.setResolution(boilerio_temp, 9);
  sensors.setResolution(lauko_temp, 9);


   //lcd meniu valdymui
  pinMode(menu_button, INPUT);
  // digitalWrite(menu_button, LOW);      // turn on pullup resistor



  //pinMode(pavara, OUTPUT);

}
// Setup pabaiga
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------//



// Loop pradzia
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------//
void loop()
{

  Cayenne.run();

  //only need to call in this loop
  sensors.requestTemperatures();

  //all these variables are global and used by Cayenne functions to display on dashboard
  katilo_isejimas = (sensors.getTempC(katilo_isejimo_temp));
  katilo_griztamas = (sensors.getTempC(katilo_griztamo_temp));
  dumu_temp = ktc.readCelsius();

  boilerioTemp = (sensors.getTempC(boilerio_temp));

  akum_temp1 = (sensors.getTempC(AkumT1));
  akum_temp2 = (sensors.getTempC(AkumT2));
  akum_temp3 = (sensors.getTempC(AkumT3));
  akum_temp4 = (sensors.getTempC(AkumT4));
  
  svetaines_temp = (sensors.getTempC(svetainesT));

  laukoTemp = (sensors.getTempC(lauko_temp));


  // Katilo siurblio valdymo salyga
  //---------------------------------------------------------------------------------//
  if (katilo_isejimas > 80 or katilo_isejimas == -127 or dumu_temp > 130) {
    katilo_siurblys_state = 0;
    digitalWrite(katilo_siurblys, LOW);
  } else if (katilo_isejimas < 79 and katilo_isejimas != -127 and dumu_temp < 125) {
    katilo_siurblys_state = 100;
    digitalWrite(katilo_siurblys, HIGH);
  }
  //---------------------------------------------------------------------------------//


  // Boilerio voztuvo valdymo salyga
  //---------------------------------------------------------------------------------//
  if (katilo_isejimas > boilerioTemp and katilo_isejimas > 65) {
    boilerio_voztuvas_state = 0;
    digitalWrite(boilerio_voztuvas, LOW);
  } else if (katilo_isejimas < 64 or katilo_isejimas < boilerioTemp) {
    boilerio_voztuvas_state = 100;
    digitalWrite(boilerio_voztuvas, HIGH);
  }
  //---------------------------------------------------------------------------------//


  // Kambario siurblio valdymo salyga (apsauga nuo katilo perkaitimo)
  //---------------------------------------------------------------------------------//
  if (katilo_isejimas > 95) {
    kambario_siurblys_state = 0;
    digitalWrite(kambario_siurblys, LOW);
  } else if (katilo_isejimas < 92) {
    kambario_siurblys_state = 100;
    digitalWrite(kambario_siurblys, HIGH);
  }
  //---------------------------------------------------------------------------------//



  // LCD meniu
  //---------------------------------------------------------------------------------//
  if (digitalRead(menu_button) == LOW) {
    delay(100);                        // delay to debounce switch

    lcd_menu = lcd_menu + 1;
    lcd.clear();
    if (lcd_menu > 3) {
      lcd_menu = 0;
    }
  }

  if (lcd_menu > 0) {
    lcd.backlight();
  }
  else {
    lcd.noBacklight();
    lcd.clear();
  }

  if (lcd_menu == 1) {

    // lcd.clear();
    lcd.setCursor(1, 0);
    lcd.print("Katilo temperatura");
    lcd.setCursor(0, 1);
    lcd.print("Paduodamas: ");
    lcd.setCursor(12, 1);
    if (katilo_isejimas == -127) {
      lcd.print("Er");
    }
    else {
      lcd.print(katilo_isejimas, 0);
    }
    lcd.setCursor(15, 1);
    lcd.print("C");
    lcd.setCursor(0, 2);
    lcd.print("Griztamas: ");
    lcd.setCursor(12, 2);
    if (katilo_griztamas == -127) {
      lcd.print("Er");
    }
    else {
      lcd.print(katilo_griztamas, 0);
    }

    lcd.setCursor(15, 2);
    lcd.print("C");
    lcd.setCursor(0, 3);
    lcd.print("Dumu temp: ");

    if (dumu_temp < 100) {
      lcd.setCursor(12, 3);
      lcd.print("       ");
      if (dumu_temp == -127) {
        lcd.setCursor(12, 3);
        lcd.print("Er");
        lcd.setCursor(15, 3);
        lcd.print("C");
      }
      else {
        lcd.setCursor(12, 3);
        lcd.print("       ");
        lcd.setCursor(12, 3);
        lcd.print(dumu_temp, 0);
        lcd.setCursor(15, 3);
        lcd.print("C");
      }
    }

    if (dumu_temp > 99) {
      if (dumu_temp == -127) {
        lcd.setCursor(12, 3);
        lcd.print("       ");
        lcd.setCursor(12, 3);
        lcd.print("Er");
        lcd.setCursor(15, 3);
        lcd.print("C");
      }
      else {
        lcd.setCursor(12, 3);
        lcd.print("       ");
        lcd.setCursor(12, 3);
        lcd.print(dumu_temp, 0);
        lcd.setCursor(16, 3);
        lcd.print("C");
      }
    }


 }

  else if (lcd_menu == 2) {

    //  lcd.clear();
    lcd.setCursor(1, 0);
    lcd.print("Akumuliacines temp");
    lcd.setCursor(0, 1);
    lcd.print("T1: ");
    lcd.setCursor(4, 1);
    if (akum_temp1 == -127) {
      lcd.print("Er");
    }
    else {
      lcd.print(akum_temp1, 0);
    }

    lcd.setCursor(7, 1);
    lcd.print("C");
    lcd.setCursor(12, 1);
    lcd.print("T2: ");
    lcd.setCursor(16, 1);
    if (akum_temp2 == -127) {
      lcd.print("Er");
    }
    else {
      lcd.print(akum_temp2, 0);
    }
    lcd.setCursor(19, 1);
    lcd.print("C");
    lcd.setCursor(0, 2);
    lcd.print("T3: ");
    lcd.setCursor(4, 2);
    if (akum_temp3 == -127) {
      lcd.print("Er");
    }
    else {
      lcd.print(akum_temp3, 0);
    }
    lcd.setCursor(7, 2);
    lcd.print("C");
    lcd.setCursor(12, 2);
    lcd.print("T4: ");
    lcd.setCursor(16, 2);
    if (akum_temp4 == -127) {
      lcd.print("Er");
    }
    else {
      lcd.print(akum_temp4, 0);
    }
    lcd.setCursor(19, 2);
    lcd.print("C");
    lcd.setCursor(0, 3);
    lcd.print("Griztamas: ");
    lcd.setCursor(11, 3);
    lcd.print("???");
  }


  else if (lcd_menu == 3) {

    //  lcd.clear();
    lcd.setCursor(6, 0);
    lcd.print("Boileris");
    lcd.setCursor(0, 1);
    lcd.print("Temperatura: ");
    lcd.setCursor(13, 1);
    if (boilerioTemp == -127) {
      lcd.print("Er");
    }
    else {
      lcd.print(boilerioTemp, 0);
    }
    lcd.setCursor(16, 1);
    lcd.print("C");
    lcd.setCursor(0, 2);
    lcd.print("Voztuvas: ");


    if (!digitalRead(boilerio_voztuvas)) {

      lcd.setCursor(10, 2);
      lcd.print("atidarytas");
    }
    else {

      lcd.setCursor(10, 2);
      lcd.print("uzdarytas ");
    }
    
  }

  //---------------------------------------------------------------------------------//


}
// Pabaiga void loop
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------//



// Cayenne funkcijos duomenu perdavimui ir gavimui

CAYENNE_IN(kamino_pavaraV12)
{
  // get value sent from dashboard
  int currentValue = getValue.asInt() / 1023; // 0 to 1023
  Serial.println(currentValue);
  if (currentValue == 0) {
    analogWrite(kamino_pavara, 255);
  }
  else if (currentValue == 1) {
    analogWrite(kamino_pavara, 230);
  }
  else if (currentValue == 2) {
    analogWrite(kamino_pavara, 205);
  }
  else if (currentValue == 3) {
    analogWrite(kamino_pavara, 180);
  }
  else if (currentValue == 4) {
    analogWrite(kamino_pavara, 155);
  }
  else if (currentValue == 5) {
    analogWrite(kamino_pavara, 130);
  }
  else if (currentValue == 6) {
    analogWrite(kamino_pavara, 105);
  }
  else if (currentValue == 7) {
    analogWrite(kamino_pavara, 80);
  }
  else if (currentValue == 8) {
    analogWrite(kamino_pavara, 55);
  }
  else if (currentValue == 9) {
    analogWrite(kamino_pavara, 30);
  }
  else if (currentValue == 10) {
    analogWrite(kamino_pavara, 0);
  }
}

//Katilo siurblio busenos indikacijai webe
CAYENNE_OUT(katilo_siurblysV7)
{
  Cayenne.virtualWrite(katilo_siurblysV7, katilo_siurblys_state);  
}

CAYENNE_OUT(boilerio_voztuvasV10)
{
    Cayenne.virtualWrite(boilerio_voztuvasV10, boilerio_voztuvas); 
}

CAYENNE_OUT(kambario_siurblysV11)
{
  Cayenne.virtualWrite(kambario_siurblysV11, kambario_siurblys_state);
}



// This function is called when the Cayenne widget requests data for the Virtual Pin.
CAYENNE_OUT(AkumTempV1)
{
  // This command writes the temperature in Celsius to the Virtual Pin.
  Cayenne.celsiusWrite(AkumTempV1, akum_temp1);
}

CAYENNE_OUT(AkumTempV2)
{
  // This command writes the temperature in Celsius to the Virtual Pin.
  Cayenne.celsiusWrite(AkumTempV2, akum_temp2);
}

CAYENNE_OUT(AkumTempV3)
{
  // This command writes the temperature in Celsius to the Virtual Pin.
  Cayenne.celsiusWrite(AkumTempV3, akum_temp3);
}

CAYENNE_OUT(AkumTempV4)
{
  // This command writes the temperature in Celsius to the Virtual Pin.
  Cayenne.celsiusWrite(AkumTempV4, akum_temp4);
}

CAYENNE_OUT(katilo_isejimasV5)
{
  // This command writes the temperature in Celsius to the Virtual Pin.
  Cayenne.celsiusWrite(katilo_isejimasV5, katilo_isejimas);
}

CAYENNE_OUT(katilo_griztamasV6)
{
  // This command writes the temperature in Celsius to the Virtual Pin.
  Cayenne.celsiusWrite(katilo_griztamasV6, katilo_griztamas);
}

CAYENNE_OUT(boilerio_tempV8)
{
  // This command writes the temperature in Celsius to the Virtual Pin.
  Cayenne.celsiusWrite(boilerio_tempV8, boilerioTemp);
}

CAYENNE_OUT(lauko_tempV9)
{  
  // This command writes the temperature in Celsius to the Virtual Pin.
  Cayenne.celsiusWrite(lauko_tempV9, laukoTemp);
}

CAYENNE_OUT(dumu_tempV13)
{ 
  // This command writes the temperature in Celsius to the Virtual Pin.
  Cayenne.celsiusWrite(dumu_tempV13, dumu_temp);
}

CAYENNE_OUT(svetaines_tempV14)
{
  // This command writes the temperature in Celsius to the Virtual Pin.
  Cayenne.celsiusWrite(svetaines_tempV14, svetaines_temp);
}

Hello @kreggly , thank you for your time and help :slight_smile:
This morning I modified code, compiled okay.
For now everything working good. I will try not reset arduino few days and I see if it will freeze again or not.
In few days I write results :wink:

p.s. I have stupid question :slight_smile:
It is possible to read compiled code with extension .cod?

1 Like

@cemasss,

Good that that code seem to be working. I was not able to compile.

I don’t know if that is a stupid question or not.

The last time I saw a .cod file was programming PIC microcontrollers.

Why would you want to?

Cheers,

Craig