hellomqttt to thingspeak mqtt and ifttt

Dependencies:   Servo MQTTPacket FP

main.cpp

Committer:
jasonberry
Date:
2021-05-05
Revision:
25:ca1b1098c77f
Parent:
24:d2e25cdf9084

File content as of revision 25:ca1b1098c77f:

/*******************************************************************************
 * 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/

#include "mbed.h"
#include "string"

#define USE_LCD 1// change this to 1 to output messages to LCD instead of serial

#if USE_LCD
#include "C12832.h"
C12832 lcd(p5, p7, p6, p8, p11);
#define logMessage1  wait(2);lcd.cls();lcd.locate(0,3);lcd.printf
#define logMessage2  wait(2);lcd.cls();lcd.locate(0,15);lcd.printf
#else  //use serial printf
#include "C12832.h"
C12832 lcd(p5, p7, p6, p8, p11);
#define logMessage1 pc.printf
#define logMessage2 pc.printf
#endif

#define MQTTCLIENT_QOS2 1

#define CLIENTID "JASON_BERRY_BOT" 
//#define USERNAME "testuser"
//#define PASSWORD "TUBNO9VEWTIJZ63R" //thingspeak

#define USERNAME "token_2F8Fe1gxYIbVpZbr" //beebotte mqtt
#define PASSWORD "token_2F8Fe1gxYIbVpZbr" //beebotte mqtt

//#define HOSTNAME "54.157.36.210"  //thingspeak mqtt broker 15 sec limit on messages
//#define HOSTNAME "5.196.95.208"     //mosquitto test broker no limit on messages
#define HOSTNAME "54.221.205.80"      //beebotte broker, which can be triggered from iffft webhooks

///STUDENT CHANGE YOUR NETWORK WIFI PASSWORD ETC HERE
#define NETWORK_ID "HUAWEI P30 Pro"
#define NETWORK_PASSWORD "4f54ed7ab852"
     
#include "easy-connect.h"
#include "MQTTNetwork.h"
#include "MQTTmbed.h"
#include "MQTTClient.h"
#include "MMA7660.h"
#include "LM75B.h"
#include "Servo.h"

//funtions prototypes
int boot_up(void);
void messageArrived(MQTT::MessageData& md);
void build_bots_AI_DI_SI_message(char *buf);
void control_bots_AO_DO_SO_message(char *ser_bt_mqtt_rec_mes);

//hardware mapping
DigitalIn  up(p16);
DigitalIn  down(p12);
DigitalOut reset(p30);
DigitalOut led1(LED1); //TEST DO
DigitalOut led2(LED2); //SUPERLOOP
DigitalOut led3(LED3); //MQTT
DigitalOut led4(LED4); //SERIAL,BLUE,PC


//Serial pc(USBTX, USBRX); setup in easy connect
MMA7660 MMA(p28, p27); //I2C Accelerometer
LM75B sensor(p28,p27); // Temperature
Serial blue(p13,p14);  //tx, rx
Servo s1(p21);
Servo s2(p22);


int arrivedcount = 0; //number of message received back from mqtt broker
int version = 88; //version number used for test messages to mqtt

//topics to subscribe
////////////////////////////////////////////////////////////////////////////////////
//thingspeak channel as topic  
////////////////////////////////////////////////////////////////////////////////////   
//char* publish_topic = "channels/1322442/publish/fields/field1/PUWBQJL3X64GWL2P";
//char* subscribe_topic = "channels/1322442/subscribe/fields/field1/H0P76513L8Z3N555";

//mosquitto mbed sample broker topic
///////////////////////////////////////////////////////////////////////////////////
//char* publish_topic = "mbed-sample/";
//char* subscribe_topic = "mbed-sample/";

//bee_botte mqtt topic
///////////////////////////////////////////////////////////////////////////////////

/////this is where you change your bot id..so maybe change to 011, 011do1, o11do2 etc...011so1
char id[] = "010"; //bot id

#define DO1  "010do1"
#define DO2  "010do2"
#define DO3  "010do3"
#define DO4  "010do4"

#define AO1  "010ao1"
#define AO2  "010ao2"
#define AO3  "010ao3"
#define AO4  "010ao4"

#define SO1  "010so1"
//////end of changes required ///////////////////////////////////////////////////////////////////

//beebotte topics
char* publish_topic = "jason/text";
char* subscribe_topic = "jason/text";
char mqtt_message_received[255];
char blue_message_received[255];
char pc_message_received[255];

//outputs variables you can assign these to whatever you want leds,servos
long int ao1=0;
long int ao2=0;
long int ao3=0;
long int ao4=0;

long int do1=0;
long int do2=0;
long int do3=0;
long int do4=0;

char so1[20] = "..";

//input variables
float ai1=0;
float ai2=0;
float ai3=0;
float ai4=0;

int di1=0;
int di2=0;
int di3=0;
int di4=0;

char si1[20] = "..";

int client_yielding = false;  //set yeilding for message to false at startup

//100ms timer
Ticker _100ms_ticker;
int timer_100ms_count = 0;

//this funtion runs every 100ms and increments timer_100ms_count by 1
///////////////////////////////////////////////////////////////////////
void _100ms_timer(void)
{
timer_100ms_count = timer_100ms_count+1;

//stop overflow 1000 secs
if(timer_100ms_count> 10000)
    {
    timer_100ms_count = 0;
    }
}

// Simon's Watchdog code from
// http://mbed.org/forum/mbed/topic/508/
class Watchdog {
public:
// Load timeout value in watchdog timer and enable
    void kick(float s) {
        LPC_WDT->WDCLKSEL = 0x1;                // Set CLK src to PCLK
        uint32_t clk = SystemCoreClock / 16;    // WD has a fixed /4 prescaler, PCLK default is /4
        LPC_WDT->WDTC = s * (float)clk;
        LPC_WDT->WDMOD = 0x3;                   // Enabled and Reset
        kick();
    }
// reset the watchdog timer
// by writing this required bit pattern
    void kick() {
        LPC_WDT->WDFEED = 0xAA;
        LPC_WDT->WDFEED = 0x55;
    }
};

// Setup the watchdog timer
Watchdog wdt;
 
/////////////////////////////////////start//////////////////////////////////////////
int main(int argc, char* argv[])
{
int rc =0;
int superloop_count = 0;  
static int watchdog_count;

//reset
reset = 0;
wait(1);
reset = 1;
wait(3);

// turn off all leds
led1=0;
led2=0;
led3=0;
led4=0;

//set servo to halfway
s1 = 0.5;
s2 = 0.5;

// On reset, indicate a watchdog reset or a pushbutton reset on LED 4 or 3
if ((LPC_WDT->WDMOD >> 2) & 1)
     {
     led4 = 1; 
     watchdog_count = watchdog_count + 1; //not working
     }
else 
     led3 = 1;
        
wait(1);

// setup a 15 second timeout on watchdog timer hardware
// needs to be longer than worst case main loop exection time
wdt.kick(15.0);  

// set up a function to play every 100 msec
_100ms_ticker.attach(&_100ms_timer, 0.1);

//serial comms at 115200 bluetooth at 9600
pc.baud(115200); 
blue.baud(9600);

logMessage1("HelloMQTT: version is:%u Watchdog Resets:%u \r\n",
                             version,watchdog_count);
blue.printf("HelloMQTT: version is:%u Watchdog Resets:%u \r\n",
                             version,watchdog_count);

///calibrate servos
//s1.calibrate(0.001, 45.0); 
//s2.calibrate(0.001, 45.0); 

//1.0 test if wifi wired
// 1.0 set up a wifi connection
///////////////////////////////////////////////////////////////////////////////////
NetworkInterface* network = easy_connect(up); //press joystick at boot up for debug
MQTTNetwork mqttNetwork(network);
MQTT::Client<MQTTNetwork, Countdown> client(mqttNetwork);   

if(ip_addr1 != 0)
    {
    logMessage2("IP address %s\r\n", ip_addr1);
   
    //2.0 set up a MQTT connection
    ////////////////////////////////////////////////////////////////////
    //MQTTNetwork mqttNetwork(network);
    //MQTT::Client<MQTTNetwork, Countdown> client(mqttNetwork);
    
    char* hostname = HOSTNAME; //"54.157.36.210";  //"103.224.182.253"; // 
    int port = 1883;
    
    //logMessage1("Conecting to %s:%d\r\n", hostname, port);
    rc = mqttNetwork.connect(hostname, port);   
    if (rc != 0)
        logMessage2("rc from TCP connect is %d\r\n", rc);

    //3.0 connect MQTT client
    ///////////////////////////////////////////////////////////////////
    MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
    data.MQTTVersion = 3;
    data.clientID.cstring = CLIENTID; //Make sure your robot name here..JASON_BERRY_BOT 
    data.username.cstring = USERNAME; // token from beebotte or anything for thingsspeak
    data.password.cstring = PASSWORD; // this thinspeak mqtt api found in thingspeak profiles
    
    if ((rc = client.connect(data)) != 0)
        {
        //logMessage2("rc MQTT connect is %d\r\n", rc);
        if (rc == 5)
            logMessage2("Bad MQTT password or username\r\n");
        }
    else
        {    
        //subscribe and read last message posted to mqtt
        ////////////////////////////////////////////////    
        //logMessage1("start of subscribe..\r\n");
    
        if ((rc = client.subscribe(subscribe_topic, MQTT::QOS0, messageArrived)) != 0)
            logMessage2("rc MQTT subsc is %d\r\n", rc);
        }
    }
 else
    {
    logMessage1("wifi unsucessful debug!!!");
    rc = 1;
    }
//end of wifi and subscibe 
///////////////////////////////////////////////////////////////////////    

// clear lcd of startup messages
lcd.cls();


//superloop
///////////////////////////////////////////////////////////////////////////////////////////////  
while(1)
    {
    char mqtt_message_send[200];
    
    //update your outputs
    /////////////////////////////////////////////
    led1=do1;
    // =do2;
    // =do3;
    // =do4;
    
    s1 = float(ao1)/255;  //a01 goes from 0 255 convert to 0.0 to 1.0 fo s1
    s2 = float(ao2)/255;  //a01 goes from 0 255 convert to 0.0 to 1.0 fo s1
    // =a03;
    // =ao4;
    
    // =so1;
    
    
    //update your inputs
    /////////////////////////////////////////////
    
    //analog inputs
    ///////////////////////////////////////////////////////////////////////////////
    // ai1: assigned to temperature sensor,  ai2: accel_x
    if (!sensor.open()) 
        {
        pc.printf("Temperature not device not detected!\n\r");
        }    
    else
        {
        ai1 = sensor.temp();
        }

    // ai2: assigned to acceration_x
    if (!MMA.testConnection())    
        {
        pc.printf("accelormeter !! spelling j !!!\n\r");  
        }
    else
        {
        ai2 = MMA.x();    
        ai3 = MMA.y();  
        }

    //ai4 tba
    ai4=0;

    //digital inputs
    /////////////////////////////////////////////////////////////////////////////////
    // di1: assigned to joystick down(pin 12)..
    // note cannot use joystick fire used for bluetoothrx
    // ai1: assigned to temperature sensor,  ai2: accel_x
    di1 = down; 

    //di12,3,4 tba
    di2=0;
    di3=0;
    di4=0;

    //string inputs
    /////////////////////////////////////////////////////////////////////////////////
    //si1 is a string meesage max 20chars, where boards can send text meesages to mqtt
    snprintf(si1,20,"jhello world..xxxx");
    
    //end of setting inout and ouput variables ////////////////////////////////////
    
        
    /////////////////////////////////////////////
    //create a message with your ai,di and si
    build_bots_AI_DI_SI_message(mqtt_message_send);
        
     
    //logMessage1(".start of publish1 yeild=%u\r\n",client_yielding);
    //wait(1);
    
    //publish message every 500 msecs to mqtt with all  ai,di and si data
    //also as part of publish read back any messages form mqtt subscribe
    
    if(timer_100ms_count >= 5 && (rc == 0))  
        {
        //"kick" to reset watchdog timer and avoid a reset
        wdt.kick();
        
   
        timer_100ms_count = 0;
        
        //create a meesage with your ai,di and si
        //build_bots_AI_DI_SI_message(buf);
        
        //publish and write to mqtt broker..this will then make its way to BEEBOTTE or thinspeak channel
        ////////////////////////////////////////////////////////////////////////////////////
        // note can only publish every 15 seconds to thingspeak mqtt, as often as you like to beebottte
        MQTT::Message message;

        // QoS 0
        //sprintf(buf, "Hello World!  QoS 0 message from app version %f\r\n", version);
        //sprintf(buf, "%u",arrivedcount); //version); //MMA.x());//test number is version
        
        message.qos = MQTT::QOS0;
        message.retained = false; //false;
        message.dup = false;
        message.payload = (void*)mqtt_message_send;
        message.payloadlen = strlen(mqtt_message_send)+1;
        
        //logMessage2("mqtt message: %s  :: lenght:%d \r\n",  message.payload, message.payloadlen);
        rc = client.publish(publish_topic, message);
        if (rc != 0)
            {
            logMessage2("rc MQTT publish error is %d %d\r\n", rc, message.payloadlen);
            client.yield(10);
            }
        else
            client.yield(10);
        //logMessage2(".end of publish..\r\n");
        } 
       

    //check if any comms from bluetooth, if so send last mqqt message received
    if (blue.readable()) 
      {
       blue.gets(blue_message_received,255);   
       
       //send back response
       blue.printf("%s\r\n",mqtt_message_received);
       blue.printf("%s\r\n",mqtt_message_send);
       
       //check bluetooth message for drive commands
       control_bots_AO_DO_SO_message(blue_message_received);  
       
       strcpy(mqtt_message_send,blue_message_received);
       
       //publish and write to mqtt broker..this will then make its way to BEEBOTTE or thinspeak channel
       ////////////////////////////////////////////////////////////////////////////////////
       // note can only publish every 15 seconds to thingspeak mqtt, as often as you like to beebottte
       MQTT::Message message;

       // QoS 0
       //sprintf(buf, "Hello World!  QoS 0 message from app version %f\r\n", version);
       //sprintf(buf, "%u",arrivedcount); //version); //MMA.x());//test number is version
        
       message.qos = MQTT::QOS0;
       message.retained = false; //false;
       message.dup = false;
       message.payload = (void*)mqtt_message_send;
       message.payloadlen = strlen(mqtt_message_send)+1;
        
       //logMessage2("mqtt message: %s  :: lenght:%d \r\n",  message.payload, message.payloadlen);
       rc = client.publish(publish_topic, message);
          if (rc != 0)
                {
                logMessage2("rc MQTT publish error is %d %d\r\n", rc, message.payloadlen);
                client.yield(10);
                }
            else
                client.yield(10);
            //logMessage2(".end of publish..\r\n");


        led4 = !led4;
    }// end of bluetooth read  

    //check if any comms from pc, if so send last mqqt message received      
    if (pc.readable()) 
      {
       pc.gets(pc_message_received,255);     
             
       //send back response
       pc.printf("%s\r\n",mqtt_message_received);
       pc.printf("%s\r\n",mqtt_message_send);
       
       //check pc message for drive commands
       control_bots_AO_DO_SO_message(pc_message_received);  
       
       strcpy(mqtt_message_send,pc_message_received);
       //drive_command_for_another_bot = 0;     
        
       //publish and write to mqtt broker..this will then make its way to BEEBOTTE or thinspeak channel
       ////////////////////////////////////////////////////////////////////////////////////
       // note can only publish every 15 seconds to thingspeak mqtt, as often as you like to beebottte
       MQTT::Message message;

       // QoS 0
       //sprintf(buf, "Hello World!  QoS 0 message from app version %f\r\n", version);
       //sprintf(buf, "%u",arrivedcount); //version); //MMA.x());//test number is version
        
       message.qos = MQTT::QOS0;
       message.retained = false; //false;
       message.dup = false;
       message.payload = (void*)mqtt_message_send;
       message.payloadlen = strlen(mqtt_message_send)+1;
        
       //logMessage2("mqtt message: %s  :: lenght:%d \r\n",  message.payload, message.payloadlen);
       rc = client.publish(publish_topic, message);
       if (rc != 0)
            {
            logMessage2("rc MQTT publish error is %d %d\r\n", rc, message.payloadlen);
            client.yield(10);
            }
       else
            client.yield(10);
   
      //toggle serial message received  
      led4 = !led4;
      }//end of pc read 
     
     //toggle heartbeat every 1 loops, 
     if(superloop_count > 1)
        {
        superloop_count = 0;    
        led2 = !led2;
        }
      else
        superloop_count++;   
        
       //diplay variables locally
       /////////////////////////////////////// 
       lcd.locate(0,1);    
       //lcd.printf(mqtt_message_received,"Payload %s", (char*)ser_bt_mqtt_rec_mes);
       lcd.printf("ao1:%ld,:%ld,:%ld,:%ld do1:%ld,%ld,%ld,%ld",ao1,ao2,ao3,ao4,do1,do2,do3,do4);//printf long int slider
       lcd.locate(0,11);
       lcd.printf("so1: %20s",so1);
       //lcd.printf("do1:%ld, do2:%ld, do3:%ld, do4:%ld ",do1,do2,do3,do4);//printf long int slider
       lcd.locate(0,21);                   
       lcd.printf("count:%u ip:%s",arrivedcount,ip_addr1);   
         
     }//end of while(1)
    
}//end of main, note: no super loop here runs once at reset

void control_bots_AO_DO_SO_message(char *ser_bt_mqtt_rec_mes)
///////////////////////////////////////////////////////////////////////////////
//
// control, message in this format {"data":"do1=0","ispublic": true}
//
//
///////////////////////////////////////////////////////////////////////////////
{
char *ptr_str;

    
//010do1: mapped to led1 on mbed
if((ptr_str = strstr((char*)ser_bt_mqtt_rec_mes, DO1)) != NULL ) // "010do1"
     { 
     do1 = strtol(ptr_str+8,NULL,10);
     } 
if((ptr_str = strstr((char*)ser_bt_mqtt_rec_mes, DO2)) != NULL ) 
     { 
     do2 = strtol(ptr_str+8,NULL,10); 
     }
if((ptr_str = strstr((char*)ser_bt_mqtt_rec_mes, DO3)) != NULL ) 
     { 
     do3 = strtol(ptr_str+8,NULL,10);   
     } 
if((ptr_str = strstr((char*)ser_bt_mqtt_rec_mes, DO4)) != NULL ) 
     { 
     do4 = strtol(ptr_str+8,NULL,10);   
     }  


if((ptr_str = strstr((char*)ser_bt_mqtt_rec_mes, AO1)) != NULL ) 
    { 
    ao1 = strtol(ptr_str+8,NULL,10); // convert string to a long integer      
    }
if((ptr_str = strstr((char*)ser_bt_mqtt_rec_mes, AO2)) != NULL ) 
    {
    ao2 = strtol(ptr_str+8,NULL,10); // convert string to a long integer
    }
if((ptr_str = strstr((char*)ser_bt_mqtt_rec_mes, AO3)) != NULL ) 
    {
    ao3 = strtol(ptr_str+8,NULL,10); // convert string to a long integer
    }
if((ptr_str = strstr((char*)ser_bt_mqtt_rec_mes, AO4)) != NULL ) 
    {
    ao4 = strtol(ptr_str+8,NULL,10); // convert string to a long integer
    }

if((ptr_str = strstr((char*)ser_bt_mqtt_rec_mes, SO1)) != NULL ) 
    {
    strncpy(so1,ptr_str+8,20); //copy 20 chars from messsage to so1
    }

}
     
void build_bots_AI_DI_SI_message(char *buf)
///////////////////////////////////////////////////////////////////////////////
//
//
//
///////////////////////////////////////////////////////////////////////////////
{
//build message store in buf
sprintf(buf,"{\"data\":\"bot_id:%.3s, %5u\",\"%.3sai1\":%.1f,\"%.3sai2\":%.2f,\"%.3sai3\":%.2f,\"%.3sai4\":%.2f,\"%.3sdi1\":%u,\"%.3sdi2\":%u,\"%.3sdi3\":%u,\"%.3sdi4\":%u,\"%.3ssi1\":%.20s,\"is public\":true}",
                                id,arrivedcount,id,ai1,id,ai2,id,ai3,id,ai4,id,di1,id,di2,id,di3,id,di4,id,si1);  
}        
        
        
/*int boot_up(void)
{
//set up a wifi connection
//////////////////////////
    
//connect to wifi network and display ip address..display in serial
NetworkInterface* network = easy_connect(up); //press joystick at boot up for debug
    
if(ip_addr1 != 0)
     logMessage2("IP address %s\r\n", ip_addr1);
else
     logMessage1("wifi unsucessful debug!!!");
   
//set up a MQTT connection
//////////////////////////
    
MQTTNetwork mqttNetwork(network);

MQTT::Client<MQTTNetwork, Countdown> client(mqttNetwork);
    
char* hostname = HOSTNAME; //"54.157.36.210";  //"103.224.182.253"; // 
int port = 1883;
    
logMessage1("Conecting to %s:%d\r\n", hostname, port);

int rc = mqttNetwork.connect(hostname, port);
if (rc != 0)
        logMessage2("rc from TCP connect is %d\r\n", rc);

//connect to client
///////////////////
MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
data.MQTTVersion = 3;
data.clientID.cstring = CLIENTID;       //can be any name,client just dont connect from two different client 
data.username.cstring = USERNAME;          //with identical name,client
data.password.cstring = PASSWORD;  // this thinspeak mqtt api found in thingspeak profiles
    
if ((rc = client.connect(data)) != 0)
    logMessage2("rc MQTT connect is %d\r\n", rc);
    
//subscribe and read last message posted to mqtt
////////////////////////////////////////////////    
//note data received with handled above in  
    
 
logMessage1("start of subscribe..\r\n");
if ((rc = client.subscribe(subscribe_topic, MQTT::QOS0, messageArrived)) != 0)
    logMessage2("rc MQTT subsc is %d\r\n", rc);
    
   
    return 0;
} 

void mqtt_message_publish(void)
{
  //while (1)
  //       {
             
        // if(client_yielding == false)
          //  {
         //   logMessage1(".start of yeilding1\r\n");    
         //   client.yield(100);
         //   client_yielding = true;
        //    }
               
         logMessage1(".start of publish1 yeild=%u\r\n",client_yielding);
         //wait(1);
         if(up == 0)       
            {
            //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",arrivedcount); //version); //MMA.x());//test number is version
            message.qos = MQTT::QOS0;
            message.retained = false; //false;
            message.dup = false;
            message.payload = (void*)buf;
            message.payloadlen = strlen(buf)+1;
                       
           
            logMessage1(".start of publish2\r\n");
           //wait(1);
            
            int rc = client.publish(publish_topic , message);
            //rc = client.publish(publish_topic , message);
            
            //wait(4);
             //while (arrivedcount < 1)
            client.yield(10);
                
            logMessage2(".end of publish..\r\n");  
            }
        else
            {
             client.yield(10);
            }
 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);
*/
    // }//end of test while
            
     //unsubscribe 
    ////////////////////////////////////////
    /*
    if ((rc = client.unsubscribe(subscribe_topic)) != 0)
        logMessage1("rc from unsubscribe was %d\r\n", rc);

    //  and disconnect from client
    if ((rc = client.disconnect()) != 0)
        logMessage1("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);
    
    logMessage1("Version %d: finish %d msgs\r\n", version, arrivedcount);
    logMessage2("IP address %s\r\n", ip_addr1);
    
}
*/

//   [FINITE_STATE_MACHINE_STATE] [STATE_SCALE_mod] [STATE_FACE_X_mod]<sp><CR><LF>

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

    
     sprintf(mqtt_message_received,"Payload %.*s  :count %u\r\n", message.payloadlen, (char*)message.payload,arrivedcount);
    //sprintf(str, "hello %s", "world");
    //snprintf(str, 255, "hello %s",  "world")
     
    ++arrivedcount;
    
    control_bots_AO_DO_SO_message(mqtt_message_received);
    
    //if message received from mqtt then do not need to send on outputs
    //drive_command_for_another_bot = 0;     
    
    
    /*
    //led1 =1; led1=0;
    if( strstr((char*)message.payload, "led1=1") != NULL ) {
            led1=1;
           // lcd.cls();
           // lcd.locate(0,3);
          //  lcd.printf("led 1");
        }
    if( strstr((char*)message.payload, "led1=0") != NULL ) {
            led1=0;
           // lcd.cls();
           // lcd.locate(0,3);
           // lcd.printf("led 0");
        }
    */    
    client_yielding = false; //can yeild for a message again
    led3 = !led3;
    
}

///////////////////////////////////////////////////////////////////
//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.thingspeak.com using windons command: tracert mqtt.thingspeak.com
//        at time of testing it w as 34.231.253.113...doesnt seem to change much :-) but check it.

// Step3.1: 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,54.157.36.210  ..(old 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
//
//        can also use Mosquitto test broker,test.mosquitto.org [5.196.95.208], topic mbed-sample/
//     
//        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
//
//        Can also suscribe use mosquitto test broker topic mbed-sample
//
//
// 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.
//
// step4.1: UPDATE LINE 86 in easy-connect.h with netwrok details as follows,
//          in easy connect folder, then mcr20a-rf-driver folder...should see it    
//          connect_success = esp.connect("eir89748912-2.4G","28eb111b");
//          ----------------------------------------------------------------
//
// 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/

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

// 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

//roborealm send
//{"data":"bot_id:110","010ao1":[MOUSE_X],"010so1":[JASONS_S01],"ispublic":true}<CR><LF>
//roborealm receive
//{"data":"bot_id:[MESSAGE_ID], [MESSAGE_COUNT]","[AI_1_BOT]ai1":[AI_1_VALUE],"[AI_2_BOT]ai2":[AI_2_VALUE],"[AI_3_BOT]ai3":[AI_3_VALUE],"[AI_4_BOT]ai4":[AI_4_VALUE],"[DI_1_BOT]di1":[DI_1_VALUE],"[DI_2_BOT]di2":[DI_2_VALUE],"[DI_3_BOT]di3":[DI_3_VALUE],"[DI_4_BOT]di4":[DI_4_VALUE],"[SI_1_BOT]si1":[SI_1_VALUE],