-
Notifications
You must be signed in to change notification settings - Fork 516
WiFiClientStream added #289
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 all commits
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 |
---|---|---|
|
@@ -110,7 +110,7 @@ | |
// the minimum interval for sampling analog input | ||
#define MINIMUM_SAMPLING_INTERVAL 1 | ||
|
||
#define WIFI_MAX_CONN_ATTEMPTS 3 | ||
#define MAX_CONN_ATTEMPTS 20 // [500 ms] -> 10 s | ||
|
||
/*============================================================================== | ||
* GLOBAL VARIABLES | ||
|
@@ -130,8 +130,8 @@ IPAddress subnet(SUBNET_MASK); | |
IPAddress gateway(GATEWAY_IP_ADDRESS); | ||
#endif | ||
|
||
int wifiConnectionAttemptCounter = 0; | ||
int wifiStatus = WL_IDLE_STATUS; | ||
int connectionAttempts = 0; | ||
bool streamConnected = false; | ||
|
||
/* analog inputs */ | ||
int analogInputsToReport = 0; // bitwise array to store pin reporting | ||
|
@@ -308,6 +308,12 @@ void checkDigitalInputs(void) | |
if (TOTAL_PORTS > 15 && reportPINs[15]) outputPort(15, readPort(15, portConfigInputs[15]), false); | ||
} | ||
|
||
// ----------------------------------------------------------------------------- | ||
// function forward declarations | ||
void enableI2CPins(); | ||
void disableI2CPins(); | ||
void reportAnalogCallback(byte analogPin, int value); | ||
|
||
// ----------------------------------------------------------------------------- | ||
/* sets the pin mode to the correct state and sets the relevant bits in the | ||
* two bit-arrays that track Digital I/O and PWM status | ||
|
@@ -826,38 +832,26 @@ void systemResetCallback() | |
} | ||
|
||
void printWifiStatus() { | ||
#if defined(ARDUINO_WIFI_SHIELD) || defined(WIFI_101) || defined(ESP8266_WIFI) | ||
if ( WiFi.status() != WL_CONNECTED ) | ||
{ | ||
DEBUG_PRINT( "WiFi connection failed. Status value: " ); | ||
DEBUG_PRINTLN( WiFi.status() ); | ||
} | ||
else | ||
#endif //defined(ARDUINO_WIFI_SHIELD) || defined(WIFI_101) || defined(ESP8266_WIFI) | ||
{ | ||
// print the SSID of the network you're attached to: | ||
DEBUG_PRINT( "SSID: " ); | ||
|
||
#if defined(ARDUINO_WIFI_SHIELD) || defined(WIFI_101) || defined(ESP8266_WIFI) | ||
DEBUG_PRINTLN( WiFi.SSID() ); | ||
#endif //defined(ARDUINO_WIFI_SHIELD) || defined(WIFI_101) || defined(ESP8266_WIFI) | ||
|
||
// print your WiFi shield's IP address: | ||
DEBUG_PRINT( "IP Address: " ); | ||
|
||
#if defined(ARDUINO_WIFI_SHIELD) || defined(WIFI_101) || defined(ESP8266_WIFI) | ||
IPAddress ip = WiFi.localIP(); | ||
DEBUG_PRINTLN( ip ); | ||
#endif //defined(ARDUINO_WIFI_SHIELD) || defined(WIFI_101) || defined(ESP8266_WIFI) | ||
|
||
// print the received signal strength: | ||
DEBUG_PRINT( "signal strength (RSSI): " ); | ||
|
||
#if defined(ARDUINO_WIFI_SHIELD) || defined(WIFI_101) || defined(ESP8266_WIFI) | ||
long rssi = WiFi.RSSI(); | ||
DEBUG_PRINT( rssi ); | ||
#endif //defined(ARDUINO_WIFI_SHIELD) || defined(WIFI_101) || defined(ESP8266_WIFI) | ||
|
||
DEBUG_PRINTLN( " dBm" ); | ||
} | ||
} | ||
|
@@ -890,7 +884,7 @@ void setup() | |
#ifdef STATIC_IP_ADDRESS | ||
DEBUG_PRINT( "Using static IP: " ); | ||
DEBUG_PRINTLN( local_ip ); | ||
#ifdef ESP8266_WIFI | ||
#if defined(ESP8266_WIFI) || (defined(SUBNET_MASK) && defined(GATEWAY_IP_ADDRESS)) | ||
stream.config( local_ip , gateway, subnet ); | ||
#else | ||
// you can also provide a static IP in the begin() functions, but this simplifies | ||
|
@@ -902,37 +896,36 @@ void setup() | |
#endif | ||
|
||
/* | ||
* Configure WiFi security | ||
* Configure WiFi security and initiate WiFi connection | ||
*/ | ||
#if defined(WIFI_WEP_SECURITY) | ||
while (wifiStatus != WL_CONNECTED) { | ||
DEBUG_PRINT( "Attempting to connect to WEP SSID: " ); | ||
DEBUG_PRINTLN(ssid); | ||
wifiStatus = stream.begin( ssid, wep_index, wep_key, SERVER_PORT ); | ||
delay(5000); // TODO - determine minimum delay | ||
if (++wifiConnectionAttemptCounter > WIFI_MAX_CONN_ATTEMPTS) break; | ||
} | ||
|
||
stream.begin(ssid, wep_index, wep_key); | ||
#elif defined(WIFI_WPA_SECURITY) | ||
while (wifiStatus != WL_CONNECTED) { | ||
DEBUG_PRINT( "Attempting to connect to WPA SSID: " ); | ||
DEBUG_PRINTLN(ssid); | ||
wifiStatus = stream.begin(ssid, wpa_passphrase, SERVER_PORT); | ||
delay(5000); // TODO - determine minimum delay | ||
if (++wifiConnectionAttemptCounter > WIFI_MAX_CONN_ATTEMPTS) break; | ||
} | ||
|
||
stream.begin(ssid, wpa_passphrase); | ||
#else //OPEN network | ||
while (wifiStatus != WL_CONNECTED) { | ||
DEBUG_PRINTLN( "Attempting to connect to open SSID: " ); | ||
DEBUG_PRINTLN(ssid); | ||
wifiStatus = stream.begin(ssid, SERVER_PORT); | ||
delay(5000); // TODO - determine minimum delay | ||
if (++wifiConnectionAttemptCounter > WIFI_MAX_CONN_ATTEMPTS) break; | ||
} | ||
stream.begin(ssid); | ||
#endif //defined(WIFI_WEP_SECURITY) | ||
|
||
DEBUG_PRINTLN( "WiFi setup done" ); | ||
|
||
/* | ||
* Wait for TCP connection to be established | ||
*/ | ||
while (!streamConnected && ++connectionAttempts <= MAX_CONN_ATTEMPTS) { | ||
delay(500); | ||
DEBUG_PRINT("."); | ||
streamConnected = stream.maintain(); | ||
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: |
||
} | ||
if (streamConnected) { | ||
DEBUG_PRINTLN( "TCP connection established" ); | ||
} else { | ||
DEBUG_PRINTLN( "failed to establish TCP connection" ); | ||
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. This is also reported in 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. This is also misleading currently as I get the failed message if I am not fast enough in starting up my host application. Maybe the while loop should continue until a connection is made and/or use a much longer timeout). Previously the while loop only waited until a connection was made with the router. 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. I didn't have a looked at the debug output so far. Waiting until connected is a drawback if you add active logic that runs independently of the host. That is one reason why I wanted to introduce a hostConnectedCallback. Regarding the timeout, I reduced it by about 30% because an ESP8266 with static IP typically connects in less than 1.5 seconds. Raising the timeout should help somewhat. 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. #define MAX_CONN_ATTEMPTS 20 // [500 ms] -> 10 s should be long enough for a WiFi connect + DHCP + TCP connect in most cases, but I know there are situations where it needs more time, especially if the signal strength is weak. I am still not sure if this is reason enough to use a higher timeout. An easy way to cope with different requirements would be to move the timeout value into the config file and assign a default. |
||
} | ||
printWifiStatus(); | ||
|
||
/* | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,16 +30,16 @@ | |
*/ | ||
//#define WIFI_101 | ||
|
||
//do not modify the following 10 lines | ||
//do not modify the following 11 lines | ||
#if defined(ARDUINO_SAMD_MKR1000) && !defined(WIFI_101) | ||
// automatically include if compiling for MRK1000 | ||
#define WIFI_101 | ||
#endif | ||
#ifdef WIFI_101 | ||
#include <WiFi101.h> | ||
#include "utility/WiFiStream.h" | ||
WiFiStream stream; | ||
#define WIFI_LIB_INCLUDED | ||
#include "utility/WiFiClientStream.h" | ||
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. What is the memory overhead of including both client and server streams simultaneously? 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. Good question. Commenting out one include and looking at the build size should tell. A good linker should notice that the code is not used and skip it. 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. With the Xtensa compiler there is no difference. 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. Verified there is also no difference when compiling for MKR1000 or Arduino Zero (with WiFi 101 shield) |
||
#include "utility/WiFiServerStream.h" | ||
#define WIFI_LIB_INCLUDED | ||
#endif | ||
|
||
/* | ||
|
@@ -57,8 +57,8 @@ WiFiStream stream; | |
//do not modify the following 10 lines | ||
#ifdef ARDUINO_WIFI_SHIELD | ||
#include <WiFi.h> | ||
#include "utility/WiFiStream.h" | ||
WiFiStream stream; | ||
#include "utility/WiFiClientStream.h" | ||
#include "utility/WiFiServerStream.h" | ||
#ifdef WIFI_LIB_INCLUDED | ||
#define MULTIPLE_WIFI_LIB_INCLUDES | ||
#else | ||
|
@@ -85,8 +85,8 @@ WiFiStream stream; | |
#endif | ||
#ifdef ESP8266_WIFI | ||
#include <ESP8266WiFi.h> | ||
#include "utility/WiFiStream.h" | ||
WiFiStream stream; | ||
#include "utility/WiFiClientStream.h" | ||
#include "utility/WiFiServerStream.h" | ||
#ifdef WIFI_LIB_INCLUDED | ||
#define MULTIPLE_WIFI_LIB_INCLUDES | ||
#else | ||
|
@@ -122,12 +122,17 @@ char ssid[] = "your_network_name"; | |
//#define GATEWAY_IP_ADDRESS 0,0,0,0 // REQUIRED for ESP8266_WIFI, optional for others | ||
|
||
|
||
// STEP 4 [REQUIRED for all boards and shields] | ||
// STEP 4 [OPTIONAL for all boards and shields] | ||
// uncomment and replace with the IP address of your server if the Arduino is the TCP client | ||
//#define SERVER_IP 10, 0, 0, 15 | ||
|
||
|
||
// STEP 5 [REQUIRED for all boards and shields] | ||
// define your port number here, you will need this to open a TCP connection to your Arduino | ||
#define SERVER_PORT 3030 | ||
|
||
|
||
// STEP 5 [REQUIRED for all boards and shields] | ||
// STEP 6 [REQUIRED for all boards and shields] | ||
// determine your network security type (OPTION A, B, or C). Option A is the most common, and the | ||
// default. | ||
|
||
|
@@ -200,6 +205,16 @@ char wep_key[] = "your_wep_key"; | |
#error "you must choose between WIFI_NO_SECURITY and WIFI_WPA_SECURITY" | ||
#endif | ||
|
||
/*============================================================================== | ||
* WIFI STREAM (don't change anything here) | ||
*============================================================================*/ | ||
|
||
#ifdef SERVER_IP | ||
WiFiClientStream stream(IPAddress(SERVER_IP), SERVER_PORT); | ||
#else | ||
WiFiServerStream stream(SERVER_PORT); | ||
#endif | ||
|
||
/*============================================================================== | ||
* PIN IGNORE MACROS (don't change anything here) | ||
*============================================================================*/ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
/* | ||
WiFiClientStream.h | ||
|
||
An Arduino Stream that wraps an instance of a WiFiClient. For use | ||
with legacy Arduino WiFi shield and other boards and shields that | ||
are compatible with the Arduino WiFi library. | ||
|
||
Copyright (C) 2016 Jens B. All rights 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. | ||
|
||
See file LICENSE.txt for further informations on licensing terms. | ||
|
||
Parts of this class are based on | ||
|
||
- EthernetClientStream - Copyright (C) 2013 Norbert Truchsess. All rights reserved. | ||
|
||
published under the same license. | ||
|
||
Last updated April 17th, 2016 | ||
*/ | ||
|
||
#ifndef WIFI_CLIENT_STREAM_H | ||
#define WIFI_CLIENT_STREAM_H | ||
|
||
#include "WiFiStream.h" | ||
|
||
#define MILLIS_RECONNECT 5000 | ||
|
||
class WiFiClientStream : public WiFiStream | ||
{ | ||
protected: | ||
uint32_t _time_connect = 0; | ||
|
||
/** | ||
* check if TCP client is connected | ||
* @return true if connected | ||
*/ | ||
virtual inline bool connect_client() | ||
{ | ||
if( _client && _client.connected() ) return true; | ||
|
||
if( _connected ) | ||
{ | ||
stop(); | ||
} | ||
|
||
// active TCP connect | ||
if( WiFi.status() == WL_CONNECTED ) | ||
{ | ||
// if the client is disconnected, try to reconnect every 5 seconds | ||
if( millis() - _time_connect >= MILLIS_RECONNECT ) | ||
{ | ||
_connected = _client.connect( _remote_ip, _port ); | ||
if( !_connected ) | ||
{ | ||
_time_connect = millis(); | ||
} | ||
else if ( _currentHostConnectionCallback ) | ||
{ | ||
(*_currentHostConnectionCallback)(HOST_CONNECTION_CONNECTED); | ||
} | ||
} | ||
} | ||
|
||
return _connected; | ||
} | ||
|
||
public: | ||
/** | ||
* create a WiFi stream with a TCP client | ||
*/ | ||
WiFiClientStream(IPAddress server_ip, uint16_t server_port) : WiFiStream(server_ip, server_port) {} | ||
|
||
/** | ||
* maintain WiFi and TCP connection | ||
* @return true if WiFi and TCP connection are established | ||
*/ | ||
virtual inline bool maintain() | ||
{ | ||
return connect_client(); | ||
} | ||
|
||
/** | ||
* stop client connection | ||
*/ | ||
virtual inline void stop() | ||
{ | ||
if( _client) | ||
{ | ||
_client.stop(); | ||
if ( _currentHostConnectionCallback ) | ||
{ | ||
(*_currentHostConnectionCallback)(HOST_CONNECTION_DISCONNECTED); | ||
} | ||
} | ||
_connected = false; | ||
_time_connect = millis(); | ||
} | ||
|
||
}; | ||
|
||
#endif //WIFI_CLIENT_STREAM_H |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
which compiler needs these?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Xtensa Compiler for the ESP8266 can't do without forward declarations if you want to call a function before it is defined. I havn't checked the dependencies. If there are no circular references reordering the functions can avoid this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After reordering the functions in the sketch the forward definitions can be removed. But there is also the question of context, of keeping certain functions in a textual proximity or order to each other.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Strange I have not run into any compiler errors when using the ESP8266 Arduino core and I have successfully compiled each module that library supports (except ThaiEasyElec's ESPino which fails). At least not as of version 2.1.0.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While compiling I see the version 1.20.0-26 for the Xtensa and a lot of compiler options that are handled by the Arduino IDE. Maybe one of them makes the difference (e.g. for Firmata.cpp):
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, you are compiling via the command line rather than using the Arduino IDE.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, I just changed to verbosity via IDE settings to see what is really happening.