From c9764bfcde0a2db58c0d1daacbf8f4955f4c2e4e Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Fri, 16 Feb 2018 17:37:28 +0100 Subject: [PATCH 01/25] Integrate ArduinoCloudThing I really dislike that I had to expose the Thing object but otherwise the addProperty() call would become terrible. I added a line on Cloud_blink example to show the composition of functions on properties. It can be safely removed in the next iteration. --- .../MKR1000_Cloud_Blink.ino | 9 +++++++++ src/ArduinoCloud.cpp | 18 ++++++++++++++++++ src/ArduinoCloudV2.h | 5 +++++ 3 files changed, 32 insertions(+) diff --git a/examples/MKR1000_Cloud_Blink/MKR1000_Cloud_Blink.ino b/examples/MKR1000_Cloud_Blink/MKR1000_Cloud_Blink.ino index 07a7deed3..fa1da60c6 100644 --- a/examples/MKR1000_Cloud_Blink/MKR1000_Cloud_Blink.ino +++ b/examples/MKR1000_Cloud_Blink/MKR1000_Cloud_Blink.ino @@ -13,6 +13,13 @@ unsigned long getTime() { return WiFi.getTime(); } +int position; + +void onPositionUpdate() { + Serial.print("New position value: "); + Serial.println(position); +} + void setup() { //Initialize serial and wait for port to open: Serial.begin(9600); @@ -57,6 +64,8 @@ void setup() { Serial.println("Successfully connected to Arduino Cloud :)"); + ArduinoCloud.Thing.addProperty(position, READ).publishEvery(10*SECONDS).onUpdate(onPositionUpdate); + CloudSerial.begin(9600); } diff --git a/src/ArduinoCloud.cpp b/src/ArduinoCloud.cpp index dddf3683d..0e4b1d82c 100644 --- a/src/ArduinoCloud.cpp +++ b/src/ArduinoCloud.cpp @@ -61,8 +61,13 @@ int ArduinoCloudClass::begin(Client& net) _mqttClient.onMessageAdvanced(ArduinoCloudClass::onMessage); _mqttClient.begin(server, 8883, *_bearSslClient); + _id = id; + + Thing.begin(); + _stdoutTopic = "$aws/things/" + _id + "/stdout"; _stdinTopic = "$aws/things/" + _id + "/stdin"; + _dataTopic = "$aws/things/" + _id + "/data"; return 1; } @@ -81,6 +86,11 @@ int ArduinoCloudClass::connect() void ArduinoCloudClass::poll() { _mqttClient.loop(); + uint8_t data[1024]; + int length = Thing.poll(data); + if (length) { + writeProperties(data, length); + } } void ArduinoCloudClass::onGetTime(unsigned long(*callback)(void)) @@ -93,6 +103,11 @@ int ArduinoCloudClass::connected() return _mqttClient.connected(); } +int ArduinoCloudClass::writeProperties(const byte data[], int length) +{ + return _mqttClient.publish(_dataTopic.c_str(), (const char*)data, length); +} + int ArduinoCloudClass::writeStdout(const byte data[], int length) { return _mqttClient.publish(_stdoutTopic.c_str(), (const char*)data, length); @@ -108,6 +123,9 @@ void ArduinoCloudClass::handleMessage(char topic[], char bytes[], int length) if (_stdinTopic == topic) { CloudSerial.appendStdin((uint8_t*)bytes, length); } + if (_dataTopic == topic) { + Thing.decode((uint8_t*)bytes, length); + } } ArduinoCloudClass ArduinoCloud; diff --git a/src/ArduinoCloudV2.h b/src/ArduinoCloudV2.h index 6a592565f..2d84d783e 100644 --- a/src/ArduinoCloudV2.h +++ b/src/ArduinoCloudV2.h @@ -3,6 +3,7 @@ #include #include +#include #include "CloudSerial.h" @@ -22,9 +23,12 @@ class ArduinoCloudClass { int connected(); + ArduinoCloudThing Thing; + protected: friend class CloudSerialClass; int writeStdout(const byte data[], int length); + int writeProperties(const byte data[], int length); private: static void onMessage(MQTTClient *client, char topic[], char bytes[], int length); @@ -38,6 +42,7 @@ class ArduinoCloudClass { String _stdinTopic; String _stdoutTopic; + String _dataTopic; }; From 4a52413e9ee99cd9349cbcf62bbf9f8033679acd Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Thu, 22 Feb 2018 16:03:55 +0100 Subject: [PATCH 02/25] Fix .readOnly/.writeOnly compisition --- examples/MKR1000_Cloud_Blink/MKR1000_Cloud_Blink.ino | 2 +- src/ArduinoCloud.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/MKR1000_Cloud_Blink/MKR1000_Cloud_Blink.ino b/examples/MKR1000_Cloud_Blink/MKR1000_Cloud_Blink.ino index fa1da60c6..cf0c72901 100644 --- a/examples/MKR1000_Cloud_Blink/MKR1000_Cloud_Blink.ino +++ b/examples/MKR1000_Cloud_Blink/MKR1000_Cloud_Blink.ino @@ -64,7 +64,7 @@ void setup() { Serial.println("Successfully connected to Arduino Cloud :)"); - ArduinoCloud.Thing.addProperty(position, READ).publishEvery(10*SECONDS).onUpdate(onPositionUpdate); + ArduinoCloud.Thing.addProperty(position).publishEvery(10*SECONDS).onUpdate(onPositionUpdate).readOnly(); CloudSerial.begin(9600); } diff --git a/src/ArduinoCloud.cpp b/src/ArduinoCloud.cpp index 0e4b1d82c..5745d088c 100644 --- a/src/ArduinoCloud.cpp +++ b/src/ArduinoCloud.cpp @@ -79,6 +79,7 @@ int ArduinoCloudClass::connect() } _mqttClient.subscribe(_stdinTopic); + _mqttClient.subscribe(_dataTopic); return 1; } From e626ea786a30c52aeb2036ef5e93d187d13b0c91 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Wed, 30 May 2018 15:51:40 +0200 Subject: [PATCH 03/25] Add addProperty API with complete signature --- examples/MKR1000_Cloud_Blink/MKR1000_Cloud_Blink.ino | 2 +- src/ArduinoCloudV2.h | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/examples/MKR1000_Cloud_Blink/MKR1000_Cloud_Blink.ino b/examples/MKR1000_Cloud_Blink/MKR1000_Cloud_Blink.ino index cf0c72901..96590c9a0 100644 --- a/examples/MKR1000_Cloud_Blink/MKR1000_Cloud_Blink.ino +++ b/examples/MKR1000_Cloud_Blink/MKR1000_Cloud_Blink.ino @@ -64,7 +64,7 @@ void setup() { Serial.println("Successfully connected to Arduino Cloud :)"); - ArduinoCloud.Thing.addProperty(position).publishEvery(10*SECONDS).onUpdate(onPositionUpdate).readOnly(); + ArduinoCloud.addProperty(position, READ, 10*SECONDS, onPositionUpdate); CloudSerial.begin(9600); } diff --git a/src/ArduinoCloudV2.h b/src/ArduinoCloudV2.h index 2d84d783e..68bbf8390 100644 --- a/src/ArduinoCloudV2.h +++ b/src/ArduinoCloudV2.h @@ -23,7 +23,12 @@ class ArduinoCloudClass { int connected(); - ArduinoCloudThing Thing; + #define addPropertyMacro(prop) addPropertyReal(prop, #prop) + #undef addProperty + + template void addProperty(T property, permissionType _permission = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL) { + Thing.addPropertyMacro(property).publishEvery(seconds).setPermission(_permission).onUpdate(fn); + } protected: friend class CloudSerialClass; @@ -37,6 +42,7 @@ class ArduinoCloudClass { private: String _id; + ArduinoCloudThing Thing; BearSSLClient* _bearSslClient; MQTTClient _mqttClient; From f5f43993d6b2d8a088b219739b505728e6ce61c4 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Wed, 30 May 2018 15:51:53 +0200 Subject: [PATCH 04/25] Initial testing on OTA --- src/ArduinoCloud.cpp | 26 ++++++++++++++++++++++++++ src/ArduinoCloudV2.h | 3 +++ 2 files changed, 29 insertions(+) diff --git a/src/ArduinoCloud.cpp b/src/ArduinoCloud.cpp index 5745d088c..4249726fa 100644 --- a/src/ArduinoCloud.cpp +++ b/src/ArduinoCloud.cpp @@ -2,6 +2,8 @@ #include "utility/ECCX08Cert.h" #include "CloudSerial.h" +#include "SerialFlashStorage.h" +//#include "SFU.h" #include "ArduinoCloudV2.h" @@ -14,6 +16,7 @@ const static int thingIdSlot = 12; ArduinoCloudClass::ArduinoCloudClass() : _bearSslClient(NULL), + _otaClient(NULL), _mqttClient(256) { } @@ -23,6 +26,9 @@ ArduinoCloudClass::~ArduinoCloudClass() if (_bearSslClient) { delete _bearSslClient; } + if (_otaClient) { + delete _otaClient; + } } int ArduinoCloudClass::begin(Client& net) @@ -65,9 +71,12 @@ int ArduinoCloudClass::begin(Client& net) Thing.begin(); + _otaClient = new HttpClient(net, server, 80); + _stdoutTopic = "$aws/things/" + _id + "/stdout"; _stdinTopic = "$aws/things/" + _id + "/stdin"; _dataTopic = "$aws/things/" + _id + "/data"; + _otaTopic = "$aws/things/" + _id + "/upload"; return 1; } @@ -80,6 +89,7 @@ int ArduinoCloudClass::connect() _mqttClient.subscribe(_stdinTopic); _mqttClient.subscribe(_dataTopic); + _mqttClient.subscribe(_otaTopic); return 1; } @@ -127,6 +137,22 @@ void ArduinoCloudClass::handleMessage(char topic[], char bytes[], int length) if (_dataTopic == topic) { Thing.decode((uint8_t*)bytes, length); } + if (_otaTopic == topic) { + + String url = String(bytes); + + _otaClient->get(url); + + SerialFlashStorage.open(_otaClient->contentLength()); + uint8_t buf[1024]; + while (_otaClient->available()) { + int size = _otaClient->available() >= 1024 ? 1024 : _otaClient->available(); + _otaClient->read(buf, size); + SerialFlashStorage.write((uint8_t*)buf, size); + } + SerialFlashStorage.close(); + SerialFlashStorage.apply(); + } } ArduinoCloudClass ArduinoCloud; diff --git a/src/ArduinoCloudV2.h b/src/ArduinoCloudV2.h index 68bbf8390..6f7517a49 100644 --- a/src/ArduinoCloudV2.h +++ b/src/ArduinoCloudV2.h @@ -4,6 +4,7 @@ #include #include #include +#include #include "CloudSerial.h" @@ -45,10 +46,12 @@ class ArduinoCloudClass { ArduinoCloudThing Thing; BearSSLClient* _bearSslClient; MQTTClient _mqttClient; + HttpClient* _otaClient; String _stdinTopic; String _stdoutTopic; String _dataTopic; + String _otaTopic; }; From ba530014c8419ded29abf8fef1f26259faa443cd Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Wed, 30 May 2018 18:36:54 +0200 Subject: [PATCH 05/25] Port to fixed ArduinoCloudThing --- src/ArduinoCloud.cpp | 2 -- src/ArduinoCloudV2.h | 7 ++----- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/ArduinoCloud.cpp b/src/ArduinoCloud.cpp index 4249726fa..05b339e86 100644 --- a/src/ArduinoCloud.cpp +++ b/src/ArduinoCloud.cpp @@ -67,8 +67,6 @@ int ArduinoCloudClass::begin(Client& net) _mqttClient.onMessageAdvanced(ArduinoCloudClass::onMessage); _mqttClient.begin(server, 8883, *_bearSslClient); - _id = id; - Thing.begin(); _otaClient = new HttpClient(net, server, 80); diff --git a/src/ArduinoCloudV2.h b/src/ArduinoCloudV2.h index 6f7517a49..65f166df4 100644 --- a/src/ArduinoCloudV2.h +++ b/src/ArduinoCloudV2.h @@ -24,11 +24,8 @@ class ArduinoCloudClass { int connected(); - #define addPropertyMacro(prop) addPropertyReal(prop, #prop) - #undef addProperty - template void addProperty(T property, permissionType _permission = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL) { - Thing.addPropertyMacro(property).publishEvery(seconds).setPermission(_permission).onUpdate(fn); + Thing.addProperty(property).publishEvery(seconds).setPermission(_permission).onUpdate(fn); } protected: @@ -45,8 +42,8 @@ class ArduinoCloudClass { String _id; ArduinoCloudThing Thing; BearSSLClient* _bearSslClient; - MQTTClient _mqttClient; HttpClient* _otaClient; + MQTTClient _mqttClient; String _stdinTopic; String _stdoutTopic; From cb76f6f0f0d5f613e0b1bced7287b99cd187ba11 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Thu, 7 Jun 2018 18:37:22 +0200 Subject: [PATCH 06/25] Add missing libraries --- src/ArduinoCloud.cpp | 2 +- src/OTAStorage.h | 35 +++++++++++++++++++ src/SerialFlashStorage.cpp | 69 ++++++++++++++++++++++++++++++++++++++ src/SerialFlashStorage.h | 43 ++++++++++++++++++++++++ 4 files changed, 148 insertions(+), 1 deletion(-) create mode 100644 src/OTAStorage.h create mode 100644 src/SerialFlashStorage.cpp create mode 100644 src/SerialFlashStorage.h diff --git a/src/ArduinoCloud.cpp b/src/ArduinoCloud.cpp index 05b339e86..5f8c7ba75 100644 --- a/src/ArduinoCloud.cpp +++ b/src/ArduinoCloud.cpp @@ -3,7 +3,7 @@ #include "utility/ECCX08Cert.h" #include "CloudSerial.h" #include "SerialFlashStorage.h" -//#include "SFU.h" +#include "SFU.h" #include "ArduinoCloudV2.h" diff --git a/src/OTAStorage.h b/src/OTAStorage.h new file mode 100644 index 000000000..0f96e2b3f --- /dev/null +++ b/src/OTAStorage.h @@ -0,0 +1,35 @@ +/* + Copyright (c) 2017 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _OTA_STORAGE_H_INCLUDED +#define _OTA_STORAGE_H_INCLUDED + +class OTAStorage { +public: + virtual int open(int length) = 0; + virtual size_t write(uint8_t* data, size_t size) = 0; + virtual void close() = 0; + virtual void clear() = 0; + virtual void apply() = 0; + + virtual long maxSize() { + return ((256 * 1024) - 0x2000); + } +}; + +#endif diff --git a/src/SerialFlashStorage.cpp b/src/SerialFlashStorage.cpp new file mode 100644 index 000000000..432b7c7b6 --- /dev/null +++ b/src/SerialFlashStorage.cpp @@ -0,0 +1,69 @@ +/* + Copyright (c) 2017 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "SerialFlashStorage.h" + +#define UPDATE_FILE "UPDATE.BIN" + +int SerialFlashStorageClass::open(int contentLength) +{ + if (!SerialFlash.begin(SERIAL_FLASH_CS)) { + return 0; + } + + while (!SerialFlash.ready()) {} + + if (SerialFlash.exists(UPDATE_FILE)) { + SerialFlash.remove(UPDATE_FILE); + } + + if (SerialFlash.create(UPDATE_FILE, contentLength)) { + _file = SerialFlash.open(UPDATE_FILE); + } + + if (!_file) { + return 0; + } + + return 1; +} + +size_t SerialFlashStorageClass::write(uint8_t *data, size_t size) +{ + while (!SerialFlash.ready()) {} + int ret = _file.write(data, size); + return ret; +} + +void SerialFlashStorageClass::close() +{ + _file.close(); +} + +void SerialFlashStorageClass::clear() +{ + SerialFlash.remove(UPDATE_FILE); +} + +void SerialFlashStorageClass::apply() +{ + // just reset, SDU copies the data to flash + NVIC_SystemReset(); +} + +SerialFlashStorageClass SerialFlashStorage; diff --git a/src/SerialFlashStorage.h b/src/SerialFlashStorage.h new file mode 100644 index 000000000..4409969f5 --- /dev/null +++ b/src/SerialFlashStorage.h @@ -0,0 +1,43 @@ +/* + Copyright (c) 2017 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _SERIALFLASH_STORAGE_H_INCLUDED +#define _SERIALFLASH_STORAGE_H_INCLUDED + +#include + +#include "OTAStorage.h" + +#define SERIAL_FLASH_BUFFER_SIZE 64 +#define SERIAL_FLASH_CS 5 + +class SerialFlashStorageClass : public OTAStorage { +public: + virtual int open(int length); + virtual size_t write(uint8_t* data, size_t size); + virtual void close(); + virtual void clear(); + virtual void apply(); + +private: + SerialFlashFile _file; +}; + +extern SerialFlashStorageClass SerialFlashStorage; + +#endif From 8bf9cbc85a80ca5b5cc7b351c3d1a52636091558 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Wed, 27 Jun 2018 23:56:39 +0200 Subject: [PATCH 07/25] Fix addProperty macro, again --- src/ArduinoCloudV2.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ArduinoCloudV2.h b/src/ArduinoCloudV2.h index 65f166df4..03c8d99be 100644 --- a/src/ArduinoCloudV2.h +++ b/src/ArduinoCloudV2.h @@ -24,8 +24,10 @@ class ArduinoCloudClass { int connected(); - template void addProperty(T property, permissionType _permission = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL) { - Thing.addProperty(property).publishEvery(seconds).setPermission(_permission).onUpdate(fn); + #define addProperty( v, ...) addPropertyReal(v, #v, __VA_ARGS__) + + template void addPropertyReal(T property, String name, permissionType _permission = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL) { + Thing.addPropertyReal(property, name).publishEvery(seconds).setPermission(_permission).onUpdate(fn); } protected: From fcffb1bce865293efce5094ad8f82e837b764285 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Thu, 28 Jun 2018 00:46:15 +0200 Subject: [PATCH 08/25] Fix reference as value in addProperty signature --- src/ArduinoCloud.cpp | 4 ++-- src/ArduinoCloudV2.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ArduinoCloud.cpp b/src/ArduinoCloud.cpp index 5f8c7ba75..626c43685 100644 --- a/src/ArduinoCloud.cpp +++ b/src/ArduinoCloud.cpp @@ -97,8 +97,8 @@ void ArduinoCloudClass::poll() _mqttClient.loop(); uint8_t data[1024]; int length = Thing.poll(data); - if (length) { - writeProperties(data, length); + if (length > 0) { + writeProperties(data, length); } } diff --git a/src/ArduinoCloudV2.h b/src/ArduinoCloudV2.h index 03c8d99be..4f08a6cec 100644 --- a/src/ArduinoCloudV2.h +++ b/src/ArduinoCloudV2.h @@ -26,7 +26,7 @@ class ArduinoCloudClass { #define addProperty( v, ...) addPropertyReal(v, #v, __VA_ARGS__) - template void addPropertyReal(T property, String name, permissionType _permission = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL) { + template void addPropertyReal(T& property, String name, permissionType _permission = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL) { Thing.addPropertyReal(property, name).publishEvery(seconds).setPermission(_permission).onUpdate(fn); } From 8f6964de5256aff0355fd0f985091168f02c0fdd Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Thu, 28 Jun 2018 00:59:01 +0200 Subject: [PATCH 09/25] Call THing.poll with the new API --- src/ArduinoCloud.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ArduinoCloud.cpp b/src/ArduinoCloud.cpp index 626c43685..36574b697 100644 --- a/src/ArduinoCloud.cpp +++ b/src/ArduinoCloud.cpp @@ -96,7 +96,7 @@ void ArduinoCloudClass::poll() { _mqttClient.loop(); uint8_t data[1024]; - int length = Thing.poll(data); + int length = Thing.poll(data, sizeof(data)); if (length > 0) { writeProperties(data, length); } From c1c2f43b9e1f78980c163a4fec559ce154171136 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Tue, 3 Jul 2018 11:55:58 +0200 Subject: [PATCH 10/25] TEMP: remove OTA stuff --- src/ArduinoCloud.cpp | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/src/ArduinoCloud.cpp b/src/ArduinoCloud.cpp index 36574b697..0cc95094e 100644 --- a/src/ArduinoCloud.cpp +++ b/src/ArduinoCloud.cpp @@ -2,8 +2,6 @@ #include "utility/ECCX08Cert.h" #include "CloudSerial.h" -#include "SerialFlashStorage.h" -#include "SFU.h" #include "ArduinoCloudV2.h" @@ -16,7 +14,6 @@ const static int thingIdSlot = 12; ArduinoCloudClass::ArduinoCloudClass() : _bearSslClient(NULL), - _otaClient(NULL), _mqttClient(256) { } @@ -26,9 +23,6 @@ ArduinoCloudClass::~ArduinoCloudClass() if (_bearSslClient) { delete _bearSslClient; } - if (_otaClient) { - delete _otaClient; - } } int ArduinoCloudClass::begin(Client& net) @@ -69,12 +63,9 @@ int ArduinoCloudClass::begin(Client& net) Thing.begin(); - _otaClient = new HttpClient(net, server, 80); - _stdoutTopic = "$aws/things/" + _id + "/stdout"; _stdinTopic = "$aws/things/" + _id + "/stdin"; _dataTopic = "$aws/things/" + _id + "/data"; - _otaTopic = "$aws/things/" + _id + "/upload"; return 1; } @@ -87,7 +78,6 @@ int ArduinoCloudClass::connect() _mqttClient.subscribe(_stdinTopic); _mqttClient.subscribe(_dataTopic); - _mqttClient.subscribe(_otaTopic); return 1; } @@ -135,22 +125,6 @@ void ArduinoCloudClass::handleMessage(char topic[], char bytes[], int length) if (_dataTopic == topic) { Thing.decode((uint8_t*)bytes, length); } - if (_otaTopic == topic) { - - String url = String(bytes); - - _otaClient->get(url); - - SerialFlashStorage.open(_otaClient->contentLength()); - uint8_t buf[1024]; - while (_otaClient->available()) { - int size = _otaClient->available() >= 1024 ? 1024 : _otaClient->available(); - _otaClient->read(buf, size); - SerialFlashStorage.write((uint8_t*)buf, size); - } - SerialFlashStorage.close(); - SerialFlashStorage.apply(); - } } ArduinoCloudClass ArduinoCloud; From 62d2ffe73e9c891f6535ccd8a447fdd913b3cb1e Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Tue, 3 Jul 2018 11:56:29 +0200 Subject: [PATCH 11/25] Add minDelta API and a bunch of overloaded not clashing calls --- src/ArduinoCloudV2.h | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/ArduinoCloudV2.h b/src/ArduinoCloudV2.h index 4f08a6cec..5f1f71479 100644 --- a/src/ArduinoCloudV2.h +++ b/src/ArduinoCloudV2.h @@ -26,8 +26,16 @@ class ArduinoCloudClass { #define addProperty( v, ...) addPropertyReal(v, #v, __VA_ARGS__) - template void addPropertyReal(T& property, String name, permissionType _permission = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL) { - Thing.addPropertyReal(property, name).publishEvery(seconds).setPermission(_permission).onUpdate(fn); + template void addPropertyReal(T& property, String name, permissionType _permission = READWRITE, long seconds = ON_CHANGE, T minDelta = 0, void(*fn)(void) = NULL) { + Thing.addPropertyReal(property, name).publishEvery(seconds).setPermission(_permission).onUpdate(fn).minimumDelta(&minDelta); + } + + template void addPropertyReal(T& property, String name, permissionType _permission = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, T minDelta = 0) { + Thing.addPropertyReal(property, name).publishEvery(seconds).setPermission(_permission).onUpdate(fn).minimumDelta(&minDelta); + } + + template void addPropertyReal(T& property, String name, permissionType _permission = READWRITE, void(*fn)(void) = NULL, long seconds = ON_CHANGE, T minDelta = 0) { + Thing.addPropertyReal(property, name).publishEvery(seconds).setPermission(_permission).onUpdate(fn).minimumDelta(&minDelta); } protected: From bf25568f85284f8c1dc5e0c5ff388a9a06fb4c20 Mon Sep 17 00:00:00 2001 From: Simone Marchisio Date: Mon, 6 Aug 2018 14:34:59 +0200 Subject: [PATCH 12/25] work in progress, no secure communication --- src/ArduinoCloud.cpp | 57 ++++++++++++++++++++++------------ src/ArduinoCloudV2.h | 73 +++++++++++++++++++++++--------------------- 2 files changed, 77 insertions(+), 53 deletions(-) diff --git a/src/ArduinoCloud.cpp b/src/ArduinoCloud.cpp index 0cc95094e..7aa30f0cf 100644 --- a/src/ArduinoCloud.cpp +++ b/src/ArduinoCloud.cpp @@ -1,11 +1,10 @@ -#include - -#include "utility/ECCX08Cert.h" -#include "CloudSerial.h" #include "ArduinoCloudV2.h" +#include +#include +#include "CloudSerial.h" -const static char server[] = "a19g5nbe27wn47.iot.us-east-1.amazonaws.com"; //"xxxxxxxxxxxxxx.iot.xx-xxxx-x.amazonaws.com"; +const static char server[] = "broker.shiftr.io"; //"a19g5nbe27wn47.iot.us-east-1.amazonaws.com"; //"xxxxxxxxxxxxxx.iot.xx-xxxx-x.amazonaws.com"; const static int keySlot = 0; const static int compressedCertSlot = 10; @@ -14,6 +13,7 @@ const static int thingIdSlot = 12; ArduinoCloudClass::ArduinoCloudClass() : _bearSslClient(NULL), + // Size of the receive buffer _mqttClient(256) { } @@ -28,7 +28,8 @@ ArduinoCloudClass::~ArduinoCloudClass() int ArduinoCloudClass::begin(Client& net) { byte thingIdBytes[72]; - + + /* if (!ECCX08.begin()) { return 0; } @@ -57,27 +58,45 @@ int ArduinoCloudClass::begin(Client& net) } _bearSslClient = new BearSSLClient(net); _bearSslClient->setEccSlot(keySlot, ECCX08Cert.bytes(), ECCX08Cert.length()); - +*/ + //END of TLS communication part. The result of that part is *_bearSslClient [Network Client] + + + // MQTT topics definition + _id = "XXX"; + + _stdoutTopic = "/a/d/" + _id + "/s/o"; + _stdinTopic = "/a/d/" + _id + "/s/i"; + _dataTopicIn = "/a/d/" + _id + "/e/i"; + _dataTopicOut = "/a/d/" + _id + "/e/o"; + + // use onMessage as callback for received mqtt messages _mqttClient.onMessageAdvanced(ArduinoCloudClass::onMessage); - _mqttClient.begin(server, 8883, *_bearSslClient); - + //_mqttClient.begin(server, 8883, *_bearSslClient); + _mqttClient.begin(server, 1883, net); + // Set will for MQTT client: {topic, qos, retain message} + const char lastMessage[] = "abcb"; + _mqttClient.setWill(_dataTopicOut.c_str(), lastMessage, false, 1); + // Set MQTT broker connection options + _mqttClient.setOptions(120, false, 1000); + + // Thing initialization Thing.begin(); - _stdoutTopic = "$aws/things/" + _id + "/stdout"; - _stdinTopic = "$aws/things/" + _id + "/stdin"; - _dataTopic = "$aws/things/" + _id + "/data"; - return 1; } int ArduinoCloudClass::connect() { - if (!_mqttClient.connect(_id.c_str())) { + //TODO MQTT brocker connection + // Username: device id + // Password: empty + if (!_mqttClient.connect(_id.c_str(), "try", "try")) { return 0; } _mqttClient.subscribe(_stdinTopic); - _mqttClient.subscribe(_dataTopic); + _mqttClient.subscribe(_dataTopicIn); return 1; } @@ -104,7 +123,7 @@ int ArduinoCloudClass::connected() int ArduinoCloudClass::writeProperties(const byte data[], int length) { - return _mqttClient.publish(_dataTopic.c_str(), (const char*)data, length); + return _mqttClient.publish(_dataTopicOut.c_str(), (const char*)data, length); } int ArduinoCloudClass::writeStdout(const byte data[], int length) @@ -119,10 +138,10 @@ void ArduinoCloudClass::onMessage(MQTTClient* /*client*/, char topic[], char byt void ArduinoCloudClass::handleMessage(char topic[], char bytes[], int length) { - if (_stdinTopic == topic) { + if (strcmp(_stdinTopic.c_str(), topic) == 0) { CloudSerial.appendStdin((uint8_t*)bytes, length); - } - if (_dataTopic == topic) { + } + if (strcmp(_dataTopicIn.c_str(), topic) == 0) { Thing.decode((uint8_t*)bytes, length); } } diff --git a/src/ArduinoCloudV2.h b/src/ArduinoCloudV2.h index 5f1f71479..23ad21aff 100644 --- a/src/ArduinoCloudV2.h +++ b/src/ArduinoCloudV2.h @@ -11,57 +11,62 @@ class ArduinoCloudClass { public: - ArduinoCloudClass(); - ~ArduinoCloudClass(); + ArduinoCloudClass(); + ~ArduinoCloudClass(); - int begin(Client& net); + int begin(Client& net); - int connect(); + int connect(); - void poll(); + void poll(); - void onGetTime(unsigned long(*)(void)); + void onGetTime(unsigned long(*)(void)); - int connected(); + int connected(); - #define addProperty( v, ...) addPropertyReal(v, #v, __VA_ARGS__) + #define addProperty( v, ...) addPropertyReal(v, #v, __VA_ARGS__) - template void addPropertyReal(T& property, String name, permissionType _permission = READWRITE, long seconds = ON_CHANGE, T minDelta = 0, void(*fn)(void) = NULL) { - Thing.addPropertyReal(property, name).publishEvery(seconds).setPermission(_permission).onUpdate(fn).minimumDelta(&minDelta); - } + template void addPropertyReal(T& property, String name, permissionType _permission = READWRITE, long seconds = ON_CHANGE, T minDelta = 0, void(*fn)(void) = NULL) { + Thing.addPropertyReal(property, name).publishEvery(seconds).setPermission(_permission).onUpdate(fn).minimumDelta(&minDelta); + } - template void addPropertyReal(T& property, String name, permissionType _permission = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, T minDelta = 0) { - Thing.addPropertyReal(property, name).publishEvery(seconds).setPermission(_permission).onUpdate(fn).minimumDelta(&minDelta); - } + void addPropertyReal(String& property, String name, permissionType _permission = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0) { + Thing.addPropertyReal(property, name).publishEvery(seconds).setPermission(_permission).onUpdate(fn); + } - template void addPropertyReal(T& property, String name, permissionType _permission = READWRITE, void(*fn)(void) = NULL, long seconds = ON_CHANGE, T minDelta = 0) { - Thing.addPropertyReal(property, name).publishEvery(seconds).setPermission(_permission).onUpdate(fn).minimumDelta(&minDelta); - } + template void addPropertyReal(T& property, String name, permissionType _permission = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, T minDelta = 0) { + Thing.addPropertyReal(property, name).publishEvery(seconds).setPermission(_permission).onUpdate(fn).minimumDelta(&minDelta); + } -protected: - friend class CloudSerialClass; - int writeStdout(const byte data[], int length); - int writeProperties(const byte data[], int length); + template void addPropertyReal(T& property, String name, permissionType _permission = READWRITE, void(*fn)(void) = NULL, long seconds = ON_CHANGE, T minDelta = 0) { + Thing.addPropertyReal(property, name).publishEvery(seconds).setPermission(_permission).onUpdate(fn).minimumDelta(&minDelta); + } + + protected: + friend class CloudSerialClass; + int writeStdout(const byte data[], int length); + int writeProperties(const byte data[], int length); private: - static void onMessage(MQTTClient *client, char topic[], char bytes[], int length); + static void onMessage(MQTTClient *client, char topic[], char bytes[], int length); - void handleMessage(char topic[], char bytes[], int length); + void handleMessage(char topic[], char bytes[], int length); private: - String _id; - ArduinoCloudThing Thing; - BearSSLClient* _bearSslClient; - HttpClient* _otaClient; - MQTTClient _mqttClient; - - String _stdinTopic; - String _stdoutTopic; - String _dataTopic; - String _otaTopic; + String _id; + ArduinoCloudThing Thing; + BearSSLClient* _bearSslClient; + HttpClient* _otaClient; + MQTTClient _mqttClient; + + // Class attribute to define MTTQ topics 2 for stdIn/out and 2 for data, in order to avoid getting previous pupblished payload + String _stdinTopic; + String _stdoutTopic; + String _dataTopicIn; + String _dataTopicOut; + String _otaTopic; }; - extern ArduinoCloudClass ArduinoCloud; #endif From 48c3ba8ad85648f170f48915a252aca8c98d0669 Mon Sep 17 00:00:00 2001 From: Simone Marchisio Date: Thu, 9 Aug 2018 12:10:57 +0200 Subject: [PATCH 13/25] Reconnection ok! --- src/ArduinoCloud.cpp | 89 ++++++++++++++++++++++++++++++++++++-------- src/ArduinoCloudV2.h | 31 +++++++++++---- 2 files changed, 98 insertions(+), 22 deletions(-) diff --git a/src/ArduinoCloud.cpp b/src/ArduinoCloud.cpp index 7aa30f0cf..7dd0a94a0 100644 --- a/src/ArduinoCloud.cpp +++ b/src/ArduinoCloud.cpp @@ -1,6 +1,6 @@ #include "ArduinoCloudV2.h" -#include +#include #include #include "CloudSerial.h" @@ -14,7 +14,7 @@ const static int thingIdSlot = 12; ArduinoCloudClass::ArduinoCloudClass() : _bearSslClient(NULL), // Size of the receive buffer - _mqttClient(256) + _mqttClient(MQTT_BUFFER_SIZE) { } @@ -28,8 +28,7 @@ ArduinoCloudClass::~ArduinoCloudClass() int ArduinoCloudClass::begin(Client& net) { byte thingIdBytes[72]; - - /* +/* if (!ECCX08.begin()) { return 0; } @@ -61,7 +60,17 @@ int ArduinoCloudClass::begin(Client& net) */ //END of TLS communication part. The result of that part is *_bearSslClient [Network Client] - + // Begin function for the MQTTClient + mqttClientBegin(net); + // Thing initialization + Thing.begin(); + + return 1; +} + +// private class method used to initialize mqttClient class member. (called in the begin class method) +void ArduinoCloudClass::mqttClientBegin(Client& net) +{ // MQTT topics definition _id = "XXX"; @@ -77,13 +86,8 @@ int ArduinoCloudClass::begin(Client& net) // Set will for MQTT client: {topic, qos, retain message} const char lastMessage[] = "abcb"; _mqttClient.setWill(_dataTopicOut.c_str(), lastMessage, false, 1); - // Set MQTT broker connection options - _mqttClient.setOptions(120, false, 1000); - - // Thing initialization - Thing.begin(); - - return 1; + // Set MQTT connection options + _mqttClient.setOptions(mqttOpt.keepAlive, mqttOpt.cleanSession, mqttOpt.timeout); } int ArduinoCloudClass::connect() @@ -94,7 +98,6 @@ int ArduinoCloudClass::connect() if (!_mqttClient.connect(_id.c_str(), "try", "try")) { return 0; } - _mqttClient.subscribe(_stdinTopic); _mqttClient.subscribe(_dataTopicIn); @@ -103,14 +106,70 @@ int ArduinoCloudClass::connect() void ArduinoCloudClass::poll() { + // If user call poll() without parameters use the default ones + poll(MAX_RETRIES, RECONNECTION_TIMEOUT); +} + +bool ArduinoCloudClass::mqttReconnect(int maxRetries, int timeout) +{ + // Counter for reconnection retries + int retries = 0; + + // Check for MQTT broker connection, of if maxReties limit is reached + // if MQTTClient is connected , simply do nothing and retun true + while(!_mqttClient.connected() && retries++ < maxRetries) { + + // Get last MTTQClient error, (a common error may be a buffer overflow) + lwmqtt_err_t err = _mqttClient.lastError(); + + // try establish the MQTT broker connection + connect(); + // delay eventually used for the nex re-connection try + delay(timeout); + } + + // It was impossible to establish a connection, return + if (retries == maxRetries) + return false; + + return true; +} + +void ArduinoCloudClass::poll(int reconnectionMaxRetries, int reconnectionTimeoutMs) +{ + // Method's argument controls + int maxRetries = (reconnectionMaxRetries > 0) ? reconnectionMaxRetries : MAX_RETRIES; + int timeout = (reconnectionTimeoutMs > 0) ? reconnectionTimeoutMs : RECONNECTION_TIMEOUT; + + // If something has to be read from the network (prop with Write permission), perform reconnection now + if(!Thing.hasAllReadProperties()) { + // If the reconnect() culd not establish the connection, return the control to the user sketch + if (!mqttReconnect(maxRetries, timeout)) + return; + } + + // MTTQClient connected!, poll() used to retrieve data from MQTT broker _mqttClient.loop(); - uint8_t data[1024]; + + uint8_t data[MQTT_BUFFER_SIZE]; int length = Thing.poll(data, sizeof(data)); + // Are there some read properties that must be sent to the cloud ?? if (length > 0) { - writeProperties(data, length); + // Check the connection is ok! if not reconnect + // If a thing has all read properties only try to reconnect when the have to be sent(based on their update policy) + if(mqttReconnect(maxRetries, timeout)) { + writeProperties(data, length); + } } } +void ArduinoCloudClass::reconnect(Client& net) +{ + // Initialize again the MQTTClient, otherwise it would not be able to receive messages through its callback + mqttClientBegin(net); + connect(); +} + void ArduinoCloudClass::onGetTime(unsigned long(*callback)(void)) { ArduinoBearSSL.onGetTime(callback); diff --git a/src/ArduinoCloudV2.h b/src/ArduinoCloudV2.h index 23ad21aff..5bc054847 100644 --- a/src/ArduinoCloudV2.h +++ b/src/ArduinoCloudV2.h @@ -8,21 +8,36 @@ #include "CloudSerial.h" +// Declaration of the struct for the mqtt connection options +typedef struct mqtt_opt{ + int keepAlive; + bool cleanSession; + int timeout; +} mqttConnectionOptions; + class ArduinoCloudClass { public: ArduinoCloudClass(); ~ArduinoCloudClass(); - int begin(Client& net); + // Class constant declaration + static const int MQTT_BUFFER_SIZE = 256; + static const int MAX_RETRIES = 5; + static const int RECONNECTION_TIMEOUT = 2000; + const mqttConnectionOptions mqttOpt = {120, false, 1000}; + int begin(Client& net); int connect(); - void poll(); - + // defined for users who want to specify max reconnections reties and timeout between them + void poll(int reconnectionMaxRetries, int reconnectionTimeoutMs); + // It must be a user defined function, in order to avoid ArduinoCloud include specificW iFi file + // in this case this library is independent from the WiFi one void onGetTime(unsigned long(*)(void)); - int connected(); + // Clean up existing Mqtt connection, create a new one and initialize it + void reconnect(Client& net); #define addProperty( v, ...) addPropertyReal(v, #v, __VA_ARGS__) @@ -42,17 +57,19 @@ class ArduinoCloudClass { Thing.addPropertyReal(property, name).publishEvery(seconds).setPermission(_permission).onUpdate(fn).minimumDelta(&minDelta); } - protected: +protected: friend class CloudSerialClass; int writeStdout(const byte data[], int length); int writeProperties(const byte data[], int length); + // Used to initialize MQTTClient + void mqttClientBegin(Client& net); + // Function in charge of perform MQTT reconnection, basing on class parameters(retries,and timeout) + bool mqttReconnect(int maxRetries, int timeout); private: static void onMessage(MQTTClient *client, char topic[], char bytes[], int length); - void handleMessage(char topic[], char bytes[], int length); -private: String _id; ArduinoCloudThing Thing; BearSSLClient* _bearSslClient; From 6448bc5cda49580d21185dd3e34796deba5e26cc Mon Sep 17 00:00:00 2001 From: Simone Marchisio Date: Thu, 9 Aug 2018 12:26:52 +0200 Subject: [PATCH 14/25] Added disconnect method --- src/ArduinoCloud.cpp | 5 +++++ src/ArduinoCloudV2.h | 1 + 2 files changed, 6 insertions(+) diff --git a/src/ArduinoCloud.cpp b/src/ArduinoCloud.cpp index 7dd0a94a0..3117312be 100644 --- a/src/ArduinoCloud.cpp +++ b/src/ArduinoCloud.cpp @@ -104,6 +104,11 @@ int ArduinoCloudClass::connect() return 1; } +bool ArduinoCloudClass::disconnect() +{ + return _mqttClient.disconnect(); +} + void ArduinoCloudClass::poll() { // If user call poll() without parameters use the default ones diff --git a/src/ArduinoCloudV2.h b/src/ArduinoCloudV2.h index 5bc054847..62056f7be 100644 --- a/src/ArduinoCloudV2.h +++ b/src/ArduinoCloudV2.h @@ -29,6 +29,7 @@ class ArduinoCloudClass { int begin(Client& net); int connect(); + bool disconnect(); void poll(); // defined for users who want to specify max reconnections reties and timeout between them void poll(int reconnectionMaxRetries, int reconnectionTimeoutMs); From 270d67bf0f9e1d5fb53feed255779a6d1f921e8a Mon Sep 17 00:00:00 2001 From: Simone Marchisio Date: Thu, 9 Aug 2018 12:30:54 +0200 Subject: [PATCH 15/25] Updated example sketch cloud_blink --- .../MKR1000_Cloud_Blink.ino | 66 ++++++++++++++++--- 1 file changed, 56 insertions(+), 10 deletions(-) diff --git a/examples/MKR1000_Cloud_Blink/MKR1000_Cloud_Blink.ino b/examples/MKR1000_Cloud_Blink/MKR1000_Cloud_Blink.ino index 96590c9a0..ba76dfd69 100644 --- a/examples/MKR1000_Cloud_Blink/MKR1000_Cloud_Blink.ino +++ b/examples/MKR1000_Cloud_Blink/MKR1000_Cloud_Blink.ino @@ -13,13 +13,35 @@ unsigned long getTime() { return WiFi.getTime(); } +// Thing properties int position; +bool valid = true; +float ratio = 2.47; +String welcome = "ciao"; + +// Last time when the WiFi connection was checked +unsigned long lastMillis = 0; void onPositionUpdate() { Serial.print("New position value: "); Serial.println(position); } +void onWelcomeUpdate() { + Serial.print("New state value: "); + Serial.println(welcome); +} + +void onValidUpdate() { + Serial.print("New valid value: "); + Serial.println(valid); +} + +void onRatioUpdate() { + Serial.print("New ratio value: "); + Serial.println(ratio); +} + void setup() { //Initialize serial and wait for port to open: Serial.begin(9600); @@ -47,7 +69,7 @@ void setup() { status = WiFi.begin(ssid, pass); // wait 10 seconds for connection: - delay(10000); + delay(5000); } // you're connected now, so print out the data: @@ -63,21 +85,45 @@ void setup() { } Serial.println("Successfully connected to Arduino Cloud :)"); - - ArduinoCloud.addProperty(position, READ, 10*SECONDS, onPositionUpdate); + ArduinoCloud.addProperty(welcome, READWRITE, ON_CHANGE, onWelcomeUpdate); + ArduinoCloud.addProperty(position, READWRITE, ON_CHANGE, onPositionUpdate); + ArduinoCloud.addProperty(valid, READWRITE, ON_CHANGE, onValidUpdate); + ArduinoCloud.addProperty(ratio, READWRITE, ON_CHANGE, onRatioUpdate); CloudSerial.begin(9600); + lastMillis = millis(); } void loop() { ArduinoCloud.poll(); - - if (CloudSerial.available()) { - Serial.write(CloudSerial.read()); + Serial.println("loop updated"); + /* + Serial.println("."); + welcome += "!"; + ratio += 0.4355; + valid = !valid; + position += 1; +*/ + if (millis() - lastMillis > 20000) { + Serial.println("..Check WiFi status.."); + bool error = false; + // Check Wifi status + while (WiFi.status() != WL_CONNECTED) { + error = true; + Serial.print("..Reconnection to connect to WPA SSID: "); + Serial.println(ssid); + status = WiFi.begin(ssid, pass); + // wait 10 seconds for connection: + delay(2000); + } + if(error) { + Serial.println("..Reconnected to the Nework!"); + // Call the reconnect method to clean up the ArduinoCloud connection + ArduinoCloud.reconnect(wifiClient); + } + delay(500); + lastMillis = millis(); } - if (Serial.available()) { - CloudSerial.write(Serial.read()); - } + delay(2000); } - From 3ddf07a1265866a0fc8dd155102e4940f0725f63 Mon Sep 17 00:00:00 2001 From: Alberto Iannaccone Date: Thu, 9 Aug 2018 16:16:49 +0200 Subject: [PATCH 16/25] blink via cloud monitor --- .../MKR1000_Cloud_Blink.ino | 142 +++++++++--------- 1 file changed, 74 insertions(+), 68 deletions(-) diff --git a/examples/MKR1000_Cloud_Blink/MKR1000_Cloud_Blink.ino b/examples/MKR1000_Cloud_Blink/MKR1000_Cloud_Blink.ino index ba76dfd69..5fa4d6367 100644 --- a/examples/MKR1000_Cloud_Blink/MKR1000_Cloud_Blink.ino +++ b/examples/MKR1000_Cloud_Blink/MKR1000_Cloud_Blink.ino @@ -1,11 +1,11 @@ #include #include -#include "arduino_secrets.h" ///////please enter your sensitive data in the Secret tab/arduino_secrets.h char ssid[] = SECRET_SSID; // your network SSID (name) char pass[] = SECRET_PASS; // your network password (use for WPA, or use as key for WEP) int status = WL_IDLE_STATUS; // the WiFi radio's status +String serialString = ""; // the string used to compose network messages from the received characters WiFiClient wifiClient; @@ -13,41 +13,10 @@ unsigned long getTime() { return WiFi.getTime(); } -// Thing properties -int position; -bool valid = true; -float ratio = 2.47; -String welcome = "ciao"; - -// Last time when the WiFi connection was checked -unsigned long lastMillis = 0; - -void onPositionUpdate() { - Serial.print("New position value: "); - Serial.println(position); -} - -void onWelcomeUpdate() { - Serial.print("New state value: "); - Serial.println(welcome); -} - -void onValidUpdate() { - Serial.print("New valid value: "); - Serial.println(valid); -} - -void onRatioUpdate() { - Serial.print("New ratio value: "); - Serial.println(ratio); -} - void setup() { //Initialize serial and wait for port to open: Serial.begin(9600); - while (!Serial) { - ; // wait for serial port to connect. Needed for native USB port only - } + delay(7000); // check for the presence of the shield: if (WiFi.status() == WL_NO_SHIELD) { @@ -62,14 +31,20 @@ void setup() { } // attempt to connect to WiFi network: - while (status != WL_CONNECTED) { + int attempts = 0; + while (status != WL_CONNECTED && attempts < 6) { Serial.print("Attempting to connect to WPA SSID: "); Serial.println(ssid); // Connect to WPA/WPA2 network: status = WiFi.begin(ssid, pass); // wait 10 seconds for connection: - delay(5000); + delay(10000); + attempts++; + } + + if (status != WL_CONNECTED) { + Serial.println("Failed to connect to Wifi!"); } // you're connected now, so print out the data: @@ -79,51 +54,82 @@ void setup() { Serial.println("Attempting to connect to Arduino Cloud ..."); ArduinoCloud.onGetTime(getTime); - if (!ArduinoCloud.connect()) { + + attempts = 0; + while (!ArduinoCloud.connect() && attempts < 10) { + attempts++; + } + + if (attempts >= 3) { Serial.println("Failed to connect to Arduino Cloud!"); while (1); } Serial.println("Successfully connected to Arduino Cloud :)"); - ArduinoCloud.addProperty(welcome, READWRITE, ON_CHANGE, onWelcomeUpdate); - ArduinoCloud.addProperty(position, READWRITE, ON_CHANGE, onPositionUpdate); - ArduinoCloud.addProperty(valid, READWRITE, ON_CHANGE, onValidUpdate); - ArduinoCloud.addProperty(ratio, READWRITE, ON_CHANGE, onRatioUpdate); CloudSerial.begin(9600); - lastMillis = millis(); + CloudSerial.print("I'm ready for blinking!\n"); } void loop() { ArduinoCloud.poll(); - Serial.println("loop updated"); - /* - Serial.println("."); - welcome += "!"; - ratio += 0.4355; - valid = !valid; - position += 1; -*/ - if (millis() - lastMillis > 20000) { - Serial.println("..Check WiFi status.."); - bool error = false; - // Check Wifi status - while (WiFi.status() != WL_CONNECTED) { - error = true; - Serial.print("..Reconnection to connect to WPA SSID: "); - Serial.println(ssid); - status = WiFi.begin(ssid, pass); - // wait 10 seconds for connection: - delay(2000); - } - if(error) { - Serial.println("..Reconnected to the Nework!"); - // Call the reconnect method to clean up the ArduinoCloud connection - ArduinoCloud.reconnect(wifiClient); + + // check if there is something waiting to be read + if (CloudSerial.available()) { + char character = CloudSerial.read(); + serialString += character; + + // if a \n character has been received, there should be a complete command inside serialString + if (character == '\n') { + manageString(); } - delay(500); - lastMillis = millis(); + } + else // if there is nothing to read, it could be that the last command didn't end with a '\n'. Check. + { + manageString(); } - delay(2000); + // Just to be able to simulate MKR1000's responses through the serial monitor + if (Serial.available()) { + CloudSerial.write(Serial.read()); + } } + +void manageString() { + // Don't proceed if the string is empty + if (serialString.equals("")) return; + + // Remove whitespaces + serialString.trim(); + + // Make it uppercase; + serialString.toUpperCase(); + + if (serialString.equals("ON")) { + digitalWrite(6, HIGH); + } + if (serialString.equals("OFF")) { + digitalWrite(6, LOW); + } + + // Send back the command you just applied. This way the Angular frontend can stay synchronized with the MKR1000 state. + sendString(serialString); + + // Reset serialString + serialString = ""; +} + +// sendString sends a string to the Arduino Cloud. +void sendString(String stringToSend) { + // send the characters one at a time + char lastSentChar = 0; + for (int i = 0; i < stringToSend.length(); i++) { + lastSentChar = stringToSend.charAt(i); + CloudSerial.write(lastSentChar); + } + + // if the last sent character wasn't a '\n' add it + if (lastSentChar != '\n') { + CloudSerial.write('\n'); + } +} \ No newline at end of file From e30b390c7e8584c21b7c8d8450ea141e80f88382 Mon Sep 17 00:00:00 2001 From: Alberto Iannaccone Date: Fri, 10 Aug 2018 12:36:13 +0200 Subject: [PATCH 17/25] use AWS server --- src/ArduinoCloud.cpp | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/src/ArduinoCloud.cpp b/src/ArduinoCloud.cpp index 3117312be..0c36c9b45 100644 --- a/src/ArduinoCloud.cpp +++ b/src/ArduinoCloud.cpp @@ -4,7 +4,7 @@ #include #include "CloudSerial.h" -const static char server[] = "broker.shiftr.io"; //"a19g5nbe27wn47.iot.us-east-1.amazonaws.com"; //"xxxxxxxxxxxxxx.iot.xx-xxxx-x.amazonaws.com"; +const static char server[] = "a19g5nbe27wn47.iot.us-east-1.amazonaws.com"; //"xxxxxxxxxxxxxx.iot.xx-xxxx-x.amazonaws.com"; const static int keySlot = 0; const static int compressedCertSlot = 10; @@ -28,7 +28,7 @@ ArduinoCloudClass::~ArduinoCloudClass() int ArduinoCloudClass::begin(Client& net) { byte thingIdBytes[72]; -/* + if (!ECCX08.begin()) { return 0; } @@ -57,11 +57,9 @@ int ArduinoCloudClass::begin(Client& net) } _bearSslClient = new BearSSLClient(net); _bearSslClient->setEccSlot(keySlot, ECCX08Cert.bytes(), ECCX08Cert.length()); -*/ - //END of TLS communication part. The result of that part is *_bearSslClient [Network Client] // Begin function for the MQTTClient - mqttClientBegin(net); + mqttClientBegin(*_bearSslClient); // Thing initialization Thing.begin(); @@ -72,22 +70,19 @@ int ArduinoCloudClass::begin(Client& net) void ArduinoCloudClass::mqttClientBegin(Client& net) { // MQTT topics definition - _id = "XXX"; - - _stdoutTopic = "/a/d/" + _id + "/s/o"; - _stdinTopic = "/a/d/" + _id + "/s/i"; - _dataTopicIn = "/a/d/" + _id + "/e/i"; - _dataTopicOut = "/a/d/" + _id + "/e/o"; + _stdoutTopic = "$aws/things/" + _id + "/stdout"; + _stdinTopic = "$aws/things/" + _id + "/stdin"; + _dataTopicIn = "$aws/things/" + _id + "/datain"; + _dataTopicOut = "$aws/things/" + _id + "/dataout"; // use onMessage as callback for received mqtt messages _mqttClient.onMessageAdvanced(ArduinoCloudClass::onMessage); - //_mqttClient.begin(server, 8883, *_bearSslClient); - _mqttClient.begin(server, 1883, net); + _mqttClient.begin(server, 8883, net); // Set will for MQTT client: {topic, qos, retain message} - const char lastMessage[] = "abcb"; - _mqttClient.setWill(_dataTopicOut.c_str(), lastMessage, false, 1); - // Set MQTT connection options - _mqttClient.setOptions(mqttOpt.keepAlive, mqttOpt.cleanSession, mqttOpt.timeout); + // const char lastMessage[] = "abcb"; + // _mqttClient.setWill(_dataTopicOut.c_str(), lastMessage, false, 1); + // // Set MQTT connection options + // _mqttClient.setOptions(mqttOpt.keepAlive, mqttOpt.cleanSession, mqttOpt.timeout); } int ArduinoCloudClass::connect() @@ -95,7 +90,7 @@ int ArduinoCloudClass::connect() //TODO MQTT brocker connection // Username: device id // Password: empty - if (!_mqttClient.connect(_id.c_str(), "try", "try")) { + if (!_mqttClient.connect(_id.c_str())) { return 0; } _mqttClient.subscribe(_stdinTopic); From 5ffabab4dabab5bb7fd1bbda3ed652eefa69071d Mon Sep 17 00:00:00 2001 From: Alberto Iannaccone Date: Tue, 21 Aug 2018 12:01:34 +0200 Subject: [PATCH 18/25] connect to vernemq --- .../utility/Provisioning/Provisioning.ino | 4 +-- src/ArduinoCloud.cpp | 35 +++++++++++++------ 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/examples/utility/Provisioning/Provisioning.ino b/examples/utility/Provisioning/Provisioning.ino index 1d5dce576..5d99cdfe5 100644 --- a/examples/utility/Provisioning/Provisioning.ino +++ b/examples/utility/Provisioning/Provisioning.ino @@ -55,7 +55,8 @@ void setup() { while (1); } - ECCX08Cert.setSubjectCommonName(ECCX08.serialNumber()); + String thingId = promptAndReadLine("Please enter the thing id: "); + ECCX08Cert.setSubjectCommonName(thingId); String csr = ECCX08Cert.endCSR(); @@ -68,7 +69,6 @@ void setup() { Serial.println(); Serial.println(csr); - String thingId = promptAndReadLine("Please enter the thing id: "); String issueYear = promptAndReadLine("Please enter the issue year of the certificate (2000 - 2031): "); String issueMonth = promptAndReadLine("Please enter the issue month of the certificate (1 - 12): "); String issueDay = promptAndReadLine("Please enter the issue day of the certificate (1 - 31): "); diff --git a/src/ArduinoCloud.cpp b/src/ArduinoCloud.cpp index 0c36c9b45..e752cb06a 100644 --- a/src/ArduinoCloud.cpp +++ b/src/ArduinoCloud.cpp @@ -4,7 +4,7 @@ #include #include "CloudSerial.h" -const static char server[] = "a19g5nbe27wn47.iot.us-east-1.amazonaws.com"; //"xxxxxxxxxxxxxx.iot.xx-xxxx-x.amazonaws.com"; +const static char server[] = "mqtts-sa.iot.oniudra.cc"; const static int keySlot = 0; const static int compressedCertSlot = 10; @@ -42,7 +42,7 @@ int ArduinoCloudClass::begin(Client& net) return 0; } - ECCX08Cert.setSubjectCommonName(ECCX08.serialNumber()); + ECCX08Cert.setSubjectCommonName(_id); ECCX08Cert.setIssuerCountryName("US"); ECCX08Cert.setIssuerOrganizationName("Arduino LLC US"); ECCX08Cert.setIssuerOrganizationalUnitName("IT"); @@ -52,6 +52,21 @@ int ArduinoCloudClass::begin(Client& net) return 0; } + Serial.println("Compressed cert = "); + + const byte* certData = ECCX08Cert.bytes(); + int certLength = ECCX08Cert.length(); + + for (int i = 0; i < certLength; i++) { + byte b = certData[i]; + + if (b < 16) { + Serial.print('0'); + } + Serial.print(b, HEX); + } + Serial.println(); + if (_bearSslClient) { delete _bearSslClient; } @@ -70,19 +85,19 @@ int ArduinoCloudClass::begin(Client& net) void ArduinoCloudClass::mqttClientBegin(Client& net) { // MQTT topics definition - _stdoutTopic = "$aws/things/" + _id + "/stdout"; - _stdinTopic = "$aws/things/" + _id + "/stdin"; - _dataTopicIn = "$aws/things/" + _id + "/datain"; - _dataTopicOut = "$aws/things/" + _id + "/dataout"; + _stdoutTopic = "/a/d/" + _id + "/s/o"; + _stdinTopic = "/a/d/" + _id + "/s/i"; + _dataTopicIn = "/a/d/" + _id + "/e/i"; + _dataTopicOut = "/a/d/" + _id + "/e/o"; // use onMessage as callback for received mqtt messages _mqttClient.onMessageAdvanced(ArduinoCloudClass::onMessage); _mqttClient.begin(server, 8883, net); // Set will for MQTT client: {topic, qos, retain message} - // const char lastMessage[] = "abcb"; - // _mqttClient.setWill(_dataTopicOut.c_str(), lastMessage, false, 1); - // // Set MQTT connection options - // _mqttClient.setOptions(mqttOpt.keepAlive, mqttOpt.cleanSession, mqttOpt.timeout); + const char lastMessage[] = "abcb"; + _mqttClient.setWill(_dataTopicOut.c_str(), lastMessage, false, 1); + // Set MQTT connection options + _mqttClient.setOptions(mqttOpt.keepAlive, mqttOpt.cleanSession, mqttOpt.timeout); } int ArduinoCloudClass::connect() From c87c017cf5e474a533d1aa466b88932aed07af11 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Wed, 29 Aug 2018 09:43:55 +0200 Subject: [PATCH 19/25] Adapt to String property type --- src/ArduinoCloudV2.h | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/ArduinoCloudV2.h b/src/ArduinoCloudV2.h index 62056f7be..80da4165f 100644 --- a/src/ArduinoCloudV2.h +++ b/src/ArduinoCloudV2.h @@ -42,19 +42,15 @@ class ArduinoCloudClass { #define addProperty( v, ...) addPropertyReal(v, #v, __VA_ARGS__) - template void addPropertyReal(T& property, String name, permissionType _permission = READWRITE, long seconds = ON_CHANGE, T minDelta = 0, void(*fn)(void) = NULL) { + template void addPropertyReal(T& property, String name, permissionType _permission = READWRITE, long seconds = ON_CHANGE, T minDelta = T(0), void(*fn)(void) = NULL) { Thing.addPropertyReal(property, name).publishEvery(seconds).setPermission(_permission).onUpdate(fn).minimumDelta(&minDelta); } - void addPropertyReal(String& property, String name, permissionType _permission = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0) { - Thing.addPropertyReal(property, name).publishEvery(seconds).setPermission(_permission).onUpdate(fn); - } - - template void addPropertyReal(T& property, String name, permissionType _permission = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, T minDelta = 0) { + template void addPropertyReal(T& property, String name, permissionType _permission = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, T minDelta = T(0)) { Thing.addPropertyReal(property, name).publishEvery(seconds).setPermission(_permission).onUpdate(fn).minimumDelta(&minDelta); } - template void addPropertyReal(T& property, String name, permissionType _permission = READWRITE, void(*fn)(void) = NULL, long seconds = ON_CHANGE, T minDelta = 0) { + template void addPropertyReal(T& property, String name, permissionType _permission = READWRITE, void(*fn)(void) = NULL, long seconds = ON_CHANGE, T minDelta = T(0)) { Thing.addPropertyReal(property, name).publishEvery(seconds).setPermission(_permission).onUpdate(fn).minimumDelta(&minDelta); } From de50ddef5ee380975ba1b61362073815651feb41 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Wed, 29 Aug 2018 09:44:32 +0200 Subject: [PATCH 20/25] Remove useless dependency on HTTPClient --- src/ArduinoCloudV2.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/ArduinoCloudV2.h b/src/ArduinoCloudV2.h index 80da4165f..c5371c64f 100644 --- a/src/ArduinoCloudV2.h +++ b/src/ArduinoCloudV2.h @@ -4,7 +4,6 @@ #include #include #include -#include #include "CloudSerial.h" @@ -70,7 +69,6 @@ class ArduinoCloudClass { String _id; ArduinoCloudThing Thing; BearSSLClient* _bearSslClient; - HttpClient* _otaClient; MQTTClient _mqttClient; // Class attribute to define MTTQ topics 2 for stdIn/out and 2 for data, in order to avoid getting previous pupblished payload From 80bc4ddec77d8e949440f84e8bef69f93d048842 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Wed, 29 Aug 2018 09:48:33 +0200 Subject: [PATCH 21/25] Fix secrets include in example --- examples/MKR1000_Cloud_Blink/MKR1000_Cloud_Blink.ino | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/MKR1000_Cloud_Blink/MKR1000_Cloud_Blink.ino b/examples/MKR1000_Cloud_Blink/MKR1000_Cloud_Blink.ino index 5fa4d6367..3d66b0793 100644 --- a/examples/MKR1000_Cloud_Blink/MKR1000_Cloud_Blink.ino +++ b/examples/MKR1000_Cloud_Blink/MKR1000_Cloud_Blink.ino @@ -1,5 +1,6 @@ #include #include +#include "arduino_secrets.h" ///////please enter your sensitive data in the Secret tab/arduino_secrets.h char ssid[] = SECRET_SSID; // your network SSID (name) @@ -132,4 +133,4 @@ void sendString(String stringToSend) { if (lastSentChar != '\n') { CloudSerial.write('\n'); } -} \ No newline at end of file +} From ad4788d24ca3b4cf23d17ed3a21d764dcdf30e29 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Wed, 29 Aug 2018 09:55:38 +0200 Subject: [PATCH 22/25] Remove nonsense Thing.hasAllReadProperties --- src/ArduinoCloud.cpp | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/ArduinoCloud.cpp b/src/ArduinoCloud.cpp index e752cb06a..605704226 100644 --- a/src/ArduinoCloud.cpp +++ b/src/ArduinoCloud.cpp @@ -156,25 +156,20 @@ void ArduinoCloudClass::poll(int reconnectionMaxRetries, int reconnectionTimeout int maxRetries = (reconnectionMaxRetries > 0) ? reconnectionMaxRetries : MAX_RETRIES; int timeout = (reconnectionTimeoutMs > 0) ? reconnectionTimeoutMs : RECONNECTION_TIMEOUT; - // If something has to be read from the network (prop with Write permission), perform reconnection now - if(!Thing.hasAllReadProperties()) { - // If the reconnect() culd not establish the connection, return the control to the user sketch - if (!mqttReconnect(maxRetries, timeout)) - return; - } + // If the reconnect() culd not establish the connection, return the control to the user sketch + if (!mqttReconnect(maxRetries, timeout)) + return; // MTTQClient connected!, poll() used to retrieve data from MQTT broker _mqttClient.loop(); - + uint8_t data[MQTT_BUFFER_SIZE]; int length = Thing.poll(data, sizeof(data)); // Are there some read properties that must be sent to the cloud ?? if (length > 0) { // Check the connection is ok! if not reconnect // If a thing has all read properties only try to reconnect when the have to be sent(based on their update policy) - if(mqttReconnect(maxRetries, timeout)) { - writeProperties(data, length); - } + writeProperties(data, length); } } From d570ac2e316d03059a3d191d3f8f2afe3c299c07 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Tue, 21 Aug 2018 19:12:58 +0200 Subject: [PATCH 23/25] TEMP: fully remove OTA support --- src/OTAStorage.h | 35 ------------------- src/SerialFlashStorage.cpp | 69 -------------------------------------- src/SerialFlashStorage.h | 43 ------------------------ 3 files changed, 147 deletions(-) delete mode 100644 src/OTAStorage.h delete mode 100644 src/SerialFlashStorage.cpp delete mode 100644 src/SerialFlashStorage.h diff --git a/src/OTAStorage.h b/src/OTAStorage.h deleted file mode 100644 index 0f96e2b3f..000000000 --- a/src/OTAStorage.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - Copyright (c) 2017 Arduino LLC. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef _OTA_STORAGE_H_INCLUDED -#define _OTA_STORAGE_H_INCLUDED - -class OTAStorage { -public: - virtual int open(int length) = 0; - virtual size_t write(uint8_t* data, size_t size) = 0; - virtual void close() = 0; - virtual void clear() = 0; - virtual void apply() = 0; - - virtual long maxSize() { - return ((256 * 1024) - 0x2000); - } -}; - -#endif diff --git a/src/SerialFlashStorage.cpp b/src/SerialFlashStorage.cpp deleted file mode 100644 index 432b7c7b6..000000000 --- a/src/SerialFlashStorage.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/* - Copyright (c) 2017 Arduino LLC. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "SerialFlashStorage.h" - -#define UPDATE_FILE "UPDATE.BIN" - -int SerialFlashStorageClass::open(int contentLength) -{ - if (!SerialFlash.begin(SERIAL_FLASH_CS)) { - return 0; - } - - while (!SerialFlash.ready()) {} - - if (SerialFlash.exists(UPDATE_FILE)) { - SerialFlash.remove(UPDATE_FILE); - } - - if (SerialFlash.create(UPDATE_FILE, contentLength)) { - _file = SerialFlash.open(UPDATE_FILE); - } - - if (!_file) { - return 0; - } - - return 1; -} - -size_t SerialFlashStorageClass::write(uint8_t *data, size_t size) -{ - while (!SerialFlash.ready()) {} - int ret = _file.write(data, size); - return ret; -} - -void SerialFlashStorageClass::close() -{ - _file.close(); -} - -void SerialFlashStorageClass::clear() -{ - SerialFlash.remove(UPDATE_FILE); -} - -void SerialFlashStorageClass::apply() -{ - // just reset, SDU copies the data to flash - NVIC_SystemReset(); -} - -SerialFlashStorageClass SerialFlashStorage; diff --git a/src/SerialFlashStorage.h b/src/SerialFlashStorage.h deleted file mode 100644 index 4409969f5..000000000 --- a/src/SerialFlashStorage.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - Copyright (c) 2017 Arduino LLC. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef _SERIALFLASH_STORAGE_H_INCLUDED -#define _SERIALFLASH_STORAGE_H_INCLUDED - -#include - -#include "OTAStorage.h" - -#define SERIAL_FLASH_BUFFER_SIZE 64 -#define SERIAL_FLASH_CS 5 - -class SerialFlashStorageClass : public OTAStorage { -public: - virtual int open(int length); - virtual size_t write(uint8_t* data, size_t size); - virtual void close(); - virtual void clear(); - virtual void apply(); - -private: - SerialFlashFile _file; -}; - -extern SerialFlashStorageClass SerialFlashStorage; - -#endif From f5228c85cca0f7c9cb88a25f512fc70aa9e17e0e Mon Sep 17 00:00:00 2001 From: Alberto Iannaccone Date: Thu, 30 Aug 2018 10:59:23 +0200 Subject: [PATCH 24/25] wait for 7 seconds only if serial is not found --- .../MKR1000_Cloud_Blink.ino | 38 ++++++++++--------- src/ArduinoCloudV2.h | 1 - 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/examples/MKR1000_Cloud_Blink/MKR1000_Cloud_Blink.ino b/examples/MKR1000_Cloud_Blink/MKR1000_Cloud_Blink.ino index 3d66b0793..56679ab6e 100644 --- a/examples/MKR1000_Cloud_Blink/MKR1000_Cloud_Blink.ino +++ b/examples/MKR1000_Cloud_Blink/MKR1000_Cloud_Blink.ino @@ -2,11 +2,13 @@ #include #include "arduino_secrets.h" +#define TIMEOUT 7000 + ///////please enter your sensitive data in the Secret tab/arduino_secrets.h -char ssid[] = SECRET_SSID; // your network SSID (name) -char pass[] = SECRET_PASS; // your network password (use for WPA, or use as key for WEP) +char ssid[] = SECRET_SSID; // your network SSID (name) +char pass[] = SECRET_PASS; // your network password (use for WPA, or use as key for WEP) int status = WL_IDLE_STATUS; // the WiFi radio's status -String serialString = ""; // the string used to compose network messages from the received characters +String cloudSerialBuffer = ""; // the string used to compose network messages from the received characters WiFiClient wifiClient; @@ -17,7 +19,8 @@ unsigned long getTime() { void setup() { //Initialize serial and wait for port to open: Serial.begin(9600); - delay(7000); + int timeout = millis() + TIMEOUT; + while (!Serial && (millis() < timeout)) {} // check for the presence of the shield: if (WiFi.status() == WL_NO_SHIELD) { @@ -46,22 +49,24 @@ void setup() { if (status != WL_CONNECTED) { Serial.println("Failed to connect to Wifi!"); + while (true); } // you're connected now, so print out the data: Serial.print("You're connected to the network"); Serial.println(); - Serial.println("Attempting to connect to Arduino Cloud ..."); + Serial.println("Attempting to connect to Arduino Cloud"); ArduinoCloud.onGetTime(getTime); attempts = 0; while (!ArduinoCloud.connect() && attempts < 10) { + Serial.print("."); attempts++; } - if (attempts >= 3) { + if (attempts >= 10) { Serial.println("Failed to connect to Arduino Cloud!"); while (1); } @@ -78,9 +83,9 @@ void loop() { // check if there is something waiting to be read if (CloudSerial.available()) { char character = CloudSerial.read(); - serialString += character; + cloudSerialBuffer += character; - // if a \n character has been received, there should be a complete command inside serialString + // if a \n character has been received, there should be a complete command inside cloudSerialBuffer if (character == '\n') { manageString(); } @@ -98,26 +103,25 @@ void loop() { void manageString() { // Don't proceed if the string is empty - if (serialString.equals("")) return; + if (cloudSerialBuffer.equals("")) return; // Remove whitespaces - serialString.trim(); + cloudSerialBuffer.trim(); // Make it uppercase; - serialString.toUpperCase(); + cloudSerialBuffer.toUpperCase(); - if (serialString.equals("ON")) { + if (cloudSerialBuffer.equals("ON")) { digitalWrite(6, HIGH); } - if (serialString.equals("OFF")) { + if (cloudSerialBuffer.equals("OFF")) { digitalWrite(6, LOW); } - // Send back the command you just applied. This way the Angular frontend can stay synchronized with the MKR1000 state. - sendString(serialString); + sendString(cloudSerialBuffer); - // Reset serialString - serialString = ""; + // Reset cloudSerialBuffer + cloudSerialBuffer = ""; } // sendString sends a string to the Arduino Cloud. diff --git a/src/ArduinoCloudV2.h b/src/ArduinoCloudV2.h index c5371c64f..42527c884 100644 --- a/src/ArduinoCloudV2.h +++ b/src/ArduinoCloudV2.h @@ -76,7 +76,6 @@ class ArduinoCloudClass { String _stdoutTopic; String _dataTopicIn; String _dataTopicOut; - String _otaTopic; }; extern ArduinoCloudClass ArduinoCloud; From 2bf5d1b769c4ef78151f7fac49c88db51ec7f261 Mon Sep 17 00:00:00 2001 From: Alberto Iannaccone Date: Thu, 30 Aug 2018 12:30:21 +0200 Subject: [PATCH 25/25] print compressed cert only in debug mode --- .../utility/Provisioning/Provisioning.ino | 22 +++++++++++-------- src/ArduinoCloud.cpp | 15 ------------- 2 files changed, 13 insertions(+), 24 deletions(-) diff --git a/examples/utility/Provisioning/Provisioning.ino b/examples/utility/Provisioning/Provisioning.ino index 5d99cdfe5..7ec476346 100644 --- a/examples/utility/Provisioning/Provisioning.ino +++ b/examples/utility/Provisioning/Provisioning.ino @@ -5,6 +5,7 @@ #include #include +const bool DEBUG = true; const int keySlot = 0; const int compressedCertSlot = 10; const int serialNumberAndAuthorityKeyIdentifierSlot = 11; @@ -127,22 +128,25 @@ void setup() { while (1); } - Serial.println("Compressed cert = "); + if (DEBUG) { + Serial.println("Compressed cert = "); - const byte* certData = ECCX08Cert.bytes(); - int certLength = ECCX08Cert.length(); + const byte* certData = ECCX08Cert.bytes(); + int certLength = ECCX08Cert.length(); - for (int i = 0; i < certLength; i++) { - byte b = certData[i]; + for (int i = 0; i < certLength; i++) { + byte b = certData[i]; - if (b < 16) { - Serial.print('0'); + if (b < 16) { + Serial.print('0'); + } + Serial.print(b, HEX); } - Serial.print(b, HEX); + Serial.println(); } - Serial.println(); } + void loop() { } diff --git a/src/ArduinoCloud.cpp b/src/ArduinoCloud.cpp index 605704226..bff7939f2 100644 --- a/src/ArduinoCloud.cpp +++ b/src/ArduinoCloud.cpp @@ -52,21 +52,6 @@ int ArduinoCloudClass::begin(Client& net) return 0; } - Serial.println("Compressed cert = "); - - const byte* certData = ECCX08Cert.bytes(); - int certLength = ECCX08Cert.length(); - - for (int i = 0; i < certLength; i++) { - byte b = certData[i]; - - if (b < 16) { - Serial.print('0'); - } - Serial.print(b, HEX); - } - Serial.println(); - if (_bearSslClient) { delete _bearSslClient; }