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: azure_umqtt_c iothub_mqtt_transport mbed-rtos mbed wolfSSL Socket lwip-eth lwip-sys lwip
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 }
Generated on Wed Jul 13 2022 07:19:04 by
 1.7.2