0

Use Adafruit.io Slider to Trigger Relay
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Use Adafruit.io Slider to Trigger Relay

by bpjmalone on Sat Apr 13, 2019 3:30 pm

Hello, I want to use the slider icon to control the temperature at which a small motor turns on. I am working with a Feather Huzzah, a 5VDC SRD relay, and the Arduino IDE. In my Adafrui.io dashboard, I have a temperature and settemp feed. I believe that my project is similar to this one where triggers are discussed, but I want the trigger to cause the relay to close a normally open switch, not just to send a message:

https://forums.adafruit.com/viewtopic.php?f=56&t=150258&p=742049&hilit=set+temperature+adafruit+io#p742049


My code looks like this (adapted from Adafruit's example - thank you very much!):
Code: Select all | TOGGLE FULL SIZE
// Adafruit IO Temperature & Humidity Example
// Tutorial Link: https://learn.adafruit.com/adafruit-io-basics-temperature-and-humidity
//
// Adafruit invests time and resources providing this open source code.
// Please support Adafruit and open source hardware by purchasing
// products from Adafruit!
//
// Written by Todd Treece for Adafruit Industries
// Copyright (c) 2016-2017 Adafruit Industries
// Licensed under the MIT license.
//
// All text above must be included in any redistribution.

/************************** Configuration ***********************************/

// edit the config.h tab and enter your Adafruit IO credentials
// and any additional configuration needed for WiFi, cellular,
// or ethernet clients.
#include "config.h"

/************************ Example Starts Here *******************************/
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>

// pin connected to DH22 data line
#define DATA_PIN 2

//Relay Pin Variable
const int relayPin = 15;


// create DHT11 instance
DHT_Unified dht(DATA_PIN, DHT11);

// set up the 'temperature' feed
AdafruitIO_Feed *temperature = io.feed("temperature");
AdafruitIO_Feed *settemp = io.feed("settemp");

// Figure out how to receive 'settemp' value from Adafruit IO into this program!

void setup() {

  // start the serial connection
  Serial.begin(115200);

  // wait for serial monitor to open
  while(! Serial);

  // initialize dht11 (changed from dht22)

  // connect to io.adafruit.com
  Serial.print("Connecting to Adafruit IO");
  io.connect();

  // wait for a connection
  while(io.status() < AIO_CONNECTED) {
    Serial.println(io.statusText());
    delay(500);
  }

  // we are connected
  Serial.println();
  Serial.println(io.statusText());

    // Pin Setup/Register
  pinMode(relayPin, OUTPUT);

}


void loop() {

  // io.run(); is required for all sketches.
  // it should always be present at the top of your loop
  // function. it keeps the client connected to
  // io.adafruit.com, and processes any incoming data.
  io.run();

  sensors_event_t event;
  dht.temperature().getEvent(&event);

  float celsius = event.temperature;
  float fahrenheit = (celsius * 1.8) + 32;

  Serial.print("celsius: ");
  Serial.print(celsius);
  Serial.println("C");

  Serial.print("fahrenheit: ");
  Serial.print(fahrenheit);
  Serial.println("F");

  // save fahrenheit (or celsius) to Adafruit IO
  temperature->save(fahrenheit);

  // put your main code here, to run repeatedly:
  // if fahrenheit goes above settemp degrees, turn on motor
 
  if(fahrenheit > 'settemp'){
    powerOnRelay();
  } else if (fahrenheit <= 'settemp') {
    powerOffRelay();
  }
 delay(1000); // Check tempertature every 1 second
  }

void powerOnRelay() {
    digitalWrite(relayPin, HIGH);
    Serial.println("Relay On");
}

void powerOffRelay() {
    digitalWrite(relayPin, LOW);
    Serial.println("Relay Off");
}
 


Any suggestions? Thank you.
Attachments
Capture.JPG
My dashboard:
Capture.JPG (44.27 KiB) Viewed 71 times

bpjmalone
 
Posts: 4
Joined: Tue Mar 05, 2019 1:17 pm

Re: Use Adafruit.io Slider to Trigger Relay

by brubell on Mon Apr 15, 2019 10:40 am

I want to use the slider icon to control the temperature at which a small motor turns on.
but I want the trigger to cause the relay to close a normally open switch, not just to send a message:


Take a look at the subscribe example sketch. Set up your sketch to subscribe to the feed which the slider is connected to.

Whenever the feed value changes, the feed's handler function will fire. From within that function, you'll check against a predefined value, and call either powerOnRelay or powerOffRelay depending on the value.

brubell
 
Posts: 332
Joined: Fri Jul 17, 2015 10:33 pm

Re: Use Adafruit.io Slider to Trigger Relay

by bpjmalone on Mon Apr 15, 2019 2:20 pm

Thank you for your reply, I have incorporated the handler function into my code (lines 117-151). I did not make clear in my initial question that I intended for my code to continuously compare temperature values continuously measured by sensors with the 'settemp' value set in Adafruit.io in order to make a "relay on" or "relay off" decision. My goal is for this comparison to happen regularly (after every ~10 seconds, say), not just when a change to the dashboard item 'settemp' happens. I am trying to make a smart thermostat, in a nutshell. Is that kind of continuous comparison between Adafruit.io 'settemp' values and measured temperatures possible? If so, how?


Code with changes (thank you very much!):
Code: Select all | TOGGLE FULL SIZE
// Adafruit IO Temperature & Humidity Example
// Tutorial Link: https://learn.adafruit.com/adafruit-io-basics-temperature-and-humidity
//
// Adafruit invests time and resources providing this open source code.
// Please support Adafruit and open source hardware by purchasing
// products from Adafruit!
//
// Written by Todd Treece for Adafruit Industries
// Copyright (c) 2016-2017 Adafruit Industries
// Licensed under the MIT license.
//
// All text above must be included in any redistribution.

/************************** Configuration ***********************************/

// edit the config.h tab and enter your Adafruit IO credentials
// and any additional configuration needed for WiFi, cellular,
// or ethernet clients.
#include "config.h"

/************************ Example Starts Here *******************************/
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>

// pin connected to DH22 data line
#define DATA_PIN 2

// create DHT22 instance
DHT_Unified dht(DATA_PIN, DHT11); //changed from DHT22

//Relay Pin Variable
int relayPin = 15;

// set up the 'temperature' and 'humidity' feeds
AdafruitIO_Feed *temperature = io.feed("temperature");
AdafruitIO_Feed *humidity = io.feed("humidity");
AdafruitIO_Feed *settemp = io.feed("settemp");

void setup() {

  // start the serial connection
  Serial.begin(115200);

  // wait for serial monitor to open
  while(! Serial);

  // initialize dht11
  dht.begin();

  // connect to io.adafruit.com
  Serial.print("Connecting to Adafruit IO");
  io.connect();

  // set up a message handler for the settemp feed.
  // the handleMessage function (defined below)
  // will be called whenever a message is
  // received from adafruit io.
  settemp->onMessage(handleMessage);

  // wait for a connection
  while(io.status() < AIO_CONNECTED) {
    Serial.println(io.statusText());
    delay(500);
  }

  // Because Adafruit IO doesn't support the MQTT retain flag, we can use the
  // get() function to ask IO to resend the last value for this feed to just
  // this MQTT client after the io client is connected.
settemp->get();

  // we are connected
  Serial.println();
  Serial.println(io.statusText());

    // Pin Setup/Register
  pinMode(relayPin, OUTPUT);

}


void loop() {

  // io.run(); is required for all sketches.
  // it should always be present at the top of your loop
  // function. it keeps the client connected to
  // io.adafruit.com, and processes any incoming data.
  io.run();

  sensors_event_t event;
  dht.temperature().getEvent(&event);

  float celsius = event.temperature;
  float fahrenheit = (celsius * 1.8) + 32;

  Serial.print("celsius: ");
  Serial.print(celsius);
  Serial.println("C");

  Serial.print("fahrenheit: ");
  Serial.print(fahrenheit);
  Serial.println("F");

  // save fahrenheit temperature to Adafruit IO
  temperature->save(fahrenheit);
 
  delay(3000); // Check tempertature every 3 seconds
 }

// this function is called whenever a 'settemp' message
// is received from Adafruit IO. It was attached to
// the settemp feed in the setup() function above.
// Can the logic below be used continuously, not ust if a change occurred to 'settemp' in my Adafruit.io?

void handleMessage(AdafruitIO_Data *data) {     
  Serial.print("received <- ");
  Serial.println(data->value());
 
  // io.run(); is required for all sketches.
  // it should always be present at the top of your loop
  // function. it keeps the client connected to
  // io.adafruit.com, and processes any incoming data.
 
  io.run();

  sensors_event_t event;
  dht.temperature().getEvent(&event);

  float celsius = event.temperature;
  float fahrenheit = (celsius * 1.8) + 32;

  Serial.print("celsius: ");
  Serial.print(celsius);
  Serial.println("C");

  Serial.print("fahrenheit: ");
  Serial.print(fahrenheit);
  Serial.println("F");

  // save fahrenheit temperature to Adafruit IO
  temperature->save(fahrenheit);
 
  delay(3000); // Check tempertature every 3 seconds
    if(fahrenheit > settemp){
    powerOnRelay();
    } else if (fahrenheit <= settemp) {
    powerOffRelay();
    }
}

void powerOnRelay() {
    digitalWrite(relayPin, HIGH);
    Serial.println("Relay On");
}

void powerOffRelay() {
    digitalWrite(relayPin, LOW);
    Serial.println("Relay Off");
}
 

bpjmalone
 
Posts: 4
Joined: Tue Mar 05, 2019 1:17 pm

Re: Use Adafruit.io Slider to Trigger Relay

by bpjmalone on Mon Apr 15, 2019 4:59 pm

This part of the MQTT API documentation about retrieving "Last Data in Queue" seems promising, but I am too new to programming to really understand how to implement it:

https://io.adafruit.com/api/docs/#operation/lastData

This project uses input from the Adafruit.io dashboard to control a lamp. This bit of code in the sample project imports strings for "ON" and "OFF," but I want to import numbers from the dashboard. Is that possible? Thank you again for your hard work, you guys are amazing!

Code: Select all | TOGGLE FULL SIZE
while (subscription = mqtt.readSubscription(1000)) {

  // we only care about the lamp events
  if (subscription == &lamp) {

    // convert mqtt ascii payload to int
    char *value = (char *)lamp.lastread;
    Serial.print(F("Received: "));
    Serial.println(value);

    // Apply message to lamp
    String message = String(value);
    message.trim();
    if (message == "ON") {digitalWrite(lamp_pin, HIGH);}
    if (message == "OFF") {digitalWrite(lamp_pin, LOW);}

  }
}

bpjmalone
 
Posts: 4
Joined: Tue Mar 05, 2019 1:17 pm

Re: Use Adafruit.io Slider to Trigger Relay

by brubell on Mon Apr 15, 2019 6:25 pm

Instead of converting characters, like in the example:

Code: Select all | TOGGLE FULL SIZE
    // convert mqtt ascii payload to int
    char *value = (char *)lamp.lastread;
    Serial.print(F("Received: "));
    Serial.println(value);


You would want to cast the incoming MQTT data as a number so you can compare it against another number. Data from adafruit IO needs to be converted.

Check out the type conversion (example 05) reference included with Adafruit IO Arduino, specifically the handleMessage function:
https://github.com/adafruit/Adafruit_IO ... n.ino#L137

Converting to a double:
https://github.com/adafruit/Adafruit_IO ... n.ino#L154

Converting to an int:
https://github.com/adafruit/Adafruit_IO ... n.ino#L164

Converting to a float:
https://github.com/adafruit/Adafruit_IO ... n.ino#L160

Keep in mind - the type of data you are comparing needs to be the same. If you are comparing a `float celsius` value to an incoming piece data, the incoming data should first be converted to a `float`.

brubell
 
Posts: 332
Joined: Fri Jul 17, 2015 10:33 pm

Re: Use Adafruit.io Slider to Trigger Relay

by bpjmalone on Tue Apr 16, 2019 10:25 am

Excellent, this may be exactly what I need to receive "constant" messages from the dashboard to compare to my temperature values. I'll post results later in the week. Thank you.

bpjmalone
 
Posts: 4
Joined: Tue Mar 05, 2019 1:17 pm

Please be positive and constructive with your questions and comments.