Skip to content

Commit 25c5b71

Browse files
authored
Merge pull request #31 from arduino-libraries/gsm_proper_connmanager
Add GSM and Ethernet conn_manager + add fallback UDP based getTime()
2 parents 73f30cc + fb161bd commit 25c5b71

13 files changed

+494
-104
lines changed

examples/ArduinoIoTCloud_LED_switch/ArduinoIoTCloud_LED_switch.ino

+5-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@
55
When the potentiometer (or sensor) value changes the data is sent to the Cloud.
66
When you flip the switch in the Cloud dashboard the onboard LED lights gets turned ON or OFF.
77
8-
8+
IMPORTANT:
9+
This sketch will work with both WiFi and GSM enabled boards supported by Arduino IoT Cloud.
10+
By default, settings for WiFi are chosen. If you prefer to use a GSM board take a look at thingProperties.h arduino_secrets.h,
11+
to make sure you uncomment what's needed and comment incompatible instructions.
12+
913
*/
1014
#include "arduino_secrets.h"
1115
#include "thingProperties.h"
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
/*
2+
Fill in your login credentials:
3+
4+
The following lines are used for WiFi enabled boards (MKR1000, MKR WiFi 1010)
5+
*/
16
#define SECRET_SSID "YOUR_WIFI_NETWORK_NAME"
27
#define SECRET_PASS "YOUR_WIFI_PASSWORD"
3-
8+
/*
9+
If you prefer using a MKR GSM 1400 comment the lines above and uncommet the following.
10+
PIN, APN, Login and Password are supplied by your Cellular Data provider.
11+
*/
12+
//#define SECRET_PIN ""
13+
//#define SECRET_APN ""
14+
//#define SECRET_LOGIN ""
15+
//#define SECRET_PASS ""

examples/ArduinoIoTCloud_LED_switch/thingProperties.h

+15-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
#include <ArduinoIoTCloud.h>
2+
/*
3+
The following include line is used for WiFi enabled boards (MKR1000, MKR WiFi 1010)
4+
*/
25
#include <WiFiConnectionManager.h>
6+
/*
7+
If you prefer using a MKR GSM 1400 comment the line above and uncommet the following.
8+
*/
9+
//#include <GSMConnectionManager.h>
310

4-
5-
char ssid[] = SECRET_SSID; // your network SSID (name)
6-
char pass[] = SECRET_PASS; // your network password (use for WPA, or use as key for WEP)
711
// Your THING_ID
812
#define THING_ID "ARDUINO_IOT_CLOUD_THING_ID"
913

@@ -18,4 +22,11 @@ void initProperties() {
1822
ArduinoCloud.addProperty(potentiometer, READ, ON_CHANGE);
1923
}
2024

21-
ConnectionManager *ArduinoIoTPreferredConnection = new WiFiConnectionManager(SECRET_SSID, SECRET_PASS);
25+
/*
26+
The following include line is used for WiFi enabled boards (MKR1000, MKR WiFi 1010)
27+
*/
28+
ConnectionManager *ArduinoIoTPreferredConnection = new WiFiConnectionManager(SECRET_SSID, SECRET_PASS);
29+
/*
30+
If you prefer using a MKR GSM 1400 comment the line above and uncommet the following.
31+
*/
32+
//ConnectionManager *ArduinoIoTPreferredConnection = new GSMConnectionManager(SECRET_PIN, SECRET_APN, SECRET_LOGIN, SECRET_PASS);

library.properties

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=ArduinoIoTCloud
2-
version=0.5.0
2+
version=0.5.1
33
author=Arduino
44
maintainer=Arduino <[email protected]>
55
sentence=This library allows to connect to the Arduino IoT Cloud service.

src/ArduinoIoTCloud.cpp

+10-45
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,12 @@ static ConnectionManager *getTimeConnection = NULL;
2929

3030
static unsigned long getTime() {
3131
if (!getTimeConnection) return 0;
32-
return getTimeConnection->getTime();
32+
unsigned long time = getTimeConnection->getTime();
33+
if (!NTPUtils::isTimeValid(time)) {
34+
debugMessage("Bogus NTP time from API, fallback to UDP method", 0);
35+
time = NTPUtils(getTimeConnection->getUDP()).getTime();
36+
}
37+
return time;
3338
}
3439

3540
ArduinoIoTCloudClass::ArduinoIoTCloudClass() :
@@ -118,7 +123,6 @@ int ArduinoIoTCloudClass::begin(Client& net, String brokerAddress, uint16_t brok
118123

119124

120125
// TODO: Find a better way to allow callback into object method
121-
122126
// Begin function for the MQTTClient
123127
mqttClientBegin();
124128

@@ -184,41 +188,12 @@ void ArduinoIoTCloudClass::update()
184188
update(MAX_RETRIES, RECONNECTION_TIMEOUT);
185189
}
186190

187-
bool ArduinoIoTCloudClass::mqttReconnect(int const maxRetries, int const timeout)
188-
{
189-
// Counter for reconnection retries
190-
int retries = 0;
191-
unsigned long start = millis();
192-
193-
// Check for MQTT broker connection, of if maxReties limit is reached
194-
// if MQTTClient is connected , simply do nothing and retun true
195-
while (!_mqttClient->connected() && (retries++ < maxRetries) && (millis() - start < timeout)) {
196-
// int connectError = _mqttClient->connectError();
197-
198-
// try establish the MQTT broker connection
199-
connect();
200-
}
201-
202-
// It was impossible to establish a connection, return
203-
if ((retries == maxRetries) || (millis() - start >= timeout))
204-
return false;
205-
206-
return true;
207-
}
208-
209191
void ArduinoIoTCloudClass::update(int const reconnectionMaxRetries, int const reconnectionTimeoutMs)
210192
{
211193
connectionCheck();
212194
if(iotStatus != IOT_STATUS_CLOUD_CONNECTED){
213195
return;
214196
}
215-
// Method's argument controls
216-
int const maxRetries = (reconnectionMaxRetries > 0) ? reconnectionMaxRetries : MAX_RETRIES;
217-
int const timeout = (reconnectionTimeoutMs > 0) ? reconnectionTimeoutMs : RECONNECTION_TIMEOUT;
218-
219-
// If the reconnect() culd not establish the connection, return the control to the user sketch
220-
if (!mqttReconnect(maxRetries, timeout))
221-
return;
222197

223198
// MTTQClient connected!, poll() used to retrieve data from MQTT broker
224199
_mqttClient->poll();
@@ -320,28 +295,18 @@ void ArduinoIoTCloudClass::connectionCheck()
320295

321296

322297
switch (iotStatus) {
323-
case IOT_STATUS_IDLE:
324-
{
325-
int connectionAttempt;
326-
if(connection == NULL){
327-
connectionAttempt = begin(*_net, _brokerAddress, _brokerPort);
328-
}else{
329-
connectionAttempt = begin(connection, _brokerAddress, _brokerPort);
330-
}
331-
if(!connectionAttempt){
332-
debugMessage("Error Starting Arduino Cloud\nTrying again in a few seconds", 0);
333-
setIoTConnectionState(IOT_STATUS_CLOUD_ERROR);
334-
return;
335-
}
298+
case IOT_STATUS_CLOUD_IDLE:
336299
setIoTConnectionState(IOT_STATUS_CLOUD_CONNECTING);
337300
break;
338-
}
339301
case IOT_STATUS_CLOUD_ERROR:
340302
debugMessage("Cloud Error. Retrying...", 0);
341303
setIoTConnectionState(IOT_STATUS_CLOUD_RECONNECTING);
342304
break;
343305
case IOT_STATUS_CLOUD_CONNECTED:
344306
debugMessage(".", 4, false, true);
307+
if (!_mqttClient->connected()){
308+
setIoTConnectionState(IOT_STATUS_CLOUD_DISCONNECTED);
309+
}
345310
break;
346311
case IOT_STATUS_CLOUD_DISCONNECTED:
347312
setIoTConnectionState(IOT_STATUS_CLOUD_RECONNECTING);

src/ArduinoIoTCloud.h

+1-3
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,12 @@ typedef struct {
4343
extern ConnectionManager *ArduinoIoTPreferredConnection;
4444

4545
enum ArduinoIoTConnectionStatus {
46-
IOT_STATUS_IDLE,/* only at start */
4746
IOT_STATUS_CLOUD_IDLE,
4847
IOT_STATUS_CLOUD_CONNECTING,
4948
IOT_STATUS_CLOUD_CONNECTED,
5049
IOT_STATUS_CLOUD_DISCONNECTED,
5150
IOT_STATUS_CLOUD_RECONNECTING,
5251
IOT_STATUS_CLOUD_ERROR,
53-
IOT_STATUS_ERROR_GENERIC
5452
};
5553

5654
class ArduinoIoTCloudClass {
@@ -130,7 +128,7 @@ class ArduinoIoTCloudClass {
130128
ArduinoIoTConnectionStatus getIoTStatus() { return iotStatus; }
131129
void setIoTConnectionState(ArduinoIoTConnectionStatus _newState);
132130
private:
133-
ArduinoIoTConnectionStatus iotStatus = IOT_STATUS_IDLE;
131+
ArduinoIoTConnectionStatus iotStatus = IOT_STATUS_CLOUD_IDLE;
134132
ConnectionManager *connection;
135133
static void onMessage(int length);
136134
void handleMessage(int length);

src/CloudSerial.cpp

-6
Original file line numberDiff line numberDiff line change
@@ -38,35 +38,30 @@ void CloudSerialClass::end()
3838

3939
int CloudSerialClass::available()
4040
{
41-
ArduinoCloud.update();
4241

4342
return _rxBuffer.available();
4443
}
4544

4645
int CloudSerialClass::availableForWrite()
4746
{
48-
ArduinoCloud.update();
4947

5048
return _txBuffer.availableForStore();
5149
}
5250

5351
int CloudSerialClass::peek()
5452
{
55-
ArduinoCloud.update();
5653

5754
return _rxBuffer.peek();
5855
}
5956

6057
int CloudSerialClass::read()
6158
{
62-
ArduinoCloud.update();
6359

6460
return _rxBuffer.read_char();
6561
}
6662

6763
void CloudSerialClass::flush()
6864
{
69-
ArduinoCloud.update();
7065

7166
byte out[CLOUD_SERIAL_TX_BUFFER_SIZE];
7267
int length = 0;
@@ -91,7 +86,6 @@ size_t CloudSerialClass::write(const uint8_t data)
9186

9287
CloudSerialClass::operator bool()
9388
{
94-
ArduinoCloud.update();
9589

9690
return ArduinoCloud.connected();
9791
}

src/ConnectionManager.h

+5-2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
#define ARDUINO_CLOUD_DEBUG_LEVEL 2
2222

2323
#include <Client.h>
24+
#include <Udp.h>
25+
#include "utility/NTPUtils.h"
2426

2527
enum NetworkConnectionState {
2628
CONNECTION_STATE_INIT,
@@ -38,6 +40,7 @@ class ConnectionManager {
3840
virtual void check() = 0;
3941
virtual unsigned long getTime() = 0;
4042
virtual Client &getClient();
43+
virtual UDP &getUDP();
4144

4245
virtual NetworkConnectionState getStatus() { return netConnectionState; }
4346

@@ -82,14 +85,14 @@ inline void debugMessage(char *_msg, int _debugLevel, bool _timestamp = true, bo
8285
if (_debugLevel <= debugMessageLevel) {
8386
char prepend[20];
8487
sprintf(prepend, "\n[ %d ] ", millis());
85-
if(_timestamp)
88+
if(_timestamp){
8689
Serial.print(prepend);
90+
}
8791
if(_newline){
8892
Serial.println(_msg);
8993
}else{
9094
Serial.print(_msg);
9195
}
92-
9396
}
9497
}
9598

0 commit comments

Comments
 (0)