Wireless Networks tester code

Dependencies:   BME280 C027_Support MQTT mbed-rtos mbed

Files at this revision

API Documentation at this revision

Comitter:
maximusismax
Date:
Wed Nov 30 15:27:36 2016 +0000
Commit message:
took lots out, doesnt work yet though

Changed in this revision

BME280.lib Show annotated file Show diff for this revision Revisions of this file
C027_Support.lib Show annotated file Show diff for this revision Revisions of this file
MQTT.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-rtos.lib Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BME280.lib	Wed Nov 30 15:27:36 2016 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/MACRUM/code/BME280/#ddcaa259e65b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/C027_Support.lib	Wed Nov 30 15:27:36 2016 +0000
@@ -0,0 +1,1 @@
+https://developer.mbed.org/users/maximusismax/code/C027_Support/#356926c18d08
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MQTT.lib	Wed Nov 30 15:27:36 2016 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/teams/mqtt/code/MQTT/#e335fcc1a663
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Wed Nov 30 15:27:36 2016 +0000
@@ -0,0 +1,381 @@
+/*
+#include "mbed.h"
+#include "BME280.h"
+#ifdef TARGET_UBLOX_C027
+ #include "C027_api.h"
+#else
+ #error "This example is targeted for the C027 platform"
+#endif
+
+DigitalOut myled(LED1);
+Serial pc(USBTX, USBRX);
+I2C i2c(P0_0, P0_1);
+BME280 sensor(i2c);
+
+int main() {
+    float temp = 0;
+    float pres = 0;
+    float humid = 0;
+    pc.printf("Starting simple test program");
+    
+    sensor.initialize();
+    while(1) {
+        myled = !myled;
+        wait(0.2);
+        temp = sensor.getTemperature();
+        pres = sensor.getPressure();
+        humid = sensor.getHumidity();
+        pc.printf("temp: %f, pres: %f, humid: %f\n", temp, pres, humid);
+    }    
+}
+*/
+
+/*******************************************************************************
+ * Copyright (c) 2014 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:
+ *    Sam Danbury - initial implementation
+ *    Ian Craggs - refactoring to remove STL and other changes
+ *    Sam Grove  - added check for Ethernet cable.
+ *    Chris Styles - Added additional menu screen for software revision
+ *
+ * To do :
+ *    Add magnetometer sensor output to IoT data stream
+ *
+ *******************************************************************************/
+
+#define USE_CELLULAR    // Enable this switch on the C027 to use cellular
+
+
+#include "MQTTClient.h"
+
+#include "rtos.h"
+
+// Update this to the next number *before* a commit
+#define __APP_SW_REVISION__ "11"
+#define BOARD_NAME "IoT u-blox"
+
+// Configuration values needed to connect to IBM IoT Cloud
+#define ORG "quickstart"             // 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 TYPE_NAME DEFAULT_TYPE_NAME  // For a registered connection, replace with your type
+
+#define MQTT_PORT 1883
+#define MQTT_TLS_PORT 8883
+#define IBM_IOT_PORT MQTT_PORT
+
+#define MQTT_MAX_PACKET_SIZE 250
+
+//------------------------------------------------------------------------------------
+// You need to configure these cellular modem / SIM parameters.
+// These parameters are ignored for LISA-C200 variants and can be left NULL.
+//------------------------------------------------------------------------------------
+# include "MDM.h"
+//! Set your secret SIM pin here (e.g. "1234"). Check your SIM manual.
+# define SIMPIN      "1111" //default EE sim pin
+/*! The APN of your network operator SIM, sometimes it is "internet" check your 
+    contract with the network operator. You can also try to look-up your settings in 
+    google: https://www.google.de/search?q=APN+list */
+# define APN         "everywhere" //EE default
+//! Set the user name for your APN, or NULL if not needed
+# define USERNAME    NULL
+//! Set the password for your APN, or NULL if not needed
+# define PASSWORD    NULL 
+//------------------------------------------------------------------------------------
+# include "GPS.h"
+//------------------------------------------------------------------------------------
+
+
+static uint32_t linkStatus(void) { return true; }
+
+#define DEFAULT_TYPE_NAME "iotsample-mbed-c027"
+
+#define MQTT_CLIENT_TYPE MQTTSocket
+#include "MQTTSocket.h"
+
+bool quickstartMode = true;
+char org[11] = ORG;  
+char type[30] = TYPE_NAME;
+char id[30] = ID;                 // device ID
+char auth_token[30] = AUTH_TOKEN; // Auth_token is only used in non-quickstart mode
+
+bool connected = false;
+
+int connect(MQTT::Client<MQTT_CLIENT_TYPE, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTT_CLIENT_TYPE* ipstack)
+{   
+    const char* iot_ibm = ".messaging.internetofthings.ibmcloud.com";
+    
+    char hostname[strlen(org) + strlen(iot_ibm) + 1];
+    sprintf(hostname, "%s%s", org, iot_ibm);
+    DEBUG("hostname is %s\n", hostname);
+    int rc = ipstack->connect(hostname, IBM_IOT_PORT);
+    if (rc != 0)
+        return rc;
+     
+    // Construct clientId - d:org:type:id
+    char clientId[strlen(org) + strlen(type) + strlen(id) + 5];
+    sprintf(clientId, "d:%s:%s:%s", org, type, id);
+    DEBUG("clientid is %s\n", clientId);
+    
+    // MQTT Connect
+    MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
+    data.MQTTVersion = 3;
+    data.clientID.cstring = clientId;
+    
+    if (!quickstartMode) 
+    {        
+        data.username.cstring = "use-token-auth";
+        data.password.cstring = auth_token;
+    }
+    
+    if ((rc = client->connect(data)) == 0) 
+    {       
+        connected = true;
+    }
+    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<MQTT_CLIENT_TYPE, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTT_CLIENT_TYPE* ipstack)
+{
+    int retryAttempt = 0;
+    connected = false;
+    
+    // make sure a cable is connected before starting to connect
+    while (!linkStatus()) {
+        wait(1.0f);
+        WARN("Internet link not present. Check cable connection\n");
+    }
+        
+    while (connect(client, ipstack) != 0) 
+    {    
+        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<MQTT_CLIENT_TYPE, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTT_CLIENT_TYPE* ipstack)
+{
+    MQTT::Message message;
+    char* pubTopic = "iot-2/evt/status/fmt/json";
+            
+    char buf[250];
+    int l = 0;
+    l += sprintf(buf+l,"{\"d\":{\"myName\":\"%s\"", BOARD_NAME);
+    //if (shieldConnected) {
+        /*
+        l += sprintf(buf+l,",\"accelX\":%0.4f,\"accelY\":%0.4f,\"accelZ\":%0.4f", MMA.x(), MMA.y(), MMA.z());
+        l += sprintf(buf+l,",\"temp\":%0.4f", sensor.temp());
+        l += sprintf(buf+l,",\"joystick\":\"%s\"", joystickPos);
+        l += sprintf(buf+l,",\"potentiometer1\":%0.4f,\"potentiometer2\":%0.4f", ain1.read(), ain2.read());
+        */
+        //l += sprintf(buf+l,",\"temp\":%0.4f", sensor.getTemperature());
+    //}
+    l += sprintf(buf+l,"}}");
+
+    message.qos = MQTT::QOS0;
+    message.retained = false;
+    message.dup = false;
+    message.payload = (void*)buf;
+    message.payloadlen = strlen(buf);
+    
+    LOG("Publishing %s\n", buf);
+    return client->publish(pubTopic, message);
+}
+
+int publishMdm(MQTT::Client<MQTT_CLIENT_TYPE, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTT_CLIENT_TYPE* ipstack, MDMParser* mdm)
+{
+    MQTT::Message message;
+    char* pubTopic = "iot-2/evt/modem/fmt/json";
+    char buf[250];
+    int l = 0;
+    MDMParser::IP ip = mdm->getIpAddress();
+    l += sprintf(buf+l,"{\"d\":{\"ip\":\"" IPSTR "\"", IPNUM(ip));
+    MDMParser::NetStatus sta;
+    mdm->checkNetStatus(&sta);
+    //const char* txtAct[] = { "Unknown", "GSM", "Edge", "3G", "CDMA" };
+    //if (sta.act < sizeof(txtAct)/sizeof(*txtAct) && (sta.act != MDMParser::ACT_UNKNOWN))
+    //    l += sprintf(buf+l,",\"act\":\"%s\"",txtAct[sta.act]);
+    //if (*sta.num)             l += sprintf(buf+l,",\"num\":\"%s\"",sta.num);
+    //if (sta.lac != 0xFFFF)    l += sprintf(buf+l,",\"lac\":\"%04X\"",sta.lac);
+    //if (sta.ci != 0xFFFFFFFF) l += sprintf(buf+l,",\"ci\":\"%06X\"",sta.ci);
+    if (sta.rssi)             l += sprintf(buf+l,",\"rssi\":%d",sta.rssi);
+    if (sta.ber)              l += sprintf(buf+l,",\"ber\":%d",sta.ber);
+    if (*sta.opr)             l += sprintf(buf+l,",\"operator\":\"%s\"",sta.opr);
+    l += sprintf(buf+l,"}}");
+
+    message.qos = MQTT::QOS0;
+    message.retained = false;
+    message.dup = false;
+    message.payload = (void*)buf;
+    message.payloadlen = strlen(buf);
+    
+    LOG("Publishing %s\n", buf);
+    return client->publish(pubTopic, message);
+}
+
+int publishGps(MQTT::Client<MQTT_CLIENT_TYPE, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTT_CLIENT_TYPE* ipstack, double lat, double lon)
+{
+    MQTT::Message message;
+    char* pubTopic = "iot-2/evt/gps/fmt/json";
+    char buf[250];
+    sprintf(buf,"{\"d\":{\"lat\":\"%.7f\",\"long\":\"%.7f\"}}", lat, lon);
+    message.qos = MQTT::QOS0;
+    message.retained = false;
+    message.dup = false;
+    message.payload = (void*)buf;
+    message.payloadlen = strlen(buf);
+    LOG("Publishing GPS %s\n", buf);
+    return client->publish(pubTopic, message);
+}
+
+void messageArrived(MQTT::MessageData& md)
+{
+    MQTT::Message &message = md.message;
+    char topic[md.topicName.lenstring.len + 1];
+    
+    sprintf(topic, "%.*s", md.topicName.lenstring.len, md.topicName.lenstring.data);
+    
+    LOG("Message arrived on topic %s: %.*s\n",  topic, message.payloadlen, message.payload);
+          
+    // Command topic: iot-2/cmd/blink/fmt/json - cmd is the string between cmd/ and /fmt/
+    char* start = strstr(topic, "/cmd/") + 5;
+    int len = strstr(topic, "/fmt/") - start;
+    
+    if (memcmp(start, "blink", len) == 0)
+    {
+        char payload[message.payloadlen + 1];
+        sprintf(payload, "%.*s", message.payloadlen, (char*)message.payload);
+    
+        char* pos = strchr(payload, '}');
+        
+        
+        
+        
+        if (pos != NULL)
+        {
+            *pos = '\0';
+            if ((pos = strchr(payload, ':')) != NULL)
+            {
+                //int blink_rate = atoi(pos + 1);       
+                //blink_interval = (blink_rate <= 0) ? 0 : (blink_rate > 50 ? 1 : 50/blink_rate);
+            }
+        }
+    }
+    else
+        WARN("Unsupported command: %.*s\n", len, start);
+}
+
+int main()
+{    
+    printf("Starting program\n");
+
+    printf("Connecting");
+    
+    MDMSerial mdm;
+    //mdm.setDebug(3); // enable this for debugging issues 
+    if (!mdm.connect(SIMPIN, APN,USERNAME,PASSWORD))
+        return -1;
+
+    GPSI2C gps;
+    
+    MQTT_CLIENT_TYPE ipstack;
+    MQTT::Client<MQTT_CLIENT_TYPE, Countdown, MQTT_MAX_PACKET_SIZE> client(ipstack);
+    if (quickstartMode)
+    {
+        MDMParser::DevStatus dev;
+        mdm.getDevStatus(&dev);
+        if      (*dev.imei) strncpy(id, dev.imei, sizeof(id)-1);
+        else if (*dev.meid) strncpy(id, dev.meid, sizeof(id)-1);
+    }
+    
+    LOG("IBM Quickstart: https://quickstart.internetofthings.ibmcloud.com/#/device/%s/sensor/\n", id);
+    
+    attemptConnect(&client, &ipstack);
+    
+    if (!quickstartMode) 
+    {
+        int rc = 0;
+        if ((rc = client.subscribe("iot-2/cmd/+/fmt/json", MQTT::QOS1, messageArrived)) != 0)
+            WARN("rc from MQTT subscribe is %d\n", rc); 
+    }
+    
+    //blink_interval = 0;
+    int count = 0;
+    int count2 = 0;
+    while (true)
+    {
+        if (++count == 100)
+        {               // Publish a message every second
+            if ((publish(&client, &ipstack) != 0) ||
+                (publishMdm(&client, &ipstack, &mdm) != 0)) 
+                attemptConnect(&client, &ipstack);   // if we have lost the connection
+            count = 0;
+        }
+        if (++count2 == 10)
+        {               // Publish a message every second
+            count2 = 0;
+            while (1) {
+                char buf[256];
+                int ret = gps.getMessage(buf, sizeof(buf));
+                if (ret <= 0) break;
+                int len = LENGTH(ret);
+                if ((PROTOCOL(ret) == GPSParser::NMEA) && (len > 6)) {
+                    // talker is $GA=Galileo $GB=Beidou $GL=Glonass $GN=Combined $GP=GPS
+                    if ((buf[0] == '$') || buf[1] == 'G') {
+                        #define _CHECK_TALKER(s) ((buf[3] == s[0]) && (buf[4] == s[1]) && (buf[5] == s[2]))
+                        if (_CHECK_TALKER("GGA")) {
+                            //printf("%.*s\n", len, buf); 
+                            char ch;
+                            double latitude, longitude, elevation;
+                            static double lastLat = 0, lastLon = 0;
+                            if (gps.getNmeaAngle(2,buf,len,latitude) && 
+                                gps.getNmeaAngle(4,buf,len,longitude) && 
+                                gps.getNmeaItem(6,buf,len,ch) &&
+                                gps.getNmeaItem(9,buf,len,elevation)) {
+                                //printf("GPS Location: %.5f %.5f %.1f %c\r\n", latitude, longitude, elevation, ch); 
+                                if ((ch == '1' || ch == '2' || ch == '6') && 
+                                    (fabs(lastLat - latitude)  < 0.0000001) && 
+                                    (fabs(lastLon - longitude) < 0.0000001)) {
+                                    publishGps(&client, &ipstack, latitude, longitude);
+                                    lastLat = latitude;
+                                    lastLon = longitude;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        
+
+        client.yield(10);  // allow the MQTT client to receive messages
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos.lib	Wed Nov 30 15:27:36 2016 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed-rtos/#58563e6cba1e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Wed Nov 30 15:27:36 2016 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/d75b3fe1f5cb
\ No newline at end of file