Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: C12832 LM75B MQ2 MQTT
main.cpp
00001 /******************************************************************************* 00002 * Copyright (c) 2014, 2015 IBM Corp. 00003 * 00004 * All rights reserved. This program and the accompanying materials 00005 * are made available under the terms of the Eclipse Public License v1.0 00006 * and Eclipse Distribution License v1.0 which accompany this distribution. 00007 * 00008 * The Eclipse Public License is available at 00009 * http://www.eclipse.org/legal/epl-v10.html 00010 * and the Eclipse Distribution License is available at 00011 * http://www.eclipse.org/org/documents/edl-v10.php. 00012 * 00013 * Contributors: 00014 * Ian Craggs - initial API and implementation and/or initial documentation 00015 * Ian Craggs - make sure QoS2 processing works, and add device headers 00016 *******************************************************************************/ 00017 00018 /** 00019 This is a sample program to illustrate the use of the MQTT Client library 00020 on the mbed platform. The Client class requires two classes which mediate 00021 access to system interfaces for networking and timing. As long as these two 00022 classes provide the required public programming interfaces, it does not matter 00023 what facilities they use underneath. In this program, they use the mbed 00024 system libraries. 00025 00026 */ 00027 00028 // change this to 1 to output messages to LCD instead of serial 00029 #define USE_LCD 1 00030 00031 #if USE_LCD 00032 #include "C12832.h" 00033 00034 // the actual pins are defined in mbed_app.json and can be overridden per target 00035 C12832 lcd(LCD_MOSI, LCD_SCK, LCD_MISO, LCD_A0, LCD_NCS); 00036 00037 #define logMessage lcd.cls();lcd.locate(0,0);lcd.printf 00038 00039 #else 00040 00041 #define logMessage printf 00042 00043 #endif 00044 00045 #define MQTTCLIENT_QOS2 0 00046 00047 #include "easy-connect.h" //Ethernet Connection library 00048 #include "MQTTNetwork.h" //MQTT Connection 00049 #include "MQTTmbed.h" //MQTT Connection 00050 #include "MQTTClient.h" //MQTT Connection 00051 #include "string.h"; 00052 00053 #include "mbed.h" 00054 //#include "platform/mbed_thread.h" 00055 #include "FP.h" //For function pointer usage 00056 #include "MQ2.h" //Smoke and Gas detector library 00057 #include "LM75B.h" //Temperature sensor 00058 00059 #define ON 1 00060 #define OFF 0 00061 00062 #define PUMP PTC1 //Relay Signal for controlling pump 00063 #define TRIGGER PTB18 //Trigger pin for ultrasonic sensor 00064 #define ECHO PTB19 //Echo pin for ultrasonic sensor 00065 #define MQ2_SIG PTC10 //Smoke and Gas sensor output pin 00066 #define ALARM_SIG PTC8 //Alarm Signal Pin 00067 #define FAN_SIG PTC9 //Fan signal pin 00068 00069 //Global variables to update the ThingSpeak channel fields. 00070 int WATER_LEVEL = 0; 00071 float CO_level = 0; 00072 float SMOKE_level = 0; 00073 float GAS_level = 0; 00074 float TEMPERATURE = 0; 00075 int FAN_STATE = 0; 00076 int ALARM_STATE = 0; 00077 int PUMP_STATE = 0; 00078 00079 class indicator{ //class to allow easy usage of RGB LED 00080 private: 00081 DigitalOut RED; //LED1 00082 DigitalOut BLUE; //LED2 00083 DigitalOut GREEN; //LED3 00084 Ticker blink; //Ticker to start blinking 00085 bool red_set; //bool to check if RED is ON 00086 bool green_set; //bool to check if GREEN is ON 00087 bool blue_set; //bool to check if BLUE is ON 00088 00089 void blink_effect(){ //function to flip LEDs to generate blink effect 00090 if(red_set) 00091 RED = !RED; 00092 if(green_set) 00093 GREEN = !GREEN; 00094 if(blue_set) 00095 BLUE = !BLUE; 00096 } 00097 00098 public: 00099 indicator(PinName _LED1, PinName _LED2, PinName _LED3):RED(_LED1, 1), GREEN(_LED2, 1), BLUE(_LED3, 1){ //Initialize RGB LEDs with requried PINS. 00100 red_set = false; green_set = false; blue_set = false; //All LED intially OFF. 00101 } 00102 00103 void red_led(){ //Set Only RED LED 00104 RED = 0; red_set = true; 00105 GREEN = 1; green_set = false; 00106 BLUE = 1; blue_set = false; 00107 } 00108 00109 void green_led(){ //Set Only GREEN LED 00110 RED = 1; red_set = false; 00111 GREEN = 0; green_set = true; 00112 BLUE = 1; blue_set = false; 00113 } 00114 void blue_led(){//Set Only BLUE LED 00115 RED = 1; red_set = false; 00116 GREEN = 1; green_set = false; 00117 BLUE = 0; blue_set = true; 00118 } 00119 void amber_led(){//Set Only AMBER LED 00120 RED = 0; red_set = true; 00121 GREEN = 0; green_set = true; 00122 BLUE = 1; blue_set = false; 00123 } 00124 void pink_led(){//Set Only PINK LED 00125 RED = 0; red_set = true; 00126 GREEN = 1; green_set = false; 00127 BLUE = 0; blue_set = true; 00128 } 00129 void cyan_led(){//Set Only CYAN LED 00130 RED = 1; red_set = false; 00131 GREEN = 0; green_set = true; 00132 BLUE = 0; blue_set = true; 00133 } 00134 void white_led(){//Set Only WHITE LED 00135 RED = 0; red_set = true; 00136 GREEN = 0; green_set = true; 00137 BLUE = 0; blue_set = true; 00138 } 00139 void all_led_off(){//Set All LED OFF 00140 RED = 1; red_set = false; 00141 GREEN = 1; green_set = false; 00142 BLUE = 1; blue_set = false; 00143 } 00144 void start_blink(float blink_interval){ //Start blinking on current LED using tikcer to avoid code blocking 00145 blink.attach(callback(this, &indicator::blink_effect), blink_interval); 00146 } 00147 void stop_blink(){ //Stop blinkink. Detach Ticker function call 00148 blink.detach(); 00149 if(red_set) //Set last LED being used as ON. 00150 RED = 0; 00151 if(green_set) 00152 GREEN = 0; 00153 if(blue_set) 00154 BLUE = 0; 00155 } 00156 }; 00157 00158 indicator led_indicator(LED1, LED2, LED3); //Use K64f RGB LED for water pump 00159 indicator shield_led_indicator(D5, D9, D8); //Use Application Shield's RGB LED for MQ2 sensor 00160 00161 class ultrasonic{ //Ultrasonic sensot for measuring depth of water in tank 00162 private: 00163 DigitalOut trigger;//DigitalOut trigger; //trigger pin for UltarSonic sensor 00164 InterruptIn echo; //Echo pin for water_level measurement. Uses as Interrupt to avoid code execution blocking. 00165 Ticker measure; //Ticker to trigger water_level measurement periodically. 00166 Timeout trigger_low; //Timeout interrupt to set trigger pin low after 10us of HIGH. 00167 Timer echoTimer; //Timer to get the time elapsed between echo sent and echo received back 00168 int echo_time_us; //Timer taken by echo to resturn abck to module. 00169 float interval; //Interval after which periodic measurement should start 00170 volatile bool measuring; 00171 FP<void,int> fp; 00172 00173 void set_trigger_high(){ //Function to set Trigger Pin HIGH for 10us and set measuring = true 00174 measuring = true; 00175 trigger = ON; 00176 trigger_low.attach_us(callback(this, &ultrasonic::set_trigger_low), 10); //set trigger pin OFF after 10us 00177 } 00178 00179 void set_trigger_low(void){ //Function to set trigger pin LOW to fiish trigger after 10us. This will be called by low timer object. 00180 trigger = OFF; 00181 } 00182 00183 void start_echo(void){//Function to start listening for echo back. This will start timer echoTimer. Will be based on Echo Pin RISE(or HIGH) 00184 if(!measuring) return; //avoid fluctuations on echo pin if any. Continue echo calculation only if measuring is TRUE. 00185 echoTimer.reset(); 00186 echoTimer.start(); //Timer start since Echo pin is HIGH 00187 } 00188 void stop_echo(void){//Function to stop echoTimer after echo received back. Will be based on Echo Pin FALL(or LOW). 00189 if (!measuring)return; //avoid fluctuations on echo pin if any 00190 echoTimer.stop(); //stop timer since echo pin back to LOW 00191 echo_time_us = echoTimer.read_us(); //Calculate time for ultrasonic wave RTT. 00192 if(echo_time_us > 2000 || echo_time_us < 125)return; //ignore reading in case abnormally high or low RTT time 00193 measuring = false; //Marke measurement completed 00194 fp(echo_time_us / (29 * 2)); 00195 } 00196 public: 00197 ultrasonic(PinName _trigger, PinName _echo,float _interval):trigger(_trigger), echo(_echo){ //Constructor: initialize trigger(default value OFF) & echo pin 00198 interval = _interval; 00199 echo.rise(callback(this, &ultrasonic::start_echo)); //Attach function to Interrupt on Echo pin Rise 00200 echo.fall(callback(this, &ultrasonic::stop_echo)); //Attach function to Interrupt on Echo pin Fall 00201 measuring = false; 00202 } 00203 00204 void start_measure(){ //function to Set Trigger Pin high repeatedly every 'time' seconds 00205 measure.attach(callback(this, &ultrasonic::set_trigger_high),interval);//ticker to trigger measurement with callback function 00206 } 00207 void stop_measure(void){ //Dettach from Ticker and stop measurements 00208 measuring = false; 00209 measure.detach(); 00210 } 00211 void req_callBack(FP<void, int> _fp){ 00212 fp = _fp; 00213 } 00214 }; 00215 00216 class pump{ 00217 private: 00218 DigitalOut signal; //Signal for relay to set PUMP ON and OFF 00219 ultrasonic sensor; //Ultrasonic module objet for measuring depth of water 00220 volatile bool pump_on_request; //Bool to inform whether ita PUMP on request or only water depth meas. 00221 const int LEVEL_LOW = 4; //Low Water level defined as 4CM. Signifies Tank FULL. 00222 const int LEVEL_HIGH = 9; //High Water level defined as 11CM. Signifies Tank EMPTY. 00223 FP<void, int> fp; //Function pointer to receive call back with depth of water level in tank. 00224 00225 public: 00226 //Initialize Ultrasonic module with TRIG and ECHO pin along with measurement interval. 00227 pump(PinName _signal, PinName _trigger, PinName _echo, float _interval):signal(_signal), sensor(_trigger, _echo, _interval){ 00228 pump_on_request = false; 00229 fp.attach(this, &pump::update_depth); //update_depth function will be called bu ultrasonic module when depth meas is completed. 00230 sensor.req_callBack(fp); //set call back. 00231 } 00232 void start_measurement(int interval){ 00233 sensor.start_measure(); //Start depth measurements to calculate the water level. 00234 } 00235 void stop_measurement(){ 00236 sensor.stop_measure(); //Start depth measurements to calculate the water level. 00237 } 00238 00239 void pump_on(){ //Pump On request by User. 00240 pump_on_request = true; //bool to confirm that Pump On request is raised 00241 //sensor.start_measure(); //Start depth measurements to calculate the water level. 00242 } 00243 void pump_off(){ //Switch OFF the pump 00244 pump_on_request = false; //Set User request to flase. 00245 //sensor.stop_measure(); //Stop the ultrasonic measurements 00246 signal = OFF; //Relay Signal for pump OFF. 00247 PUMP_STATE = OFF; 00248 } 00249 00250 void get_depth(){ //Only depth of water requried. no need to switch ON pump. 00251 if(signal == OFF) //If Already PUMP ONdont start measurement again. 00252 sensor.start_measure(); //Start Ultrasonic Measurements 00253 } 00254 00255 void update_depth(int depth){ //Depth from ultrasonic is available 00256 WATER_LEVEL = depth; 00257 if(depth <= LEVEL_LOW) // set GREEN LED to inidicate the tank is FULL 00258 led_indicator.green_led(); 00259 else if(depth <= LEVEL_HIGH)// set Amber LED to inidicate the tank is more than HALF 00260 led_indicator.amber_led(); 00261 else 00262 led_indicator.red_led();// set RED LED to inidicate the tank is less than HALF 00263 00264 if(depth <= LEVEL_LOW && signal == ON)//Tank FULL and PUMP ON. Switch OFF PUMP. 00265 pump_off(); 00266 else if(signal == OFF && pump_on_request && depth > LEVEL_HIGH ) //Pump is OFF and User have requested to on PUMP 00267 signal = ON; //Pump ON 00268 else if(signal == ON && !pump_on_request) //If PUMP is ON but not requster by User. 00269 pump_off(); //Pump OFF 00270 else if(signal == OFF && !pump_on_request) // Only for depth measurement. Pump on is not requested by user. 00271 pump_off(); 00272 PUMP_STATE = signal; 00273 } 00274 }; 00275 00276 class control{ //Control object for fan and alarm. Only Switch ON and OFF requried. 00277 private: 00278 DigitalOut signal; //Signal pin for object 00279 public: 00280 control(PinName _signal, int state):signal(_signal,state){ //Initialize Signal PIN with default state(ON or OFF) 00281 } 00282 00283 void set_state(int state){ //Set the state of control 00284 if (state >= 1){ //Switch ON 00285 signal = ON; 00286 led_indicator.pink_led(); //Blink RED LED 00287 } 00288 else //Switch OFF 00289 signal = OFF; //Set Control OFF 00290 //publish data 00291 } 00292 int get_state(){ //Get the state of the control 00293 return signal.read(); 00294 } 00295 }; 00296 00297 class _temperature{ //Object for measuring current temperature and taking action accordingly 00298 private: 00299 LM75B temp_sensor; //LM75B temperature library used. 00300 float temperature_threshold_fan; // Threshold value for switching ON the FAN 00301 float temperature_threshold_alarm; // Threshold value for switching ON the ALARM 00302 Ticker periodic_meas; //Ticker for periodic measurement of the temperature 00303 control* alarm; //Poniter to control the alarm 00304 control* fan; //Poniter to control the fan 00305 void read_data(){ //Read the temperature from sensor 00306 TEMPERATURE = temp_sensor.temp(); //Use global variable TEMPERATURE which will be sent to ThingSpeak. 00307 if(TEMPERATURE >= temperature_threshold_alarm){ //Check if alarm threshold met. 00308 alarm->set_state(ON); //Set Alarm ON 00309 shield_led_indicator.red_led(); //Start RED LED Blinking 00310 } 00311 else if(TEMPERATURE >= temperature_threshold_fan){//Check if fan threshold met. 00312 shield_led_indicator.amber_led();//Set Amber LED Blinking 00313 fan->set_state(ON);//Set Alarm ON 00314 FAN_STATE = ON; 00315 } 00316 else 00317 shield_led_indicator.green_led(); 00318 } 00319 public: 00320 _temperature(control* _alarm, control* _fan):temp_sensor(D14,D15){ //Initialize temp sensor with shield PINs D14, D15 00321 alarm = _alarm; //received object for alarm from Main function 00322 fan = _fan;//received object for fan from Main function 00323 temperature_threshold_fan = 30; //Fan threshold 00324 temperature_threshold_alarm = 40; //Alarm threshold 00325 } 00326 void start_measurement(int interval){ 00327 periodic_meas.attach(callback(this, &_temperature::read_data), interval); //Start ticker based periodic temperature measurement 00328 } 00329 void stop_measurement(int interval){ 00330 periodic_meas.detach(); //Stop ticker. 00331 } 00332 }; 00333 00334 class _smoke_detector{ //Class to control the MQ2 Gas and Smoke detector 00335 private: 00336 MQ2 mq2; //Existing MQ2 library is used 00337 MQ2_data_t data; //data field to read the CO, SMOKE & GAS levels 00338 float CO_threshold_fan; //FAN Threshold for Carbon Monoxide 00339 float CO_threshold_alarm;//ALARM Threshold for Carbon Monoxide 00340 float GAS_threshold_fan; //FAN Threshold for combustible GASES 00341 float GAS_threshold_alarm; //ALARM Threshold for combustible GASES 00342 float SMOKE_threshold_fan; //FAN Threshold for SMOKE 00343 float SMOKE_threshold_alarm;//ALARM Threshold for SMOKE 00344 control* fan; //Poniter to control the fan 00345 control* alarm; //Poniter to control the alarm 00346 Ticker periodic_meas; //Ticker to complete periodic measurements 00347 00348 void read_data(){ //Read the GAS/CO/SMOKE level from sensor 00349 mq2.read(&data); 00350 CO_level = mq2.readCO(); //CO Level 00351 GAS_level = mq2.readLPG(); //GAS Level 00352 SMOKE_level = mq2.readSmoke(); //SMOKE Level 00353 //Check if alarm threhold is crossed for any measurements 00354 if(data.co >= CO_threshold_alarm || data.lpg >= GAS_threshold_alarm || data.smoke >= SMOKE_threshold_alarm){ 00355 shield_led_indicator.red_led(); //Set RED Blinker 00356 alarm->set_state(ON); //Set alarm ON 00357 } 00358 //Check if fan threhold is crossed for any measurements 00359 else if(data.co >= CO_threshold_fan || data.lpg >= GAS_threshold_fan || data.smoke >= SMOKE_threshold_fan){ 00360 shield_led_indicator.amber_led(); //Set AMBER LED 00361 fan->set_state(ON); //Set FAN ON 00362 } 00363 } 00364 00365 public: 00366 //Initialize MQ2 sensor using Analog pin. 00367 _smoke_detector(PinName _analog, control* _alarm, control* _fan):mq2(_analog){ 00368 mq2.begin(); //mq2 begin method to Calibrate sensor 00369 fan = _fan; //Fan control object from Main function 00370 alarm = _alarm;//Alarm control object from Main function 00371 CO_threshold_alarm = 3; 00372 CO_threshold_fan = 2; 00373 GAS_threshold_fan = 2; 00374 GAS_threshold_alarm = 3; 00375 SMOKE_threshold_alarm = 3; 00376 SMOKE_threshold_fan = 2; 00377 } 00378 00379 void start_measurement(int interval){ //Start Ticker based periodic measurements 00380 periodic_meas.attach(callback(this, &_smoke_detector::read_data), interval); 00381 } 00382 void stop_measurement(){//Stop Ticker based periodic measurements 00383 periodic_meas.detach(); 00384 } 00385 }; 00386 00387 int arrivedcount = 0; 00388 00389 pump water_pump(PUMP,TRIGGER, ECHO, 1); //Water Pump object 00390 control alarm(ALARM_SIG, ON); //Alarm Pump object 00391 control fan(FAN_SIG, OFF); //Fan object 00392 _smoke_detector smoke_detector(MQ2_SIG, &alarm, &fan); //Smoke Detector object 00393 _temperature temperature(&alarm, &fan);//Uses fixed PIN on shiled- D14, D15. So no need to pass from main 00394 NetworkInterface* network = easy_connect(true); //Network object. Creates ethernt conncetion 00395 MQTTNetwork mqttNetwork(network); //MQTTNetwork object. Takes Network object as input for connection over ethernet 00396 MQTT::Client<MQTTNetwork, Countdown> client(mqttNetwork); //MQTT Client for Connction with broker, Subscribe and Publsih service. 00397 00398 00399 void field1_pump_state(MQTT::MessageData& md) //Callback functionf for Field1 from thingspeak. 00400 { 00401 MQTT::Message &message = md.message; //Message recived using MQTT 00402 logMessage("Message arrived: qos %d, retained %d, dup %d, packetid %d\r\n", message.qos, message.retained, message.dup, message.id); 00403 logMessage("Message Field1 %s\r\n", message.payload); //Message Payload 00404 if(strtol((char *)message.payload, '\0', 10) == 1){ //convert to int and check if power ON command 00405 logMessage("Water Pump ON\r\n"); 00406 water_pump.stop_measurement(); 00407 water_pump.start_measurement(2); //Start Water Pump measurements. At intervals of 2s. This is small value because for test purpose very small tank is being used. In real life this could be in mins. 00408 water_pump.pump_on(); //Start the pump for 1st time 00409 } 00410 else{ 00411 logMessage("Water Pump OFF\r\n"); 00412 water_pump.pump_off(); //Power off pump otherwise 00413 } 00414 } 00415 00416 void field2_fan_state(MQTT::MessageData& md)//Callback functionf for Field2 from thingspeak. 00417 { 00418 MQTT::Message &message = md.message; //Message recived using MQTT 00419 logMessage("Message arrived: qos %d, retained %d, dup %d, packetid %d\r\n", message.qos, message.retained, message.dup, message.id); 00420 logMessage("Message Field2 %s\r\n", message.payload);//Message Payload 00421 if(strtol((char *)message.payload, '\0', 10) == 1){//convert to int and check if power ON command 00422 logMessage("FAN ON\r\n"); 00423 fan.set_state(OFF);//Power On FAN 00424 } 00425 else{ 00426 logMessage("FAN OFF\r\n"); 00427 fan.set_state(ON);//Power off fan otherwise 00428 } 00429 } 00430 00431 void field3_alarm_state(MQTT::MessageData& md) 00432 { 00433 MQTT::Message &message = md.message; 00434 logMessage("Message arrived: qos %d, retained %d, dup %d, packetid %d\r\n", message.qos, message.retained, message.dup, message.id); 00435 logMessage("Message Field3 %s\r\n", message.payload); 00436 // RED = strtol((char *)message.payload, '\0', 10); 00437 if(strtol((char *)message.payload, '\0', 10) == 1){//convert to int and check if power ON command 00438 logMessage("Alarm ON\r\n");;//Power On Alarm. This scenario should never occur, 00439 alarm.set_state(ON); 00440 } 00441 else{ 00442 logMessage("Alarm OFF\r\n"); 00443 alarm.set_state(OFF); //Power off Alarm otherwise 00444 } 00445 ++arrivedcount; 00446 } 00447 00448 void publish_field1(){ //Function to publish the values to ThingSpeak fields 00449 static int last_update = -1; 00450 if(PUMP_STATE == last_update) 00451 return; //Ignore unncessary update in case no chnage in value. 00452 last_update = PUMP_STATE; 00453 logMessage("Publish Routine\r\n"); 00454 int rc = 0; 00455 MQTT::Message message; 00456 char* topic = "channels/1608275/publish";//Topic contaning Channel ID 00457 char buf[100]; //Buffer for storing data 00458 sprintf(buf, "field1=%d&status=MQTTPUBLISH",PUMP_STATE); 00459 message.qos = MQTT::QOS0; //MQTT QOS 0 used. Best effort QOS 00460 message.retained = false; 00461 message.dup = false; 00462 message.payload = (void*)buf; //Copy buffer to Message Payload 00463 message.payloadlen = strlen(buf)+1; 00464 rc = client.publish(topic, message); //Publsih data using MQTT client 00465 logMessage("Publish rc: %d, Buf: %s\r\n", rc, buf); 00466 } 00467 00468 void publish_field2(){ //Function to publish the values to ThingSpeak fields 00469 static int last_update = -1; 00470 if(FAN_STATE == last_update) 00471 return; //Ignore unncessary update in case no chnage in value. 00472 last_update = FAN_STATE; 00473 logMessage("Publish Routine\r\n"); 00474 int rc = 0; 00475 MQTT::Message message; 00476 char* topic = "channels/1608275/publish";//Topic contaning Channel ID 00477 char buf[100]; //Buffer for storing data 00478 sprintf(buf, "field2=%d&status=MQTTPUBLISH",FAN_STATE); 00479 message.qos = MQTT::QOS0; //MQTT QOS 0 used. Best effort QOS 00480 message.retained = false; 00481 message.dup = false; 00482 message.payload = (void*)buf; //Copy buffer to Message Payload 00483 message.payloadlen = strlen(buf)+1; 00484 rc = client.publish(topic, message); //Publsih data using MQTT client 00485 logMessage("Publish rc: %d, Buf: %s\r\n", rc, buf); 00486 } 00487 00488 void publish_field3(){ //Function to publish the values to ThingSpeak fields 00489 static int last_update = -1; 00490 if(ALARM_STATE == last_update) 00491 return; //Ignore unncessary update in case no chnage in value. 00492 last_update = ALARM_STATE; 00493 logMessage("Publish Routine\r\n"); 00494 int rc = 0; 00495 MQTT::Message message; 00496 char* topic = "channels/1608275/publish";//Topic contaning Channel ID 00497 char buf[100]; //Buffer for storing data 00498 sprintf(buf, "field3=%d&status=MQTTPUBLISH",ALARM_STATE); 00499 message.qos = MQTT::QOS0; //MQTT QOS 0 used. Best effort QOS 00500 message.retained = false; 00501 message.dup = false; 00502 message.payload = (void*)buf; //Copy buffer to Message Payload 00503 message.payloadlen = strlen(buf)+1; 00504 rc = client.publish(topic, message); //Publsih data using MQTT client 00505 logMessage("Publish rc: %d, Buf: %s\r\n", rc, buf); 00506 } 00507 00508 void publish_field4(){ //Function to publish the values to ThingSpeak fields 00509 static int last_update = -1; 00510 last_update = WATER_LEVEL; 00511 //logMessage("Publish Routine\r\n"); 00512 int rc = 0; 00513 MQTT::Message message; 00514 char* topic = "channels/1608275/publish";//Topic contaning Channel ID 00515 char buf[100]; //Buffer for storing data 00516 //field5=%0.1f&field6=%0.1f&field7=%0.1f&field8=%0.1f& 00517 sprintf(buf, "field4=%d&field1=%d&field2=%d&field3=%d&status=MQTTPUBLISH",WATER_LEVEL, PUMP_STATE,FAN_STATE,ALARM_STATE); 00518 message.qos = MQTT::QOS0; //MQTT QOS 0 used. Best effort QOS 00519 message.retained = false; 00520 message.dup = false; 00521 message.payload = (void*)buf; //Copy buffer to Message Payload 00522 message.payloadlen = strlen(buf)+1; 00523 rc = client.publish(topic, message); //Publsih data using MQTT client 00524 //logMessage("Publish rc: %d, Buf: %s\r\n", rc, buf); 00525 } 00526 00527 void publish_field5(){ //Function to publish the values to ThingSpeak fields 00528 static int last_update = -1; 00529 last_update = GAS_level; 00530 //logMessage("Publish Routine\r\n"); 00531 int rc = 0; 00532 MQTT::Message message; 00533 char* topic = "channels/1608275/publish";//Topic contaning Channel ID 00534 char buf[100]; //Buffer for storing data 00535 sprintf(buf, "field5=%d&field6=%d&field7=%d&field8=%d&status=MQTTPUBLISH",GAS_level, CO_level, SMOKE_level, TEMPERATURE); 00536 message.qos = MQTT::QOS0; //MQTT QOS 0 used. Best effort QOS 00537 message.retained = false; 00538 message.dup = false; 00539 message.payload = (void*)buf; //Copy buffer to Message Payload 00540 message.payloadlen = strlen(buf)+1; 00541 rc = client.publish(topic, message); //Publsih data using MQTT client 00542 //logMessage("Publish rc: %d, Buf: %s\r\n", rc, buf); 00543 } 00544 00545 void publish_field6(){ //Function to publish the values to ThingSpeak fields 00546 static int last_update = -1; 00547 if(CO_level == last_update) 00548 return; //Ignore unncessary update in case no chnage in value. 00549 last_update = CO_level; 00550 logMessage("Publish Routine\r\n"); 00551 int rc = 0; 00552 MQTT::Message message; 00553 char* topic = "channels/1608275/publish";//Topic contaning Channel ID 00554 char buf[100]; //Buffer for storing data 00555 sprintf(buf, "field6=%d&status=MQTTPUBLISH",CO_level); 00556 message.qos = MQTT::QOS0; //MQTT QOS 0 used. Best effort QOS 00557 message.retained = false; 00558 message.dup = false; 00559 message.payload = (void*)buf; //Copy buffer to Message Payload 00560 message.payloadlen = strlen(buf)+1; 00561 rc = client.publish(topic, message); //Publsih data using MQTT client 00562 logMessage("Publish rc: %d, Buf: %s\r\n", rc, buf); 00563 } 00564 00565 void publish_field8(){ //Function to publish the values to ThingSpeak fields 00566 static int last_update = -1; 00567 if(TEMPERATURE == last_update) 00568 return; //Ignore unncessary update in case no chnage in value. 00569 last_update = TEMPERATURE; 00570 logMessage("Publish Routine\r\n"); 00571 int rc = 0; 00572 MQTT::Message message; 00573 char* topic = "channels/1608275/publish";//Topic contaning Channel ID 00574 char buf[100]; //Buffer for storing data 00575 sprintf(buf, "field8=%d&status=MQTTPUBLISH",TEMPERATURE); 00576 message.qos = MQTT::QOS0; //MQTT QOS 0 used. Best effort QOS 00577 message.retained = false; 00578 message.dup = false; 00579 message.payload = (void*)buf; //Copy buffer to Message Payload 00580 message.payloadlen = strlen(buf)+1; 00581 rc = client.publish(topic, message); //Publsih data using MQTT client 00582 logMessage("Publish rc: %d, Buf: %s\r\n", rc, buf); 00583 } 00584 00585 void publish_field7(){ //Function to publish the values to ThingSpeak fields 00586 static int last_update = -1; 00587 if(SMOKE_level == last_update) 00588 return; //Ignore unncessary update in case no chnage in value. 00589 last_update = SMOKE_level; 00590 logMessage("Publish Routine\r\n"); 00591 int rc = 0; 00592 MQTT::Message message; 00593 char* topic = "channels/1608275/publish";//Topic contaning Channel ID 00594 char buf[100]; //Buffer for storing data 00595 sprintf(buf, "field7=%d&status=MQTTPUBLISH",SMOKE_level); 00596 message.qos = MQTT::QOS0; //MQTT QOS 0 used. Best effort QOS 00597 message.retained = false; 00598 message.dup = false; 00599 message.payload = (void*)buf; //Copy buffer to Message Payload 00600 message.payloadlen = strlen(buf)+1; 00601 rc = client.publish(topic, message); //Publsih data using MQTT client 00602 logMessage("Publish rc: %d, Buf: %s\r\n", rc, buf); 00603 } 00604 00605 int main(int argc, char* argv[]) 00606 { 00607 smoke_detector.start_measurement(2); //Start periodic Smoke detector measurements at intervals of 10s 00608 temperature.start_measurement(20); //Start periodic Temperaturre readings. At interval of 20s 00609 water_pump.start_measurement(2); //Start Water Pump measurements. At intervals of 2s. This is small value because for test purpose very small tank is being used. In real life this could be in mins. 00610 water_pump.pump_on(); //Start the pump for 1st time 00611 float version = 0.6; 00612 logMessage("HelloMQTT: version is %.2f\r\n", version); 00613 int ret = 0; 00614 00615 if (!network) { //Check if ethernet connection successful 00616 return -1; 00617 } 00618 00619 const char* hostname = "mqtt3.thingspeak.com"; //Thingspeak host name 00620 int port = 1883; //MQTT default port number 00621 logMessage("Connecting to %s:%d\r\n", hostname, port); 00622 int rc = mqttNetwork.connect(hostname, port); //Attempt to connect to MQTT host 00623 if (rc != 0) 00624 logMessage("rc- TCP connect: %d\r\n", rc); 00625 00626 MQTTPacket_connectData data = MQTTPacket_connectData_initializer; //Build MQTT Client connection data 00627 data.MQTTVersion = 3; //MQTT Version 00628 data.clientID.cstring = "FA8KKzQ1CDY6EjENATYTESc"; //Thingspeak MQTT Client ID 00629 data.username.cstring = "FA8KKzQ1CDY6EjENATYTESc";//Thingspeak MQTT Username 00630 data.password.cstring = "vVdiiGscVIGLEgQIZ250Unxc";//Thingspeak MQTT Password 00631 00632 00633 if ((rc = client.connect(data)) != 0) //Connect Client 00634 logMessage("rc- connect: %d\r\n", rc); 00635 00636 char* topic = "channels/1608275/subscribe/fields/field1"; //Subscribe for field1 00637 if ((rc = client.subscribe(topic, MQTT::QOS0, field1_pump_state)) != 0)//Use field1_pump_state function pointer as call back function 00638 logMessage("rc1: %d\r\n", rc); 00639 00640 topic = "channels/1608275/subscribe/fields/field2"; 00641 if ((rc = client.subscribe(topic, MQTT::QOS0, field2_fan_state)) != 0)//Use field2_fan_state function pointer as call back function 00642 logMessage("rc2: %d\r\n", rc); 00643 00644 topic = "channels/1608275/subscribe/fields/field3"; 00645 if ((rc = client.subscribe(topic, MQTT::QOS0, field3_alarm_state)) != 0)//Use field3_alarm_state function pointer as call back function 00646 logMessage("rc: %d\r\n", rc); 00647 00648 while (1){ 00649 logMessage("GAS: %d, CO: %d, Smoke: %d, TEMP = %0.1f, Water = %d", GAS_level, CO_level, SMOKE_level, TEMPERATURE, WATER_LEVEL); 00650 publish_field4(); 00651 wait(5); 00652 publish_field5(); 00653 wait(5); 00654 client.yield(50); 00655 00656 } 00657 if ((rc = client.unsubscribe(topic)) != 0) 00658 logMessage("rc from unsubscribe was %d\r\n", rc); 00659 if ((rc = client.disconnect()) != 0) 00660 logMessage("rc from disconnect was %d\r\n", rc); 00661 mqttNetwork.disconnect(); 00662 logMessage("Version %.2f: finish %d msgs\r\n", version, arrivedcount); 00663 return 0; 00664 }
Generated on Mon Sep 26 2022 17:55:51 by
1.7.2