Adafruit IO Relay and Servo both handling the same message. from web app

Hello,

I am running a servo and a relay from adafruit I/O. Servo works and relay works from their respective dashboards on the adafruit I/O web but both will run together on occasion. I would like them to be completely separated at all times.

Any guidance would be appreciated. Attached is the complete .ino file.

Thanks,

.

Magnetic_Platooning_12-10-2018.ino (3.13 KB)

If you want them separate the 2 things then you should call different functions on receiving different messages and not the same one as you do now.

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

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

as Such:

  // set up a message handler for the 'servo' feed.

  servo_feed->onMessage(handleServoMessage);

  digital->onMessage(handleDigitalMessage);

Thank you very much for the excellent support. :slight_smile: . I really appreciate you taking the time to respond. I am working on a robotics / magnetics project but software is not my area of expertise . So thanks again.

For some reason, after making the changes recommended, I keep getting an error stating that the handleservomessage is not declared in this scope. I tried moving the location and declaring it but I am not successful.

Thanks for your continued support.

The problem is probably in the code you haven't posted ....

BTW, your code is short. So, when you do post it, read this first:
Read this before posting a programming question ...
Pay particular attention to Item #6 on how to post your code in-line using Code Tags.

FinalHorizon1:
Thank you very much for the excellent support. :slight_smile: . I really appreciate you taking the time to respond. I am working on a robotics / magnetics project but software is not my area of expertise . So thanks again.

i was expecting you to create the 2 functions with the new names that there is now reference to:

// this function is called whenever a 'servo' message
// is received from Adafruit IO. it was attached to
// the servo feed in the setup() function above.
void handleMessage(AdafruitIO_Data *data) {

  // convert the data to integer
  int angle = data->toInt();

  // make sure we don't exceed the limit
  // of the servo. the range is from 0
  // to 180.
  if(angle < 0)
    angle = 0;
  else if(angle > 180)
    angle = 180;

     if (angle < 100)
    PWR_PIN == LOW;

   servo.write(angle);
 

  Serial.print("received <- ");
 
  if(data->toPinLevel() == HIGH)
    Serial.println("HIGH");
  else
    Serial.println("LOW");
 
  // write the current state to the led
  digitalWrite(PWR_PIN, data->toPinLevel());
 

}

this was the function that the servo referred to before, you should rename it tovoid handleServoMessage(AdafruitIO_Data *data) so data received for the servo sends to the servo:

  int angle = data->toInt();

  // make sure we don't exceed the limit
  // of the servo. the range is from 0
  // to 180.
  if(angle < 0)
    angle = 0;
  else if(angle > 180)
    angle = 180;

     if (angle < 100)
    PWR_PIN == LOW;

   servo.write(angle);

and create a function called void handleDigitalMessage(AdafruitIO_Data *data) which deals with data received for the relay.

  Serial.print("received <- ");
 
  if(data->toPinLevel() == HIGH)
    Serial.println("HIGH");
  else
    Serial.println("LOW");
 
  // write the current state to the led
  digitalWrite(PWR_PIN, data->toPinLevel());

I hope this is more clear now, these are just snippets and i do not have a complete image of what your handleMessage() was doing before, but i saw it dealing with data from both streams and you wanted them separate (IOW i am not 100% sure which part of the function was dealing with what part of the data, but you should know.)

// Edited by GRH - MagnaDrive Magnetic Platooning Project.  Control for power and magnetic coupling
// Adafruit IO Servo Example
// Tutorial Link: https://learn.adafruit.com/adafruit-io-basics-servo
//
// 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 <Servo.h>

// pin used to control the servo
#define SERVO_PIN 16

// digital pin 0
#define PWR_PIN 0

// create an instance of the servo class
Servo servo;

// set up the 'servo' feed
AdafruitIO_Feed *servo_feed = io.feed("servo");

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

void setup() {

    // set led pin as a digital output
  pinMode(PWR_PIN, OUTPUT);

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

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

  // tell the servo class which pin we are using
  servo.attach(SERVO_PIN);

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

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

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

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

  // we are connected
  Serial.println();
  Serial.println(io.statusText());
  servo_feed->get();
   digital->get();

}

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

}

// this function is called whenever a 'servo' message
// is received from Adafruit IO. it was attached to
// the servo feed in the setup() function above.
void handleMessage(AdafruitIO_Data *data) {

  // convert the data to integer
  int angle = data->toInt();

  // make sure we don't exceed the limit
  // of the servo. the range is from 0
  // to 180.
  if(angle < 0)
    angle = 0;
  else if(angle > 180)
    angle = 180;

     if (angle < 100)
    PWR_PIN == LOW;

   servo.write(angle);
 

  Serial.print("received <- ");
 
  if(data->toPinLevel() == HIGH)
    Serial.println("HIGH");
  else
    Serial.println("LOW");
 
  // write the current state to the led
  digitalWrite(PWR_PIN, data->toPinLevel());
 

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

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

you do see that you are referring to the 'same' handleMessage function here for both the message received for the servo_feed as for the digital ? This is where you should put a "fork in the road" i don't know how to explain it more clearly. (also you have not really motivated your "Bump")

Hello Dev,

I understand your comments about handlemessage and why it is causing the problem and thanks for the help. I am still working on this fix with your suggestion.

Dev,

I have made the changes but am still getting handleDigitalMessage not declared in this scope. I am trying to fix this error.

So have you created the function void handleDigitalMessage() ? and put the part of the code that deals with controlling the relay in there ?

Hi Dev,

These changes compile okay but the web app does not seem to be communicating any longer?

// Edited by GRH - MagnaDrive Magnetic Platooning Project.  Control for power and magnetic coupling
// Adafruit IO Servo Example
// Tutorial Link: https://learn.adafruit.com/adafruit-io-basics-servo
//
// 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 <Servo.h>

// pin used to control the servo
#define SERVO_PIN 16

// digital pin 0
#define PWR_PIN 0

// create an instance of the servo class
Servo servo;

// set up the 'servo' feed
AdafruitIO_Feed *servo_feed = io.feed("servo");

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


void setup() {

    // set led pin as a digital output
  pinMode(PWR_PIN, OUTPUT);

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

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

  // tell the servo class which pin we are using
  servo.attach(SERVO_PIN);

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

  // set up a message handler for the 'servo' feed.
  // the handleMessage function (defined below)
  // will be called whenever a message is
  // received from adafruit io.
 
  
void handleServoMessage(AdafruitIO_Data *data);

   // set up a message handler for the 'digital' feed.
  // the handleMessage function (defined below)
  // will be called whenever a message is
  // received from adafruit io.

  void handledigitalMessage(AdafruitIO_Data *data);
 

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

  // we are connected
  Serial.println();
  Serial.println(io.statusText());
  servo_feed->get();
   digital->get();

}

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

}

// this function is called whenever a 'servo' message
// is received from Adafruit IO. it was attached to
// the servo feed in the setup() function above.
void handleservoMessage(AdafruitIO_Data *data) {

  // convert the data to integer
  int angle = data->toInt();

  // make sure we don't exceed the limit
  // of the servo. the range is from 0
  // to 180.
  if(angle < 0)
    angle = 0;
  else if(angle > 180)
    angle = 180;

     if (angle < 100)
    PWR_PIN == LOW;

   servo.write(angle);
 

  Serial.print("received <- ");
 
  if(data->toPinLevel() == HIGH)
    Serial.println("HIGH");
  else
    Serial.println("LOW");
 
  // write the current state to the led
  digitalWrite(PWR_PIN, data->toPinLevel());
 

}

Do you think I will need to change something in the Adafruit Servo and Digital Library?

No i think you need to re-introduce these lines into your code

servo_feed->onMessage(handleServoMessage);
  digital->onMessage(handledigitalMessage);

within setup() also i think there is a '}' missing for setup()

Just to be complete, this should work:

// Edited by GRH - MagnaDrive Magnetic Platooning Project.  Control for power and magnetic coupling
// Adafruit IO Servo Example
// Tutorial Link: https://learn.adafruit.com/adafruit-io-basics-servo
//
// 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"
#include <Servo.h>

#define SERVO_PIN 16  // pin used to control the servo
#define PWR_PIN 0    // digital pin 0

Servo servo;   // create an instance of the servo class

AdafruitIO_Feed *servo_feed = io.feed("servo");   // set up the 'servo' feed
AdafruitIO_Feed *digital = io.feed("digital");    // set up the 'digital' feed


void setup() {
    
  pinMode(PWR_PIN, OUTPUT);  // set led pin as a digital output  
  Serial.begin(115200);   // start the serial connection  
  while(! Serial);   // wait for serial monitor to open  
  servo.attach(SERVO_PIN);  // tell the servo class which pin we are using  
  Serial.print("Connecting to Adafruit IO");    // connect to io.adafruit.com
  io.connect();
  
  servo_feed->onMessage(handleServoMessage);  // setup a msgHandler for the servo_feed
  digital->onMessage(handleDigitalMessage);   // setup a msgHandler for the digital feed

  while(io.status() < AIO_CONNECTED) {    // wait for a connection 
    Serial.print(".");
    delay(500);
  }  
  Serial.println();  // we are connected
  Serial.println(io.statusText());
  servo_feed->get();
  digital->get();
}

void loop() {
  io.run();
}


void handleServoMessage(AdafruitIO_Data *data) {  // this function is called whenever a 'servo' message
                                                  // is received from Adafruit IO. it was attached to
                                                  // the servo feed in the setup() function above.  
  int angle = data->toInt();         // convert the data to integer  make sure we don't exceed the limit
  if(angle < 0)  angle = 0;          // of the servo. the range is from 0  to 180.
  else if(angle > 180)  angle = 180;    
  if (angle < 100)  PWR_PIN == LOW;
  servo.write(angle);
}

void handleDigitalMessage(AdafruitIO_Data *data) {  // this function is called whenever a 'digital' message
                                                  // is received from Adafruit IO. it was attached to
                                                  // the digital feed in the setup() function above.  
  Serial.print("received <- "); 
  if(data->toPinLevel() == HIGH)      Serial.println("HIGH");
  else    Serial.println("LOW");  
  digitalWrite(PWR_PIN, data->toPinLevel());  // write the current state to the led
}

The tutorial on this page does go through the process for the servo step by step and basically you would have to duplicate all steps for a separate feed unfortunately the code they created is a good example of how comments can obstruct the 'code'
anyway if you've setup the adafruit_io properly and created 2 feeds as instructed here (where they only setup 1 feed of course) all should work as desired.