0

Feather M0 + MQTT + Adafruit.io + Multiple Feeds
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.
Please be positive and constructive with your questions and comments.

Feather M0 + MQTT + Adafruit.io + Multiple Feeds

by IAmOrion on Wed May 11, 2016 10:29 pm

I have an Adafruit Feather M0 WINC. I have, for the time being, quite literally combined 2 adafruit examples into one. The Connecting Wifi example, and the MQTT example.

So my sketch is pretty simple, connects to wifi, then to adafruit.io to send and receive data.

I've created my 2 subscription feeds as required:

Code: Select all | TOGGLE FULL SIZE
const char ONOFF_RELAY1_FEED[] PROGMEM = AIO_USERNAME "/feeds/relay-01";
Adafruit_MQTT_Subscribe relay1 = Adafruit_MQTT_Subscribe(&mqtt, ONOFF_RELAY1_FEED);

const char ONOFF_WANHAOi3[] PROGMEM = AIO_USERNAME "/feeds/wanhao-i3";
Adafruit_MQTT_Subscribe WANHAOi3 = Adafruit_MQTT_Subscribe(&mqtt, ONOFF_WANHAOi3);


I then have my 2 subscribe commands

Code: Select all | TOGGLE FULL SIZE
  mqtt.subscribe(&relay1);
  mqtt.subscribe(&WANHAOi3);


And now the subscription code:

Code: Select all | TOGGLE FULL SIZE
  while ((subscription = mqtt.readSubscription(5000))) {
    if (subscription == &relay1) {

      char *MQTTVal = (char *)relay1.lastread;
     
      Serial.print(F("Relay 1 - Got: "));
      Serial.println(MQTTVal);

      if (0 == strcmp((char *)relay1.lastread, "OFF")) {
        Serial.println(F("Turning Relay 1 OFF"));
        digitalWrite(Relay_1, RELAY_OFF);
      }
      if (0 == strcmp((char *)relay1.lastread, "ON")) {
        Serial.println(F("Turning Relay 1 ON"));
        digitalWrite(Relay_1, RELAY_ON);
      }

      Serial.print(F("STRCMP(")); Serial.print(MQTTVal); Serial.print(F(", OFF) = ")); Serial.println(strcmp((char *)relay1.lastread, "OFF"));
      Serial.print(F("STRCMP(")); Serial.print(MQTTVal); Serial.print(F(", ON) = ")); Serial.println(strcmp((char *)relay1.lastread, "ON"));

      Serial.print(F("STRCMP(")); Serial.print(MQTTVal); Serial.print(F(", OFF1) = ")); Serial.println(strcmp((char *)relay1.lastread, "OFF1"));
      Serial.print(F("STRCMP(")); Serial.print(MQTTVal); Serial.print(F(", ON1) = ")); Serial.println(strcmp((char *)relay1.lastread, "ON1"));

    }
    else if (subscription == &WANHAOi3) {

      char *MQTTVal = (char *)WANHAOi3.lastread;
     
      Serial.print(F("Wanhao i3 - Got: "));
      Serial.println(MQTTVal);

      if (0 == strcmp((char *)WANHAOi3.lastread, "OFF1")) {
        Serial.println(F("Turning Wanhao i3 OFF"));
        digitalWrite(WANHAO_RELAY, TTL_RELAY_OFF);
      }
      if (0 == strcmp((char *)WANHAOi3.lastread, "ON1")) {
        Serial.println(F("Turning Wanhao i3 OFF"));
        digitalWrite(WANHAO_RELAY, TTL_RELAY_ON);
      }

      Serial.print(F("STRCMP(")); Serial.print(MQTTVal); Serial.print(F(", OFF) = ")); Serial.println(strcmp((char *)WANHAOi3.lastread, "OFF"));
      Serial.print(F("STRCMP(")); Serial.print(MQTTVal); Serial.print(F(", ON) = ")); Serial.println(strcmp((char *)WANHAOi3.lastread, "ON"));

      Serial.print(F("STRCMP(")); Serial.print(MQTTVal); Serial.print(F(", OFF1) = ")); Serial.println(strcmp((char *)WANHAOi3.lastread, "OFF1"));
      Serial.print(F("STRCMP(")); Serial.print(MQTTVal); Serial.print(F(", ON1) = ")); Serial.println(strcmp((char *)WANHAOi3.lastread, "ON1"));

    }
  }


Now, I'm really really confused and stuck. For "Relay 1" everything works perfectly.

I added some addition serial prints to help me debug.

So for relay 1 the output is:

Code: Select all | TOGGLE FULL SIZE
Relay 1 - Got: OFF
Turning Relay 1 OFF
STRCMP(OFF, OFF) = 0
STRCMP(OFF, ON) = -8
STRCMP(OFF, OFF1) = -49
STRCMP(OFF, ON1) = -8


When, however, I toggle the switch for the second relay, it fails. The strcmp is way off but I don't understand why. At first I had just copy and pasted the code, then when testing, adafruit.io appeared to sending ON1 or OFF1 instead of just ON or OFF.

Here's the results of the same strcmp output for the Wanhao i3 relay

Code: Select all | TOGGLE FULL SIZE
Wanhao i3 - Got: ON1
STRCMP(ON1, OFF) = 8
STRCMP(ON1, ON) = 49
STRCMP(ON1, OFF1) = 8
STRCMP(ON1, ON1) = 27


Unless I'm missing something stupid, surely STRCMP(ON1, ON1) *should* = 0 ??

What am I doing wrong?

IAmOrion
 
Posts: 65
Joined: Thu May 14, 2015 8:22 am

Re: Feather M0 + MQTT + Adafruit.io + Multiple Feeds

by adafruit_support_mike on Thu May 12, 2016 10:38 pm

[moved to Adafruit.io forum]

adafruit_support_mike
 
Posts: 61876
Joined: Thu Feb 11, 2010 2:51 pm

Re: Feather M0 + MQTT + Adafruit.io + Multiple Feeds

by erikwed on Fri May 13, 2016 2:29 am

I have exactly the same problem. What is wrong here? Please help us out.

erikwed
 
Posts: 17
Joined: Sun Apr 03, 2016 4:51 am

Re: Feather M0 + MQTT + Adafruit.io + Multiple Feeds

by IAmOrion on Fri May 13, 2016 10:37 pm

Erikwed:

Can you test something for me? After adding:

Code: Select all | TOGGLE FULL SIZE
      int len = strlen(MQTTVal);
      Serial.print(F("Wanhao i3 Feed String Length: ")); Serial.println(len);


I realised there was a "space" character. Eg, for OFF1 the character count was 5 (not the expected 4), and for ON1 the count was 4 and not the expected 3!!

After I amended my code by copy and pasting in the character from the serial monitor (since it isn't the space bar) it now works for me!!!

Code: Select all | TOGGLE FULL SIZE
      if (0 == strcmp((char *)WANHAOi3.lastread, "OFF1")) {
        Serial.println(F("Turning Wanhao i3 OFF"));
        digitalWrite(WANHAO_RELAY, TTL_RELAY_OFF);
      }
      if (0 == strcmp((char *)WANHAOi3.lastread, "ON1")) {
        Serial.println(F("Turning Wanhao i3 ON"));
        digitalWrite(WANHAO_RELAY, TTL_RELAY_ON);
      }


The white space after the OFF1 and ON1 is different. Originally I just copied the white space printed in the serial after OFF1 and pasted after OFF1 and after ON1... OFF now worked as intended but ON still wasn't, so I have to conclude the white space char being used is different.

The character after ON1 is:
Code: Select all | TOGGLE FULL SIZE
      \x{1B}   esc escape ctrl-[   033   27   0x1B   


The character after OFF1 is:
Code: Select all | TOGGLE FULL SIZE
      \x{1C}   fs information separator four ctrl-\   034   28   0x1C   


Hey, Mr or Mrs Adafruit Tech Person -- what's that all about!? lol

EDIT::

I think it must be something in the Adafruit MQTT Arduino Library as well as an issue with the adafruit.io site. I say this, because I opened MQTT.fx desktop client and subscribed to the same 2 feeds.

BOTH of my feeds returned ON of OFF (no number 1 added to the end!). Something I did notice though is that when I toggle the second switch on or off, the message is sent TWICE to the client. Whereas my first toggle switch sends each message just once. Eg ON is sent once, and OFF is sent once. But the second toggle switch (with wanhao-i3 feed above in code), Adafruit.io sends the message TWICE for each toggle. So for example, switching on, sends ON twice - with such a tiny time difference!

Here are the time stamps of the 2 messages:

14-05-2016__03/53/25.14005532 - ON
14-05-2016__03/53/25.14005533 - ON

IAmOrion
 
Posts: 65
Joined: Thu May 14, 2015 8:22 am

Re: Feather M0 + MQTT + Adafruit.io + Multiple Feeds

by erikwed on Sat May 14, 2016 2:37 am

Hi jtanner,

thanks for your detailed answer! I also discovered there was some kind of backspace, once I tried it didn't work. Awesome solution to copy and paste, GJ. I found another way: Change the value in the box in ON-OFF in Adafruit IO to 1 and 0 instead of ON-OFF. Then check the output in your sketch by printing the "your feed".lastread value. In my case this printed a 1 + backspace-like (weird character) after the value sent. So if you use the atoi-function, you could check for either 11 or 1 for ON/OFF. This actually works!

erikwed
 
Posts: 17
Joined: Sun Apr 03, 2016 4:51 am

Please be positive and constructive with your questions and comments.