Mark Radbourne / Mbed 2 deprecated FXOS8700CQ_To_Azure_IoT

Dependencies:   azure_umqtt_c iothub_mqtt_transport mbed-rtos mbed wolfSSL Socket lwip-eth lwip-sys lwip

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 // Copyright (c) Microsoft. All rights reserved.
00002 // Licensed under the MIT license. See LICENSE file at https://github.com/Azure/azure-iot-sdks/blob/master/LICENSE for full license information.
00003 
00004 /* -------------------------------------------------------------------------- *\
00005 
00006    Simple progam to demonstrate reading the FRDM-K64F FXOS8700CQ 
00007    accelerometer, convert the data to JSON and send to an Azure IoT Hub. You 
00008    must provide your hub's connection string in the variable 
00009    'connectionString'.
00010 
00011    markrad
00012 
00013 \* -------------------------------------------------------------------------- */
00014 
00015 #include <string.h>
00016 #include <limits.h>
00017 
00018 #include "SingletonFXOS8700CQ.h"
00019 
00020 #include "iothub_client.h"
00021 #include "iothub_message.h"
00022 #include "azure_c_shared_utility/threadapi.h"
00023 #include "azure_c_shared_utility/crt_abstractions.h"
00024 #include "azure_c_shared_utility/platform.h"
00025 #include "iothubtransportmqtt.h"
00026 #include "lock.h"
00027 
00028 #include "certs.h"
00029 #include "NTPClient.h"
00030 
00031 NTPClient ntp;
00032 
00033 /*
00034 int readingToJSON(char *buffer, int bufferlen, READING &reading)
00035 {
00036     static const char READING[] = "\"reading\"";
00037     static const char ACCELEROMETER[] = "\"accelerometer\"";
00038     static const char MAGNOMETER[] = "\"magnometer\"";
00039     static const char X[] = "\"X\"";
00040     static const char Y[] = "\"Y\"";
00041     static const char Z[] = "\"Z\"";
00042     static const char STARTOBJ[] = " : {\n";
00043     static const char ENDOBJ[] = "}\n";
00044     static const char PREPEND[] = "{\n";
00045     static const int MINBUFFERLEN = 
00046         sizeof(READING) + 
00047         sizeof(ACCELEROMETER) +
00048         sizeof(MAGNOMETER) +
00049         2 * (sizeof(X) + sizeof(Y) + sizeof(Z)) +
00050         3 * sizeof(STARTOBJ) +
00051         4 * sizeof(ENDOBJ) +
00052         sizeof(PREPEND) +
00053         6 * 9;
00054     static const char numConvert[] = "%d";
00055     
00056     char toNum[10];
00057     char work[MINBUFFERLEN + 1];
00058     
00059     if (buffer == NULL)
00060         return 0;
00061     
00062     buffer[0] = '\0';
00063         
00064     strcpy(work, PREPEND);
00065     strcat(work, READING);
00066     strcat(work, STARTOBJ);
00067     strcat(work, ACCELEROMETER);
00068     strcat(work, STARTOBJ);
00069     strcat(work, X);
00070     strcat(work, " : ");
00071     sprintf(toNum, numConvert, reading.accelerometer.x);
00072     strcat(work, toNum);
00073     strcat(work, ",\n");
00074     strcat(work, Y);
00075     strcat(work, " : ");
00076     sprintf(toNum, numConvert, reading.accelerometer.y);
00077     strcat(work, toNum);
00078     strcat(work, ",\n");
00079     strcat(work, Z);
00080     strcat(work, " : ");
00081     sprintf(toNum, numConvert, reading.accelerometer.z);
00082     strcat(work, toNum);
00083     strcat(work, "\n");
00084     strcat(work, ENDOBJ);
00085     strcat(work, MAGNOMETER);
00086     strcat(work, STARTOBJ);
00087     strcat(work, X);
00088     strcat(work, " : ");
00089     sprintf(toNum, numConvert, reading.magnometer.x);
00090     strcat(work, toNum);
00091     strcat(work, ",\n");
00092     strcat(work, Y);
00093     strcat(work, " : ");
00094     sprintf(toNum, numConvert, reading.magnometer.y);
00095     strcat(work, toNum);
00096     strcat(work, ",\n");
00097     strcat(work, Z);
00098     strcat(work, " : ");
00099     sprintf(toNum, numConvert, reading.magnometer.z);
00100     strcat(work, toNum);
00101     strcat(work, "\n");
00102     strcat(work, ENDOBJ);
00103     strcat(work, ENDOBJ);
00104     strcat(work, ENDOBJ);
00105     
00106     if (strlen(work) + 1 < bufferlen)
00107         strcpy(buffer, work); 
00108     
00109     return strlen(work);
00110 }
00111 */
00112 
00113 static int JSONifyData(char *buffer, int bufferlen, int reading)
00114 {
00115     static const char *format = "{ \"device\": \"%s\", \"timestamp\": \"%s\", \"epochoffset\": %d, \"reading\": %f }";
00116     static const char *timeFormat = "%FT%X";
00117     char timeOut[80];
00118     double work;
00119     int rc;
00120     time_t rawtime = 0;
00121     struct tm *ptm;
00122     
00123     // gmtime() does not work on the FRDM K64F - set RTC to UTC
00124     rawtime = time(NULL);
00125     ptm = localtime(&rawtime);
00126     
00127     strftime(timeOut, sizeof(timeOut), timeFormat, ptm);
00128     printf("rawtime=%d;time=%s\r\n", rawtime, timeOut);
00129     work = sqrt((double)reading);
00130     rc = snprintf(buffer, bufferlen, format, "mydevice", timeOut, rawtime, work);   
00131     
00132     if (rc < 0)
00133         printf("*** ERROR *** out of buffer space\r\n");
00134         
00135     return rc;
00136 }    
00137 
00138 static LOCK_HANDLE msgLock;
00139 static int msgCount = 0;
00140 static Timer t;
00141 static int CONNECTIONTIMEOUT = (20 * 1000);
00142 
00143 static IOTHUBMESSAGE_DISPOSITION_RESULT ReceiveMessageCallback(IOTHUB_MESSAGE_HANDLE message, void* userContextCallback)
00144 {
00145     int* counter = (int*)userContextCallback;
00146     const char* buffer;
00147     size_t size;
00148 
00149     if (IoTHubMessage_GetByteArray(message, (const unsigned char**)&buffer, &size) != IOTHUB_MESSAGE_OK)
00150     {
00151         (void)printf("unable to retrieve the message data\r\n");
00152     }
00153     else
00154     {
00155         (void)printf("Received Message [%d] with Data: <<<%.*s>>> & Size=%d\r\n", *counter, (int)size, buffer, (int)size);
00156     }
00157 
00158     // Some device specific action code goes here...
00159     (*counter)++;
00160 
00161     return IOTHUBMESSAGE_ACCEPTED;
00162 }
00163 
00164 static void SendConfirmationCallback(IOTHUB_CLIENT_CONFIRMATION_RESULT result, void* userContextCallback)
00165 {
00166     int* messageTrackingId = (int*)userContextCallback;
00167     
00168     (void)printf("Confirmation received for message tracking id = %d with result = %s\r\n", 
00169         *messageTrackingId, ENUM_TO_STRING(IOTHUB_CLIENT_CONFIRMATION_RESULT, result));
00170         
00171     free(userContextCallback);
00172     Lock(msgLock);
00173     msgCount--;
00174         
00175     if (result == IOTHUB_CLIENT_CONFIRMATION_OK)
00176     {
00177         t.stop();
00178         t.reset();
00179     }
00180 
00181     Unlock(msgLock);
00182 
00183 }
00184 
00185 void stall(Serial &pc, char *message)
00186 {
00187     printf(message);
00188     printf("stalled ");
00189     
00190     while(true) 
00191     {
00192         pc.putc('.'); // idle dots
00193         wait(1.0);
00194     }
00195 }
00196 
00197 IOTHUB_CLIENT_HANDLE setupConnection(Serial &pc, const char *connectionString, IOTHUB_CLIENT_TRANSPORT_PROVIDER protocol, void *receiveContext)
00198 {
00199     IOTHUB_CLIENT_HANDLE iotHubClientHandle = NULL;
00200     
00201     printf("Calling platform_init\r\n");
00202     
00203     while (platform_init())
00204     {
00205         pc.putc('P');
00206         wait(1.0);
00207         platform_deinit();
00208     }
00209     
00210 //    if (platform_init() != 0)
00211 //        stall(pc, "Failed to initialize platform\n");
00212         
00213     printf("Calling IoTHubClient_CreateFromConnectionString\r\n");
00214     if ((iotHubClientHandle = IoTHubClient_CreateFromConnectionString(connectionString, protocol)) == NULL)
00215         stall(pc, "ERROR: Could not create iotHubClientHandle\n");
00216         
00217     bool traceOn = false;
00218     //bool traceOn = true;
00219     
00220     printf("Calling IoTHubClient_SetOption logtrace with %d\r\n", traceOn);
00221     IoTHubClient_SetOption(iotHubClientHandle, "logtrace", &traceOn);
00222 
00223     // For mbed add the certificate information
00224     printf("Calling IoTHubClient_SetOption TrustedCerts\r\n");
00225 
00226     if (IoTHubClient_SetOption(iotHubClientHandle, "TrustedCerts", certificates) != IOTHUB_CLIENT_OK)
00227         stall(pc, "ERROR: failure to set option \"TrustedCerts\"\n");
00228 
00229     printf("Calling IoTHubClient_SetMessageCallback\r\n");
00230 
00231     if (IoTHubClient_SetMessageCallback(iotHubClientHandle, ReceiveMessageCallback, receiveContext) != IOTHUB_CLIENT_OK)
00232         stall(pc, "ERROR: IoTHubClient_SetMessageCallback failed\r\n");
00233     
00234     return iotHubClientHandle;
00235 }
00236 
00237 void terminateConnection(Serial &pc, IOTHUB_CLIENT_HANDLE iotHubClientHandle)
00238 {
00239     printf("Calling IoTHubClient_Destroy\r\n");
00240     IoTHubClient_Destroy(iotHubClientHandle);
00241     printf("Calling platform_deinit\r\n");
00242     platform_deinit();
00243     printf("Connection terminated\r\n");
00244 }    
00245 
00246 void calibrate(double *pmean, double *pdeviation)
00247 {
00248     READING reading;
00249     const int calibrationPeriod = 10;    // in seconds
00250     SingletonFXOS8700CQ &sfxos = SingletonFXOS8700CQ::getInstance();
00251     
00252     double *data = new double[calibrationPeriod * 50];
00253     int i;
00254     double sum = 0.0;
00255     double mean = 0.0;
00256     double temp;
00257     
00258     printf("Calibrating...\r\n");
00259     
00260     i = calibrationPeriod * 50;
00261     
00262     while (i > 0)
00263     {
00264         if (sfxos.getInt2Triggered())
00265         {
00266             sfxos.setInt2Triggered(false);
00267             sfxos.getData(reading);
00268             data[i] = sqrt((double)(reading.accelerometer.x * reading.accelerometer.x) + (reading.accelerometer.y * reading.accelerometer.y));
00269 //            data[i] = reading.accelerometer.x + reading.accelerometer.y;
00270             printf("x=%d\t\ty=%d\t\tsum=%f\r\n", reading.accelerometer.x, reading.accelerometer.y, data[i]);
00271             sum += data[i];
00272             --i;
00273         }
00274         else
00275         {
00276             printf("WARNING: Sensor was not ready in time during calibration\r\n");
00277         }
00278         wait_ms(20);
00279     }
00280     
00281     mean = (double)sum / (double)(calibrationPeriod * 50);
00282     
00283     for (i = 0; i < calibrationPeriod * 50; i++)
00284     {
00285         temp += ((float)data[i] - mean) * ((float)data[i] - mean);
00286     }
00287     
00288     temp /= (double)(calibrationPeriod * 50);
00289     
00290     delete [] data;
00291     
00292     *pmean = mean;
00293     *pdeviation = sqrt(temp);
00294     
00295     printf("Calibration complete - mean=%f; devation=%f\r\n", *pmean, *pdeviation);
00296 }
00297 
00298 int main()
00299 {
00300     const char *connectionString = "HostName=MarkRadHub1.azure-devices.net;DeviceId=mrcc3200;SharedAccessKey=8pGKChTBsz0VGw234iLX7XDDKwcyWRC7hsrVZEHfZHs=";
00301     const char *ntpServer = "0.pool.ntp.org";
00302     const int ntpRefreshInterval = 60 * 60;
00303     const int ledInterval = 300 / 20;
00304 
00305     READING reading;
00306     Serial pc(USBTX, USBRX); // Primary output to demonstrate library
00307     SingletonFXOS8700CQ &sfxos = SingletonFXOS8700CQ::getInstance();
00308     IOTHUB_CLIENT_HANDLE iotHubClientHandle;
00309     int receiveContext = 0;
00310     int transmitCounter = 0;
00311     double mean;
00312     double deviation;
00313     DigitalOut ledBlue(LED_BLUE);    
00314     
00315     pc.baud(115200); // Print quickly! 200Hz x line of output data!
00316     ledBlue = 1;
00317     
00318     printf("\n\n\rFXOS8700CQ identity = %X\r\n", sfxos.getWhoAmI());
00319     
00320     msgLock = Lock_Init();  // TODO: Check error code
00321     
00322     sfxos.enable();
00323     sfxos.getData(reading);
00324     
00325     int rc;
00326 
00327     int LOOPCOUNT = -1;     // Set to -1 to run forever
00328     
00329     int localMsgCount;
00330     int *userContext;
00331     IOTHUB_MESSAGE_HANDLE msgHandle;
00332     int elapsedTime = 0;
00333     
00334     char buffer[200];
00335     
00336     iotHubClientHandle = setupConnection(pc, connectionString, MQTT_Protocol, &receiveContext);
00337     calibrate(&mean, &deviation);
00338     
00339     int readCount = 0;
00340     int32_t maxVal = LONG_MIN;
00341     int32_t curVal;
00342     time_t lastUpdate = 0;
00343     int ntpRc;
00344     int ledOffAt = 0;
00345     
00346     while (NTP_OK != (ntpRc = ntp.setTime("0.pool.ntp.org")))
00347     {
00348         printf("ERROR: Failed to set current time from NTP server - rc = %d\r\n", ntpRc);
00349         wait_ms(100);
00350     }
00351     
00352     lastUpdate = time(NULL);
00353     
00354     while (LOOPCOUNT)
00355     {
00356         if (sfxos.getInt2Triggered())
00357         {
00358             sfxos.setInt2Triggered(false);
00359             sfxos.getData(reading);
00360             curVal = (reading.accelerometer.x * reading.accelerometer.x) + (reading.accelerometer.y * reading.accelerometer.y);
00361             
00362             if (curVal > maxVal)
00363             {
00364                 maxVal = curVal;
00365                 //printf("new maxVal=%d\r\n", maxVal);
00366             }
00367             
00368             //rc = readingToJSON(buffer, sizeof(buffer), reading);
00369             
00370             //if (rc > sizeof(buffer))
00371                 //printf("ERROR: JSON buffer too small - require %d characters\n", rc);
00372 
00373             if (++readCount >= 50)
00374             {
00375                 Lock(msgLock);
00376                 localMsgCount = msgCount;
00377                 Unlock(msgLock);
00378                 
00379                 if (localMsgCount < 2)
00380                 {
00381                     rc = JSONifyData(buffer, sizeof(buffer), maxVal);
00382                     //printf("DATA >>>%s<<<\r\n", buffer);
00383                     
00384                     if ((msgHandle = IoTHubMessage_CreateFromByteArray((const unsigned char*)buffer, rc)) == NULL)
00385                     {
00386                         (void)printf("ERROR: iotHubMessageHandle is NULL!\r\n");
00387                     }
00388                     else
00389                     {
00390                         userContext = (int *) malloc(sizeof(userContext));
00391                         
00392                         if (userContext != NULL)
00393                         {
00394                             *userContext = transmitCounter;
00395         
00396                             if (IoTHubClient_SendEventAsync(iotHubClientHandle, msgHandle, SendConfirmationCallback, userContext) != IOTHUB_CLIENT_OK)
00397                             {
00398                                 (void)printf("ERROR: IoTHubClient_LL_SendEventAsync..........FAILED!\r\n");
00399                             }
00400                             else
00401                             {
00402                                 (void)printf("IoTHubClient_LL_SendEventAsync accepted message [%d] for transmission to IoT Hub.\r\n", (int)transmitCounter);
00403                                 ledBlue = 0;
00404                                 ledOffAt = ledInterval;
00405                             }
00406                             
00407                             IoTHubMessage_Destroy(msgHandle);
00408                             Lock(msgLock);
00409                             msgCount++;
00410                             t.start();
00411                             Unlock(msgLock);
00412                             
00413                             transmitCounter++;
00414                         }
00415                         else
00416                         {
00417                             (void)printf("ERROR: malloc - unable to allocate user context\r\n");
00418                         }
00419                     }
00420                 }
00421                 else
00422                 {
00423                     (void)printf("WARNING: Message dropped queue length %d\r\n", localMsgCount);
00424                 }
00425                 
00426                 Lock(msgLock);
00427                 elapsedTime = t.read_ms();
00428                 Unlock(msgLock);
00429                 
00430                 if (elapsedTime > CONNECTIONTIMEOUT)
00431                 {
00432                     printf("No response for %d milliseconds - attempt reconnection\r\n", elapsedTime);
00433                     NVIC_SystemReset(); // Just blow it all away
00434                     terminateConnection(pc, iotHubClientHandle);
00435                     iotHubClientHandle = setupConnection(pc, connectionString, MQTT_Protocol, &receiveContext);
00436                     printf("Reconnection complete\r\n");
00437                 }
00438                             
00439                 if (LOOPCOUNT > 0)
00440                     LOOPCOUNT--;
00441                     
00442                 readCount = 0;
00443                 maxVal = LONG_MIN;
00444                 
00445                 if (time(NULL) - lastUpdate > ntpRefreshInterval)
00446                 {
00447                     while (NTP_OK != (ntpRc = ntp.setTime("0.pool.ntp.org")))
00448                     {
00449                         printf("ERROR: Failed to set current time from NTP server - rc = %d\r\n", ntpRc);
00450                         wait_ms(100);
00451                     }
00452                     
00453                     lastUpdate = time(NULL);
00454                 }
00455             }
00456         }
00457         else
00458         {
00459             printf("WARNING: Sensor was not ready in time\r\n");
00460         }
00461         
00462         if (!((int)ledBlue) && --ledOffAt <= 0)
00463         {
00464             ledBlue = 1;
00465         }
00466         
00467         // Read at 50 hz
00468         wait_ms(20);
00469     }
00470     
00471     printf("Loop complete - clean up\n");
00472     
00473     terminateConnection(pc, iotHubClientHandle);
00474     Lock_Deinit(msgLock);
00475     
00476     printf("Test complete\n");
00477     
00478 
00479     while(true) 
00480     {
00481         pc.putc('.'); // idle dots
00482         wait(1.0);
00483     }
00484 }