-
Notifications
You must be signed in to change notification settings - Fork 82
Add GSM and Ethernet conn_manager + add fallback UDP based getTime() #31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 19 commits
db14c67
68d2c3c
1324ac6
19c688e
e0abeb8
75ddfcc
da7179b
e01a981
4014095
a243573
096022a
98efd08
e905238
8646505
8eefcc0
e4e11e5
20cbb75
7fc775b
bff994e
ae7dae9
f86f04f
961a71c
fb161bd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,15 @@ | ||
/* | ||
Fill in your login credentials: | ||
ubidefeo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
The following lines are used for WiFi enabled boards (MKR1000, MKR WiFi 1010) | ||
ubidefeo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
*/ | ||
#define SECRET_SSID "YOUR_WIFI_NETWORK_NAME" | ||
#define SECRET_PASS "YOUR_WIFI_PASSWORD" | ||
|
||
/* | ||
If you prefer using a MKR GSM 1400 comment the lines above and uncommet the following. | ||
ubidefeo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
PIN, APN, Login and Password are supplied by your Cellular Data provider. | ||
ubidefeo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
*/ | ||
//#define SECRET_PIN "" | ||
//#define SECRET_APN "" | ||
//#define SECRET_LOGIN "" | ||
//#define SECRET_PASS "" |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,9 +1,13 @@ | ||||||
#include <ArduinoIoTCloud.h> | ||||||
/* | ||||||
ubidefeo marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
The following include line is used for WiFi enabled boards (MKR1000, MKR WiFi 1010) | ||||||
ubidefeo marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
*/ | ||||||
#include <WiFiConnectionManager.h> | ||||||
/* | ||||||
ubidefeo marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
If you prefer using a MKR GSM 1400 comment the line above and uncommet the following. | ||||||
ubidefeo marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
*/ | ||||||
//#include <GSMConnectionManager.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) | ||||||
// Your THING_ID | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
#define THING_ID "ARDUINO_IOT_CLOUD_THING_ID" | ||||||
|
||||||
|
@@ -18,4 +22,11 @@ void initProperties() { | |||||
ArduinoCloud.addProperty(potentiometer, READ, ON_CHANGE); | ||||||
} | ||||||
|
||||||
ConnectionManager *ArduinoIoTPreferredConnection = new WiFiConnectionManager(SECRET_SSID, SECRET_PASS); | ||||||
/* | ||||||
ubidefeo marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
The following include line is used for WiFi enabled boards (MKR1000, MKR WiFi 1010) | ||||||
ubidefeo marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
*/ | ||||||
ConnectionManager *ArduinoIoTPreferredConnection = new WiFiConnectionManager(SECRET_SSID, SECRET_PASS); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A quick side note: Everything that follows is a suggestion for improvement and must not necessarily implemented within this PR. We can (and probably should) do cleanups in further PRs after this is merged. A misconception, for which I've fallen myself until quite recently, is that if you instantiate derived classes with virtual functions in it (C++ runtime polymorphism) you always need to use the keyword
Suggested change
Doing it this way the memory for the object is allocated on the stack and not on the heap (static memory allocation vs dynamic memory allocation - prefer the former whenever possible/feasible). The reason above statement works is because of a C++ "feature" called object slicing. Now object slicing has some pitfalls to it but it can be used effectively in this scenario where we have an abstract base class (= one or more pure virtual functions in it) When passing the connection around to various classes you then have to use pass-by-reference. void myFunc(ConnectionManager & connection_mgr) { ... It´s also possible to store a reference of it as a class member variable. class MyClass {
public:
void MyClass(ConnectionManager & connection_mgr) : _connection_mgr(connection_mgr) { ... }
void myMemberFunc();
private:
ConnectionManager & _connection_mgr;
}; The void MyClass:myMemberFunc() {
_connection_mgr.check();
} Furthermore I'd also suggest to keep variable names in lowercase so to not confuse them with class/type names. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. interesting... I'll proceed to merge this PR in :) |
||||||
/* | ||||||
ubidefeo marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
If you prefer using a MKR GSM 1400 comment the line above and uncommet the following. | ||||||
ubidefeo marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
*/ | ||||||
//ConnectionManager *ArduinoIoTPreferredConnection = new GSMConnectionManager(SECRET_PIN, SECRET_APN, SECRET_LOGIN, SECRET_PASS); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
name=ArduinoIoTCloud | ||
version=0.5.0 | ||
version=0.5.1 | ||
author=Arduino | ||
maintainer=Arduino <[email protected]> | ||
sentence=This library allows to connect to the Arduino IoT Cloud service. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,187 @@ | ||
#include "ConnectionManager.h" | ||
|
||
#include <Ethernet.h> | ||
#define BOARD_HAS_ETHERNET | ||
|
||
class EthConnectionManager : public ConnectionManager { | ||
public: | ||
EthConnectionManager(uint8_t *mac, int ss_pin); | ||
|
||
virtual unsigned long getTime(); | ||
virtual void init(); | ||
virtual void check(); | ||
virtual Client &getClient() { return ethClient; }; | ||
virtual UDP &getUDP() { return udp; }; | ||
|
||
private: | ||
|
||
void changeConnectionState(NetworkConnectionState _newState); | ||
const int CHECK_INTERVAL_IDLE = 100; | ||
const int CHECK_INTERVAL_INIT = 100; | ||
const int CHECK_INTERVAL_CONNECTING = 500; | ||
const int CHECK_INTERVAL_GETTIME = 100; | ||
const int CHECK_INTERVAL_CONNECTED = 10000; | ||
const int CHECK_INTERVAL_RETRYING = 5000; | ||
const int CHECK_INTERVAL_DISCONNECTED = 1000; | ||
const int CHECK_INTERVAL_ERROR = 500; | ||
|
||
unsigned long lastConnectionTickTime, lastNetworkStep; | ||
uint8_t* mac; | ||
int ss_pin; | ||
EthernetClient ethClient; | ||
EthernetUDP udp; | ||
int connectionTickTimeInterval; | ||
}; | ||
|
||
#if !defined(BOARD_HAS_WIFI) && !defined(BOARD_HAS_GSM) | ||
static const unsigned long NETWORK_CONNECTION_INTERVAL = 30000; | ||
#endif | ||
|
||
EthConnectionManager::EthConnectionManager(uint8_t *mac, int ss_pin = -1) : | ||
mac(mac), | ||
ss_pin(ss_pin), | ||
lastConnectionTickTime(millis()), | ||
connectionTickTimeInterval(CHECK_INTERVAL_IDLE) { | ||
} | ||
|
||
unsigned long EthConnectionManager::getTime() { | ||
//handled by fallback manager | ||
return lastValidTimestamp + 1; | ||
} | ||
|
||
void EthConnectionManager::init() { | ||
} | ||
|
||
void EthConnectionManager::changeConnectionState(NetworkConnectionState _newState) { | ||
netConnectionState = _newState; | ||
int newInterval = CHECK_INTERVAL_IDLE; | ||
switch (_newState) { | ||
case CONNECTION_STATE_INIT: | ||
newInterval = CHECK_INTERVAL_INIT; | ||
break; | ||
case CONNECTION_STATE_CONNECTING: | ||
newInterval = CHECK_INTERVAL_CONNECTING; | ||
break; | ||
case CONNECTION_STATE_GETTIME: | ||
newInterval = CHECK_INTERVAL_GETTIME; | ||
break; | ||
case CONNECTION_STATE_CONNECTED: | ||
newInterval = CHECK_INTERVAL_CONNECTED; | ||
break; | ||
case CONNECTION_STATE_DISCONNECTED: | ||
newInterval = CHECK_INTERVAL_DISCONNECTED; | ||
|
||
break; | ||
} | ||
connectionTickTimeInterval = newInterval; | ||
lastConnectionTickTime = millis(); | ||
} | ||
|
||
void EthConnectionManager::check() { | ||
char msgBuffer[120]; | ||
unsigned long const now = millis(); | ||
int networkStatus = 0; | ||
if (now - lastConnectionTickTime > connectionTickTimeInterval) { | ||
switch (netConnectionState) { | ||
case CONNECTION_STATE_INIT: | ||
if (ss_pin == -1) { | ||
networkStatus = Ethernet.begin(mac); | ||
} else { | ||
networkStatus = Ethernet.begin(mac, ss_pin); | ||
} | ||
networkStatus = Ethernet.hardwareStatus(); | ||
*msgBuffer = 0; | ||
sprintf(msgBuffer, "Eth hardware status(): %d", networkStatus); | ||
debugMessage(msgBuffer, 2); | ||
if (networkStatus == EthernetNoHardware) { | ||
debugMessage("No Ethernet chip connected", 0); | ||
// don't continue: | ||
changeConnectionState(CONNECTION_STATE_ERROR); | ||
lastConnectionTickTime = now; | ||
return; | ||
} | ||
networkStatus = Ethernet.linkStatus(); | ||
*msgBuffer = 0; | ||
sprintf(msgBuffer, "Eth link status(): %d", networkStatus); | ||
debugMessage(msgBuffer, 2); | ||
if (networkStatus == LinkOFF) { | ||
debugMessage("Failed to configure Ethernet via dhcp", 0); | ||
// don't continue: | ||
changeConnectionState(CONNECTION_STATE_ERROR); | ||
lastConnectionTickTime = now; | ||
return; | ||
} | ||
*msgBuffer = 0; | ||
sprintf(msgBuffer, "Ethernet shield recognized: ID", Ethernet.hardwareStatus()); | ||
debugMessage(msgBuffer, 0); | ||
changeConnectionState(CONNECTION_STATE_CONNECTING); | ||
break; | ||
case CONNECTION_STATE_CONNECTING: | ||
*msgBuffer = 0; | ||
sprintf(msgBuffer, "Connecting via dhcp"); | ||
debugMessage(msgBuffer, 2); | ||
if (ss_pin == -1) { | ||
networkStatus = Ethernet.begin(mac); | ||
} else { | ||
networkStatus = Ethernet.begin(mac, ss_pin); | ||
} | ||
*msgBuffer = 0; | ||
sprintf(msgBuffer, "Ethernet.status(): %d", networkStatus); | ||
debugMessage(msgBuffer, 2); | ||
if (networkStatus == 0) { | ||
*msgBuffer = 0; | ||
sprintf(msgBuffer, "Connection failed"); | ||
debugMessage(msgBuffer, 0); | ||
|
||
*msgBuffer = 0; | ||
sprintf(msgBuffer, "Retrying in \"%d\" milliseconds", connectionTickTimeInterval); | ||
debugMessage(msgBuffer, 2); | ||
//changeConnectionState(CONNECTION_STATE_CONNECTING); | ||
return; | ||
} else { | ||
*msgBuffer = 0; | ||
sprintf(msgBuffer, "Connected!"); | ||
debugMessage(msgBuffer, 2); | ||
changeConnectionState(CONNECTION_STATE_GETTIME); | ||
return; | ||
} | ||
break; | ||
case CONNECTION_STATE_GETTIME: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add an exit condition from the CONNECTION_STATE_GETTIME state in a similar way of the WiFiConnectionManager. |
||
debugMessage("Acquiring Time from Network", 3); | ||
unsigned long networkTime; | ||
networkTime = getTime(); | ||
*msgBuffer = 0; | ||
sprintf(msgBuffer, "Network Time: %u", networkTime); | ||
debugMessage(msgBuffer, 3); | ||
if(networkTime > lastValidTimestamp){ | ||
lastValidTimestamp = networkTime; | ||
changeConnectionState(CONNECTION_STATE_CONNECTED); | ||
} | ||
break; | ||
case CONNECTION_STATE_CONNECTED: | ||
// keep testing connection | ||
Ethernet.maintain(); | ||
networkStatus = Ethernet.linkStatus(); | ||
*msgBuffer = 0; | ||
sprintf(msgBuffer, "Eth link status(): %d", networkStatus); | ||
debugMessage(msgBuffer, 4); | ||
if (networkStatus != LinkON) { | ||
changeConnectionState(CONNECTION_STATE_DISCONNECTED); | ||
return; | ||
} | ||
*msgBuffer = 0; | ||
sprintf(msgBuffer, "Connected"); | ||
debugMessage(msgBuffer, 2); | ||
break; | ||
case CONNECTION_STATE_DISCONNECTED: | ||
*msgBuffer = 0; | ||
sprintf(msgBuffer, "Connection lost."); | ||
debugMessage(msgBuffer, 0); | ||
debugMessage("Attempting reconnection", 1); | ||
changeConnectionState(CONNECTION_STATE_CONNECTING); | ||
//wifiClient.stop(); | ||
break; | ||
} | ||
lastConnectionTickTime = now; | ||
} | ||
} |
Uh oh!
There was an error while loading. Please reload this page.