hellomqttt to thingspeak mqtt and ifttt

Dependencies:   Servo MQTTPacket FP

main.cpp

Committer:
jasonberry
Date:
2021-03-11
Revision:
24:d2e25cdf9084
Parent:
21:a68bd76740f9
Child:
25:ca1b1098c77f

File content as of revision 24:d2e25cdf9084:

/*******************************************************************************
 * Copyright (c) 2014, 2015 IBM Corp.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * and Eclipse Distribution License v1.0 which accompany this distribution.
 *
 * The Eclipse Public License is available at
 *    http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at
 *   http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *    Ian Craggs - initial API and implementation and/or initial documentation
 *    Ian Craggs - make sure QoS2 processing works, and add device headers
 *******************************************************************************/

 /**
  original ported form here https://os.mbed.com/teams/mqtt/wiki/Using-MQTT
  
  This is a sample program to illustrate the use of the MQTT Client library
  on the mbed platform.  The Client class requires two classes which mediate
  access to system interfaces for networking and timing.  As long as these two
  classes provide the required public programming interfaces, it does not matter
  what facilities they use underneath. In this program, they use the mbed
  system libraries.
 */

//STARTED WITH IMPORT FROM HERE https://os.mbed.com/teams/mqtt/code/HelloMQTT/

///////////////////////////////////////////////////////////////////
//IFFT TO THINSPEAK TO THINSPEAK MQTT BROKER TO MBED/ESP8266 CLIENT
///////////////////////////////////////////////////////////////////

// Step1: THINGSPEAK CHANNEL
//..........................
//
//        Set up a Thinspeak channel, record the channel number(1322442), channel read api(mine was H0P76513L8Z3N555), 
//        channel write api(mine was 1PUWBQJL3X64GWL2P), 
//        and look up my profile for thinspeakMQTT api(mine was HXPY4BZ5Z0OPAH0W) ...start channel off 
//
// Step2: TEST THINGSPEAK CHANNEL VIA BROSWER
//...........................................
// 
//        Test thingspeak channel is working using browser by entering in test value 89 as follows
//        https://api.thingspeak.com/update?api_key=PUWBQJL3X64GWL2P&field1=89
//        check thingspeak channel to see if 89 is plotted

// Step3: FIND MQTT.THINGSPEAK.COM FIXED IP ADDRESS
//        Find out fixed ip address of mqtt.thinspeak.com using windons command: tracert mqtt.thinspeak.com
//        at time of testing it was 34.231.253.113...doesnt seem to change much :-) but check it.

// Step4: SETUP A DESK MQTT CLIENT TO TEST THINGSPEAK MQTT BROKER
//        Set up a desktop client to test thingspeak mqtt broker, I used MQTT.fx 1.71 from
//        https://mqttfx.jensd.de/index.php/download.
//
//        This is a good tuturial to show how to set up client and send messages to thigspeak channel via desltop mqtt
//        https://uk.mathworks.com/help/thingspeak/use-desktop-mqtt-client-to-publish-to-a-channel.html#d122e3819
//        
//        In summary from mathswork,
//        click in droplist and select new profile, 
//        broker type: select mqtt broker, 
//        broker address: put in ip address for mqtt.thingspeak.com that you found in step 2, 34.231.253.113 
//        broker port: is 1883, 
//        client id: anything, 
//        username: anything
//        password: is thingspeakMQTT.api HXPY4BZ5Z0OPAH0W
//        Save profile as mbed
//        Next ready to go, press connect hopefully you connect sucessfully
//
//        PUBLISH:
//        Ok now set up to publish to thinspeak channel via mqtt 
//        put channels/1322442/publish/fields/field1/PUWBQJL3X64GWL2P  in publish entry
//        next put some number in field below.. then press publish go to thingspeak and check channel for plot update,
//        put another number in field and publish, again check thinspeak channel..hopefully you see data
//
//        SUBSCRIBE
//        Click on subscribe tab and enter channels/1322442/subscribe/fields/field1/H0P76513L8Z3N555, 
//        click subscribe 
//        Test subscribe by sending data to thinsgspeak channel via browser
//        Go to browser and enter some channel data as step 3, 
//        https://api.thingspeak.com/update?api_key=PUWBQJL3X64GWL2P&field1=67
//        you should see message in mqtt panel with data 67


// Step4: CONFIGURE THE CODE WITH WIFI SETTINGS, DEBUG, PINS ETC
//        In the mbed_app.json file change as required, I wired esp8266 rx to mbed tx pin9, esp8266 tx to mbed rx pin 10        
//        "esp8266-tx": {
//            "help": "Pin used as TX (connects to ESP8266 RX)",
//            "value": "p9"
//        },
//        "esp8266-rx": {
//            "help": "Pin used as RX (connects to ESP8266 TX)",
//            "value": "p10"
//        },
//        "esp8266-ssid": {
//            "value": "1231321423dfdf16_2G"  
//        },
//        "esp8266-password": {
//            "value": "12345"
//
//       If you want to see all the at commands for esp8266, then select debug true in mbed_app.json file
//       pretty cool to see all the messages and good obviously for debug.

// Step 5: COMPILE
//         Compile the code should have no errors
//         famous last words !!!!

// Step 6: WIRE UP ESP8266 TO MBED
//         Wire up the ESP8266 to mbed see following for pinouts esp8266 h
//         https://circuits4you.com/2016/12/14/esp8266-pin-diagram/
//         Use an external power supply for wifi
//
//         ESP pin1(gnd)   to MBED pin 1(gnd)
//         ESP pin2(tx)    to MBED pin 10(rx)
//         ESP pin4(ch en) to MBED 3.3v , I used pin one xbee break out connector on baseboard..
//          see see page 3 for pinout of xbee connector, pin closest to ethernet entry point , 
//          https://os.mbed.com/media/uploads/chris/mbed-014.1_b.pdf 
//
//         ESP pin6(reset) to MBED pin 30 .. not used in this example..but might be used in future so just in case
//         ESP pin7(rx)    to MBED pin 9(tx)
//         ESP pin8(3.3v)  to MBED pin 40(3.3v)

//Step 7: DOWNLOAD TO BOARD

//Step 8: PUTTY
//        Open putty with mbed comm port and 115200 baud

//Step 9: RESET AND RUN CODE
//        Watch putty serial to see if this is output (NO DEBUG)
//        HelloMQTT: version is 111
//        [EasyConnect] Using WiFi (ESP8266)
//        [EasyConnect] Connecting to WiFi..
//        [EasyConnect] Connected to Network successfully
//        [EasyConnect] IP address 192.168.1.6
//        Connecting to 34.231.253.113:1883
//        test point 1..end of subscribe..
//        test point 2..start of publish..
//        Message arrived: qos 0, retained 0, dup 0, packetid 51817
//        Payload 111
//        Message arrived: qos 0, retained 0, dup 0, packetid 51817
//        Payload 111
//        test point 3...end of publish..
//        Version 111: finish 2 msgs

//Step 10: TEST IF THINGSPEAK UPDATED WITH VALUE FROM MBED!!! (MBED WRITE)
//         Check to see if 111 went to thingspeak channel

//Step 11: TEST IF VLAUE SENT TO THINGSPEAK FROM BROWSER FINDS ITS WAS TO (MBED READ)
//         Send test value 44 via browser https://api.thingspeak.com/update?api_key=PUWBQJL3X64GWL2P&field1=44
//         check 44 is in subscribe section of desktop mqtt.fx
//          
//         Then run code by reseting board,check putty output to see if 44 is picked up as a message in mbed.
//

//Step 12: SEND TEMPERATURE UP
//

//Step 13: TURN ON/OFF LED1 ON MBED      
//

//Step14: Set IFTTT APPLET TO SEND VALUE TO MBED VIA THINGSPEAK MQTT
//        use webhook see tuturial for controlling leds via google assistant via ardunio, used this to help
//        see https://www.engineersgarage.com/electronic-projects/esp32-voice-operated-home-automation-with-thingspeak-mqtt-ifttt-and-google-assistant/

//Step15: HTTP-TO-MQTT-BRIDGE(not tested) 
//        Set up https to  mqtt bridge which allow us to send ifttt to mbed without thinspeak.
//        see this tutrial https://www.home-assistant.io/blog/2017/03/28/http-to-mqtt-bridge/

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include "mbed.h"
 // change this to 1 to output messages to LCD instead of serial
#define USE_LCD 0

#if USE_LCD
#include "C12832.h"

// the actual pins are defined in mbed_app.json and can be overridden per target
C12832 lcd(LCD_MOSI, LCD_SCK, LCD_MISO, LCD_A0, LCD_NCS);

#define logMessage lcd.cls();lcd.printf

#else  //use serial printf

#define logMessage pc.printf
Serial pc(USBTX, USBRX);
#endif

#define MQTTCLIENT_QOS2 1

#include "easy-connect.h"
#include "MQTTNetwork.h"
#include "MQTTmbed.h"
#include "MQTTClient.h"

int arrivedcount = 0; //number of message received back from mqtt broker

//message received handler
void messageArrived(MQTT::MessageData& md)
{
    MQTT::Message &message = md.message;
    logMessage("Message arrived: qos %d, retained %d, dup %d, packetid %d\r\n", message.qos, message.retained, message.dup, message.id);
    logMessage("Payload %.*s\r\n", message.payloadlen, (char*)message.payload);
    ++arrivedcount;
    
}


int main(int argc, char* argv[])
{
    int version = 111; //version number used for test messages to mqtt
   
    // mqtt publish and subscribe topics linked to mqtt.thinspeak.com, channel api 
    // and channel read(suscribe) and write(publish) api...these can be used in any mqtt client conection..
    // for pc testing could use mqtt.fx
    // the following mathswork shows how to set up a desktop client to test thinspeak channel
    // https://uk.mathworks.com/help/thingspeak/use-desktop-mqtt-client-to-publish-to-a-channel.html#d122e3819
    
    char* publish_topic = "channels/1322442/publish/fields/field1/PUWBQJL3X64GWL2P";
    char* subscribe_topic = "channels/1322442/subscribe/fields/field1/H0P76513L8Z3N555";
    
    //serial comms at 115200 
    pc.baud(115200); 
    
    logMessage("HelloMQTT: version is %u\r\n", version);

    //set up a wifi connection
    //////////////////////////
    
    //connect to wifi network and display ip address..display in serial
    NetworkInterface* network = easy_connect(true);
    if (!network) {
        return -1;
    }
    
    //set up a MQTT connection
    //////////////////////////
    
    MQTTNetwork mqttNetwork(network);

    MQTT::Client<MQTTNetwork, Countdown> client(mqttNetwork);
    
    // fixed ip for mqtt broker at mqtt.thingspeak.com found using 
    // windows command: tracert mqtt.thinspeak.com ..note will change keep an eye on it
    char* hostname =  "34.231.253.113"; 
    int port = 1883;
    
    logMessage("Connecting to %s:%d\r\n", hostname, port);
    int rc = mqttNetwork.connect(hostname, port);
    if (rc != 0)
        logMessage("rc from TCP connect is %d\r\n", rc);

    //connect to client
    MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
    data.MQTTVersion = 3;
    data.clientID.cstring = "mbed-sample";       //can be any name,client just dont connect from two different client 
    data.username.cstring = "testuser";          //with identical name,client
    data.password.cstring = "HXPY4BZ5Z0OPAH0W";  // this thinspeak mqtt api found in thingspeak profiles
    
    if ((rc = client.connect(data)) != 0)
        logMessage("rc from MQTT connect is %d\r\n", rc);
    
    //subscribe and read last message posted to mqtt
    ////////////////////////////////////////////////    
    //note data received with handled above in  
    if ((rc = client.subscribe(subscribe_topic, MQTT::QOS0, messageArrived)) != 0)
        logMessage("rc from MQTT subscribe is %d\r\n", rc);
        
    
    //debug test message can be turned off once happy with functioning    
    logMessage("test point 1..end of subscribe..\r\n");
    
    //publish and write to mqtt broker..this will then make its way to thinspeak channel
    ////////////////////////////////////////////////////////////////////////////////////
    // note can only publish every 15 seconds to thingspeak mqtt 
    
    MQTT::Message message;

    // QoS 0
    char buf[100];
    //sprintf(buf, "Hello World!  QoS 0 message from app version %f\r\n", version);
    sprintf(buf, "%u",version);//test number is version
    message.qos = MQTT::QOS0;
    message.retained = false; //false;
    message.dup = false;
    message.payload = (void*)buf;
    message.payloadlen = strlen(buf)+1;
     
    logMessage("test point 2..start of publish..\r\n");
    rc = client.publish(publish_topic , message);
    while (arrivedcount < 1)
        client.yield(100);
    logMessage("test point 3...end of publish..\r\n");  
    
/* not tested on this set up other fields possible
    // QoS 1
    sprintf(buf, "Hello World!  QoS 1 message from app version %f\r\n", version);
    message.qos = MQTT::QOS1;
    message.payloadlen = strlen(buf)+1;
    rc = client.publish(publish_topic , message);
    while (arrivedcount < 2)
        client.yield(100);

    // QoS 2
    sprintf(buf, "Hello World!  QoS 2 message from app version %f\r\n", version);
    message.qos = MQTT::QOS2;
    message.payloadlen = strlen(buf)+1;
    rc = client.publish(topic, message);
    while (arrivedcount < 3)
        client.yield(100);
*/

    //unsubscribe and disconnect from client
    ////////////////////////////////////////
    if ((rc = client.unsubscribe(subscribe_topic)) != 0)
        logMessage("rc from unsubscribe was %d\r\n", rc);

    if ((rc = client.disconnect()) != 0)
        logMessage("rc from disconnect was %d\r\n", rc);
        
    //disconnect from wifi network
    //////////////////////////////
    //this would use a lot of current (mA) up battery life,
    //if connecting and disconnecting to wifi each time you sent received a message
    
    mqttNetwork.disconnect();
    wait(1);
    
    logMessage("Version %d: finish %d msgs\r\n", version, arrivedcount);

    return 0;
    
}//end of main, note: no super loop here runs once at reset