diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e43b0f9 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.DS_Store diff --git a/README.md b/README.md index 94d83e6..3d5ea9b 100644 --- a/README.md +++ b/README.md @@ -46,34 +46,35 @@ The library includes several Typical Write Example In this case, write to a field with an ESP8266 with an incrementing number. ``` -#include "ThingSpeak.h" #include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros -//---------------- Fill in your credentails --------------------- -char ssid[] = "MySSID"; // your network SSID (name) -char pass[] = "MyPassword"; // your network password -unsigned long myChannelNumber = 0; // Replace the 0 with your channel number -const char * myWriteAPIKey = ""; // Paste your ThingSpeak Write API Key between the quotes -//------------------------------------------------------------------ - +char ssid[] = SECRET_SSID; // your network SSID (name) +char pass[] = SECRET_PASS; // your network password +int keyIndex = 0; // your network key Index number (needed only for WEP) WiFiClient client; +unsigned long myChannelNumber = SECRET_CH_ID; +const char * myWriteAPIKey = SECRET_WRITE_APIKEY; + int number = 0; void setup() { - //Initialize serial and wait for port to open: - Serial.begin(9600); + Serial.begin(115200); // Initialize serial while (!Serial) { ; // wait for serial port to connect. Needed for native USB port only } - - WiFi.mode(WIFI_STA); - ThingSpeak.begin(client); + + WiFi.mode(WIFI_STA); + ThingSpeak.begin(client); // Initialize ThingSpeak } void loop() { @@ -83,7 +84,7 @@ void loop() { Serial.print("Attempting to connect to SSID: "); Serial.println(SECRET_SSID); while(WiFi.status() != WL_CONNECTED){ - WiFi.begin(ssid, pass); + WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network Serial.print("."); delay(5000); } @@ -93,8 +94,6 @@ void loop() { // Write to ThingSpeak. There are up to 8 fields in a channel, allowing you to store up to 8 different // pieces of information in a channel. Here, we write to field 1. int x = ThingSpeak.writeField(myChannelNumber, 1, number, myWriteAPIKey); - - // Check the return code if(x == 200){ Serial.println("Channel update successful."); } @@ -102,12 +101,13 @@ void loop() { Serial.println("Problem updating channel. HTTP error code " + String(x)); } + // change the value number++; if(number > 99){ number = 0; } - delay(20000); // Wait 20 seconds before sending a new value + delay(20000); // Wait 20 seconds to update the channel again } ``` @@ -115,32 +115,32 @@ void loop() { In this case, read from a public channel and a private channel with an ESP8266. The public channel is the temperature(F) at MathWorks headquarters. The private channel is a counter that increments. ``` -#include "ThingSpeak.h" #include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros -//---------------- Fill in your credentails --------------------- -char ssid[] = "MySSID"; // your network SSID (name) -char pass[] = "MyPassword"; // your network password -//------------------------------------------------------------------ - +char ssid[] = SECRET_SSID; // your network SSID (name) +char pass[] = SECRET_PASS; // your network password +int keyIndex = 0; // your network key Index number (needed only for WEP) WiFiClient client; -unsigned long weatherStationChannelNumber = 12397; +// Weather station channel details +unsigned long weatherStationChannelNumber = SECRET_CH_ID_WEATHER_STATION; unsigned int temperatureFieldNumber = 4; -unsigned long counterChannelNumber = 298725; -const char * myCounterReadAPIKey = "SODG0O2UZVGKWAWG"; +// Counting channel details +unsigned long counterChannelNumber = SECRET_CH_ID_COUNTER; +const char * myCounterReadAPIKey = SECRET_READ_APIKEY_COUNTER; unsigned int counterFieldNumber = 1; void setup() { - //Initialize serial and wait for port to open: - Serial.begin(9600); + Serial.begin(115200); // Initialize serial while (!Serial) { ; // wait for serial port to connect. Needed for native USB port only } - - WiFi.mode(WIFI_STA); - ThingSpeak.begin(client); + + WiFi.mode(WIFI_STA); + ThingSpeak.begin(client); // Initialize ThingSpeak } void loop() { @@ -152,7 +152,7 @@ void loop() { Serial.print("Attempting to connect to SSID: "); Serial.println(SECRET_SSID); while(WiFi.status() != WL_CONNECTED){ - WiFi.begin(ssid, pass); + WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network Serial.print("."); delay(5000); } @@ -193,26 +193,27 @@ void loop() { # Documentation ## begin -Initializes the ThingSpeak library and network settings. +Initializes the ThingSpeak library and network settings, whether performing a secure connection or a normal connection to ThingSpeak. ``` bool begin (client) // defaults to ThingSpeak.com ``` -``` -bool begin (client, port) -``` + | Parameter | Type | Description | |----------------|:-------------|:-------------------------------------------------------| | client | Client & | TCPClient created earlier in the sketch | -| port | unsigned int | Port number to use with a custom install of ThingSpeak | ### Returns Always returns true. This does not validate the information passed in, or generate any calls to ThingSpeak. +### Remarks +use ```#define TS_ENABLE_SSL``` before ```#include ``` so as to perform a secure connection by passing a client that is capable of doing SSL. See the note regarding secure connection below. + ## writeField Write a value to a single field in a ThingSpeak channel. ``` int writeField(channelNumber, field, value, writeAPIKey) ``` + | Parameter | Type | Description | |---------------|:--------------|:------------------------------------------------------------------------------------------------| | channelNumber | unsigned long | Channel number | @@ -235,6 +236,7 @@ Write a multi-field update. Call setField() for each of the fields you want to w ``` int writeFields (channelNumber, writeAPIKey) ``` + | Parameter | Type | Description | |---------------|:--------------|:------------------------------------------------------------------------------------------------| | channelNumber | unsigned long | Channel number | @@ -453,7 +455,7 @@ String readStatus (channelNumber, readAPIKey) String readStatus (channelNumber) ``` -| Parameter | Type | Description | +| Parameter | Type | Description | |---------------|:--------------|:-----------------------------------------------------------------------------------------------| | channelNumber | unsigned long | Channel number | | readAPIKey | const char * | Read API key associated with the channel. If you share code with others, do not share this key | @@ -470,6 +472,8 @@ String readCreatedAt (channelNumber, readAPIKey) String readCreatedAt (channelNumber) ``` +| Parameter | Type | Description | +|---------------|:--------------|:-----------------------------------------------------------------------------------------------| | channelNumber | unsigned long | Channel number | | readAPIKey | const char * | Read API key associated with the channel. If you share code with others, do not share this key | @@ -485,7 +489,7 @@ String readRaw (channelNumber, URLSuffix, readAPIKey) String readRaw (channelNumber, URLSuffix) ``` -| Parameter | Type | Description | +| Parameter | Type | Description | |---------------|:--------------|:-------------------------------------------------------------------------------------------------------------------| | channelNumber | unsigned long | Channel number | | URLSuffix | String | Raw URL to write to ThingSpeak as a String. See the documentation at https://thingspeak.com/docs/channels#get_feed | @@ -494,6 +498,86 @@ String readRaw (channelNumber, URLSuffix) ### Returns Returns the raw response from a HTTP request as a String. +## readMultipleFields +Read all the latest fields, status, location, and created-at timestamp; and store these values locally. Use ```getField``` functions mentioned below to fetch the stored values. Include the readAPIKey to read a private channel. +``` +int readMultipleFields (channelNumber, readAPIKey) +``` +``` +int readMultipleFields (channelNumber) +``` + +| Parameter | Type | Description | +|---------------|:--------------|:-----------------------------------------------------------------------------------------------| +| channelNumber | unsigned long | Channel number | +| readAPIKey | const char * | Read API key associated with the channel. If you share code with others, do not share this key | + +### Returns +HTTP status code of 200 if successful. See Return Codes below for other possible return values. + +### Remarks +This feature not available in Arduino Uno due to memory constraints. + +## getFieldAsString +Fetch the stored value from a field as String. Invoke this after invoking ```readMultipleFields```. +``` +String getFieldAsString (field) +``` +| Parameter | Type | Description | +|---------------|:--------------|:-----------------------------------------------------------------------------------------------| +| field | unsigned int | Field number (1-8) within the channel to read from. | + +### Returns +Value read (UTF8 string), empty string if there is an error, or old value read (UTF8 string) if invoked before readMultipleFields(). Use getLastReadStatus() to get more specific information. + +### Remarks +This feature not available in Arduino Uno due to memory constraints. + +## getFieldAsFloat +Fetch the stored value from a field as Float. Invoke this after invoking ```readMultipleFields```. +``` +float getFieldAsFloat (field) +``` +| Parameter | Type | Description | +|---------------|:--------------|:-----------------------------------------------------------------------------------------------| +| field | unsigned int | Field number (1-8) within the channel to read from. | + +### Returns +Value read, 0 if the field is text or there is an error, or old value read if invoked before readMultipleFields(). Use getLastReadStatus() to get more specific information. Note that NAN, INFINITY, and -INFINITY are valid results. + +### Remarks +This feature not available in Arduino Uno due to memory constraints. + +## getFieldAsLong +Fetch the stored value from a field as Long. Invoke this after invoking ```readMultipleFields```. +``` +long getFieldAsLong (field) +``` +| Parameter | Type | Description | +|---------------|:--------------|:-----------------------------------------------------------------------------------------------| +| field | unsigned int | Field number (1-8) within the channel to read from. | + +### Returns +Value read, 0 if the field is text or there is an error, or old value read if invoked before readMultipleFields(). Use getLastReadStatus() to get more specific information. + +### Remarks +This feature not available in Arduino Uno due to memory constraints. + +## getFieldAsInt +Fetch the stored value from a field as Int. Invoke this after invoking ```readMultipleFields```. +``` +int getFieldAsInt (field) +``` +| Parameter | Type | Description | +|---------------|:--------------|:-----------------------------------------------------------------------------------------------| +| field | unsigned int | Field number (1-8) within the channel to read from. | + +### Returns +Value read, 0 if the field is text or there is an error, or old value read if invoked before readMultipleFields(). Use getLastReadStatus() to get more specific information. + +### Remarks +This feature not available in Arduino Uno due to memory constraints. + ## getLastReadStatus Get the status of the previous read. ``` @@ -504,7 +588,7 @@ int getLastReadStatus () See Return Codes below for other possible return values. ## Return Codes -| Value | Meaning | +| Value | Meaning | |-------|:----------------------------------------------------------------------------------------| | 200 | OK / Success | | 404 | Incorrect API key (or invalid ThingSpeak server address) | @@ -518,6 +602,31 @@ See Return Codes below for other possible return values. | -401 | Point was not inserted (most probable cause is the rate limit of once every 15 seconds) | | 0 | Other error | +## Secure Connection +Securely connect to ThingSpeak API to use the above features and functionalities. + +### HTTPS +HTTPS ensures confidentiality as well as authenticity. +Confidentiality: SSL Encryption using public-key cryptography. +Authenticity: creates "trust", the device knows whether it's connected to the actual api.thingkspeak.com and not a spoof of it. + +### User Sketch Requirements +Always use ```#define TS_ENABLE_SSL``` before ```#include ``` so as to perform a secure connection. If not, then the default connection would be insecured HTTP. + +#### Confidentiality without Authenticity +Case 1: TS_ENABLE_SSL macro defined + Client capable of doing SSL = Secure HTTPS Connection
+Case 2: TS_ENABLE_SSL macro defined + Client not capable of SSL = Defualt HTTP connection with a warning message sent to the user
+Case 3: TS_ENABLE_SSL macro undefined + Client capable of doing SSL = Error connecting to ThingSpeak status code returned to user
+Case 4: TS_ENABLE_SSL macro undefined + Client not capable of SSL = HTTP connection + +#### Confidentiality + Authenticity +Different client libraries have different methods of performing authenticity.
+Some ways: Root Certificate Check, Certificate Fingerprint Check.
+Perform the fingerprint and/or certificate check prior to invoking the ```begin()``` function.
+The certificate has an expiration date associated with it, and hence it's the user's responsibility to fetch the updated certificate for the Confidentiality + Authenticity HTTPS connection to be established.
+See the ReadMultipleFieldsSecure example on Fingerprint check HTTPS connection using ESP8266. +See the ReadMultipleFieldsSecure example on Root Certificate check HTTPS connection using ESP32. + ## Special Characters Some characters require '%XX' style URL encoding before sending to ThingSpeak. The writeField() and writeFields() methods will perform the encoding automatically. The writeRaw() method will not. diff --git a/examples/ArduinoEthernet/ReadField/ReadField.ino b/examples/ArduinoEthernet/ReadField/ReadField.ino index 22d2d35..80ae112 100644 --- a/examples/ArduinoEthernet/ReadField/ReadField.ino +++ b/examples/ArduinoEthernet/ReadField/ReadField.ino @@ -1,109 +1,112 @@ -/* - ReadField - - Description: Demonstates reading from a public channel which doesn't not require an API key and reading from a private channel which does requires a read API key. - The value read from the public channel is the current outside temperature at MathWorks headquaters in Natick, MA. The value from the - private channel is an example counter that increments every 10 seconds. - - Hardware: Arduino Ethernet - - !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! - - Note: - - Requires the Ethernet library - - ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and - analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. - - Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. - See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. - - For licensing information, see the accompanying license file. - - Copyright 2018, The MathWorks, Inc. -*/ - -#include "ThingSpeak.h" -#include -#include "secrets.h" - -byte mac[] = SECRET_MAC; - -// Set the static IP address to use if the DHCP fails to assign -IPAddress ip(192, 168, 0, 177); -IPAddress myDns(192, 168, 0, 1); - -EthernetClient client; - -// Weather station channel details -unsigned long weatherStationChannelNumber = SECRET_CH_ID_WEATHER_STATION; -unsigned int temperatureFieldNumber = 4; - -// Counting channel details -unsigned long counterChannelNumber = SECRET_CH_ID_COUNTER; -const char * myCounterReadAPIKey = SECRET_READ_APIKEY_COUNTER; -unsigned int counterFieldNumber = 1; - -void setup() { - Ethernet.init(10); // Most Arduino Ethernet hardware - Serial.begin(115200); //Initialize serial - - // start the Ethernet connection: - Serial.println("Initialize Ethernet with DHCP:"); - if (Ethernet.begin(mac) == 0) { - Serial.println("Failed to configure Ethernet using DHCP"); - // Check for Ethernet hardware present - if (Ethernet.hardwareStatus() == EthernetNoHardware) { - Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :("); - while (true) { - delay(1); // do nothing, no point running without Ethernet hardware - } - } - if (Ethernet.linkStatus() == LinkOFF) { - Serial.println("Ethernet cable is not connected."); - } - // try to congifure using IP address instead of DHCP: - Ethernet.begin(mac, ip, myDns); - } else { - Serial.print(" DHCP assigned IP "); - Serial.println(Ethernet.localIP()); - } - // give the Ethernet shield a second to initialize: - delay(1000); - - ThingSpeak.begin(client); // Initialize ThingSpeak -} - -void loop() { - - int statusCode = 0; - - // Read in field 4 of the public channel recording the temperature - float temperatureInF = ThingSpeak.readFloatField(weatherStationChannelNumber, temperatureFieldNumber); - - // Check the status of the read operation to see if it was successful - statusCode = ThingSpeak.getLastReadStatus(); - if(statusCode == 200){ - Serial.println("Temperature at MathWorks HQ: " + String(temperatureInF) + " deg F"); - } - else{ - Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); - } - - delay(15000); // No need to read the temperature too often. - - // Read in field 1 of the private channel which is a counter - long count = ThingSpeak.readLongField(counterChannelNumber, counterFieldNumber, myCounterReadAPIKey); - - // Check the status of the read operation to see if it was successful - statusCode = ThingSpeak.getLastReadStatus(); - if(statusCode == 200){ - Serial.println("Counter: " + String(count)); - } - else{ - Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); - } - - delay(15000); // No need to read the counter too often. - -} +/* + ReadField + + Description: Demonstates reading from a public channel which doesn't not require an API key and reading from a private channel which does requires a read API key. + The value read from the public channel is the current outside temperature at MathWorks headquaters in Natick, MA. The value from the + private channel is an example counter that increments every 10 seconds. + + Hardware: Arduino Ethernet + + !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! + + Note: + - Requires the Ethernet library + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +#include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros + +byte mac[] = SECRET_MAC; + +// Set the static IP address to use if the DHCP fails to assign +IPAddress ip(192, 168, 0, 177); +IPAddress myDns(192, 168, 0, 1); + +EthernetClient client; + +// Weather station channel details +unsigned long weatherStationChannelNumber = SECRET_CH_ID_WEATHER_STATION; +unsigned int temperatureFieldNumber = 4; + +// Counting channel details +unsigned long counterChannelNumber = SECRET_CH_ID_COUNTER; +const char * myCounterReadAPIKey = SECRET_READ_APIKEY_COUNTER; +unsigned int counterFieldNumber = 1; + +void setup() { + Ethernet.init(10); // Most Arduino Ethernet hardware + Serial.begin(115200); //Initialize serial + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + // start the Ethernet connection: + Serial.println("Initialize Ethernet with DHCP:"); + if (Ethernet.begin(mac) == 0) { + Serial.println("Failed to configure Ethernet using DHCP"); + // Check for Ethernet hardware present + if (Ethernet.hardwareStatus() == EthernetNoHardware) { + Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :("); + while (true) { + delay(1); // do nothing, no point running without Ethernet hardware + } + } + if (Ethernet.linkStatus() == LinkOFF) { + Serial.println("Ethernet cable is not connected."); + } + // try to congifure using IP address instead of DHCP: + Ethernet.begin(mac, ip, myDns); + } else { + Serial.print(" DHCP assigned IP "); + Serial.println(Ethernet.localIP()); + } + // give the Ethernet shield a second to initialize: + delay(1000); + + ThingSpeak.begin(client); // Initialize ThingSpeak +} + +void loop() { + + int statusCode = 0; + + // Read in field 4 of the public channel recording the temperature + float temperatureInF = ThingSpeak.readFloatField(weatherStationChannelNumber, temperatureFieldNumber); + + // Check the status of the read operation to see if it was successful + statusCode = ThingSpeak.getLastReadStatus(); + if(statusCode == 200){ + Serial.println("Temperature at MathWorks HQ: " + String(temperatureInF) + " deg F"); + } + else{ + Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); + } + + delay(15000); // No need to read the temperature too often. + + // Read in field 1 of the private channel which is a counter + long count = ThingSpeak.readLongField(counterChannelNumber, counterFieldNumber, myCounterReadAPIKey); + + // Check the status of the read operation to see if it was successful + statusCode = ThingSpeak.getLastReadStatus(); + if(statusCode == 200){ + Serial.println("Counter: " + String(count)); + } + else{ + Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); + } + + delay(15000); // No need to read the counter too often. + +} diff --git a/examples/ArduinoEthernet/WriteMultipleFields/WriteMultipleFields.ino b/examples/ArduinoEthernet/WriteMultipleFields/WriteMultipleFields.ino index f886d2d..35f5e19 100644 --- a/examples/ArduinoEthernet/WriteMultipleFields/WriteMultipleFields.ino +++ b/examples/ArduinoEthernet/WriteMultipleFields/WriteMultipleFields.ino @@ -1,104 +1,106 @@ -/* - WriteMultipleFields - - Description: Writes values to fields 1,2,3 and 4 in a single ThingSpeak update every 20 seconds. - - Hardware: Arduino Ethernet - - !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! - - Note: - - Requires the Ethernet library - - ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and - analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. - - Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. - See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. - - For licensing information, see the accompanying license file. - - Copyright 2018, The MathWorks, Inc. -*/ - - -#include "ThingSpeak.h" -#include -#include "secrets.h" - -byte mac[] = SECRET_MAC; - -// Set the static IP address to use if the DHCP fails to assign -IPAddress ip(192, 168, 0, 177); -IPAddress myDns(192, 168, 0, 1); - -EthernetClient client; - -unsigned long myChannelNumber = SECRET_CH_ID; -const char * myWriteAPIKey = SECRET_WRITE_APIKEY; - -// Initialize our values -int number1 = 0; -int number2 = random(0,100); -int number3 = random(0,100); -int number4 = random(0,100); - -void setup() { - Ethernet.init(10); // Most Arduino Ethernet hardware - Serial.begin(115200); //Initialize serial - - // start the Ethernet connection: - Serial.println("Initialize Ethernet with DHCP:"); - if (Ethernet.begin(mac) == 0) { - Serial.println("Failed to configure Ethernet using DHCP"); - // Check for Ethernet hardware present - if (Ethernet.hardwareStatus() == EthernetNoHardware) { - Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :("); - while (true) { - delay(1); // do nothing, no point running without Ethernet hardware - } - } - if (Ethernet.linkStatus() == LinkOFF) { - Serial.println("Ethernet cable is not connected."); - } - // try to congifure using IP address instead of DHCP: - Ethernet.begin(mac, ip, myDns); - } else { - Serial.print(" DHCP assigned IP "); - Serial.println(Ethernet.localIP()); - } - // give the Ethernet shield a second to initialize: - delay(1000); - - ThingSpeak.begin(client); // Initialize ThingSpeak -} - -void loop() { - - // set the fields with the values - ThingSpeak.setField(1, number1); - ThingSpeak.setField(2, number2); - ThingSpeak.setField(3, number3); - ThingSpeak.setField(4, number4); - - - // write to the ThingSpeak channel - int x = ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey); - if(x == 200){ - Serial.println("Channel update successful."); - } - else{ - Serial.println("Problem updating channel. HTTP error code " + String(x)); - } - - // change the values - number1++; - if(number1 > 99){ - number1 = 0; - } - number2 = random(0,100); - number3 = random(0,100); - number4 = random(0,100); - - delay(20000); // Wait 20 seconds to update the channel again -} +/* + WriteMultipleFields + + Description: Writes values to fields 1,2,3 and 4 in a single ThingSpeak update every 20 seconds. + + Hardware: Arduino Ethernet + + !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! + + Note: + - Requires the Ethernet library + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +#include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros + +byte mac[] = SECRET_MAC; + +// Set the static IP address to use if the DHCP fails to assign +IPAddress ip(192, 168, 0, 177); +IPAddress myDns(192, 168, 0, 1); + +EthernetClient client; + +unsigned long myChannelNumber = SECRET_CH_ID; +const char * myWriteAPIKey = SECRET_WRITE_APIKEY; + +// Initialize our values +int number1 = 0; +int number2 = random(0,100); +int number3 = random(0,100); +int number4 = random(0,100); + +void setup() { + Ethernet.init(10); // Most Arduino Ethernet hardware + Serial.begin(115200); //Initialize serial + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + // start the Ethernet connection: + Serial.println("Initialize Ethernet with DHCP:"); + if (Ethernet.begin(mac) == 0) { + Serial.println("Failed to configure Ethernet using DHCP"); + // Check for Ethernet hardware present + if (Ethernet.hardwareStatus() == EthernetNoHardware) { + Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :("); + while (true) { + delay(1); // do nothing, no point running without Ethernet hardware + } + } + if (Ethernet.linkStatus() == LinkOFF) { + Serial.println("Ethernet cable is not connected."); + } + // try to congifure using IP address instead of DHCP: + Ethernet.begin(mac, ip, myDns); + } else { + Serial.print(" DHCP assigned IP "); + Serial.println(Ethernet.localIP()); + } + // give the Ethernet shield a second to initialize: + delay(1000); + + ThingSpeak.begin(client); // Initialize ThingSpeak +} + +void loop() { + + // set the fields with the values + ThingSpeak.setField(1, number1); + ThingSpeak.setField(2, number2); + ThingSpeak.setField(3, number3); + ThingSpeak.setField(4, number4); + + + // write to the ThingSpeak channel + int x = ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey); + if(x == 200){ + Serial.println("Channel update successful."); + } + else{ + Serial.println("Problem updating channel. HTTP error code " + String(x)); + } + + // change the values + number1++; + if(number1 > 99){ + number1 = 0; + } + number2 = random(0,100); + number3 = random(0,100); + number4 = random(0,100); + + delay(20000); // Wait 20 seconds to update the channel again +} diff --git a/examples/ArduinoEthernet/WriteSingleField/WriteSingleField.ino b/examples/ArduinoEthernet/WriteSingleField/WriteSingleField.ino index 7dffcf4..9574437 100644 --- a/examples/ArduinoEthernet/WriteSingleField/WriteSingleField.ino +++ b/examples/ArduinoEthernet/WriteSingleField/WriteSingleField.ino @@ -1,91 +1,93 @@ -/* - WriteSingleField - - Description: Writes a value to a channel on ThingSpeak every 20 seconds. - - Hardware: Arduino Ethernet - - !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! - - Note: - - Requires the Ethernet library - - ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and - analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. - - Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. - See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. - - For licensing information, see the accompanying license file. - - Copyright 2018, The MathWorks, Inc. -*/ - - -#include "ThingSpeak.h" -#include -#include "secrets.h" - -byte mac[] = SECRET_MAC; - -// Set the static IP address to use if the DHCP fails to assign -IPAddress ip(192, 168, 0, 177); -IPAddress myDns(192, 168, 0, 1); - -EthernetClient client; - -unsigned long myChannelNumber = SECRET_CH_ID; -const char * myWriteAPIKey = SECRET_WRITE_APIKEY; - -int number = 0; - -void setup() { - Ethernet.init(10); // Most Arduino Ethernet hardware - Serial.begin(115200); //Initialize serial - - // start the Ethernet connection: - Serial.println("Initialize Ethernet with DHCP:"); - if (Ethernet.begin(mac) == 0) { - Serial.println("Failed to configure Ethernet using DHCP"); - // Check for Ethernet hardware present - if (Ethernet.hardwareStatus() == EthernetNoHardware) { - Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :("); - while (true) { - delay(1); // do nothing, no point running without Ethernet hardware - } - } - if (Ethernet.linkStatus() == LinkOFF) { - Serial.println("Ethernet cable is not connected."); - } - // try to congifure using IP address instead of DHCP: - Ethernet.begin(mac, ip, myDns); - } else { - Serial.print(" DHCP assigned IP "); - Serial.println(Ethernet.localIP()); - } - // give the Ethernet shield a second to initialize: - delay(1000); - - ThingSpeak.begin(client); // Initialize ThingSpeak -} - -void loop() { - - // Write to ThingSpeak. There are up to 8 fields in a channel, allowing you to store up to 8 different - // pieces of information in a channel. Here, we write to field 1. - int x = ThingSpeak.writeField(myChannelNumber, 1, number, myWriteAPIKey); - if(x == 200){ - Serial.println("Channel update successful."); - } - else{ - Serial.println("Problem updating channel. HTTP error code " + String(x)); - } - - // change the value - number++; - if(number > 99){ - number = 0; - } - - delay(20000); // Wait 20 seconds to update the channel again -} +/* + WriteSingleField + + Description: Writes a value to a channel on ThingSpeak every 20 seconds. + + Hardware: Arduino Ethernet + + !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! + + Note: + - Requires the Ethernet library + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +#include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros + +byte mac[] = SECRET_MAC; + +// Set the static IP address to use if the DHCP fails to assign +IPAddress ip(192, 168, 0, 177); +IPAddress myDns(192, 168, 0, 1); + +EthernetClient client; + +unsigned long myChannelNumber = SECRET_CH_ID; +const char * myWriteAPIKey = SECRET_WRITE_APIKEY; + +int number = 0; + +void setup() { + Ethernet.init(10); // Most Arduino Ethernet hardware + Serial.begin(115200); //Initialize serial + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + // start the Ethernet connection: + Serial.println("Initialize Ethernet with DHCP:"); + if (Ethernet.begin(mac) == 0) { + Serial.println("Failed to configure Ethernet using DHCP"); + // Check for Ethernet hardware present + if (Ethernet.hardwareStatus() == EthernetNoHardware) { + Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :("); + while (true) { + delay(1); // do nothing, no point running without Ethernet hardware + } + } + if (Ethernet.linkStatus() == LinkOFF) { + Serial.println("Ethernet cable is not connected."); + } + // try to congifure using IP address instead of DHCP: + Ethernet.begin(mac, ip, myDns); + } else { + Serial.print(" DHCP assigned IP "); + Serial.println(Ethernet.localIP()); + } + // give the Ethernet shield a second to initialize: + delay(1000); + + ThingSpeak.begin(client); // Initialize ThingSpeak +} + +void loop() { + + // Write to ThingSpeak. There are up to 8 fields in a channel, allowing you to store up to 8 different + // pieces of information in a channel. Here, we write to field 1. + int x = ThingSpeak.writeField(myChannelNumber, 1, number, myWriteAPIKey); + if(x == 200){ + Serial.println("Channel update successful."); + } + else{ + Serial.println("Problem updating channel. HTTP error code " + String(x)); + } + + // change the value + number++; + if(number > 99){ + number = 0; + } + + delay(20000); // Wait 20 seconds to update the channel again +} diff --git a/examples/ArduinoMKR1000/ReadField/ReadField.ino b/examples/ArduinoMKR1000/ReadField/ReadField.ino index c0e35e2..a232187 100644 --- a/examples/ArduinoMKR1000/ReadField/ReadField.ino +++ b/examples/ArduinoMKR1000/ReadField/ReadField.ino @@ -1,94 +1,97 @@ -/* - ReadField - - Description: Demonstates reading from a public channel which requires no API key and reading from a private channel which requires a read API key. - The value read from the public channel is the current outside temperature at MathWorks headquaters in Natick, MA. The value from the - private channel is an example counter that increments every 10 seconds. - - Hardware: Arduino MKR1000 - - !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! - - Note: - - Requires WiFi101 library version 0.15.3 or newer. - - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. - - ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and - analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. - - Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. - See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. - - For licensing information, see the accompanying license file. - - Copyright 2018, The MathWorks, Inc. -*/ - -#include "ThingSpeak.h" -#include -#include "secrets.h" - -char ssid[] = SECRET_SSID; // your network SSID (name) -char pass[] = SECRET_PASS; // your network password -int keyIndex = 0; // your network key Index number (needed only for WEP) -WiFiClient client; - -// Weather station channel details -unsigned long weatherStationChannelNumber = SECRET_CH_ID_WEATHER_STATION; -unsigned int temperatureFieldNumber = 4; - -// Counting channel details -unsigned long counterChannelNumber = SECRET_CH_ID_COUNTER; -const char * myCounterReadAPIKey = SECRET_READ_APIKEY_COUNTER; -unsigned int counterFieldNumber = 1; - -void setup() { - Serial.begin(115200); // Initialize serial - ThingSpeak.begin(client); // Initialize ThingSpeak -} - -void loop() { - - int statusCode = 0; - - // Connect or reconnect to WiFi - if(WiFi.status() != WL_CONNECTED){ - Serial.print("Attempting to connect to SSID: "); - Serial.println(SECRET_SSID); - while(WiFi.status() != WL_CONNECTED){ - WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network - Serial.print("."); - delay(5000); - } - Serial.println("\nConnected"); - } - - // Read in field 4 of the public channel recording the temperature - float temperatureInF = ThingSpeak.readFloatField(weatherStationChannelNumber, temperatureFieldNumber); - - // Check the status of the read operation to see if it was successful - statusCode = ThingSpeak.getLastReadStatus(); - if(statusCode == 200){ - Serial.println("Temperature at MathWorks HQ: " + String(temperatureInF) + " deg F"); - } - else{ - Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); - } - - delay(15000); // No need to read the temperature too often. - - // Read in field 1 of the private channel which is a counter - long count = ThingSpeak.readLongField(counterChannelNumber, counterFieldNumber, myCounterReadAPIKey); - - // Check the status of the read operation to see if it was successful - statusCode = ThingSpeak.getLastReadStatus(); - if(statusCode == 200){ - Serial.println("Counter: " + String(count)); - } - else{ - Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); - } - - delay(15000); // No need to read the counter too often. - -} +/* + ReadField + + Description: Demonstates reading from a public channel which requires no API key and reading from a private channel which requires a read API key. + The value read from the public channel is the current outside temperature at MathWorks headquaters in Natick, MA. The value from the + private channel is an example counter that increments every 10 seconds. + + Hardware: Arduino MKR1000 + + !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! + + Note: + - Requires WiFi101 library version 0.15.3 or newer. + - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +#include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros + +char ssid[] = SECRET_SSID; // your network SSID (name) +char pass[] = SECRET_PASS; // your network password +int keyIndex = 0; // your network key Index number (needed only for WEP) +WiFiClient client; + +// Weather station channel details +unsigned long weatherStationChannelNumber = SECRET_CH_ID_WEATHER_STATION; +unsigned int temperatureFieldNumber = 4; + +// Counting channel details +unsigned long counterChannelNumber = SECRET_CH_ID_COUNTER; +const char * myCounterReadAPIKey = SECRET_READ_APIKEY_COUNTER; +unsigned int counterFieldNumber = 1; + +void setup() { + Serial.begin(115200); // Initialize serial + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + ThingSpeak.begin(client); // Initialize ThingSpeak +} + +void loop() { + + int statusCode = 0; + + // Connect or reconnect to WiFi + if(WiFi.status() != WL_CONNECTED){ + Serial.print("Attempting to connect to SSID: "); + Serial.println(SECRET_SSID); + while(WiFi.status() != WL_CONNECTED){ + WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network + Serial.print("."); + delay(5000); + } + Serial.println("\nConnected"); + } + + // Read in field 4 of the public channel recording the temperature + float temperatureInF = ThingSpeak.readFloatField(weatherStationChannelNumber, temperatureFieldNumber); + + // Check the status of the read operation to see if it was successful + statusCode = ThingSpeak.getLastReadStatus(); + if(statusCode == 200){ + Serial.println("Temperature at MathWorks HQ: " + String(temperatureInF) + " deg F"); + } + else{ + Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); + } + + delay(15000); // No need to read the temperature too often. + + // Read in field 1 of the private channel which is a counter + long count = ThingSpeak.readLongField(counterChannelNumber, counterFieldNumber, myCounterReadAPIKey); + + // Check the status of the read operation to see if it was successful + statusCode = ThingSpeak.getLastReadStatus(); + if(statusCode == 200){ + Serial.println("Counter: " + String(count)); + } + else{ + Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); + } + + delay(15000); // No need to read the counter too often. + +} diff --git a/examples/ArduinoMKR1000/ReadFieldSecure/ReadFieldSecure.ino b/examples/ArduinoMKR1000/ReadFieldSecure/ReadFieldSecure.ino new file mode 100644 index 0000000..21e4df3 --- /dev/null +++ b/examples/ArduinoMKR1000/ReadFieldSecure/ReadFieldSecure.ino @@ -0,0 +1,100 @@ +/* + ReadField + + Description: Demonstates reading from a public channel which requires no API key and reading from a private channel which requires a read API key. + The value read from the public channel is the current outside temperature at MathWorks headquaters in Natick, MA. The value from the + private channel is an example counter that increments every 10 seconds over secured HTTPS connection. + + Hardware: Arduino MKR1000 + + !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! + + Note: + - Requires WiFi101 library version 0.15.3 or newer. + - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +#define TS_ENABLE_SSL // For HTTPS SSL connection + +#include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros + +char ssid[] = SECRET_SSID; // your network SSID (name) +char pass[] = SECRET_PASS; // your network password +int keyIndex = 0; // your network key Index number (needed only for WEP) +WiFiSSLClient client; + +// Weather station channel details +unsigned long weatherStationChannelNumber = SECRET_CH_ID_WEATHER_STATION; +unsigned int temperatureFieldNumber = 4; + +// Counting channel details +unsigned long counterChannelNumber = SECRET_CH_ID_COUNTER; +const char * myCounterReadAPIKey = SECRET_READ_APIKEY_COUNTER; +unsigned int counterFieldNumber = 1; + +void setup() { + Serial.begin(115200); // Initialize serial + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + ThingSpeak.begin(client); // Initialize ThingSpeak +} + +void loop() { + + int statusCode = 0; + + // Connect or reconnect to WiFi + if(WiFi.status() != WL_CONNECTED){ + Serial.print("Attempting to connect to SSID: "); + Serial.println(SECRET_SSID); + while(WiFi.status() != WL_CONNECTED){ + WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network + Serial.print("."); + delay(5000); + } + Serial.println("\nConnected"); + } + + // Read in field 4 of the public channel recording the temperature + float temperatureInF = ThingSpeak.readFloatField(weatherStationChannelNumber, temperatureFieldNumber); + + // Check the status of the read operation to see if it was successful + statusCode = ThingSpeak.getLastReadStatus(); + if(statusCode == 200){ + Serial.println("Temperature at MathWorks HQ: " + String(temperatureInF) + " deg F"); + } + else{ + Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); + } + + delay(15000); // No need to read the temperature too often. + + // Read in field 1 of the private channel which is a counter + long count = ThingSpeak.readLongField(counterChannelNumber, counterFieldNumber, myCounterReadAPIKey); + + // Check the status of the read operation to see if it was successful + statusCode = ThingSpeak.getLastReadStatus(); + if(statusCode == 200){ + Serial.println("Counter: " + String(count)); + } + else{ + Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); + } + + delay(15000); // No need to read the counter too often. + +} diff --git a/examples/ArduinoMKR1000/ReadFieldSecure/secrets.h b/examples/ArduinoMKR1000/ReadFieldSecure/secrets.h new file mode 100644 index 0000000..f381ba2 --- /dev/null +++ b/examples/ArduinoMKR1000/ReadFieldSecure/secrets.h @@ -0,0 +1,10 @@ +// Use this file to store all of the private credentials +// and connection details + +#define SECRET_SSID "MySSID" // replace MySSID with your WiFi network name +#define SECRET_PASS "MyPassword" // replace MyPassword with your WiFi password + +#define SECRET_CH_ID_WEATHER_STATION 12397 //MathWorks weather station + +#define SECRET_CH_ID_COUNTER 298725 //Test channel for counting +#define SECRET_READ_APIKEY_COUNTER "SODG0O2UZVGKWAWG" //API Key for Test channel diff --git a/examples/ArduinoMKR1000/ReadMultipleFields/ReadMultipleFields.ino b/examples/ArduinoMKR1000/ReadMultipleFields/ReadMultipleFields.ino new file mode 100644 index 0000000..cb2c543 --- /dev/null +++ b/examples/ArduinoMKR1000/ReadMultipleFields/ReadMultipleFields.ino @@ -0,0 +1,109 @@ +/* + ReadMultipleFields + + Description: Demonstates reading from a public channel which requires no API key (reading from a private channel requires a read API key). + The values read from the public channel is the current wind direction, wind speed, humidity, outside temperature, rain, pressure, + power level, and light intensity at MathWorks headquaters in Natick, MA.The functionality also provides us to read the + status message, location coordinates, and created-at timestamp associated with the latest feed. + + Hardware: Arduino MKR1000 + + !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! + + Note: + - Requires WiFi101 library version 0.15.3 or newer. + - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +#include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros + +char ssid[] = SECRET_SSID; // your network SSID (name) +char pass[] = SECRET_PASS; // your network password +int keyIndex = 0; // your network key Index number (needed only for WEP) +WiFiClient client; + +// Weather station channel details +unsigned long weatherStationChannelNumber = SECRET_CH_ID_WEATHER_STATION; + +int statusCode = 0; +int field[8] = {1,2,3,4,5,6,7,8}; + +void setup() { + Serial.begin(115200); // Initialize serial + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + ThingSpeak.begin(client); // Initialize ThingSpeak + + // Connect to WiFi + if(WiFi.status() != WL_CONNECTED){ + Serial.print("Attempting to connect to SSID: "); + Serial.println(SECRET_SSID); + while(WiFi.status() != WL_CONNECTED){ + WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network + Serial.print("."); + delay(5000); + } + Serial.println("\nConnected"); + } +} + +void loop() { + + // Read and store all the latest field values, location coordinates, status message, and created-at timestamp + // use ThingSpeak.readMultipleFields(channelNumber, readAPIKey) for private channels + statusCode = ThingSpeak.readMultipleFields(weatherStationChannelNumber); + + if(statusCode == 200) + { + // Fetch the stored data + + int windDir = ThingSpeak.getFieldAsInt(field[0]); // Field 1 + float windSpeed = ThingSpeak.getFieldAsFloat(field[1]); // Field 2 + int percentHumid = ThingSpeak.getFieldAsInt(field[2]); // Field 3 + float tempInF = ThingSpeak.getFieldAsFloat(field[3]); // Field 4 + float rainInchPerMin = ThingSpeak.getFieldAsFloat(field[4]); // Field 5 + float pressureInHg = ThingSpeak.getFieldAsFloat(field[5]); // Field 6 + float powerLevel = ThingSpeak.getFieldAsFloat(field[6]); // Field 7 + int lightIntensity = ThingSpeak.getFieldAsInt(field[7]); // Field 8 + String statusMessage = ThingSpeak.getStatus(); // Status message + String latitude = ThingSpeak.getLatitude(); // Latitude + String longitude = ThingSpeak.getLongitude(); // Longitude + String elevation = ThingSpeak.getElevation(); // Elevation + String createdAt = ThingSpeak.getCreatedAt(); // Created-at timestamp + + Serial.println("Wind Direction (North = 0 degrees): " + String(windDir)); + Serial.println("Wind Speed (mph): " + String(windSpeed)); + Serial.println("% Humidity: " + String(percentHumid)); + Serial.println("Temperature (F): " + String(tempInF)); + Serial.println("Rain (Inches/minute): " + String(rainInchPerMin)); + Serial.println("Pressure (\"Hg): " + String(pressureInHg)); + Serial.println("Power Level (V): " + String(powerLevel)); + Serial.println("Light Intensity: " + String(lightIntensity)); + Serial.println("Status Message, if any: " + statusMessage); + Serial.println("Latitude, if any (+ve is North, -ve is South): " + latitude); + Serial.println("Longitude, if any (+ve is East, -ve is West): " + longitude); + Serial.println("Elevation, if any (meters above sea level): " + elevation); + Serial.println("Created at, if any (YYYY-MM-DD hh:mm:ss): " + createdAt); + } + else{ + Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); + } + + Serial.println(); + delay(5000); // no need to fetch too often + +} diff --git a/examples/ArduinoMKR1000/ReadMultipleFields/secrets.h b/examples/ArduinoMKR1000/ReadMultipleFields/secrets.h new file mode 100644 index 0000000..f523bd5 --- /dev/null +++ b/examples/ArduinoMKR1000/ReadMultipleFields/secrets.h @@ -0,0 +1,7 @@ +// Use this file to store all of the private credentials +// and connection details + +#define SECRET_SSID "MySSID" // replace MySSID with your WiFi network name +#define SECRET_PASS "MyPassword" // replace MyPassword with your WiFi password + +#define SECRET_CH_ID_WEATHER_STATION 12397 //MathWorks weather station diff --git a/examples/ArduinoMKR1000/ReadMultipleFieldsSecure/ReadMultipleFieldsSecure.ino b/examples/ArduinoMKR1000/ReadMultipleFieldsSecure/ReadMultipleFieldsSecure.ino new file mode 100644 index 0000000..9b9a7bf --- /dev/null +++ b/examples/ArduinoMKR1000/ReadMultipleFieldsSecure/ReadMultipleFieldsSecure.ino @@ -0,0 +1,112 @@ +/* + ReadMultipleFields + + Description: Demonstates reading from a public channel which requires no API key (reading from a private channel requires a read API key). + The values read from the public channel is the current wind direction, wind speed, humidity, outside temperature, rain, pressure, + power level, and light intensity at MathWorks headquaters in Natick, MA.The functionality also provides us to read the + status message, location coordinates, and created-at timestamp associated with the latest feed over secured HTTPS connection. + + Hardware: Arduino MKR1000 + + !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! + + Note: + - Requires WiFi101 library version 0.15.3 or newer. + - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +#define TS_ENABLE_SSL // For HTTPS SSL connection + +#include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros + +char ssid[] = SECRET_SSID; // your network SSID (name) +char pass[] = SECRET_PASS; // your network password +int keyIndex = 0; // your network key Index number (needed only for WEP) +WiFiSSLClient client; + +// Weather station channel details +unsigned long weatherStationChannelNumber = SECRET_CH_ID_WEATHER_STATION; + +int statusCode = 0; +int field[8] = {1,2,3,4,5,6,7,8}; + +void setup() { + Serial.begin(115200); // Initialize serial + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + ThingSpeak.begin(client); // Initialize ThingSpeak + + // Connect to WiFi + if(WiFi.status() != WL_CONNECTED){ + Serial.print("Attempting to connect to SSID: "); + Serial.println(SECRET_SSID); + while(WiFi.status() != WL_CONNECTED){ + WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network + Serial.print("."); + delay(5000); + } + Serial.println("\nConnected"); + } +} + +void loop() { + + // Read and store all the latest field values, location coordinates, status message, and created-at timestamp + // use ThingSpeak.readMultipleFields(channelNumber, readAPIKey) for private channels + statusCode = ThingSpeak.readMultipleFields(weatherStationChannelNumber); + + if(statusCode == 200) + { + + // Fetch the stored data + + int windDir = ThingSpeak.getFieldAsInt(field[0]); // Field 1 + float windSpeed = ThingSpeak.getFieldAsFloat(field[1]); // Field 2 + int percentHumid = ThingSpeak.getFieldAsInt(field[2]); // Field 3 + float tempInF = ThingSpeak.getFieldAsFloat(field[3]); // Field 4 + float rainInchPerMin = ThingSpeak.getFieldAsFloat(field[4]); // Field 5 + float pressureInHg = ThingSpeak.getFieldAsFloat(field[5]); // Field 6 + float powerLevel = ThingSpeak.getFieldAsFloat(field[6]); // Field 7 + int lightIntensity = ThingSpeak.getFieldAsInt(field[7]); // Field 8 + String statusMessage = ThingSpeak.getStatus(); // Status message + String latitude = ThingSpeak.getLatitude(); // Latitude + String longitude = ThingSpeak.getLongitude(); // Longitude + String elevation = ThingSpeak.getElevation(); // Elevation + String createdAt = ThingSpeak.getCreatedAt(); // Created-at timestamp + + Serial.println("Wind Direction (North = 0 degrees): " + String(windDir)); + Serial.println("Wind Speed (mph): " + String(windSpeed)); + Serial.println("% Humidity: " + String(percentHumid)); + Serial.println("Temperature (F): " + String(tempInF)); + Serial.println("Rain (Inches/minute): " + String(rainInchPerMin)); + Serial.println("Pressure (\"Hg): " + String(pressureInHg)); + Serial.println("Power Level (V): " + String(powerLevel)); + Serial.println("Light Intensity: " + String(lightIntensity)); + Serial.println("Status Message, if any: " + statusMessage); + Serial.println("Latitude, if any (+ve is North, -ve is South): " + latitude); + Serial.println("Longitude, if any (+ve is East, -ve is West): " + longitude); + Serial.println("Elevation, if any (meters above sea level): " + elevation); + Serial.println("Created at, if any (YYYY-MM-DD hh:mm:ss): " + createdAt); + } + else{ + Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); + } + + Serial.println(); + delay(5000); // no need to fetch too often + +} diff --git a/examples/ArduinoMKR1000/ReadMultipleFieldsSecure/secrets.h b/examples/ArduinoMKR1000/ReadMultipleFieldsSecure/secrets.h new file mode 100644 index 0000000..f523bd5 --- /dev/null +++ b/examples/ArduinoMKR1000/ReadMultipleFieldsSecure/secrets.h @@ -0,0 +1,7 @@ +// Use this file to store all of the private credentials +// and connection details + +#define SECRET_SSID "MySSID" // replace MySSID with your WiFi network name +#define SECRET_PASS "MyPassword" // replace MyPassword with your WiFi password + +#define SECRET_CH_ID_WEATHER_STATION 12397 //MathWorks weather station diff --git a/examples/ArduinoMKR1000/WriteMultipleFields/WriteMultipleFields.ino b/examples/ArduinoMKR1000/WriteMultipleFields/WriteMultipleFields.ino index 98bb799..00cfa77 100644 --- a/examples/ArduinoMKR1000/WriteMultipleFields/WriteMultipleFields.ino +++ b/examples/ArduinoMKR1000/WriteMultipleFields/WriteMultipleFields.ino @@ -1,102 +1,106 @@ -/* - WriteMultipleFields - - Description: Writes values to fields 1,2,3,4 and status in a single ThingSpeak update every 20 seconds. - - Hardware: Arduino MKR1000 - - !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! - - Note: - - Requires WiFi101 library version 0.15.3 or newer. - - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. - - ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and - analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. - - Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. - See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. - - For licensing information, see the accompanying license file. - - Copyright 2018, The MathWorks, Inc. -*/ - -#include "ThingSpeak.h" -#include -#include "secrets.h" - -char ssid[] = SECRET_SSID; // your network SSID (name) -char pass[] = SECRET_PASS; // your network password -int keyIndex = 0; // your network key Index number (needed only for WEP) -WiFiClient client; - -unsigned long myChannelNumber = SECRET_CH_ID; -const char * myWriteAPIKey = SECRET_WRITE_APIKEY; - -// Initialize our values -int number1 = 0; -int number2 = random(0,100); -int number3 = random(0,100); -int number4 = random(0,100); -String myStatus = ""; - -void setup() { - Serial.begin(115200); // Initialize serial - ThingSpeak.begin(client); // Initialize ThingSpeak -} - -void loop() { - - // Connect or reconnect to WiFi - if(WiFi.status() != WL_CONNECTED){ - Serial.print("Attempting to connect to SSID: "); - Serial.println(SECRET_SSID); - while(WiFi.status() != WL_CONNECTED){ - WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network - Serial.print("."); - delay(5000); - } - Serial.println("\nConnected."); - } - - // set the fields with the values - ThingSpeak.setField(1, number1); - ThingSpeak.setField(2, number2); - ThingSpeak.setField(3, number3); - ThingSpeak.setField(4, number4); - - // figure out the status message - if(number1 > number2){ - myStatus = String("field1 is greater than field2"); - } - else if(number1 < number2){ - myStatus = String("field1 is less than field2"); - } - else{ - myStatus = String("field1 equals field2"); - } - - // set the status - ThingSpeak.setStatus(myStatus); - - // write to the ThingSpeak channel - int x = ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey); - if(x == 200){ - Serial.println("Channel update successful."); - } - else{ - Serial.println("Problem updating channel. HTTP error code " + String(x)); - } - - // change the values - number1++; - if(number1 > 99){ - number1 = 0; - } - number2 = random(0,100); - number3 = random(0,100); - number4 = random(0,100); - - delay(20000); // Wait 20 seconds to update the channel again -} +/* + WriteMultipleFields + + Description: Writes values to fields 1,2,3,4 and status in a single ThingSpeak update every 20 seconds. + + Hardware: Arduino MKR1000 + + !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! + + Note: + - Requires WiFi101 library version 0.15.3 or newer. + - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +#include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros + +char ssid[] = SECRET_SSID; // your network SSID (name) +char pass[] = SECRET_PASS; // your network password +int keyIndex = 0; // your network key Index number (needed only for WEP) +WiFiClient client; + +unsigned long myChannelNumber = SECRET_CH_ID; +const char * myWriteAPIKey = SECRET_WRITE_APIKEY; + +// Initialize our values +int number1 = 0; +int number2 = random(0,100); +int number3 = random(0,100); +int number4 = random(0,100); +String myStatus = ""; + +void setup() { + Serial.begin(115200); // Initialize serial + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + ThingSpeak.begin(client); // Initialize ThingSpeak +} + +void loop() { + + // Connect or reconnect to WiFi + if(WiFi.status() != WL_CONNECTED){ + Serial.print("Attempting to connect to SSID: "); + Serial.println(SECRET_SSID); + while(WiFi.status() != WL_CONNECTED){ + WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network + Serial.print("."); + delay(5000); + } + Serial.println("\nConnected."); + } + + // set the fields with the values + ThingSpeak.setField(1, number1); + ThingSpeak.setField(2, number2); + ThingSpeak.setField(3, number3); + ThingSpeak.setField(4, number4); + + // figure out the status message + if(number1 > number2){ + myStatus = String("field1 is greater than field2"); + } + else if(number1 < number2){ + myStatus = String("field1 is less than field2"); + } + else{ + myStatus = String("field1 equals field2"); + } + + // set the status + ThingSpeak.setStatus(myStatus); + + // write to the ThingSpeak channel + int x = ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey); + if(x == 200){ + Serial.println("Channel update successful."); + } + else{ + Serial.println("Problem updating channel. HTTP error code " + String(x)); + } + + // change the values + number1++; + if(number1 > 99){ + number1 = 0; + } + number2 = random(0,100); + number3 = random(0,100); + number4 = random(0,100); + + delay(20000); // Wait 20 seconds to update the channel again +} diff --git a/examples/ArduinoMKR1000/WriteMultipleFieldsSecure/WriteMultipleFieldsSecure.ino b/examples/ArduinoMKR1000/WriteMultipleFieldsSecure/WriteMultipleFieldsSecure.ino new file mode 100644 index 0000000..96d030f --- /dev/null +++ b/examples/ArduinoMKR1000/WriteMultipleFieldsSecure/WriteMultipleFieldsSecure.ino @@ -0,0 +1,108 @@ +/* + WriteMultipleFields + + Description: Writes values to fields 1,2,3,4 and status in a single ThingSpeak update every 20 seconds over secured HTTPS connection. + + Hardware: Arduino MKR1000 + + !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! + + Note: + - Requires WiFi101 library version 0.15.3 or newer. + - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +#define TS_ENABLE_SSL // For HTTPS SSL connection + +#include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros + +char ssid[] = SECRET_SSID; // your network SSID (name) +char pass[] = SECRET_PASS; // your network password +int keyIndex = 0; // your network key Index number (needed only for WEP) +WiFiSSLClient client; + +unsigned long myChannelNumber = SECRET_CH_ID; +const char * myWriteAPIKey = SECRET_WRITE_APIKEY; + +// Initialize our values +int number1 = 0; +int number2 = random(0,100); +int number3 = random(0,100); +int number4 = random(0,100); +String myStatus = ""; + +void setup() { + Serial.begin(115200); // Initialize serial + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + ThingSpeak.begin(client); // Initialize ThingSpeak +} + +void loop() { + + // Connect or reconnect to WiFi + if(WiFi.status() != WL_CONNECTED){ + Serial.print("Attempting to connect to SSID: "); + Serial.println(SECRET_SSID); + while(WiFi.status() != WL_CONNECTED){ + WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network + Serial.print("."); + delay(5000); + } + Serial.println("\nConnected."); + } + + // set the fields with the values + ThingSpeak.setField(1, number1); + ThingSpeak.setField(2, number2); + ThingSpeak.setField(3, number3); + ThingSpeak.setField(4, number4); + + // figure out the status message + if(number1 > number2){ + myStatus = String("field1 is greater than field2"); + } + else if(number1 < number2){ + myStatus = String("field1 is less than field2"); + } + else{ + myStatus = String("field1 equals field2"); + } + + // set the status + ThingSpeak.setStatus(myStatus); + + // write to the ThingSpeak channel + int x = ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey); + if(x == 200){ + Serial.println("Channel update successful."); + } + else{ + Serial.println("Problem updating channel. HTTP error code " + String(x)); + } + + // change the values + number1++; + if(number1 > 99){ + number1 = 0; + } + number2 = random(0,100); + number3 = random(0,100); + number4 = random(0,100); + + delay(20000); // Wait 20 seconds to update the channel again +} diff --git a/examples/ArduinoMKR1000/WriteMultipleFieldsSecure/secrets.h b/examples/ArduinoMKR1000/WriteMultipleFieldsSecure/secrets.h new file mode 100644 index 0000000..8c0539d --- /dev/null +++ b/examples/ArduinoMKR1000/WriteMultipleFieldsSecure/secrets.h @@ -0,0 +1,8 @@ +// Use this file to store all of the private credentials +// and connection details + +#define SECRET_SSID "MySSID" // replace MySSID with your WiFi network name +#define SECRET_PASS "MyPassword" // replace MyPassword with your WiFi password + +#define SECRET_CH_ID 000000 // replace 0000000 with your channel number +#define SECRET_WRITE_APIKEY "XYZ" // replace XYZ with your channel write API Key diff --git a/examples/ArduinoMKR1000/WriteSingleField/WriteSingleField.ino b/examples/ArduinoMKR1000/WriteSingleField/WriteSingleField.ino index 28bb0d3..6bd33c3 100644 --- a/examples/ArduinoMKR1000/WriteSingleField/WriteSingleField.ino +++ b/examples/ArduinoMKR1000/WriteSingleField/WriteSingleField.ino @@ -1,75 +1,79 @@ -/* - WriteSingleField - - Description: Writes a value to a channel on ThingSpeak every 20 seconds. - - Hardware: Arduino MKR1000 - - !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! - - Note: - - Requires WiFi101 library version 0.15.3 or newer. - - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. - - ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and - analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. - - Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. - See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. - - For licensing information, see the accompanying license file. - - Copyright 2018, The MathWorks, Inc. -*/ - -#include "ThingSpeak.h" -#include -#include "secrets.h" - -char ssid[] = SECRET_SSID; // your network SSID (name) -char pass[] = SECRET_PASS; // your network password -int keyIndex = 0; // your network key Index number (needed only for WEP) -WiFiClient client; - -unsigned long myChannelNumber = SECRET_CH_ID; -const char * myWriteAPIKey = SECRET_WRITE_APIKEY; - -int number = 0; - -void setup() { - Serial.begin(115200); // Initialize serial - ThingSpeak.begin(client); // Initialize ThingSpeak -} - -void loop() { - - // Connect or reconnect to WiFi - if(WiFi.status() != WL_CONNECTED){ - Serial.print("Attempting to connect to SSID: "); - Serial.println(SECRET_SSID); - while(WiFi.status() != WL_CONNECTED){ - WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network - Serial.print("."); - delay(5000); - } - Serial.println("\nConnected."); - } - - // Write to ThingSpeak. There are up to 8 fields in a channel, allowing you to store up to 8 different - // pieces of information in a channel. Here, we write to field 1. - int x = ThingSpeak.writeField(myChannelNumber, 1, number, myWriteAPIKey); - if(x == 200){ - Serial.println("Channel update successful."); - } - else{ - Serial.println("Problem updating channel. HTTP error code " + String(x)); - } - - // change the value - number++; - if(number > 99){ - number = 0; - } - - delay(20000); // Wait 20 seconds to update the channel again -} +/* + WriteSingleField + + Description: Writes a value to a channel on ThingSpeak every 20 seconds. + + Hardware: Arduino MKR1000 + + !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! + + Note: + - Requires WiFi101 library version 0.15.3 or newer. + - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +#include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros + +char ssid[] = SECRET_SSID; // your network SSID (name) +char pass[] = SECRET_PASS; // your network password +int keyIndex = 0; // your network key Index number (needed only for WEP) +WiFiClient client; + +unsigned long myChannelNumber = SECRET_CH_ID; +const char * myWriteAPIKey = SECRET_WRITE_APIKEY; + +int number = 0; + +void setup() { + Serial.begin(115200); // Initialize serial + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + ThingSpeak.begin(client); // Initialize ThingSpeak +} + +void loop() { + + // Connect or reconnect to WiFi + if(WiFi.status() != WL_CONNECTED){ + Serial.print("Attempting to connect to SSID: "); + Serial.println(SECRET_SSID); + while(WiFi.status() != WL_CONNECTED){ + WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network + Serial.print("."); + delay(5000); + } + Serial.println("\nConnected."); + } + + // Write to ThingSpeak. There are up to 8 fields in a channel, allowing you to store up to 8 different + // pieces of information in a channel. Here, we write to field 1. + int x = ThingSpeak.writeField(myChannelNumber, 1, number, myWriteAPIKey); + if(x == 200){ + Serial.println("Channel update successful."); + } + else{ + Serial.println("Problem updating channel. HTTP error code " + String(x)); + } + + // change the value + number++; + if(number > 99){ + number = 0; + } + + delay(20000); // Wait 20 seconds to update the channel again +} diff --git a/examples/ArduinoMKR1000/WriteSingleFieldSecure/WriteSingleFieldSecure.ino b/examples/ArduinoMKR1000/WriteSingleFieldSecure/WriteSingleFieldSecure.ino new file mode 100644 index 0000000..7769f19 --- /dev/null +++ b/examples/ArduinoMKR1000/WriteSingleFieldSecure/WriteSingleFieldSecure.ino @@ -0,0 +1,81 @@ +/* + WriteSingleField + + Description: Writes a value to a channel on ThingSpeak every 20 seconds over secured HTTPS connection. + + Hardware: Arduino MKR1000 + + !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! + + Note: + - Requires WiFi101 library version 0.15.3 or newer. + - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +#define TS_ENABLE_SSL // For HTTPS SSL connection + +#include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros + +char ssid[] = SECRET_SSID; // your network SSID (name) +char pass[] = SECRET_PASS; // your network password +int keyIndex = 0; // your network key Index number (needed only for WEP) +WiFiSSLClient client; + +unsigned long myChannelNumber = SECRET_CH_ID; +const char * myWriteAPIKey = SECRET_WRITE_APIKEY; + +int number = 0; + +void setup() { + Serial.begin(115200); // Initialize serial + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + ThingSpeak.begin(client); // Initialize ThingSpeak +} + +void loop() { + + // Connect or reconnect to WiFi + if(WiFi.status() != WL_CONNECTED){ + Serial.print("Attempting to connect to SSID: "); + Serial.println(SECRET_SSID); + while(WiFi.status() != WL_CONNECTED){ + WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network + Serial.print("."); + delay(5000); + } + Serial.println("\nConnected."); + } + + // Write to ThingSpeak. There are up to 8 fields in a channel, allowing you to store up to 8 different + // pieces of information in a channel. Here, we write to field 1. + int x = ThingSpeak.writeField(myChannelNumber, 1, number, myWriteAPIKey); + if(x == 200){ + Serial.println("Channel update successful."); + } + else{ + Serial.println("Problem updating channel. HTTP error code " + String(x)); + } + + // change the value + number++; + if(number > 99){ + number = 0; + } + + delay(20000); // Wait 20 seconds to update the channel again +} diff --git a/examples/ArduinoMKR1000/WriteSingleFieldSecure/secrets.h b/examples/ArduinoMKR1000/WriteSingleFieldSecure/secrets.h new file mode 100644 index 0000000..8c0539d --- /dev/null +++ b/examples/ArduinoMKR1000/WriteSingleFieldSecure/secrets.h @@ -0,0 +1,8 @@ +// Use this file to store all of the private credentials +// and connection details + +#define SECRET_SSID "MySSID" // replace MySSID with your WiFi network name +#define SECRET_PASS "MyPassword" // replace MyPassword with your WiFi password + +#define SECRET_CH_ID 000000 // replace 0000000 with your channel number +#define SECRET_WRITE_APIKEY "XYZ" // replace XYZ with your channel write API Key diff --git a/examples/ArduinoMKRETHShield/ReadField/ReadField.ino b/examples/ArduinoMKRETHShield/ReadField/ReadField.ino index 17f84cb..1ce9cbb 100644 --- a/examples/ArduinoMKRETHShield/ReadField/ReadField.ino +++ b/examples/ArduinoMKRETHShield/ReadField/ReadField.ino @@ -1,109 +1,112 @@ -/* - ReadField - - Description: Demonstates reading from a public channel which requires no API key and reading from a private channel which requires a read API key. - The value read from the public channel is the current outside temperature at MathWorks headquaters in Natick, MA. The value from the - private channel is an example counter that increments every 10 seconds. - - Hardware: Arduino MKR ETH Shield - - !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! - - Note: - - Requires the Ethernet library - - ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and - analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. - - Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. - See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. - - For licensing information, see the accompanying license file. - - Copyright 2018, The MathWorks, Inc. -*/ - -#include "ThingSpeak.h" -#include -#include "secrets.h" - -byte mac[] = SECRET_MAC; - -// Set the static IP address to use if the DHCP fails to assign -IPAddress ip(192, 168, 0, 177); -IPAddress myDns(192, 168, 0, 1); - -EthernetClient client; - -// Weather station channel details -unsigned long weatherStationChannelNumber = SECRET_CH_ID_WEATHER_STATION; -unsigned int temperatureFieldNumber = 4; - -// Counting channel details -unsigned long counterChannelNumber = SECRET_CH_ID_COUNTER; -const char * myCounterReadAPIKey = SECRET_READ_APIKEY_COUNTER; -unsigned int counterFieldNumber = 1; - -void setup() { - Ethernet.init(5); // MKR ETH shield - Serial.begin(115200); //Initialize serial - - // start the Ethernet connection: - Serial.println("Initialize Ethernet with DHCP:"); - if (Ethernet.begin(mac) == 0) { - Serial.println("Failed to configure Ethernet using DHCP"); - // Check for Ethernet hardware present - if (Ethernet.hardwareStatus() == EthernetNoHardware) { - Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :("); - while (true) { - delay(1); // do nothing, no point running without Ethernet hardware - } - } - if (Ethernet.linkStatus() == LinkOFF) { - Serial.println("Ethernet cable is not connected."); - } - // try to congifure using IP address instead of DHCP: - Ethernet.begin(mac, ip, myDns); - } else { - Serial.print(" DHCP assigned IP "); - Serial.println(Ethernet.localIP()); - } - // give the Ethernet shield a second to initialize: - delay(1000); - - ThingSpeak.begin(client); // Initialize ThingSpeak -} - -void loop() { - - int statusCode = 0; - - // Read in field 4 of the public channel recording the temperature - float temperatureInF = ThingSpeak.readFloatField(weatherStationChannelNumber, temperatureFieldNumber); - - // Check the status of the read operation to see if it was successful - statusCode = ThingSpeak.getLastReadStatus(); - if(statusCode == 200){ - Serial.println("Temperature at MathWorks HQ: " + String(temperatureInF) + " deg F"); - } - else{ - Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); - } - - delay(15000); // No need to read the temperature too often. - - // Read in field 1 of the private channel which is a counter - long count = ThingSpeak.readLongField(counterChannelNumber, counterFieldNumber, myCounterReadAPIKey); - - // Check the status of the read operation to see if it was successful - statusCode = ThingSpeak.getLastReadStatus(); - if(statusCode == 200){ - Serial.println("Counter: " + String(count)); - } - else{ - Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); - } - - delay(15000); // No need to read the counter too often. - -} +/* + ReadField + + Description: Demonstates reading from a public channel which requires no API key and reading from a private channel which requires a read API key. + The value read from the public channel is the current outside temperature at MathWorks headquaters in Natick, MA. The value from the + private channel is an example counter that increments every 10 seconds. + + Hardware: Arduino MKR ETH Shield + + !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! + + Note: + - Requires the Ethernet library + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +#include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros + +byte mac[] = SECRET_MAC; + +// Set the static IP address to use if the DHCP fails to assign +IPAddress ip(192, 168, 0, 177); +IPAddress myDns(192, 168, 0, 1); + +EthernetClient client; + +// Weather station channel details +unsigned long weatherStationChannelNumber = SECRET_CH_ID_WEATHER_STATION; +unsigned int temperatureFieldNumber = 4; + +// Counting channel details +unsigned long counterChannelNumber = SECRET_CH_ID_COUNTER; +const char * myCounterReadAPIKey = SECRET_READ_APIKEY_COUNTER; +unsigned int counterFieldNumber = 1; + +void setup() { + Ethernet.init(5); // MKR ETH shield + Serial.begin(115200); //Initialize serial + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + // start the Ethernet connection: + Serial.println("Initialize Ethernet with DHCP:"); + if (Ethernet.begin(mac) == 0) { + Serial.println("Failed to configure Ethernet using DHCP"); + // Check for Ethernet hardware present + if (Ethernet.hardwareStatus() == EthernetNoHardware) { + Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :("); + while (true) { + delay(1); // do nothing, no point running without Ethernet hardware + } + } + if (Ethernet.linkStatus() == LinkOFF) { + Serial.println("Ethernet cable is not connected."); + } + // try to congifure using IP address instead of DHCP: + Ethernet.begin(mac, ip, myDns); + } else { + Serial.print(" DHCP assigned IP "); + Serial.println(Ethernet.localIP()); + } + // give the Ethernet shield a second to initialize: + delay(1000); + + ThingSpeak.begin(client); // Initialize ThingSpeak +} + +void loop() { + + int statusCode = 0; + + // Read in field 4 of the public channel recording the temperature + float temperatureInF = ThingSpeak.readFloatField(weatherStationChannelNumber, temperatureFieldNumber); + + // Check the status of the read operation to see if it was successful + statusCode = ThingSpeak.getLastReadStatus(); + if(statusCode == 200){ + Serial.println("Temperature at MathWorks HQ: " + String(temperatureInF) + " deg F"); + } + else{ + Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); + } + + delay(15000); // No need to read the temperature too often. + + // Read in field 1 of the private channel which is a counter + long count = ThingSpeak.readLongField(counterChannelNumber, counterFieldNumber, myCounterReadAPIKey); + + // Check the status of the read operation to see if it was successful + statusCode = ThingSpeak.getLastReadStatus(); + if(statusCode == 200){ + Serial.println("Counter: " + String(count)); + } + else{ + Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); + } + + delay(15000); // No need to read the counter too often. + +} diff --git a/examples/ArduinoMKRETHShield/WriteMultipleFields/WriteMultipleFields.ino b/examples/ArduinoMKRETHShield/WriteMultipleFields/WriteMultipleFields.ino index a9b2bc9..48783e7 100644 --- a/examples/ArduinoMKRETHShield/WriteMultipleFields/WriteMultipleFields.ino +++ b/examples/ArduinoMKRETHShield/WriteMultipleFields/WriteMultipleFields.ino @@ -1,117 +1,120 @@ -/* - WriteMultipleFields - - Description: Writes values to fields 1,2,3,4 and status in a single ThingSpeak update every 20 seconds. - - Hardware: Arduino MKR ETH Shield - - !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! - - Note: - - Requires the Ethernet library - - ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and - analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. - - Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. - See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. - - For licensing information, see the accompanying license file. - - Copyright 2018, The MathWorks, Inc. -*/ - -#include "ThingSpeak.h" -#include -#include "secrets.h" - -byte mac[] = { 0x90, 0xA2, 0xDA, 0x10, 0x40, 0x4F }; - -// Set the static IP address to use if the DHCP fails to assign -IPAddress ip(192, 168, 0, 177); -IPAddress myDns(192, 168, 0, 1); - -EthernetClient client; - -unsigned long myChannelNumber = SECRET_CH_ID; -const char * myWriteAPIKey = SECRET_WRITE_APIKEY; - -// Initialize our values -int number1 = 0; -int number2 = random(0,100); -int number3 = random(0,100); -int number4 = random(0,100); -String myStatus = ""; - -void setup() { - Ethernet.init(5); // MKR ETH shield - Serial.begin(115200); //Initialize serial - - // start the Ethernet connection: - Serial.println("Initialize Ethernet with DHCP:"); - if (Ethernet.begin(mac) == 0) { - Serial.println("Failed to configure Ethernet using DHCP"); - // Check for Ethernet hardware present - if (Ethernet.hardwareStatus() == EthernetNoHardware) { - Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :("); - while (true) { - delay(1); // do nothing, no point running without Ethernet hardware - } - } - if (Ethernet.linkStatus() == LinkOFF) { - Serial.println("Ethernet cable is not connected."); - } - // try to congifure using IP address instead of DHCP: - Ethernet.begin(mac, ip, myDns); - } else { - Serial.print(" DHCP assigned IP "); - Serial.println(Ethernet.localIP()); - } - // give the Ethernet shield a second to initialize: - delay(1000); - - ThingSpeak.begin(client); // Initialize ThingSpeak -} - -void loop() { - - // set the fields with the values - ThingSpeak.setField(1, number1); - ThingSpeak.setField(2, number2); - ThingSpeak.setField(3, number3); - ThingSpeak.setField(4, number4); - - // figure out the status message - if(number1 > number2){ - myStatus = String("field1 is greater than field2"); - } - else if(number1 < number2){ - myStatus = String("field1 is less than field2"); - } - else{ - myStatus = String("field1 equals field2"); - } - - // set the status - ThingSpeak.setStatus(myStatus); - - // write to the ThingSpeak channel - int x = ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey); - if(x == 200){ - Serial.println("Channel update successful."); - } - else{ - Serial.println("Problem updating channel. HTTP error code " + String(x)); - } - - // change the values - number1++; - if(number1 > 99){ - number1 = 0; - } - number2 = random(0,100); - number3 = random(0,100); - number4 = random(0,100); - - delay(20000); // Wait 20 seconds to update the channel again -} +/* + WriteMultipleFields + + Description: Writes values to fields 1,2,3,4 and status in a single ThingSpeak update every 20 seconds. + + Hardware: Arduino MKR ETH Shield + + !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! + + Note: + - Requires the Ethernet library + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +#include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros + +byte mac[] = { 0x90, 0xA2, 0xDA, 0x10, 0x40, 0x4F }; + +// Set the static IP address to use if the DHCP fails to assign +IPAddress ip(192, 168, 0, 177); +IPAddress myDns(192, 168, 0, 1); + +EthernetClient client; + +unsigned long myChannelNumber = SECRET_CH_ID; +const char * myWriteAPIKey = SECRET_WRITE_APIKEY; + +// Initialize our values +int number1 = 0; +int number2 = random(0,100); +int number3 = random(0,100); +int number4 = random(0,100); +String myStatus = ""; + +void setup() { + Ethernet.init(5); // MKR ETH shield + Serial.begin(115200); //Initialize serial + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + // start the Ethernet connection: + Serial.println("Initialize Ethernet with DHCP:"); + if (Ethernet.begin(mac) == 0) { + Serial.println("Failed to configure Ethernet using DHCP"); + // Check for Ethernet hardware present + if (Ethernet.hardwareStatus() == EthernetNoHardware) { + Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :("); + while (true) { + delay(1); // do nothing, no point running without Ethernet hardware + } + } + if (Ethernet.linkStatus() == LinkOFF) { + Serial.println("Ethernet cable is not connected."); + } + // try to congifure using IP address instead of DHCP: + Ethernet.begin(mac, ip, myDns); + } else { + Serial.print(" DHCP assigned IP "); + Serial.println(Ethernet.localIP()); + } + // give the Ethernet shield a second to initialize: + delay(1000); + + ThingSpeak.begin(client); // Initialize ThingSpeak +} + +void loop() { + + // set the fields with the values + ThingSpeak.setField(1, number1); + ThingSpeak.setField(2, number2); + ThingSpeak.setField(3, number3); + ThingSpeak.setField(4, number4); + + // figure out the status message + if(number1 > number2){ + myStatus = String("field1 is greater than field2"); + } + else if(number1 < number2){ + myStatus = String("field1 is less than field2"); + } + else{ + myStatus = String("field1 equals field2"); + } + + // set the status + ThingSpeak.setStatus(myStatus); + + // write to the ThingSpeak channel + int x = ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey); + if(x == 200){ + Serial.println("Channel update successful."); + } + else{ + Serial.println("Problem updating channel. HTTP error code " + String(x)); + } + + // change the values + number1++; + if(number1 > 99){ + number1 = 0; + } + number2 = random(0,100); + number3 = random(0,100); + number4 = random(0,100); + + delay(20000); // Wait 20 seconds to update the channel again +} diff --git a/examples/ArduinoMKRETHShield/WriteSingleField/WriteSingleField.ino b/examples/ArduinoMKRETHShield/WriteSingleField/WriteSingleField.ino index 8bf23eb..4a18cfb 100644 --- a/examples/ArduinoMKRETHShield/WriteSingleField/WriteSingleField.ino +++ b/examples/ArduinoMKRETHShield/WriteSingleField/WriteSingleField.ino @@ -1,90 +1,93 @@ -/* - WriteSingleField - - Description: Writes a value to a channel on ThingSpeak every 20 seconds. - - Hardware: Arduino MKR ETH Shield - - !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! - - Note: - - Requires the Ethernet library - - ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and - analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. - - Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. - See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. - - For licensing information, see the accompanying license file. - - Copyright 2018, The MathWorks, Inc. -*/ - -#include "ThingSpeak.h" -#include -#include "secrets.h" - -byte mac[] = { 0x90, 0xA2, 0xDA, 0x10, 0x40, 0x4F }; - -// Set the static IP address to use if the DHCP fails to assign -IPAddress ip(192, 168, 0, 177); -IPAddress myDns(192, 168, 0, 1); - -EthernetClient client; - -unsigned long myChannelNumber = SECRET_CH_ID; -const char * myWriteAPIKey = SECRET_WRITE_APIKEY; - -int number = 0; - -void setup() { - Ethernet.init(5); // MKR ETH shield - Serial.begin(115200); //Initialize serial - - // start the Ethernet connection: - Serial.println("Initialize Ethernet with DHCP:"); - if (Ethernet.begin(mac) == 0) { - Serial.println("Failed to configure Ethernet using DHCP"); - // Check for Ethernet hardware present - if (Ethernet.hardwareStatus() == EthernetNoHardware) { - Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :("); - while (true) { - delay(1); // do nothing, no point running without Ethernet hardware - } - } - if (Ethernet.linkStatus() == LinkOFF) { - Serial.println("Ethernet cable is not connected."); - } - // try to congifure using IP address instead of DHCP: - Ethernet.begin(mac, ip, myDns); - } else { - Serial.print(" DHCP assigned IP "); - Serial.println(Ethernet.localIP()); - } - // give the Ethernet shield a second to initialize: - delay(1000); - - ThingSpeak.begin(client); // Initialize ThingSpeak -} - -void loop() { - - // Write to ThingSpeak. There are up to 8 fields in a channel, allowing you to store up to 8 different - // pieces of information in a channel. Here, we write to field 1. - int x = ThingSpeak.writeField(myChannelNumber, 1, number, myWriteAPIKey); - if(x == 200){ - Serial.println("Channel update successful."); - } - else{ - Serial.println("Problem updating channel. HTTP error code " + String(x)); - } - - // change the value - number++; - if(number > 99){ - number = 0; - } - - delay(20000); // Wait 20 seconds to update the channel again -} +/* + WriteSingleField + + Description: Writes a value to a channel on ThingSpeak every 20 seconds. + + Hardware: Arduino MKR ETH Shield + + !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! + + Note: + - Requires the Ethernet library + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +#include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros + +byte mac[] = { 0x90, 0xA2, 0xDA, 0x10, 0x40, 0x4F }; + +// Set the static IP address to use if the DHCP fails to assign +IPAddress ip(192, 168, 0, 177); +IPAddress myDns(192, 168, 0, 1); + +EthernetClient client; + +unsigned long myChannelNumber = SECRET_CH_ID; +const char * myWriteAPIKey = SECRET_WRITE_APIKEY; + +int number = 0; + +void setup() { + Ethernet.init(5); // MKR ETH shield + Serial.begin(115200); //Initialize serial + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + // start the Ethernet connection: + Serial.println("Initialize Ethernet with DHCP:"); + if (Ethernet.begin(mac) == 0) { + Serial.println("Failed to configure Ethernet using DHCP"); + // Check for Ethernet hardware present + if (Ethernet.hardwareStatus() == EthernetNoHardware) { + Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :("); + while (true) { + delay(1); // do nothing, no point running without Ethernet hardware + } + } + if (Ethernet.linkStatus() == LinkOFF) { + Serial.println("Ethernet cable is not connected."); + } + // try to congifure using IP address instead of DHCP: + Ethernet.begin(mac, ip, myDns); + } else { + Serial.print(" DHCP assigned IP "); + Serial.println(Ethernet.localIP()); + } + // give the Ethernet shield a second to initialize: + delay(1000); + + ThingSpeak.begin(client); // Initialize ThingSpeak +} + +void loop() { + + // Write to ThingSpeak. There are up to 8 fields in a channel, allowing you to store up to 8 different + // pieces of information in a channel. Here, we write to field 1. + int x = ThingSpeak.writeField(myChannelNumber, 1, number, myWriteAPIKey); + if(x == 200){ + Serial.println("Channel update successful."); + } + else{ + Serial.println("Problem updating channel. HTTP error code " + String(x)); + } + + // change the value + number++; + if(number > 99){ + number = 0; + } + + delay(20000); // Wait 20 seconds to update the channel again +} diff --git a/examples/ArduinoMKRGSM1400/ReadField/ReadField.ino b/examples/ArduinoMKRGSM1400/ReadField/ReadField.ino index 2c13318..a81a3db 100644 --- a/examples/ArduinoMKRGSM1400/ReadField/ReadField.ino +++ b/examples/ArduinoMKRGSM1400/ReadField/ReadField.ino @@ -1,108 +1,110 @@ -/* - ReadField - - Description: Demonstates reading from a public channel which requires no API key and reading from a private channel which requires a read API key. - The value read from the public channel is the current outside temperature at MathWorks headquaters in Natick, MA. The value from the - private channel is an example counter that increments every 10 seconds. - - Hardware: Arduino MKR GSM 1400 - - !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! - - Note: - - Requires MKRGSM library. - - Reqires GSM access (SIM card or credentials). - - ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and - analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. - - Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. - See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. - - For licensing information, see the accompanying license file. - - Copyright 2018, The MathWorks, Inc. -*/ - - -#include "ThingSpeak.h" -#include -#include "secrets.h" - -// PIN Number -const char PINNUMBER[] = SECRET_PIN; -// APN data -const char GPRS_APN[] = SECRET_GPRS_APN; -const char GPRS_LOGIN[] = SECRET_GPRS_LOGIN; -const char GPRS_PASSWORD[] = SECRET_GPRS_PASS; - -GSMClient client; -GPRS gprs; -GSM gsmAccess; - -// Weather station channel details -unsigned long weatherStationChannelNumber = SECRET_CH_ID_WEATHER_STATION; -unsigned int temperatureFieldNumber = 4; - -// Counting channel details -unsigned long counterChannelNumber = SECRET_CH_ID_COUNTER; -const char * myCounterReadAPIKey = SECRET_READ_APIKEY_COUNTER; -unsigned int counterFieldNumber = 1; - -void setup() { - Serial.begin(115200); //Initialize serial - - Serial.println("Starting Arduino web client."); - boolean connected = false; - - // wait 10 seconds for connection: - delay(10000); - - while (!connected) { - if ((gsmAccess.begin(PINNUMBER) == GSM_READY) && - (gprs.attachGPRS(GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD) == GPRS_READY)) { - connected = true; - } else { - Serial.println("Not connected"); - delay(1000); - } - } - - Serial.println("connected"); - - ThingSpeak.begin(client); // Initialize ThingSpeak -} - -void loop() { - - int statusCode = 0; - - // Read in field 4 of the public channel recording the temperature - float temperatureInF = ThingSpeak.readFloatField(weatherStationChannelNumber, temperatureFieldNumber); - - // Check the status of the read operation to see if it was successful - statusCode = ThingSpeak.getLastReadStatus(); - if(statusCode == 200){ - Serial.println("Temperature at MathWorks HQ: " + String(temperatureInF) + " deg F"); - } - else{ - Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); - } - - delay(15000); // No need to read the temperature too often. - - // Read in field 1 of the private channel which is a counter - long count = ThingSpeak.readLongField(counterChannelNumber, counterFieldNumber, myCounterReadAPIKey); - - // Check the status of the read operation to see if it was successful - statusCode = ThingSpeak.getLastReadStatus(); - if(statusCode == 200){ - Serial.println("Counter: " + String(count)); - } - else{ - Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); - } - - delay(15000); // No need to read the counter too often. - -} +/* + ReadField + + Description: Demonstates reading from a public channel which requires no API key and reading from a private channel which requires a read API key. + The value read from the public channel is the current outside temperature at MathWorks headquaters in Natick, MA. The value from the + private channel is an example counter that increments every 10 seconds. + + Hardware: Arduino MKR GSM 1400 + + !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! + + Note: + - Requires MKRGSM library. + - Reqires GSM access (SIM card or credentials). + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +#include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros + +// PIN Number +const char PINNUMBER[] = SECRET_PIN; +// APN data +const char GPRS_APN[] = SECRET_GPRS_APN; +const char GPRS_LOGIN[] = SECRET_GPRS_LOGIN; +const char GPRS_PASSWORD[] = SECRET_GPRS_PASS; + +GSMClient client; +GPRS gprs; +GSM gsmAccess; + +// Weather station channel details +unsigned long weatherStationChannelNumber = SECRET_CH_ID_WEATHER_STATION; +unsigned int temperatureFieldNumber = 4; + +// Counting channel details +unsigned long counterChannelNumber = SECRET_CH_ID_COUNTER; +const char * myCounterReadAPIKey = SECRET_READ_APIKEY_COUNTER; +unsigned int counterFieldNumber = 1; + +void setup() { + Serial.begin(115200); //Initialize serial + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + Serial.println("Starting Arduino web client."); + boolean connected = false; + + // wait 10 seconds for connection: + delay(10000); + + while (!connected) { + if ((gsmAccess.begin(PINNUMBER) == GSM_READY) && + (gprs.attachGPRS(GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD) == GPRS_READY)) { + connected = true; + } else { + Serial.println("Not connected"); + delay(1000); + } + } + + Serial.println("connected"); + + ThingSpeak.begin(client); // Initialize ThingSpeak +} + +void loop() { + + int statusCode = 0; + + // Read in field 4 of the public channel recording the temperature + float temperatureInF = ThingSpeak.readFloatField(weatherStationChannelNumber, temperatureFieldNumber); + + // Check the status of the read operation to see if it was successful + statusCode = ThingSpeak.getLastReadStatus(); + if(statusCode == 200){ + Serial.println("Temperature at MathWorks HQ: " + String(temperatureInF) + " deg F"); + } + else{ + Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); + } + + delay(15000); // No need to read the temperature too often. + + // Read in field 1 of the private channel which is a counter + long count = ThingSpeak.readLongField(counterChannelNumber, counterFieldNumber, myCounterReadAPIKey); + + // Check the status of the read operation to see if it was successful + statusCode = ThingSpeak.getLastReadStatus(); + if(statusCode == 200){ + Serial.println("Counter: " + String(count)); + } + else{ + Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); + } + + delay(15000); // No need to read the counter too often. + +} diff --git a/examples/ArduinoMKRGSM1400/WriteMultipleFields/WriteMultipleFields.ino b/examples/ArduinoMKRGSM1400/WriteMultipleFields/WriteMultipleFields.ino index b5a0408..4a258b8 100644 --- a/examples/ArduinoMKRGSM1400/WriteMultipleFields/WriteMultipleFields.ino +++ b/examples/ArduinoMKRGSM1400/WriteMultipleFields/WriteMultipleFields.ino @@ -1,116 +1,118 @@ -/* - WriteMultipleFields - - Description: Writes values to fields 1,2,3,4 and status in a single ThingSpeak update every 20 seconds. - - Hardware: Arduino MKR GSM 1400 - - !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! - - Note: - - Requires MKRGSM library. - - Reqires GSM access (SIM card or credentials). - - ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and - analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. - - Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. - See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. - - For licensing information, see the accompanying license file. - - Copyright 2018, The MathWorks, Inc. -*/ - - -#include "ThingSpeak.h" -#include -#include "secrets.h" - -// PIN Number -const char PINNUMBER[] = SECRET_PIN; -// APN data -const char GPRS_APN[] = SECRET_GPRS_APN; -const char GPRS_LOGIN[] = SECRET_GPRS_LOGIN; -const char GPRS_PASSWORD[] = SECRET_GPRS_PASS; - -GSMClient client; -GPRS gprs; -GSM gsmAccess; - -unsigned long myChannelNumber = SECRET_CH_ID; -const char * myWriteAPIKey = SECRET_WRITE_APIKEY; - -// Initialize our values -int number1 = 0; -int number2 = random(0,100); -int number3 = random(0,100); -int number4 = random(0,100); -String myStatus = ""; - -void setup() { - Serial.begin(115200); //Initialize serial - - Serial.println("Starting Arduino web client."); - boolean connected = false; - - // wait 10 seconds for connection: - delay(10000); - - while (!connected) { - if ((gsmAccess.begin(PINNUMBER) == GSM_READY) && - (gprs.attachGPRS(GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD) == GPRS_READY)) { - connected = true; - } else { - Serial.println("Not connected"); - delay(1000); - } - } - - Serial.println("connected"); - - ThingSpeak.begin(client); // Initialize ThingSpeak -} - -void loop() { - - // set the fields with the values - ThingSpeak.setField(1, number1); - ThingSpeak.setField(2, number2); - ThingSpeak.setField(3, number3); - ThingSpeak.setField(4, number4); - - // figure out the status message - if(number1 > number2){ - myStatus = String("field1 is greater than field2"); - } - else if(number1 < number2){ - myStatus = String("field1 is less than field2"); - } - else{ - myStatus = String("field1 equals field2"); - } - - // set the status - ThingSpeak.setStatus(myStatus); - - // write to the ThingSpeak channel - int x = ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey); - if(x == 200){ - Serial.println("Channel update successful."); - } - else{ - Serial.println("Problem updating channel. HTTP error code " + String(x)); - } - - // change the values - number1++; - if(number1 > 99){ - number1 = 0; - } - number2 = random(0,100); - number3 = random(0,100); - number4 = random(0,100); - - delay(20000); // Wait 20 seconds to update the channel again -} +/* + WriteMultipleFields + + Description: Writes values to fields 1,2,3,4 and status in a single ThingSpeak update every 20 seconds. + + Hardware: Arduino MKR GSM 1400 + + !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! + + Note: + - Requires MKRGSM library. + - Reqires GSM access (SIM card or credentials). + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +#include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros + +// PIN Number +const char PINNUMBER[] = SECRET_PIN; +// APN data +const char GPRS_APN[] = SECRET_GPRS_APN; +const char GPRS_LOGIN[] = SECRET_GPRS_LOGIN; +const char GPRS_PASSWORD[] = SECRET_GPRS_PASS; + +GSMClient client; +GPRS gprs; +GSM gsmAccess; + +unsigned long myChannelNumber = SECRET_CH_ID; +const char * myWriteAPIKey = SECRET_WRITE_APIKEY; + +// Initialize our values +int number1 = 0; +int number2 = random(0,100); +int number3 = random(0,100); +int number4 = random(0,100); +String myStatus = ""; + +void setup() { + Serial.begin(115200); //Initialize serial + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + Serial.println("Starting Arduino web client."); + boolean connected = false; + + // wait 10 seconds for connection: + delay(10000); + + while (!connected) { + if ((gsmAccess.begin(PINNUMBER) == GSM_READY) && + (gprs.attachGPRS(GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD) == GPRS_READY)) { + connected = true; + } else { + Serial.println("Not connected"); + delay(1000); + } + } + + Serial.println("connected"); + + ThingSpeak.begin(client); // Initialize ThingSpeak +} + +void loop() { + + // set the fields with the values + ThingSpeak.setField(1, number1); + ThingSpeak.setField(2, number2); + ThingSpeak.setField(3, number3); + ThingSpeak.setField(4, number4); + + // figure out the status message + if(number1 > number2){ + myStatus = String("field1 is greater than field2"); + } + else if(number1 < number2){ + myStatus = String("field1 is less than field2"); + } + else{ + myStatus = String("field1 equals field2"); + } + + // set the status + ThingSpeak.setStatus(myStatus); + + // write to the ThingSpeak channel + int x = ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey); + if(x == 200){ + Serial.println("Channel update successful."); + } + else{ + Serial.println("Problem updating channel. HTTP error code " + String(x)); + } + + // change the values + number1++; + if(number1 > 99){ + number1 = 0; + } + number2 = random(0,100); + number3 = random(0,100); + number4 = random(0,100); + + delay(20000); // Wait 20 seconds to update the channel again +} diff --git a/examples/ArduinoMKRGSM1400/WriteSingleField/WriteSingleField.ino b/examples/ArduinoMKRGSM1400/WriteSingleField/WriteSingleField.ino index e7ac089..74ea6f7 100644 --- a/examples/ArduinoMKRGSM1400/WriteSingleField/WriteSingleField.ino +++ b/examples/ArduinoMKRGSM1400/WriteSingleField/WriteSingleField.ino @@ -1,89 +1,91 @@ -/* - WriteSingleField - - Description: Writes a value to a channel on ThingSpeak every 20 seconds. - - Hardware: Arduino MKR GSM 1400 - - !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! - - Note: - - Requires MKRGSM library. - - Reqires GSM access (SIM card or credentials). - - ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and - analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. - - Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. - See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. - - For licensing information, see the accompanying license file. - - Copyright 2018, The MathWorks, Inc. -*/ - - -#include "ThingSpeak.h" -#include -#include "secrets.h" - -// PIN Number -const char PINNUMBER[] = SECRET_PIN; -// APN data -const char GPRS_APN[] = SECRET_GPRS_APN; -const char GPRS_LOGIN[] = SECRET_GPRS_LOGIN; -const char GPRS_PASSWORD[] = SECRET_GPRS_PASS; - -GSMClient client; -GPRS gprs; -GSM gsmAccess; - -unsigned long myChannelNumber = SECRET_CH_ID; -const char * myWriteAPIKey = SECRET_WRITE_APIKEY; - -int number = 0; - -void setup() { - Serial.begin(115200); //Initialize serial - - Serial.println("Starting Arduino web client."); - boolean connected = false; - - // wait 10 seconds for connection: - delay(10000); - - while (!connected) { - if ((gsmAccess.begin(PINNUMBER) == GSM_READY) && - (gprs.attachGPRS(GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD) == GPRS_READY)) { - connected = true; - } else { - Serial.println("Not connected"); - delay(1000); - } - } - - Serial.println("connected"); - - ThingSpeak.begin(client); // Initialize ThingSpeak -} - -void loop() { - - // Write to ThingSpeak. There are up to 8 fields in a channel, allowing you to store up to 8 different - // pieces of information in a channel. Here, we write to field 1. - int x = ThingSpeak.writeField(myChannelNumber, 1, number, myWriteAPIKey); - if(x == 200){ - Serial.println("Channel update successful."); - } - else{ - Serial.println("Problem updating channel. HTTP error code " + String(x)); - } - - // change the value - number++; - if(number > 99){ - number = 0; - } - - delay(20000); // Wait 20 seconds to update the channel again -} +/* + WriteSingleField + + Description: Writes a value to a channel on ThingSpeak every 20 seconds. + + Hardware: Arduino MKR GSM 1400 + + !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! + + Note: + - Requires MKRGSM library. + - Reqires GSM access (SIM card or credentials). + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +#include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros + +// PIN Number +const char PINNUMBER[] = SECRET_PIN; +// APN data +const char GPRS_APN[] = SECRET_GPRS_APN; +const char GPRS_LOGIN[] = SECRET_GPRS_LOGIN; +const char GPRS_PASSWORD[] = SECRET_GPRS_PASS; + +GSMClient client; +GPRS gprs; +GSM gsmAccess; + +unsigned long myChannelNumber = SECRET_CH_ID; +const char * myWriteAPIKey = SECRET_WRITE_APIKEY; + +int number = 0; + +void setup() { + Serial.begin(115200); //Initialize serial + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + Serial.println("Starting Arduino web client."); + boolean connected = false; + + // wait 10 seconds for connection: + delay(10000); + + while (!connected) { + if ((gsmAccess.begin(PINNUMBER) == GSM_READY) && + (gprs.attachGPRS(GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD) == GPRS_READY)) { + connected = true; + } else { + Serial.println("Not connected"); + delay(1000); + } + } + + Serial.println("connected"); + + ThingSpeak.begin(client); // Initialize ThingSpeak +} + +void loop() { + + // Write to ThingSpeak. There are up to 8 fields in a channel, allowing you to store up to 8 different + // pieces of information in a channel. Here, we write to field 1. + int x = ThingSpeak.writeField(myChannelNumber, 1, number, myWriteAPIKey); + if(x == 200){ + Serial.println("Channel update successful."); + } + else{ + Serial.println("Problem updating channel. HTTP error code " + String(x)); + } + + // change the value + number++; + if(number > 99){ + number = 0; + } + + delay(20000); // Wait 20 seconds to update the channel again +} diff --git a/examples/ArduinoMKRVIDOR4000/ReadField/ReadField.ino b/examples/ArduinoMKRVIDOR4000/ReadField/ReadField.ino index 8e8efee..083a179 100644 --- a/examples/ArduinoMKRVIDOR4000/ReadField/ReadField.ino +++ b/examples/ArduinoMKRVIDOR4000/ReadField/ReadField.ino @@ -1,107 +1,110 @@ -/* - ReadField - - Description: Demonstates reading from a public channel which requires no API key and reading from a private channel which requires a read API key. - The value read from the public channel is the current outside temperature at MathWorks headquaters in Natick, MA. The value from the - private channel is an example counter that increments every 10 seconds. - - Hardware: Arduino MKR VIDOR 4000 - - !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! - - Note: - - Requires WiFiNINA library - - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. - - ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and - analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. - - Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. - See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. - - For licensing information, see the accompanying license file. - - Copyright 2018, The MathWorks, Inc. -*/ - -#include "ThingSpeak.h" -#include -#include "secrets.h" - -char ssid[] = SECRET_SSID; // your network SSID (name) -char pass[] = SECRET_PASS; // your network password -int keyIndex = 0; // your network key Index number (needed only for WEP) -WiFiClient client; - -// Weather station channel details -unsigned long weatherStationChannelNumber = SECRET_CH_ID_WEATHER_STATION; -unsigned int temperatureFieldNumber = 4; - -// Counting channel details -unsigned long counterChannelNumber = SECRET_CH_ID_COUNTER; -const char * myCounterReadAPIKey = SECRET_READ_APIKEY_COUNTER; -unsigned int counterFieldNumber = 1; - -void setup() { - Serial.begin(115200); // Initialize serial - - // check for the WiFi module: - if (WiFi.status() == WL_NO_MODULE) { - Serial.println("Communication with WiFi module failed!"); - // don't continue - while (true); - } - - String fv = WiFi.firmwareVersion(); - if (fv != "1.0.0") { - Serial.println("Please upgrade the firmware"); - } - - ThingSpeak.begin(client); // Initialize ThingSpeak -} - -void loop() { - - int statusCode = 0; - - // Connect or reconnect to WiFi - if(WiFi.status() != WL_CONNECTED){ - Serial.print("Attempting to connect to SSID: "); - Serial.println(SECRET_SSID); - while(WiFi.status() != WL_CONNECTED){ - WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network - Serial.print("."); - delay(5000); - } - Serial.println("\nConnected"); - } - - // Read in field 4 of the public channel recording the temperature - float temperatureInF = ThingSpeak.readFloatField(weatherStationChannelNumber, temperatureFieldNumber); - - // Check the status of the read operation to see if it was successful - statusCode = ThingSpeak.getLastReadStatus(); - if(statusCode == 200){ - Serial.println("Temperature at MathWorks HQ: " + String(temperatureInF) + " deg F"); - } - else{ - Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); - } - - delay(15000); // No need to read the temperature too often. - - // Read in field 1 of the private channel which is a counter - long count = ThingSpeak.readLongField(counterChannelNumber, counterFieldNumber, myCounterReadAPIKey); - - // Check the status of the read operation to see if it was successful - statusCode = ThingSpeak.getLastReadStatus(); - if(statusCode == 200){ - Serial.println("Counter: " + String(count)); - } - else{ - Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); - } - - delay(15000); // No need to read the counter too often. - -} +/* + ReadField + + Description: Demonstates reading from a public channel which requires no API key and reading from a private channel which requires a read API key. + The value read from the public channel is the current outside temperature at MathWorks headquaters in Natick, MA. The value from the + private channel is an example counter that increments every 10 seconds. + + Hardware: Arduino MKR VIDOR 4000 + + !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! + + Note: + - Requires WiFiNINA library + - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +#include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros + +char ssid[] = SECRET_SSID; // your network SSID (name) +char pass[] = SECRET_PASS; // your network password +int keyIndex = 0; // your network key Index number (needed only for WEP) +WiFiClient client; + +// Weather station channel details +unsigned long weatherStationChannelNumber = SECRET_CH_ID_WEATHER_STATION; +unsigned int temperatureFieldNumber = 4; + +// Counting channel details +unsigned long counterChannelNumber = SECRET_CH_ID_COUNTER; +const char * myCounterReadAPIKey = SECRET_READ_APIKEY_COUNTER; +unsigned int counterFieldNumber = 1; + +void setup() { + Serial.begin(115200); // Initialize serial + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + // check for the WiFi module: + if (WiFi.status() == WL_NO_MODULE) { + Serial.println("Communication with WiFi module failed!"); + // don't continue + while (true); + } + + String fv = WiFi.firmwareVersion(); + if (fv != "1.0.0") { + Serial.println("Please upgrade the firmware"); + } + + ThingSpeak.begin(client); // Initialize ThingSpeak +} + +void loop() { + + int statusCode = 0; + + // Connect or reconnect to WiFi + if(WiFi.status() != WL_CONNECTED){ + Serial.print("Attempting to connect to SSID: "); + Serial.println(SECRET_SSID); + while(WiFi.status() != WL_CONNECTED){ + WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network + Serial.print("."); + delay(5000); + } + Serial.println("\nConnected"); + } + + // Read in field 4 of the public channel recording the temperature + float temperatureInF = ThingSpeak.readFloatField(weatherStationChannelNumber, temperatureFieldNumber); + + // Check the status of the read operation to see if it was successful + statusCode = ThingSpeak.getLastReadStatus(); + if(statusCode == 200){ + Serial.println("Temperature at MathWorks HQ: " + String(temperatureInF) + " deg F"); + } + else{ + Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); + } + + delay(15000); // No need to read the temperature too often. + + // Read in field 1 of the private channel which is a counter + long count = ThingSpeak.readLongField(counterChannelNumber, counterFieldNumber, myCounterReadAPIKey); + + // Check the status of the read operation to see if it was successful + statusCode = ThingSpeak.getLastReadStatus(); + if(statusCode == 200){ + Serial.println("Counter: " + String(count)); + } + else{ + Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); + } + + delay(15000); // No need to read the counter too often. + +} diff --git a/examples/ArduinoMKRVIDOR4000/WriteMultipleFields/WriteMultipleFields.ino b/examples/ArduinoMKRVIDOR4000/WriteMultipleFields/WriteMultipleFields.ino index a46c210..003f660 100644 --- a/examples/ArduinoMKRVIDOR4000/WriteMultipleFields/WriteMultipleFields.ino +++ b/examples/ArduinoMKRVIDOR4000/WriteMultipleFields/WriteMultipleFields.ino @@ -1,115 +1,118 @@ -/* - WriteMultipleFields - - Description: Writes values to fields 1,2,3,4 and status in a single ThingSpeak update every 20 seconds. - - Hardware: Arduino MKR VIDOR 4000 - - !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! - - Note: - - Requires WiFiNINA library - - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. - - ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and - analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. - - Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. - See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. - - For licensing information, see the accompanying license file. - - Copyright 2018, The MathWorks, Inc. -*/ - -#include "ThingSpeak.h" -#include -#include "secrets.h" - -char ssid[] = SECRET_SSID; // your network SSID (name) -char pass[] = SECRET_PASS; // your network password -int keyIndex = 0; // your network key Index number (needed only for WEP) -WiFiClient client; - -unsigned long myChannelNumber = SECRET_CH_ID; -const char * myWriteAPIKey = SECRET_WRITE_APIKEY; - -// Initialize our values -int number1 = 0; -int number2 = random(0,100); -int number3 = random(0,100); -int number4 = random(0,100); -String myStatus = ""; - -void setup() { - Serial.begin(115200); // Initialize serial - - // check for the WiFi module: - if (WiFi.status() == WL_NO_MODULE) { - Serial.println("Communication with WiFi module failed!"); - // don't continue - while (true); - } - - String fv = WiFi.firmwareVersion(); - if (fv != "1.0.0") { - Serial.println("Please upgrade the firmware"); - } - - ThingSpeak.begin(client); // Initialize ThingSpeak -} - -void loop() { - - // Connect or reconnect to WiFi - if(WiFi.status() != WL_CONNECTED){ - Serial.print("Attempting to connect to SSID: "); - Serial.println(SECRET_SSID); - while(WiFi.status() != WL_CONNECTED){ - WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network - Serial.print("."); - delay(5000); - } - Serial.println("\nConnected."); - } - - // set the fields with the values - ThingSpeak.setField(1, number1); - ThingSpeak.setField(2, number2); - ThingSpeak.setField(3, number3); - ThingSpeak.setField(4, number4); - - // figure out the status message - if(number1 > number2){ - myStatus = String("field1 is greater than field2"); - } - else if(number1 < number2){ - myStatus = String("field1 is less than field2"); - } - else{ - myStatus = String("field1 equals field2"); - } - - // set the status - ThingSpeak.setStatus(myStatus); - - // write to the ThingSpeak channel - int x = ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey); - if(x == 200){ - Serial.println("Channel update successful."); - } - else{ - Serial.println("Problem updating channel. HTTP error code " + String(x)); - } - - // change the values - number1++; - if(number1 > 99){ - number1 = 0; - } - number2 = random(0,100); - number3 = random(0,100); - number4 = random(0,100); - - delay(20000); // ThingSpeak will only accept updates every 20 seconds. -} +/* + WriteMultipleFields + + Description: Writes values to fields 1,2,3,4 and status in a single ThingSpeak update every 20 seconds. + + Hardware: Arduino MKR VIDOR 4000 + + !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! + + Note: + - Requires WiFiNINA library + - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +#include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros + +char ssid[] = SECRET_SSID; // your network SSID (name) +char pass[] = SECRET_PASS; // your network password +int keyIndex = 0; // your network key Index number (needed only for WEP) +WiFiClient client; + +unsigned long myChannelNumber = SECRET_CH_ID; +const char * myWriteAPIKey = SECRET_WRITE_APIKEY; + +// Initialize our values +int number1 = 0; +int number2 = random(0,100); +int number3 = random(0,100); +int number4 = random(0,100); +String myStatus = ""; + +void setup() { + Serial.begin(115200); // Initialize serial + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + // check for the WiFi module: + if (WiFi.status() == WL_NO_MODULE) { + Serial.println("Communication with WiFi module failed!"); + // don't continue + while (true); + } + + String fv = WiFi.firmwareVersion(); + if (fv != "1.0.0") { + Serial.println("Please upgrade the firmware"); + } + + ThingSpeak.begin(client); // Initialize ThingSpeak +} + +void loop() { + + // Connect or reconnect to WiFi + if(WiFi.status() != WL_CONNECTED){ + Serial.print("Attempting to connect to SSID: "); + Serial.println(SECRET_SSID); + while(WiFi.status() != WL_CONNECTED){ + WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network + Serial.print("."); + delay(5000); + } + Serial.println("\nConnected."); + } + + // set the fields with the values + ThingSpeak.setField(1, number1); + ThingSpeak.setField(2, number2); + ThingSpeak.setField(3, number3); + ThingSpeak.setField(4, number4); + + // figure out the status message + if(number1 > number2){ + myStatus = String("field1 is greater than field2"); + } + else if(number1 < number2){ + myStatus = String("field1 is less than field2"); + } + else{ + myStatus = String("field1 equals field2"); + } + + // set the status + ThingSpeak.setStatus(myStatus); + + // write to the ThingSpeak channel + int x = ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey); + if(x == 200){ + Serial.println("Channel update successful."); + } + else{ + Serial.println("Problem updating channel. HTTP error code " + String(x)); + } + + // change the values + number1++; + if(number1 > 99){ + number1 = 0; + } + number2 = random(0,100); + number3 = random(0,100); + number4 = random(0,100); + + delay(20000); // ThingSpeak will only accept updates every 20 seconds. +} diff --git a/examples/ArduinoMKRVIDOR4000/WriteSingleField/WriteSingleField.ino b/examples/ArduinoMKRVIDOR4000/WriteSingleField/WriteSingleField.ino index e2ae6a2..7f05c2b 100644 --- a/examples/ArduinoMKRVIDOR4000/WriteSingleField/WriteSingleField.ino +++ b/examples/ArduinoMKRVIDOR4000/WriteSingleField/WriteSingleField.ino @@ -1,89 +1,92 @@ -/* - WriteSingleField - - Description: Writes a value to a channel on ThingSpeak every 20 seconds. - - Hardware: Arduino MKR VIDOR 4000 - - !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! - - Note: - - Requires WiFiNINA library - - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. - - ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and - analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. - - Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. - See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. - - For licensing information, see the accompanying license file. - - Copyright 2018, The MathWorks, Inc. -*/ - -#include "ThingSpeak.h" -#include -#include "secrets.h" - -char ssid[] = SECRET_SSID; // your network SSID (name) -char pass[] = SECRET_PASS; // your network password -int keyIndex = 0; // your network key Index number (needed only for WEP) -WiFiClient client; - -unsigned long myChannelNumber = SECRET_CH_ID; -const char * myWriteAPIKey = SECRET_WRITE_APIKEY; - -int number = 0; - -void setup() { - Serial.begin(115200); // Initialize serial - - // check for the WiFi module: - if (WiFi.status() == WL_NO_MODULE) { - Serial.println("Communication with WiFi module failed!"); - // don't continue - while (true); - } - - String fv = WiFi.firmwareVersion(); - if (fv != "1.0.0") { - Serial.println("Please upgrade the firmware"); - } - - ThingSpeak.begin(client); // Initialize ThingSpeak -} - -void loop() { - - // Connect or reconnect to WiFi - if(WiFi.status() != WL_CONNECTED){ - Serial.print("Attempting to connect to SSID: "); - Serial.println(SECRET_SSID); - while(WiFi.status() != WL_CONNECTED){ - WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network - Serial.print("."); - delay(5000); - } - Serial.println("\nConnected."); - } - - - // Write to ThingSpeak. There are up to 8 fields in a channel, allowing you to store up to 8 different - // pieces of information in a channel. Here, we write to field 1. - int x = ThingSpeak.writeField(myChannelNumber, 1, number, myWriteAPIKey); - if(x == 200){ - Serial.println("Channel update successful."); - } - else{ - Serial.println("Problem updating channel. HTTP error code " + String(x)); - } - - // change the value - number++; - if(number > 99){ - number = 0; - } - - delay(20000); // ThingSpeak will only accept updates every 20 seconds. -} +/* + WriteSingleField + + Description: Writes a value to a channel on ThingSpeak every 20 seconds. + + Hardware: Arduino MKR VIDOR 4000 + + !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! + + Note: + - Requires WiFiNINA library + - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +#include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros + +char ssid[] = SECRET_SSID; // your network SSID (name) +char pass[] = SECRET_PASS; // your network password +int keyIndex = 0; // your network key Index number (needed only for WEP) +WiFiClient client; + +unsigned long myChannelNumber = SECRET_CH_ID; +const char * myWriteAPIKey = SECRET_WRITE_APIKEY; + +int number = 0; + +void setup() { + Serial.begin(115200); // Initialize serial + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + // check for the WiFi module: + if (WiFi.status() == WL_NO_MODULE) { + Serial.println("Communication with WiFi module failed!"); + // don't continue + while (true); + } + + String fv = WiFi.firmwareVersion(); + if (fv != "1.0.0") { + Serial.println("Please upgrade the firmware"); + } + + ThingSpeak.begin(client); // Initialize ThingSpeak +} + +void loop() { + + // Connect or reconnect to WiFi + if(WiFi.status() != WL_CONNECTED){ + Serial.print("Attempting to connect to SSID: "); + Serial.println(SECRET_SSID); + while(WiFi.status() != WL_CONNECTED){ + WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network + Serial.print("."); + delay(5000); + } + Serial.println("\nConnected."); + } + + + // Write to ThingSpeak. There are up to 8 fields in a channel, allowing you to store up to 8 different + // pieces of information in a channel. Here, we write to field 1. + int x = ThingSpeak.writeField(myChannelNumber, 1, number, myWriteAPIKey); + if(x == 200){ + Serial.println("Channel update successful."); + } + else{ + Serial.println("Problem updating channel. HTTP error code " + String(x)); + } + + // change the value + number++; + if(number > 99){ + number = 0; + } + + delay(20000); // ThingSpeak will only accept updates every 20 seconds. +} diff --git a/examples/ArduinoMKRWiFi1010/ReadField/ReadField.ino b/examples/ArduinoMKRWiFi1010/ReadField/ReadField.ino index 22e138c..066630a 100644 --- a/examples/ArduinoMKRWiFi1010/ReadField/ReadField.ino +++ b/examples/ArduinoMKRWiFi1010/ReadField/ReadField.ino @@ -1,107 +1,110 @@ -/* - ReadField - - Description: Demonstates reading from a public channel which requires no API key and reading from a private channel which requires a read API key. - The value read from the public channel is the current outside temperature at MathWorks headquaters in Natick, MA. The value from the - private channel is an example counter that increments every 10 seconds. - - Hardware: Arduino MKR WiFi 1010 - - !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! - - Note: - - Requires WiFiNINA library - - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. - - ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and - analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. - - Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. - See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. - - For licensing information, see the accompanying license file. - - Copyright 2018, The MathWorks, Inc. -*/ - -#include "ThingSpeak.h" -#include -#include "secrets.h" - -char ssid[] = SECRET_SSID; // your network SSID (name) -char pass[] = SECRET_PASS; // your network password -int keyIndex = 0; // your network key Index number (needed only for WEP) -WiFiClient client; - -// Weather station channel details -unsigned long weatherStationChannelNumber = SECRET_CH_ID_WEATHER_STATION; -unsigned int temperatureFieldNumber = 4; - -// Counting channel details -unsigned long counterChannelNumber = SECRET_CH_ID_COUNTER; -const char * myCounterReadAPIKey = SECRET_READ_APIKEY_COUNTER; -unsigned int counterFieldNumber = 1; - -void setup() { - Serial.begin(115200); // Initialize serial - - // check for the WiFi module: - if (WiFi.status() == WL_NO_MODULE) { - Serial.println("Communication with WiFi module failed!"); - // don't continue - while (true); - } - - String fv = WiFi.firmwareVersion(); - if (fv != "1.0.0") { - Serial.println("Please upgrade the firmware"); - } - - ThingSpeak.begin(client); //Initialize ThingSpeak -} - -void loop() { - - int statusCode = 0; - - // Connect or reconnect to WiFi - if(WiFi.status() != WL_CONNECTED){ - Serial.print("Attempting to connect to SSID: "); - Serial.println(SECRET_SSID); - while(WiFi.status() != WL_CONNECTED){ - WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network - Serial.print("."); - delay(5000); - } - Serial.println("\nConnected"); - } - - // Read in field 4 of the public channel recording the temperature - float temperatureInF = ThingSpeak.readFloatField(weatherStationChannelNumber, temperatureFieldNumber); - - // Check the status of the read operation to see if it was successful - statusCode = ThingSpeak.getLastReadStatus(); - if(statusCode == 200){ - Serial.println("Temperature at MathWorks HQ: " + String(temperatureInF) + " deg F"); - } - else{ - Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); - } - - delay(15000); // No need to read the temperature too often. - - // Read in field 1 of the private channel which is a counter - long count = ThingSpeak.readLongField(counterChannelNumber, counterFieldNumber, myCounterReadAPIKey); - - // Check the status of the read operation to see if it was successful - statusCode = ThingSpeak.getLastReadStatus(); - if(statusCode == 200){ - Serial.println("Counter: " + String(count)); - } - else{ - Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); - } - - delay(15000); // No need to read the counter too often. - -} +/* + ReadField + + Description: Demonstates reading from a public channel which requires no API key and reading from a private channel which requires a read API key. + The value read from the public channel is the current outside temperature at MathWorks headquaters in Natick, MA. The value from the + private channel is an example counter that increments every 10 seconds. + + Hardware: Arduino MKR WiFi 1010 + + !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! + + Note: + - Requires WiFiNINA library + - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +#include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros + +char ssid[] = SECRET_SSID; // your network SSID (name) +char pass[] = SECRET_PASS; // your network password +int keyIndex = 0; // your network key Index number (needed only for WEP) +WiFiClient client; + +// Weather station channel details +unsigned long weatherStationChannelNumber = SECRET_CH_ID_WEATHER_STATION; +unsigned int temperatureFieldNumber = 4; + +// Counting channel details +unsigned long counterChannelNumber = SECRET_CH_ID_COUNTER; +const char * myCounterReadAPIKey = SECRET_READ_APIKEY_COUNTER; +unsigned int counterFieldNumber = 1; + +void setup() { + Serial.begin(115200); // Initialize serial + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + // check for the WiFi module: + if (WiFi.status() == WL_NO_MODULE) { + Serial.println("Communication with WiFi module failed!"); + // don't continue + while (true); + } + + String fv = WiFi.firmwareVersion(); + if (fv != "1.0.0") { + Serial.println("Please upgrade the firmware"); + } + + ThingSpeak.begin(client); //Initialize ThingSpeak +} + +void loop() { + + int statusCode = 0; + + // Connect or reconnect to WiFi + if(WiFi.status() != WL_CONNECTED){ + Serial.print("Attempting to connect to SSID: "); + Serial.println(SECRET_SSID); + while(WiFi.status() != WL_CONNECTED){ + WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network + Serial.print("."); + delay(5000); + } + Serial.println("\nConnected"); + } + + // Read in field 4 of the public channel recording the temperature + float temperatureInF = ThingSpeak.readFloatField(weatherStationChannelNumber, temperatureFieldNumber); + + // Check the status of the read operation to see if it was successful + statusCode = ThingSpeak.getLastReadStatus(); + if(statusCode == 200){ + Serial.println("Temperature at MathWorks HQ: " + String(temperatureInF) + " deg F"); + } + else{ + Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); + } + + delay(15000); // No need to read the temperature too often. + + // Read in field 1 of the private channel which is a counter + long count = ThingSpeak.readLongField(counterChannelNumber, counterFieldNumber, myCounterReadAPIKey); + + // Check the status of the read operation to see if it was successful + statusCode = ThingSpeak.getLastReadStatus(); + if(statusCode == 200){ + Serial.println("Counter: " + String(count)); + } + else{ + Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); + } + + delay(15000); // No need to read the counter too often. + +} diff --git a/examples/ArduinoMKRWiFi1010/WriteMultipleFields/WriteMultipleFields.ino b/examples/ArduinoMKRWiFi1010/WriteMultipleFields/WriteMultipleFields.ino index 9e82078..aba7db5 100644 --- a/examples/ArduinoMKRWiFi1010/WriteMultipleFields/WriteMultipleFields.ino +++ b/examples/ArduinoMKRWiFi1010/WriteMultipleFields/WriteMultipleFields.ino @@ -1,115 +1,118 @@ -/* - WriteMultipleFields - - Description: Writes values to fields 1,2,3,4 and status in a single ThingSpeak update every 20 seconds. - - Hardware: Arduino MKR WiFi 1010 - - !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! - - Note: - - Requires WiFiNINA library - - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. - - ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and - analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. - - Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. - See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. - - For licensing information, see the accompanying license file. - - Copyright 2018, The MathWorks, Inc. -*/ - -#include "ThingSpeak.h" -#include -#include "secrets.h" - -char ssid[] = SECRET_SSID; // your network SSID (name) -char pass[] = SECRET_PASS; // your network password -int keyIndex = 0; // your network key Index number (needed only for WEP) -WiFiClient client; - -unsigned long myChannelNumber = SECRET_CH_ID; -const char * myWriteAPIKey = SECRET_WRITE_APIKEY; - -// Initialize our values -int number1 = 0; -int number2 = random(0,100); -int number3 = random(0,100); -int number4 = random(0,100); -String myStatus = ""; - -void setup() { - Serial.begin(115200); // Initialize serial - - // check for the WiFi module: - if (WiFi.status() == WL_NO_MODULE) { - Serial.println("Communication with WiFi module failed!"); - // don't continue - while (true); - } - - String fv = WiFi.firmwareVersion(); - if (fv != "1.0.0") { - Serial.println("Please upgrade the firmware"); - } - - ThingSpeak.begin(client); //Initialize ThingSpeak -} - -void loop() { - - // Connect or reconnect to WiFi - if(WiFi.status() != WL_CONNECTED){ - Serial.print("Attempting to connect to SSID: "); - Serial.println(SECRET_SSID); - while(WiFi.status() != WL_CONNECTED){ - WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network - Serial.print("."); - delay(5000); - } - Serial.println("\nConnected."); - } - - // set the fields with the values - ThingSpeak.setField(1, number1); - ThingSpeak.setField(2, number2); - ThingSpeak.setField(3, number3); - ThingSpeak.setField(4, number4); - - // figure out the status message - if(number1 > number2){ - myStatus = String("field1 is greater than field2"); - } - else if(number1 < number2){ - myStatus = String("field1 is less than field2"); - } - else{ - myStatus = String("field1 equals field2"); - } - - // set the status - ThingSpeak.setStatus(myStatus); - - // write to the ThingSpeak channel - int x = ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey); - if(x == 200){ - Serial.println("Channel update successful."); - } - else{ - Serial.println("Problem updating channel. HTTP error code " + String(x)); - } - - // change the values - number1++; - if(number1 > 99){ - number1 = 0; - } - number2 = random(0,100); - number3 = random(0,100); - number4 = random(0,100); - - delay(20000); // Wait 20 seconds to update the channel again -} +/* + WriteMultipleFields + + Description: Writes values to fields 1,2,3,4 and status in a single ThingSpeak update every 20 seconds. + + Hardware: Arduino MKR WiFi 1010 + + !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! + + Note: + - Requires WiFiNINA library + - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +#include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros + +char ssid[] = SECRET_SSID; // your network SSID (name) +char pass[] = SECRET_PASS; // your network password +int keyIndex = 0; // your network key Index number (needed only for WEP) +WiFiClient client; + +unsigned long myChannelNumber = SECRET_CH_ID; +const char * myWriteAPIKey = SECRET_WRITE_APIKEY; + +// Initialize our values +int number1 = 0; +int number2 = random(0,100); +int number3 = random(0,100); +int number4 = random(0,100); +String myStatus = ""; + +void setup() { + Serial.begin(115200); // Initialize serial + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + // check for the WiFi module: + if (WiFi.status() == WL_NO_MODULE) { + Serial.println("Communication with WiFi module failed!"); + // don't continue + while (true); + } + + String fv = WiFi.firmwareVersion(); + if (fv != "1.0.0") { + Serial.println("Please upgrade the firmware"); + } + + ThingSpeak.begin(client); //Initialize ThingSpeak +} + +void loop() { + + // Connect or reconnect to WiFi + if(WiFi.status() != WL_CONNECTED){ + Serial.print("Attempting to connect to SSID: "); + Serial.println(SECRET_SSID); + while(WiFi.status() != WL_CONNECTED){ + WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network + Serial.print("."); + delay(5000); + } + Serial.println("\nConnected."); + } + + // set the fields with the values + ThingSpeak.setField(1, number1); + ThingSpeak.setField(2, number2); + ThingSpeak.setField(3, number3); + ThingSpeak.setField(4, number4); + + // figure out the status message + if(number1 > number2){ + myStatus = String("field1 is greater than field2"); + } + else if(number1 < number2){ + myStatus = String("field1 is less than field2"); + } + else{ + myStatus = String("field1 equals field2"); + } + + // set the status + ThingSpeak.setStatus(myStatus); + + // write to the ThingSpeak channel + int x = ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey); + if(x == 200){ + Serial.println("Channel update successful."); + } + else{ + Serial.println("Problem updating channel. HTTP error code " + String(x)); + } + + // change the values + number1++; + if(number1 > 99){ + number1 = 0; + } + number2 = random(0,100); + number3 = random(0,100); + number4 = random(0,100); + + delay(20000); // Wait 20 seconds to update the channel again +} diff --git a/examples/ArduinoMKRWiFi1010/WriteSingleField/WriteSingleField.ino b/examples/ArduinoMKRWiFi1010/WriteSingleField/WriteSingleField.ino index a5ecb43..6087c7b 100644 --- a/examples/ArduinoMKRWiFi1010/WriteSingleField/WriteSingleField.ino +++ b/examples/ArduinoMKRWiFi1010/WriteSingleField/WriteSingleField.ino @@ -1,88 +1,91 @@ -/* - WriteSingleField - - Description: Writes a value to a channel on ThingSpeak every 20 seconds. - - Hardware: Arduino MKR WiFi 1010 - - !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! - - Note: - - Requires WiFiNINA library - - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. - - ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and - analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. - - Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. - See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. - - For licensing information, see the accompanying license file. - - Copyright 2018, The MathWorks, Inc. -*/ - -#include "ThingSpeak.h" -#include -#include "secrets.h" - -char ssid[] = SECRET_SSID; // your network SSID (name) -char pass[] = SECRET_PASS; // your network password -int keyIndex = 0; // your network key Index number (needed only for WEP) -WiFiClient client; - -unsigned long myChannelNumber = SECRET_CH_ID; -const char * myWriteAPIKey = SECRET_WRITE_APIKEY; - -int number = 0; - -void setup() { - Serial.begin(115200); // Initialize serial - - // check for the WiFi module: - if (WiFi.status() == WL_NO_MODULE) { - Serial.println("Communication with WiFi module failed!"); - // don't continue - while (true); - } - - String fv = WiFi.firmwareVersion(); - if (fv != "1.0.0") { - Serial.println("Please upgrade the firmware"); - } - - ThingSpeak.begin(client); //Initialize ThingSpeak -} - -void loop() { - - // Connect or reconnect to WiFi - if(WiFi.status() != WL_CONNECTED){ - Serial.print("Attempting to connect to SSID: "); - Serial.println(SECRET_SSID); - while(WiFi.status() != WL_CONNECTED){ - WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network - Serial.print("."); - delay(5000); - } - Serial.println("\nConnected."); - } - - // Write to ThingSpeak. There are up to 8 fields in a channel, allowing you to store up to 8 different - // pieces of information in a channel. Here, we write to field 1. - int x = ThingSpeak.writeField(myChannelNumber, 1, number, myWriteAPIKey); - if(x == 200){ - Serial.println("Channel update successful."); - } - else{ - Serial.println("Problem updating channel. HTTP error code " + String(x)); - } - - // change the value - number++; - if(number > 99){ - number = 0; - } - - delay(20000); // Wait 20 seconds to update the channel again -} +/* + WriteSingleField + + Description: Writes a value to a channel on ThingSpeak every 20 seconds. + + Hardware: Arduino MKR WiFi 1010 + + !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! + + Note: + - Requires WiFiNINA library + - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +#include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros + +char ssid[] = SECRET_SSID; // your network SSID (name) +char pass[] = SECRET_PASS; // your network password +int keyIndex = 0; // your network key Index number (needed only for WEP) +WiFiClient client; + +unsigned long myChannelNumber = SECRET_CH_ID; +const char * myWriteAPIKey = SECRET_WRITE_APIKEY; + +int number = 0; + +void setup() { + Serial.begin(115200); // Initialize serial + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + // check for the WiFi module: + if (WiFi.status() == WL_NO_MODULE) { + Serial.println("Communication with WiFi module failed!"); + // don't continue + while (true); + } + + String fv = WiFi.firmwareVersion(); + if (fv != "1.0.0") { + Serial.println("Please upgrade the firmware"); + } + + ThingSpeak.begin(client); //Initialize ThingSpeak +} + +void loop() { + + // Connect or reconnect to WiFi + if(WiFi.status() != WL_CONNECTED){ + Serial.print("Attempting to connect to SSID: "); + Serial.println(SECRET_SSID); + while(WiFi.status() != WL_CONNECTED){ + WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network + Serial.print("."); + delay(5000); + } + Serial.println("\nConnected."); + } + + // Write to ThingSpeak. There are up to 8 fields in a channel, allowing you to store up to 8 different + // pieces of information in a channel. Here, we write to field 1. + int x = ThingSpeak.writeField(myChannelNumber, 1, number, myWriteAPIKey); + if(x == 200){ + Serial.println("Channel update successful."); + } + else{ + Serial.println("Problem updating channel. HTTP error code " + String(x)); + } + + // change the value + number++; + if(number > 99){ + number = 0; + } + + delay(20000); // Wait 20 seconds to update the channel again +} diff --git a/examples/ArduinoUnoWiFi Rev2/ReadField/ReadField.ino b/examples/ArduinoUnoWiFi Rev2/ReadField/ReadField.ino index e022b33..02f5577 100644 --- a/examples/ArduinoUnoWiFi Rev2/ReadField/ReadField.ino +++ b/examples/ArduinoUnoWiFi Rev2/ReadField/ReadField.ino @@ -1,107 +1,110 @@ -/* - ReadField - - Description: Demonstates reading from a public channel which requires no API key and reading from a private channel which requires a read API key. - The value read from the public channel is the current outside temperature at MathWorks headquaters in Natick, MA. The value from the - private channel is an example counter that increments every 10 seconds. - - Hardware: Arduino Uno WiFi Rev2 - - !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! - - Note: - - Requires WiFiNINA library. - - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. - - ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and - analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. - - Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. - See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. - - For licensing information, see the accompanying license file. - - Copyright 2019, The MathWorks, Inc. -*/ - -#include "ThingSpeak.h" -#include -#include "secrets.h" - -char ssid[] = SECRET_SSID; // your network SSID (name) -char pass[] = SECRET_PASS; // your network password -int keyIndex = 0; // your network key Index number (needed only for WEP) -WiFiClient client; - -// Weather station channel details -unsigned long weatherStationChannelNumber = SECRET_CH_ID_WEATHER_STATION; -unsigned int temperatureFieldNumber = 4; - -// Counting channel details -unsigned long counterChannelNumber = SECRET_CH_ID_COUNTER; -const char * myCounterReadAPIKey = SECRET_READ_APIKEY_COUNTER; -unsigned int counterFieldNumber = 1; - -void setup() { - Serial.begin(115200); // Initialize serial - - // check for the WiFi module: - if (WiFi.status() == WL_NO_MODULE) { - Serial.println("Communication with WiFi module failed!"); - // don't continue - while (true); - } - - String fv = WiFi.firmwareVersion(); - if (fv != "1.0.0") { - Serial.println("Please upgrade the firmware"); - } - - ThingSpeak.begin(client); //Initialize ThingSpeak -} - -void loop() { - - int statusCode = 0; - - // Connect or reconnect to WiFi - if(WiFi.status() != WL_CONNECTED){ - Serial.print("Attempting to connect to SSID: "); - Serial.println(SECRET_SSID); - while(WiFi.status() != WL_CONNECTED){ - WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network - Serial.print("."); - delay(5000); - } - Serial.println("\nConnected"); - } - - // Read in field 4 of the public channel recording the temperature - float temperatureInF = ThingSpeak.readFloatField(weatherStationChannelNumber, temperatureFieldNumber); - - // Check the status of the read operation to see if it was successful - statusCode = ThingSpeak.getLastReadStatus(); - if(statusCode == 200){ - Serial.println("Temperature at MathWorks HQ: " + String(temperatureInF) + " deg F"); - } - else{ - Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); - } - - delay(15000); // No need to read the temperature too often. - - // Read in field 1 of the private channel which is a counter - long count = ThingSpeak.readLongField(counterChannelNumber, counterFieldNumber, myCounterReadAPIKey); - - // Check the status of the read operation to see if it was successful - statusCode = ThingSpeak.getLastReadStatus(); - if(statusCode == 200){ - Serial.println("Counter: " + String(count)); - } - else{ - Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); - } - - delay(15000); // No need to read the counter too often. - -} +/* + ReadField + + Description: Demonstates reading from a public channel which requires no API key and reading from a private channel which requires a read API key. + The value read from the public channel is the current outside temperature at MathWorks headquaters in Natick, MA. The value from the + private channel is an example counter that increments every 10 seconds. + + Hardware: Arduino Uno WiFi Rev2 + + !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! + + Note: + - Requires WiFiNINA library. + - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +#include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros + +char ssid[] = SECRET_SSID; // your network SSID (name) +char pass[] = SECRET_PASS; // your network password +int keyIndex = 0; // your network key Index number (needed only for WEP) +WiFiClient client; + +// Weather station channel details +unsigned long weatherStationChannelNumber = SECRET_CH_ID_WEATHER_STATION; +unsigned int temperatureFieldNumber = 4; + +// Counting channel details +unsigned long counterChannelNumber = SECRET_CH_ID_COUNTER; +const char * myCounterReadAPIKey = SECRET_READ_APIKEY_COUNTER; +unsigned int counterFieldNumber = 1; + +void setup() { + Serial.begin(115200); // Initialize serial + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + // check for the WiFi module: + if (WiFi.status() == WL_NO_MODULE) { + Serial.println("Communication with WiFi module failed!"); + // don't continue + while (true); + } + + String fv = WiFi.firmwareVersion(); + if (fv != "1.0.0") { + Serial.println("Please upgrade the firmware"); + } + + ThingSpeak.begin(client); //Initialize ThingSpeak +} + +void loop() { + + int statusCode = 0; + + // Connect or reconnect to WiFi + if(WiFi.status() != WL_CONNECTED){ + Serial.print("Attempting to connect to SSID: "); + Serial.println(SECRET_SSID); + while(WiFi.status() != WL_CONNECTED){ + WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network + Serial.print("."); + delay(5000); + } + Serial.println("\nConnected"); + } + + // Read in field 4 of the public channel recording the temperature + float temperatureInF = ThingSpeak.readFloatField(weatherStationChannelNumber, temperatureFieldNumber); + + // Check the status of the read operation to see if it was successful + statusCode = ThingSpeak.getLastReadStatus(); + if(statusCode == 200){ + Serial.println("Temperature at MathWorks HQ: " + String(temperatureInF) + " deg F"); + } + else{ + Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); + } + + delay(15000); // No need to read the temperature too often. + + // Read in field 1 of the private channel which is a counter + long count = ThingSpeak.readLongField(counterChannelNumber, counterFieldNumber, myCounterReadAPIKey); + + // Check the status of the read operation to see if it was successful + statusCode = ThingSpeak.getLastReadStatus(); + if(statusCode == 200){ + Serial.println("Counter: " + String(count)); + } + else{ + Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); + } + + delay(15000); // No need to read the counter too often. + +} diff --git a/examples/ArduinoUnoWiFi Rev2/WriteMultipleFields/WriteMultipleFields.ino b/examples/ArduinoUnoWiFi Rev2/WriteMultipleFields/WriteMultipleFields.ino index 587505f..d7e5222 100644 --- a/examples/ArduinoUnoWiFi Rev2/WriteMultipleFields/WriteMultipleFields.ino +++ b/examples/ArduinoUnoWiFi Rev2/WriteMultipleFields/WriteMultipleFields.ino @@ -1,115 +1,118 @@ -/* - WriteMultipleFields - - Description: Writes values to fields 1,2,3,4 and status in a single ThingSpeak update every 20 seconds. - - Hardware: Arduino Uno WiFi Rev2 - - !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! - - Note: - - Requires WiFiNINA library. - - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. - - ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and - analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. - - Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. - See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. - - For licensing information, see the accompanying license file. - - Copyright 2018, The MathWorks, Inc. -*/ - -#include "ThingSpeak.h" -#include -#include "secrets.h" - -char ssid[] = SECRET_SSID; // your network SSID (name) -char pass[] = SECRET_PASS; // your network password -int keyIndex = 0; // your network key Index number (needed only for WEP) -WiFiClient client; - -unsigned long myChannelNumber = SECRET_CH_ID; -const char * myWriteAPIKey = SECRET_WRITE_APIKEY; - -// Initialize our values -int number1 = 0; -int number2 = random(0,100); -int number3 = random(0,100); -int number4 = random(0,100); -String myStatus = ""; - -void setup() { - Serial.begin(115200); // Initialize serial - - // check for the WiFi module: - if (WiFi.status() == WL_NO_MODULE) { - Serial.println("Communication with WiFi module failed!"); - // don't continue - while (true); - } - - String fv = WiFi.firmwareVersion(); - if (fv != "1.0.0") { - Serial.println("Please upgrade the firmware"); - } - - ThingSpeak.begin(client); //Initialize ThingSpeak -} - -void loop() { - - // Connect or reconnect to WiFi - if(WiFi.status() != WL_CONNECTED){ - Serial.print("Attempting to connect to SSID: "); - Serial.println(SECRET_SSID); - while(WiFi.status() != WL_CONNECTED){ - WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network - Serial.print("."); - delay(5000); - } - Serial.println("\nConnected."); - } - - // set the fields with the values - ThingSpeak.setField(1, number1); - ThingSpeak.setField(2, number2); - ThingSpeak.setField(3, number3); - ThingSpeak.setField(4, number4); - - // figure out the status message - if(number1 > number2){ - myStatus = String("field1 is greater than field2"); - } - else if(number1 < number2){ - myStatus = String("field1 is less than field2"); - } - else{ - myStatus = String("field1 equals field2"); - } - - // set the status - ThingSpeak.setStatus(myStatus); - - // write to the ThingSpeak channel - int x = ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey); - if(x == 200){ - Serial.println("Channel update successful."); - } - else{ - Serial.println("Problem updating channel. HTTP error code " + String(x)); - } - - // change the values - number1++; - if(number1 > 99){ - number1 = 0; - } - number2 = random(0,100); - number3 = random(0,100); - number4 = random(0,100); - - delay(20000); // Wait 20 seconds to update the channel again -} +/* + WriteMultipleFields + + Description: Writes values to fields 1,2,3,4 and status in a single ThingSpeak update every 20 seconds. + + Hardware: Arduino Uno WiFi Rev2 + + !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! + + Note: + - Requires WiFiNINA library. + - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +#include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros + +char ssid[] = SECRET_SSID; // your network SSID (name) +char pass[] = SECRET_PASS; // your network password +int keyIndex = 0; // your network key Index number (needed only for WEP) +WiFiClient client; + +unsigned long myChannelNumber = SECRET_CH_ID; +const char * myWriteAPIKey = SECRET_WRITE_APIKEY; + +// Initialize our values +int number1 = 0; +int number2 = random(0,100); +int number3 = random(0,100); +int number4 = random(0,100); +String myStatus = ""; + +void setup() { + Serial.begin(115200); // Initialize serial + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + // check for the WiFi module: + if (WiFi.status() == WL_NO_MODULE) { + Serial.println("Communication with WiFi module failed!"); + // don't continue + while (true); + } + + String fv = WiFi.firmwareVersion(); + if (fv != "1.0.0") { + Serial.println("Please upgrade the firmware"); + } + + ThingSpeak.begin(client); //Initialize ThingSpeak +} + +void loop() { + + // Connect or reconnect to WiFi + if(WiFi.status() != WL_CONNECTED){ + Serial.print("Attempting to connect to SSID: "); + Serial.println(SECRET_SSID); + while(WiFi.status() != WL_CONNECTED){ + WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network + Serial.print("."); + delay(5000); + } + Serial.println("\nConnected."); + } + + // set the fields with the values + ThingSpeak.setField(1, number1); + ThingSpeak.setField(2, number2); + ThingSpeak.setField(3, number3); + ThingSpeak.setField(4, number4); + + // figure out the status message + if(number1 > number2){ + myStatus = String("field1 is greater than field2"); + } + else if(number1 < number2){ + myStatus = String("field1 is less than field2"); + } + else{ + myStatus = String("field1 equals field2"); + } + + // set the status + ThingSpeak.setStatus(myStatus); + + // write to the ThingSpeak channel + int x = ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey); + if(x == 200){ + Serial.println("Channel update successful."); + } + else{ + Serial.println("Problem updating channel. HTTP error code " + String(x)); + } + + // change the values + number1++; + if(number1 > 99){ + number1 = 0; + } + number2 = random(0,100); + number3 = random(0,100); + number4 = random(0,100); + + delay(20000); // Wait 20 seconds to update the channel again +} diff --git a/examples/ArduinoUnoWiFi Rev2/WriteSingleField/WriteSingleField.ino b/examples/ArduinoUnoWiFi Rev2/WriteSingleField/WriteSingleField.ino index 848cbc7..a4943ac 100644 --- a/examples/ArduinoUnoWiFi Rev2/WriteSingleField/WriteSingleField.ino +++ b/examples/ArduinoUnoWiFi Rev2/WriteSingleField/WriteSingleField.ino @@ -1,88 +1,91 @@ -/* - WriteSingleField - - Description: Writes a value to a channel on ThingSpeak every 20 seconds. - - Hardware: Arduino Uno WiFi Rev2 - - !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! - - Note: - - Requires WiFiNINA library. - - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. - - ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and - analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. - - Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. - See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. - - For licensing information, see the accompanying license file. - - Copyright 2018, The MathWorks, Inc. -*/ - -#include "ThingSpeak.h" -#include -#include "secrets.h" - -char ssid[] = SECRET_SSID; // your network SSID (name) -char pass[] = SECRET_PASS; // your network password -int keyIndex = 0; // your network key Index number (needed only for WEP) -WiFiClient client; - -unsigned long myChannelNumber = SECRET_CH_ID; -const char * myWriteAPIKey = SECRET_WRITE_APIKEY; - -int number = 0; - -void setup() { - Serial.begin(115200); // Initialize serial - - // check for the WiFi module: - if (WiFi.status() == WL_NO_MODULE) { - Serial.println("Communication with WiFi module failed!"); - // don't continue - while (true); - } - - String fv = WiFi.firmwareVersion(); - if (fv != "1.0.0") { - Serial.println("Please upgrade the firmware"); - } - - ThingSpeak.begin(client); //Initialize ThingSpeak -} - -void loop() { - - // Connect or reconnect to WiFi - if(WiFi.status() != WL_CONNECTED){ - Serial.print("Attempting to connect to SSID: "); - Serial.println(SECRET_SSID); - while(WiFi.status() != WL_CONNECTED){ - WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network - Serial.print("."); - delay(5000); - } - Serial.println("\nConnected."); - } - - // Write to ThingSpeak. There are up to 8 fields in a channel, allowing you to store up to 8 different - // pieces of information in a channel. Here, we write to field 1. - int x = ThingSpeak.writeField(myChannelNumber, 1, number, myWriteAPIKey); - if(x == 200){ - Serial.println("Channel update successful."); - } - else{ - Serial.println("Problem updating channel. HTTP error code " + String(x)); - } - - // change the value - number++; - if(number > 99){ - number = 0; - } - - delay(20000); // Wait 20 seconds to update the channel again -} +/* + WriteSingleField + + Description: Writes a value to a channel on ThingSpeak every 20 seconds. + + Hardware: Arduino Uno WiFi Rev2 + + !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! + + Note: + - Requires WiFiNINA library. + - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +#include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros + +char ssid[] = SECRET_SSID; // your network SSID (name) +char pass[] = SECRET_PASS; // your network password +int keyIndex = 0; // your network key Index number (needed only for WEP) +WiFiClient client; + +unsigned long myChannelNumber = SECRET_CH_ID; +const char * myWriteAPIKey = SECRET_WRITE_APIKEY; + +int number = 0; + +void setup() { + Serial.begin(115200); // Initialize serial + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + // check for the WiFi module: + if (WiFi.status() == WL_NO_MODULE) { + Serial.println("Communication with WiFi module failed!"); + // don't continue + while (true); + } + + String fv = WiFi.firmwareVersion(); + if (fv != "1.0.0") { + Serial.println("Please upgrade the firmware"); + } + + ThingSpeak.begin(client); //Initialize ThingSpeak +} + +void loop() { + + // Connect or reconnect to WiFi + if(WiFi.status() != WL_CONNECTED){ + Serial.print("Attempting to connect to SSID: "); + Serial.println(SECRET_SSID); + while(WiFi.status() != WL_CONNECTED){ + WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network + Serial.print("."); + delay(5000); + } + Serial.println("\nConnected."); + } + + // Write to ThingSpeak. There are up to 8 fields in a channel, allowing you to store up to 8 different + // pieces of information in a channel. Here, we write to field 1. + int x = ThingSpeak.writeField(myChannelNumber, 1, number, myWriteAPIKey); + if(x == 200){ + Serial.println("Channel update successful."); + } + else{ + Serial.println("Problem updating channel. HTTP error code " + String(x)); + } + + // change the value + number++; + if(number > 99){ + number = 0; + } + + delay(20000); // Wait 20 seconds to update the channel again +} diff --git a/examples/ArduinoWiFiShield/ReadField/ReadField.ino b/examples/ArduinoWiFiShield/ReadField/ReadField.ino index 9d150e7..2bd9f3b 100644 --- a/examples/ArduinoWiFiShield/ReadField/ReadField.ino +++ b/examples/ArduinoWiFiShield/ReadField/ReadField.ino @@ -1,112 +1,112 @@ -/* - ReadField - - Description: Demonstates reading from a public channel which requires no API key and reading from a private channel which requires a read API key. - The value read from the public channel is the current outside temperature at MathWorks headquaters in Natick, MA. The value from the - private channel is an example counter that increments every 10 seconds. - - Hardware: Arduino WiFi Shield - - !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! - - Note: - - Requires the WiFi library - - Ensure the WiFi Shield has the latest firmware. Instruction to update can be found here: https://www.arduino.cc/en/Hacking/WiFiShieldFirmwareUpgrading - - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. - - ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and - analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. - - Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. - See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. - - For licensing information, see the accompanying license file. - - Copyright 2018, The MathWorks, Inc. -*/ - -#include "ThingSpeak.h" -#include -#include "secrets.h" - -char ssid[] = SECRET_SSID; // your network SSID (name) -char pass[] = SECRET_PASS; // your network password -int keyIndex = 0; // your network key Index number (needed only for WEP) -WiFiClient client; - -// Weather station channel details -unsigned long weatherStationChannelNumber = SECRET_CH_ID_WEATHER_STATION; -unsigned int temperatureFieldNumber = 4; - -// Counting channel details -unsigned long counterChannelNumber = SECRET_CH_ID_COUNTER; -const char * myCounterReadAPIKey = SECRET_READ_APIKEY_COUNTER; -unsigned int counterFieldNumber = 1; - -void setup() { - //Initialize serial and wait for port to open: - Serial.begin(115200); - while (!Serial) { - ; // wait for serial port to connect. Needed for Leonardo native USB port only - } - - // check for the presence of the shield: - if (WiFi.status() == WL_NO_SHIELD) { - Serial.println("WiFi shield not present"); - // don't continue: - while (true); - } - - String fv = WiFi.firmwareVersion(); - if (fv != "1.1.0") { - Serial.println("Please upgrade the firmware"); - } - - ThingSpeak.begin(client); // Initialize ThingSpeak -} - -void loop() { - - int statusCode = 0; - - // Connect or reconnect to WiFi - if(WiFi.status() != WL_CONNECTED){ - Serial.print("Attempting to connect to SSID: "); - Serial.println(SECRET_SSID); - while(WiFi.status() != WL_CONNECTED){ - WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network - Serial.print("."); - delay(5000); - } - Serial.println("\nConnected"); - } - - // Read in field 4 of the public channel recording the temperature - float temperatureInF = ThingSpeak.readFloatField(weatherStationChannelNumber, temperatureFieldNumber); - - // Check the status of the read operation to see if it was successful - statusCode = ThingSpeak.getLastReadStatus(); - if(statusCode == 200){ - Serial.println("Temperature at MathWorks HQ: " + String(temperatureInF) + " deg F"); - } - else{ - Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); - } - - delay(15000); // No need to read the temperature too often. - - // Read in field 1 of the private channel which is a counter - long count = ThingSpeak.readLongField(counterChannelNumber, counterFieldNumber, myCounterReadAPIKey); - - // Check the status of the read operation to see if it was successful - statusCode = ThingSpeak.getLastReadStatus(); - if(statusCode == 200){ - Serial.println("Counter: " + String(count)); - } - else{ - Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); - } - - delay(15000); // No need to read the counter too often. - -} +/* + ReadField + + Description: Demonstates reading from a public channel which requires no API key and reading from a private channel which requires a read API key. + The value read from the public channel is the current outside temperature at MathWorks headquaters in Natick, MA. The value from the + private channel is an example counter that increments every 10 seconds. + + Hardware: Arduino WiFi Shield + + !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! + + Note: + - Requires the WiFi library + - Ensure the WiFi Shield has the latest firmware. Instruction to update can be found here: https://www.arduino.cc/en/Hacking/WiFiShieldFirmwareUpgrading + - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +#include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros + +char ssid[] = SECRET_SSID; // your network SSID (name) +char pass[] = SECRET_PASS; // your network password +int keyIndex = 0; // your network key Index number (needed only for WEP) +WiFiClient client; + +// Weather station channel details +unsigned long weatherStationChannelNumber = SECRET_CH_ID_WEATHER_STATION; +unsigned int temperatureFieldNumber = 4; + +// Counting channel details +unsigned long counterChannelNumber = SECRET_CH_ID_COUNTER; +const char * myCounterReadAPIKey = SECRET_READ_APIKEY_COUNTER; +unsigned int counterFieldNumber = 1; + +void setup() { + //Initialize serial and wait for port to open: + Serial.begin(115200); + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + // check for the presence of the shield: + if (WiFi.status() == WL_NO_SHIELD) { + Serial.println("WiFi shield not present"); + // don't continue: + while (true); + } + + String fv = WiFi.firmwareVersion(); + if (fv != "1.1.0") { + Serial.println("Please upgrade the firmware"); + } + + ThingSpeak.begin(client); // Initialize ThingSpeak +} + +void loop() { + + int statusCode = 0; + + // Connect or reconnect to WiFi + if(WiFi.status() != WL_CONNECTED){ + Serial.print("Attempting to connect to SSID: "); + Serial.println(SECRET_SSID); + while(WiFi.status() != WL_CONNECTED){ + WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network + Serial.print("."); + delay(5000); + } + Serial.println("\nConnected"); + } + + // Read in field 4 of the public channel recording the temperature + float temperatureInF = ThingSpeak.readFloatField(weatherStationChannelNumber, temperatureFieldNumber); + + // Check the status of the read operation to see if it was successful + statusCode = ThingSpeak.getLastReadStatus(); + if(statusCode == 200){ + Serial.println("Temperature at MathWorks HQ: " + String(temperatureInF) + " deg F"); + } + else{ + Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); + } + + delay(15000); // No need to read the temperature too often. + + // Read in field 1 of the private channel which is a counter + long count = ThingSpeak.readLongField(counterChannelNumber, counterFieldNumber, myCounterReadAPIKey); + + // Check the status of the read operation to see if it was successful + statusCode = ThingSpeak.getLastReadStatus(); + if(statusCode == 200){ + Serial.println("Counter: " + String(count)); + } + else{ + Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); + } + + delay(15000); // No need to read the counter too often. + +} diff --git a/examples/ArduinoWiFiShield/WriteMultipleFields/WriteMultipleFields.ino b/examples/ArduinoWiFiShield/WriteMultipleFields/WriteMultipleFields.ino index 42dd48f..0e8d90c 100644 --- a/examples/ArduinoWiFiShield/WriteMultipleFields/WriteMultipleFields.ino +++ b/examples/ArduinoWiFiShield/WriteMultipleFields/WriteMultipleFields.ino @@ -1,120 +1,120 @@ -/* - WriteMultipleFields - - Description: Writes values to fields 1,2,3,4 and status in a single ThingSpeak update every 20 seconds. - - Hardware: Arduino WiFi Shield - - !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! - - Note: - - Requires the WiFi library - - Ensure the WiFi Shield has the latest firmware. Instruction to update can be found here: https://www.arduino.cc/en/Hacking/WiFiShieldFirmwareUpgrading - - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. - - ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and - analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. - - Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. - See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. - - For licensing information, see the accompanying license file. - - Copyright 2018, The MathWorks, Inc. -*/ - -#include "ThingSpeak.h" -#include -#include "secrets.h" - -char ssid[] = SECRET_SSID; // your network SSID (name) -char pass[] = SECRET_PASS; // your network password -int keyIndex = 0; // your network key Index number (needed only for WEP) -WiFiClient client; - -unsigned long myChannelNumber = SECRET_CH_ID; -const char * myWriteAPIKey = SECRET_WRITE_APIKEY; - -// Initialize our values -int number1 = 0; -int number2 = random(0,100); -int number3 = random(0,100); -int number4 = random(0,100); -String myStatus = ""; - -void setup() { - //Initialize serial and wait for port to open: - Serial.begin(115200); - while (!Serial) { - ; // wait for serial port to connect. Needed for Leonardo native USB port only - } - - // check for the presence of the shield: - if (WiFi.status() == WL_NO_SHIELD) { - Serial.println("WiFi shield not present"); - // don't continue: - while (true); - } - - String fv = WiFi.firmwareVersion(); - if (fv != "1.1.0") { - Serial.println("Please upgrade the firmware"); - } - - ThingSpeak.begin(client); // Initialize ThingSpeak -} - -void loop() { - - // Connect or reconnect to WiFi - if(WiFi.status() != WL_CONNECTED){ - Serial.print("Attempting to connect to SSID: "); - Serial.println(SECRET_SSID); - while(WiFi.status() != WL_CONNECTED){ - WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network - Serial.print("."); - delay(5000); - } - Serial.println("\nConnected."); - } - - // set the fields with the values - ThingSpeak.setField(1, number1); - ThingSpeak.setField(2, number2); - ThingSpeak.setField(3, number3); - ThingSpeak.setField(4, number4); - - // figure out the status message - if(number1 > number2){ - myStatus = String("field1 is greater than field2"); - } - else if(number1 < number2){ - myStatus = String("field1 is less than field2"); - } - else{ - myStatus = String("field1 equals field2"); - } - - // set the status - ThingSpeak.setStatus(myStatus); - - // write to the ThingSpeak channel - int x = ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey); - if(x == 200){ - Serial.println("Channel update successful."); - } - else{ - Serial.println("Problem updating channel. HTTP error code " + String(x)); - } - - // change the values - number1++; - if(number1 > 99){ - number1 = 0; - } - number2 = random(0,100); - number3 = random(0,100); - number4 = random(0,100); - - delay(20000); // Wait 20 seconds to update the channel again -} +/* + WriteMultipleFields + + Description: Writes values to fields 1,2,3,4 and status in a single ThingSpeak update every 20 seconds. + + Hardware: Arduino WiFi Shield + + !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! + + Note: + - Requires the WiFi library + - Ensure the WiFi Shield has the latest firmware. Instruction to update can be found here: https://www.arduino.cc/en/Hacking/WiFiShieldFirmwareUpgrading + - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +#include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros + +char ssid[] = SECRET_SSID; // your network SSID (name) +char pass[] = SECRET_PASS; // your network password +int keyIndex = 0; // your network key Index number (needed only for WEP) +WiFiClient client; + +unsigned long myChannelNumber = SECRET_CH_ID; +const char * myWriteAPIKey = SECRET_WRITE_APIKEY; + +// Initialize our values +int number1 = 0; +int number2 = random(0,100); +int number3 = random(0,100); +int number4 = random(0,100); +String myStatus = ""; + +void setup() { + //Initialize serial and wait for port to open: + Serial.begin(115200); + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + // check for the presence of the shield: + if (WiFi.status() == WL_NO_SHIELD) { + Serial.println("WiFi shield not present"); + // don't continue: + while (true); + } + + String fv = WiFi.firmwareVersion(); + if (fv != "1.1.0") { + Serial.println("Please upgrade the firmware"); + } + + ThingSpeak.begin(client); // Initialize ThingSpeak +} + +void loop() { + + // Connect or reconnect to WiFi + if(WiFi.status() != WL_CONNECTED){ + Serial.print("Attempting to connect to SSID: "); + Serial.println(SECRET_SSID); + while(WiFi.status() != WL_CONNECTED){ + WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network + Serial.print("."); + delay(5000); + } + Serial.println("\nConnected."); + } + + // set the fields with the values + ThingSpeak.setField(1, number1); + ThingSpeak.setField(2, number2); + ThingSpeak.setField(3, number3); + ThingSpeak.setField(4, number4); + + // figure out the status message + if(number1 > number2){ + myStatus = String("field1 is greater than field2"); + } + else if(number1 < number2){ + myStatus = String("field1 is less than field2"); + } + else{ + myStatus = String("field1 equals field2"); + } + + // set the status + ThingSpeak.setStatus(myStatus); + + // write to the ThingSpeak channel + int x = ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey); + if(x == 200){ + Serial.println("Channel update successful."); + } + else{ + Serial.println("Problem updating channel. HTTP error code " + String(x)); + } + + // change the values + number1++; + if(number1 > 99){ + number1 = 0; + } + number2 = random(0,100); + number3 = random(0,100); + number4 = random(0,100); + + delay(20000); // Wait 20 seconds to update the channel again +} diff --git a/examples/ArduinoWiFiShield/WriteSingleField/WriteSingleField.ino b/examples/ArduinoWiFiShield/WriteSingleField/WriteSingleField.ino index 427c56d..a690b47 100644 --- a/examples/ArduinoWiFiShield/WriteSingleField/WriteSingleField.ino +++ b/examples/ArduinoWiFiShield/WriteSingleField/WriteSingleField.ino @@ -1,93 +1,93 @@ -/* - WriteSingleField - - Description: Writes a value to a channel on ThingSpeak every 20 seconds. - - Hardware: Arduino WiFi Shield - - !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! - - Note: - - Requires the WiFi library - - Ensure the WiFi Shield has the latest firmware. Instruction to update can be found here: https://www.arduino.cc/en/Hacking/WiFiShieldFirmwareUpgrading - - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. - - ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and - analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. - - Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. - See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. - - For licensing information, see the accompanying license file. - - Copyright 2018, The MathWorks, Inc. -*/ - -#include "ThingSpeak.h" -#include -#include "secrets.h" - -char ssid[] = SECRET_SSID; // your network SSID (name) -char pass[] = SECRET_PASS; // your network password -int keyIndex = 0; // your network key Index number (needed only for WEP) -WiFiClient client; - -unsigned long myChannelNumber = SECRET_CH_ID; -const char * myWriteAPIKey = SECRET_WRITE_APIKEY; - -int number = 0; - -void setup() { - //Initialize serial and wait for port to open: - Serial.begin(115200); - while (!Serial) { - ; // wait for serial port to connect. Needed for Leonardo native USB port only - } - - // check for the presence of the shield: - if (WiFi.status() == WL_NO_SHIELD) { - Serial.println("WiFi shield not present"); - // don't continue: - while (true); - } - - String fv = WiFi.firmwareVersion(); - if (fv != "1.1.0") { - Serial.println("Please upgrade the firmware"); - } - - ThingSpeak.begin(client); // Initialize ThingSpeak -} - -void loop() { - - // Connect or reconnect to WiFi - if(WiFi.status() != WL_CONNECTED){ - Serial.print("Attempting to connect to SSID: "); - Serial.println(SECRET_SSID); - while(WiFi.status() != WL_CONNECTED){ - WiFi.begin(ssid, pass); - Serial.print("."); - delay(5000); - } - Serial.println("\nConnected."); - } - - // Write to ThingSpeak. There are up to 8 fields in a channel, allowing you to store up to 8 different - // pieces of information in a channel. Here, we write to field 1. - int x = ThingSpeak.writeField(myChannelNumber, 1, number, myWriteAPIKey); - if(x == 200){ - Serial.println("Channel update successful."); - } - else{ - Serial.println("Problem updating channel. HTTP error code " + String(x)); - } - - // change the value - number++; - if(number > 99){ - number = 0; - } - - delay(20000); // Wait 20 seconds to update the channel again -} +/* + WriteSingleField + + Description: Writes a value to a channel on ThingSpeak every 20 seconds. + + Hardware: Arduino WiFi Shield + + !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! + + Note: + - Requires the WiFi library + - Ensure the WiFi Shield has the latest firmware. Instruction to update can be found here: https://www.arduino.cc/en/Hacking/WiFiShieldFirmwareUpgrading + - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +#include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros + +char ssid[] = SECRET_SSID; // your network SSID (name) +char pass[] = SECRET_PASS; // your network password +int keyIndex = 0; // your network key Index number (needed only for WEP) +WiFiClient client; + +unsigned long myChannelNumber = SECRET_CH_ID; +const char * myWriteAPIKey = SECRET_WRITE_APIKEY; + +int number = 0; + +void setup() { + //Initialize serial and wait for port to open: + Serial.begin(115200); + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + // check for the presence of the shield: + if (WiFi.status() == WL_NO_SHIELD) { + Serial.println("WiFi shield not present"); + // don't continue: + while (true); + } + + String fv = WiFi.firmwareVersion(); + if (fv != "1.1.0") { + Serial.println("Please upgrade the firmware"); + } + + ThingSpeak.begin(client); // Initialize ThingSpeak +} + +void loop() { + + // Connect or reconnect to WiFi + if(WiFi.status() != WL_CONNECTED){ + Serial.print("Attempting to connect to SSID: "); + Serial.println(SECRET_SSID); + while(WiFi.status() != WL_CONNECTED){ + WiFi.begin(ssid, pass); + Serial.print("."); + delay(5000); + } + Serial.println("\nConnected."); + } + + // Write to ThingSpeak. There are up to 8 fields in a channel, allowing you to store up to 8 different + // pieces of information in a channel. Here, we write to field 1. + int x = ThingSpeak.writeField(myChannelNumber, 1, number, myWriteAPIKey); + if(x == 200){ + Serial.println("Channel update successful."); + } + else{ + Serial.println("Problem updating channel. HTTP error code " + String(x)); + } + + // change the value + number++; + if(number > 99){ + number = 0; + } + + delay(20000); // Wait 20 seconds to update the channel again +} diff --git a/examples/ArduinoWiFiShield101/ReadField/ReadField.ino b/examples/ArduinoWiFiShield101/ReadField/ReadField.ino index a529dd6..dd497b1 100644 --- a/examples/ArduinoWiFiShield101/ReadField/ReadField.ino +++ b/examples/ArduinoWiFiShield101/ReadField/ReadField.ino @@ -23,12 +23,12 @@ For licensing information, see the accompanying license file. - Copyright 2018, The MathWorks, Inc. + Copyright 2020, The MathWorks, Inc. */ -#include "ThingSpeak.h" #include #include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros char ssid[] = SECRET_SSID; // your network SSID (name) char pass[] = SECRET_PASS; // your network password diff --git a/examples/ArduinoWiFiShield101/WriteMultipleFields/WriteMultipleFields.ino b/examples/ArduinoWiFiShield101/WriteMultipleFields/WriteMultipleFields.ino index 203fadb..f058e02 100644 --- a/examples/ArduinoWiFiShield101/WriteMultipleFields/WriteMultipleFields.ino +++ b/examples/ArduinoWiFiShield101/WriteMultipleFields/WriteMultipleFields.ino @@ -21,12 +21,12 @@ For licensing information, see the accompanying license file. - Copyright 2018, The MathWorks, Inc. + Copyright 2020, The MathWorks, Inc. */ -#include "ThingSpeak.h" #include #include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros char ssid[] = SECRET_SSID; // your network SSID (name) char pass[] = SECRET_PASS; // your network password diff --git a/examples/ArduinoWiFiShield101/WriteSingleField/WriteSingleField.ino b/examples/ArduinoWiFiShield101/WriteSingleField/WriteSingleField.ino index 776c2af..31f3dfb 100644 --- a/examples/ArduinoWiFiShield101/WriteSingleField/WriteSingleField.ino +++ b/examples/ArduinoWiFiShield101/WriteSingleField/WriteSingleField.ino @@ -21,12 +21,12 @@ For licensing information, see the accompanying license file. - Copyright 2018, The MathWorks, Inc. + Copyright 2020, The MathWorks, Inc. */ -#include "ThingSpeak.h" #include #include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros char ssid[] = SECRET_SSID; // your network SSID (name) char pass[] = SECRET_PASS; // your network password diff --git a/examples/ArduinoYun/ReadField/ReadField.ino b/examples/ArduinoYun/ReadField/ReadField.ino index 0ea4155..0f38fbe 100644 --- a/examples/ArduinoYun/ReadField/ReadField.ino +++ b/examples/ArduinoYun/ReadField/ReadField.ino @@ -1,83 +1,86 @@ -/* - ReadField - - Description: Demonstates reading from a public channel which requires no API key and reading from a private channel which requires a read API key. - The value read from the public channel is the current outside temperature at MathWorks headquaters in Natick, MA. The value from the - private channel is an example counter that increments every 10 seconds. - - Hardware: Arduino Yún, Yún Rev.2 - - !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! - - Notes: - - This example works with both Ethernet and WiFi - - For WiFi with the Yún Rev.2, configure the SSID and password through the Access Point portal. - See https://www.arduino.cc/en/Guide/ArduinoYunRev2 for details. - - ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and - analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. - - Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. - See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. - - For licensing information, see the accompanying license file. - - Copyright 2018, The MathWorks, Inc. -*/ - -#include "ThingSpeak.h" -#include "secrets.h" -#include - -BridgeClient client; - -// Weather station channel details -unsigned long weatherStationChannelNumber = SECRET_CH_ID_WEATHER_STATION; -unsigned int temperatureFieldNumber = 4; - -// Counting channel details -unsigned long counterChannelNumber = SECRET_CH_ID_COUNTER; -const char * myCounterReadAPIKey = SECRET_READ_APIKEY_COUNTER; -unsigned int counterFieldNumber = 1; - -void setup() { - Serial.begin(115200); //Initialize serial - - Bridge.begin(); - ThingSpeak.begin(client); // Initialize ThingSpeak -} - -void loop() { - - int statusCode = 0; - - // Read in field 4 of the public channel recording the temperature - float temperatureInF = ThingSpeak.readFloatField(weatherStationChannelNumber, temperatureFieldNumber); - - // Check the status of the read operation to see if it was successful - statusCode = ThingSpeak.getLastReadStatus(); - if(statusCode == 200){ - Serial.println("Temperature at MathWorks HQ: " + String(temperatureInF) + " deg F"); - } - else{ - Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); - } - - delay(15000); // No need to read the temperature too often. - - // Read in field 1 of the private channel which is a counter - long count = ThingSpeak.readLongField(counterChannelNumber, counterFieldNumber, myCounterReadAPIKey); - - // Check the status of the read operation to see if it was successful - statusCode = ThingSpeak.getLastReadStatus(); - if(statusCode == 200){ - Serial.println("Counter: " + String(count)); - } - else{ - Serial.print("Problem reading channel. HTTP error code "); - Serial.println(statusCode); - } - - delay(15000); // No need to read the counter too often. - -} +/* + ReadField + + Description: Demonstates reading from a public channel which requires no API key and reading from a private channel which requires a read API key. + The value read from the public channel is the current outside temperature at MathWorks headquaters in Natick, MA. The value from the + private channel is an example counter that increments every 10 seconds. + + Hardware: Arduino Yún, Yún Rev.2 + + !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! + + Notes: + - This example works with both Ethernet and WiFi + - For WiFi with the Yún Rev.2, configure the SSID and password through the Access Point portal. + See https://www.arduino.cc/en/Guide/ArduinoYunRev2 for details. + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +#include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros + +BridgeClient client; + +// Weather station channel details +unsigned long weatherStationChannelNumber = SECRET_CH_ID_WEATHER_STATION; +unsigned int temperatureFieldNumber = 4; + +// Counting channel details +unsigned long counterChannelNumber = SECRET_CH_ID_COUNTER; +const char * myCounterReadAPIKey = SECRET_READ_APIKEY_COUNTER; +unsigned int counterFieldNumber = 1; + +void setup() { + Serial.begin(115200); //Initialize serial + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + Bridge.begin(); + ThingSpeak.begin(client); // Initialize ThingSpeak +} + +void loop() { + + int statusCode = 0; + + // Read in field 4 of the public channel recording the temperature + float temperatureInF = ThingSpeak.readFloatField(weatherStationChannelNumber, temperatureFieldNumber); + + // Check the status of the read operation to see if it was successful + statusCode = ThingSpeak.getLastReadStatus(); + if(statusCode == 200){ + Serial.println("Temperature at MathWorks HQ: " + String(temperatureInF) + " deg F"); + } + else{ + Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); + } + + delay(15000); // No need to read the temperature too often. + + // Read in field 1 of the private channel which is a counter + long count = ThingSpeak.readLongField(counterChannelNumber, counterFieldNumber, myCounterReadAPIKey); + + // Check the status of the read operation to see if it was successful + statusCode = ThingSpeak.getLastReadStatus(); + if(statusCode == 200){ + Serial.println("Counter: " + String(count)); + } + else{ + Serial.print("Problem reading channel. HTTP error code "); + Serial.println(statusCode); + } + + delay(15000); // No need to read the counter too often. + +} diff --git a/examples/ArduinoYun/WriteMultipleFields/WriteMultipleFields.ino b/examples/ArduinoYun/WriteMultipleFields/WriteMultipleFields.ino index a06a3bb..a6b64f7 100644 --- a/examples/ArduinoYun/WriteMultipleFields/WriteMultipleFields.ino +++ b/examples/ArduinoYun/WriteMultipleFields/WriteMultipleFields.ino @@ -1,89 +1,91 @@ -/* - WriteMultipleFields - - Description: Writes values to fields 1,2,3,4 and status in a single ThingSpeak update every 20 seconds. - - Hardware: Arduino Yún, Yún Rev.2 - - !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! - - Note: - - This example works with both Ethernet and WiFi - - For WiFi with the Yún Rev.2, configure the SSID and password through the Access Point portal. - See https://www.arduino.cc/en/Guide/ArduinoYunRev2 for details. - - ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and - analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. - - Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. - See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. - - For licensing information, see the accompanying license file. - - Copyright 2018, The MathWorks, Inc. -*/ - -#include "ThingSpeak.h" -#include "secrets.h" -#include - -BridgeClient client; -unsigned long myChannelNumber = SECRET_CH_ID; -const char * myWriteAPIKey = SECRET_WRITE_APIKEY; - -// Initialize our values -int number1 = 0; -int number2 = random(0,100); -int number3 = random(0,100); -int number4 = random(0,100); -String myStatus = ""; - -void setup() { - Serial.begin(115200); //Initialize serial - - Bridge.begin(); - ThingSpeak.begin(client); // Initialize ThingSpeak -} - -void loop() { - - // set the fields with the values - ThingSpeak.setField(1, number1); - ThingSpeak.setField(2, number2); - ThingSpeak.setField(3, number3); - ThingSpeak.setField(4, number4); - - // figure out the status message - if(number1 > number2){ - myStatus = String("field1 is greater than field2"); - } - else if(number1 < number2){ - myStatus = String("field1 is less than field2"); - } - else{ - myStatus = String("field1 equals field2"); - } - - // set the status - ThingSpeak.setStatus(myStatus); - - // write to the ThingSpeak channel - int x = ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey); - if(x == 200){ - Serial.println("Channel update successful."); - } - else{ - Serial.println("Problem updating channel. HTTP error code " + String(x)); - } - - // change the values - number1++; - if(number1 > 99){ - number1 = 0; - } - number2 = random(0,100); - number3 = random(0,100); - number4 = random(0,100); - - delay(20000); // Wait 20 seconds to update the channel again -} +/* + WriteMultipleFields + + Description: Writes values to fields 1,2,3,4 and status in a single ThingSpeak update every 20 seconds. + + Hardware: Arduino Yún, Yún Rev.2 + + !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! + + Note: + - This example works with both Ethernet and WiFi + - For WiFi with the Yún Rev.2, configure the SSID and password through the Access Point portal. + See https://www.arduino.cc/en/Guide/ArduinoYunRev2 for details. + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ +#include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros + +BridgeClient client; +unsigned long myChannelNumber = SECRET_CH_ID; +const char * myWriteAPIKey = SECRET_WRITE_APIKEY; + +// Initialize our values +int number1 = 0; +int number2 = random(0,100); +int number3 = random(0,100); +int number4 = random(0,100); +String myStatus = ""; + +void setup() { + Serial.begin(115200); //Initialize serial + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + Bridge.begin(); + ThingSpeak.begin(client); // Initialize ThingSpeak +} + +void loop() { + + // set the fields with the values + ThingSpeak.setField(1, number1); + ThingSpeak.setField(2, number2); + ThingSpeak.setField(3, number3); + ThingSpeak.setField(4, number4); + + // figure out the status message + if(number1 > number2){ + myStatus = String("field1 is greater than field2"); + } + else if(number1 < number2){ + myStatus = String("field1 is less than field2"); + } + else{ + myStatus = String("field1 equals field2"); + } + + // set the status + ThingSpeak.setStatus(myStatus); + + // write to the ThingSpeak channel + int x = ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey); + if(x == 200){ + Serial.println("Channel update successful."); + } + else{ + Serial.println("Problem updating channel. HTTP error code " + String(x)); + } + + // change the values + number1++; + if(number1 > 99){ + number1 = 0; + } + number2 = random(0,100); + number3 = random(0,100); + number4 = random(0,100); + + delay(20000); // Wait 20 seconds to update the channel again +} diff --git a/examples/ArduinoYun/WriteSingleField/WriteSingleField.ino b/examples/ArduinoYun/WriteSingleField/WriteSingleField.ino index 37467f0..1731099 100644 --- a/examples/ArduinoYun/WriteSingleField/WriteSingleField.ino +++ b/examples/ArduinoYun/WriteSingleField/WriteSingleField.ino @@ -1,62 +1,65 @@ -/* - WriteSingleField - - Description: Writes a value to a channel on ThingSpeak every 20 seconds. - - Hardware: Arduino Yún, Yún Rev.2 - - !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! - - Notes: - - This example works with both Ethernet and WiFi - - For WiFi with the Yún Rev.2, configure the SSID and password through the Access Point portal. - See https://www.arduino.cc/en/Guide/ArduinoYunRev2 for details. - - ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and - analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. - - Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. - See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. - - For licensing information, see the accompanying license file. - - Copyright 2018, The MathWorks, Inc. -*/ - -#include "ThingSpeak.h" -#include "secrets.h" -#include - -BridgeClient client; -unsigned long myChannelNumber = SECRET_CH_ID; -const char * myWriteAPIKey = SECRET_WRITE_APIKEY; - -int number = 0; - -void setup() { - Serial.begin(115200); //Initialize serial - - Bridge.begin(); - ThingSpeak.begin(client); // Initialize ThingSpeak -} - -void loop() { - - // Write to ThingSpeak. There are up to 8 fields in a channel, allowing you to store up to 8 different - // pieces of information in a channel. Here, we write to field 1. - int x = ThingSpeak.writeField(myChannelNumber, 1, number, myWriteAPIKey); - if(x == 200){ - Serial.println("Channel update successful."); - } - else{ - Serial.println("Problem updating channel. HTTP error code " + String(x)); - } - - // change the value - number++; - if(number > 99){ - number = 0; - } - - delay(20000); // Wait 20 seconds to update the channel again -} +/* + WriteSingleField + + Description: Writes a value to a channel on ThingSpeak every 20 seconds. + + Hardware: Arduino Yún, Yún Rev.2 + + !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! + + Notes: + - This example works with both Ethernet and WiFi + - For WiFi with the Yún Rev.2, configure the SSID and password through the Access Point portal. + See https://www.arduino.cc/en/Guide/ArduinoYunRev2 for details. + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +#include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros + +BridgeClient client; +unsigned long myChannelNumber = SECRET_CH_ID; +const char * myWriteAPIKey = SECRET_WRITE_APIKEY; + +int number = 0; + +void setup() { + Serial.begin(115200); //Initialize serial + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + Bridge.begin(); + ThingSpeak.begin(client); // Initialize ThingSpeak +} + +void loop() { + + // Write to ThingSpeak. There are up to 8 fields in a channel, allowing you to store up to 8 different + // pieces of information in a channel. Here, we write to field 1. + int x = ThingSpeak.writeField(myChannelNumber, 1, number, myWriteAPIKey); + if(x == 200){ + Serial.println("Channel update successful."); + } + else{ + Serial.println("Problem updating channel. HTTP error code " + String(x)); + } + + // change the value + number++; + if(number > 99){ + number = 0; + } + + delay(20000); // Wait 20 seconds to update the channel again +} diff --git a/examples/ESP32/ReadField/ReadField.ino b/examples/ESP32/ReadField/ReadField.ino index 76af303..455edf2 100644 --- a/examples/ESP32/ReadField/ReadField.ino +++ b/examples/ESP32/ReadField/ReadField.ino @@ -1,97 +1,100 @@ -/* - ReadField - - Description: Demonstates reading from a public channel which requires no API key and reading from a private channel which requires a read API key. - The value read from the public channel is the current outside temperature at MathWorks headquaters in Natick, MA. The value from the - private channel is an example counter that increments every 10 seconds. - - Hardware: ESP32 based boards - - !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! - - Note: - - Requires installation of EPS32 core. See https://github.com/espressif/arduino-esp32/blob/master/docs/arduino-ide/boards_manager.md for details. - - Select the target hardware from the Tools->Board menu - - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. - - ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and - analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. - - Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. - See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. - - For licensing information, see the accompanying license file. - - Copyright 2018, The MathWorks, Inc. -*/ - -#include "ThingSpeak.h" -#include "secrets.h" -#include - -char ssid[] = SECRET_SSID; // your network SSID (name) -char pass[] = SECRET_PASS; // your network password -int keyIndex = 0; // your network key Index number (needed only for WEP) -WiFiClient client; - -// Weather station channel details -unsigned long weatherStationChannelNumber = SECRET_CH_ID_WEATHER_STATION; -unsigned int temperatureFieldNumber = 4; - -// Counting channel details -unsigned long counterChannelNumber = SECRET_CH_ID_COUNTER; -const char * myCounterReadAPIKey = SECRET_READ_APIKEY_COUNTER; -unsigned int counterFieldNumber = 1; - -void setup() { - Serial.begin(115200); //Initialize serial - - WiFi.mode(WIFI_STA); - ThingSpeak.begin(client); // Initialize ThingSpeak -} - -void loop() { - - int statusCode = 0; - - // Connect or reconnect to WiFi - if(WiFi.status() != WL_CONNECTED){ - Serial.print("Attempting to connect to SSID: "); - Serial.println(SECRET_SSID); - while(WiFi.status() != WL_CONNECTED){ - WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network - Serial.print("."); - delay(5000); - } - Serial.println("\nConnected"); - } - - // Read in field 4 of the public channel recording the temperature - float temperatureInF = ThingSpeak.readFloatField(weatherStationChannelNumber, temperatureFieldNumber); - - // Check the status of the read operation to see if it was successful - statusCode = ThingSpeak.getLastReadStatus(); - if(statusCode == 200){ - Serial.println("Temperature at MathWorks HQ: " + String(temperatureInF) + " deg F"); - } - else{ - Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); - } - - delay(15000); // No need to read the temperature too often. - - // Read in field 1 of the private channel which is a counter - long count = ThingSpeak.readLongField(counterChannelNumber, counterFieldNumber, myCounterReadAPIKey); - - // Check the status of the read operation to see if it was successful - statusCode = ThingSpeak.getLastReadStatus(); - if(statusCode == 200){ - Serial.println("Counter: " + String(count)); - } - else{ - Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); - } - - delay(15000); // No need to read the counter too often. - -} +/* + ReadField + + Description: Demonstates reading from a public channel which requires no API key and reading from a private channel which requires a read API key. + The value read from the public channel is the current outside temperature at MathWorks headquaters in Natick, MA. The value from the + private channel is an example counter that increments every 10 seconds. + + Hardware: ESP32 based boards + + !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! + + Note: + - Requires installation of EPS32 core. See https://github.com/espressif/arduino-esp32/blob/master/docs/arduino-ide/boards_manager.md for details. + - Select the target hardware from the Tools->Board menu + - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +#include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros + +char ssid[] = SECRET_SSID; // your network SSID (name) +char pass[] = SECRET_PASS; // your network password +int keyIndex = 0; // your network key Index number (needed only for WEP) +WiFiClient client; + +// Weather station channel details +unsigned long weatherStationChannelNumber = SECRET_CH_ID_WEATHER_STATION; +unsigned int temperatureFieldNumber = 4; + +// Counting channel details +unsigned long counterChannelNumber = SECRET_CH_ID_COUNTER; +const char * myCounterReadAPIKey = SECRET_READ_APIKEY_COUNTER; +unsigned int counterFieldNumber = 1; + +void setup() { + Serial.begin(115200); //Initialize serial + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + WiFi.mode(WIFI_STA); + ThingSpeak.begin(client); // Initialize ThingSpeak +} + +void loop() { + + int statusCode = 0; + + // Connect or reconnect to WiFi + if(WiFi.status() != WL_CONNECTED){ + Serial.print("Attempting to connect to SSID: "); + Serial.println(SECRET_SSID); + while(WiFi.status() != WL_CONNECTED){ + WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network + Serial.print("."); + delay(5000); + } + Serial.println("\nConnected"); + } + + // Read in field 4 of the public channel recording the temperature + float temperatureInF = ThingSpeak.readFloatField(weatherStationChannelNumber, temperatureFieldNumber); + + // Check the status of the read operation to see if it was successful + statusCode = ThingSpeak.getLastReadStatus(); + if(statusCode == 200){ + Serial.println("Temperature at MathWorks HQ: " + String(temperatureInF) + " deg F"); + } + else{ + Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); + } + + delay(15000); // No need to read the temperature too often. + + // Read in field 1 of the private channel which is a counter + long count = ThingSpeak.readLongField(counterChannelNumber, counterFieldNumber, myCounterReadAPIKey); + + // Check the status of the read operation to see if it was successful + statusCode = ThingSpeak.getLastReadStatus(); + if(statusCode == 200){ + Serial.println("Counter: " + String(count)); + } + else{ + Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); + } + + delay(15000); // No need to read the counter too often. + +} diff --git a/examples/ESP32/ReadFieldSecure/ReadFieldSecure.ino b/examples/ESP32/ReadFieldSecure/ReadFieldSecure.ino new file mode 100644 index 0000000..b67b517 --- /dev/null +++ b/examples/ESP32/ReadFieldSecure/ReadFieldSecure.ino @@ -0,0 +1,102 @@ +/* + ReadField + + Description: Demonstates reading from a public channel which requires no API key and reading from a private channel which requires a read API key. + The value read from the public channel is the current outside temperature at MathWorks headquaters in Natick, MA. The value from the + private channel is an example counter that increments every 10 seconds over secured HTTPS connection. + + Hardware: ESP32 based boards + + !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! + + Note: + - Requires installation of EPS32 core and WiFiClientSecure library. See https://github.com/espressif/arduino-esp32/blob/master/docs/arduino-ide/boards_manager.md for details. + - Select the target hardware from the Tools->Board menu + - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +#define TS_ENABLE_SSL // For HTTPS SSL connection + +#include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros + +char ssid[] = SECRET_SSID; // your network SSID (name) +char pass[] = SECRET_PASS; // your network password +int keyIndex = 0; // your network key Index number (needed only for WEP) +WiFiClientSecure client; + +// Weather station channel details +unsigned long weatherStationChannelNumber = SECRET_CH_ID_WEATHER_STATION; +unsigned int temperatureFieldNumber = 4; + +// Counting channel details +unsigned long counterChannelNumber = SECRET_CH_ID_COUNTER; +const char * myCounterReadAPIKey = SECRET_READ_APIKEY_COUNTER; +unsigned int counterFieldNumber = 1; + +void setup() { + Serial.begin(115200); //Initialize serial + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + WiFi.mode(WIFI_STA); + ThingSpeak.begin(client); // Initialize ThingSpeak +} + +void loop() { + + int statusCode = 0; + + // Connect or reconnect to WiFi + if(WiFi.status() != WL_CONNECTED){ + Serial.print("Attempting to connect to SSID: "); + Serial.println(SECRET_SSID); + while(WiFi.status() != WL_CONNECTED){ + WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network + Serial.print("."); + delay(5000); + } + Serial.println("\nConnected"); + } + + // Read in field 4 of the public channel recording the temperature + float temperatureInF = ThingSpeak.readFloatField(weatherStationChannelNumber, temperatureFieldNumber); + + // Check the status of the read operation to see if it was successful + statusCode = ThingSpeak.getLastReadStatus(); + if(statusCode == 200){ + Serial.println("Temperature at MathWorks HQ: " + String(temperatureInF) + " deg F"); + } + else{ + Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); + } + + delay(15000); // No need to read the temperature too often. + + // Read in field 1 of the private channel which is a counter + long count = ThingSpeak.readLongField(counterChannelNumber, counterFieldNumber, myCounterReadAPIKey); + + // Check the status of the read operation to see if it was successful + statusCode = ThingSpeak.getLastReadStatus(); + if(statusCode == 200){ + Serial.println("Counter: " + String(count)); + } + else{ + Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); + } + + delay(15000); // No need to read the counter too often. + +} diff --git a/examples/ESP32/ReadFieldSecure/secrets.h b/examples/ESP32/ReadFieldSecure/secrets.h new file mode 100644 index 0000000..f381ba2 --- /dev/null +++ b/examples/ESP32/ReadFieldSecure/secrets.h @@ -0,0 +1,10 @@ +// Use this file to store all of the private credentials +// and connection details + +#define SECRET_SSID "MySSID" // replace MySSID with your WiFi network name +#define SECRET_PASS "MyPassword" // replace MyPassword with your WiFi password + +#define SECRET_CH_ID_WEATHER_STATION 12397 //MathWorks weather station + +#define SECRET_CH_ID_COUNTER 298725 //Test channel for counting +#define SECRET_READ_APIKEY_COUNTER "SODG0O2UZVGKWAWG" //API Key for Test channel diff --git a/examples/ESP32/ReadMultipleFields/ReadMultipleFields.ino b/examples/ESP32/ReadMultipleFields/ReadMultipleFields.ino new file mode 100644 index 0000000..1f69cc1 --- /dev/null +++ b/examples/ESP32/ReadMultipleFields/ReadMultipleFields.ino @@ -0,0 +1,112 @@ +/* + ReadMultipleFields + + Description: Demonstates reading from a public channel which requires no API key (reading from a private channel requires a read API key). + The values read from the public channel is the current wind direction, wind speed, humidity, outside temperature, rain, pressure, + power level, and light intensity at MathWorks headquaters in Natick, MA.The functionality also provides us to read the + status message, location coordinates, and created-at timestamp associated with the latest feed. + + Hardware: ESP32 based boards + + !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! + + Note: + - Requires installation of EPS32 core. See https://github.com/espressif/arduino-esp32/blob/master/docs/arduino-ide/boards_manager.md for details. + - Select the target hardware from the Tools->Board menu + - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +#include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros + +char ssid[] = SECRET_SSID; // your network SSID (name) +char pass[] = SECRET_PASS; // your network password +int keyIndex = 0; // your network key Index number (needed only for WEP) +WiFiClient client; + +// Weather station channel details +unsigned long weatherStationChannelNumber = SECRET_CH_ID_WEATHER_STATION; + +int statusCode = 0; +int field[8] = {1,2,3,4,5,6,7,8}; + +void setup() { + Serial.begin(115200); // Initialize serial + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + WiFi.mode(WIFI_STA); + + ThingSpeak.begin(client); // Initialize ThingSpeak + + // Connect or reconnect to WiFi + if(WiFi.status() != WL_CONNECTED){ + Serial.print("Attempting to connect to SSID: "); + Serial.println(SECRET_SSID); + while(WiFi.status() != WL_CONNECTED){ + WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network + Serial.print("."); + delay(5000); + } + Serial.println("\nConnected"); + } +} + +void loop() { + + // Read and store all the latest field values, location coordinates, status message, and created-at timestamp + // use ThingSpeak.readMultipleFields(channelNumber, readAPIKey) for private channels + statusCode = ThingSpeak.readMultipleFields(weatherStationChannelNumber); + + if(statusCode == 200) + { + // Fetch the stored data + + int windDir = ThingSpeak.getFieldAsInt(field[0]); // Field 1 + float windSpeed = ThingSpeak.getFieldAsFloat(field[1]); // Field 2 + int percentHumid = ThingSpeak.getFieldAsInt(field[2]); // Field 3 + float tempInF = ThingSpeak.getFieldAsFloat(field[3]); // Field 4 + float rainInchPerMin = ThingSpeak.getFieldAsFloat(field[4]); // Field 5 + float pressureInHg = ThingSpeak.getFieldAsFloat(field[5]); // Field 6 + float powerLevel = ThingSpeak.getFieldAsFloat(field[6]); // Field 7 + int lightIntensity = ThingSpeak.getFieldAsInt(field[7]); // Field 8 + String statusMessage = ThingSpeak.getStatus(); // Status message + String latitude = ThingSpeak.getLatitude(); // Latitude + String longitude = ThingSpeak.getLongitude(); // Longitude + String elevation = ThingSpeak.getElevation(); // Elevation + String createdAt = ThingSpeak.getCreatedAt(); // Created-at timestamp + + Serial.println("Wind Direction (North = 0 degrees): " + String(windDir)); + Serial.println("Wind Speed (mph): " + String(windSpeed)); + Serial.println("% Humidity: " + String(percentHumid)); + Serial.println("Temperature (F): " + String(tempInF)); + Serial.println("Rain (Inches/minute): " + String(rainInchPerMin)); + Serial.println("Pressure (\"Hg): " + String(pressureInHg)); + Serial.println("Power Level (V): " + String(powerLevel)); + Serial.println("Light Intensity: " + String(lightIntensity)); + Serial.println("Status Message, if any: " + statusMessage); + Serial.println("Latitude, if any (+ve is North, -ve is South): " + latitude); + Serial.println("Longitude, if any (+ve is East, -ve is West): " + longitude); + Serial.println("Elevation, if any (meters above sea level): " + elevation); + Serial.println("Created at, if any (YYYY-MM-DD hh:mm:ss): " + createdAt); + } + else{ + Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); + } + + Serial.println(); + delay(5000); // no need to fetch too often + +} diff --git a/examples/ESP32/ReadMultipleFields/secrets.h b/examples/ESP32/ReadMultipleFields/secrets.h new file mode 100644 index 0000000..f523bd5 --- /dev/null +++ b/examples/ESP32/ReadMultipleFields/secrets.h @@ -0,0 +1,7 @@ +// Use this file to store all of the private credentials +// and connection details + +#define SECRET_SSID "MySSID" // replace MySSID with your WiFi network name +#define SECRET_PASS "MyPassword" // replace MyPassword with your WiFi password + +#define SECRET_CH_ID_WEATHER_STATION 12397 //MathWorks weather station diff --git a/examples/ESP32/ReadMultipleFieldsSecure/ReadMultipleFieldsSecure.ino b/examples/ESP32/ReadMultipleFieldsSecure/ReadMultipleFieldsSecure.ino new file mode 100644 index 0000000..27231de --- /dev/null +++ b/examples/ESP32/ReadMultipleFieldsSecure/ReadMultipleFieldsSecure.ino @@ -0,0 +1,119 @@ +/* + ReadMultipleFields + + Description: Demonstates reading from a public channel which requires no API key (reading from a private channel requires a read API key). + The values read from the public channel is the current wind direction, wind speed, humidity, outside temperature, rain, pressure, + power level, and light intensity at MathWorks headquaters in Natick, MA.The functionality also provides us to read the + status message, location coordinates, and created-at timestamp associated with the latest feed over secured HTTPS connection. + + Hardware: ESP32 based boards + + !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! + + Note: + - Requires installation of EPS32 core and WiFiClientSecure library. See https://github.com/espressif/arduino-esp32/blob/master/docs/arduino-ide/boards_manager.md for details. + - Select the target hardware from the Tools->Board menu + - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +#define TS_ENABLE_SSL // For HTTPS SSL connection + +#include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros + +char ssid[] = SECRET_SSID; // your network SSID (name) +char pass[] = SECRET_PASS; // your network password +int keyIndex = 0; // your network key Index number (needed only for WEP) +WiFiClientSecure client; + +// Weather station channel details +unsigned long weatherStationChannelNumber = SECRET_CH_ID_WEATHER_STATION; + +// Root Certificate Check, make sure that the root certificate has not expired +const char* certificate = SECRET_TS_ROOT_CA; + +int statusCode = 0; +int field[8] = {1,2,3,4,5,6,7,8}; + +void setup() { + Serial.begin(115200); // Initialize serial + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + WiFi.mode(WIFI_STA); + + client.setCACert(certificate); // Set Root Certificate for authenticity check + + ThingSpeak.begin(client); // Initialize ThingSpeak + + // Connect or reconnect to WiFi + if(WiFi.status() != WL_CONNECTED){ + Serial.print("Attempting to connect to SSID: "); + Serial.println(SECRET_SSID); + while(WiFi.status() != WL_CONNECTED){ + WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network + Serial.print("."); + delay(5000); + } + Serial.println("\nConnected"); + } +} + +void loop() { + + // Read and store all the latest field values, location coordinates, status message, and created-at timestamp + // use ThingSpeak.readMultipleFields(channelNumber, readAPIKey) for private channels + statusCode = ThingSpeak.readMultipleFields(weatherStationChannelNumber); + + if(statusCode == 200) + { + // Fetch the stored data + + int windDir = ThingSpeak.getFieldAsInt(field[0]); // Field 1 + float windSpeed = ThingSpeak.getFieldAsFloat(field[1]); // Field 2 + int percentHumid = ThingSpeak.getFieldAsInt(field[2]); // Field 3 + float tempInF = ThingSpeak.getFieldAsFloat(field[3]); // Field 4 + float rainInchPerMin = ThingSpeak.getFieldAsFloat(field[4]); // Field 5 + float pressureInHg = ThingSpeak.getFieldAsFloat(field[5]); // Field 6 + float powerLevel = ThingSpeak.getFieldAsFloat(field[6]); // Field 7 + int lightIntensity = ThingSpeak.getFieldAsInt(field[7]); // Field 8 + String statusMessage = ThingSpeak.getStatus(); // Status message + String latitude = ThingSpeak.getLatitude(); // Latitude + String longitude = ThingSpeak.getLongitude(); // Longitude + String elevation = ThingSpeak.getElevation(); // Elevation + String createdAt = ThingSpeak.getCreatedAt(); // Created-at timestamp + + Serial.println("Wind Direction (North = 0 degrees): " + String(windDir)); + Serial.println("Wind Speed (mph): " + String(windSpeed)); + Serial.println("% Humidity: " + String(percentHumid)); + Serial.println("Temperature (F): " + String(tempInF)); + Serial.println("Rain (Inches/minute): " + String(rainInchPerMin)); + Serial.println("Pressure (\"Hg): " + String(pressureInHg)); + Serial.println("Power Level (V): " + String(powerLevel)); + Serial.println("Light Intensity: " + String(lightIntensity)); + Serial.println("Status Message, if any: " + statusMessage); + Serial.println("Latitude, if any (+ve is North, -ve is South): " + latitude); + Serial.println("Longitude, if any (+ve is East, -ve is West): " + longitude); + Serial.println("Elevation, if any (meters above sea level): " + elevation); + Serial.println("Created at, if any (YYYY-MM-DD hh:mm:ss): " + createdAt); + } + else{ + Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); + } + + Serial.println(); + delay(5000); // no need to fetch too often + +} diff --git a/examples/ESP32/ReadMultipleFieldsSecure/secrets.h b/examples/ESP32/ReadMultipleFieldsSecure/secrets.h new file mode 100644 index 0000000..57697ae --- /dev/null +++ b/examples/ESP32/ReadMultipleFieldsSecure/secrets.h @@ -0,0 +1,32 @@ +// Use this file to store all of the private credentials +// and connection details + +#define SECRET_SSID "MySSID" // replace MySSID with your WiFi network name +#define SECRET_PASS "MyPassword" // replace MyPassword with your WiFi password + +#define SECRET_CH_ID_WEATHER_STATION 12397 //MathWorks weather station + +// ThingSpeak Root Certificate, Expiration Date: November 9, 2031 at 7:00:00 PM EST +#define SECRET_TS_ROOT_CA "-----BEGIN CERTIFICATE-----\n" \ +"MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs\n" \ +"MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n" \ +"d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j\n" \ +"ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL\n" \ +"MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3\n" \ +"LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug\n" \ +"RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm\n" \ +"+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW\n" \ +"PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM\n" \ +"xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB\n" \ +"Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3\n" \ +"hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg\n" \ +"EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF\n" \ +"MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA\n" \ +"FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec\n" \ +"nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z\n" \ +"eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF\n" \ +"hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2\n" \ +"Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe\n" \ +"vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep\n" \ +"+OkuE6N36B9K\n" \ +"-----END CERTIFICATE-----\n" diff --git a/examples/ESP32/WriteMultipleFields/WriteMultipleFields.ino b/examples/ESP32/WriteMultipleFields/WriteMultipleFields.ino index accec61..571544f 100644 --- a/examples/ESP32/WriteMultipleFields/WriteMultipleFields.ino +++ b/examples/ESP32/WriteMultipleFields/WriteMultipleFields.ino @@ -1,105 +1,108 @@ -/* - WriteMultipleFields - - Description: Writes values to fields 1,2,3,4 and status in a single ThingSpeak update every 20 seconds. - - Hardware: ESP32 based boards - - !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! - - Note: - - Requires installation of EPS32 core. See https://github.com/espressif/arduino-esp32/blob/master/docs/arduino-ide/boards_manager.md for details. - - Select the target hardware from the Tools->Board menu - - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. - - ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and - analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. - - Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. - See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. - - For licensing information, see the accompanying license file. - - Copyright 2018, The MathWorks, Inc. -*/ - -#include "ThingSpeak.h" -#include "secrets.h" -#include - -char ssid[] = SECRET_SSID; // your network SSID (name) -char pass[] = SECRET_PASS; // your network password -int keyIndex = 0; // your network key Index number (needed only for WEP) -WiFiClient client; - -unsigned long myChannelNumber = SECRET_CH_ID; -const char * myWriteAPIKey = SECRET_WRITE_APIKEY; - -// Initialize our values -int number1 = 0; -int number2 = random(0,100); -int number3 = random(0,100); -int number4 = random(0,100); -String myStatus = ""; - -void setup() { - Serial.begin(115200); //Initialize serial - - WiFi.mode(WIFI_STA); - ThingSpeak.begin(client); // Initialize ThingSpeak -} - -void loop() { - - // Connect or reconnect to WiFi - if(WiFi.status() != WL_CONNECTED){ - Serial.print("Attempting to connect to SSID: "); - Serial.println(SECRET_SSID); - while(WiFi.status() != WL_CONNECTED){ - WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network - Serial.print("."); - delay(5000); - } - Serial.println("\nConnected."); - } - - // set the fields with the values - ThingSpeak.setField(1, number1); - ThingSpeak.setField(2, number2); - ThingSpeak.setField(3, number3); - ThingSpeak.setField(4, number4); - - // figure out the status message - if(number1 > number2){ - myStatus = String("field1 is greater than field2"); - } - else if(number1 < number2){ - myStatus = String("field1 is less than field2"); - } - else{ - myStatus = String("field1 equals field2"); - } - - // set the status - ThingSpeak.setStatus(myStatus); - - // write to the ThingSpeak channel - int x = ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey); - if(x == 200){ - Serial.println("Channel update successful."); - } - else{ - Serial.println("Problem updating channel. HTTP error code " + String(x)); - } - - // change the values - number1++; - if(number1 > 99){ - number1 = 0; - } - number2 = random(0,100); - number3 = random(0,100); - number4 = random(0,100); - - delay(20000); // Wait 20 seconds to update the channel again -} +/* + WriteMultipleFields + + Description: Writes values to fields 1,2,3,4 and status in a single ThingSpeak update every 20 seconds. + + Hardware: ESP32 based boards + + !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! + + Note: + - Requires installation of EPS32 core. See https://github.com/espressif/arduino-esp32/blob/master/docs/arduino-ide/boards_manager.md for details. + - Select the target hardware from the Tools->Board menu + - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +#include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros + +char ssid[] = SECRET_SSID; // your network SSID (name) +char pass[] = SECRET_PASS; // your network password +int keyIndex = 0; // your network key Index number (needed only for WEP) +WiFiClient client; + +unsigned long myChannelNumber = SECRET_CH_ID; +const char * myWriteAPIKey = SECRET_WRITE_APIKEY; + +// Initialize our values +int number1 = 0; +int number2 = random(0,100); +int number3 = random(0,100); +int number4 = random(0,100); +String myStatus = ""; + +void setup() { + Serial.begin(115200); //Initialize serial + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + WiFi.mode(WIFI_STA); + ThingSpeak.begin(client); // Initialize ThingSpeak +} + +void loop() { + + // Connect or reconnect to WiFi + if(WiFi.status() != WL_CONNECTED){ + Serial.print("Attempting to connect to SSID: "); + Serial.println(SECRET_SSID); + while(WiFi.status() != WL_CONNECTED){ + WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network + Serial.print("."); + delay(5000); + } + Serial.println("\nConnected."); + } + + // set the fields with the values + ThingSpeak.setField(1, number1); + ThingSpeak.setField(2, number2); + ThingSpeak.setField(3, number3); + ThingSpeak.setField(4, number4); + + // figure out the status message + if(number1 > number2){ + myStatus = String("field1 is greater than field2"); + } + else if(number1 < number2){ + myStatus = String("field1 is less than field2"); + } + else{ + myStatus = String("field1 equals field2"); + } + + // set the status + ThingSpeak.setStatus(myStatus); + + // write to the ThingSpeak channel + int x = ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey); + if(x == 200){ + Serial.println("Channel update successful."); + } + else{ + Serial.println("Problem updating channel. HTTP error code " + String(x)); + } + + // change the values + number1++; + if(number1 > 99){ + number1 = 0; + } + number2 = random(0,100); + number3 = random(0,100); + number4 = random(0,100); + + delay(20000); // Wait 20 seconds to update the channel again +} diff --git a/examples/ESP32/WriteMultipleFieldsSecure/WriteMultipleFieldsSecure.ino b/examples/ESP32/WriteMultipleFieldsSecure/WriteMultipleFieldsSecure.ino new file mode 100644 index 0000000..81e5e85 --- /dev/null +++ b/examples/ESP32/WriteMultipleFieldsSecure/WriteMultipleFieldsSecure.ino @@ -0,0 +1,112 @@ +/* + WriteMultipleFields + + Description: Writes values to fields 1,2,3,4 and status in a single ThingSpeak update every 20 seconds over secured HTTPS connection. + + Hardware: ESP32 based boards + + !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! + + Note: + - Requires installation of EPS32 core and WiFiClientSecure library. See https://github.com/espressif/arduino-esp32/blob/master/docs/arduino-ide/boards_manager.md for details. + - Select the target hardware from the Tools->Board menu + - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +#define TS_ENABLE_SSL // For HTTPS SSL connection + +#include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros + +char ssid[] = SECRET_SSID; // your network SSID (name) +char pass[] = SECRET_PASS; // your network password +int keyIndex = 0; // your network key Index number (needed only for WEP) +WiFiClientSecure client; + +unsigned long myChannelNumber = SECRET_CH_ID; +const char * myWriteAPIKey = SECRET_WRITE_APIKEY; + +// Initialize our values +int number1 = 0; +int number2 = random(0,100); +int number3 = random(0,100); +int number4 = random(0,100); +String myStatus = ""; + +const char * fingerprint = SECRET_SHA1_FINGERPRINT; + +void setup() { + Serial.begin(115200); //Initialize serial + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + WiFi.mode(WIFI_STA); + ThingSpeak.begin(client); // Initialize ThingSpeak +} + +void loop() { + + // Connect or reconnect to WiFi + if(WiFi.status() != WL_CONNECTED){ + Serial.print("Attempting to connect to SSID: "); + Serial.println(SECRET_SSID); + while(WiFi.status() != WL_CONNECTED){ + WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network + Serial.print("."); + delay(5000); + } + Serial.println("\nConnected."); + } + + // set the fields with the values + ThingSpeak.setField(1, number1); + ThingSpeak.setField(2, number2); + ThingSpeak.setField(3, number3); + ThingSpeak.setField(4, number4); + + // figure out the status message + if(number1 > number2){ + myStatus = String("field1 is greater than field2"); + } + else if(number1 < number2){ + myStatus = String("field1 is less than field2"); + } + else{ + myStatus = String("field1 equals field2"); + } + + // set the status + ThingSpeak.setStatus(myStatus); + + // write to the ThingSpeak channel + int x = ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey); + if(x == 200){ + Serial.println("Channel update successful."); + } + else{ + Serial.println("Problem updating channel. HTTP error code " + String(x)); + } + + // change the values + number1++; + if(number1 > 99){ + number1 = 0; + } + number2 = random(0,100); + number3 = random(0,100); + number4 = random(0,100); + + delay(5000); // Wait 20 seconds to update the channel again +} diff --git a/examples/ESP32/WriteMultipleFieldsSecure/secrets.h b/examples/ESP32/WriteMultipleFieldsSecure/secrets.h new file mode 100644 index 0000000..8c0539d --- /dev/null +++ b/examples/ESP32/WriteMultipleFieldsSecure/secrets.h @@ -0,0 +1,8 @@ +// Use this file to store all of the private credentials +// and connection details + +#define SECRET_SSID "MySSID" // replace MySSID with your WiFi network name +#define SECRET_PASS "MyPassword" // replace MyPassword with your WiFi password + +#define SECRET_CH_ID 000000 // replace 0000000 with your channel number +#define SECRET_WRITE_APIKEY "XYZ" // replace XYZ with your channel write API Key diff --git a/examples/ESP32/WriteSingleField/WriteSingleField.ino b/examples/ESP32/WriteSingleField/WriteSingleField.ino index 9183448..2e71c7a 100644 --- a/examples/ESP32/WriteSingleField/WriteSingleField.ino +++ b/examples/ESP32/WriteSingleField/WriteSingleField.ino @@ -1,78 +1,81 @@ -/* - WriteSingleField - - Description: Writes a value to a channel on ThingSpeak every 20 seconds. - - Hardware: ESP32 based boards - - !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! - - Note: - - Requires installation of EPS32 core. See https://github.com/espressif/arduino-esp32/blob/master/docs/arduino-ide/boards_manager.md for details. - - Select the target hardware from the Tools->Board menu - - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. - - ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and - analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. - - Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. - See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. - - For licensing information, see the accompanying license file. - - Copyright 2018, The MathWorks, Inc. -*/ - -#include "ThingSpeak.h" -#include "secrets.h" -#include - -char ssid[] = SECRET_SSID; // your network SSID (name) -char pass[] = SECRET_PASS; // your network password -int keyIndex = 0; // your network key Index number (needed only for WEP) -WiFiClient client; - -unsigned long myChannelNumber = SECRET_CH_ID; -const char * myWriteAPIKey = SECRET_WRITE_APIKEY; - -int number = 0; - -void setup() { - Serial.begin(115200); //Initialize serial - - WiFi.mode(WIFI_STA); - ThingSpeak.begin(client); // Initialize ThingSpeak -} - -void loop() { - - // Connect or reconnect to WiFi - if(WiFi.status() != WL_CONNECTED){ - Serial.print("Attempting to connect to SSID: "); - Serial.println(SECRET_SSID); - while(WiFi.status() != WL_CONNECTED){ - WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network - Serial.print("."); - delay(5000); - } - Serial.println("\nConnected."); - } - - // Write to ThingSpeak. There are up to 8 fields in a channel, allowing you to store up to 8 different - // pieces of information in a channel. Here, we write to field 1. - int x = ThingSpeak.writeField(myChannelNumber, 1, number, myWriteAPIKey); - if(x == 200){ - Serial.println("Channel update successful."); - } - else{ - Serial.println("Problem updating channel. HTTP error code " + String(x)); - } - - // change the value - number++; - if(number > 99){ - number = 0; - } - - delay(20000); // Wait 20 seconds to update the channel again -} +/* + WriteSingleField + + Description: Writes a value to a channel on ThingSpeak every 20 seconds. + + Hardware: ESP32 based boards + + !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! + + Note: + - Requires installation of EPS32 core. See https://github.com/espressif/arduino-esp32/blob/master/docs/arduino-ide/boards_manager.md for details. + - Select the target hardware from the Tools->Board menu + - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +#include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros + +char ssid[] = SECRET_SSID; // your network SSID (name) +char pass[] = SECRET_PASS; // your network password +int keyIndex = 0; // your network key Index number (needed only for WEP) +WiFiClient client; + +unsigned long myChannelNumber = SECRET_CH_ID; +const char * myWriteAPIKey = SECRET_WRITE_APIKEY; + +int number = 0; + +void setup() { + Serial.begin(115200); //Initialize serial + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + WiFi.mode(WIFI_STA); + ThingSpeak.begin(client); // Initialize ThingSpeak +} + +void loop() { + + // Connect or reconnect to WiFi + if(WiFi.status() != WL_CONNECTED){ + Serial.print("Attempting to connect to SSID: "); + Serial.println(SECRET_SSID); + while(WiFi.status() != WL_CONNECTED){ + WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network + Serial.print("."); + delay(5000); + } + Serial.println("\nConnected."); + } + + // Write to ThingSpeak. There are up to 8 fields in a channel, allowing you to store up to 8 different + // pieces of information in a channel. Here, we write to field 1. + int x = ThingSpeak.writeField(myChannelNumber, 1, number, myWriteAPIKey); + if(x == 200){ + Serial.println("Channel update successful."); + } + else{ + Serial.println("Problem updating channel. HTTP error code " + String(x)); + } + + // change the value + number++; + if(number > 99){ + number = 0; + } + + delay(20000); // Wait 20 seconds to update the channel again +} diff --git a/examples/ESP32/WriteSingleFieldSecure/WriteSingleFieldSecure.ino b/examples/ESP32/WriteSingleFieldSecure/WriteSingleFieldSecure.ino new file mode 100644 index 0000000..ed084f9 --- /dev/null +++ b/examples/ESP32/WriteSingleFieldSecure/WriteSingleFieldSecure.ino @@ -0,0 +1,83 @@ +/* + WriteSingleField + + Description: Writes a value to a channel on ThingSpeak every 20 seconds over secured HTTPS connection. + + Hardware: ESP32 based boards + + !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! + + Note: + - Requires installation of EPS32 core and WiFiClientSecure library. See https://github.com/espressif/arduino-esp32/blob/master/docs/arduino-ide/boards_manager.md for details. + - Select the target hardware from the Tools->Board menu + - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +#define TS_ENABLE_SSL // For HTTPS SSL connection + +#include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros + +char ssid[] = SECRET_SSID; // your network SSID (name) +char pass[] = SECRET_PASS; // your network password +int keyIndex = 0; // your network key Index number (needed only for WEP) +WiFiClientSecure client; + +unsigned long myChannelNumber = SECRET_CH_ID; +const char * myWriteAPIKey = SECRET_WRITE_APIKEY; + +int number = 0; + +void setup() { + Serial.begin(115200); //Initialize serial + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + WiFi.mode(WIFI_STA); + ThingSpeak.begin(client); // Initialize ThingSpeak +} + +void loop() { + + // Connect or reconnect to WiFi + if(WiFi.status() != WL_CONNECTED){ + Serial.print("Attempting to connect to SSID: "); + Serial.println(SECRET_SSID); + while(WiFi.status() != WL_CONNECTED){ + WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network + Serial.print("."); + delay(5000); + } + Serial.println("\nConnected."); + } + + // Write to ThingSpeak. There are up to 8 fields in a channel, allowing you to store up to 8 different + // pieces of information in a channel. Here, we write to field 1. + int x = ThingSpeak.writeField(myChannelNumber, 1, number, myWriteAPIKey); + if(x == 200){ + Serial.println("Channel update successful."); + } + else{ + Serial.println("Problem updating channel. HTTP error code " + String(x)); + } + + // change the value + number++; + if(number > 99){ + number = 0; + } + + delay(20000); // Wait 20 seconds to update the channel again +} diff --git a/examples/ESP32/WriteSingleFieldSecure/secrets.h b/examples/ESP32/WriteSingleFieldSecure/secrets.h new file mode 100644 index 0000000..8c0539d --- /dev/null +++ b/examples/ESP32/WriteSingleFieldSecure/secrets.h @@ -0,0 +1,8 @@ +// Use this file to store all of the private credentials +// and connection details + +#define SECRET_SSID "MySSID" // replace MySSID with your WiFi network name +#define SECRET_PASS "MyPassword" // replace MyPassword with your WiFi password + +#define SECRET_CH_ID 000000 // replace 0000000 with your channel number +#define SECRET_WRITE_APIKEY "XYZ" // replace XYZ with your channel write API Key diff --git a/examples/ESP8266/program board directly/ReadField/ReadField.ino b/examples/ESP8266/program board directly/ReadField/ReadField.ino index ad27918..0ba7ed7 100644 --- a/examples/ESP8266/program board directly/ReadField/ReadField.ino +++ b/examples/ESP8266/program board directly/ReadField/ReadField.ino @@ -22,12 +22,12 @@ For licensing information, see the accompanying license file. - Copyright 2018, The MathWorks, Inc. + Copyright 2020, The MathWorks, Inc. */ -#include "ThingSpeak.h" -#include "secrets.h" #include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros char ssid[] = SECRET_SSID; // your network SSID (name) char pass[] = SECRET_PASS; // your network password @@ -45,7 +45,10 @@ unsigned int counterFieldNumber = 1; void setup() { Serial.begin(115200); // Initialize serial - + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + WiFi.mode(WIFI_STA); ThingSpeak.begin(client); // Initialize ThingSpeak } diff --git a/examples/ESP8266/program board directly/ReadFieldSecure/ReadFieldSecure.ino b/examples/ESP8266/program board directly/ReadFieldSecure/ReadFieldSecure.ino new file mode 100644 index 0000000..0717669 --- /dev/null +++ b/examples/ESP8266/program board directly/ReadFieldSecure/ReadFieldSecure.ino @@ -0,0 +1,114 @@ +/* + ReadField + + Description: Demonstates reading from a public channel which requires no API key and reading from a private channel which requires a read API key. + The value read from the public channel is the current outside temperature at MathWorks headquaters in Natick, MA. The value from the + private channel is an example counter that increments every 10 seconds over secured HTTPS connection. + + Hardware: ESP8266 based boards + + !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! + + Note: + - Requires ESP8266WiFi library, WiFiClientSecure library and ESP8622 board add-on. See https://github.com/esp8266/Arduino for details. + - Select the target hardware from the Tools->Board menu + - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +#define TS_ENABLE_SSL // For HTTPS SSL connection + +#include +#include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros + +char ssid[] = SECRET_SSID; // your network SSID (name) +char pass[] = SECRET_PASS; // your network password +int keyIndex = 0; // your network key Index number (needed only for WEP) +WiFiClientSecure client; + +// Weather station channel details +unsigned long weatherStationChannelNumber = SECRET_CH_ID_WEATHER_STATION; +unsigned int temperatureFieldNumber = 4; + +// Counting channel details +unsigned long counterChannelNumber = SECRET_CH_ID_COUNTER; +const char * myCounterReadAPIKey = SECRET_READ_APIKEY_COUNTER; +unsigned int counterFieldNumber = 1; + +// Fingerprint check, make sure that the certificate has not expired. +const char * fingerprint = NULL; // use SECRET_SHA1_FINGERPRINT for fingerprint check + +void setup() { + Serial.begin(115200); // Initialize serial + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + WiFi.mode(WIFI_STA); + + if(fingerprint!=NULL){ + client.setFingerprint(fingerprint); + } + else{ + client.setInsecure(); // To perform a simple SSL Encryption + } + + ThingSpeak.begin(client); // Initialize ThingSpeak +} + +void loop() { + + int statusCode = 0; + + // Connect or reconnect to WiFi + if(WiFi.status() != WL_CONNECTED){ + Serial.print("Attempting to connect to SSID: "); + Serial.println(SECRET_SSID); + while(WiFi.status() != WL_CONNECTED){ + WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network + Serial.print("."); + delay(5000); + } + Serial.println("\nConnected"); + } + + // Read in field 4 of the public channel recording the temperature + float temperatureInF = ThingSpeak.readFloatField(weatherStationChannelNumber, temperatureFieldNumber); + + // Check the status of the read operation to see if it was successful + statusCode = ThingSpeak.getLastReadStatus(); + if(statusCode == 200){ + Serial.println("Temperature at MathWorks HQ: " + String(temperatureInF) + " deg F"); + } + else{ + Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); + } + + delay(15000); // No need to read the temperature too often. + + // Read in field 1 of the private channel which is a counter + long count = ThingSpeak.readLongField(counterChannelNumber, counterFieldNumber, myCounterReadAPIKey); + + // Check the status of the read operation to see if it was successful + statusCode = ThingSpeak.getLastReadStatus(); + if(statusCode == 200){ + Serial.println("Counter: " + String(count)); + } + else{ + Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); + } + + delay(15000); // No need to read the counter too often. + +} diff --git a/examples/ESP8266/program board directly/ReadFieldSecure/secrets.h b/examples/ESP8266/program board directly/ReadFieldSecure/secrets.h new file mode 100644 index 0000000..20a0d0c --- /dev/null +++ b/examples/ESP8266/program board directly/ReadFieldSecure/secrets.h @@ -0,0 +1,13 @@ +// Use this file to store all of the private credentials +// and connection details + +#define SECRET_SSID "MySSID" // replace MySSID with your WiFi network name +#define SECRET_PASS "MyPassword" // replace MyPassword with your WiFi password + +#define SECRET_CH_ID_WEATHER_STATION 12397 //MathWorks weather station + +#define SECRET_CH_ID_COUNTER 298725 //Test channel for counting +#define SECRET_READ_APIKEY_COUNTER "SODG0O2UZVGKWAWG" //API Key for Test channel + +// ThingSpeak Certificate Fingerprint, Expiration Date: August 3, 2022 at 8:00:00 AM EST +#define SECRET_SHA1_FINGERPRINT "27 18 92 DD A4 26 C3 07 09 B9 7A E6 C5 21 B9 5B 48 F7 16 E1" diff --git a/examples/ESP8266/program board directly/ReadMultipleFields/ReadMultipleFields.ino b/examples/ESP8266/program board directly/ReadMultipleFields/ReadMultipleFields.ino new file mode 100644 index 0000000..69fed4b --- /dev/null +++ b/examples/ESP8266/program board directly/ReadMultipleFields/ReadMultipleFields.ino @@ -0,0 +1,113 @@ +/* + ReadMultipleFields + + Description: Demonstates reading from a public channel which requires no API key (reading from a private channel requires a read API key). + The values read from the public channel is the current wind direction, wind speed, humidity, outside temperature, rain, pressure, + power level, and light intensity at MathWorks headquaters in Natick, MA.The functionality also provides us to read the + status message, location coordinates, and created-at timestamp associated with the latest feed. + + Hardware: ESP8266 based boards + + !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! + + Note: + - Requires ESP8266WiFi library and ESP8622 board add-on. See https://github.com/esp8266/Arduino for details. + - Select the target hardware from the Tools->Board menu + - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +#include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros + +char ssid[] = SECRET_SSID; // your network SSID (name) +char pass[] = SECRET_PASS; // your network password +int keyIndex = 0; // your network key Index number (needed only for WEP) +WiFiClient client; + +// Weather station channel details +unsigned long weatherStationChannelNumber = SECRET_CH_ID_WEATHER_STATION; + +// +int statusCode = 0; +int field[8] = {1,2,3,4,5,6,7,8}; + +void setup() { + Serial.begin(115200); // Initialize serial + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + WiFi.mode(WIFI_STA); + + ThingSpeak.begin(client); // Initialize ThingSpeak + + // Connect or reconnect to WiFi + if(WiFi.status() != WL_CONNECTED){ + Serial.print("Attempting to connect to SSID: "); + Serial.println(SECRET_SSID); + while(WiFi.status() != WL_CONNECTED){ + WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network + Serial.print("."); + delay(5000); + } + Serial.println("\nConnected"); + } +} + +void loop() { + + // Read and store all the latest field values, location coordinates, status message, and created-at timestamp + // use ThingSpeak.readMultipleFields(channelNumber, readAPIKey) for private channels + statusCode = ThingSpeak.readMultipleFields(weatherStationChannelNumber); + + if(statusCode == 200) + { + // Fetch the stored data + + int windDir = ThingSpeak.getFieldAsInt(field[0]); // Field 1 + float windSpeed = ThingSpeak.getFieldAsFloat(field[1]); // Field 2 + int percentHumid = ThingSpeak.getFieldAsInt(field[2]); // Field 3 + float tempInF = ThingSpeak.getFieldAsFloat(field[3]); // Field 4 + float rainInchPerMin = ThingSpeak.getFieldAsFloat(field[4]); // Field 5 + float pressureInHg = ThingSpeak.getFieldAsFloat(field[5]); // Field 6 + float powerLevel = ThingSpeak.getFieldAsFloat(field[6]); // Field 7 + int lightIntensity = ThingSpeak.getFieldAsInt(field[7]); // Field 8 + String statusMessage = ThingSpeak.getStatus(); // Status message + String latitude = ThingSpeak.getLatitude(); // Latitude + String longitude = ThingSpeak.getLongitude(); // Longitude + String elevation = ThingSpeak.getElevation(); // Elevation + String createdAt = ThingSpeak.getCreatedAt(); // Created-at timestamp + + Serial.println("Wind Direction (North = 0 degrees): " + String(windDir)); + Serial.println("Wind Speed (mph): " + String(windSpeed)); + Serial.println("% Humidity: " + String(percentHumid)); + Serial.println("Temperature (F): " + String(tempInF)); + Serial.println("Rain (Inches/minute): " + String(rainInchPerMin)); + Serial.println("Pressure (\"Hg): " + String(pressureInHg)); + Serial.println("Power Level (V): " + String(powerLevel)); + Serial.println("Light Intensity: " + String(lightIntensity)); + Serial.println("Status Message, if any: " + statusMessage); + Serial.println("Latitude, if any (+ve is North, -ve is South): " + latitude); + Serial.println("Longitude, if any (+ve is East, -ve is West): " + longitude); + Serial.println("Elevation, if any (meters above sea level): " + elevation); + Serial.println("Created at, if any (YYYY-MM-DD hh:mm:ss): " + createdAt); + } + else{ + Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); + } + + Serial.println(); + delay(5000); // no need to fetch too often + +} diff --git a/examples/ESP8266/program board directly/ReadMultipleFields/secrets.h b/examples/ESP8266/program board directly/ReadMultipleFields/secrets.h new file mode 100644 index 0000000..f523bd5 --- /dev/null +++ b/examples/ESP8266/program board directly/ReadMultipleFields/secrets.h @@ -0,0 +1,7 @@ +// Use this file to store all of the private credentials +// and connection details + +#define SECRET_SSID "MySSID" // replace MySSID with your WiFi network name +#define SECRET_PASS "MyPassword" // replace MyPassword with your WiFi password + +#define SECRET_CH_ID_WEATHER_STATION 12397 //MathWorks weather station diff --git a/examples/ESP8266/program board directly/ReadMultipleFieldsSecure/ReadMultipleFieldsSecure.ino b/examples/ESP8266/program board directly/ReadMultipleFieldsSecure/ReadMultipleFieldsSecure.ino new file mode 100644 index 0000000..a793692 --- /dev/null +++ b/examples/ESP8266/program board directly/ReadMultipleFieldsSecure/ReadMultipleFieldsSecure.ino @@ -0,0 +1,125 @@ +/* + ReadMultipleFields + + Description: Demonstates reading from a public channel which requires no API key (reading from a private channel requires a read API key). + The values read from the public channel is the current wind direction, wind speed, humidity, outside temperature, rain, pressure, + power level, and light intensity at MathWorks headquaters in Natick, MA.The functionality also provides us to read the + status message, location coordinates, and created-at timestamp associated with the latest feed over secured HTTPS connection. + + Hardware: ESP8266 based boards + + !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! + + Note: + - Requires ESP8266WiFi library, WiFiClientSecure library and ESP8622 board add-on. See https://github.com/esp8266/Arduino for details. + - Select the target hardware from the Tools->Board menu + - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +#define TS_ENABLE_SSL // For HTTPS SSL connection + +#include +#include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros + +char ssid[] = SECRET_SSID; // your network SSID (name) +char pass[] = SECRET_PASS; // your network password +int keyIndex = 0; // your network key Index number (needed only for WEP) +WiFiClientSecure client; + +// Weather station channel details +unsigned long weatherStationChannelNumber = SECRET_CH_ID_WEATHER_STATION; + +int statusCode = 0; +int field[8] = {1,2,3,4,5,6,7,8}; + +// Fingerprint check, make sure that the certificate has not expired. +const char * fingerprint = SECRET_SHA1_FINGERPRINT; // use SECRET_SHA1_FINGERPRINT for fingerprint check + +void setup() { + Serial.begin(115200); // Initialize serial + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + WiFi.mode(WIFI_STA); + + if(fingerprint!=NULL){ + client.setFingerprint(fingerprint); + } + else{ + client.setInsecure(); // To perform a simple SSL Encryption + } + + ThingSpeak.begin(client); // Initialize ThingSpeak + + // Connect or reconnect to WiFi + if(WiFi.status() != WL_CONNECTED){ + Serial.print("Attempting to connect to SSID: "); + Serial.println(SECRET_SSID); + while(WiFi.status() != WL_CONNECTED){ + WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network + Serial.print("."); + delay(5000); + } + Serial.println("\nConnected"); + } +} + +void loop() { + + // Read and store all the latest field values, location coordinates, status message, and created-at timestamp + // use ThingSpeak.readMultipleFields(channelNumber, readAPIKey) for private channels + statusCode = ThingSpeak.readMultipleFields(weatherStationChannelNumber); + + if(statusCode == 200) + { + // Fetch the stored data + + int windDir = ThingSpeak.getFieldAsInt(field[0]); // Field 1 + float windSpeed = ThingSpeak.getFieldAsFloat(field[1]); // Field 2 + int percentHumid = ThingSpeak.getFieldAsInt(field[2]); // Field 3 + float tempInF = ThingSpeak.getFieldAsFloat(field[3]); // Field 4 + float rainInchPerMin = ThingSpeak.getFieldAsFloat(field[4]); // Field 5 + float pressureInHg = ThingSpeak.getFieldAsFloat(field[5]); // Field 6 + float powerLevel = ThingSpeak.getFieldAsFloat(field[6]); // Field 7 + int lightIntensity = ThingSpeak.getFieldAsInt(field[7]); // Field 8 + String statusMessage = ThingSpeak.getStatus(); // Status message + String latitude = ThingSpeak.getLatitude(); // Latitude + String longitude = ThingSpeak.getLongitude(); // Longitude + String elevation = ThingSpeak.getElevation(); // Elevation + String createdAt = ThingSpeak.getCreatedAt(); // Created-at timestamp + + Serial.println("Wind Direction (North = 0 degrees): " + String(windDir)); + Serial.println("Wind Speed (mph): " + String(windSpeed)); + Serial.println("% Humidity: " + String(percentHumid)); + Serial.println("Temperature (F): " + String(tempInF)); + Serial.println("Rain (Inches/minute): " + String(rainInchPerMin)); + Serial.println("Pressure (\"Hg): " + String(pressureInHg)); + Serial.println("Power Level (V): " + String(powerLevel)); + Serial.println("Light Intensity: " + String(lightIntensity)); + Serial.println("Status Message, if any: " + statusMessage); + Serial.println("Latitude, if any (+ve is North, -ve is South): " + latitude); + Serial.println("Longitude, if any (+ve is East, -ve is West): " + longitude); + Serial.println("Elevation, if any (meters above sea level): " + elevation); + Serial.println("Created at, if any (YYYY-MM-DD hh:mm:ss): " + createdAt); + } + else{ + Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); + } + + Serial.println(); + delay(5000); // no need to fetch too often + +} diff --git a/examples/ESP8266/program board directly/ReadMultipleFieldsSecure/secrets.h b/examples/ESP8266/program board directly/ReadMultipleFieldsSecure/secrets.h new file mode 100644 index 0000000..bbac2ab --- /dev/null +++ b/examples/ESP8266/program board directly/ReadMultipleFieldsSecure/secrets.h @@ -0,0 +1,10 @@ +// Use this file to store all of the private credentials +// and connection details + +#define SECRET_SSID "MySSID" // replace MySSID with your WiFi network name +#define SECRET_PASS "MyPassword" // replace MyPassword with your WiFi password + +#define SECRET_CH_ID_WEATHER_STATION 12397 //MathWorks weather station + +// ThingSpeak Certificate Fingerprint, Expiration Date: August 3, 2022 at 8:00:00 AM EST +#define SECRET_SHA1_FINGERPRINT "27 18 92 DD A4 26 C3 07 09 B9 7A E6 C5 21 B9 5B 48 F7 16 E1" diff --git a/examples/ESP8266/program board directly/WriteMultipleFields/WriteMultipleFields.ino b/examples/ESP8266/program board directly/WriteMultipleFields/WriteMultipleFields.ino index bbde392..75d7cee 100644 --- a/examples/ESP8266/program board directly/WriteMultipleFields/WriteMultipleFields.ino +++ b/examples/ESP8266/program board directly/WriteMultipleFields/WriteMultipleFields.ino @@ -20,12 +20,12 @@ For licensing information, see the accompanying license file. - Copyright 2018, The MathWorks, Inc. + Copyright 2020, The MathWorks, Inc. */ -#include "ThingSpeak.h" -#include "secrets.h" #include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros char ssid[] = SECRET_SSID; // your network SSID (name) char pass[] = SECRET_PASS; // your network password @@ -44,7 +44,10 @@ String myStatus = ""; void setup() { Serial.begin(115200); // Initialize serial - + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + WiFi.mode(WIFI_STA); ThingSpeak.begin(client); // Initialize ThingSpeak } diff --git a/examples/ESP8266/program board directly/WriteMultipleFieldsSecure/WriteMultipleFieldsSecure.ino b/examples/ESP8266/program board directly/WriteMultipleFieldsSecure/WriteMultipleFieldsSecure.ino new file mode 100644 index 0000000..8f4eab6 --- /dev/null +++ b/examples/ESP8266/program board directly/WriteMultipleFieldsSecure/WriteMultipleFieldsSecure.ino @@ -0,0 +1,122 @@ +/* + WriteMultipleFields + + Description: Writes values to fields 1,2,3,4 and status in a single ThingSpeak update every 20 seconds over secured HTTPS connection. + + Hardware: ESP8266 based boards + + !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! + + Note: + - Requires ESP8266WiFi library, WiFiClientSecure library and ESP8622 board add-on. See https://github.com/esp8266/Arduino for details. + - Select the target hardware from the Tools->Board menu + - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +#define TS_ENABLE_SSL // For HTTPS SSL connection + +#include +#include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros + +char ssid[] = SECRET_SSID; // your network SSID (name) +char pass[] = SECRET_PASS; // your network password +int keyIndex = 0; // your network key Index number (needed only for WEP) +WiFiClientSecure client; + +unsigned long myChannelNumber = SECRET_CH_ID; +const char * myWriteAPIKey = SECRET_WRITE_APIKEY; + +// Initialize our values +int number1 = 0; +int number2 = random(0,100); +int number3 = random(0,100); +int number4 = random(0,100); +String myStatus = ""; + +// Fingerprint check, make sure that the certificate has not expired. +const char * fingerprint = NULL; // use SECRET_SHA1_FINGERPRINT for fingerprint check + +void setup() { + Serial.begin(115200); // Initialize serial + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + WiFi.mode(WIFI_STA); + + if(fingerprint!=NULL){ + client.setFingerprint(fingerprint); + } + else{ + client.setInsecure(); // To perform a simple SSL Encryption + } + + ThingSpeak.begin(client); // Initialize ThingSpeak +} + +void loop() { + + // Connect or reconnect to WiFi + if(WiFi.status() != WL_CONNECTED){ + Serial.print("Attempting to connect to SSID: "); + Serial.println(SECRET_SSID); + while(WiFi.status() != WL_CONNECTED){ + WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network + Serial.print("."); + delay(5000); + } + Serial.println("\nConnected."); + } + + // set the fields with the values + ThingSpeak.setField(1, number1); + ThingSpeak.setField(2, number2); + ThingSpeak.setField(3, number3); + ThingSpeak.setField(4, number4); + + // figure out the status message + if(number1 > number2){ + myStatus = String("field1 is greater than field2"); + } + else if(number1 < number2){ + myStatus = String("field1 is less than field2"); + } + else{ + myStatus = String("field1 equals field2"); + } + + // set the status + ThingSpeak.setStatus(myStatus); + + // write to the ThingSpeak channel + int x = ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey); + if(x == 200){ + Serial.println("Channel update successful."); + } + else{ + Serial.println("Problem updating channel. HTTP error code " + String(x)); + } + + // change the values + number1++; + if(number1 > 99){ + number1 = 0; + } + number2 = random(0,100); + number3 = random(0,100); + number4 = random(0,100); + + delay(20000); // Wait 20 seconds to update the channel again +} diff --git a/examples/ESP8266/program board directly/WriteMultipleFieldsSecure/secrets.h b/examples/ESP8266/program board directly/WriteMultipleFieldsSecure/secrets.h new file mode 100644 index 0000000..0c809c4 --- /dev/null +++ b/examples/ESP8266/program board directly/WriteMultipleFieldsSecure/secrets.h @@ -0,0 +1,11 @@ +// Use this file to store all of the private credentials +// and connection details + +#define SECRET_SSID "MySSID" // replace MySSID with your WiFi network name +#define SECRET_PASS "MyPassword" // replace MyPassword with your WiFi password + +#define SECRET_CH_ID 000000 // replace 0000000 with your channel number +#define SECRET_WRITE_APIKEY "XYZ" // replace XYZ with your channel write API Key + +// ThingSpeak Certificate Fingerprint, Expiration Date: August 3, 2022 at 8:00:00 AM EST +#define SECRET_SHA1_FINGERPRINT "27 18 92 DD A4 26 C3 07 09 B9 7A E6 C5 21 B9 5B 48 F7 16 E1" diff --git a/examples/ESP8266/program board directly/WriteSingleField/WriteSingleField.ino b/examples/ESP8266/program board directly/WriteSingleField/WriteSingleField.ino index 9ac782c..836e38a 100644 --- a/examples/ESP8266/program board directly/WriteSingleField/WriteSingleField.ino +++ b/examples/ESP8266/program board directly/WriteSingleField/WriteSingleField.ino @@ -20,12 +20,12 @@ For licensing information, see the accompanying license file. - Copyright 2018, The MathWorks, Inc. + Copyright 2020, The MathWorks, Inc. */ -#include "ThingSpeak.h" -#include "secrets.h" #include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros char ssid[] = SECRET_SSID; // your network SSID (name) char pass[] = SECRET_PASS; // your network password @@ -39,7 +39,10 @@ int number = 0; void setup() { Serial.begin(115200); // Initialize serial - + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + WiFi.mode(WIFI_STA); ThingSpeak.begin(client); // Initialize ThingSpeak } diff --git a/examples/ESP8266/program board directly/WriteSingleFieldSecure/WriteSingleFieldSecure.ino b/examples/ESP8266/program board directly/WriteSingleFieldSecure/WriteSingleFieldSecure.ino new file mode 100644 index 0000000..3458094 --- /dev/null +++ b/examples/ESP8266/program board directly/WriteSingleFieldSecure/WriteSingleFieldSecure.ino @@ -0,0 +1,95 @@ +/* + WriteSingleField + + Description: Writes a value to a channel on ThingSpeak every 20 seconds over secured HTTPS connection. + + Hardware: ESP8266 based boards + + !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! + + Note: + - Requires ESP8266WiFi library, WiFiClientSecure library and ESP8622 board add-on. See https://github.com/esp8266/Arduino for details. + - Select the target hardware from the Tools->Board menu + - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +#define TS_ENABLE_SSL // For HTTPS SSL connection + +#include +#include +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros + +char ssid[] = SECRET_SSID; // your network SSID (name) +char pass[] = SECRET_PASS; // your network password +int keyIndex = 0; // your network key Index number (needed only for WEP) +WiFiClientSecure client; + +unsigned long myChannelNumber = SECRET_CH_ID; +const char * myWriteAPIKey = SECRET_WRITE_APIKEY; + +int number = 0; + +// Fingerprint check, make sure that the certificate has not expired. +const char * fingerprint = NULL; // use SECRET_SHA1_FINGERPRINT for fingerprint check + +void setup() { + Serial.begin(115200); // Initialize serial + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + WiFi.mode(WIFI_STA); + + if(fingerprint!=NULL){ + client.setFingerprint(fingerprint); + } + else{ + client.setInsecure(); // To perform a simple SSL Encryption + } + + ThingSpeak.begin(client); // Initialize ThingSpeak +} + +void loop() { + + // Connect or reconnect to WiFi + if(WiFi.status() != WL_CONNECTED){ + Serial.print("Attempting to connect to SSID: "); + Serial.println(SECRET_SSID); + while(WiFi.status() != WL_CONNECTED){ + WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network + Serial.print("."); + delay(5000); + } + Serial.println("\nConnected."); + } + + // Write to ThingSpeak. There are up to 8 fields in a channel, allowing you to store up to 8 different + // pieces of information in a channel. Here, we write to field 1. + int x = ThingSpeak.writeField(myChannelNumber, 1, number, myWriteAPIKey); + if(x == 200){ + Serial.println("Channel update successful."); + } + else{ + Serial.println("Problem updating channel. HTTP error code " + String(x)); + } + + // change the value + number++; + if(number > 99){ + number = 0; + } + + delay(5000); // Wait 20 seconds to update the channel again +} diff --git a/examples/ESP8266/program board directly/WriteSingleFieldSecure/secrets.h b/examples/ESP8266/program board directly/WriteSingleFieldSecure/secrets.h new file mode 100644 index 0000000..0c809c4 --- /dev/null +++ b/examples/ESP8266/program board directly/WriteSingleFieldSecure/secrets.h @@ -0,0 +1,11 @@ +// Use this file to store all of the private credentials +// and connection details + +#define SECRET_SSID "MySSID" // replace MySSID with your WiFi network name +#define SECRET_PASS "MyPassword" // replace MyPassword with your WiFi password + +#define SECRET_CH_ID 000000 // replace 0000000 with your channel number +#define SECRET_WRITE_APIKEY "XYZ" // replace XYZ with your channel write API Key + +// ThingSpeak Certificate Fingerprint, Expiration Date: August 3, 2022 at 8:00:00 AM EST +#define SECRET_SHA1_FINGERPRINT "27 18 92 DD A4 26 C3 07 09 B9 7A E6 C5 21 B9 5B 48 F7 16 E1" diff --git a/examples/ESP8266/via AT commands/ReadField/ReadField.ino b/examples/ESP8266/via AT commands/ReadField/ReadField.ino index fc0f3c5..73528ba 100644 --- a/examples/ESP8266/via AT commands/ReadField/ReadField.ino +++ b/examples/ESP8266/via AT commands/ReadField/ReadField.ino @@ -1,163 +1,166 @@ -/* - ReadField - - Description: Demonstates reading from a public channel which requires no API key and reading from a private channel which requires a read API key. - The value read from the public channel is the current outside temperature at MathWorks headquaters in Natick, MA. The value from the - private channel is an example counter that increments every 10 seconds. - - Hardware: Arduino compatible hardware controlling ESP8266 through AT commands. THIS IS CODE FOR THE ARDUINO, NOT THE ESP8266! - - - !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! - - Note: - - Requires Arduino main board connected to ESP8266 (ESP-01) serial pins. - - The ESP8266 device must be running firmware capable of AT commands over TX/RX pins. - Details on reflashing and binaries can be found here: https://www.espressif.com/en/support/download/at - - Requires WiFiEsp library which is available through the Library Manager. The logging level for the WiFiEsp library is set to INFO. - To disable logging completely, set _ESPLOGLEVEL_ to 0 in \Arduino\libraries\WiFiEsp\src\utility\debug.h - - Use TX1/RX1 if present on Arduino header (Mega, Due, etc). If not, then connect TX to pin 7, RX to pin 6. - - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. - - Wiring diagrams are available at: - SoftSerial (Uno, Nano, Mini, etc): https://github.com/mathworks/thingspeak-arduino/blob/master/ESP-01_AT_Commands_SoftSerial_Hookup.pdf - Hardware Serial1 (Mega, Leonardo, Due) - https://github.com/mathworks/thingspeak-arduino/blob/master/ESP-01_AT_Commands_Hardware_Serial_Hookup.pdf - - ESP8266 | Arduino without Serial1 | Arduino with Serial1 - -------------------------------------------------------- - RX | pin 7 | TX1 - TX | pin 6 | RX1 - GND | GND | GND - VCC | 5V | 5V - CH_PD | 5V | 5V - - ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and - analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. - - Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. - See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. - - For licensing information, see the accompanying license file. - - Copyright 2019, The MathWorks, Inc. -*/ - -#include "ThingSpeak.h" -#include "WiFiEsp.h" -#include "secrets.h" - -char ssid[] = SECRET_SSID; // your network SSID (name) -char pass[] = SECRET_PASS; // your network password -int keyIndex = 0; // your network key Index number (needed only for WEP) -WiFiEspClient client; - -// Emulate Serial1 on pins 6/7 if not present -#ifndef HAVE_HWSERIAL1 -#include "SoftwareSerial.h" -SoftwareSerial Serial1(6, 7); // RX, TX -#define ESP_BAUDRATE 19200 -#else -#define ESP_BAUDRATE 115200 -#endif - -// Weather station channel details -unsigned long weatherStationChannelNumber = SECRET_CH_ID_WEATHER_STATION; -unsigned int temperatureFieldNumber = 4; - -// Counting channel details -unsigned long counterChannelNumber = SECRET_CH_ID_COUNTER; -const char * myCounterReadAPIKey = SECRET_READ_APIKEY_COUNTER; -unsigned int counterFieldNumber = 1; - -void setup() { - //Initialize serial and wait for port to open - Serial.begin(115200); - - // initialize serial for ESP module - setEspBaudRate(ESP_BAUDRATE); - - while (!Serial) { - ; // wait for serial port to connect. Needed for Leonardo native USB port only - } - - Serial.print("Searching for ESP8266..."); - // initialize ESP module - WiFi.init(&Serial1); - - // check for the presence of the shield - if (WiFi.status() == WL_NO_SHIELD) { - Serial.println("WiFi shield not present"); - // don't continue - while (true); - } - Serial.println("found it!"); - - ThingSpeak.begin(client); // Initialize ThingSpeak -} - -void loop() { - - int statusCode = 0; - - // Connect or reconnect to WiFi - if(WiFi.status() != WL_CONNECTED){ - Serial.print("Attempting to connect to SSID: "); - Serial.println(SECRET_SSID); - while(WiFi.status() != WL_CONNECTED){ - WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network - Serial.print("."); - delay(5000); - } - Serial.println("\nConnected"); - } - - // Read in field 4 of the public channel recording the temperature - float temperatureInF = ThingSpeak.readFloatField(weatherStationChannelNumber, temperatureFieldNumber); - - // Check the status of the read operation to see if it was successful - statusCode = ThingSpeak.getLastReadStatus(); - if(statusCode == 200){ - Serial.println("Temperature at MathWorks HQ: " + String(temperatureInF) + " deg F"); - } - else{ - Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); - } - - delay(15000); // No need to read the temperature too often. - - // Read in field 1 of the private channel which is a counter - long count = ThingSpeak.readLongField(counterChannelNumber, counterFieldNumber, myCounterReadAPIKey); - - // Check the status of the read operation to see if it was successful - statusCode = ThingSpeak.getLastReadStatus(); - if(statusCode == 200){ - Serial.println("Counter: " + String(count)); - } - else{ - Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); - } - - delay(15000); // No need to read the counter too often. - -} - -// This function attempts to set the ESP8266 baudrate. Boards with additional hardware serial ports -// can use 115200, otherwise software serial is limited to 19200. -void setEspBaudRate(unsigned long baudrate){ - long rates[6] = {115200,74880,57600,38400,19200,9600}; - - Serial.print("Setting ESP8266 baudrate to "); - Serial.print(baudrate); - Serial.println("..."); - - for(int i = 0; i < 6; i++){ - Serial1.begin(rates[i]); - delay(100); - Serial1.print("AT+UART_DEF="); - Serial1.print(baudrate); - Serial1.print(",8,1,0,0\r\n"); - delay(100); - } - - Serial1.begin(baudrate); -} +/* + ReadField + + Description: Demonstates reading from a public channel which requires no API key and reading from a private channel which requires a read API key. + The value read from the public channel is the current outside temperature at MathWorks headquaters in Natick, MA. The value from the + private channel is an example counter that increments every 10 seconds. + + Hardware: Arduino compatible hardware controlling ESP8266 through AT commands. THIS IS CODE FOR THE ARDUINO, NOT THE ESP8266! + + + !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! + + Note: + - Requires Arduino main board connected to ESP8266 (ESP-01) serial pins. + - The ESP8266 device must be running firmware capable of AT commands over TX/RX pins. + Details on reflashing and binaries can be found here: https://www.espressif.com/en/support/download/at + - Requires WiFiEsp library which is available through the Library Manager. The logging level for the WiFiEsp library is set to INFO. + To disable logging completely, set _ESPLOGLEVEL_ to 0 in \Arduino\libraries\WiFiEsp\src\utility\debug.h + - Use TX1/RX1 if present on Arduino header (Mega, Due, etc). If not, then connect TX to pin 7, RX to pin 6. + - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. + + Wiring diagrams are available at: + SoftSerial (Uno, Nano, Mini, etc): https://github.com/mathworks/thingspeak-arduino/blob/master/ESP-01_AT_Commands_SoftSerial_Hookup.pdf + Hardware Serial1 (Mega, Leonardo, Due) - https://github.com/mathworks/thingspeak-arduino/blob/master/ESP-01_AT_Commands_Hardware_Serial_Hookup.pdf + + ESP8266 | Arduino without Serial1 | Arduino with Serial1 + -------------------------------------------------------- + RX | pin 7 | TX1 + TX | pin 6 | RX1 + GND | GND | GND + VCC | 5V | 5V + CH_PD | 5V | 5V + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +#include "WiFiEsp.h" +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros + +char ssid[] = SECRET_SSID; // your network SSID (name) +char pass[] = SECRET_PASS; // your network password +int keyIndex = 0; // your network key Index number (needed only for WEP) +WiFiEspClient client; + +// Emulate Serial1 on pins 6/7 if not present +#ifndef HAVE_HWSERIAL1 +#include "SoftwareSerial.h" +SoftwareSerial Serial1(6, 7); // RX, TX +#define ESP_BAUDRATE 19200 +#else +#define ESP_BAUDRATE 115200 +#endif + +// Weather station channel details +unsigned long weatherStationChannelNumber = SECRET_CH_ID_WEATHER_STATION; +unsigned int temperatureFieldNumber = 4; + +// Counting channel details +unsigned long counterChannelNumber = SECRET_CH_ID_COUNTER; +const char * myCounterReadAPIKey = SECRET_READ_APIKEY_COUNTER; +unsigned int counterFieldNumber = 1; + +void setup() { + //Initialize serial and wait for port to open + Serial.begin(115200); + while(!Serial){ + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + // initialize serial for ESP module + setEspBaudRate(ESP_BAUDRATE); + + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + Serial.print("Searching for ESP8266..."); + // initialize ESP module + WiFi.init(&Serial1); + + // check for the presence of the shield + if (WiFi.status() == WL_NO_SHIELD) { + Serial.println("WiFi shield not present"); + // don't continue + while (true); + } + Serial.println("found it!"); + + ThingSpeak.begin(client); // Initialize ThingSpeak +} + +void loop() { + + int statusCode = 0; + + // Connect or reconnect to WiFi + if(WiFi.status() != WL_CONNECTED){ + Serial.print("Attempting to connect to SSID: "); + Serial.println(SECRET_SSID); + while(WiFi.status() != WL_CONNECTED){ + WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network + Serial.print("."); + delay(5000); + } + Serial.println("\nConnected"); + } + + // Read in field 4 of the public channel recording the temperature + float temperatureInF = ThingSpeak.readFloatField(weatherStationChannelNumber, temperatureFieldNumber); + + // Check the status of the read operation to see if it was successful + statusCode = ThingSpeak.getLastReadStatus(); + if(statusCode == 200){ + Serial.println("Temperature at MathWorks HQ: " + String(temperatureInF) + " deg F"); + } + else{ + Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); + } + + delay(15000); // No need to read the temperature too often. + + // Read in field 1 of the private channel which is a counter + long count = ThingSpeak.readLongField(counterChannelNumber, counterFieldNumber, myCounterReadAPIKey); + + // Check the status of the read operation to see if it was successful + statusCode = ThingSpeak.getLastReadStatus(); + if(statusCode == 200){ + Serial.println("Counter: " + String(count)); + } + else{ + Serial.println("Problem reading channel. HTTP error code " + String(statusCode)); + } + + delay(15000); // No need to read the counter too often. + +} + +// This function attempts to set the ESP8266 baudrate. Boards with additional hardware serial ports +// can use 115200, otherwise software serial is limited to 19200. +void setEspBaudRate(unsigned long baudrate){ + long rates[6] = {115200,74880,57600,38400,19200,9600}; + + Serial.print("Setting ESP8266 baudrate to "); + Serial.print(baudrate); + Serial.println("..."); + + for(int i = 0; i < 6; i++){ + Serial1.begin(rates[i]); + delay(100); + Serial1.print("AT+UART_DEF="); + Serial1.print(baudrate); + Serial1.print(",8,1,0,0\r\n"); + delay(100); + } + + Serial1.begin(baudrate); +} diff --git a/examples/ESP8266/via AT commands/WriteMultipleFields/WriteMultipleFields.ino b/examples/ESP8266/via AT commands/WriteMultipleFields/WriteMultipleFields.ino index d53fda4..40b68d5 100644 --- a/examples/ESP8266/via AT commands/WriteMultipleFields/WriteMultipleFields.ino +++ b/examples/ESP8266/via AT commands/WriteMultipleFields/WriteMultipleFields.ino @@ -1,172 +1,175 @@ -/* - WriteMultipleFields - - Description: Writes values to fields 1,2,3,4 and status in a single ThingSpeak update every 20 seconds. - - Hardware: Arduino compatible hardware controlling ESP8266 through AT commands. THIS IS CODE FOR THE ARDUINO, NOT THE ESP8266! - - !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! - - Note: - - Requires Arduino main board connected to ESP8266 (ESP-01) serial pins - - The ESP8266 device must be running firmware capable of AT commands over TX/RX pins. - Details on reflashing and binaries can be found here: https://www.espressif.com/en/support/download/at - - Requires WiFiEsp library which is available through the Library Manager. The logging level for the WiFiEsp library is set to INFO. - To disable logging completely, set _ESPLOGLEVEL_ to 0 in \Arduino\libraries\WiFiEsp\src\utility\debug.h - - Use TX1/RX1 if present on Arduino header (Mega, Due, etc). If not, then connect TX to pin 7, RX to pin 6. - - Some boards (Uno, Nano, Leonardo, etc) do not have enough memory to handle writing large strings to ThingSpeak. - For these boards, keep individual field data lengths 32 characters or less. - - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. - - Wiring diagrams are available at: - SoftSerial (Uno, Nano, Mini, etc): https://github.com/mathworks/thingspeak-arduino/blob/master/ESP-01_AT_Commands_SoftSerial_Hookup.pdf - Hardware Serial1 (Mega, Leonardo, Due) - https://github.com/mathworks/thingspeak-arduino/blob/master/ESP-01_AT_Commands_Hardware_Serial_Hookup.pdf - - ESP8266 | Arduino without Serial1 | Arduino with Serial1 - -------------------------------------------------------- - RX | pin 7 | TX1 - TX | pin 6 | RX1 - GND | GND | GND - VCC | 5V | 5V - CH_PD | 5V | 5V - - ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and - analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. - - Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. - See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. - - For licensing information, see the accompanying license file. - - Copyright 2019, The MathWorks, Inc. -*/ - -#include "ThingSpeak.h" -#include "WiFiEsp.h" -#include "secrets.h" - -char ssid[] = SECRET_SSID; // your network SSID (name) -char pass[] = SECRET_PASS; // your network password -int keyIndex = 0; // your network key Index number (needed only for WEP) -WiFiEspClient client; - -// Emulate Serial1 on pins 6/7 if not present -#ifndef HAVE_HWSERIAL1 -#include "SoftwareSerial.h" -SoftwareSerial Serial1(6, 7); // RX, TX -#define ESP_BAUDRATE 19200 -#else -#define ESP_BAUDRATE 115200 -#endif - -unsigned long myChannelNumber = SECRET_CH_ID; -const char * myWriteAPIKey = SECRET_WRITE_APIKEY; - -// Initialize our values -int number1 = 0; -int number2 = random(0,100); -int number3 = random(0,100); -int number4 = random(0,100); -String myStatus = ""; - -void setup() { - //Initialize serial and wait for port to open - Serial.begin(115200); // Initialize serial - - // initialize serial for ESP module - setEspBaudRate(ESP_BAUDRATE); - - while (!Serial) { - ; // wait for serial port to connect. Needed for Leonardo native USB port only - } - - Serial.print("Searching for ESP8266..."); - // initialize ESP module - WiFi.init(&Serial1); - - // check for the presence of the shield - if (WiFi.status() == WL_NO_SHIELD) { - Serial.println("WiFi shield not present"); - // don't continue - while (true); - } - Serial.println("found it!"); - - ThingSpeak.begin(client); // Initialize ThingSpeak -} - -void loop() { - - // Connect or reconnect to WiFi - if(WiFi.status() != WL_CONNECTED){ - Serial.print("Attempting to connect to SSID: "); - Serial.println(SECRET_SSID); - while(WiFi.status() != WL_CONNECTED){ - WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network - Serial.print("."); - delay(5000); - } - Serial.println("\nConnected."); - } - - // set the fields with the values - ThingSpeak.setField(1, number1); - ThingSpeak.setField(2, number2); - ThingSpeak.setField(3, number3); - ThingSpeak.setField(4, number4); - - // figure out the status message - if(number1 > number2){ - myStatus = String("field1 is greater than field2"); - } - else if(number1 < number2){ - myStatus = String("field1 is less than field2"); - } - else{ - myStatus = String("field1 equals field2"); - } - - // set the status - ThingSpeak.setStatus(myStatus); - - // write to the ThingSpeak channel - int x = ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey); - if(x == 200){ - Serial.println("Channel update successful."); - } - else{ - Serial.println("Problem updating channel. HTTP error code " + String(x)); - } - - // change the values - number1++; - if(number1 > 99){ - number1 = 0; - } - number2 = random(0,100); - number3 = random(0,100); - number4 = random(0,100); - - delay(20000); // Wait 20 seconds to update the channel again -} - -// This function attempts to set the ESP8266 baudrate. Boards with additional hardware serial ports -// can use 115200, otherwise software serial is limited to 19200. -void setEspBaudRate(unsigned long baudrate){ - long rates[6] = {115200,74880,57600,38400,19200,9600}; - - Serial.print("Setting ESP8266 baudrate to "); - Serial.print(baudrate); - Serial.println("..."); - - for(int i = 0; i < 6; i++){ - Serial1.begin(rates[i]); - delay(100); - Serial1.print("AT+UART_DEF="); - Serial1.print(baudrate); - Serial1.print(",8,1,0,0\r\n"); - delay(100); - } - - Serial1.begin(baudrate); -} \ No newline at end of file +/* + WriteMultipleFields + + Description: Writes values to fields 1,2,3,4 and status in a single ThingSpeak update every 20 seconds. + + Hardware: Arduino compatible hardware controlling ESP8266 through AT commands. THIS IS CODE FOR THE ARDUINO, NOT THE ESP8266! + + !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! + + Note: + - Requires Arduino main board connected to ESP8266 (ESP-01) serial pins + - The ESP8266 device must be running firmware capable of AT commands over TX/RX pins. + Details on reflashing and binaries can be found here: https://www.espressif.com/en/support/download/at + - Requires WiFiEsp library which is available through the Library Manager. The logging level for the WiFiEsp library is set to INFO. + To disable logging completely, set _ESPLOGLEVEL_ to 0 in \Arduino\libraries\WiFiEsp\src\utility\debug.h + - Use TX1/RX1 if present on Arduino header (Mega, Due, etc). If not, then connect TX to pin 7, RX to pin 6. + - Some boards (Uno, Nano, Leonardo, etc) do not have enough memory to handle writing large strings to ThingSpeak. + For these boards, keep individual field data lengths 32 characters or less. + - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. + + Wiring diagrams are available at: + SoftSerial (Uno, Nano, Mini, etc): https://github.com/mathworks/thingspeak-arduino/blob/master/ESP-01_AT_Commands_SoftSerial_Hookup.pdf + Hardware Serial1 (Mega, Leonardo, Due) - https://github.com/mathworks/thingspeak-arduino/blob/master/ESP-01_AT_Commands_Hardware_Serial_Hookup.pdf + + ESP8266 | Arduino without Serial1 | Arduino with Serial1 + -------------------------------------------------------- + RX | pin 7 | TX1 + TX | pin 6 | RX1 + GND | GND | GND + VCC | 5V | 5V + CH_PD | 5V | 5V + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +#include "WiFiEsp.h" +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros + +char ssid[] = SECRET_SSID; // your network SSID (name) +char pass[] = SECRET_PASS; // your network password +int keyIndex = 0; // your network key Index number (needed only for WEP) +WiFiEspClient client; + +// Emulate Serial1 on pins 6/7 if not present +#ifndef HAVE_HWSERIAL1 +#include "SoftwareSerial.h" +SoftwareSerial Serial1(6, 7); // RX, TX +#define ESP_BAUDRATE 19200 +#else +#define ESP_BAUDRATE 115200 +#endif + +unsigned long myChannelNumber = SECRET_CH_ID; +const char * myWriteAPIKey = SECRET_WRITE_APIKEY; + +// Initialize our values +int number1 = 0; +int number2 = random(0,100); +int number3 = random(0,100); +int number4 = random(0,100); +String myStatus = ""; + +void setup() { + //Initialize serial and wait for port to open + Serial.begin(115200); // Initialize serial + while(!Serial){ + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + // initialize serial for ESP module + setEspBaudRate(ESP_BAUDRATE); + + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + Serial.print("Searching for ESP8266..."); + // initialize ESP module + WiFi.init(&Serial1); + + // check for the presence of the shield + if (WiFi.status() == WL_NO_SHIELD) { + Serial.println("WiFi shield not present"); + // don't continue + while (true); + } + Serial.println("found it!"); + + ThingSpeak.begin(client); // Initialize ThingSpeak +} + +void loop() { + + // Connect or reconnect to WiFi + if(WiFi.status() != WL_CONNECTED){ + Serial.print("Attempting to connect to SSID: "); + Serial.println(SECRET_SSID); + while(WiFi.status() != WL_CONNECTED){ + WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network + Serial.print("."); + delay(5000); + } + Serial.println("\nConnected."); + } + + // set the fields with the values + ThingSpeak.setField(1, number1); + ThingSpeak.setField(2, number2); + ThingSpeak.setField(3, number3); + ThingSpeak.setField(4, number4); + + // figure out the status message + if(number1 > number2){ + myStatus = String("field1 is greater than field2"); + } + else if(number1 < number2){ + myStatus = String("field1 is less than field2"); + } + else{ + myStatus = String("field1 equals field2"); + } + + // set the status + ThingSpeak.setStatus(myStatus); + + // write to the ThingSpeak channel + int x = ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey); + if(x == 200){ + Serial.println("Channel update successful."); + } + else{ + Serial.println("Problem updating channel. HTTP error code " + String(x)); + } + + // change the values + number1++; + if(number1 > 99){ + number1 = 0; + } + number2 = random(0,100); + number3 = random(0,100); + number4 = random(0,100); + + delay(20000); // Wait 20 seconds to update the channel again +} + +// This function attempts to set the ESP8266 baudrate. Boards with additional hardware serial ports +// can use 115200, otherwise software serial is limited to 19200. +void setEspBaudRate(unsigned long baudrate){ + long rates[6] = {115200,74880,57600,38400,19200,9600}; + + Serial.print("Setting ESP8266 baudrate to "); + Serial.print(baudrate); + Serial.println("..."); + + for(int i = 0; i < 6; i++){ + Serial1.begin(rates[i]); + delay(100); + Serial1.print("AT+UART_DEF="); + Serial1.print(baudrate); + Serial1.print(",8,1,0,0\r\n"); + delay(100); + } + + Serial1.begin(baudrate); +} diff --git a/examples/ESP8266/via AT commands/WriteSingleField/WriteSingleField.ino b/examples/ESP8266/via AT commands/WriteSingleField/WriteSingleField.ino index 0ef2025..b9a374b 100644 --- a/examples/ESP8266/via AT commands/WriteSingleField/WriteSingleField.ino +++ b/examples/ESP8266/via AT commands/WriteSingleField/WriteSingleField.ino @@ -1,145 +1,147 @@ -/* - WriteSingleField - - Description: Writes a value to a channel on ThingSpeak every 20 seconds. - - Hardware: Arduino compatible hardware controlling ESP8266 through AT commands. THIS IS CODE FOR THE ARDUINO, NOT THE ESP8266! - - !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! - - Note: - - Requires Arduino main board connected to ESP8266 (ESP-01) serial pins - - The ESP8266 device must be running firmware capable of AT commands over TX/RX pins. - Details on reflashing and binaries can be found here: https://www.espressif.com/en/support/download/at - - Requires WiFiEsp library which is available through the Library Manager. The logging level for the WiFiEsp library is set to INFO. - To disable logging completely, set _ESPLOGLEVEL_ to 0 in \Arduino\libraries\WiFiEsp\src\utility\debug.h - - Use TX1/RX1 if present on Arduino header (Mega, Due, etc). If not, then connect TX to pin 7, RX to pin 6. - - Some boards (Uno, Nano, Leonardo, etc) do not have enough memory to handle writing large strings to ThingSpeak. - For these boards, keep individual field data lengths 32 characters or less. - - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. - - Wiring diagrams are available at: - SoftSerial (Uno, Nano, Mini, etc): https://github.com/mathworks/thingspeak-arduino/blob/master/ESP-01_AT_Commands_SoftSerial_Hookup.pdf - Hardware Serial1 (Mega, Leonardo, Due) - https://github.com/mathworks/thingspeak-arduino/blob/master/ESP-01_AT_Commands_Hardware_Serial_Hookup.pdf - - ESP8266 | Arduino without Serial1 | Arduino with Serial1 - -------------------------------------------------------- - RX | pin 7 | TX1 - TX | pin 6 | RX1 - GND | GND | GND - VCC | 5V | 5V - CH_PD | 5V | 5V - - ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and - analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. - - Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. - See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. - - For licensing information, see the accompanying license file. - - Copyright 2019, The MathWorks, Inc. -*/ - -#include "ThingSpeak.h" -#include "WiFiEsp.h" -#include "secrets.h" - -char ssid[] = SECRET_SSID; // your network SSID (name) -char pass[] = SECRET_PASS; // your network password -int keyIndex = 0; // your network key Index number (needed only for WEP) -WiFiEspClient client; - -// Emulate Serial1 on pins 6/7 if not present -#ifndef HAVE_HWSERIAL1 -#include "SoftwareSerial.h" -SoftwareSerial Serial1(6, 7); // RX, TX -#define ESP_BAUDRATE 19200 -#else -#define ESP_BAUDRATE 115200 -#endif - -unsigned long myChannelNumber = SECRET_CH_ID; -const char * myWriteAPIKey = SECRET_WRITE_APIKEY; - -int number = 0; - -void setup() { - //Initialize serial and wait for port to open - Serial.begin(115200); - - // initialize serial for ESP module - setEspBaudRate(ESP_BAUDRATE); - - while (!Serial) { - ; // wait for serial port to connect. Needed for Leonardo native USB port only - } - - Serial.print("Searching for ESP8266..."); - // initialize ESP module - WiFi.init(&Serial1); - - // check for the presence of the shield - if (WiFi.status() == WL_NO_SHIELD) { - Serial.println("WiFi shield not present"); - // don't continue - while (true); - } - Serial.println("found it!"); - - ThingSpeak.begin(client); // Initialize ThingSpeak -} - -void loop() { - - // Connect or reconnect to WiFi - if(WiFi.status() != WL_CONNECTED){ - Serial.print("Attempting to connect to SSID: "); - Serial.println(SECRET_SSID); - while(WiFi.status() != WL_CONNECTED){ - WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network - Serial.print("."); - delay(5000); - } - Serial.println("\nConnected."); - } - - // Write to ThingSpeak. There are up to 8 fields in a channel, allowing you to store up to 8 different - // pieces of information in a channel. Here, we write to field 1. - int x = ThingSpeak.writeField(myChannelNumber, 1, number, myWriteAPIKey); - if(x == 200){ - Serial.println("Channel update successful."); - } - else{ - Serial.println("Problem updating channel. HTTP error code " + String(x)); - } - - // change the value - number++; - if(number > 99){ - number = 0; - } - - delay(20000); // Wait 20 seconds to update the channel again -} - -// This function attempts to set the ESP8266 baudrate. Boards with additional hardware serial ports -// can use 115200, otherwise software serial is limited to 19200. -void setEspBaudRate(unsigned long baudrate){ - long rates[6] = {115200,74880,57600,38400,19200,9600}; - - Serial.print("Setting ESP8266 baudrate to "); - Serial.print(baudrate); - Serial.println("..."); - - for(int i = 0; i < 6; i++){ - Serial1.begin(rates[i]); - delay(100); - Serial1.print("AT+UART_DEF="); - Serial1.print(baudrate); - Serial1.print(",8,1,0,0\r\n"); - delay(100); - } - - Serial1.begin(baudrate); -} \ No newline at end of file +/* + WriteSingleField + + Description: Writes a value to a channel on ThingSpeak every 20 seconds. + + Hardware: Arduino compatible hardware controlling ESP8266 through AT commands. THIS IS CODE FOR THE ARDUINO, NOT THE ESP8266! + + !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!! + + Note: + - Requires Arduino main board connected to ESP8266 (ESP-01) serial pins + - The ESP8266 device must be running firmware capable of AT commands over TX/RX pins. + Details on reflashing and binaries can be found here: https://www.espressif.com/en/support/download/at + - Requires WiFiEsp library which is available through the Library Manager. The logging level for the WiFiEsp library is set to INFO. + To disable logging completely, set _ESPLOGLEVEL_ to 0 in \Arduino\libraries\WiFiEsp\src\utility\debug.h + - Use TX1/RX1 if present on Arduino header (Mega, Due, etc). If not, then connect TX to pin 7, RX to pin 6. + - Some boards (Uno, Nano, Leonardo, etc) do not have enough memory to handle writing large strings to ThingSpeak. + For these boards, keep individual field data lengths 32 characters or less. + - This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. + + Wiring diagrams are available at: + SoftSerial (Uno, Nano, Mini, etc): https://github.com/mathworks/thingspeak-arduino/blob/master/ESP-01_AT_Commands_SoftSerial_Hookup.pdf + Hardware Serial1 (Mega, Leonardo, Due) - https://github.com/mathworks/thingspeak-arduino/blob/master/ESP-01_AT_Commands_Hardware_Serial_Hookup.pdf + + ESP8266 | Arduino without Serial1 | Arduino with Serial1 + -------------------------------------------------------- + RX | pin 7 | TX1 + TX | pin 6 | RX1 + GND | GND | GND + VCC | 5V | 5V + CH_PD | 5V | 5V + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +#include "WiFiEsp.h" +#include "secrets.h" +#include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros + +char ssid[] = SECRET_SSID; // your network SSID (name) +char pass[] = SECRET_PASS; // your network password +int keyIndex = 0; // your network key Index number (needed only for WEP) +WiFiEspClient client; + +// Emulate Serial1 on pins 6/7 if not present +#ifndef HAVE_HWSERIAL1 +#include "SoftwareSerial.h" +SoftwareSerial Serial1(6, 7); // RX, TX +#define ESP_BAUDRATE 19200 +#else +#define ESP_BAUDRATE 115200 +#endif + +unsigned long myChannelNumber = SECRET_CH_ID; +const char * myWriteAPIKey = SECRET_WRITE_APIKEY; + +int number = 0; + +void setup() { + Serial.begin(115200); //Initialize serial + while(!Serial){ + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + // initialize serial for ESP module + setEspBaudRate(ESP_BAUDRATE); + + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo native USB port only + } + + Serial.print("Searching for ESP8266..."); + // initialize ESP module + WiFi.init(&Serial1); + + // check for the presence of the shield + if (WiFi.status() == WL_NO_SHIELD) { + Serial.println("WiFi shield not present"); + // don't continue + while (true); + } + Serial.println("found it!"); + + ThingSpeak.begin(client); // Initialize ThingSpeak +} + +void loop() { + + // Connect or reconnect to WiFi + if(WiFi.status() != WL_CONNECTED){ + Serial.print("Attempting to connect to SSID: "); + Serial.println(SECRET_SSID); + while(WiFi.status() != WL_CONNECTED){ + WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network + Serial.print("."); + delay(5000); + } + Serial.println("\nConnected."); + } + + // Write to ThingSpeak. There are up to 8 fields in a channel, allowing you to store up to 8 different + // pieces of information in a channel. Here, we write to field 1. + int x = ThingSpeak.writeField(myChannelNumber, 1, number, myWriteAPIKey); + if(x == 200){ + Serial.println("Channel update successful."); + } + else{ + Serial.println("Problem updating channel. HTTP error code " + String(x)); + } + + // change the value + number++; + if(number > 99){ + number = 0; + } + + delay(20000); // Wait 20 seconds to update the channel again +} + +// This function attempts to set the ESP8266 baudrate. Boards with additional hardware serial ports +// can use 115200, otherwise software serial is limited to 19200. +void setEspBaudRate(unsigned long baudrate){ + long rates[6] = {115200,74880,57600,38400,19200,9600}; + + Serial.print("Setting ESP8266 baudrate to "); + Serial.print(baudrate); + Serial.println("..."); + + for(int i = 0; i < 6; i++){ + Serial1.begin(rates[i]); + delay(100); + Serial1.print("AT+UART_DEF="); + Serial1.print(baudrate); + Serial1.print(",8,1,0,0\r\n"); + delay(100); + } + + Serial1.begin(baudrate); +} diff --git a/extras/test/testBegin/testBegin.ino b/extras/test/testBegin/testBegin.ino index 002cd2a..a8bf866 100644 --- a/extras/test/testBegin/testBegin.ino +++ b/extras/test/testBegin/testBegin.ino @@ -1,8 +1,8 @@ #line 2 "testBegin.ino" /* - testWriteField unit test + testBegin unit test - Unit Test for the writeField function in the ThingSpeak Communication Library for Arduino + Unit Test for the connection through HTTP in the ThingSpeak Communication Library for Arduino This test use the ArduinoUnit 2.1.0 unit test framework. Visit https://github.com/mmurdoch/arduinounit to learn more. @@ -16,7 +16,7 @@ For licensing information, see the accompanying license file. - Copyright 2018, The MathWorks, Inc. + Copyright 2020, The MathWorks, Inc. */ //#define USE_WIFI101_SHIELD @@ -28,7 +28,6 @@ #endif #include -#include #if defined(ARDUINO_AVR_YUN) #include "YunClient.h" @@ -51,50 +50,24 @@ #endif #endif +#include // always include thingspeak header file after other header files and custom macros +#define FIELD1 1 +#define WRITE_DELAY_FOR_THINGSPEAK 15000 // Data write limit for a free user (15 sec). -unsigned long testChannelNumber = 209617; -const char * testChannelWriteAPIKey = "514SX5OBP2OFEPL2"; +unsigned long testChannelNumber = 1070863; +const char * testChannelWriteAPIKey = "UI7FSU4O8ZJ5BM8O"; test(beginCase) { assertTrue(ThingSpeak.begin(client)); - assertTrue(ThingSpeak.begin(client,IPAddress(1,2,3,4),80)); - - assertTrue(ThingSpeak.begin(client,"www.mathworks.com",80)); -} - - -test(badAddresses) -{ - // Test for valid, but incorrect, URL (www.mathworks.com) - assertTrue(ThingSpeak.begin(client,"www.mathworks.com",80)); - // www.mathworks.com will sometimes sometimes return a 404 or a 301 depending on server settings. Test the negative case instead. - assertNotEqual(OK_SUCCESS, ThingSpeak.writeField(testChannelNumber, 1, (float)1.0, testChannelWriteAPIKey) ); - - // Test for non-existant URL (http://www.iwishthiswebsitewerereal.com/) - #ifdef USE_ETHERNET_SHIELD - int badDomainResponse = ERR_UNEXPECTED_FAIL; - #else - int badDomainResponse = ERR_CONNECT_FAILED; - #endif - assertTrue(ThingSpeak.begin(client,"www.iwishthiswebsitewerereal.com",80)); - assertEqual(badDomainResponse, ThingSpeak.writeField(testChannelNumber, 1, (float)2.0, testChannelWriteAPIKey)); - - // Test for non-existant IP 192.168.1.234 - assertTrue(ThingSpeak.begin(client,IPAddress(192,168,1,234),80)); - assertEqual(ERR_CONNECT_FAILED, ThingSpeak.writeField(testChannelNumber, 1, (float)2.0, testChannelWriteAPIKey)); - - //Test for bad suburl (badapi.thingspeak.com) - #ifdef USE_ETHERNET_SHIELD - int badURLResponse = ERR_UNEXPECTED_FAIL; - #else - int badURLResponse = ERR_CONNECT_FAILED; - #endif - assertTrue(ThingSpeak.begin(client,"invalid.thingspeak.com",80)); - assertEqual(badURLResponse, ThingSpeak.writeField(testChannelNumber, 1, (float)4.0, testChannelWriteAPIKey)); + int val = 25; + // Always wait to ensure that rate limit isn't hit + delay(WRITE_DELAY_FOR_THINGSPEAK); + assertTrue(ThingSpeak.begin(client)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.writeField(testChannelNumber, FIELD1, val, testChannelWriteAPIKey)); } void setup() @@ -117,4 +90,3 @@ void loop() { Test::run(); } - diff --git a/extras/test/testReadField/testReadField.ino b/extras/test/testReadField/testReadField.ino index a86f818..a9c9ba8 100644 --- a/extras/test/testReadField/testReadField.ino +++ b/extras/test/testReadField/testReadField.ino @@ -27,7 +27,6 @@ #endif #include -#include #if defined(ARDUINO_AVR_YUN) #include "YunClient.h" @@ -50,6 +49,8 @@ #endif #endif +#include // always include thingspeak header file after other header files and custom macros + unsigned long testPublicChannelNumber = 209617; const char * testPublicChannelWriteAPIKey = "514SX5OBP2OFEPL2"; @@ -63,13 +64,13 @@ test(readPrivateFieldCase) { // Test basic value read -- should give anything but 0 assertNotEqual(0.0,ThingSpeak.readFloatField(testPrivateChannelNumber, 1, testPrivateChannelReadAPIKey)); - assertEqual(OK_SUCCESS,ThingSpeak.getLastReadStatus()); + assertEqual(TS_OK_SUCCESS,ThingSpeak.getLastReadStatus()); // Test read with invalid API key // * Using the wrong API key causes a connection failure on the next attempt to connect to ThingSpeak // * The cause is unknown, disable this test for now //assertEqual(0.0,ThingSpeak.readFloatField(testPrivateChannelNumber, 1, "AFAKEAPIKEYFAKEX")); - //assertEqual(ERR_BADAPIKEY,ThingSpeak.getLastReadStatus()); + //assertEqual(TS_ERR_BADAPIKEY,ThingSpeak.getLastReadStatus()); } @@ -78,31 +79,31 @@ test(readPublicFieldCase) { delay(WRITE_DELAY_FOR_THINGSPEAK); - assertEqual(OK_SUCCESS, ThingSpeak.writeField(testPublicChannelNumber, 4, (float)1.0, testPublicChannelWriteAPIKey)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.writeField(testPublicChannelNumber, 4, (float)1.0, testPublicChannelWriteAPIKey)); // Test basic value read -- should give anything but 0 assertNotEqual(0.0,ThingSpeak.readFloatField(testPublicChannelNumber, 4)); - assertEqual(OK_SUCCESS,ThingSpeak.getLastReadStatus()); + assertEqual(TS_OK_SUCCESS,ThingSpeak.getLastReadStatus()); // Test read of field out of range assertEqual(0.0,ThingSpeak.readFloatField(testPublicChannelNumber, 0)); - assertEqual(ERR_INVALID_FIELD_NUM,ThingSpeak.getLastReadStatus()); + assertEqual(TS_ERR_INVALID_FIELD_NUM,ThingSpeak.getLastReadStatus()); assertEqual(0.0,ThingSpeak.readFloatField(testPublicChannelNumber, 9)); - assertEqual(ERR_INVALID_FIELD_NUM,ThingSpeak.getLastReadStatus()); + assertEqual(TS_ERR_INVALID_FIELD_NUM,ThingSpeak.getLastReadStatus()); #if defined(USE_WIFI101_SHIELD) - #define ERR_BAD ERR_CONNECT_FAILED + #define TS_ERR_BAD TS_ERR_CONNECT_FAILED #else - #define ERR_BAD ERR_BADURL + #define TS_ERR_BAD TS_ERR_BADURL #endif // Test read of invalid channel # // * Using the wrong API key causes a connection failure on the next attempt to connect to ThingSpeak // * The cause is unknown, disable this test for now //assertEqual(0.0,ThingSpeak.readFloatField(0, 1)); - //assertEqual(ERR_BADURL,ThingSpeak.getLastReadStatus()); + //assertEqual(TS_ERR_BADURL,ThingSpeak.getLastReadStatus()); //assertEqual(0.0,ThingSpeak.readFloatField(4294967295L, 1)); - //assertEqual(ERR_BAD,ThingSpeak.getLastReadStatus()); + //assertEqual(TS_ERR_BAD,ThingSpeak.getLastReadStatus()); } @@ -111,31 +112,31 @@ test(ReadFloatFieldCase) // Always to ensure that rate limit isn't hit delay(WRITE_DELAY_FOR_THINGSPEAK); - assertEqual(OK_SUCCESS,ThingSpeak.setField(1,(float)3.14159)); // float - assertEqual(OK_SUCCESS,ThingSpeak.setField(2,-47)); // integer - assertEqual(OK_SUCCESS,ThingSpeak.setField(3,(long)100000L)); // long - assertEqual(OK_SUCCESS,ThingSpeak.setField(4,(float)NAN)); // Nan - assertEqual(OK_SUCCESS,ThingSpeak.setField(5,"foobar")); // string - assertEqual(OK_SUCCESS,ThingSpeak.setField(6,(float)INFINITY)); // + inf - assertEqual(OK_SUCCESS,ThingSpeak.setField(7,(float)-INFINITY)); // + inf - assertEqual(OK_SUCCESS,ThingSpeak.writeFields(testPrivateChannelNumber, testPrivateChannelWriteAPIKey)); // string + assertEqual(TS_OK_SUCCESS,ThingSpeak.setField(1,(float)3.14159)); // float + assertEqual(TS_OK_SUCCESS,ThingSpeak.setField(2,-47)); // integer + assertEqual(TS_OK_SUCCESS,ThingSpeak.setField(3,(long)100000L)); // long + assertEqual(TS_OK_SUCCESS,ThingSpeak.setField(4,(float)NAN)); // Nan + assertEqual(TS_OK_SUCCESS,ThingSpeak.setField(5,"foobar")); // string + assertEqual(TS_OK_SUCCESS,ThingSpeak.setField(6,(float)INFINITY)); // + inf + assertEqual(TS_OK_SUCCESS,ThingSpeak.setField(7,(float)-INFINITY)); // + inf + assertEqual(TS_OK_SUCCESS,ThingSpeak.writeFields(testPrivateChannelNumber, testPrivateChannelWriteAPIKey)); // string // Test read as float assertLess(abs((float)3.14159 - ThingSpeak.readFloatField(testPrivateChannelNumber, 1, testPrivateChannelReadAPIKey)),float(0.001)); - assertEqual(OK_SUCCESS,ThingSpeak.getLastReadStatus()); + assertEqual(TS_OK_SUCCESS,ThingSpeak.getLastReadStatus()); assertEqual(-47.0,ThingSpeak.readFloatField(testPrivateChannelNumber, 2, testPrivateChannelReadAPIKey)); - assertEqual(OK_SUCCESS,ThingSpeak.getLastReadStatus()); + assertEqual(TS_OK_SUCCESS,ThingSpeak.getLastReadStatus()); assertEqual(100000.0,ThingSpeak.readFloatField(testPrivateChannelNumber, 3, testPrivateChannelReadAPIKey)); - assertEqual(OK_SUCCESS,ThingSpeak.getLastReadStatus()); + assertEqual(TS_OK_SUCCESS,ThingSpeak.getLastReadStatus()); assertTrue(isnan(ThingSpeak.readFloatField(testPrivateChannelNumber, 4, testPrivateChannelReadAPIKey))); - assertEqual(OK_SUCCESS,ThingSpeak.getLastReadStatus()); + assertEqual(TS_OK_SUCCESS,ThingSpeak.getLastReadStatus()); assertEqual(0.0,ThingSpeak.readFloatField(testPrivateChannelNumber, 5, testPrivateChannelReadAPIKey)); - assertEqual(OK_SUCCESS,ThingSpeak.getLastReadStatus()); + assertEqual(TS_OK_SUCCESS,ThingSpeak.getLastReadStatus()); assertEqual(1,isinf(ThingSpeak.readFloatField(testPrivateChannelNumber, 6, testPrivateChannelReadAPIKey))); - assertEqual(OK_SUCCESS,ThingSpeak.getLastReadStatus()); + assertEqual(TS_OK_SUCCESS,ThingSpeak.getLastReadStatus()); // AVR compiler doesn't correctly test for negative infinite (http://www.atmel.com/webdoc/AVRLibcReferenceManual/group__avr__math_1ga18a7409e0b2341afaa41993960961772.html) assertEqual(1,isinf(ThingSpeak.readFloatField(testPrivateChannelNumber, 7, testPrivateChannelReadAPIKey))); - assertEqual(OK_SUCCESS,ThingSpeak.getLastReadStatus()); + assertEqual(TS_OK_SUCCESS,ThingSpeak.getLastReadStatus()); } test(ReadIntFieldCase) @@ -159,28 +160,28 @@ test(ReadIntFieldCase) ThingSpeak.setField(5,"foobar"); // string ThingSpeak.setField(6,(float)INFINITY); // + inf ThingSpeak.setField(7,(float)-INFINITY); // + inf - assertEqual(OK_SUCCESS,ThingSpeak.writeFields(testPrivateChannelNumber, testPrivateChannelWriteAPIKey)); // string + assertEqual(TS_OK_SUCCESS,ThingSpeak.writeFields(testPrivateChannelNumber, testPrivateChannelWriteAPIKey)); // string // Test read as int assertEqual(3,ThingSpeak.readIntField(testPrivateChannelNumber, 1, testPrivateChannelReadAPIKey)); - assertEqual(OK_SUCCESS,ThingSpeak.getLastReadStatus()); + assertEqual(TS_OK_SUCCESS,ThingSpeak.getLastReadStatus()); assertEqual(-47,ThingSpeak.readIntField(testPrivateChannelNumber, 2, testPrivateChannelReadAPIKey)); - assertEqual(OK_SUCCESS,ThingSpeak.getLastReadStatus()); + assertEqual(TS_OK_SUCCESS,ThingSpeak.getLastReadStatus()); // Out of range assertEqual(OUT_OF_RANGE_OUT,ThingSpeak.readIntField(testPrivateChannelNumber, 3, testPrivateChannelReadAPIKey)); - assertEqual(OK_SUCCESS,ThingSpeak.getLastReadStatus()); + assertEqual(TS_OK_SUCCESS,ThingSpeak.getLastReadStatus()); // NAN assertEqual(0,ThingSpeak.readIntField(testPrivateChannelNumber, 4, testPrivateChannelReadAPIKey)); - assertEqual(OK_SUCCESS,ThingSpeak.getLastReadStatus()); + assertEqual(TS_OK_SUCCESS,ThingSpeak.getLastReadStatus()); // Text assertEqual(0,ThingSpeak.readIntField(testPrivateChannelNumber, 5, testPrivateChannelReadAPIKey)); - assertEqual(OK_SUCCESS,ThingSpeak.getLastReadStatus()); + assertEqual(TS_OK_SUCCESS,ThingSpeak.getLastReadStatus()); // INF assertEqual(0,ThingSpeak.readIntField(testPrivateChannelNumber, 6, testPrivateChannelReadAPIKey)); - assertEqual(OK_SUCCESS,ThingSpeak.getLastReadStatus()); + assertEqual(TS_OK_SUCCESS,ThingSpeak.getLastReadStatus()); // -INF assertEqual(0,ThingSpeak.readIntField(testPrivateChannelNumber, 7, testPrivateChannelReadAPIKey)); - assertEqual(OK_SUCCESS,ThingSpeak.getLastReadStatus()); + assertEqual(TS_OK_SUCCESS,ThingSpeak.getLastReadStatus()); } test(ReadLongFieldCase) @@ -195,28 +196,28 @@ test(ReadLongFieldCase) ThingSpeak.setField(5,"foobar"); // string ThingSpeak.setField(6,(float)INFINITY); // + inf ThingSpeak.setField(7,(float)-INFINITY); // + inf - assertEqual(OK_SUCCESS,ThingSpeak.writeFields(testPrivateChannelNumber, testPrivateChannelWriteAPIKey)); // string + assertEqual(TS_OK_SUCCESS,ThingSpeak.writeFields(testPrivateChannelNumber, testPrivateChannelWriteAPIKey)); // string // Test read as long assertEqual(3L,ThingSpeak.readLongField(testPrivateChannelNumber, 1, testPrivateChannelReadAPIKey)); - assertEqual(OK_SUCCESS,ThingSpeak.getLastReadStatus()); + assertEqual(TS_OK_SUCCESS,ThingSpeak.getLastReadStatus()); assertEqual(-47L,ThingSpeak.readLongField(testPrivateChannelNumber, 2, testPrivateChannelReadAPIKey)); - assertEqual(OK_SUCCESS,ThingSpeak.getLastReadStatus()); + assertEqual(TS_OK_SUCCESS,ThingSpeak.getLastReadStatus()); // Out of range assertEqual(100000L,ThingSpeak.readLongField(testPrivateChannelNumber, 3, testPrivateChannelReadAPIKey)); - assertEqual(OK_SUCCESS,ThingSpeak.getLastReadStatus()); + assertEqual(TS_OK_SUCCESS,ThingSpeak.getLastReadStatus()); // NAN assertEqual(0L,ThingSpeak.readLongField(testPrivateChannelNumber, 4, testPrivateChannelReadAPIKey)); - assertEqual(OK_SUCCESS,ThingSpeak.getLastReadStatus()); + assertEqual(TS_OK_SUCCESS,ThingSpeak.getLastReadStatus()); // Text assertEqual(0L,ThingSpeak.readLongField(testPrivateChannelNumber, 5, testPrivateChannelReadAPIKey)); - assertEqual(OK_SUCCESS,ThingSpeak.getLastReadStatus()); + assertEqual(TS_OK_SUCCESS,ThingSpeak.getLastReadStatus()); // INF assertEqual(0L,ThingSpeak.readLongField(testPrivateChannelNumber, 6, testPrivateChannelReadAPIKey)); - assertEqual(OK_SUCCESS,ThingSpeak.getLastReadStatus()); + assertEqual(TS_OK_SUCCESS,ThingSpeak.getLastReadStatus()); // -INF assertEqual(0L,ThingSpeak.readLongField(testPrivateChannelNumber, 7, testPrivateChannelReadAPIKey)); - assertEqual(OK_SUCCESS,ThingSpeak.getLastReadStatus()); + assertEqual(TS_OK_SUCCESS,ThingSpeak.getLastReadStatus()); } test(ReadStringFieldCase) @@ -243,29 +244,29 @@ test(ReadStringFieldCase) ThingSpeak.setField(5,"foobar"); // string ThingSpeak.setField(6,(float)INFINITY); // + inf ThingSpeak.setField(7,(float)-INFINITY); // + inf - assertEqual(OK_SUCCESS,ThingSpeak.writeFields(testPrivateChannelNumber, testPrivateChannelWriteAPIKey)); // string + assertEqual(TS_OK_SUCCESS,ThingSpeak.writeFields(testPrivateChannelNumber, testPrivateChannelWriteAPIKey)); // string // Test read as long assertEqual(String("3.14159"),ThingSpeak.readStringField(testPrivateChannelNumber, 1, testPrivateChannelReadAPIKey)); - assertEqual(OK_SUCCESS,ThingSpeak.getLastReadStatus()); + assertEqual(TS_OK_SUCCESS,ThingSpeak.getLastReadStatus()); assertEqual(String("-47"),ThingSpeak.readStringField(testPrivateChannelNumber, 2, testPrivateChannelReadAPIKey)); - assertEqual(OK_SUCCESS,ThingSpeak.getLastReadStatus()); + assertEqual(TS_OK_SUCCESS,ThingSpeak.getLastReadStatus()); // Out of range assertEqual(String("100000"),ThingSpeak.readStringField(testPrivateChannelNumber, 3, testPrivateChannelReadAPIKey)); - assertEqual(OK_SUCCESS,ThingSpeak.getLastReadStatus()); + assertEqual(TS_OK_SUCCESS,ThingSpeak.getLastReadStatus()); // NAN assertEqual(String(NAN_STR),ThingSpeak.readStringField(testPrivateChannelNumber, 4, testPrivateChannelReadAPIKey)); - assertEqual(OK_SUCCESS,ThingSpeak.getLastReadStatus()); + assertEqual(TS_OK_SUCCESS,ThingSpeak.getLastReadStatus()); // Text assertEqual(String("foobar"),ThingSpeak.readStringField(testPrivateChannelNumber, 5, testPrivateChannelReadAPIKey)); - assertEqual(OK_SUCCESS,ThingSpeak.getLastReadStatus()); + assertEqual(TS_OK_SUCCESS,ThingSpeak.getLastReadStatus()); // INF assertEqual(String(POS_INF_STR),ThingSpeak.readStringField(testPrivateChannelNumber, 6, testPrivateChannelReadAPIKey)); - assertEqual(OK_SUCCESS,ThingSpeak.getLastReadStatus()); + assertEqual(TS_OK_SUCCESS,ThingSpeak.getLastReadStatus()); // -INF assertEqual(String(NEG_INF_STR),ThingSpeak.readStringField(testPrivateChannelNumber, 7, testPrivateChannelReadAPIKey)); - assertEqual(OK_SUCCESS,ThingSpeak.getLastReadStatus()); + assertEqual(TS_OK_SUCCESS,ThingSpeak.getLastReadStatus()); } test(readStatusPublicCase) @@ -274,8 +275,8 @@ test(readStatusPublicCase) delay(WRITE_DELAY_FOR_THINGSPEAK); ThingSpeak.setStatus("abcdef"); - assertEqual(OK_SUCCESS,ThingSpeak.writeFields(testPublicChannelNumber, testPublicChannelWriteAPIKey)); // string - //assertEqual(OK_SUCCESS,ThingSpeak.getLastReadStatus()); + assertEqual(TS_OK_SUCCESS,ThingSpeak.writeFields(testPublicChannelNumber, testPublicChannelWriteAPIKey)); // string + //assertEqual(TS_OK_SUCCESS,ThingSpeak.getLastReadStatus()); assertEqual(String("abcdef"),ThingSpeak.readStatus(testPublicChannelNumber)); } @@ -285,8 +286,8 @@ test(readStatusPrivateCase) delay(WRITE_DELAY_FOR_THINGSPEAK); ThingSpeak.setStatus("abcdef"); - assertEqual(OK_SUCCESS,ThingSpeak.writeFields(testPrivateChannelNumber, testPrivateChannelWriteAPIKey)); // string - //assertEqual(OK_SUCCESS,ThingSpeak.getLastReadStatus()); + assertEqual(TS_OK_SUCCESS,ThingSpeak.writeFields(testPrivateChannelNumber, testPrivateChannelWriteAPIKey)); // string + //assertEqual(TS_OK_SUCCESS,ThingSpeak.getLastReadStatus()); assertEqual(String("abcdef"),ThingSpeak.readStatus(testPrivateChannelNumber, testPrivateChannelReadAPIKey)); } @@ -296,8 +297,8 @@ test(readCreatedAtPublicCase) delay(WRITE_DELAY_FOR_THINGSPEAK); ThingSpeak.setCreatedAt("2016-12-21T11:11:11Z"); - assertEqual(OK_SUCCESS,ThingSpeak.writeFields(testPublicChannelNumber, testPublicChannelWriteAPIKey)); // string - //assertEqual(OK_SUCCESS,ThingSpeak.getLastReadStatus()); + assertEqual(TS_OK_SUCCESS,ThingSpeak.writeFields(testPublicChannelNumber, testPublicChannelWriteAPIKey)); // string + //assertEqual(TS_OK_SUCCESS,ThingSpeak.getLastReadStatus()); assertEqual(String("2016-12-21T11:11:11Z"),ThingSpeak.readCreatedAt(testPublicChannelNumber)); } @@ -307,8 +308,8 @@ test(readCreatedAtPrivateCase) delay(WRITE_DELAY_FOR_THINGSPEAK); ThingSpeak.setCreatedAt("2016-12-21T11:11:11Z"); - assertEqual(OK_SUCCESS,ThingSpeak.writeFields(testPrivateChannelNumber, testPrivateChannelWriteAPIKey)); // string - //assertEqual(OK_SUCCESS,ThingSpeak.getLastReadStatus()); + assertEqual(TS_OK_SUCCESS,ThingSpeak.writeFields(testPrivateChannelNumber, testPrivateChannelWriteAPIKey)); // string + //assertEqual(TS_OK_SUCCESS,ThingSpeak.getLastReadStatus()); assertEqual(String("2016-12-21T11:11:11Z"),ThingSpeak.readCreatedAt(testPrivateChannelNumber, testPrivateChannelReadAPIKey)); } @@ -340,4 +341,3 @@ void loop() { Test::run(); } - diff --git a/extras/test/testReadMultiple/testReadMultiple.ino b/extras/test/testReadMultiple/testReadMultiple.ino new file mode 100644 index 0000000..973f516 --- /dev/null +++ b/extras/test/testReadMultiple/testReadMultiple.ino @@ -0,0 +1,524 @@ +#line 2 "testReadMultipleFields.ino" +/* + testReadField unit test + + Unit Test for the readMultipleFields functionality in the ThingSpeak Communication Library for Arduino + + This test use the ArduinoUnit 2.1.0 unit test framework. Visit https://github.com/mmurdoch/arduinounit to learn more. + + ArduinoUnit does not support ESP8266 or ESP32 and therefor these tests will not compile for those platforms. + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +//#define USE_WIFI101_SHIELD +//#define USE_ETHERNET_SHIELD + +#if !defined(USE_WIFI101_SHIELD) && !defined(USE_ETHERNET_SHIELD) && !defined(ARDUINO_SAMD_MKR1000) && !defined(ARDUINO_AVR_YUN) +#error "Uncomment the #define for either USE_WIFI101_SHIELD or USE_ETHERNET_SHIELD" +#endif + +#include + +#if defined(ARDUINO_AVR_YUN) +#include "YunClient.h" +YunClient client; +#else +#if defined(USE_WIFI101_SHIELD) || defined(ARDUINO_SAMD_MKR1000) +// Use WiFi +#include +#include +char ssid[] = ""; // your network SSID (name) +char pass[] = ""; // your network password +int status = WL_IDLE_STATUS; +WiFiClient client; +#elif defined(USE_ETHERNET_SHIELD) +// Use wired ethernet shield +#include +#include +byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; +EthernetClient client; +#endif +#endif + +#include // always include thingspeak header file after other header files and custom macros + +unsigned long testPublicChannelNumber = 12397; // public channel number + +unsigned long testPrivateChannelNumber = 1070863; // private channel number +const char * testPrivateChannelWriteAPIKey = "UI7FSU4O8ZJ5BM8O"; // write API key for the private channel +const char * testPrivateChannelReadAPIKey = "I0QKRG8MU0HEFKYQ"; // read API key for the private channel + + +#define WRITE_DELAY_FOR_THINGSPEAK 15000 // Data write limit for a free user (15 sec). + +// Field number macros +#define FIELD0 0 // invalid +#define FIELD1 1 +#define FIELD2 2 +#define FIELD3 3 +#define FIELD4 4 +#define FIELD5 5 +#define FIELD6 6 +#define FIELD7 7 +#define FIELD8 8 +#define FIELD9 9 // invalid + +/* This test case checks for the following: + - read multiple with right channel number and read API key + - read multiple with invalid channel number + - read multiple with invalid read API key +*/ +test(readBasicCase) +{ + // Test basic feed read + assertEqual(TS_OK_SUCCESS, ThingSpeak.readMultipleFields(testPrivateChannelNumber, testPrivateChannelReadAPIKey)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.readMultipleFields(testPublicChannelNumber)); + + // Test read with invalid API key from a private channel + assertEqual(TS_ERR_BADAPIKEY, ThingSpeak.readMultipleFields(testPrivateChannelNumber, "AFAKEAPIKEYFAKEX")); + + // Test read with invalid channel number + assertEqual(TS_ERR_BADURL, ThingSpeak.readMultipleFields(00000, testPrivateChannelReadAPIKey)); + assertEqual(TS_ERR_BADURL, ThingSpeak.readMultipleFields(00000)); + + +} + + +#if defined(ARDUINO_AVR_MEGA2560) || defined(ARDUINO_SAMD_MKR1000) // Only the mega and mkr1000 has enough memory for all these tests + + + /* This test case checks for the following: + - Number of characters that can be read at a time per field + */ + test(fieldLimitsCase) + { + unsigned int numChar = 110; + String longString; + String longStatus; + float latitude = 3.1415926535; + float longitude = 3.1415926535; + float elevation = 3.1415926535; + + // Always to ensure that rate limit isn't hit + delay(WRITE_DELAY_FOR_THINGSPEAK); + + // Test field character limits via string + for(unsigned int i = 0; i < numChar; i++) + { + longString += '0'; + } + + // status message will have 255 characters + for(unsigned int i = 0; i < 255; i++) + { + longStatus += '0'; + } + + // Test multiple write + assertEqual(TS_OK_SUCCESS, ThingSpeak.setField(FIELD1, longString)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.setField(FIELD2, longString)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.setField(FIELD3, longString)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.setField(FIELD4, longString)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.setField(FIELD5, longString)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.setField(FIELD6, longString)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.setField(FIELD7, longString)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.setField(FIELD8, longString)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.setStatus(longStatus)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.setLatitude(latitude)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.setLongitude(longitude)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.setElevation(elevation)); + assertEqual(TS_OK_SUCCESS,ThingSpeak.writeFields(testPrivateChannelNumber, testPrivateChannelWriteAPIKey)); + + // Test basic feed read + assertEqual(TS_OK_SUCCESS, ThingSpeak.readMultipleFields(testPrivateChannelNumber, testPrivateChannelReadAPIKey)); + + // Test fetching data + assertEqual(longString, ThingSpeak.getFieldAsString(FIELD1)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.getLastReadStatus()); + + assertEqual(longString, ThingSpeak.getFieldAsString(FIELD2)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.getLastReadStatus()); + + assertEqual(longString, ThingSpeak.getFieldAsString(FIELD3)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.getLastReadStatus()); + + assertEqual(longString, ThingSpeak.getFieldAsString(FIELD4)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.getLastReadStatus()); + + assertEqual(longString, ThingSpeak.getFieldAsString(FIELD5)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.getLastReadStatus()); + + assertEqual(longString, ThingSpeak.getFieldAsString(FIELD6)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.getLastReadStatus()); + + assertEqual(longString, ThingSpeak.getFieldAsString(FIELD7)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.getLastReadStatus()); + + assertEqual(longString, ThingSpeak.getFieldAsString(FIELD8)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.getLastReadStatus()); + + } + + + /* This test case checks for the following: + - set values for all 8 fields + - read multiple + - get values for all 8 fields as float + - invalid field number + */ + test(getFieldAsFloatCase) + { + float floatVal = 3.14159; + int intVal = -47; + long longVal = 100000L; + float nanVal = NAN; + float infVal = INFINITY; + const char * constCharVal = "foobar"; + String stringVal = "barfoo"; + + // Always to ensure that rate limit isn't hit + delay(WRITE_DELAY_FOR_THINGSPEAK); + + // Test basic multi-field write + assertEqual(TS_OK_SUCCESS, ThingSpeak.setField(FIELD1, floatVal)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.setField(FIELD2, intVal)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.setField(FIELD3, longVal)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.setField(FIELD4, nanVal)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.setField(FIELD5, constCharVal)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.setField(FIELD6, stringVal)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.setField(FIELD7, infVal)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.setField(FIELD8, NULL)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.writeFields(testPrivateChannelNumber, testPrivateChannelWriteAPIKey)); + + // Test basic feed read + assertEqual(TS_OK_SUCCESS, ThingSpeak.readMultipleFields(testPrivateChannelNumber, testPrivateChannelReadAPIKey)); + + // Test fetching data as float + assertEqual(floatVal, ThingSpeak.getFieldAsFloat(FIELD1)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.getLastReadStatus()); + + assertEqual((float)intVal, ThingSpeak.getFieldAsFloat(FIELD2)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.getLastReadStatus()); + + assertEqual((float)longVal, ThingSpeak.getFieldAsFloat(FIELD3)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.getLastReadStatus()); + + assertTrue(isnan( ThingSpeak.getFieldAsFloat(FIELD4))); + assertEqual(TS_OK_SUCCESS, ThingSpeak.getLastReadStatus()); + + assertEqual(0.0, ThingSpeak.getFieldAsFloat(FIELD5)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.getLastReadStatus()); + + assertEqual(0.0, ThingSpeak.getFieldAsFloat(FIELD6)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.getLastReadStatus()); + + assertTrue(isinf(ThingSpeak.getFieldAsFloat(FIELD7))); + assertEqual(TS_OK_SUCCESS, ThingSpeak.getLastReadStatus()); + + assertEqual((float)NULL, ThingSpeak.getFieldAsFloat(FIELD8)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.getLastReadStatus()); + + // Test invalid field numbers + assertNotEqual(floatVal, ThingSpeak.getFieldAsFloat(FIELD0)); + assertEqual(TS_ERR_INVALID_FIELD_NUM, ThingSpeak.getLastReadStatus()); + + assertNotEqual(floatVal, ThingSpeak.getFieldAsFloat(FIELD9)); + assertEqual(TS_ERR_INVALID_FIELD_NUM, ThingSpeak.getLastReadStatus()); + } + + + /* This test case checks for the following: + - set values for all 8 fields + - read multiple + - get values for all 8 fields as int + - invalid field number + */ + test(getFieldAsIntCase) + { + float floatVal = 3.14159; + int intVal = -47; + long longVal = 100000L; + const char * constCharVal = "foobar"; + String stringVal = "barfoo"; + + // Always to ensure that rate limit isn't hit + delay(WRITE_DELAY_FOR_THINGSPEAK); + + // Test basic multi-field write + assertEqual(TS_OK_SUCCESS, ThingSpeak.setField(FIELD1, floatVal)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.setField(FIELD2, intVal)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.setField(FIELD3, longVal)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.setField(FIELD4, constCharVal)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.setField(FIELD5, stringVal)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.setField(FIELD6, NULL)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.writeFields(testPrivateChannelNumber, testPrivateChannelWriteAPIKey)); + + // Test basic feed read + assertEqual(TS_OK_SUCCESS, ThingSpeak.readMultipleFields(testPrivateChannelNumber, testPrivateChannelReadAPIKey)); + + // Test fetching data as int + assertEqual((int)floatVal, ThingSpeak.getFieldAsInt(FIELD1)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.getLastReadStatus()); + + assertEqual(intVal, ThingSpeak.getFieldAsInt(FIELD2)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.getLastReadStatus()); + + assertEqual((int)longVal, ThingSpeak.getFieldAsInt(FIELD3)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.getLastReadStatus()); + + assertEqual(0, ThingSpeak.getFieldAsInt(FIELD4)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.getLastReadStatus()); + + assertEqual(0, ThingSpeak.getFieldAsInt(FIELD5)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.getLastReadStatus()); + + assertEqual((int)NULL, ThingSpeak.getFieldAsInt(FIELD6)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.getLastReadStatus()); + + // Test invalid field numbers + assertNotEqual(intVal, ThingSpeak.getFieldAsInt(FIELD0)); + assertEqual(TS_ERR_INVALID_FIELD_NUM, ThingSpeak.getLastReadStatus()); + + assertNotEqual(intVal, ThingSpeak.getFieldAsInt(FIELD9)); + assertEqual(TS_ERR_INVALID_FIELD_NUM, ThingSpeak.getLastReadStatus()); + } + + + /* This test case checks for the following: + - set values for all 8 fields + - read multiple + - get values for all 8 fields as long + - invalid field number + */ + test(getFieldAsLongCase) + { + float floatVal = 3.14159; + int intVal = -47; + long longVal = 100000L; + const char * constCharVal = "foobar"; + String stringVal = "barfoo"; + + // Always to ensure that rate limit isn't hit + delay(WRITE_DELAY_FOR_THINGSPEAK); + + // Test basic multi-field write + assertEqual(TS_OK_SUCCESS, ThingSpeak.setField(FIELD1, floatVal)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.setField(FIELD2, intVal)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.setField(FIELD3, longVal)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.setField(FIELD4, constCharVal)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.setField(FIELD5, stringVal)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.setField(FIELD6, NULL)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.writeFields(testPrivateChannelNumber, testPrivateChannelWriteAPIKey)); + + // Test basic feed read + assertEqual(TS_OK_SUCCESS, ThingSpeak.readMultipleFields(testPrivateChannelNumber, testPrivateChannelReadAPIKey)); + + // Test fetching data as long + assertEqual((long)floatVal, ThingSpeak.getFieldAsLong(FIELD1)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.getLastReadStatus()); + + assertEqual((long)intVal, ThingSpeak.getFieldAsInt(FIELD2)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.getLastReadStatus()); + + assertEqual(longVal, ThingSpeak.getFieldAsInt(FIELD3)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.getLastReadStatus()); + + assertEqual(0, ThingSpeak.getFieldAsInt(FIELD4)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.getLastReadStatus()); + + assertEqual(0, ThingSpeak.getFieldAsInt(FIELD5)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.getLastReadStatus()); + + assertEqual((long)NULL, ThingSpeak.getFieldAsInt(FIELD6)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.getLastReadStatus()); + + // Test invalid field numbers + assertNotEqual(longVal, ThingSpeak.getFieldAsInt(FIELD0)); + assertEqual(TS_ERR_INVALID_FIELD_NUM, ThingSpeak.getLastReadStatus()); + + assertNotEqual(longVal, ThingSpeak.getFieldAsInt(FIELD9)); + assertEqual(TS_ERR_INVALID_FIELD_NUM, ThingSpeak.getLastReadStatus()); + } + + + /* This test case checks for the following: + - set values for all 8 fields + - read multiple + - get values for all 8 fields as String + - invalid field number + */ + test(getFieldAsStringCase) + { + float floatVal = 3.14159; + int intVal = -47; + long longVal = 100000L; + float nanVal = NAN; + float infVal = INFINITY; + const char * constCharVal = "foobar"; + String stringVal = "barfoo"; + + // Always to ensure that rate limit isn't hit + delay(WRITE_DELAY_FOR_THINGSPEAK); + + // Test basic multi-field write + assertEqual(TS_OK_SUCCESS, ThingSpeak.setField(FIELD1, floatVal)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.setField(FIELD2, intVal)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.setField(FIELD3, longVal)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.setField(FIELD4, nanVal)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.setField(FIELD5, constCharVal)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.setField(FIELD6, stringVal)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.setField(FIELD7, infVal)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.setField(FIELD8, NULL)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.writeFields(testPrivateChannelNumber, testPrivateChannelWriteAPIKey)); + + // Test basic feed read + assertEqual(TS_OK_SUCCESS, ThingSpeak.readMultipleFields(testPrivateChannelNumber, testPrivateChannelReadAPIKey)); + + // Test fetching data as String + assertEqual("3.14159", ThingSpeak.getFieldAsString(FIELD1)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.getLastReadStatus()); + + assertEqual("-47", ThingSpeak.getFieldAsString(FIELD2)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.getLastReadStatus()); + + assertEqual("100000", ThingSpeak.getFieldAsString(FIELD3)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.getLastReadStatus()); + + assertEqual("nan", ThingSpeak.getFieldAsString(FIELD4)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.getLastReadStatus()); + + assertEqual(constCharVal, ThingSpeak.getFieldAsString(FIELD5)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.getLastReadStatus()); + + assertEqual(stringVal, ThingSpeak.getFieldAsString(FIELD6)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.getLastReadStatus()); + + assertEqual("inf", ThingSpeak.getFieldAsString(FIELD7)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.getLastReadStatus()); + + assertEqual(String(NULL), ThingSpeak.getFieldAsString(FIELD8)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.getLastReadStatus()); + + // Test invalid field numbers + assertNotEqual(stringVal, ThingSpeak.getFieldAsString(FIELD0)); + assertEqual(TS_ERR_INVALID_FIELD_NUM, ThingSpeak.getLastReadStatus()); + + assertNotEqual(stringVal, ThingSpeak.getFieldAsString(FIELD9)); + assertEqual(TS_ERR_INVALID_FIELD_NUM, ThingSpeak.getLastReadStatus()); + } + + + /* This test case checks for the following: + - set status message + - read multiple + - get status message + */ + test(getStatusCase) + { + String statusMessage = "abcdef"; + // Always wait 15 seconds to ensure that rate limit isn't hit + delay(WRITE_DELAY_FOR_THINGSPEAK); + + // Test status write + assertEqual(TS_OK_SUCCESS, ThingSpeak.setStatus(statusMessage)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.writeFields(testPrivateChannelNumber, testPrivateChannelWriteAPIKey)); // string + + // Test basic feed read + assertEqual(TS_OK_SUCCESS, ThingSpeak.readMultipleFields(testPrivateChannelNumber, testPrivateChannelReadAPIKey)); + + // Test fetching status message + assertEqual(statusMessage, ThingSpeak.getStatus()); + } + + + /* This test case checks for the following: + - set latitude, longitude, elevation + - read multiple + - get latitude, longitude, elevation + */ + test(getLocationCase) + { + float latitude = 42.28372; // +ve is North, -ve is South + float longitude = -71.3472; // +ve is East, -ve is West + float elevation = 54.9; // metres above sea level + + // Always wait 15 seconds to ensure that rate limit isn't hit + delay(WRITE_DELAY_FOR_THINGSPEAK); + + // Test status write + assertEqual(TS_OK_SUCCESS, ThingSpeak.setLatitude(latitude)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.setLongitude(longitude)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.setElevation(elevation)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.writeFields(testPrivateChannelNumber, testPrivateChannelWriteAPIKey)); // string + + // Test basic feed read + assertEqual(TS_OK_SUCCESS, ThingSpeak.readMultipleFields(testPrivateChannelNumber, testPrivateChannelReadAPIKey)); + + // Test fetching location coordinates + assertNotEqual("", ThingSpeak.getLatitude()); + assertNotEqual("", ThingSpeak.getLongitude()); + assertNotEqual("", ThingSpeak.getElevation()); + } + + + /* This test case checks for the following: + - read multiple + - get default current created-at timestamp + - get user-defined created-at timestamp + */ + test(getCreatedAtCase) + { + // Test basic feed read + assertEqual(TS_OK_SUCCESS, ThingSpeak.readMultipleFields(testPrivateChannelNumber, testPrivateChannelReadAPIKey)); + + // Default current created-at timestamp + assertNotEqual("", ThingSpeak.getCreatedAt()); + + /* Test this separately + + // Always wait 15 seconds to ensure that rate limit isn't hit + delay(WRITE_DELAY_FOR_THINGSPEAK); + + // User-defined created-at timestamp + ThingSpeak.setCreatedAt("2020-07-17T20:24:50Z"); // Time should be later than the current time, since latest feed is read. + assertEqual(TS_OK_SUCCESS, ThingSpeak.writeFields(testPrivateChannelNumber, testPrivateChannelWriteAPIKey)); // string + assertEqual(TS_OK_SUCCESS, ThingSpeak.readMultipleFields(testPrivateChannelNumber, testPrivateChannelReadAPIKey)); + assertEqual("2020-07-17T20:24:50Z", ThingSpeak.getCreatedAt()); + + */ + } + +#endif // Mega and MKR1000 only tests + + +void setup() +{ + Serial.begin(9600); + while (!Serial); // for the Arduino Leonardo/Micro only + Serial.println("Starting test..."); + #ifdef ARDUINO_AVR_YUN + Bridge.begin(); + #else + #if defined(USE_WIFI101_SHIELD) || defined(ARDUINO_SAMD_MKR1000) + WiFi.begin(ssid, pass); + #else + Ethernet.begin(mac); + #endif + #endif + ThingSpeak.begin(client); +} + +void loop() +{ + Test::run(); +} diff --git a/extras/test/testSecureConnect/testSecureConnect.ino b/extras/test/testSecureConnect/testSecureConnect.ino new file mode 100644 index 0000000..e8bd132 --- /dev/null +++ b/extras/test/testSecureConnect/testSecureConnect.ino @@ -0,0 +1,108 @@ +#line 2 "testSecureConnect.ino" +/* + testSecureConnect unit test + + Unit Test for the secure connection through HTTPS in the ThingSpeak Communication Library for Arduino + + This test use the ArduinoUnit 2.1.0 unit test framework. Visit https://github.com/mmurdoch/arduinounit to learn more. + + ArduinoUnit does not support ESP8266 or ESP32 and therefor these tests will not compile for those platforms. + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +//#define USE_WIFI101_SHIELD +//#define USE_ETHERNET_SHIELD + + +#if !defined(USE_WIFI101_SHIELD) && !defined(USE_ETHERNET_SHIELD) && !defined(ARDUINO_SAMD_MKR1000) && !defined(ARDUINO_AVR_YUN) + #error "Uncomment the #define for either USE_WIFI101_SHIELD or USE_ETHERNET_SHIELD" +#endif + +#include + +#if defined(ARDUINO_AVR_YUN) + #include "YunClient.h" + YunClient client; +#else + #if defined(USE_WIFI101_SHIELD) || defined(ARDUINO_SAMD_MKR1000) + // Use WiFi + #include + #include + char ssid[] = ""; // your network SSID (name) + char pass[] = ""; // your network password + int status = WL_IDLE_STATUS; + WiFiSSLClient secureClient; + #elif defined(USE_ETHERNET_SHIELD) + // Use wired ethernet shield + #include + #include + byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; + EthernetClient client; + #endif +#endif + +#define TS_ENABLE_SSL +#include // always include thingspeak header file after other header files and custom macros +#define FIELD1 1 +#define WRITE_DELAY_FOR_THINGSPEAK 15000 // Data write limit for a free user (15 sec). + +unsigned long testChannelNumber = 1070863; +const char * testChannelWriteAPIKey = "UI7FSU4O8ZJ5BM8O"; + +#if defined(USE_WIFI101_SHIELD) || defined(ARDUINO_SAMD_MKR1000) + test(secureConnectMKR1000Case) + { + assertTrue(ThingSpeak.begin(secureClient)); + + int val = 25; + + // Always wait to ensure that rate limit isn't hit + delay(WRITE_DELAY_FOR_THINGSPEAK); + assertTrue(ThingSpeak.begin(secureClient)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.writeField(testChannelNumber, FIELD1, val, testChannelWriteAPIKey)); + } +#endif + +#if defined(USE_ETHERNET_SHIELD) || defined(ARDUINO_AVR_UNO) + test(secureConnectUnoEthernetCase) + { + assertTrue(ThingSpeak.begin(client)); + + int val = 25; + + // Always wait to ensure that rate limit isn't hit + delay(WRITE_DELAY_FOR_THINGSPEAK); + assertTrue(ThingSpeak.begin(client)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.writeField(testChannelNumber, FIELD1, val, testChannelWriteAPIKey)); + } +#endif + +void setup() +{ + Serial.begin(9600); + while(!Serial); // for the Arduino Leonardo/Micro only + Serial.println("Starting test..."); + #ifdef ARDUINO_AVR_YUN + Bridge.begin(); + #else + #if defined(USE_WIFI101_SHIELD) || defined(ARDUINO_SAMD_MKR1000) + WiFi.begin(ssid, pass); + #else + Ethernet.begin(mac); + #endif + #endif +} + +void loop() +{ + Test::run(); +} diff --git a/extras/test/testSetField/testSetField.ino b/extras/test/testSetField/testSetField.ino deleted file mode 100644 index 4206455..0000000 --- a/extras/test/testSetField/testSetField.ino +++ /dev/null @@ -1,383 +0,0 @@ -#line 2 "testSetField.ino" -/* - testSetField unit test - - Unit Test for the writeFields and setField functions in the ThingSpeak Communication Library for Arduino - - This test use the ArduinoUnit 2.1.0 unit test framework. Visit https://github.com/mmurdoch/arduinounit to learn more. - - ArduinoUnit does not support ESP8266 or ESP32 and therefor these tests will not compile for those platforms. - - ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and - analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. - - Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. - See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. - - For licensing information, see the accompanying license file. - - Copyright 2018, The MathWorks, Inc. -*/ - -//#define USE_WIFI101_SHIELD -//#define USE_ETHERNET_SHIELD - -#if !defined(USE_WIFI101_SHIELD) && !defined(USE_ETHERNET_SHIELD) && !defined(ARDUINO_SAMD_MKR1000) && !defined(ARDUINO_AVR_YUN) - #error "Uncomment the #define for either USE_WIFI101_SHIELD or USE_ETHERNET_SHIELD" -#endif - -#include -#include - -#if defined(ARDUINO_AVR_YUN) - #include "YunClient.h" - YunClient client; -#else - #if defined(USE_WIFI101_SHIELD) || defined(ARDUINO_SAMD_MKR1000) - #include - #include - char ssid[] = ""; // your network SSID (name) - char pass[] = ""; // your network password - int status = WL_IDLE_STATUS; - WiFiClient client; - #elif defined(USE_ETHERNET_SHIELD) - // Use wired ethernet shield - #include - #include - byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; - EthernetClient client; - #endif -#endif - -unsigned long testChannelNumber = 209617; -const char * testChannelWriteAPIKey = "514SX5OBP2OFEPL2"; - -#define WRITE_DELAY_FOR_THINGSPEAK 15000 - -test(setFieldCase) -{ - // Always wait to ensure that rate limit isn't hit - delay(WRITE_DELAY_FOR_THINGSPEAK); - - // No fields set - assertEqual(ERR_SETFIELD_NOT_CALLED, ThingSpeak.writeFields(testChannelNumber, testChannelWriteAPIKey)); - - // Test basic multi-field write - assertEqual(OK_SUCCESS,ThingSpeak.setField(1,(float)3.14159)); // float - assertEqual(OK_SUCCESS,ThingSpeak.setField(2,-47)); // integer - assertEqual(OK_SUCCESS,ThingSpeak.setField(3,(long)100000L)); // long - assertEqual(OK_SUCCESS,ThingSpeak.setField(4,(float)NAN)); // Nan - assertEqual(OK_SUCCESS,ThingSpeak.setField(5,"foobar")); // string - assertEqual(OK_SUCCESS,ThingSpeak.setField(6,(float)INFINITY)); // + inf - assertEqual(OK_SUCCESS,ThingSpeak.setField(7,(float)-INFINITY)); // + inf - assertEqual(OK_SUCCESS,ThingSpeak.writeFields(testChannelNumber, testChannelWriteAPIKey)); - - // Test write when not enough time has elapsed - assertEqual(OK_SUCCESS,ThingSpeak.setField(1,(float)3.14159)); // float - assertEqual(ERR_NOT_INSERTED,ThingSpeak.writeFields(testChannelNumber, testChannelWriteAPIKey)); - - // Allow enough time to pass to make sure that it would work - delay(WRITE_DELAY_FOR_THINGSPEAK); - - // Test write to field out of range - assertEqual(ERR_INVALID_FIELD_NUM,ThingSpeak.setField(0,(float)3.14159)); - assertEqual(ERR_INVALID_FIELD_NUM,ThingSpeak.setField(9,(float)3.14159)); -} - -#if defined(ARDUINO_AVR_MEGA2560) || defined(ARDUINO_SAMD_MKR1000) // Only the mega and mkr1000 has enough memory for all these tests -test(setFieldFloatCase) -{ - // Always wait to ensure that rate limit isn't hit - delay(WRITE_DELAY_FOR_THINGSPEAK); - - // Test max range values - assertEqual(OK_SUCCESS, ThingSpeak.setField(1, (float)-999999000000)); - assertEqual(OK_SUCCESS, ThingSpeak.setField(2, (float)999999000000)); - - // Test high precision values - assertEqual(OK_SUCCESS, ThingSpeak.setField(3, (float)3.14159)); - assertEqual(OK_SUCCESS, ThingSpeak.setField(4, (float)-3.14159)); - - // Test passing NaN and Inf - assertEqual(OK_SUCCESS, ThingSpeak.setField(5, (float)NAN)); - assertEqual(OK_SUCCESS, ThingSpeak.setField(6, (float)INFINITY)); - assertEqual(OK_SUCCESS, ThingSpeak.setField(7, (float)-INFINITY)); - - // Test out of range values - assertEqual(ERR_OUT_OF_RANGE, ThingSpeak.setField(8, (float)-1000000000000.0)); - assertEqual(ERR_OUT_OF_RANGE, ThingSpeak.setField(8, (float)1000000000000.0)); - - assertEqual(OK_SUCCESS,ThingSpeak.writeFields(testChannelNumber, testChannelWriteAPIKey)); -} - -test(setFieldIntCase) -{ - // Always wait to ensure that rate limit isn't hit - delay(WRITE_DELAY_FOR_THINGSPEAK); - - // Test max range values - assertEqual(OK_SUCCESS, ThingSpeak.setField(1, (int)-32768)); - assertEqual(OK_SUCCESS, ThingSpeak.setField(2, (int)32767)); - - assertEqual(OK_SUCCESS,ThingSpeak.writeFields(testChannelNumber, testChannelWriteAPIKey)); -} - -test(setFieldLongCase) -{ - // Always wait to ensure that rate limit isn't hit - delay(WRITE_DELAY_FOR_THINGSPEAK); - - // Test max range values - assertEqual(OK_SUCCESS, ThingSpeak.setField(1, (long)-2147483648L)); - assertEqual(OK_SUCCESS, ThingSpeak.setField(2, (long)2147483647L)); - - assertEqual(OK_SUCCESS,ThingSpeak.writeFields(testChannelNumber, testChannelWriteAPIKey)); -} - -test(setFieldCharStarCase) -{ - // Always wait to ensure that rate limit isn't hit - delay(WRITE_DELAY_FOR_THINGSPEAK); - - // Test empty string - assertEqual(OK_SUCCESS, ThingSpeak.setField(1, "")); - - char longString[300]; - - // Test max string - memset(longString, '0',255); - longString[255] = 0; - assertEqual(OK_SUCCESS, ThingSpeak.setField(2, longString)); - - // Test long string - memset(longString, '0',sizeof(longString)/sizeof(longString[0]) - 1); - longString[sizeof(longString)] = 0; - - assertEqual(ERR_OUT_OF_RANGE, ThingSpeak.setField(3, longString)); - - assertEqual(OK_SUCCESS,ThingSpeak.writeFields(testChannelNumber, testChannelWriteAPIKey)); -} - -test(setFieldStringCase) -{ - // Always wait to ensure that rate limit isn't hit - delay(WRITE_DELAY_FOR_THINGSPEAK); - - // Test empty string - assertEqual(OK_SUCCESS, ThingSpeak.setField(1, String())); - - unsigned int numChar = 300; - String longString; - longString.reserve(numChar); - - // Test max string - for(unsigned int i = 0; i < 255; i++) - { - longString += '0'; - } - assertEqual(OK_SUCCESS, ThingSpeak.setField(2, longString)); - - // Test long string - longString.reserve(numChar); - for(unsigned int i = 0; i < numChar; i++) - { - longString += '0'; - } - - assertEqual(ERR_OUT_OF_RANGE, ThingSpeak.setField(3, longString)); - - assertEqual(OK_SUCCESS,ThingSpeak.writeFields(testChannelNumber, testChannelWriteAPIKey)); -} - -test(setStatusCharStarCase) -{ - // Always wait to ensure that rate limit isn't hit - delay(WRITE_DELAY_FOR_THINGSPEAK); - - // Test empty string - assertEqual(OK_SUCCESS, ThingSpeak.setStatus("")); - - char longString[300]; - - // Test max string - memset(longString, '0',255); - longString[255] = 0; - assertEqual(OK_SUCCESS, ThingSpeak.setStatus(longString)); - - // Test long string - memset(longString, '0',sizeof(longString)/sizeof(longString[0]) - 1); - longString[sizeof(longString)] = 0; - - assertEqual(ERR_OUT_OF_RANGE, ThingSpeak.setStatus(longString)); - - assertEqual(OK_SUCCESS,ThingSpeak.writeFields(testChannelNumber, testChannelWriteAPIKey)); - -} - -test(setStatusStringCase) -{ - // Always wait to ensure that rate limit isn't hit - delay(WRITE_DELAY_FOR_THINGSPEAK); - - // Test empty string - assertEqual(OK_SUCCESS, ThingSpeak.setStatus(String())); - - unsigned int numChar = 300; - String longString; - longString.reserve(numChar); - - // Test max string - for(unsigned int i = 0; i < 255; i++) - { - longString += '0'; - } - assertEqual(OK_SUCCESS, ThingSpeak.setStatus(longString)); - - // Test long string - longString.reserve(numChar); - for(unsigned int i = 0; i < numChar; i++) - { - longString += '0'; - } - - assertEqual(ERR_OUT_OF_RANGE, ThingSpeak.setStatus(longString)); - - assertEqual(OK_SUCCESS,ThingSpeak.writeFields(testChannelNumber, testChannelWriteAPIKey)); -} - -test(setTwitterTweetTwitterCharStarCase) -{ - // Always wait to ensure that rate limit isn't hit - delay(WRITE_DELAY_FOR_THINGSPEAK); - - // Test empty string - assertEqual(OK_SUCCESS, ThingSpeak.setTwitterTweet("","")); - - char longString[300]; - char normalString[32] = "normalString"; - - // Test max string - memset(longString, '0',255); - longString[255] = 0; - assertEqual(OK_SUCCESS, ThingSpeak.setTwitterTweet(longString, normalString)); - assertEqual(OK_SUCCESS, ThingSpeak.setTwitterTweet(normalString, longString)); - - // Test long string - memset(longString, '0',sizeof(longString)/sizeof(longString[0]) - 1); - longString[sizeof(longString)] = 0; - - assertEqual(ERR_OUT_OF_RANGE, ThingSpeak.setTwitterTweet(longString, normalString)); - assertEqual(ERR_OUT_OF_RANGE, ThingSpeak.setTwitterTweet(normalString, longString)); - - assertEqual(OK_SUCCESS,ThingSpeak.writeFields(testChannelNumber, testChannelWriteAPIKey)); -} - -test(setTwitterTweetStringCase) -{ - // Always wait to ensure that rate limit isn't hit - delay(WRITE_DELAY_FOR_THINGSPEAK); - - // Test empty string - assertEqual(OK_SUCCESS, ThingSpeak.setTwitterTweet(String(),String())); - - unsigned int numChar = 300; - String longString; - longString.reserve(numChar); - - String normalString = "normalString"; - - // Test max string - for(unsigned int i = 0; i < 255; i++) - { - longString += '0'; - } - assertEqual(OK_SUCCESS, ThingSpeak.setTwitterTweet(longString, normalString)); - assertEqual(OK_SUCCESS, ThingSpeak.setTwitterTweet(normalString, longString)); - - // Test long string - longString.reserve(numChar); - for(unsigned int i = 0; i < numChar; i++) - { - longString += '0'; - } - - assertEqual(ERR_OUT_OF_RANGE, ThingSpeak.setTwitterTweet(longString, normalString)); - assertEqual(ERR_OUT_OF_RANGE, ThingSpeak.setTwitterTweet(normalString, longString)); - - assertEqual(OK_SUCCESS,ThingSpeak.writeFields(testChannelNumber, testChannelWriteAPIKey)); -} - -test(setCreatedAtCharStarCase) -{ - // Always wait to ensure that rate limit isn't hit - delay(WRITE_DELAY_FOR_THINGSPEAK); - - // Test empty string - assertEqual(OK_SUCCESS, ThingSpeak.setCreatedAt("")); - - char longString[300]; - - // Test timestamp string - strcpy(longString,"2016-12-21T11:11:11Z"); - assertEqual(OK_SUCCESS, ThingSpeak.setCreatedAt(longString)); - - // Test long string - memset(longString, '0',sizeof(longString)/sizeof(longString[0]) - 1); - longString[sizeof(longString)] = 0; - - assertEqual(ERR_OUT_OF_RANGE, ThingSpeak.setCreatedAt(longString)); - - assertEqual(OK_SUCCESS,ThingSpeak.writeFields(testChannelNumber, testChannelWriteAPIKey)); -} - -test(setCreatedAtStringCase) -{ - // Always wait to ensure that rate limit isn't hit - delay(WRITE_DELAY_FOR_THINGSPEAK); - - // Test empty string - assertEqual(OK_SUCCESS, ThingSpeak.setCreatedAt(String())); - - unsigned int numChar = 300; - String longString; - longString.reserve(numChar); - - // Test timestamp string - longString = "2016-12-21T11:11:11Z"; - assertEqual(OK_SUCCESS, ThingSpeak.setCreatedAt(longString)); - - // Test long string - longString.reserve(numChar); - for(unsigned int i = 0; i < numChar; i++) - { - longString += '0'; - } - - assertEqual(ERR_OUT_OF_RANGE, ThingSpeak.setCreatedAt(longString)); - - assertEqual(OK_SUCCESS,ThingSpeak.writeFields(testChannelNumber, testChannelWriteAPIKey)); -} -#endif // Mega and MKR1000 only tests - -void setup() -{ - Serial.begin(9600); - while(!Serial); // for the Arduino Leonardo/Micro only - Serial.println("Starting test..."); - #ifdef ARDUINO_AVR_YUN - Bridge.begin(); - #else - #if defined(USE_WIFI101_SHIELD) || defined(ARDUINO_SAMD_MKR1000) - WiFi.begin(ssid, pass); - #else - Ethernet.begin(mac); - #endif - #endif - ThingSpeak.begin(client); -} - -void loop() -{ - Test::run(); -} - diff --git a/extras/test/testSetFunctions/testSetFunctions.ino b/extras/test/testSetFunctions/testSetFunctions.ino new file mode 100644 index 0000000..e5b94cf --- /dev/null +++ b/extras/test/testSetFunctions/testSetFunctions.ino @@ -0,0 +1,374 @@ +#line 2 "testSetFunctions.ino" +/* + testSetField unit test + + Unit Test for the writeFields and setField functions in the ThingSpeak Communication Library for Arduino along with setTwitter, setStatus and setCreatedAt functionalities. + + This test use the ArduinoUnit 2.1.0 unit test framework. Visit https://github.com/mmurdoch/arduinounit to learn more. + + ArduinoUnit does not support ESP8266 or ESP32 and therefor these tests will not compile for those platforms. + + ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and + analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel. + + Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed. + See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation. + + For licensing information, see the accompanying license file. + + Copyright 2020, The MathWorks, Inc. +*/ + +//#define USE_WIFI101_SHIELD +//#define USE_ETHERNET_SHIELD + +#if !defined(USE_WIFI101_SHIELD) && !defined(USE_ETHERNET_SHIELD) && !defined(ARDUINO_SAMD_MKR1000) && !defined(ARDUINO_AVR_YUN) + #error "Uncomment the #define for either USE_WIFI101_SHIELD or USE_ETHERNET_SHIELD" +#endif + +#include + +#if defined(ARDUINO_AVR_YUN) + #include "YunClient.h" + YunClient client; +#else + #if defined(USE_WIFI101_SHIELD) || defined(ARDUINO_SAMD_MKR1000) + #include + #include + char ssid[] = ""; // your network SSID (name) + char pass[] = ""; // your network password + int status = WL_IDLE_STATUS; + WiFiClient client; + #elif defined(USE_ETHERNET_SHIELD) + // Use wired ethernet shield + #include + #include + byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; + EthernetClient client; + #endif +#endif + +#include // always include thingspeak header file after other header files and custom macros + +unsigned long testChannelNumber = 1070863; +const char * testChannelWriteAPIKey = "UI7FSU4O8ZJ5BM8O"; + +#define WRITE_DELAY_FOR_THINGSPEAK 15000 // Data write limit for a free user (15 sec). + +// Field number macros +#define FIELD0 0 +#define FIELD1 1 +#define FIELD2 2 +#define FIELD3 3 +#define FIELD4 4 +#define FIELD5 5 +#define FIELD6 6 +#define FIELD7 7 +#define FIELD8 8 +#define FIELD9 9 + +/* This test case checks for the following: + - set float value + - set int value + - set long value + - set NAN + - set const char * string value + - set String class instance value + - set INFINITY + - set NULL + - multiple write + - rate limit error + - invalid field set +*/ +test(setFieldCase) +{ + float floatVal = 3.14159; + int intVal = -47; + long longVal = 100000L; + float nanVal = NAN; + float infVal = INFINITY; + const char * constCharVal = "foobar"; + String stringVal = "barfoo"; + // Always wait to ensure that rate limit isn't hit + delay(WRITE_DELAY_FOR_THINGSPEAK); + + // No fields set + assertEqual(TS_ERR_SETFIELD_NOT_CALLED, ThingSpeak.writeFields(testChannelNumber, testChannelWriteAPIKey)); + + // Test basic multi-field write + assertEqual(TS_OK_SUCCESS,ThingSpeak.setField(FIELD1,floatVal)); + assertEqual(TS_OK_SUCCESS,ThingSpeak.setField(FIELD2,intVal)); + assertEqual(TS_OK_SUCCESS,ThingSpeak.setField(FIELD3,longVal)); + assertEqual(TS_OK_SUCCESS,ThingSpeak.setField(FIELD4,nanVal)); + assertEqual(TS_OK_SUCCESS,ThingSpeak.setField(FIELD5,constCharVal)); + assertEqual(TS_OK_SUCCESS,ThingSpeak.setField(FIELD6,stringVal)); + assertEqual(TS_OK_SUCCESS,ThingSpeak.setField(FIELD7,infVal)); + assertEqual(TS_OK_SUCCESS,ThingSpeak.setField(FIELD8,NULL)); + assertEqual(TS_OK_SUCCESS,ThingSpeak.writeFields(testChannelNumber, testChannelWriteAPIKey)); + + // Test write when not enough time has elapsed + assertEqual(TS_OK_SUCCESS,ThingSpeak.setField(1,(float)3.14159)); // float + assertEqual(TS_ERR_NOT_INSERTED,ThingSpeak.writeFields(testChannelNumber, testChannelWriteAPIKey)); + + // Allow enough time to pass to make sure that it would work + delay(WRITE_DELAY_FOR_THINGSPEAK); + + // Test write to field out of range + assertEqual(TS_ERR_INVALID_FIELD_NUM,ThingSpeak.setField(FIELD0,floatVal)); + assertEqual(TS_ERR_INVALID_FIELD_NUM,ThingSpeak.setField(FIELD9,floatVal)); +} + +#if defined(ARDUINO_AVR_MEGA2560) || defined(ARDUINO_SAMD_MKR1000) // Only the mega and mkr1000 has enough memory for all these tests + /* This test case checks the following: + - max/min values of float + - high precision values of float + - NaN and Inf values + - out of range values of float + */ + test(setFieldFloatCase) + { + float val = -999999000000; + // Always wait to ensure that rate limit isn't hit + delay(WRITE_DELAY_FOR_THINGSPEAK); + + // Test max/min range values + assertEqual(TS_OK_SUCCESS, ThingSpeak.setField(FIELD1, val)); + val = 999999000000; + assertEqual(TS_OK_SUCCESS, ThingSpeak.setField(FIELD2, val)); + + // Test high precision values + val = 3.14159; + assertEqual(TS_OK_SUCCESS, ThingSpeak.setField(FIELD3, val)); + val = -3.14159; + assertEqual(TS_OK_SUCCESS, ThingSpeak.setField(FIELD4, val)); + + // Test passing NaN and Inf + val = NAN; + assertEqual(TS_OK_SUCCESS,ThingSpeak.setField(FIELD5,val)); + val = INFINITY; + assertEqual(TS_OK_SUCCESS,ThingSpeak.setField(FIELD6,val)); + val = -INFINITY; + assertEqual(TS_OK_SUCCESS,ThingSpeak.setField(FIELD7,val)); + + // Test out of range values + val = -1000000000000.0; + assertEqual(TS_ERR_OUT_OF_RANGE, ThingSpeak.setField(FIELD8, val)); + val = 1000000000000.0; + assertEqual(TS_ERR_OUT_OF_RANGE, ThingSpeak.setField(FIELD8, val)); + + assertEqual(TS_OK_SUCCESS,ThingSpeak.writeFields(testChannelNumber, testChannelWriteAPIKey)); + } + + /* This test case checks for the following: + - max/min range values of int + */ + test(setFieldIntCase) + { + int val = -32768; + // Always wait to ensure that rate limit isn't hit + delay(WRITE_DELAY_FOR_THINGSPEAK); + + // Test max/min range values + assertEqual(TS_OK_SUCCESS, ThingSpeak.setField(FIELD1, val)); + val = 32767; + assertEqual(TS_OK_SUCCESS, ThingSpeak.setField(FIELD2, val)); + + assertEqual(TS_OK_SUCCESS,ThingSpeak.writeFields(testChannelNumber, testChannelWriteAPIKey)); + } + + /* This test case checks for the following: + - max/min range values of long + */ + test(setFieldLongCase) + { + long val = -2147483648L; + // Always wait to ensure that rate limit isn't hit + delay(WRITE_DELAY_FOR_THINGSPEAK); + + // Test max range values + assertEqual(TS_OK_SUCCESS, ThingSpeak.setField(FIELD1, val)); + val = 2147483647L; + assertEqual(TS_OK_SUCCESS, ThingSpeak.setField(FIELD2, val)); + + assertEqual(TS_OK_SUCCESS,ThingSpeak.writeFields(testChannelNumber, testChannelWriteAPIKey)); + } + + /* This test case checks for the following: + - emptry string values (String class and const char *) + - field character limits via String (positive and negative cases) + */ + test(setFieldStringCase) + { + const char * constChar_val = ""; + String string_val = ""; + // Always wait to ensure that rate limit isn't hit + delay(WRITE_DELAY_FOR_THINGSPEAK); + + // Test empty string + assertEqual(TS_OK_SUCCESS, ThingSpeak.setField(FIELD1, string_val)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.setField(FIELD2, constChar_val)); + + unsigned int numChar = 256; + String longString; + longString.reserve(numChar); + + // Test field character limits via string + for(unsigned int i = 0; i < 255; i++) + { + longString += '0'; + } + + // longString will have 256 '0' characters, since the number of characters ThingSpeak field can store is limited to 256 characters. + + assertEqual(TS_OK_SUCCESS, ThingSpeak.setField(FIELD3, longString)); + + longString += '0'; + + // longString will now have 257 '0' characters. Out of range error. + + assertEqual(TS_ERR_OUT_OF_RANGE, ThingSpeak.setField(FIELD4, longString)); + + assertEqual(TS_OK_SUCCESS,ThingSpeak.writeFields(testChannelNumber, testChannelWriteAPIKey)); + } + + /* This test case checks for the following: + - emptry string values (String class and const char *) + - status character limits via String (positive and negative cases) + */ + test(setStatusCase) + { + const char * constChar_status = ""; + String string_status = ""; + // Always wait to ensure that rate limit isn't hit + delay(WRITE_DELAY_FOR_THINGSPEAK); + + // Test empty string + assertEqual(TS_OK_SUCCESS, ThingSpeak.setStatus(constChar_status)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.setStatus(string_status)); + + unsigned int numChar = 256; + String longStatus; + longStatus.reserve(numChar); + + // Test status character limits via string + for(unsigned int i = 0; i < 255; i++) + { + longStatus += '0'; + } + + // longStatus will have 256 '0' characters, since the number of characters ThingSpeak status can store is limited to 256 characters. + + assertEqual(TS_OK_SUCCESS, ThingSpeak.setStatus(longStatus)); + + longStatus += '0'; + + // longString will now have 257 '0' characters. Out of range error. + + assertEqual(TS_ERR_OUT_OF_RANGE, ThingSpeak.setStatus(longStatus)); + + assertEqual(TS_OK_SUCCESS,ThingSpeak.writeFields(testChannelNumber, testChannelWriteAPIKey)); + } + + /* This test case checks for the following: + - emptry string values (String class and const char *) + - twitter handle and tweet character limits via String (positive and negative cases) + */ + test(setTwitterTweetCase) + { + const char * constChar_twitter = ""; + String string_twitter = ""; + // Always wait to ensure that rate limit isn't hit + delay(WRITE_DELAY_FOR_THINGSPEAK); + + // Test empty string + assertEqual(TS_OK_SUCCESS, ThingSpeak.setTwitterTweet(string_twitter, string_twitter)); // First argument is the twitter handle, second argument is the tweet + assertEqual(TS_OK_SUCCESS, ThingSpeak.setTwitterTweet(constChar_twitter, constChar_twitter)); // First argument is the twitter handle, second argument is the tweet + + unsigned int numChar = 256; + String longTwitter; + longTwitter.reserve(numChar); + + String normalTwitter = "normalString"; + + // Test twitter character limits + for(unsigned int i = 0; i < 255; i++) + { + longTwitter += '0'; + } + + // longTwitter will have 256 '0' characters, since the number of characters ThingSpeak status can store is limited to 256 characters. + + assertEqual(TS_OK_SUCCESS, ThingSpeak.setTwitterTweet(longTwitter, normalTwitter)); // First argument is the twitter handle, second argument is the tweet + assertEqual(TS_OK_SUCCESS, ThingSpeak.setTwitterTweet(normalTwitter, longTwitter)); // First argument is the twitter handle, second argument is the tweet + + longTwitter += '0'; + + // longTwitter will now have 257 '0' characters. Out of range error. + + assertEqual(TS_ERR_OUT_OF_RANGE, ThingSpeak.setTwitterTweet(longTwitter, normalTwitter)); // First argument is the twitter handle, second argument is the tweet + assertEqual(TS_ERR_OUT_OF_RANGE, ThingSpeak.setTwitterTweet(normalTwitter, longTwitter)); // First argument is the twitter handle, second argument is the tweet + + assertEqual(TS_OK_SUCCESS,ThingSpeak.writeFields(testChannelNumber, testChannelWriteAPIKey)); + } + + /* This test case checks for the following: + - emptry string values (String class and const char *) + - CreatedAt character limits via String (negative case) + - ISO 8601 format timestamp value + */ + test(setCreatedAtCase) + { + const char * constChar_time = ""; + String string_time = ""; + + // Always wait to ensure that rate limit isn't hit + delay(WRITE_DELAY_FOR_THINGSPEAK); + + // Test empty string + assertEqual(TS_OK_SUCCESS, ThingSpeak.setCreatedAt(string_time)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.setCreatedAt(constChar_time)); + + unsigned int numChar = 256; + String longTime; + longTime.reserve(numChar); + + // Test createdAt character limits + longTime.reserve(numChar); + for(unsigned int i = 0; i < numChar; i++) + { + longTime += '0'; + } + + // longTime will have 257 '0' characters. Out of range error. + + assertEqual(TS_ERR_OUT_OF_RANGE, ThingSpeak.setCreatedAt(longTime)); + + // Test timestamp string + longTime = "2020-19-06 04:47:10"; // ISO 8601 format + assertEqual(TS_OK_SUCCESS, ThingSpeak.setCreatedAt(longTime)); + + assertEqual(TS_OK_SUCCESS,ThingSpeak.writeFields(testChannelNumber, testChannelWriteAPIKey)); + } +#endif // Mega and MKR1000 only tests + +void setup() +{ + Serial.begin(9600); + while(!Serial); // for the Arduino Leonardo/Micro only + Serial.println("Starting test..."); + #ifdef ARDUINO_AVR_YUN + Bridge.begin(); + #else + #if defined(USE_WIFI101_SHIELD) || defined(ARDUINO_SAMD_MKR1000) + WiFi.begin(ssid, pass); + #else + Ethernet.begin(mac); + #endif + #endif + ThingSpeak.begin(client); +} + +void loop() +{ + Test::run(); +} diff --git a/extras/test/testWriteField/testWriteField.ino b/extras/test/testWriteField/testWriteField.ino index b5d5ce5..218f584 100644 --- a/extras/test/testWriteField/testWriteField.ino +++ b/extras/test/testWriteField/testWriteField.ino @@ -27,7 +27,6 @@ #endif #include -#include #if defined(ARDUINO_AVR_YUN) #include "YunClient.h" @@ -50,167 +49,222 @@ #endif #endif -unsigned long testChannelNumber = 209617; -const char * testChannelWriteAPIKey = "514SX5OBP2OFEPL2"; - -#define WRITE_DELAY_FOR_THINGSPEAK 15000 - +#include // always include thingspeak header file after other header files and custom macros + +unsigned long testChannelNumber = 1070863; +const char * testChannelWriteAPIKey = "UI7FSU4O8ZJ5BM8O"; + +#define WRITE_DELAY_FOR_THINGSPEAK 15000 // Data write limit for a free user (15 sec). + +// Field number macros +#define FIELD0 0 +#define FIELD1 1 +#define FIELD2 2 +#define FIELD3 3 +#define FIELD4 4 +#define FIELD5 5 +#define FIELD6 6 +#define FIELD7 7 +#define FIELD8 8 +#define FIELD9 9 + +/* This test case checks the following: + - basic value write + - rate limit error + - invalid field number + - invalid channel number + - invalid write API key + - NULL value +*/ test(writeFieldCase) { + float val = 1.0; + // Always wait to ensure that rate limit isn't hit delay(WRITE_DELAY_FOR_THINGSPEAK); // Test basic value write - assertEqual(OK_SUCCESS, ThingSpeak.writeField(testChannelNumber, 1, (float)1.0, testChannelWriteAPIKey)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.writeField(testChannelNumber, FIELD1, val, testChannelWriteAPIKey)); // Test write when not enough time has elapsed - assertEqual(ERR_NOT_INSERTED, ThingSpeak.writeField(testChannelNumber, 1, (float)1.0, testChannelWriteAPIKey)); - - // Allow enough time to pass to make sure that it would work - delay(WRITE_DELAY_FOR_THINGSPEAK); + // This test will work correctly after the fix by Afan is in production ThingSpeak + //assertEqual(TS_ERR_NOT_INSERTED, ThingSpeak.writeField(testChannelNumber, FIELD1, val, testChannelWriteAPIKey)); // Test write to field out of range - assertEqual(ERR_INVALID_FIELD_NUM, ThingSpeak.writeField(testChannelNumber, 0, (float)1.0, testChannelWriteAPIKey)); - assertEqual(ERR_INVALID_FIELD_NUM, ThingSpeak.writeField(testChannelNumber, 9, (float)1.0, testChannelWriteAPIKey)); + delay(WRITE_DELAY_FOR_THINGSPEAK); + assertEqual(TS_ERR_INVALID_FIELD_NUM, ThingSpeak.writeField(testChannelNumber, FIELD0, val, testChannelWriteAPIKey)); + assertEqual(TS_ERR_INVALID_FIELD_NUM, ThingSpeak.writeField(testChannelNumber, FIELD9, val, testChannelWriteAPIKey)); // Test write to invalid channel # // ThingSpeak accepts this, since it only uses the API key to write. The Channel number is ignored. - assertEqual(OK_SUCCESS, ThingSpeak.writeField(0, 1, (float)1.0, testChannelWriteAPIKey)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.writeField(0, FIELD1, val, testChannelWriteAPIKey)); delay(WRITE_DELAY_FOR_THINGSPEAK); - assertEqual(OK_SUCCESS, ThingSpeak.writeField(4294967295L, 1, (float)1.0, testChannelWriteAPIKey)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.writeField(4294967295L, FIELD1, val, testChannelWriteAPIKey)); // Test write with invalid API key - // * Using the wrong API key causes a connection failure on the next attempt to connect to ThingSpeak - // * The cause is unknown, disable this test for now - //delay(WRITE_DELAY_FOR_THINGSPEAK); - //assertEqual(ERR_BADAPIKEY, ThingSpeak.writeField(testChannelNumber, 1, (float)1.0, "AFAKEAPIKEYFAKEX")); + delay(WRITE_DELAY_FOR_THINGSPEAK); + assertEqual(TS_ERR_BADAPIKEY, ThingSpeak.writeField(testChannelNumber, FIELD1, val, "AFAKEAPIKEYFAKEX")); + + // Test NULL value + delay(WRITE_DELAY_FOR_THINGSPEAK); + assertEqual(TS_OK_SUCCESS, ThingSpeak.writeField(testChannelNumber, FIELD1, NULL, testChannelWriteAPIKey)); } +/* This test case checks the following: + - right float value + - max/min values of float + - high precision values of float + - NaN and Inf values + - out of range values of float +*/ test(writeFieldFloatCase) { + float val = 1.0; + // Always wait to ensure that rate limit isn't hit delay(WRITE_DELAY_FOR_THINGSPEAK); // Test float write - assertEqual(OK_SUCCESS, ThingSpeak.writeField(testChannelNumber, 1, (float)1.0, testChannelWriteAPIKey)); + assertEqual(TS_OK_SUCCESS, ThingSpeak.writeField(testChannelNumber, FIELD1, val, testChannelWriteAPIKey)); - // Test max range values + // Test max/min range values delay(WRITE_DELAY_FOR_THINGSPEAK); - assertEqual(OK_SUCCESS, ThingSpeak.writeField(testChannelNumber, 1, (float)-999999000000, testChannelWriteAPIKey)); + val = -999999000000; + assertEqual(TS_OK_SUCCESS, ThingSpeak.writeField(testChannelNumber, FIELD1, val, testChannelWriteAPIKey)); delay(WRITE_DELAY_FOR_THINGSPEAK); - assertEqual(OK_SUCCESS, ThingSpeak.writeField(testChannelNumber, 1, (float)999999000000, testChannelWriteAPIKey)); + val = 999999000000; + assertEqual(TS_OK_SUCCESS, ThingSpeak.writeField(testChannelNumber, FIELD1, val, testChannelWriteAPIKey)); // Test high precision values delay(WRITE_DELAY_FOR_THINGSPEAK); - assertEqual(OK_SUCCESS, ThingSpeak.writeField(testChannelNumber, 1, (float)3.14159, testChannelWriteAPIKey)); + val = -3.14159; + assertEqual(TS_OK_SUCCESS, ThingSpeak.writeField(testChannelNumber, FIELD1, val, testChannelWriteAPIKey)); delay(WRITE_DELAY_FOR_THINGSPEAK); - assertEqual(OK_SUCCESS, ThingSpeak.writeField(testChannelNumber, 1, (float)-3.14159, testChannelWriteAPIKey)); + val = 3.14159; + assertEqual(TS_OK_SUCCESS, ThingSpeak.writeField(testChannelNumber, FIELD1, val, testChannelWriteAPIKey)); // Test passing NaN and Inf delay(WRITE_DELAY_FOR_THINGSPEAK); - assertEqual(OK_SUCCESS, ThingSpeak.writeField(testChannelNumber, 1, (float)NAN, testChannelWriteAPIKey)); + val = NAN; + assertEqual(TS_OK_SUCCESS, ThingSpeak.writeField(testChannelNumber, FIELD1, val, testChannelWriteAPIKey)); delay(WRITE_DELAY_FOR_THINGSPEAK); - assertEqual(OK_SUCCESS, ThingSpeak.writeField(testChannelNumber, 1, (float)INFINITY, testChannelWriteAPIKey)); + val = -INFINITY; + assertEqual(TS_OK_SUCCESS, ThingSpeak.writeField(testChannelNumber, FIELD1, val, testChannelWriteAPIKey)); delay(WRITE_DELAY_FOR_THINGSPEAK); - assertEqual(OK_SUCCESS, ThingSpeak.writeField(testChannelNumber, 1, (float)-INFINITY, testChannelWriteAPIKey)); + val = INFINITY; + assertEqual(TS_OK_SUCCESS, ThingSpeak.writeField(testChannelNumber, FIELD1, val, testChannelWriteAPIKey)); // Test out of range values - assertEqual(ERR_OUT_OF_RANGE, ThingSpeak.writeField(testChannelNumber, 1, (float)-1000000000000.0, testChannelWriteAPIKey)); - assertEqual(ERR_OUT_OF_RANGE, ThingSpeak.writeField(testChannelNumber, 1, (float)1000000000000.0, testChannelWriteAPIKey)); -} - -#if defined(ARDUINO_AVR_MEGA2560) || defined(ARDUINO_SAMD_MKR1000) // Only the mega and mkr1000 has enough memory for all these tests -test(writeFieldIntCase) -{ - // Always wait to ensure that rate limit isn't hit delay(WRITE_DELAY_FOR_THINGSPEAK); - - // Test int write - assertEqual(OK_SUCCESS, ThingSpeak.writeField(testChannelNumber, 1, (int)1, testChannelWriteAPIKey)); - - // Test max range values - delay(WRITE_DELAY_FOR_THINGSPEAK); - assertEqual(OK_SUCCESS, ThingSpeak.writeField(testChannelNumber, 1, (int)-32768, testChannelWriteAPIKey)); - delay(WRITE_DELAY_FOR_THINGSPEAK); - assertEqual(OK_SUCCESS, ThingSpeak.writeField(testChannelNumber, 1, (int)32767, testChannelWriteAPIKey)); -} - -test(writeFieldLongCase) -{ - // Always wait to ensure that rate limit isn't hit - delay(WRITE_DELAY_FOR_THINGSPEAK); - - // Test long write - assertEqual(OK_SUCCESS, ThingSpeak.writeField(testChannelNumber, 1, 1000000L, testChannelWriteAPIKey)); - - // Test max range values - delay(WRITE_DELAY_FOR_THINGSPEAK); - assertEqual(OK_SUCCESS, ThingSpeak.writeField(testChannelNumber, 1, (long)-2147483648L, testChannelWriteAPIKey)); - delay(WRITE_DELAY_FOR_THINGSPEAK); - assertEqual(OK_SUCCESS, ThingSpeak.writeField(testChannelNumber, 1, (long)2147483647L, testChannelWriteAPIKey)); + val = -1000000000000.0; + assertEqual(TS_ERR_OUT_OF_RANGE, ThingSpeak.writeField(testChannelNumber, FIELD1, val, testChannelWriteAPIKey)); + val = 1000000000000.0; + assertEqual(TS_ERR_OUT_OF_RANGE, ThingSpeak.writeField(testChannelNumber, FIELD1, val, testChannelWriteAPIKey)); } -test(writeFieldCharStarCase) -{ - // Always wait to ensure that rate limit isn't hit - delay(WRITE_DELAY_FOR_THINGSPEAK); - - // Test char * write - assertEqual(OK_SUCCESS, ThingSpeak.writeField(testChannelNumber, 1, "The Rain in Spain", testChannelWriteAPIKey)); - - // Test empty string - delay(WRITE_DELAY_FOR_THINGSPEAK); - assertEqual(OK_SUCCESS, ThingSpeak.writeField(testChannelNumber, 1, "", testChannelWriteAPIKey)); - - char longString[300]; - - // Test max string - memset(longString, '0',255); - longString[255] = 0; - delay(WRITE_DELAY_FOR_THINGSPEAK); - assertEqual(OK_SUCCESS, ThingSpeak.writeField(testChannelNumber, 1, longString, testChannelWriteAPIKey)); - - // Test long string - memset(longString, '0',sizeof(longString)/sizeof(longString[0]) - 1); - longString[sizeof(longString)] = 0; - delay(WRITE_DELAY_FOR_THINGSPEAK); - assertEqual(ERR_OUT_OF_RANGE, ThingSpeak.writeField(testChannelNumber, 1, longString, testChannelWriteAPIKey)); -} - -test(writeFieldStringCase) -{ - // Always wait to ensure that rate limit isn't hit - delay(WRITE_DELAY_FOR_THINGSPEAK); - - // Test String write - assertEqual(OK_SUCCESS, ThingSpeak.writeField(testChannelNumber, 1, String("The Rain in Spain"), testChannelWriteAPIKey)); - - // Test empty string - delay(WRITE_DELAY_FOR_THINGSPEAK); - assertEqual(OK_SUCCESS, ThingSpeak.writeField(testChannelNumber, 1, String(), testChannelWriteAPIKey)); - - unsigned int numChar = 300; - String longString; - longString.reserve(numChar); +#if defined(ARDUINO_AVR_MEGA2560) || defined(ARDUINO_SAMD_MKR1000) // Only the mega and mkr1000 has enough memory for all these tests - // Test max string - for(unsigned int i = 0; i < 255; i++) + /* This test case checks the following: + - right int value + - max/min values of int + */ + test(writeFieldIntCase) { - longString += '0'; + int val = 1; + // Always wait to ensure that rate limit isn't hit + delay(WRITE_DELAY_FOR_THINGSPEAK); + + // Test int write + assertEqual(TS_OK_SUCCESS, ThingSpeak.writeField(testChannelNumber, FIELD1, val, testChannelWriteAPIKey)); + + // Test max/min range values + delay(WRITE_DELAY_FOR_THINGSPEAK); + val = -32768; + assertEqual(TS_OK_SUCCESS, ThingSpeak.writeField(testChannelNumber, FIELD1, val, testChannelWriteAPIKey)); + delay(WRITE_DELAY_FOR_THINGSPEAK); + val = 32767; + assertEqual(TS_OK_SUCCESS, ThingSpeak.writeField(testChannelNumber, FIELD1, val, testChannelWriteAPIKey)); + } - delay(WRITE_DELAY_FOR_THINGSPEAK); - assertEqual(OK_SUCCESS, ThingSpeak.writeField(testChannelNumber, 1, longString, testChannelWriteAPIKey)); - - // Test long string - longString.reserve(numChar); - for(unsigned int i = 0; i < numChar; i++) + + /* This test case checks the following: + - right long value + - max/min values of long + */ + test(writeFieldLongCase) { + long val = 1000000L; + + // Always wait to ensure that rate limit isn't hit + delay(WRITE_DELAY_FOR_THINGSPEAK); + + // Test long write + assertEqual(TS_OK_SUCCESS, ThingSpeak.writeField(testChannelNumber, FIELD1, val, testChannelWriteAPIKey)); + + // Test max/min range values + delay(WRITE_DELAY_FOR_THINGSPEAK); + val = -2147483648L; + assertEqual(TS_OK_SUCCESS, ThingSpeak.writeField(testChannelNumber, FIELD1, val, testChannelWriteAPIKey)); + delay(WRITE_DELAY_FOR_THINGSPEAK); + val = 2147483647L; + assertEqual(TS_OK_SUCCESS, ThingSpeak.writeField(testChannelNumber, FIELD1, val, testChannelWriteAPIKey)); + } + + /* This test case checks the following: + - right const char * value + - empty const char * value + - right String value (using String class) + - empty String value (using String class) + - field character limits via String (positive and negative cases) + */ + test(writeFieldStringCase) + { + const char * constCharVal = "The Rain in Spain"; + // Always wait to ensure that rate limit isn't hit + delay(WRITE_DELAY_FOR_THINGSPEAK); + + // Test const char * string write + assertEqual(TS_OK_SUCCESS, ThingSpeak.writeField(testChannelNumber, FIELD1, constCharVal, testChannelWriteAPIKey)); + + // Test empty const char * string write + delay(WRITE_DELAY_FOR_THINGSPEAK); + constCharVal = ""; + assertEqual(TS_OK_SUCCESS, ThingSpeak.writeField(testChannelNumber, FIELD1, constCharVal, testChannelWriteAPIKey)); + + String stringVal = "The Rain in Spain"; + + // Test String class instance write + delay(WRITE_DELAY_FOR_THINGSPEAK); + assertEqual(TS_OK_SUCCESS, ThingSpeak.writeField(testChannelNumber, FIELD1, stringVal, testChannelWriteAPIKey)); + + // Test empty String class instance write + delay(WRITE_DELAY_FOR_THINGSPEAK); + stringVal = ""; + assertEqual(TS_OK_SUCCESS, ThingSpeak.writeField(testChannelNumber, FIELD1, stringVal, testChannelWriteAPIKey)); + + unsigned int numChar = 256; + String longString; + longString.reserve(numChar); + + // Test field character limits via string + for(unsigned int i = 0; i < 255; i++) + { + longString += '0'; + } + + // longString will have 256 '0' characters, since the number of characters ThingSpeak field can store is limited to 256 characters. + + delay(WRITE_DELAY_FOR_THINGSPEAK); + assertEqual(TS_OK_SUCCESS, ThingSpeak.writeField(testChannelNumber, 1, longString, testChannelWriteAPIKey)); + longString += '0'; + + // longString will now have 257 '0' characters. Out of range error. + + delay(WRITE_DELAY_FOR_THINGSPEAK); + assertEqual(TS_ERR_OUT_OF_RANGE, ThingSpeak.writeField(testChannelNumber, 1, longString, testChannelWriteAPIKey)); } - delay(WRITE_DELAY_FOR_THINGSPEAK); - assertEqual(ERR_OUT_OF_RANGE, ThingSpeak.writeField(testChannelNumber, 1, longString, testChannelWriteAPIKey)); -} #endif // Mega and MKR1000 only tests void setup() @@ -234,4 +288,3 @@ void loop() { Test::run(); } - diff --git a/library.properties b/library.properties index 8a8d0c3..fd439ed 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ThingSpeak -version=1.5.0 +version=2.0.0 author=MathWorks maintainer=MathWorks sentence=ThingSpeak Communication Library for Arduino, ESP8266 & EPS32 diff --git a/src/ThingSpeak.h b/src/ThingSpeak.h index 9c744c6..81cb309 100644 --- a/src/ThingSpeak.h +++ b/src/ThingSpeak.h @@ -7,7 +7,7 @@ ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize and analyze live data streams in the cloud. - Copyright 2018, The MathWorks, Inc. + Copyright 2020, The MathWorks, Inc. See the accompaning licence file for licensing information. */ @@ -16,1667 +16,1711 @@ // #define PRINT_HTTP #ifndef ThingSpeak_h -#define ThingSpeak_h + #define ThingSpeak_h -#define TS_VER "1.5.0" + #define TS_VER "2.0.0" -#include "Arduino.h" -#include + #include "Arduino.h" + #include -#define THINGSPEAK_URL "api.thingspeak.com" -#define THINGSPEAK_PORT_NUMBER 80 + #define THINGSPEAK_URL "api.thingspeak.com" + #define THINGSPEAK_PORT_NUMBER 80 + #define THINGSPEAK_HTTPS_PORT_NUMBER 443 -#ifdef ARDUINO_ARCH_AVR - #ifdef ARDUINO_AVR_YUN - #define TS_USER_AGENT "tslib-arduino/" TS_VER " (arduino yun)" + #ifdef ARDUINO_ARCH_AVR + #ifdef ARDUINO_AVR_YUN + #define TS_USER_AGENT "tslib-arduino/" TS_VER " (arduino yun)" + #else + #define TS_USER_AGENT "tslib-arduino/" TS_VER " (arduino uno or mega)" + #endif + #elif defined(ARDUINO_ARCH_ESP8266) + #define TS_USER_AGENT "tslib-arduino/" TS_VER " (ESP8266)" + #elif defined(ARDUINO_SAMD_MKR1000) + #define TS_USER_AGENT "tslib-arduino/" TS_VER " (arduino mkr1000)" + #elif defined(ARDUINO_SAM_DUE) + #define TS_USER_AGENT "tslib-arduino/" TS_VER " (arduino due)" + #elif defined(ARDUINO_ARCH_SAMD) + #define TS_USER_AGENT "tslib-arduino/" TS_VER " (arduino samd)" + #elif defined(ARDUINO_ARCH_SAM) + #define TS_USER_AGENT "tslib-arduino/" TS_VER " (arduino sam)" + #elif defined(ARDUINO_ARCH_SAMD_BETA) + #define TS_USER_AGENT "tslib-arduino/" TS_VER " (arduino samd_beta )" + #elif defined(ARDUINO_ARCH_ESP32) + #define TS_USER_AGENT "tslib-arduino/" TS_VER " (ESP32)" + #elif defined(ARDUINO_ARCH_SAMD_BETA) + #define TS_USER_AGENT "tslib-arduino/" TS_VER " (arduino vidor)" #else - #define TS_USER_AGENT "tslib-arduino/" TS_VER " (arduino uno or mega)" + #define TS_USER_AGENT "tslib-arduino/" TS_VER " (unknown)" #endif -#elif defined(ARDUINO_ARCH_ESP8266) - #define TS_USER_AGENT "tslib-arduino/" TS_VER " (ESP8266)" -#elif defined(ARDUINO_SAMD_MKR1000) - #define TS_USER_AGENT "tslib-arduino/" TS_VER " (arduino mkr1000)" -#elif defined(ARDUINO_SAM_DUE) - #define TS_USER_AGENT "tslib-arduino/" TS_VER " (arduino due)" -#elif defined(ARDUINO_ARCH_SAMD) - #define TS_USER_AGENT "tslib-arduino/" TS_VER " (arduino samd)" -#elif defined(ARDUINO_ARCH_SAM) - #define TS_USER_AGENT "tslib-arduino/" TS_VER " (arduino sam)" -#elif defined(ARDUINO_ARCH_SAMD_BETA) - #define TS_USER_AGENT "tslib-arduino/" TS_VER " (arduino samd_beta )" -#elif defined(ARDUINO_ARCH_ESP32) - #define TS_USER_AGENT "tslib-arduino/" TS_VER " (ESP32)" -#elif defined(ARDUINO_ARCH_SAMD_BETA) - #define TS_USER_AGENT "tslib-arduino/" TS_VER " (arduino vidor)" -#else - #define TS_USER_AGENT "tslib-arduino/" TS_VER " (unknown)" -#endif - -#define FIELDNUM_MIN 1 -#define FIELDNUM_MAX 8 -#define FIELDLENGTH_MAX 255 // Max length for a field in ThingSpeak is 255 bytes (UTF-8) - -#define TIMEOUT_MS_SERVERRESPONSE 5000 // Wait up to five seconds for server to respond - -#define OK_SUCCESS 200 // OK / Success -#define ERR_BADAPIKEY 400 // Incorrect API key (or invalid ThingSpeak server address) -#define ERR_BADURL 404 // Incorrect API key (or invalid ThingSpeak server address) -#define ERR_OUT_OF_RANGE -101 // Value is out of range or string is too long (> 255 bytes) -#define ERR_INVALID_FIELD_NUM -201 // Invalid field number specified -#define ERR_SETFIELD_NOT_CALLED -210 // setField() was not called before writeFields() -#define ERR_CONNECT_FAILED -301 // Failed to connect to ThingSpeak -#define ERR_UNEXPECTED_FAIL -302 // Unexpected failure during write to ThingSpeak -#define ERR_BAD_RESPONSE -303 // Unable to parse response -#define ERR_TIMEOUT -304 // Timeout waiting for server to respond -#define ERR_NOT_INSERTED -401 // Point was not inserted (most probable cause is the rate limit of once every 15 seconds) - -// Enables an Arduino, ESP8266, ESP32 or other compatible hardware to write or read data to or from ThingSpeak, an open data platform for the Internet of Things with MATLAB analytics and visualization. -class ThingSpeakClass -{ - public: - ThingSpeakClass() - { - resetWriteFields(); - this->lastReadStatus = OK_SUCCESS; - }; - - - /* - Function: begin - - Summary: - Initializes the ThingSpeak library and network settings using the ThingSpeak.com service. - - Parameters: - client - EthernetClient, YunClient, TCPClient, or WiFiClient created earlier in the sketch - - Returns: - Always returns true - - Notes: - This does not validate the information passed in, or generate any calls to ThingSpeak. - - */ - bool begin(Client & client) - { - - #ifdef PRINT_DEBUG_MESSAGES - Serial.println("ts::tsBegin"); - #endif - this->setClient(&client); - this->setPort(THINGSPEAK_PORT_NUMBER); - - resetWriteFields(); - this->lastReadStatus = OK_SUCCESS; - - return true; - }; - - /* - Function: begin - - Summary: - Initializes the ThingSpeak library and network settings using the ThingSpeak.com service. - - Parameters: - client - EthernetClient, YunClient, TCPClient, or WiFiClient created earlier in the sketch - port - TCP port of server - - Returns: - Always returns true - - Notes: - This does not validate the information passed in, or generate any calls to ThingSpeak. - - */ - bool begin(Client & client, unsigned int port) - { - #ifdef PRINT_DEBUG_MESSAGES - Serial.print("ts::tsBegin"); - #endif - this->setClient(&client); - this->setPort(port); - resetWriteFields(); - this->lastReadStatus = OK_SUCCESS; - return true; - }; - - - /* - Function: writeField - - Summary: - Write an integer value to a single field in a ThingSpeak channel - - Parameters: - channelNumber - Channel number - field - Field number (1-8) within the channel to write to. - value - Integer value (from -32,768 to 32,767) to write. - writeAPIKey - Write API key associated with the channel. *If you share code with others, do _not_ share this key* - - Returns: - HTTP status code of 200 if successful. - - Notes: - See getLastReadStatus() for other possible return values. - */ - int writeField(unsigned long channelNumber, unsigned int field, int value, const char * writeAPIKey) - { - char valueString[10]; // int range is -32768 to 32768, so 7 bytes including terminator, plus a little extra - itoa(value, valueString, 10); - return writeField(channelNumber, field, valueString, writeAPIKey); - }; - - - /* - Function: writeField - - Summary: - Write a long value to a single field in a ThingSpeak channel - - Parameters: - channelNumber - Channel number - field - Field number (1-8) within the channel to write to. - value - Long value (from -2,147,483,648 to 2,147,483,647) to write. - writeAPIKey - Write API key associated with the channel. *If you share code with others, do _not_ share this key* - - Returns: - HTTP status code of 200 if successful. - - Notes: - See getLastReadStatus() for other possible return values. - */ - int writeField(unsigned long channelNumber, unsigned int field, long value, const char * writeAPIKey) - { - char valueString[15]; // long range is -2147483648 to 2147483647, so 12 bytes including terminator - ltoa(value, valueString, 10); - return writeField(channelNumber, field, valueString, writeAPIKey); - }; - - /* - Function: writeField - - Summary: - Write a floating point value to a single field in a ThingSpeak channel - - Parameters: - channelNumber - Channel number - field - Field number (1-8) within the channel to write to. - value - Floating point value (from -999999000000 to 999999000000) to write. If you need more accuracy, or a wider range, you should format the number using dtostrf and writeField(). - writeAPIKey - Write API key associated with the channel. *If you share code with others, do _not_ share this key* - - Returns: - HTTP status code of 200 if successful. - - Notes: - See getLastReadStatus() for other possible return values. - */ - int writeField(unsigned long channelNumber, unsigned int field, float value, const char * writeAPIKey) - { - #ifdef PRINT_DEBUG_MESSAGES - Serial.print("ts::writeField (channelNumber: "); Serial.print(channelNumber); Serial.print(" writeAPIKey: "); Serial.print(writeAPIKey); Serial.print(" field: "); Serial.print(field); Serial.print(" value: "); Serial.print(value,5); Serial.println(")"); - #endif - char valueString[20]; // range is -999999000000.00000 to 999999000000.00000, so 19 + 1 for the terminator - int status = convertFloatToChar(value, valueString); - if(status != OK_SUCCESS) return status; - - return writeField(channelNumber, field, valueString, writeAPIKey); - }; - - - /* - Function: writeField - - Summary: - Write a string to a single field in a ThingSpeak channel - - Parameters: - channelNumber - Channel number - field - Field number (1-8) within the channel to write to. - value - String to write (UTF8 string). ThingSpeak limits this field to 255 bytes. - writeAPIKey - Write API key associated with the channel. *If you share code with others, do _not_ share this key* - - Returns: - HTTP status code of 200 if successful. - - Notes: - See getLastReadStatus() for other possible return values. - */ - int writeField(unsigned long channelNumber, unsigned int field, const char * value, const char * writeAPIKey) - { - return writeField(channelNumber, field, String(value), writeAPIKey); - }; - - /* - Function: writeField - - Summary: - Write a string to a single field in a ThingSpeak channel - - Parameters: - channelNumber - Channel number - field - Field number (1-8) within the channel to write to. - value - String to write (UTF8 string). ThingSpeak limits this field to 255 bytes. - writeAPIKey - Write API key associated with the channel. *If you share code with others, do _not_ share this key* - - Returns: - HTTP status code of 200 if successful. - - Notes: - See getLastReadStatus() for other possible return values. - */ - int writeField(unsigned long channelNumber, unsigned int field, String value, const char * writeAPIKey) - { - // Invalid field number specified - if(field < FIELDNUM_MIN || field > FIELDNUM_MAX) return ERR_INVALID_FIELD_NUM; - // Max # bytes for ThingSpeak field is 255 - if(value.length() > FIELDLENGTH_MAX) return ERR_OUT_OF_RANGE; - - #ifdef PRINT_DEBUG_MESSAGES - Serial.print("ts::writeField (channelNumber: "); Serial.print(channelNumber); Serial.print(" writeAPIKey: "); Serial.print(writeAPIKey); Serial.print(" field: "); Serial.print(field); Serial.print(" value: \""); Serial.print(value); Serial.println("\")"); - #endif - String postMessage = String("field"); - postMessage.concat(field); - postMessage.concat("="); - postMessage.concat(value); - return writeRaw(channelNumber, postMessage, writeAPIKey); - }; - - - /* - Function: setField - - Summary: - Set the value of a single field that will be part of a multi-field update. - - Parameters: - field - Field number (1-8) within the channel to set. - value - Integer value (from -32,768 to 32,767) to set. - - Returns: - Code of 200 if successful. - Code of -101 if value is out of range or string is too long (> 255 bytes) - - */ - int setField(unsigned int field, int value) - { - - char valueString[10]; // int range is -32768 to 32768, so 7 bytes including terminator - itoa(value, valueString, 10); - - return setField(field, valueString); - - }; - - /* - Function: setField - - Summary: - Set the value of a single field that will be part of a multi-field update. - - Parameters: - field - Field number (1-8) within the channel to set. - value - Long value (from -2,147,483,648 to 2,147,483,647) to write. - - Returns: - Code of 200 if successful. - Code of -101 if value is out of range or string is too long (> 255 bytes) - - */ - int setField(unsigned int field, long value) - { - char valueString[15]; // long range is -2147483648 to 2147483647, so 12 bytes including terminator - ltoa(value, valueString, 10); - return setField(field, valueString); - }; - - /* - Function: setField - - Summary: - Set the value of a single field that will be part of a multi-field update. - - Parameters: - field - Field number (1-8) within the channel to set. - value - Floating point value (from -999999000000 to 999999000000) to write. If you need more accuracy, or a wider range, you should format the number yourself (using dtostrf) and setField() using the resulting string. - - Returns: - Code of 200 if successful. - Code of -101 if value is out of range or string is too long (> 255 bytes) - - */ - int setField(unsigned int field, float value) - { - char valueString[20]; // range is -999999000000.00000 to 999999000000.00000, so 19 + 1 for the terminator - int status = convertFloatToChar(value, valueString); - if(status != OK_SUCCESS) return status; - - return setField(field, valueString); - }; - - - /* - Function: setField - - Summary: - Set the value of a single field that will be part of a multi-field update. - - Parameters: - field - Field number (1-8) within the channel to set. - value - String to write (UTF8). ThingSpeak limits this to 255 bytes. - - Returns: - Code of 200 if successful. - Code 0f -101 if value is out of range or string is too long (> 255 bytes) - - */ - int setField(unsigned int field, const char * value) - { - return setField(field, String(value)); - }; - - - /* - Function: setField - - Summary: - Set the value of a single field that will be part of a multi-field update. - - Parameters: - field - Field number (1-8) within the channel to set. - value - String to write (UTF8). ThingSpeak limits this to 255 bytes. - - Returns: - Code of 200 if successful. - Code of -101 if value is out of range or string is too long (> 255 bytes) - - */ - int setField(unsigned int field, String value) - { - #ifdef PRINT_DEBUG_MESSAGES - Serial.print("ts::setField (field: "); Serial.print(field); Serial.print(" value: \""); Serial.print(value); Serial.println("\")"); - #endif - if(field < FIELDNUM_MIN || field > FIELDNUM_MAX) return ERR_INVALID_FIELD_NUM; - // Max # bytes for ThingSpeak field is 255 (UTF-8) - if(value.length() > FIELDLENGTH_MAX) return ERR_OUT_OF_RANGE; - this->nextWriteField[field - 1] = value; - return OK_SUCCESS; - }; - - - /* - Function: setLatitude - - Summary: - Set the latitude of a multi-field update. - - Parameters: - latitude - Latitude of the measurement as a floating point value (degrees N, use negative values for degrees S) - - Returns: - Always return 200 - - Notes: - To record latitude, longitude and elevation of a write, call setField() for each of the fields you want to write. Then setLatitude(), setLongitude(), setElevation() and then call writeFields() - - */ - int setLatitude(float latitude) - { - #ifdef PRINT_DEBUG_MESSAGES - Serial.print("ts::setLatitude(latitude: "); Serial.print(latitude,3); Serial.println("\")"); - #endif - this->nextWriteLatitude = latitude; - return OK_SUCCESS; - }; - - /* - Function: setLongitude - - Summary: - Set the longitude of a multi-field update. - - Parameters: - longitude - Longitude of the measurement as a floating point value (degrees E, use negative values for degrees W) - - Returns: - Always return 200 - - Notes: - To record latitude, longitude and elevation of a write, call setField() for each of the fields you want to write. Then setLatitude(), setLongitude(), setElevation() and then call writeFields() - - */ - int setLongitude(float longitude) - { - #ifdef PRINT_DEBUG_MESSAGES - Serial.print("ts::setLongitude(longitude: "); Serial.print(longitude,3); Serial.println("\")"); - #endif - this->nextWriteLongitude = longitude; - return OK_SUCCESS; - }; - - - /* - Function: setElevation - - Summary: - Set the elevation of a multi-field update. - - Parameters: - elevation - Elevation of the measurement as a floating point value (meters above sea level) - - Returns: - Always return 200 - - Notes: - To record latitude, longitude and elevation of a write, call setField() for each of the fields you want to write. Then setLatitude(), setLongitude(), setElevation() and then call writeFields() - - */ - int setElevation(float elevation) - { - #ifdef PRINT_DEBUG_MESSAGES - Serial.print("ts::setElevation(elevation: "); Serial.print(elevation,3); Serial.println("\")"); - #endif - this->nextWriteElevation = elevation; - return OK_SUCCESS; - }; - - - /* - Function: setStatus - - Summary: - Set the status field of a multi-field update. - - Parameters: - status - String to write (UTF8). ThingSpeak limits this to 255 bytes. - - Returns: - Code of 200 if successful. - Code of -101 if string is too long (> 255 bytes) - - Notes: - To record a status message on a write, call setStatus() then call writeFields(). - Use status to provide additonal details when writing a channel update. - Additonally, status can be used by the ThingTweet App to send a message to Twitter. - - */ - int setStatus(const char * status) - { - return setStatus(String(status)); - }; - - - /* - Function: setStatus - - Summary: - Set the status field of a multi-field update. - - Parameters: - status - String to write (UTF8). ThingSpeak limits this to 255 bytes. - - Returns: - Code of 200 if successful. - Code of -101 if string is too long (> 255 bytes) - - Notes: - To record a status message on a write, call setStatus() then call writeFields(). - Use status to provide additonal details when writing a channel update. - Additonally, status can be used by the ThingTweet App to send a message to Twitter. - - */ - int setStatus(String status) - { - #ifdef PRINT_DEBUG_MESSAGES - Serial.print("ts::setStatus(status: "); Serial.print(status); Serial.println("\")"); - #endif - // Max # bytes for ThingSpeak field is 255 (UTF-8) - if(status.length() > FIELDLENGTH_MAX) return ERR_OUT_OF_RANGE; - this->nextWriteStatus = status; - return OK_SUCCESS; - }; - - - /* - Function: setTwitterTweet - - Summary: - Set the Twitter account and message to use for an update to be tweeted. - - Parameters: - twitter - Twitter account name as a String. - tweet - Twitter message as a String (UTF-8) limited to 140 character. - - Returns: - Code of 200 if successful. - Code of -101 if string is too long (> 255 bytes) - - Notes: - To send a message to twitter call setTwitterTweet() then call writeFields(). - Prior to using this feature, a twitter account must be linked to your ThingSpeak account. Do this by logging into ThingSpeak and going to Apps, then ThingTweet and clicking Link Twitter Account. - */ - int setTwitterTweet(const char * twitter, const char * tweet) - { - return setTwitterTweet(String(twitter), String(tweet)); - }; - - /* - Function: setTwitterTweet - - Summary: - Set the Twitter account and message to use for an update to be tweeted. - - Parameters: - twitter - Twitter account name as a String. - tweet - Twitter message as a String (UTF-8) limited to 140 character. - - Returns: - Code of 200 if successful. - Code of -101 if string is too long (> 255 bytes) - - Notes: - To send a message to twitter call setTwitterTweet() then call writeFields(). - Prior to using this feature, a twitter account must be linked to your ThingSpeak account. Do this by logging into ThingSpeak and going to Apps, then ThingTweet and clicking Link Twitter Account. - */ - int setTwitterTweet(String twitter, const char * tweet) - { - return setTwitterTweet(twitter, String(tweet)); - }; - - /* - Function: setTwitterTweet - - Summary: - Set the Twitter account and message to use for an update to be tweeted. - - Parameters: - twitter - Twitter account name as a String. - tweet - Twitter message as a String (UTF-8) limited to 140 character. - - Returns: - Code of 200 if successful. - Code of -101 if string is too long (> 255 bytes) - - Notes: - To send a message to twitter call setTwitterTweet() then call writeFields(). - Prior to using this feature, a twitter account must be linked to your ThingSpeak account. Do this by logging into ThingSpeak and going to Apps, then ThingTweet and clicking Link Twitter Account. - */ - int setTwitterTweet(const char * twitter, String tweet) - { - return setTwitterTweet(String(twitter), tweet); - }; - - /* - Function: setTwitterTweet - - Summary: - Set the Twitter account and message to use for an update to be tweeted. - - Parameters: - twitter - Twitter account name as a String. - tweet - Twitter message as a String (UTF-8) limited to 140 character. - - Returns: - Code of 200 if successful. - Code of -101 if string is too long (> 255 bytes) - - Notes: - To send a message to twitter call setTwitterTweet() then call writeFields(). - Prior to using this feature, a twitter account must be linked to your ThingSpeak account. Do this by logging into ThingSpeak and going to Apps, then ThingTweet and clicking Link Twitter Account. - */ - int setTwitterTweet(String twitter, String tweet){ - #ifdef PRINT_DEBUG_MESSAGES - Serial.print("ts::setTwitterTweet(twitter: "); Serial.print(twitter); Serial.print(", tweet: "); Serial.print(tweet); Serial.println("\")"); - #endif - // Max # bytes for ThingSpeak field is 255 (UTF-8) - if((twitter.length() > FIELDLENGTH_MAX) || (tweet.length() > FIELDLENGTH_MAX)) return ERR_OUT_OF_RANGE; - - this->nextWriteTwitter = twitter; - this->nextWriteTweet = tweet; - - return OK_SUCCESS; - }; - - - /* - Function: setCreatedAt - - Summary: - Set the created-at date of a multi-field update. - - Parameters: - createdAt - Desired timestamp to be included with the channel update as a String. The timestamp string must be in the ISO 8601 format. Example "2017-01-12 13:22:54" - - Returns: - Code of 200 if successful. - Code of -101 if string is too long (> 255 bytes) - - Notes: - Timezones can be set using the timezone hour offset parameter. For example, a timestamp for Eastern Standard Time is: "2017-01-12 13:22:54-05". - If no timezone hour offset parameter is used, UTC time is assumed. - - */ - int setCreatedAt(const char * createdAt) - { - return setCreatedAt(String(createdAt)); - } - - - /* - Function: setCreatedAt - - Summary: - Set the created-at date of a multi-field update. - - Parameters: - createdAt - Desired timestamp to be included with the channel update as a String. The timestamp string must be in the ISO 8601 format. Example "2017-01-12 13:22:54" - - Returns: - Code of 200 if successful. - Code of -101 if string is too long (> 255 bytes) - - Notes: - Timezones can be set using the timezone hour offset parameter. For example, a timestamp for Eastern Standard Time is: "2017-01-12 13:22:54-05". - If no timezone hour offset parameter is used, UTC time is assumed. - - */ - int setCreatedAt(String createdAt) - { - #ifdef PRINT_DEBUG_MESSAGES - Serial.print("ts::setCreatedAt(createdAt: "); Serial.print(createdAt); Serial.println("\")"); - #endif - - // the ISO 8601 format is too complicated to check for valid timestamps here - // we'll need to reply on the api to tell us if there is a problem - // Max # bytes for ThingSpeak field is 255 (UTF-8) - if(createdAt.length() > FIELDLENGTH_MAX) return ERR_OUT_OF_RANGE; - this->nextWriteCreatedAt = createdAt; - - return OK_SUCCESS; - } - - - /* - Function: writeFields - - Summary: - Write a multi-field update. - - Parameters: - channelNumber - Channel number - writeAPIKey - Write API key associated with the channel. *If you share code with others, do _not_ share this key* - - Returns: - 200 - successful. - 404 - Incorrect API key (or invalid ThingSpeak server address) - -101 - Value is out of range or string is too long (> 255 characters) - -201 - Invalid field number specified - -210 - setField() was not called before writeFields() - -301 - Failed to connect to ThingSpeak - -302 - Unexpected failure during write to ThingSpeak - -303 - Unable to parse response - -304 - Timeout waiting for server to respond - -401 - Point was not inserted (most probable cause is the rate limit of once every 15 seconds) - - - Notes: - Call setField(), setLatitude(), setLongitude(), setElevation() and/or setStatus() and then call writeFields() - - */ - int writeFields(unsigned long channelNumber, const char * writeAPIKey) - { - if(!connectThingSpeak()){ - // Failed to connect to ThingSpeak - return ERR_CONNECT_FAILED; - } - - // Get the content length of the payload - int contentLen = getWriteFieldsContentLength(); - - if(contentLen == 0){ - // setField was not called before writeFields - return ERR_SETFIELD_NOT_CALLED; - } - - #ifdef PRINT_DEBUG_MESSAGES - Serial.print("ts::writeFields (channelNumber: "); Serial.print(channelNumber); Serial.print(" writeAPIKey: "); Serial.println(writeAPIKey); - #endif - - // Post data to thingspeak - if(!this->client->print("POST /update HTTP/1.1\r\n")) return abortWriteRaw(); - if(!writeHTTPHeader(writeAPIKey)) return abortWriteRaw(); - if(!this->client->print("Content-Type: application/x-www-form-urlencoded\r\n")) return abortWriteRaw(); - if(!this->client->print("Content-Length: ")) return abortWriteRaw(); - if(!this->client->print(contentLen)) return abortWriteRaw(); - if(!this->client->print("\r\n\r\n")) return abortWriteRaw(); - - bool fFirstItem = true; - for(size_t iField = 0; iField < FIELDNUM_MAX; iField++){ - if(this->nextWriteField[iField].length() > 0){ - if(!fFirstItem){ - if(!this->client->print("&")) return abortWriteRaw(); - } - if(!this->client->print("field")) return abortWriteRaw(); - if(!this->client->print(iField + 1)) return abortWriteRaw(); - if(!this->client->print("=")) return abortWriteRaw(); - if(!this->client->print(this->nextWriteField[iField])) return abortWriteRaw(); - fFirstItem = false; - } - } - - if(!isnan(this->nextWriteLatitude)){ - if(!fFirstItem){ - if(!this->client->print("&")) return abortWriteRaw(); - } - if(!this->client->print("lat=")) return abortWriteRaw(); - if(!this->client->print(this->nextWriteLatitude)) return abortWriteRaw(); - fFirstItem = false; - } - - if(!isnan(this->nextWriteLongitude)){ - if(!fFirstItem){ - if(!this->client->print("&")) return abortWriteRaw(); - } - if(!this->client->print("long=")) return abortWriteRaw(); - if(!this->client->print(this->nextWriteLongitude)) return abortWriteRaw(); - fFirstItem = false; - } - - - if(!isnan(this->nextWriteElevation)){ - if(!fFirstItem){ - if(!this->client->print("&")) return abortWriteRaw(); - } - if(!this->client->print("elevation=")) return abortWriteRaw(); - if(!this->client->print(this->nextWriteElevation)) return abortWriteRaw(); - fFirstItem = false; - } - - if(this->nextWriteStatus.length() > 0){ - if(!fFirstItem){ - if(!this->client->print("&")) return abortWriteRaw(); - } - if(!this->client->print("status=")) return abortWriteRaw(); - if(!this->client->print(this->nextWriteStatus)) return abortWriteRaw(); - fFirstItem = false; - } - - if(this->nextWriteTwitter.length() > 0){ - if(!fFirstItem){ - if(!this->client->print("&")) return abortWriteRaw(); - } - if(!this->client->print("twitter=")) return abortWriteRaw(); - if(!this->client->print(this->nextWriteTwitter)) return abortWriteRaw(); - fFirstItem = false; - } - - if(this->nextWriteTweet.length() > 0){ - if(!fFirstItem){ - if(!this->client->print("&")) return abortWriteRaw(); - } - if(!this->client->print("tweet=")) return abortWriteRaw(); - if(!this->client->print(this->nextWriteTweet)) return abortWriteRaw(); - fFirstItem = false; - } - - if(this->nextWriteCreatedAt.length() > 0){ - if(!fFirstItem){ - if(!this->client->print("&")) return abortWriteRaw(); - } - if(!this->client->print("created_at=")) return abortWriteRaw(); - if(!this->client->print(this->nextWriteCreatedAt)) return abortWriteRaw(); - fFirstItem = false; - } - - - if(!this->client->print("&headers=false")) return abortWriteRaw(); - - resetWriteFields(); - - return finishWrite(); - - } - - - /* - Function: writeRaw - - Summary: - Write a raw POST to a ThingSpeak channel - - Parameters: - channelNumber - Channel number - postMessage - Raw URL to write to ThingSpeak as a string. See the documentation at https://thingspeak.com/docs/channels#update_feed. - writeAPIKey - Write API key associated with the channel. *If you share code with others, do _not_ share this key* - - Returns: - 200 - successful. - 404 - Incorrect API key (or invalid ThingSpeak server address) - -101 - Value is out of range or string is too long (> 255 characters) - -201 - Invalid field number specified - -210 - setField() was not called before writeFields() - -301 - Failed to connect to ThingSpeak - -302 - Unexpected failure during write to ThingSpeak - -303 - Unable to parse response - -304 - Timeout waiting for server to respond - -401 - Point was not inserted (most probable cause is the rate limit of once every 15 seconds) - - Notes: - This is low level functionality that will not be required by most users. - - */ - int writeRaw(unsigned long channelNumber, const char * postMessage, const char * writeAPIKey) - { - return writeRaw(channelNumber, String(postMessage), writeAPIKey); - }; - - - /* - Function: writeRaw - - Summary: - Write a raw POST to a ThingSpeak channel - - Parameters: - channelNumber - Channel number - postMessage - Raw URL to write to ThingSpeak as a string. See the documentation at https://thingspeak.com/docs/channels#update_feed. - writeAPIKey - Write API key associated with the channel. *If you share code with others, do _not_ share this key* - - Returns: - 200 - successful. - 404 - Incorrect API key (or invalid ThingSpeak server address) - -101 - Value is out of range or string is too long (> 255 characters) - -201 - Invalid field number specified - -210 - setField() was not called before writeFields() - -301 - Failed to connect to ThingSpeak - -302 - Unexpected failure during write to ThingSpeak - -303 - Unable to parse response - -304 - Timeout waiting for server to respond - -401 - Point was not inserted (most probable cause is the rate limit of once every 15 seconds) - - Notes: - This is low level functionality that will not be required by most users. - - */ - int writeRaw(unsigned long channelNumber, String postMessage, const char * writeAPIKey) - { - #ifdef PRINT_DEBUG_MESSAGES - Serial.print("ts::writeRaw (channelNumber: "); Serial.print(channelNumber); Serial.print(" writeAPIKey: "); Serial.println(writeAPIKey); - #endif - - if(!connectThingSpeak()) - { - // Failed to connect to ThingSpeak - return ERR_CONNECT_FAILED; - } - - postMessage.concat("&headers=false"); - - #ifdef PRINT_DEBUG_MESSAGES - Serial.print(" POST \"");Serial.print(postMessage);Serial.println("\""); - #endif - - - // Post data to thingspeak - if(!this->client->print("POST /update HTTP/1.1\r\n")) return abortWriteRaw(); - if(!writeHTTPHeader(writeAPIKey)) return abortWriteRaw(); - if(!this->client->print("Content-Type: application/x-www-form-urlencoded\r\n")) return abortWriteRaw(); - if(!this->client->print("Content-Length: ")) return abortWriteRaw(); - if(!this->client->print(postMessage.length())) return abortWriteRaw(); - if(!this->client->print("\r\n\r\n")) return abortWriteRaw(); - if(!this->client->print(postMessage)) return abortWriteRaw(); - - resetWriteFields(); - - return finishWrite(); - - }; - - - /* - Function: readStringField - - Summary: - Read the latest string from a private ThingSpeak channel - - Parameters: - channelNumber - Channel number - field - Field number (1-8) within the channel to read from. - readAPIKey - Read API key associated with the channel. *If you share code with others, do _not_ share this key* - - Returns: - Value read (UTF8 string), or empty string if there is an error. Use getLastReadStatus() to get more specific information. - - */ - String readStringField(unsigned long channelNumber, unsigned int field, const char * readAPIKey) - { - if(field < FIELDNUM_MIN || field > FIELDNUM_MAX) - { - this->lastReadStatus = ERR_INVALID_FIELD_NUM; - return(""); - } - #ifdef PRINT_DEBUG_MESSAGES - Serial.print("ts::readStringField(channelNumber: "); Serial.print(channelNumber); - if(NULL != readAPIKey) - { - Serial.print(" readAPIKey: "); Serial.print(readAPIKey); - } - Serial.print(" field: "); Serial.print(field); Serial.println(")"); - #endif - String urlSuffix = String("/fields/"); - urlSuffix.concat(field); - urlSuffix.concat("/last"); - return readRaw(channelNumber, urlSuffix, readAPIKey); - } - - - - /* - Function: readStringField - - Summary: - Read the latest string from a private ThingSpeak channel - - Parameters: - channelNumber - Channel number - field - Field number (1-8) within the channel to read from. - - Returns: - Value read (UTF8 string), or empty string if there is an error. Use getLastReadStatus() to get more specific information. - - */ - String readStringField(unsigned long channelNumber, unsigned int field) - { - return readStringField(channelNumber, field, NULL); - }; - - - /* - Function: readFloatField - - Summary: - ead the latest floating point value from a private ThingSpeak channel - - Parameters: - channelNumber - Channel number - field - Field number (1-8) within the channel to read from. - readAPIKey - Read API key associated with the channel. *If you share code with others, do _not_ share this key* - - Returns: - Value read, or 0 if the field is text or there is an error. Use getLastReadStatus() to get more specific information. Note that NAN, INFINITY, and -INFINITY are valid results. - - */ - float readFloatField(unsigned long channelNumber, unsigned int field, const char * readAPIKey) - { - return convertStringToFloat(readStringField(channelNumber, field, readAPIKey)); - }; + #define FIELDNUM_MIN 1 + #define FIELDNUM_MAX 8 + #define FIELDLENGTH_MAX 255 // Max length for a field in ThingSpeak is 255 bytes (UTF-8) + + #define TIMEOUT_MS_SERVERRESPONSE 5000 // Wait up to five seconds for server to respond + + #define TS_OK_SUCCESS 200 // OK / Success + #define TS_ERR_BADAPIKEY 400 // Incorrect API key (or invalid ThingSpeak server address) + #define TS_ERR_BADURL 404 // Incorrect API key (or invalid ThingSpeak server address) + #define TS_ERR_OUT_OF_RANGE -101 // Value is out of range or string is too long (> 255 bytes) + #define TS_ERR_INVALID_FIELD_NUM -201 // Invalid field number specified + #define TS_ERR_SETFIELD_NOT_CALLED -210 // setField() was not called before writeFields() + #define TS_ERR_CONNECT_FAILED -301 // Failed to connect to ThingSpeak + #define TS_ERR_UNEXPECTED_FAIL -302 // Unexpected failure during write to ThingSpeak + #define TS_ERR_BAD_RESPONSE -303 // Unable to parse response + #define TS_ERR_TIMEOUT -304 // Timeout waiting for server to respond + #define TS_ERR_NOT_INSERTED -401 // Point was not inserted (most probable cause is the rate limit of once every 15 seconds) - /* - Function: readFloatField - - Summary: - Read the latest floating point value from a private ThingSpeak channel - - Parameters: - channelNumber - Channel number - field - Field number (1-8) within the channel to read from. - - Returns: - Value read, or 0 if the field is text or there is an error. Use getLastReadStatus() to get more specific information. Note that NAN, INFINITY, and -INFINITY are valid results. - - */ - float readFloatField(unsigned long channelNumber, unsigned int field) - { - return readFloatField(channelNumber, field, NULL); - }; - - - /* - Function: readLongField - - Summary: - Read the latest long value from a private ThingSpeak channel - - Parameters: - channelNumber - Channel number - field - Field number (1-8) within the channel to read from. - readAPIKey - Read API key associated with the channel. *If you share code with others, do _not_ share this key* - - Returns: - Value read, or 0 if the field is text or there is an error. Use getLastReadStatus() to get more specific information. Note that NAN, INFINITY, and -INFINITY are valid results. - - */ - long readLongField(unsigned long channelNumber, unsigned int field, const char * readAPIKey) - { - // Note that although the function is called "toInt" it really returns a long. - return readStringField(channelNumber, field, readAPIKey).toInt(); - } - - - /* - Function: readLongField - - Summary: - Read the latest long value from a private ThingSpeak channel - - Parameters: - channelNumber - Channel number - field - Field number (1-8) within the channel to read from. - - Returns: - Value read, or 0 if the field is text or there is an error. Use getLastReadStatus() to get more specific information. Note that NAN, INFINITY, and -INFINITY are valid results. - - */ - long readLongField(unsigned long channelNumber, unsigned int field) - { - return readLongField(channelNumber, field, NULL); - }; - - - /* - Function: readIntField - - Summary: - Read the latest int value from a private ThingSpeak channel - - Parameters: - channelNumber - Channel number - field - Field number (1-8) within the channel to read from. - readAPIKey - Read API key associated with the channel. *If you share code with others, do _not_ share this key* - - Returns: - Value read, or 0 if the field is text or there is an error. Use getLastReadStatus() to get more specific information. Note that NAN, INFINITY, and -INFINITY are valid results. - - */ - int readIntField(unsigned long channelNumber, unsigned int field, const char * readAPIKey) - { - return readLongField(channelNumber, field, readAPIKey); - } - - - /* - Function: readIntField - - Summary: - Read the latest int value from a private ThingSpeak channel - - Parameters: - channelNumber - Channel number - field - Field number (1-8) within the channel to read from. - - Returns: - Value read, or 0 if the field is text or there is an error. Use getLastReadStatus() to get more specific information. Note that NAN, INFINITY, and -INFINITY are valid results. - - */ - int readIntField(unsigned long channelNumber, unsigned int field) - { - return readLongField(channelNumber, field, NULL); - }; - - - /* - Function: readStatus - - Summary: - Read the latest status from a private ThingSpeak channel - - Parameters: - channelNumber - Channel number - readAPIKey - Read API key associated with the channel. *If you share code with others, do _not_ share this key* - - Results: - Value read (UTF8 string). An empty string is returned if there was no status written to the channel or in case of an error. Use getLastReadStatus() to get more specific information. - - */ - String readStatus(unsigned long channelNumber, const char * readAPIKey) - { - String content = readRaw(channelNumber, "/feeds/last.txt?status=true", readAPIKey); - - if(getLastReadStatus() != OK_SUCCESS){ - return String(""); - } - - return getJSONValueByKey(content, "status"); - }; - - - /* - Function: readStatus - - Summary: - Read the latest status from a private ThingSpeak channel - - Parameters: - channelNumber - Channel number - - Results: - Value read (UTF8 string). An empty string is returned if there was no status written to the channel or in case of an error. Use getLastReadStatus() to get more specific information. - - */ - String readStatus(unsigned long channelNumber) - { - return readStatus(channelNumber, NULL); - }; - - - /* - Function: readCreatedAt - - Summary: - Read the created-at timestamp associated with the latest update to a private ThingSpeak channel - - Parameters: - channelNumber - Channel number - readAPIKey - Read API key associated with the channel. *If you share code with others, do _not_ share this key* - - Results: - Value read (UTF8 string). An empty string is returned if there was no created-at timestamp written to the channel or in case of an error. Use getLastReadStatus() to get more specific information. - - */ - String readCreatedAt(unsigned long channelNumber, const char * readAPIKey) - { - String content = readRaw(channelNumber, "/feeds/last.txt", readAPIKey); - - if(getLastReadStatus() != OK_SUCCESS){ - return String(""); - } - - return getJSONValueByKey(content, "created_at"); - }; - - - /* - Function: readCreatedAt - - Summary: - Read the created-at timestamp associated with the latest update to a private ThingSpeak channel - - Parameters: - channelNumber - Channel number - - Results: - Value read (UTF8 string). An empty string is returned if there was no created-at timestamp written to the channel or in case of an error. Use getLastReadStatus() to get more specific information. - - */ - String readCreatedAt(unsigned long channelNumber) - { - return readCreatedAt(channelNumber, NULL); - }; - - - /* - Function: readRaw - - Summary: - Read a raw response from a public ThingSpeak channel - - Parameters: - channelNumber - Channel number - URLSuffix - Raw URL to write to ThingSpeak as a String. See the documentation at https://thingspeak.com/docs/channels#get_feed - - Returns: - Response if successful, or empty string. Use getLastReadStatus() to get more specific information. - - Notes: - This is low level functionality that will not be required by most users. - - */ - String readRaw(unsigned long channelNumber, String URLSuffix) - { - return readRaw(channelNumber, URLSuffix, NULL); - } - - - /* - Function: readRaw - - Summary: - Read a raw response from a public ThingSpeak channel - - Parameters: - channelNumber - Channel number - URLSuffix - Raw URL to write to ThingSpeak as a String. See the documentation at https://thingspeak.com/docs/channels#get_feed - readAPIKey - Read API key associated with the channel. *If you share code with others, do _not_ share this key* - - Returns: - Response if successful, or empty string. Use getLastReadStatus() to get more specific information. - - Notes: - This is low level functionality that will not be required by most users. - - */ - String readRaw(unsigned long channelNumber, String URLSuffix, const char * readAPIKey) - { - #ifdef PRINT_DEBUG_MESSAGES - Serial.print("ts::readRaw (channelNumber: "); Serial.print(channelNumber); - if(NULL != readAPIKey) - { - Serial.print(" readAPIKey: "); Serial.print(readAPIKey); - } - Serial.print(" URLSuffix: \""); Serial.print(URLSuffix); Serial.println("\")"); - #endif - - if(!connectThingSpeak()) - { - this->lastReadStatus = ERR_CONNECT_FAILED; - return String(""); - } - - String URL = String("/channels/"); - URL.concat(channelNumber); - URL.concat(URLSuffix); - - #ifdef PRINT_DEBUG_MESSAGES - Serial.print(" GET \"");Serial.print(URL);Serial.println("\""); - #endif - - // Post data to thingspeak - if(!this->client->print("GET ")) return abortReadRaw(); - if(!this->client->print(URL)) return abortReadRaw(); - if(!this->client->print(" HTTP/1.1\r\n")) return abortReadRaw(); - if(!writeHTTPHeader(readAPIKey)) return abortReadRaw(); - if(!this->client->print("\r\n")) return abortReadRaw(); - - String content = String(); - int status = getHTTPResponse(content); - - this->lastReadStatus = status; - - emptyStream(); - - #ifdef PRINT_DEBUG_MESSAGES - if(status == OK_SUCCESS) - { - Serial.print("Read: \""); Serial.print(content); Serial.println("\""); - } - #endif - - this->client->stop(); - #ifdef PRINT_DEBUG_MESSAGES - Serial.println("disconnected."); - #endif - - if(status != OK_SUCCESS) - { - // return status; - return String(""); - } - - return content; - }; - - - /* - Function: getLastReadStatus - - Summary: - Get the status of the previous read. - - Returns: - Generally, these are HTTP status codes. Negative values indicate an error generated by the library. - Possible response codes... - 200 - OK / Success - 404 - Incorrect API key (or invalid ThingSpeak server address) - -101 - Value is out of range or string is too long (> 255 characters) - -201 - Invalid field number specified - -210 - setField() was not called before writeFields() - -301 - Failed to connect to ThingSpeak - -302 - Unexpected failure during write to ThingSpeak - -303 - Unable to parse response - -304 - Timeout waiting for server to respond - -401 - Point was not inserted (most probable cause is exceeding the rate limit) - - Notes: - The read functions will return zero or empty if there is an error. Use this function to retrieve the details. - */ - int getLastReadStatus() - { - return this->lastReadStatus; - }; -private: - - int getWriteFieldsContentLength(){ - size_t iField; - int contentLen = 0; - - for(iField = 0; iField < FIELDNUM_MAX; iField++){ - if(this->nextWriteField[iField].length() > 0){ - contentLen = contentLen + 8 + this->nextWriteField[iField].length(); // &fieldX=[value] - - // future-proof in case ThingSpeak allows 999 fields someday - if(iField > 9){ - contentLen = contentLen + 1; - } - else if(iField > 99){ - contentLen = contentLen + 2; - } - - } - } - - if(!isnan(this->nextWriteLatitude)){ - contentLen = contentLen + 5 + String(this->nextWriteLatitude).length(); // &lat=[value] - } - - if(!isnan(this->nextWriteLongitude)){ - contentLen = contentLen + 6 + String(this->nextWriteLongitude).length(); // &long=[value] - } - - if(!isnan(this->nextWriteElevation)){ - contentLen = contentLen + 11 + String(this->nextWriteElevation).length(); // &elevation=[value] - } - - if(this->nextWriteStatus.length() > 0){ - contentLen = contentLen + 8 + this->nextWriteStatus.length(); // &status=[value] - } - - if(this->nextWriteTwitter.length() > 0){ - contentLen = contentLen + 9 + this->nextWriteTwitter.length(); // &twitter=[value] - } - - if(this->nextWriteTweet.length() > 0){ - contentLen = contentLen + 7 + this->nextWriteTweet.length(); // &tweet=[value] - } - - if(this->nextWriteCreatedAt.length() > 0){ - contentLen = contentLen + 12 + this->nextWriteCreatedAt.length(); // &created_at=[value] - } - - if(contentLen == 0){ - return 0; - } - - contentLen = contentLen + 13; // add 14 for '&headers=false', subtract 1 for missing first '&' - - return contentLen; - - } - - void emptyStream(){ - while(this->client->available() > 0){ - this->client->read(); - } - } - - int finishWrite(){ - String entryIDText = String(); - int status = getHTTPResponse(entryIDText); - - emptyStream(); - - if(status != OK_SUCCESS) - { - this->client->stop(); - return status; - } - long entryID = entryIDText.toInt(); - - #ifdef PRINT_DEBUG_MESSAGES - Serial.print(" Entry ID \"");Serial.print(entryIDText);Serial.print("\" (");Serial.print(entryID);Serial.println(")"); - #endif - - this->client->stop(); - - #ifdef PRINT_DEBUG_MESSAGES - Serial.println("disconnected."); - #endif - if(entryID == 0) - { - // ThingSpeak did not accept the write - status = ERR_NOT_INSERTED; - } - return status; - } - - - String getJSONValueByKey(String textToSearch, String key) - { - if(textToSearch.length() == 0){ - return String(""); - } - - String searchPhrase = String("\""); - searchPhrase.concat(key); - searchPhrase.concat("\":\""); - - int fromPosition = textToSearch.indexOf(searchPhrase,0); - - if(fromPosition == -1){ - // return because there is no status or it's null - return String(""); - } - - fromPosition = fromPosition + searchPhrase.length(); - - int toPosition = textToSearch.indexOf("\"", fromPosition); - - - if(toPosition == -1){ - // return because there is no end quote - return String(""); - } - - textToSearch.remove(toPosition); - - return textToSearch.substring(fromPosition); - } - - int abortWriteRaw() - { - while(this->client->available() > 0){ - this->client->read(); - } - this->client->stop(); - resetWriteFields(); - return ERR_UNEXPECTED_FAIL; - } - - String abortReadRaw() + // variables to store the values from the readMultipleFields functionality + #ifndef ARDUINO_AVR_UNO + typedef struct feedRecord + { + String nextReadField[8]; + String nextReadStatus; + String nextReadLatitude; + String nextReadLongitude; + String nextReadElevation; + String nextReadCreatedAt; + }feed; + #endif + + + // Enables an Arduino, ESP8266, ESP32 or other compatible hardware to write or read data to or from ThingSpeak, an open data platform for the Internet of Things with MATLAB analytics and visualization. + class ThingSpeakClass { - while(this->client->available() > 0){ - this->client->read(); - } - this->client->stop(); - #ifdef PRINT_DEBUG_MESSAGES - Serial.println("ReadRaw abort - disconnected."); - #endif - this->lastReadStatus = ERR_UNEXPECTED_FAIL; - return String(""); - } - - void setPort(unsigned int port) - { - this->port = port; - } - - - void setClient(Client * client) {this->client = client;}; - - Client * client = NULL; - unsigned int port = THINGSPEAK_PORT_NUMBER; - String nextWriteField[8]; - float nextWriteLatitude; - float nextWriteLongitude; - float nextWriteElevation; - int lastReadStatus; - String nextWriteStatus; - String nextWriteTwitter; - String nextWriteTweet; - String nextWriteCreatedAt; - - bool connectThingSpeak() - { - bool connectSuccess = false; - - #ifdef PRINT_DEBUG_MESSAGES - Serial.print(" Connect to default ThingSpeak: "); - Serial.print(THINGSPEAK_URL); - Serial.print(":"); - Serial.print(this->port); - Serial.print("..."); - #endif - - connectSuccess = client->connect(const_cast(THINGSPEAK_URL), this->port); - - - #ifdef PRINT_DEBUG_MESSAGES - if (connectSuccess) - { - Serial.println("Success."); - } - else - { - Serial.println("Failed."); - } - #endif - return connectSuccess; - }; - - bool writeHTTPHeader(const char * APIKey) - { - - if (!this->client->print("Host: api.thingspeak.com\r\n")) return false; - if (!this->client->print("User-Agent: ")) return false; - if (!this->client->print(TS_USER_AGENT)) return false; - if (!this->client->print("\r\n")) return false; - if(NULL != APIKey) - { - if (!this->client->print("X-THINGSPEAKAPIKEY: ")) return false; - if (!this->client->print(APIKey)) return false; - if (!this->client->print("\r\n")) return false; - } - return true; - }; - - int getHTTPResponse(String & response) - { - - // make sure all of the HTTP request is pushed out of the buffer before looking for a response - this->client->flush(); - - long timeoutTime = millis() + TIMEOUT_MS_SERVERRESPONSE; - - while(this->client-> available() < 17){ - delay(2); - if(millis() > timeoutTime){ - return ERR_TIMEOUT; - } - } - - if(!this->client->find(const_cast("HTTP/1.1"))) - { - #ifdef PRINT_HTTP - Serial.println("ERROR: Didn't find HTTP/1.1"); - #endif - return ERR_BAD_RESPONSE; // Couldn't parse response (didn't find HTTP/1.1) - } - int status = this->client->parseInt(); - #ifdef PRINT_HTTP - Serial.print("Got Status of ");Serial.println(status); - #endif - if(status != OK_SUCCESS) - { - return status; - } - - // Find Content-Length - if(!this->client->find(const_cast("Content-Length:"))){ - #ifdef PRINT_HTTP - Serial.println("ERROR: Didn't find Content-Length header"); - #endif - return ERR_BAD_RESPONSE; // Couldn't parse response (didn't find HTTP/1.1) - } - int contentLength = this->client->parseInt(); - - #ifdef PRINT_HTTP - Serial.print("Content Length: "); - Serial.println(contentLength); - #endif - - if(!this->client->find(const_cast("\r\n\r\n"))) - { - #ifdef PRINT_HTTP - Serial.println("ERROR: Didn't find end of headers"); - #endif - return ERR_BAD_RESPONSE; - } - #ifdef PRINT_HTTP - Serial.println("Found end of header"); - #endif - - timeoutTime = millis() + TIMEOUT_MS_SERVERRESPONSE; - - while(this->client->available() < contentLength){ - delay(2); - if(millis() > timeoutTime){ - return ERR_TIMEOUT; - } - } - - String tempString = String(""); - char y = 0; - for(int i = 0; i < contentLength; i++){ - y = client->read(); - tempString.concat(y); - } - response = tempString; - - - #ifdef PRINT_HTTP - Serial.print("Response: \"");Serial.print(response);Serial.println("\""); - #endif - return status; - }; - - - int convertFloatToChar(float value, char *valueString) - { - // Supported range is -999999000000 to 999999000000 - if(0 == isinf(value) && (value > 999999000000 || value < -999999000000)) - { - // Out of range - return ERR_OUT_OF_RANGE; - } - // assume that 5 places right of decimal should be sufficient for most applications - - #if defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_SAM) - sprintf(valueString, "%.5f", value); - #else - dtostrf(value,1,5, valueString); + public: + ThingSpeakClass() + { + resetWriteFields(); + this->lastReadStatus = TS_OK_SUCCESS; + } + + + /* + Function: begin + + Summary: + Initializes the ThingSpeak library and network settings using the ThingSpeak.com service. + + Parameters: + client - EthernetClient, YunClient, TCPClient, or WiFiClient for HTTP connection and WiFiSSLClient, WiFiClientSecure for HTTPS connection created earlier in the sketch. + + Returns: + Always returns true + + Notes: + This does not validate the information passed in, or generate any calls to ThingSpeak. + Include this ThingSpeak header file after including the client header file and the TS_ENABLE_SSL macro in the user sketch. + */ + bool begin(Client & client) + { + #ifdef PRINT_DEBUG_MESSAGES + Serial.println("ts::tsBegin"); + #endif + + this->setClient(&client); + + this->setPort(THINGSPEAK_PORT_NUMBER); + #if defined(TS_ENABLE_SSL) + #if defined(WIFISSLCLIENT_H) || defined(wificlientbearssl_h) || defined(WiFiClientSecure_h) + this->setPort(THINGSPEAK_HTTPS_PORT_NUMBER); + #else + Serial.println("WARNING: This library doesn't support SSL connection to ThingSpeak. Default HTTP Connection used."); + #endif + #endif + + resetWriteFields(); + this->lastReadStatus = TS_OK_SUCCESS; + return true; + } + + + /* + Function: writeField + + Summary: + Write an integer value to a single field in a ThingSpeak channel + + Parameters: + channelNumber - Channel number + field - Field number (1-8) within the channel to write to. + value - Integer value (from -32,768 to 32,767) to write. + writeAPIKey - Write API key associated with the channel. *If you share code with others, do _not_ share this key* + + Returns: + HTTP status code of 200 if successful. + + Notes: + See getLastReadStatus() for other possible return values. + */ + int writeField(unsigned long channelNumber, unsigned int field, int value, const char * writeAPIKey) + { + char valueString[10]; // int range is -32768 to 32768, so 7 bytes including terminator, plus a little extra + itoa(value, valueString, 10); + return writeField(channelNumber, field, valueString, writeAPIKey); + } + + + /* + Function: writeField + + Summary: + Write a long value to a single field in a ThingSpeak channel + + Parameters: + channelNumber - Channel number + field - Field number (1-8) within the channel to write to. + value - Long value (from -2,147,483,648 to 2,147,483,647) to write. + writeAPIKey - Write API key associated with the channel. *If you share code with others, do _not_ share this key* + + Returns: + HTTP status code of 200 if successful. + + Notes: + See getLastReadStatus() for other possible return values. + */ + int writeField(unsigned long channelNumber, unsigned int field, long value, const char * writeAPIKey) + { + char valueString[15]; // long range is -2147483648 to 2147483647, so 12 bytes including terminator + ltoa(value, valueString, 10); + return writeField(channelNumber, field, valueString, writeAPIKey); + } + + /* + Function: writeField + + Summary: + Write a floating point value to a single field in a ThingSpeak channel + + Parameters: + channelNumber - Channel number + field - Field number (1-8) within the channel to write to. + value - Floating point value (from -999999000000 to 999999000000) to write. If you need more accuracy, or a wider range, you should format the number using dtostrf and writeField(). + writeAPIKey - Write API key associated with the channel. *If you share code with others, do _not_ share this key* + + Returns: + HTTP status code of 200 if successful. + + Notes: + See getLastReadStatus() for other possible return values. + */ + int writeField(unsigned long channelNumber, unsigned int field, float value, const char * writeAPIKey) + { + #ifdef PRINT_DEBUG_MESSAGES + Serial.print("ts::writeField (channelNumber: "); Serial.print(channelNumber); Serial.print(" writeAPIKey: "); Serial.print(writeAPIKey); Serial.print(" field: "); Serial.print(field); Serial.print(" value: "); Serial.print(value,5); Serial.println(")"); + #endif + char valueString[20]; // range is -999999000000.00000 to 999999000000.00000, so 19 + 1 for the terminator + int status = convertFloatToChar(value, valueString); + if(status != TS_OK_SUCCESS) return status; + + return writeField(channelNumber, field, valueString, writeAPIKey); + } + + + /* + Function: writeField + + Summary: + Write a string to a single field in a ThingSpeak channel + + Parameters: + channelNumber - Channel number + field - Field number (1-8) within the channel to write to. + value - String to write (UTF8 string). ThingSpeak limits this field to 255 bytes. + writeAPIKey - Write API key associated with the channel. *If you share code with others, do _not_ share this key* + + Returns: + HTTP status code of 200 if successful. + + Notes: + See getLastReadStatus() for other possible return values. + */ + int writeField(unsigned long channelNumber, unsigned int field, String value, const char * writeAPIKey) + { + // Invalid field number specified + if(field < FIELDNUM_MIN || field > FIELDNUM_MAX) return TS_ERR_INVALID_FIELD_NUM; + // Max # bytes for ThingSpeak field is 255 + if(value.length() > FIELDLENGTH_MAX) return TS_ERR_OUT_OF_RANGE; + + #ifdef PRINT_DEBUG_MESSAGES + Serial.print("ts::writeField (channelNumber: "); Serial.print(channelNumber); Serial.print(" writeAPIKey: "); Serial.print(writeAPIKey); Serial.print(" field: "); Serial.print(field); Serial.print(" value: \""); Serial.print(value); Serial.println("\")"); + #endif + String postMessage = String("field"); + postMessage.concat(field); + postMessage.concat("="); + postMessage.concat(value); + + return writeRaw(channelNumber, postMessage, writeAPIKey); + } + + + /* + Function: setField + + Summary: + Set the value of a single field that will be part of a multi-field update. + + Parameters: + field - Field number (1-8) within the channel to set. + value - Integer value (from -32,768 to 32,767) to set. + + Returns: + Code of 200 if successful. + Code of -101 if value is out of range or string is too long (> 255 bytes) + */ + int setField(unsigned int field, int value) + { + char valueString[10]; // int range is -32768 to 32768, so 7 bytes including terminator + itoa(value, valueString, 10); + + return setField(field, valueString); + } + + + /* + Function: setField + + Summary: + Set the value of a single field that will be part of a multi-field update. + + Parameters: + field - Field number (1-8) within the channel to set. + value - Long value (from -2,147,483,648 to 2,147,483,647) to write. + + Returns: + Code of 200 if successful. + Code of -101 if value is out of range or string is too long (> 255 bytes) + */ + int setField(unsigned int field, long value) + { + char valueString[15]; // long range is -2147483648 to 2147483647, so 12 bytes including terminator + ltoa(value, valueString, 10); + + return setField(field, valueString); + } + + /* + Function: setField + + Summary: + Set the value of a single field that will be part of a multi-field update. + + Parameters: + field - Field number (1-8) within the channel to set. + value - Floating point value (from -999999000000 to 999999000000) to write. If you need more accuracy, or a wider range, you should format the number yourself (using dtostrf) and setField() using the resulting string. + + Returns: + Code of 200 if successful. + Code of -101 if value is out of range or string is too long (> 255 bytes) + */ + int setField(unsigned int field, float value) + { + char valueString[20]; // range is -999999000000.00000 to 999999000000.00000, so 19 + 1 for the terminator + int status = convertFloatToChar(value, valueString); + if(status != TS_OK_SUCCESS) return status; + + return setField(field, valueString); + } + + + /* + Function: setField + + Summary: + Set the value of a single field that will be part of a multi-field update. + + Parameters: + field - Field number (1-8) within the channel to set. + value - String to write (UTF8). ThingSpeak limits this to 255 bytes. + + Returns: + Code of 200 if successful. + Code of -101 if value is out of range or string is too long (> 255 bytes) + */ + int setField(unsigned int field, String value) + { + #ifdef PRINT_DEBUG_MESSAGES + Serial.print("ts::setField (field: "); Serial.print(field); Serial.print(" value: \""); Serial.print(value); Serial.println("\")"); + #endif + if(field < FIELDNUM_MIN || field > FIELDNUM_MAX) return TS_ERR_INVALID_FIELD_NUM; + // Max # bytes for ThingSpeak field is 255 (UTF-8) + if(value.length() > FIELDLENGTH_MAX) return TS_ERR_OUT_OF_RANGE; + this->nextWriteField[field - 1] = value; + + return TS_OK_SUCCESS; + } + + + /* + Function: setLatitude + + Summary: + Set the latitude of a multi-field update. + + Parameters: + latitude - Latitude of the measurement as a floating point value (degrees N, use negative values for degrees S) + + Returns: + Always return 200 + + Notes: + To record latitude, longitude and elevation of a write, call setField() for each of the fields you want to write. Then setLatitude(), setLongitude(), setElevation() and then call writeFields() + */ + int setLatitude(float latitude) + { + #ifdef PRINT_DEBUG_MESSAGES + Serial.print("ts::setLatitude(latitude: "); Serial.print(latitude,3); Serial.println("\")"); + #endif + this->nextWriteLatitude = latitude; + + return TS_OK_SUCCESS; + } + + + /* + Function: setLongitude + + Summary: + Set the longitude of a multi-field update. + + Parameters: + longitude - Longitude of the measurement as a floating point value (degrees E, use negative values for degrees W) + + Returns: + Always return 200 + + Notes: + To record latitude, longitude and elevation of a write, call setField() for each of the fields you want to write. Then setLatitude(), setLongitude(), setElevation() and then call writeFields() + */ + int setLongitude(float longitude) + { + #ifdef PRINT_DEBUG_MESSAGES + Serial.print("ts::setLongitude(longitude: "); Serial.print(longitude,3); Serial.println("\")"); + #endif + this->nextWriteLongitude = longitude; + + return TS_OK_SUCCESS; + } + + + /* + Function: setElevation + + Summary: + Set the elevation of a multi-field update. + + Parameters: + elevation - Elevation of the measurement as a floating point value (meters above sea level) + + Returns: + Always return 200 + + Notes: + To record latitude, longitude and elevation of a write, call setField() for each of the fields you want to write. Then setLatitude(), setLongitude(), setElevation() and then call writeFields() + + */ + int setElevation(float elevation) + { + #ifdef PRINT_DEBUG_MESSAGES + Serial.print("ts::setElevation(elevation: "); Serial.print(elevation,3); Serial.println("\")"); + #endif + this->nextWriteElevation = elevation; + + return TS_OK_SUCCESS; + } + + + /* + Function: setStatus + + Summary: + Set the status field of a multi-field update. + + Parameters: + status - String to write (UTF8). ThingSpeak limits this to 255 bytes. + + Returns: + Code of 200 if successful. + Code of -101 if string is too long (> 255 bytes) + + Notes: + To record a status message on a write, call setStatus() then call writeFields(). + Use status to provide additonal details when writing a channel update. + Additonally, status can be used by the ThingTweet App to send a message to Twitter. + */ + int setStatus(String status) + { + #ifdef PRINT_DEBUG_MESSAGES + Serial.print("ts::setStatus(status: "); Serial.print(status); Serial.println("\")"); + #endif + // Max # bytes for ThingSpeak field is 255 (UTF-8) + if(status.length() > FIELDLENGTH_MAX) return TS_ERR_OUT_OF_RANGE; + this->nextWriteStatus = status; + + return TS_OK_SUCCESS; + } + + + /* + Function: setTwitterTweet + + Summary: + Set the Twitter account and message to use for an update to be tweeted. + + Parameters: + twitter - Twitter account name as a String. + tweet - Twitter message as a String (UTF-8) limited to 140 character. + + Returns: + Code of 200 if successful. + Code of -101 if string is too long (> 255 bytes) + + Notes: + To send a message to twitter call setTwitterTweet() then call writeFields(). + Prior to using this feature, a twitter account must be linked to your ThingSpeak account. Do this by logging into ThingSpeak and going to Apps, then ThingTweet and clicking Link Twitter Account. + */ + int setTwitterTweet(String twitter, String tweet){ + #ifdef PRINT_DEBUG_MESSAGES + Serial.print("ts::setTwitterTweet(twitter: "); Serial.print(twitter); Serial.print(", tweet: "); Serial.print(tweet); Serial.println("\")"); + #endif + // Max # bytes for ThingSpeak field is 255 (UTF-8) + if((twitter.length() > FIELDLENGTH_MAX) || (tweet.length() > FIELDLENGTH_MAX)) return TS_ERR_OUT_OF_RANGE; + + this->nextWriteTwitter = twitter; + this->nextWriteTweet = tweet; + + return TS_OK_SUCCESS; + } + + + /* + Function: setCreatedAt + + Summary: + Set the created-at date of a multi-field update. + + Parameters: + createdAt - Desired timestamp to be included with the channel update as a String. The timestamp string must be in the ISO 8601 format. Example "2017-01-12 13:22:54" + + Returns: + Code of 200 if successful. + Code of -101 if string is too long (> 255 bytes) + + Notes: + Timezones can be set using the timezone hour offset parameter. For example, a timestamp for Eastern Standard Time is: "2017-01-12 13:22:54-05". + If no timezone hour offset parameter is used, UTC time is assumed. + */ + int setCreatedAt(String createdAt) + { + #ifdef PRINT_DEBUG_MESSAGES + Serial.print("ts::setCreatedAt(createdAt: "); Serial.print(createdAt); Serial.println("\")"); + #endif + + // the ISO 8601 format is too complicated to check for valid timestamps here + // we'll need to reply on the api to tell us if there is a problem + // Max # bytes for ThingSpeak field is 255 (UTF-8) + if(createdAt.length() > FIELDLENGTH_MAX) return TS_ERR_OUT_OF_RANGE; + this->nextWriteCreatedAt = createdAt; + + return TS_OK_SUCCESS; + } + + + /* + Function: writeFields + + Summary: + Write a multi-field update. + + Parameters: + channelNumber - Channel number + writeAPIKey - Write API key associated with the channel. *If you share code with others, do _not_ share this key* + + Returns: + 200 - successful. + 404 - Incorrect API key (or invalid ThingSpeak server address) + -101 - Value is out of range or string is too long (> 255 characters) + -201 - Invalid field number specified + -210 - setField() was not called before writeFields() + -301 - Failed to connect to ThingSpeak + -302 - Unexpected failure during write to ThingSpeak + -303 - Unable to parse response + -304 - Timeout waiting for server to respond + -401 - Point was not inserted (most probable cause is the rate limit of once every 15 seconds) + + Notes: + Call setField(), setLatitude(), setLongitude(), setElevation() and/or setStatus() and then call writeFields() + */ + int writeFields(unsigned long channelNumber, const char * writeAPIKey) + { + if(!connectThingSpeak()){ + // Failed to connect to ThingSpeak + return TS_ERR_CONNECT_FAILED; + } + + // Get the content length of the payload + int contentLen = getWriteFieldsContentLength(); + + if(contentLen == 0){ + // setField was not called before writeFields + return TS_ERR_SETFIELD_NOT_CALLED; + } + + #ifdef PRINT_DEBUG_MESSAGES + Serial.print("ts::writeFields (channelNumber: "); Serial.print(channelNumber); Serial.print(" writeAPIKey: "); Serial.println(writeAPIKey); + #endif + + // Post data to thingspeak + if(!this->client->print("POST /update HTTP/1.1\r\n")) return abortWriteRaw(); + if(!writeHTTPHeader(writeAPIKey)) return abortWriteRaw(); + if(!this->client->print("Content-Type: application/x-www-form-urlencoded\r\n")) return abortWriteRaw(); + if(!this->client->print("Content-Length: ")) return abortWriteRaw(); + if(!this->client->print(contentLen)) return abortWriteRaw(); + if(!this->client->print("\r\n\r\n")) return abortWriteRaw(); + + bool fFirstItem = true; + for(size_t iField = 0; iField < FIELDNUM_MAX; iField++){ + if(this->nextWriteField[iField].length() > 0){ + if(!fFirstItem){ + if(!this->client->print("&")) return abortWriteRaw(); + } + if(!this->client->print("field")) return abortWriteRaw(); + if(!this->client->print(iField + 1)) return abortWriteRaw(); + if(!this->client->print("=")) return abortWriteRaw(); + if(!this->client->print(this->nextWriteField[iField])) return abortWriteRaw(); + fFirstItem = false; + } + } + + if(!isnan(this->nextWriteLatitude)){ + if(!fFirstItem){ + if(!this->client->print("&")) return abortWriteRaw(); + } + if(!this->client->print("lat=")) return abortWriteRaw(); + if(!this->client->print(this->nextWriteLatitude)) return abortWriteRaw(); + fFirstItem = false; + } + + if(!isnan(this->nextWriteLongitude)){ + if(!fFirstItem){ + if(!this->client->print("&")) return abortWriteRaw(); + } + if(!this->client->print("long=")) return abortWriteRaw(); + if(!this->client->print(this->nextWriteLongitude)) return abortWriteRaw(); + fFirstItem = false; + } + + if(!isnan(this->nextWriteElevation)){ + if(!fFirstItem){ + if(!this->client->print("&")) return abortWriteRaw(); + } + if(!this->client->print("elevation=")) return abortWriteRaw(); + if(!this->client->print(this->nextWriteElevation)) return abortWriteRaw(); + fFirstItem = false; + } + + if(this->nextWriteStatus.length() > 0){ + if(!fFirstItem){ + if(!this->client->print("&")) return abortWriteRaw(); + } + if(!this->client->print("status=")) return abortWriteRaw(); + if(!this->client->print(this->nextWriteStatus)) return abortWriteRaw(); + fFirstItem = false; + } + + if(this->nextWriteTwitter.length() > 0){ + if(!fFirstItem){ + if(!this->client->print("&")) return abortWriteRaw(); + } + if(!this->client->print("twitter=")) return abortWriteRaw(); + if(!this->client->print(this->nextWriteTwitter)) return abortWriteRaw(); + fFirstItem = false; + } + + if(this->nextWriteTweet.length() > 0){ + if(!fFirstItem){ + if(!this->client->print("&")) return abortWriteRaw(); + } + if(!this->client->print("tweet=")) return abortWriteRaw(); + if(!this->client->print(this->nextWriteTweet)) return abortWriteRaw(); + fFirstItem = false; + } + + if(this->nextWriteCreatedAt.length() > 0){ + if(!fFirstItem){ + if(!this->client->print("&")) return abortWriteRaw(); + } + if(!this->client->print("created_at=")) return abortWriteRaw(); + if(!this->client->print(this->nextWriteCreatedAt)) return abortWriteRaw(); + fFirstItem = false; + } + + if(!this->client->print("&headers=false")) return abortWriteRaw(); + + resetWriteFields(); + + return finishWrite(); + } + + + /* + Function: writeRaw + + Summary: + Write a raw POST to a ThingSpeak channel + + Parameters: + channelNumber - Channel number + postMessage - Raw URL to write to ThingSpeak as a string. See the documentation at https://thingspeak.com/docs/channels#update_feed. + writeAPIKey - Write API key associated with the channel. *If you share code with others, do _not_ share this key* + + Returns: + 200 - successful. + 404 - Incorrect API key (or invalid ThingSpeak server address) + -101 - Value is out of range or string is too long (> 255 characters) + -201 - Invalid field number specified + -210 - setField() was not called before writeFields() + -301 - Failed to connect to ThingSpeak + -302 - Unexpected failure during write to ThingSpeak + -303 - Unable to parse response + -304 - Timeout waiting for server to respond + -401 - Point was not inserted (most probable cause is the rate limit of once every 15 seconds) + + Notes: + This is low level functionality that will not be required by most users. + */ + int writeRaw(unsigned long channelNumber, String postMessage, const char * writeAPIKey) + { + #ifdef PRINT_DEBUG_MESSAGES + Serial.print("ts::writeRaw (channelNumber: "); Serial.print(channelNumber); Serial.print(" writeAPIKey: "); Serial.println(writeAPIKey); + #endif + + if(!connectThingSpeak()) + { + // Failed to connect to ThingSpeak + return TS_ERR_CONNECT_FAILED; + } + + postMessage.concat("&headers=false"); + + #ifdef PRINT_DEBUG_MESSAGES + Serial.print(" POST \"");Serial.print(postMessage);Serial.println("\""); + #endif + + + // Post data to thingspeak + if(!this->client->print("POST /update HTTP/1.1\r\n")) return abortWriteRaw(); + if(!writeHTTPHeader(writeAPIKey)) return abortWriteRaw(); + if(!this->client->print("Content-Type: application/x-www-form-urlencoded\r\n")) return abortWriteRaw(); + if(!this->client->print("Content-Length: ")) return abortWriteRaw(); + if(!this->client->print(postMessage.length())) return abortWriteRaw(); + if(!this->client->print("\r\n\r\n")) return abortWriteRaw(); + if(!this->client->print(postMessage)) return abortWriteRaw(); + + resetWriteFields(); + + return finishWrite(); + } + + + /* + Function: readStringField + + Summary: + Read the latest string from a private ThingSpeak channel + + Parameters: + channelNumber - Channel number + field - Field number (1-8) within the channel to read from. + readAPIKey - Read API key associated with the channel. *If you share code with others, do _not_ share this key* + + Returns: + Value read (UTF8 string), or empty string if there is an error. Use getLastReadStatus() to get more specific information. + */ + String readStringField(unsigned long channelNumber, unsigned int field, const char * readAPIKey) + { + if(field < FIELDNUM_MIN || field > FIELDNUM_MAX) + { + this->lastReadStatus = TS_ERR_INVALID_FIELD_NUM; + return(""); + } + #ifdef PRINT_DEBUG_MESSAGES + Serial.print("ts::readStringField(channelNumber: "); Serial.print(channelNumber); + if(NULL != readAPIKey) + { + Serial.print(" readAPIKey: "); Serial.print(readAPIKey); + } + Serial.print(" field: "); Serial.print(field); Serial.println(")"); + #endif + String suffixURL = String("/fields/"); + suffixURL.concat(field); + suffixURL.concat("/last"); + + return readRaw(channelNumber, suffixURL, readAPIKey); + } + + + /* + Function: readStringField + + Summary: + Read the latest string from a public ThingSpeak channel + + Parameters: + channelNumber - Channel number + field - Field number (1-8) within the channel to read from. + + Returns: + Value read (UTF8 string), or empty string if there is an error. Use getLastReadStatus() to get more specific information. + */ + String readStringField(unsigned long channelNumber, unsigned int field) + { + return readStringField(channelNumber, field, NULL); + } + + + /* + Function: readFloatField + + Summary: + ead the latest floating point value from a private ThingSpeak channel + + Parameters: + channelNumber - Channel number + field - Field number (1-8) within the channel to read from. + readAPIKey - Read API key associated with the channel. *If you share code with others, do _not_ share this key* + + Returns: + Value read, or 0 if the field is text or there is an error. Use getLastReadStatus() to get more specific information. Note that NAN, INFINITY, and -INFINITY are valid results. + */ + float readFloatField(unsigned long channelNumber, unsigned int field, const char * readAPIKey) + { + return convertStringToFloat(readStringField(channelNumber, field, readAPIKey)); + } + + + /* + Function: readFloatField + + Summary: + Read the latest floating point value from a public ThingSpeak channel + + Parameters: + channelNumber - Channel number + field - Field number (1-8) within the channel to read from. + + Returns: + Value read, or 0 if the field is text or there is an error. Use getLastReadStatus() to get more specific information. Note that NAN, INFINITY, and -INFINITY are valid results. + */ + float readFloatField(unsigned long channelNumber, unsigned int field) + { + return readFloatField(channelNumber, field, NULL); + } + + + /* + Function: readLongField + + Summary: + Read the latest long value from a private ThingSpeak channel + + Parameters: + channelNumber - Channel number + field - Field number (1-8) within the channel to read from. + readAPIKey - Read API key associated with the channel. *If you share code with others, do _not_ share this key* + + Returns: + Value read, or 0 if the field is text or there is an error. Use getLastReadStatus() to get more specific information. Note that NAN, INFINITY, and -INFINITY are valid results. + */ + long readLongField(unsigned long channelNumber, unsigned int field, const char * readAPIKey) + { + // Note that although the function is called "toInt" it really returns a long. + return readStringField(channelNumber, field, readAPIKey).toInt(); + } + + + /* + Function: readLongField + + Summary: + Read the latest long value from a public ThingSpeak channel + + Parameters: + channelNumber - Channel number + field - Field number (1-8) within the channel to read from. + + Returns: + Value read, or 0 if the field is text or there is an error. Use getLastReadStatus() to get more specific information. Note that NAN, INFINITY, and -INFINITY are valid results. + */ + long readLongField(unsigned long channelNumber, unsigned int field) + { + return readLongField(channelNumber, field, NULL); + } + + + /* + Function: readIntField + + Summary: + Read the latest int value from a private ThingSpeak channel + + Parameters: + channelNumber - Channel number + field - Field number (1-8) within the channel to read from. + readAPIKey - Read API key associated with the channel. *If you share code with others, do _not_ share this key* + + Returns: + Value read, or 0 if the field is text or there is an error. Use getLastReadStatus() to get more specific information. Note that NAN, INFINITY, and -INFINITY are valid results. + */ + int readIntField(unsigned long channelNumber, unsigned int field, const char * readAPIKey) + { + return readLongField(channelNumber, field, readAPIKey); + } + + + /* + Function: readIntField + + Summary: + Read the latest int value from a public ThingSpeak channel + + Parameters: + channelNumber - Channel number + field - Field number (1-8) within the channel to read from. + + Returns: + Value read, or 0 if the field is text or there is an error. Use getLastReadStatus() to get more specific information. Note that NAN, INFINITY, and -INFINITY are valid results. + */ + int readIntField(unsigned long channelNumber, unsigned int field) + { + return readLongField(channelNumber, field, NULL); + } + + + /* + Function: readStatus + + Summary: + Read the latest status from a private ThingSpeak channel + + Parameters: + channelNumber - Channel number + readAPIKey - Read API key associated with the channel. *If you share code with others, do _not_ share this key* + + Results: + Value read (UTF8 string). An empty string is returned if there was no status written to the channel or in case of an error. Use getLastReadStatus() to get more specific information. + */ + String readStatus(unsigned long channelNumber, const char * readAPIKey) + { + String content = readRaw(channelNumber, "/feeds/last.txt?status=true", readAPIKey); + + if(getLastReadStatus() != TS_OK_SUCCESS){ + return String(""); + } + + return getJSONValueByKey(content, "status"); + } + + + /* + Function: readStatus + + Summary: + Read the latest status from a public ThingSpeak channel + + Parameters: + channelNumber - Channel number + + Results: + Value read (UTF8 string). An empty string is returned if there was no status written to the channel or in case of an error. Use getLastReadStatus() to get more specific information. + */ + String readStatus(unsigned long channelNumber) + { + return readStatus(channelNumber, NULL); + } + + + /* + Function: readCreatedAt + + Summary: + Read the created-at timestamp associated with the latest update to a private ThingSpeak channel + + Parameters: + channelNumber - Channel number + readAPIKey - Read API key associated with the channel. *If you share code with others, do _not_ share this key* + + Results: + Value read (UTF8 string). An empty string is returned if there was no created-at timestamp written to the channel or in case of an error. Use getLastReadStatus() to get more specific information. + */ + String readCreatedAt(unsigned long channelNumber, const char * readAPIKey) + { + String content = readRaw(channelNumber, "/feeds/last.txt", readAPIKey); + + if(getLastReadStatus() != TS_OK_SUCCESS){ + return String(""); + } + + return getJSONValueByKey(content, "created_at"); + } + + + /* + Function: readCreatedAt + + Summary: + Read the created-at timestamp associated with the latest update to a public ThingSpeak channel + + Parameters: + channelNumber - Channel number + + Results: + Value read (UTF8 string). An empty string is returned if there was no created-at timestamp written to the channel or in case of an error. Use getLastReadStatus() to get more specific information. + */ + String readCreatedAt(unsigned long channelNumber) + { + return readCreatedAt(channelNumber, NULL); + } + + + /* + Function: readRaw + + Summary: + Read a raw response from a private ThingSpeak channel + + Parameters: + channelNumber - Channel number + suffixURL - Raw URL to write to ThingSpeak as a String. See the documentation at https://thingspeak.com/docs/channels#get_feed + readAPIKey - Read API key associated with the channel. *If you share code with others, do _not_ share this key* + + Returns: + Response if successful, or empty string. Use getLastReadStatus() to get more specific information. + + Notes: + This is low level functionality that will not be required by most users. + */ + String readRaw(unsigned long channelNumber, String suffixURL, const char * readAPIKey) + { + #ifdef PRINT_DEBUG_MESSAGES + Serial.print("ts::readRaw (channelNumber: "); Serial.print(channelNumber); + if(NULL != readAPIKey) + { + Serial.print(" readAPIKey: "); Serial.print(readAPIKey); + } + Serial.print(" suffixURL: \""); Serial.print(suffixURL); Serial.println("\")"); + #endif + + if(!connectThingSpeak()) + { + this->lastReadStatus = TS_ERR_CONNECT_FAILED; + return String(""); + } + + String readURL = String("/channels/"); + readURL.concat(channelNumber); + readURL.concat(suffixURL); + + #ifdef PRINT_DEBUG_MESSAGES + Serial.print(" GET \"");Serial.print(readURL);Serial.println("\""); + #endif + + // Get data from thingspeak + if(!this->client->print("GET ")) return abortReadRaw(); + if(!this->client->print(readURL)) return abortReadRaw(); + if(!this->client->print(" HTTP/1.1\r\n")) return abortReadRaw(); + if(!writeHTTPHeader(readAPIKey)) return abortReadRaw(); + if(!this->client->print("\r\n")) return abortReadRaw(); + + String content = String(); + int status = getHTTPResponse(content); + + this->lastReadStatus = status; + + emptyStream(); + + #ifdef PRINT_DEBUG_MESSAGES + if(status == TS_OK_SUCCESS) + { + Serial.print("Read: \""); Serial.print(content); Serial.println("\""); + } + #endif + + this->client->stop(); + #ifdef PRINT_DEBUG_MESSAGES + Serial.println("disconnected."); + #endif + + if(status != TS_OK_SUCCESS) + { + return String(""); + } + + return content; + } + + + /* + Function: readRaw + + Summary: + Read a raw response from a public ThingSpeak channel + + Parameters: + channelNumber - Channel number + suffixURL - Raw URL to write to ThingSpeak as a String. See the documentation at https://thingspeak.com/docs/channels#get_feed + + Returns: + Response if successful, or empty string. Use getLastReadStatus() to get more specific information. + + Notes: + This is low level functionality that will not be required by most users. + */ + String readRaw(unsigned long channelNumber, String suffixURL) + { + return readRaw(channelNumber, suffixURL, NULL); + } + + + #ifndef ARDUINO_AVR_UNO // Arduino Uno doesn't have enough memory to perform the following functionalities. + + /* + Function: readMultipleFields + + Summary: + Read all the field values, status message, location coordinates, and created-at timestamp associated with the latest feed to a private ThingSpeak channel and store the values locally in variables within a struct. + + Parameters: + channelNumber - Channel number + readAPIKey - Read API key associated with the channel. *If you share code with others, do _not_ share this key* + + Returns: + HTTP status code of 200 if successful. + + Notes: + See getLastReadStatus() for other possible return values. + */ + int readMultipleFields(unsigned long channelNumber, const char * readAPIKey) + { + String readCondition = "/feeds/last.txt?status=true&location=true"; + + String multiContent = readRaw(channelNumber, readCondition, readAPIKey); + + if(getLastReadStatus() != TS_OK_SUCCESS){ + return getLastReadStatus(); + } + + this->lastFeed.nextReadField[0] = parseValues(multiContent, "field1"); + this->lastFeed.nextReadField[1] = parseValues(multiContent, "field2"); + this->lastFeed.nextReadField[2] = parseValues(multiContent, "field3"); + this->lastFeed.nextReadField[3] = parseValues(multiContent, "field4"); + this->lastFeed.nextReadField[4] = parseValues(multiContent, "field5"); + this->lastFeed.nextReadField[5] = parseValues(multiContent, "field6"); + this->lastFeed.nextReadField[6] = parseValues(multiContent, "field7"); + this->lastFeed.nextReadField[7] = parseValues(multiContent, "field8"); + this->lastFeed.nextReadCreatedAt = parseValues(multiContent, "created_at"); + this->lastFeed.nextReadLatitude = parseValues(multiContent, "latitude"); + this->lastFeed.nextReadLongitude = parseValues(multiContent, "longitude"); + this->lastFeed.nextReadElevation = parseValues(multiContent, "elevation"); + this->lastFeed.nextReadStatus = parseValues(multiContent, "status"); + + return TS_OK_SUCCESS; + } + + + /* + Function: readMultipleFields + + Summary: + Read all the field values, status message, location coordinates, and created-at timestamp associated with the latest update to a private ThingSpeak channel and store the values locally in variables within a struct. + + Parameters: + channelNumber - Channel number + readAPIKey - Read API key associated with the channel. *If you share code with others, do _not_ share this key* + + Returns: + HTTP status code of 200 if successful. + + Notes: + See getLastReadStatus() for other possible return values. + */ + int readMultipleFields(unsigned long channelNumber) + { + return readMultipleFields(channelNumber, NULL); + } + + + /* + Function: getFieldAsString + + Summary: + Fetch the value as string from the latest stored feed record. + + Parameters: + field - Field number (1-8) within the channel to read from. + + Returns: + Value read (UTF8 string), empty string if there is an error, or old value read (UTF8 string) if invoked before readMultipleFields(). Use getLastReadStatus() to get more specific information. + */ + String getFieldAsString(unsigned int field) + { + if(field < FIELDNUM_MIN || field > FIELDNUM_MAX) + { + this->lastReadStatus = TS_ERR_INVALID_FIELD_NUM; + return(""); + } + + this->lastReadStatus = TS_OK_SUCCESS; + return this->lastFeed.nextReadField[field-1]; + } + + + /* + Function: getFieldAsFloat + + Summary: + Fetch the value as float from the latest stored feed record. + + Parameters: + field - Field number (1-8) within the channel to read from. + + Returns: + Value read, 0 if the field is text or there is an error, or old value read if invoked before readMultipleFields(). Use getLastReadStatus() to get more specific information. Note that NAN, INFINITY, and -INFINITY are valid results. + */ + float getFieldAsFloat(unsigned int field) + { + return convertStringToFloat(getFieldAsString(field)); + } + + + /* + Function: getFieldAsLong + + Summary: + Fetch the value as long from the latest stored feed record. + + Parameters: + field - Field number (1-8) within the channel to read from. + + Returns: + Value read, 0 if the field is text or there is an error, or old value read if invoked before readMultipleFields(). Use getLastReadStatus() to get more specific information. + */ + long getFieldAsLong(unsigned int field) + { + // Note that although the function is called "toInt" it really returns a long. + return getFieldAsString(field).toInt(); + } + + + /* + Function: getFieldAsInt + + Summary: + Fetch the value as int from the latest stored feed record. + + Parameters: + field - Field number (1-8) within the channel to read from. + + Returns: + Value read, 0 if the field is text or there is an error, or old value read if invoked before readMultipleFields(). Use getLastReadStatus() to get more specific information. + */ + int getFieldAsInt(unsigned int field) + { + // int and long are same + return getFieldAsLong(field); + } + + + /* + Function: getStatus + + Summary: + Fetch the status message associated with the latest stored feed record. + + Results: + Value read (UTF8 string). An empty string is returned if there was no status written to the channel or in case of an error. Use getLastReadStatus() to get more specific information. + */ + String getStatus() + { + return this->lastFeed.nextReadStatus; + } + + + /* + Function: getLatitude + + Summary: + Fetch the latitude associated with the latest stored feed record. + + Results: + Value read (UTF8 string). An empty string is returned if there was no latitude written to the channel or in case of an error. Use getLastReadStatus() to get more specific information. + */ + String getLatitude() + { + return this->lastFeed.nextReadLatitude; + } + + + /* + Function: getLongitude + + Summary: + Fetch the longitude associated with the latest stored feed record. + + Results: + Value read (UTF8 string). An empty string is returned if there was no longitude written to the channel or in case of an error. Use getLastReadStatus() to get more specific information. + */ + String getLongitude() + { + return this->lastFeed.nextReadLongitude; + } + + + /* + Function: getElevation + + Summary: + Fetch the longitude associated with the latest stored feed record. + + Results: + Value read (UTF8 string). An empty string is returned if there was no elevation written to the channel or in case of an error. Use getLastReadStatus() to get more specific information. + */ + String getElevation() + { + return this->lastFeed.nextReadElevation; + } + + + /* + Function: getCreatedAt + + Summary: + Fetch the created-at timestamp associated with the latest stored feed record. + + Results: + Value read (UTF8 string). An empty string is returned if there was no created-at timestamp written to the channel or in case of an error. Use getLastReadStatus() to get more specific information. + */ + String getCreatedAt() + { + return this->lastFeed.nextReadCreatedAt; + } + #endif - return OK_SUCCESS; - }; - - float convertStringToFloat(String value) - { - // There's a bug in the AVR function strtod that it doesn't decode -INF correctly (it maps it to INF) - float result = value.toFloat(); - - if(1 == isinf(result) && *value.c_str() == '-') - { - result = (float)-INFINITY; - } - return result; - }; - - void resetWriteFields() - { - for(size_t iField = 0; iField < FIELDNUM_MAX; iField++) - { - this->nextWriteField[iField] = ""; - } - this->nextWriteLatitude = NAN; - this->nextWriteLongitude = NAN; - this->nextWriteElevation = NAN; - this->nextWriteStatus = ""; - this->nextWriteTwitter = ""; - this->nextWriteTweet = ""; - this->nextWriteCreatedAt = ""; - }; -}; - -extern ThingSpeakClass ThingSpeak; + + + /* + Function: getLastReadStatus + + Summary: + Get the status of the previous read. + + Returns: + Generally, these are HTTP status codes. Negative values indicate an error generated by the library. + Possible response codes... + 200 - OK / Success + 404 - Incorrect API key (or invalid ThingSpeak server address) + -101 - Value is out of range or string is too long (> 255 characters) + -201 - Invalid field number specified + -210 - setField() was not called before writeFields() + -301 - Failed to connect to ThingSpeak + -302 - Unexpected failure during write to ThingSpeak + -303 - Unable to parse response + -304 - Timeout waiting for server to respond + -401 - Point was not inserted (most probable cause is exceeding the rate limit) + + Notes: + The read functions will return zero or empty if there is an error. Use this function to retrieve the details. + */ + int getLastReadStatus() + { + return this->lastReadStatus; + } + + + private: + + int getWriteFieldsContentLength(){ + size_t iField; + int contentLen = 0; + + for(iField = 0; iField < FIELDNUM_MAX; iField++){ + if(this->nextWriteField[iField].length() > 0){ + contentLen = contentLen + 8 + this->nextWriteField[iField].length(); // &fieldX=[value] + + // future-proof in case ThingSpeak allows 999 fields someday + if(iField > 9){ + contentLen = contentLen + 1; + } + else if(iField > 99){ + contentLen = contentLen + 2; + } + + } + } + + if(!isnan(this->nextWriteLatitude)){ + contentLen = contentLen + 5 + String(this->nextWriteLatitude).length(); // &lat=[value] + } + + if(!isnan(this->nextWriteLongitude)){ + contentLen = contentLen + 6 + String(this->nextWriteLongitude).length(); // &long=[value] + } + + if(!isnan(this->nextWriteElevation)){ + contentLen = contentLen + 11 + String(this->nextWriteElevation).length(); // &elevation=[value] + } + + if(this->nextWriteStatus.length() > 0){ + contentLen = contentLen + 8 + this->nextWriteStatus.length(); // &status=[value] + } + + if(this->nextWriteTwitter.length() > 0){ + contentLen = contentLen + 9 + this->nextWriteTwitter.length(); // &twitter=[value] + } + + if(this->nextWriteTweet.length() > 0){ + contentLen = contentLen + 7 + this->nextWriteTweet.length(); // &tweet=[value] + } + + if(this->nextWriteCreatedAt.length() > 0){ + contentLen = contentLen + 12 + this->nextWriteCreatedAt.length(); // &created_at=[value] + } + + if(contentLen == 0){ + return 0; + } + + contentLen = contentLen + 13; // add 14 for '&headers=false', subtract 1 for missing first '&' + + return contentLen; + } + + void emptyStream(){ + while(this->client->available() > 0){ + this->client->read(); + } + } + + int finishWrite(){ + String entryIDText = String(); + int status = getHTTPResponse(entryIDText); + + emptyStream(); + + if(status != TS_OK_SUCCESS) + { + this->client->stop(); + return status; + } + long entryID = entryIDText.toInt(); + + #ifdef PRINT_DEBUG_MESSAGES + Serial.print(" Entry ID \"");Serial.print(entryIDText);Serial.print("\" (");Serial.print(entryID);Serial.println(")"); + #endif + + this->client->stop(); + + #ifdef PRINT_DEBUG_MESSAGES + Serial.println("disconnected."); + #endif + if(entryID == 0) + { + // ThingSpeak did not accept the write + status = TS_ERR_NOT_INSERTED; + } + + return status; + } + + String getJSONValueByKey(String textToSearch, String key) + { + if(textToSearch.length() == 0){ + return String(""); + } + + String searchPhrase = String("\""); + searchPhrase.concat(key); + searchPhrase.concat("\":\""); + + int fromPosition = textToSearch.indexOf(searchPhrase,0); + + if(fromPosition == -1){ + // return because there is no status or it's null + return String(""); + } + + fromPosition = fromPosition + searchPhrase.length(); + + int toPosition = textToSearch.indexOf("\"", fromPosition); + + + if(toPosition == -1){ + // return because there is no end quote + return String(""); + } + + textToSearch.remove(toPosition); + + return textToSearch.substring(fromPosition); + } + + #ifndef ARDUINO_AVR_UNO + String parseValues(String & multiContent, String key) + { + if(multiContent.length() == 0){ + return String(""); + } + + String searchPhrase = String("\""); + searchPhrase.concat(key); + searchPhrase.concat("\":\""); + + int fromPosition = multiContent.indexOf(searchPhrase,0); + + if(fromPosition == -1){ + // return because there is no status or it's null + return String(""); + } + + fromPosition = fromPosition + searchPhrase.length(); + + int toPosition = multiContent.indexOf("\"", fromPosition); + + + if(toPosition == -1){ + // return because there is no end quote + return String(""); + } + + return multiContent.substring(fromPosition, toPosition); + } + #endif + + int abortWriteRaw() + { + while(this->client->available() > 0){ + this->client->read(); + } + this->client->stop(); + resetWriteFields(); + + return TS_ERR_UNEXPECTED_FAIL; + } + + String abortReadRaw() + { + while(this->client->available() > 0){ + this->client->read(); + } + this->client->stop(); + #ifdef PRINT_DEBUG_MESSAGES + Serial.println("ReadRaw abort - disconnected."); + #endif + this->lastReadStatus = TS_ERR_UNEXPECTED_FAIL; + return String(""); + } + + void setPort(unsigned int port) + { + this->port = port; + } + + void setClient(Client * client) + { + this->client = client; + + } + + Client * client = NULL; + unsigned int port = THINGSPEAK_PORT_NUMBER; + String nextWriteField[8]; + float nextWriteLatitude; + float nextWriteLongitude; + float nextWriteElevation; + int lastReadStatus; + String nextWriteStatus; + String nextWriteTwitter; + String nextWriteTweet; + String nextWriteCreatedAt; + #ifndef ARDUINO_AVR_UNO + feed lastFeed; + #endif + + bool connectThingSpeak() + { + bool connectSuccess = false; + + #ifdef PRINT_DEBUG_MESSAGES + Serial.print(" Connect to default ThingSpeak: "); + Serial.print(THINGSPEAK_URL); + Serial.print(":"); + Serial.print(this->port); + Serial.print("..."); + #endif + + connectSuccess = client->connect(const_cast(THINGSPEAK_URL), this->port); + + #ifdef PRINT_DEBUG_MESSAGES + if (connectSuccess) + { + Serial.println("Success."); + } + else + { + Serial.println("Failed."); + } + #endif + + return connectSuccess; + } + + bool writeHTTPHeader(const char * APIKey) + { + + if (!this->client->print("Host: api.thingspeak.com\r\n")) return false; + if (!this->client->print("User-Agent: ")) return false; + if (!this->client->print(TS_USER_AGENT)) return false; + if (!this->client->print("\r\n")) return false; + if(NULL != APIKey) + { + if (!this->client->print("X-THINGSPEAKAPIKEY: ")) return false; + if (!this->client->print(APIKey)) return false; + if (!this->client->print("\r\n")) return false; + } + + return true; + } + + int getHTTPResponse(String & response) + { + // make sure all of the HTTP request is pushed out of the buffer before looking for a response + this->client->flush(); + + long timeoutTime = millis() + TIMEOUT_MS_SERVERRESPONSE; + + while(this->client-> available() < 17){ + delay(2); + if(millis() > timeoutTime){ + return TS_ERR_TIMEOUT; + } + } + + if(!this->client->find(const_cast("HTTP/1.1"))) + { + #ifdef PRINT_HTTP + Serial.println("ERROR: Didn't find HTTP/1.1"); + #endif + return TS_ERR_BAD_RESPONSE; // Couldn't parse response (didn't find HTTP/1.1) + } + + int status = this->client->parseInt(); + #ifdef PRINT_HTTP + Serial.print("Got Status of ");Serial.println(status); + #endif + if(status != TS_OK_SUCCESS) + { + return status; + } + + // Find Content-Length + if(!this->client->find(const_cast("Content-Length:"))){ + #ifdef PRINT_HTTP + Serial.println("ERROR: Didn't find Content-Length header"); + #endif + return TS_ERR_BAD_RESPONSE; // Couldn't parse response (didn't find HTTP/1.1) + } + int contentLength = this->client->parseInt(); + + #ifdef PRINT_HTTP + Serial.print("Content Length: "); + Serial.println(contentLength); + #endif + + if(!this->client->find(const_cast("\r\n\r\n"))) + { + #ifdef PRINT_HTTP + Serial.println("ERROR: Didn't find end of headers"); + #endif + return TS_ERR_BAD_RESPONSE; + } + #ifdef PRINT_HTTP + Serial.println("Found end of header"); + #endif + + timeoutTime = millis() + TIMEOUT_MS_SERVERRESPONSE; + + while(this->client->available() < contentLength){ + delay(2); + if(millis() > timeoutTime){ + return TS_ERR_TIMEOUT; + } + } + + String tempString = String(""); + char y = 0; + for(int i = 0; i < contentLength; i++){ + y = client->read(); + tempString.concat(y); + } + response = tempString; + + #ifdef PRINT_HTTP + Serial.print("Response: \"");Serial.print(response);Serial.println("\""); + #endif + + return status; + } + + + int convertFloatToChar(float value, char *valueString) + { + // Supported range is -999999000000 to 999999000000 + if(0 == isinf(value) && (value > 999999000000 || value < -999999000000)) + { + // Out of range + return TS_ERR_OUT_OF_RANGE; + } + // assume that 5 places right of decimal should be sufficient for most applications + + #if defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_SAM) + sprintf(valueString, "%.5f", value); + #else + dtostrf(value,1,5, valueString); + #endif + + return TS_OK_SUCCESS; + } + + float convertStringToFloat(String value) + { + // There's a bug in the AVR function strtod that it doesn't decode -INF correctly (it maps it to INF) + float result = value.toFloat(); + + if(1 == isinf(result) && *value.c_str() == '-') + { + result = (float)-INFINITY; + } + + return result; + } + + void resetWriteFields() + { + for(size_t iField = 0; iField < FIELDNUM_MAX; iField++) + { + this->nextWriteField[iField] = ""; + } + this->nextWriteLatitude = NAN; + this->nextWriteLongitude = NAN; + this->nextWriteElevation = NAN; + this->nextWriteStatus = ""; + this->nextWriteTwitter = ""; + this->nextWriteTweet = ""; + this->nextWriteCreatedAt = ""; + } + }; + + extern ThingSpeakClass ThingSpeak; #endif //ThingSpeak_h