Raspberry Pi 3 + Cayenne + local functions


#1

Hello, I have made project with Arduino UNO for controlling home heating. I was need in Cayenne only monitoring temperatures, and if internet lost that Arduino to continue controlling heating, water pump and etc. But now Arduino for me is too slow, too small :slight_smile: I want to remake my project on more powerful Raspberry Pi 3.

In Raspberry I completely newbie :smiley: and I don’t know is it possible make Raspberry with same DS18B20 sensors to send temperatures to Cayenne and by the same DS18B20 temperature will control relays and circulation pumps independently from Cayenne and internet connection (I need this for safety, and all IF conditions should run independently for example:
if (akum_temp3 < 70) {

    if (katilo_isejimas > 75 or katilo_isejimas == -127 or dumu_temp > 140) {
      digitalWrite(katilo_siurblys, LOW);
      katilo_siurblys_state = 100;
    } else if (katilo_isejimas < 75 and katilo_isejimas != -127 and dumu_temp < 135) {
      digitalWrite(katilo_siurblys, HIGH);
      katilo_siurblys_state = 0;
    }

  }

My English pretty bad, so if my explanation confusing, please tell me I will try more :slight_smile:


#2

Hello Sir,
Yes you can do your job with Raspberry as well :slight_smile: You can monitor your sensors and also you can make logic. I suggest using Python.

I suggest to see this series from Adafruit, I post a link for exactly the DS18B20 sensor (Lesson 11) but you can start from the begging to get familiar with Raspberry and its functionalities:


#3

Hello @ognqn.chikov, thank you for reply :slight_smile:

Maybe you can tell me some advice how to implement this? :slight_smile:
Is it possible to run Cayenne for monitoring and same time from same sensor control circulation pump relay? I need this to autorun after restart. My code on Arduino is pretty simple:

//#define CAYENNE_PRINT Serial  
#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
#define akum_kwhV15 V15
#define akum_kwh_procV16 V16
//-------------------------------------------------------------------------------------------------------------------------//



//-------------------------------------------------------------------------------------------------------------------------//
#define katilo_siurblys A0
#define boilerio_voztuvas A1
#define kambario_siurblys A2
#define boilerio_tenas A3 //laisvas portas releje tono valdymui
//-------------------------------------------------------------------------------------------------------------------------//



//-------------------------------------------------------------------------------------------------------------------------//
#define TempDavikliai 2 //DS18B20 davikliu PIN

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



//-------------------------------------------------------------------------------------------------------------------------//
#define kamino_pavara 3
//int pavara = 3;
//-------------------------------------------------------------------------------------------------------------------------//



//-------------------------------------------------------------------------------------------------------------------------//
float katilo_isejimas;  
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;

float akum_kwh;
int akum_kwh_proc;

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

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



//-------------------------------------------------------------------------------------------------------------------------//
int ktcSO = 7;
int ktcCS = 6;
int ktcCLK = 5;

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



//-------------------------------------------------------------------------------------------------------------------------//
int menu_button = 8;  //ant ground naudojama 10kO varza.
int lcd_menu = 0;
//-------------------------------------------------------------------------------------------------------------------------//



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



OneWire oneWire(TempDavikliai);
DallasTemperature sensors(&oneWire);



//-------------------------------------------------------------------------------------------------------------------------//
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[] = "xxxxxxx";

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

byte arduino_mac[] = { 0xxE, 0x9B, 0xx9, 0x56, 0xA7, 0xEA };
IPAddress arduino_ip(192, 168, 7, 110);
IPAddress dns_ip(192, 168, 7, 1);
IPAddress gateway_ip(192, 168, 7, 1);
IPAddress subnet_mask(255, 255, 255, 0);
//-------------------------------------------------------------------------------------------------------------------------//




//---------------------------------------------------------------------------------------------------------------------------------------------------------------------//
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(); // 

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


 
  pinMode(menu_button, INPUT);




 

}
// 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 (akum_temp3 < 70) {

    if (katilo_isejimas > 75 or katilo_isejimas == -127 or dumu_temp > 140) {
      digitalWrite(katilo_siurblys, LOW);
      katilo_siurblys_state = 100;
    } else if (katilo_isejimas < 75 and katilo_isejimas != -127 and dumu_temp < 135) {
      digitalWrite(katilo_siurblys, HIGH);
      katilo_siurblys_state = 0;
    }

  }

  else if (akum_temp3 > 70) {

    if (katilo_isejimas > 85 or katilo_isejimas == -127 or dumu_temp > 140) {
      digitalWrite(katilo_siurblys, LOW);
      katilo_siurblys_state = 100;
    } else if (katilo_isejimas < 85 and katilo_isejimas != -127 and dumu_temp < 135) {
      digitalWrite(katilo_siurblys, HIGH);
      katilo_siurblys_state = 0;
    }

  }

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


  
  //---------------------------------------------------------------------------------//
  if (katilo_isejimas > boilerioTemp and katilo_isejimas > 70) {
    digitalWrite(boilerio_voztuvas, LOW);
    boilerio_voztuvas_state = 100;
  } else if (katilo_isejimas < 69 or katilo_isejimas < boilerioTemp) {
    digitalWrite(boilerio_voztuvas, HIGH);
    boilerio_voztuvas_state = 0;
  }
  //---------------------------------------------------------------------------------//


  
  //---------------------------------------------------------------------------------//
  if (katilo_isejimas > 97) {
    digitalWrite(kambario_siurblys, LOW);
    kambario_siurblys_state = 100;
  } else if (katilo_isejimas < 97) {
    digitalWrite(kambario_siurblys, HIGH);
    kambario_siurblys_state = 0;
  }
  //---------------------------------------------------------------------------------//


 // 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("Ikrauta: ");

    if (akum_kwh_proc <= 0) {
      lcd.setCursor(9, 3);
      lcd.print("0%");
    }
    else if (akum_kwh_proc > 0 and akum_kwh_proc < 100) {
      lcd.setCursor(9, 3);
      lcd.print(akum_kwh_proc);
      lcd.setCursor(12, 3);
      lcd.print("%");
    }

    else if (akum_kwh_proc > 100) {
      lcd.setCursor(9, 3);
      lcd.print(akum_kwh_proc);
      lcd.setCursor(13, 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 ");
    }

  }

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



  akum_kwh = ((((akum_temp1 + akum_temp2 + akum_temp3 + akum_temp4) / 4) - 30) * 12) / 10;
  akum_kwh_proc = (akum_kwh * 100) / 66;





}
// 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_state);
}


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


CAYENNE_OUT(akum_kwhV15)
{
  Cayenne.virtualWrite(akum_kwhV15, akum_kwh);
}


CAYENNE_OUT(akum_kwh_procV16)
{
  Cayenne.virtualWrite(akum_kwh_procV16, akum_kwh_proc);
}



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

But I need to work this code independently from Cayenne, because offline situation should NOT stop controlling hot water circulation pumps.


#4

I honestly prefer Arduino more for gathering sensor data and controlling relays and general IO. There are less things that can go wrong, and in general it’s just simpler. That said if you really want to do this with a Pi you will have to take advantage of the MQTT API since LCD displays and max6675 sensors are not yet supported. Have a look at the docs here for more info and report back if you have any questions!