Example of publishing an integer value to arduino thermostat

Moderators: adafruit_support_bill, adafruit

Forum rules
If you're posting code, please make sure your code does not include your Adafruit IO Active Key or WiFi network credentials.
Locked
User avatar
johnzbesko
 
Posts: 15
Joined: Wed Jan 09, 2013 12:34 pm

Example of publishing an integer value to arduino thermostat

Post by johnzbesko »

I have an arduino thermostat for running my brewery. It has two temperature probes and a flowmeter. Currently, it reports to a python program over serial which logs the data and enables me to set a desiredTemp. I've added an ESP8266 and experimented with thingsboard.io and made some progress with mqtt. I am able to connect to a mqtt broker (wirelessly) on my home PC with the following:

$ mosquitto_sub -v -t '#'
v1/devices/me/telemetry {"RIMtemp":71.88,"Mashtemp":75.52,"Flow":3,"SetTemp":90}

I cannot seem to figure out how to send, and for the arduino to properly receive, a new SetTemp. I have been able to successfully perform examples of turning a GPIO pin on and off, but I just want to send a number, desiredTemp, and let the Arduino control the application of heat, ie. turn on/off a pin for a SSD relay. My attempts to send a new SetTemp seem to cause the Arduino to disconnect.

Could anyone please point me to an example? Maybe a tutorial making a simple (no multiple zones, no daily program, extra features, etc.) thermostat with a DHT?

Attached is what I have so far. Thank you for your help.

#include <ArduinoJson.h>
#include <WiFiEspClient.h>
#include <WiFiEsp.h>
#include <WiFiEspUdp.h>
#include <PubSubClient.h>
#define DEBUG true
#define WIFI_AP "MySSID"
#define WIFI_PASSWORD "MyPassword"
char thingsboardServer[] = "192.168.0.250";
#define TOKEN "QJfrkyH27xl3jqK6aPYB"

// Initialize the Ethernet client object
WiFiEspClient espClient;
PubSubClient client(espClient);

#include <SoftwareSerial.h>
const byte rxPin = 6; // Wire this to Tx Pin of ESP8266
const byte txPin = 7; // Wire this to Rx Pin of ESP8266

// We'll use a software serial interface to connect to ESP8266
SoftwareSerial soft (rxPin, txPin);

int status = WL_IDLE_STATUS;
unsigned long lastSend;

#include <Adafruit_MAX31865.h>
#include <SPI.h>

// Use software SPI: CS, DI, DO, CLK
Adafruit_MAX31865 max2 = Adafruit_MAX31865(10, 11, 12, 13);
Adafruit_MAX31865 max = Adafruit_MAX31865(8, 11, 12, 13);
// use hardware SPI, just pass in the CS pin
//Adafruit_MAX31865 max = Adafruit_MAX31865(10);

// The value of the Rref resistor. Use 430.0! 130
#define RREF 428.51 //RIM
#define RREF2 428.51 //MASH

volatile int NbTopsFan; //measuring the rising edges of the signal
long Calc;
int hallsensor = 2; //The pin location of the sensor

void rpm () //This is the function that the interupt calls
{
NbTopsFan++; //This function measures the rising and falling edge of the hall effect sensors signal
}

// this constant is the pin for controlling heating element, OFF and HEAT set output of pin
int heatPin = 3;
const int OFF = 0;
const int HEAT = 1;
int desiredTemp = 90;
unsigned long lastStatusChangeRequest = 0; //Don't want heater cycling too much

void setup()
{
Serial.begin(115200); ///////For Serial monitor
InitWiFi();
client.setServer( thingsboardServer, 1883 );
lastSend = 0;
client.setCallback(on_message);

pinMode(hallsensor, INPUT); //initializes digital pin 3 as an input
pinMode(heatPin, OUTPUT);

max.begin(MAX31865_3WIRE); // set to 2WIRE or 4WIRE as necessary
max2.begin(MAX31865_3WIRE); // set to 2WIRE or 4WIRE as necessary

}


int connectionId;

void loop()
{
status = WiFi.status();
if ( status != WL_CONNECTED) {
while ( status != WL_CONNECTED) {
Serial.print("Attempting to connect to WPA SSID: ");
Serial.println(WIFI_AP);
// Connect to WPA/WPA2 network
status = WiFi.begin(WIFI_AP, WIFI_PASSWORD);
delay(500);
}
Serial.println("Connected to AP");
}

if ( !client.connected() ) {
reconnect();
}

if ( millis() - lastSend > 1000 ) { // Update and send only after 1 seconds
GetTempsFlow();
lastSend = millis();
}

client.loop();
delay(50);
}

void GetTempsFlow()
{
uint16_t rtd = max.readRTD();
float temp = max.temperature(100, RREF)*9/5+32;
uint16_t rtd2 = max2.readRTD();
float temp2 = max2.temperature(100, RREF2)*9/5+32;

NbTopsFan = 0; //Set NbTops to 0 ready for calculations
attachInterrupt(0, rpm, RISING);
delay (2000); //Wait 1 second
detachInterrupt(0); //Disable interrupt when calculating
Calc = (NbTopsFan * 3); // JZ calibration(Pulse frequency x 60) / 7.5Q, = flow rate in L/hour

// Check and print any faults
uint8_t fault = max.readFault();
if (fault) {
Serial.print("Fault 0x"); Serial.println(fault, HEX);
if (fault & MAX31865_FAULT_HIGHTHRESH) {
Serial.println("RTD High Threshold");
}
if (fault & MAX31865_FAULT_LOWTHRESH) {
Serial.println("RTD Low Threshold");
}
if (fault & MAX31865_FAULT_REFINLOW) {
Serial.println("REFIN- > 0.85 x Bias");
}
if (fault & MAX31865_FAULT_REFINHIGH) {
Serial.println("REFIN- < 0.85 x Bias - FORCE- open");
}
if (fault & MAX31865_FAULT_RTDINLOW) {
Serial.println("RTDIN- < 0.85 x Bias - FORCE- open");
}
if (fault & MAX31865_FAULT_OVUV) {
Serial.println("Under/Over voltage");
}
max.clearFault();
}
// Prepare a JSON payload string
String payload = "{";
payload += "\"RIMtemp\":";
payload += temp;payload += ",";
payload += "\"Mashtemp\":";
payload += temp2;

payload += ",";
payload += "\"Flow\":";
payload += Calc;
payload += ",";
payload += "\"SetTemp\":";
payload += desiredTemp;
payload += "}";

// Send payload
char attributes[100];
payload.toCharArray( attributes, 100 );
client.publish( "v1/devices/me/telemetry", attributes );
Serial.println( attributes );
}

// The callback for when a PUBLISH message is received from the server.

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

Serial.println("On message");

char json[length + 1];
strncpy (json, (char*)payload, length);
json[length] = '\0';

Serial.print("Topic: ");
Serial.println(topic);
Serial.print("Message: ");
Serial.println(json);

// Decode JSON request
StaticJsonBuffer<200> jsonBuffer;
JsonObject& data = jsonBuffer.parseObject((char*)json);

if (!data.success())
{
Serial.println("parseObject() failed");
return;
}
// Check request method
String methodName = String((const char*)data["method"]);

if (methodName.equals("getValue")) {
// Reply with GPIO status
String responseTopic = String(topic);
responseTopic.replace("request", "response");
client.subscribe(responseTopic.c_str(), desiredTemp);
Serial.println("get Value: ");
} else if (methodName.equals("setValue")) {
// Update GPIO status and reply
//desiredTemp=data["params"];
Serial.println("Desired Temp: ");
//Serial.println(setValue);
String responseTopic = String(topic);
responseTopic.replace("request", "response");
client.publish(responseTopic.c_str(), desiredTemp);
client.publish("v1/devices/me/attributes", desiredTemp);
}

}

void InitWiFi()
{
// initialize serial for ESP module
soft.begin(9600);
// initialize ESP module
WiFi.init(&soft);
// check for the presence of the shield
if (WiFi.status() == WL_NO_SHIELD) {
Serial.println("WiFi shield not present");
// don't continue
while (true);
}

Serial.println("Connecting to AP ...");
// attempt to connect to WiFi network
while ( status != WL_CONNECTED) {
Serial.print("Attempting to connect to WPA SSID: ");
Serial.println(WIFI_AP);
// Connect to WPA/WPA2 network
status = WiFi.begin(WIFI_AP, WIFI_PASSWORD);
delay(500);
}
Serial.println("Connected to AP");
}

void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Connecting to ThingsBoard node ...");
// Attempt to connect (clientId, username, password)
if ( client.connect("Arduino Uno Device", TOKEN, NULL) ) {
Serial.println( "[DONE]" );
client.subscribe("v1/devices/me/rpc/request/+");
} else {
Serial.print( "[FAILED] [ rc = " );
Serial.print( client.state() );
Serial.println( " : retrying in 5 seconds]" );
// Wait 5 seconds before retrying
delay( 5000 );
}
}
}

Locked
Forum rules
If you're posting code, please make sure your code does not include your Adafruit IO Active Key or WiFi network credentials.

Return to “Internet of Things: Adafruit IO and Wippersnapper”