An example that demonstrates uploading data from the DISCO-F746 (STM32F746) board to GroveStreams.com, an IoT analytics platform. Also demonstrations downloading commands, re-establishing dropped ethernet connections, accurate polling frequencies, and tracing to the LCD.
Dependencies: BSP_DISCO_F746NG F7_Ethernet GroveStreams LCD_DISCO_F746NG LcdDiscoF746NgTracer MbedJSONValue NetworkAPI mbed-rtos mbed
main.cpp@1:83187cd9f34d, 2017-01-05 (annotated)
- Committer:
- mmills
- Date:
- Thu Jan 05 18:48:17 2017 +0000
- Revision:
- 1:83187cd9f34d
- Parent:
- 0:04ac35f1846e
An example of pushing data into GroveStreams.com. The example is for the STM32F746 and demonstrates:; * Polling; * Tracing to the LCD; * Uploading Samples; * Downloading Commands; * Handling dropped Ethernet connections
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
mmills | 0:04ac35f1846e | 1 | /* |
mmills | 0:04ac35f1846e | 2 | |
mmills | 0:04ac35f1846e | 3 | STM32F746 GroveStreams Stream Feed via Ethernet |
mmills | 0:04ac35f1846e | 4 | |
mmills | 1:83187cd9f34d | 5 | This GroveStreams example is designed for the STM32F746. |
mmills | 0:04ac35f1846e | 6 | A full "how to" guide for this sketh can be found at https://www.grovestreams.com/developers/getting_started_stm32F746.html |
mmills | 0:04ac35f1846e | 7 | This example: |
mmills | 0:04ac35f1846e | 8 | * Demonstrates uploading data to GroveStreams while downloading commands. |
mmills | 0:04ac35f1846e | 9 | * Demonstrates the GroveStreams API: https://www.grovestreams.com/developers/api.html |
mmills | 0:04ac35f1846e | 10 | * Passing in a custom name for a new component |
mmills | 0:04ac35f1846e | 11 | * Passing in a component template ID to be used for new component definitions |
mmills | 0:04ac35f1846e | 12 | * Downloading a couple of commands during the sample upload and implements them. |
mmills | 0:04ac35f1846e | 13 | * Demonstrates an accurate way to poll and send samples periodically |
mmills | 0:04ac35f1846e | 14 | * Demonstrates send retries and Internet Connection Reset logic to ensure the |
mmills | 0:04ac35f1846e | 15 | STM32 stays connected and can regain connectivity after a network outage. |
mmills | 0:04ac35f1846e | 16 | * Printing verbose trace statements to the LCD (optional) |
mmills | 0:04ac35f1846e | 17 | The STM32 uses DHCP and DNS for a simpler network setup. |
mmills | 0:04ac35f1846e | 18 | |
mmills | 0:04ac35f1846e | 19 | License: |
mmills | 0:04ac35f1846e | 20 | Copyright (C) 2017 GroveStreams LLC. |
mmills | 0:04ac35f1846e | 21 | Licensed under the Apache License, Version 2.0 (the "License"); |
mmills | 0:04ac35f1846e | 22 | you may not use this file except in compliance with the License. |
mmills | 0:04ac35f1846e | 23 | You may obtain a copy of the License at: http://www.apache.org/licenses/LICENSE-2.0 |
mmills | 0:04ac35f1846e | 24 | |
mmills | 0:04ac35f1846e | 25 | Unless required by applicable law or agreed to in writing, software |
mmills | 0:04ac35f1846e | 26 | distributed under the License is distributed on an "AS IS" BASIS, |
mmills | 0:04ac35f1846e | 27 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
mmills | 0:04ac35f1846e | 28 | See the License for the specific language governing permissions and |
mmills | 0:04ac35f1846e | 29 | limitations under the License. |
mmills | 0:04ac35f1846e | 30 | */ |
mmills | 0:04ac35f1846e | 31 | |
mmills | 0:04ac35f1846e | 32 | #if !FEATURE_LWIP |
mmills | 0:04ac35f1846e | 33 | #error [NOT_SUPPORTED] LWIP not supported for this target |
mmills | 0:04ac35f1846e | 34 | #endif |
mmills | 0:04ac35f1846e | 35 | |
mmills | 0:04ac35f1846e | 36 | #include "mbed.h" |
mmills | 0:04ac35f1846e | 37 | #include "LcdDiscoF746NgTracer.h" |
mmills | 0:04ac35f1846e | 38 | #include "GroveStreams.h" |
mmills | 0:04ac35f1846e | 39 | #include "MbedJSONValue.h" |
mmills | 0:04ac35f1846e | 40 | |
mmills | 0:04ac35f1846e | 41 | // GroveStreams Settings |
mmills | 0:04ac35f1846e | 42 | const char gsApiKey[] = "YOUR_SECRET_API_KEY_HERE"; //Change This!!! |
mmills | 0:04ac35f1846e | 43 | const char gsCompName[] = "STM32F746+Discovery"; //Optionally change. Set this to give your component a name when it initially registers. Encode special chars such as spaces. |
mmills | 0:04ac35f1846e | 44 | |
mmills | 0:04ac35f1846e | 45 | const char gsCompTmplId[] = ""; //Optional. Tells GS what template to use when the feed initially arrives and a new component needs to be created. |
mmills | 0:04ac35f1846e | 46 | |
mmills | 0:04ac35f1846e | 47 | //GroveStreams Stream IDs. Stream IDs tell GroveStreams which component streams the values will be assigned to. |
mmills | 0:04ac35f1846e | 48 | //Don't change these unless you edit your GroveStreams component definition and change the stream IDs to match these. |
mmills | 0:04ac35f1846e | 49 | const char gsStreamId1[] = "voltage"; |
mmills | 0:04ac35f1846e | 50 | const char gsStreamId2[] = "temperature"; |
mmills | 0:04ac35f1846e | 51 | |
mmills | 0:04ac35f1846e | 52 | // Other Settings |
mmills | 0:04ac35f1846e | 53 | int updateFrequency = 20; // Update frequency in seconds. Change this to change your sample frequency. |
mmills | 0:04ac35f1846e | 54 | |
mmills | 0:04ac35f1846e | 55 | AnalogIn adc_temp(ADC_TEMP); |
mmills | 0:04ac35f1846e | 56 | AnalogIn adc_vref(ADC_VREF); |
mmills | 0:04ac35f1846e | 57 | DigitalOut myled(LED1); |
mmills | 0:04ac35f1846e | 58 | |
mmills | 0:04ac35f1846e | 59 | int main() |
mmills | 0:04ac35f1846e | 60 | { |
mmills | 0:04ac35f1846e | 61 | //Create Lcd class for verbose tracing |
mmills | 0:04ac35f1846e | 62 | LcdDiscoF746NgTracer lcd; |
mmills | 0:04ac35f1846e | 63 | |
mmills | 0:04ac35f1846e | 64 | //lastSuccessfulUploadTime is used for upload frequency. |
mmills | 0:04ac35f1846e | 65 | time_t lastSuccessfulUploadTime = 0; |
mmills | 0:04ac35f1846e | 66 | |
mmills | 0:04ac35f1846e | 67 | lcd.printf("Starting..."); |
mmills | 0:04ac35f1846e | 68 | |
mmills | 0:04ac35f1846e | 69 | GroveStreams groveStreams(gsApiKey, &lcd); |
mmills | 0:04ac35f1846e | 70 | |
mmills | 0:04ac35f1846e | 71 | const char* myMac = groveStreams.getMACAddress(); |
mmills | 0:04ac35f1846e | 72 | |
mmills | 0:04ac35f1846e | 73 | while (true) { |
mmills | 0:04ac35f1846e | 74 | // Update sensor data to GroveStreams |
mmills | 0:04ac35f1846e | 75 | time_t seconds = time(NULL); |
mmills | 0:04ac35f1846e | 76 | |
mmills | 0:04ac35f1846e | 77 | if(seconds - lastSuccessfulUploadTime > updateFrequency) { |
mmills | 0:04ac35f1846e | 78 | lcd.clear(); |
mmills | 0:04ac35f1846e | 79 | |
mmills | 0:04ac35f1846e | 80 | lcd.printf("Getting Samples..."); |
mmills | 0:04ac35f1846e | 81 | |
mmills | 0:04ac35f1846e | 82 | //Assemble the samples into URL parameters which are seperated with the "&" character |
mmills | 0:04ac35f1846e | 83 | // Example: &s1=6.2&s2=78.231 |
mmills | 0:04ac35f1846e | 84 | int temperature = adc_temp.read() * 100.0f; |
mmills | 0:04ac35f1846e | 85 | int voltage = adc_vref.read() * 100.0f; |
mmills | 0:04ac35f1846e | 86 | char samples[64] = {0}; |
mmills | 0:04ac35f1846e | 87 | sprintf(samples, "&%s=%d&%s=%d", gsStreamId1, voltage, gsStreamId2, temperature); |
mmills | 0:04ac35f1846e | 88 | |
mmills | 0:04ac35f1846e | 89 | //Append on command requests (request stream values) |
mmills | 0:04ac35f1846e | 90 | //This will indicate to GroveStreams to return the last value |
mmills | 0:04ac35f1846e | 91 | // of each request stream during the sample upload |
mmills | 0:04ac35f1846e | 92 | strcat(samples, "&rsid=freq&rsid=led"); |
mmills | 0:04ac35f1846e | 93 | |
mmills | 0:04ac35f1846e | 94 | char resultBuffer[700]= {0}; |
mmills | 0:04ac35f1846e | 95 | |
mmills | 0:04ac35f1846e | 96 | //Sending Samples (and returning current command stream values) |
mmills | 0:04ac35f1846e | 97 | time_t connectAttemptTime = time(NULL); |
mmills | 0:04ac35f1846e | 98 | int sendResult = groveStreams.send(myMac, samples, gsCompName, gsCompTmplId, resultBuffer, sizeof resultBuffer); |
mmills | 0:04ac35f1846e | 99 | |
mmills | 0:04ac35f1846e | 100 | if (sendResult == 0) { |
mmills | 0:04ac35f1846e | 101 | lcd.printf("Send Successful"); |
mmills | 0:04ac35f1846e | 102 | lastSuccessfulUploadTime = connectAttemptTime; |
mmills | 0:04ac35f1846e | 103 | |
mmills | 0:04ac35f1846e | 104 | //Handle command streams |
mmills | 0:04ac35f1846e | 105 | if (strlen(resultBuffer) > 0 && resultBuffer[0] == '{') { |
mmills | 0:04ac35f1846e | 106 | MbedJSONValue mbedJson; |
mmills | 0:04ac35f1846e | 107 | parse(mbedJson, resultBuffer); |
mmills | 0:04ac35f1846e | 108 | |
mmills | 0:04ac35f1846e | 109 | if (mbedJson.hasMember("freq") && mbedJson["freq"].get<int>() >= 10) { |
mmills | 0:04ac35f1846e | 110 | //Change the update frequency |
mmills | 0:04ac35f1846e | 111 | updateFrequency = mbedJson["freq"].get<int>(); |
mmills | 0:04ac35f1846e | 112 | lcd.printf("updateFrequency: %d", updateFrequency); |
mmills | 0:04ac35f1846e | 113 | } |
mmills | 0:04ac35f1846e | 114 | if (mbedJson.hasMember("led")) { |
mmills | 0:04ac35f1846e | 115 | //Change LED |
mmills | 0:04ac35f1846e | 116 | myled = mbedJson["led"].get<bool>() ? 1 : 0; |
mmills | 0:04ac35f1846e | 117 | lcd.printf("LED: %s", mbedJson["led"].get<bool>() ? "On" : "Off"); |
mmills | 0:04ac35f1846e | 118 | } |
mmills | 0:04ac35f1846e | 119 | } |
mmills | 0:04ac35f1846e | 120 | } |
mmills | 0:04ac35f1846e | 121 | } |
mmills | 0:04ac35f1846e | 122 | } |
mmills | 0:04ac35f1846e | 123 | } |
mmills | 0:04ac35f1846e | 124 |