Duy tran
/
Water_Monitor_clone_v1
Duy_new_test_Water_Monitor
Fork of Cloud_IBM_MbedOS by
Diff: main.cpp
- Revision:
- 0:e477c0f8b2e4
- Child:
- 2:e3846f091b6b
diff -r 000000000000 -r e477c0f8b2e4 main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Fri Nov 17 08:46:13 2017 +0000 @@ -0,0 +1,330 @@ +/* SpwfInterface NetworkSocketAPI Example Program + * Copyright (c) 2015 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mbed.h" +#include "easy-connect.h" +#include "MQTTClient.h" +#include "XNucleoIKS01A2.h" +#include "XNucleoNFC01A1.h" +#include "NDefLib/NDefNfcTag.h" +#include "NDefLib/RecordType/RecordURI.h" +#include "MQTTNetwork.h" +#include "MQTTmbed.h" + + +//------------------------------------ +// Hyperterminal configuration +// 9600 bauds, 8-bit data, no parity +//------------------------------------ +static Serial pc(SERIAL_TX, SERIAL_RX); +static DigitalOut myled(LED1); +static bool quickstartMode = true; // set to false to connect with authentication tocken +static bool BlueButtonToggle = false; + +#define ORG_QUICKSTART // comment to connect to play.internetofthings.ibmcloud.com +//#define SUBSCRIBE // uncomment to subscribe to broker msgs (not to be used with IBM broker) +//#define X_NUCLEO_NFC01A1_PRESENT // uncomment to add NFC support + +#define MQTT_MAX_PACKET_SIZE 400 +#define MQTT_MAX_PAYLOAD_SIZE 300 + + // Configuration values needed to connect to IBM IoT Cloud +#ifdef ORG_QUICKSTART +#define ORG "quickstart" // connect to quickstart.internetofthings.ibmcloud.com/ For a registered connection, replace with your org +#define ID "" +#define AUTH_TOKEN "" +#define DEFAULT_TYPE_NAME "iotsample-mbed-Nucleo" +#else // not def ORG_QUICKSTART +#define ORG "play" // connect to play.internetofthings.ibmcloud.com/ For a registered connection, replace with your org +#define ID "" // For a registered connection, replace with your id +#define AUTH_TOKEN ""// For a registered connection, replace with your auth-token +#define DEFAULT_TYPE_NAME "sensor" +#endif + +#define TYPE DEFAULT_TYPE_NAME // For a registered connection, replace with your type +#define IBM_IOT_PORT MQTT_PORT + +static char id[30] = ID; // mac without colons +static char org[12] = ORG; +static int connack_rc = 0; // MQTT connack return code +static char type[30] = TYPE; +static char auth_token[30] = AUTH_TOKEN; // Auth_token is only used in non-quickstart mode +static bool netConnecting = false; +static int connectTimeout = 1000; +static bool mqttConnecting = false; +static bool netConnected = false; +static bool connected = false; +static int retryAttempt = 0; +static char subscription_url[MQTT_MAX_PAYLOAD_SIZE]; + +static LPS22HBSensor *pressure_sensor; +static HTS221Sensor *humidity_sensor; +static HTS221Sensor *temp_sensor1; + +#ifndef TARGET_SENSOR_TILE +static void BlueButtonPressed () +{ + BlueButtonToggle = true; +} +#endif + +#ifdef SUBSCRIBE +void subscribe_cb(MQTT::MessageData & msgMQTT) { + char msg[MQTT_MAX_PAYLOAD_SIZE]; + msg[0]='\0'; + strncat (msg, (char*)msgMQTT.message.payload, msgMQTT.message.payloadlen); + printf ("--->>> subscribe_cb msg: %s\n\r", msg); +} + +int subscribe(char *pubTopic, MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client) +{ + return client->subscribe(pubTopic, MQTT::QOS1, subscribe_cb); +} +#endif + +int connect(MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTNetwork *mqttNetwork, NetworkInterface* network) +{ + const char* iot_ibm = MQTT_BROKER_URL; + char hostname[strlen(org) + strlen(iot_ibm) + 1]; + + sprintf(hostname, "%s%s", org, iot_ibm); + // Construct clientId - d:org:type:id + char clientId[strlen(org) + strlen(type) + strlen(id) + 5]; + sprintf(clientId, "d:%s:%s:%s", org, type, id); + sprintf(subscription_url, "%s.%s/#/device/%s/sensor/", org, "internetofthings.ibmcloud.com",id); + + // Network debug statements + LOG("=====================================\n\r"); + LOG("Nucleo IP ADDRESS: %s\n\r", network->get_ip_address()); + LOG("Nucleo MAC ADDRESS: %s\n\r", network->get_mac_address()); + LOG("Server Hostname: %s port: %d\n\r", hostname, IBM_IOT_PORT); +// for(int i = 0; clientId[i]; i++){ // set lowercase mac +// clientId[i] = tolower(clientId[i]); +// } + LOG("Client ID: %s\n\r", clientId); + LOG("Topic: %s\n\r",MQTT_TOPIC); + LOG("Subscription URL: %s\n\r", subscription_url); + LOG("=====================================\n\r"); + netConnecting = true; + int rc = mqttNetwork->connect(hostname, IBM_IOT_PORT); + if (rc != 0) + { + printf("rc from TCP connect is %d\r\n", rc); + return rc; + } + + printf ("--->TCP Connected\n\r"); + netConnected = true; + netConnecting = false; + + // MQTT Connect + mqttConnecting = true; + MQTTPacket_connectData data = MQTTPacket_connectData_initializer; + data.MQTTVersion = 4; + data.struct_version=0; + data.clientID.cstring = clientId; + data.keepAliveInterval = MQTT_KEEPALIVE; // in Sec + if (!quickstartMode) + { + data.username.cstring = "use-token-auth"; + data.password.cstring = auth_token; + } + if ((rc = client->connect(data)) != 0) { + printf("rc from MQTT connect is %d\r\n", rc); + connack_rc = rc; + return rc; + } + connected = true; + printf ("--->MQTT Connected\n\r"); +#ifdef SUBSCRIBE + int rc=0; + if ((rc=subscribe(MQTT_TOPIC, client)) == 0) LOG ("--->>>MQTT subscribed to: %s\n\r",MQTT_TOPIC); + else LOG ("--->>>ERROR MQTT subscribe : %s\n\r",MQTT_TOPIC); +#endif + mqttConnecting = false; + connack_rc = rc; + return rc; +} + + +int getConnTimeout(int attemptNumber) +{ // First 10 attempts try within 3 seconds, next 10 attempts retry after every 1 minute + // after 20 attempts, retry every 10 minutes + return (attemptNumber < 10) ? 3 : (attemptNumber < 20) ? 60 : 600; +} + + +void attemptConnect(MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTNetwork *mqttNetwork, NetworkInterface* network) +{ + connected = false; + + while (connect(client, mqttNetwork, network) != MQTT_CONNECTION_ACCEPTED) + { + if (connack_rc == MQTT_NOT_AUTHORIZED || connack_rc == MQTT_BAD_USERNAME_OR_PASSWORD) { + printf ("File: %s, Line: %d Error: %d\n\r",__FILE__,__LINE__, connack_rc); + return; // don't reattempt to connect if credentials are wrong + } + int timeout = getConnTimeout(++retryAttempt); + WARN("Retry attempt number %d waiting %d\n", retryAttempt, timeout); + + // if ipstack and client were on the heap we could deconstruct and goto a label where they are constructed + // or maybe just add the proper members to do this disconnect and call attemptConnect(...) + // this works - reset the system when the retry count gets to a threshold + if (retryAttempt == 5) + NVIC_SystemReset(); + else + wait(timeout); + } +} + +int publish(MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client) +{ + MQTT::Message message; + const char* pubTopic = MQTT_TOPIC; + + char buf[MQTT_MAX_PAYLOAD_SIZE]; + float temp, press, hum; + + if (!client->isConnected()) { printf ("---> MQTT DISCONNECTED\n\r"); return MQTT::FAILURE; } + temp_sensor1->get_temperature(&temp); + pressure_sensor->get_pressure(&press); + humidity_sensor->get_humidity(&hum); + sprintf(buf, + "{\"d\":{\"ST\":\"Nucleo-IoT-mbed\",\"Temp\":%0.4f,\"Pressure\":%0.4f,\"Humidity\":%0.4f}}", + temp, press, hum); + message.qos = MQTT::QOS0; + message.retained = false; + message.dup = false; + message.payload = (void*)buf; + message.payloadlen = strlen(buf); + + if( (message.payloadlen + strlen(pubTopic)+1) >= MQTT_MAX_PACKET_SIZE ) + printf("message too long!\r\n"); + + LOG("Publishing %s\n\r", buf); + return client->publish(pubTopic, message); +} + +int main() +{ + myled=0; + DevI2C *i2c = new DevI2C(I2C_SDA, I2C_SCL); + i2c->frequency(400000); + + XNucleoIKS01A2 *mems_expansion_board = XNucleoIKS01A2::instance(i2c); + pressure_sensor = mems_expansion_board->pt_sensor; + temp_sensor1 = mems_expansion_board->ht_sensor; + humidity_sensor = mems_expansion_board->ht_sensor; + pressure_sensor->enable(); + temp_sensor1->enable(); + humidity_sensor->enable(); + +#if !defined (TARGET_SENSOR_TILE) + InterruptIn BlueButton(USER_BUTTON); + BlueButton.fall(&BlueButtonPressed); + BlueButtonToggle = false; +#endif + + pc.printf("\r\nX-NUCLEO-IDW01M1 mbed Application\r\n"); + pc.printf("\r\nconnecting to AP\r\n"); + + quickstartMode=false; + if (strcmp(org, "quickstart") == 0){quickstartMode = true;} + NetworkInterface* network = easy_connect(true); + if (!network) { + printf ("Error easy_connect\n\r"); + return -1; + } + MQTTNetwork mqttNetwork(network); + MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE> client(mqttNetwork); + + if (quickstartMode){ + char mac[50]; // remove all : from mac + char *digit=NULL; + sprintf (id,"%s", ""); + sprintf (mac,"%s",network->get_mac_address()); + digit = strtok (mac,":"); + while (digit != NULL) + { + strcat (id, digit); + digit = strtok (NULL, ":"); + } + } + printf ("ATTEMPT CONNECT\n\r"); + attemptConnect(&client, &mqttNetwork, network); + if (connack_rc == MQTT_NOT_AUTHORIZED || connack_rc == MQTT_BAD_USERNAME_OR_PASSWORD) + { + printf ("---ERROR line : %d\n\r", __LINE__); + while (true) + wait(1.0); // Permanent failures - don't retry + } +#ifdef X_NUCLEO_NFC01A1_PRESENT + // program NFC with broker URL + XNucleoNFC01A1 *nfcNucleo = XNucleoNFC01A1::instance(*i2c, NULL, XNucleoNFC01A1::DEFAULT_GPO_PIN, XNucleoNFC01A1::DEFAULT_RF_DISABLE_PIN, NC,NC,NC); + NDefLib::NDefNfcTag& tag = nfcNucleo->get_M24SR().get_NDef_tag(); + printf("NFC Init done: !\r\n"); + //open the i2c session with the nfc chip + if(tag.open_session()){ + //create the NDef message and record + NDefLib::Message msg; + NDefLib::RecordURI rUri(NDefLib::RecordURI::HTTPS, subscription_url); + msg.add_record(&rUri); + //write the tag + if(tag.write(msg)){ + printf("Tag writed \r\n"); + } + //close the i2c session + if(!tag.close_session()){ + printf("Error Closing the session\r\n"); + } + }else printf("Error open Session\r\n"); +#endif + myled=1; + int count = 0; + while (true) + { + if (BlueButtonToggle == false && connected == true) { + if (++count == 6) + { // Publish a message every 3 second + if (publish(&client) != MQTT::SUCCESS) { + myled=0; + count=0; + client.disconnect(); + mqttNetwork.disconnect(); + attemptConnect(&client, &mqttNetwork, network); // if we have lost the connection + } else { + myled=1; + count=0; + } + } + client.yield(500); // allow the MQTT client to receive subscribe messages and manage keep alive + } else if (BlueButtonToggle == true && connected == true){ // disconnect MQTT + printf ("--->> Disconnect\n\r"); + connected = false; + count = 0; + BlueButtonToggle = false; +#ifdef SUBSCRIBE + // unsubscribe(const char* topicFilter); // unsubscribe if subscribed +#endif + client.disconnect(); + mqttNetwork.disconnect(); + } else if (BlueButtonToggle == true && connected == false) { + connected = true; + BlueButtonToggle = false; + } else wait (0.5); + } +} + \ No newline at end of file