ESP8266: Wifi gets connected, but no internet access - iot

I am trying to connect my ESP8266 NodeMCU to my Mobile Hotspot Wifi
When I try to connect to the ESP Wifi using laptop, It says Wifi Connected, no Internet access.
Which means, The Wifi_SSID and Password are fetched by ESP correctly.
Why is the ESP not able to connect to the Internet?
I have used Arduino IDE for uploading code to ESP8266.
I have uploaded the below code to the ESP8266.
#include <FirebaseArduino.h>
#include <ESP8266WiFi.h>
// Set these to run example.
#define WIFI_SSID "OnePlus3"
#define WIFI_PASSWORD ""
#define FIREBASE_DB_URL "https://my_db_url.firebaseio.com/"
#define FIREBASE_DB_SECRET_KEY "fakezaSyDsdadasddwGClaAy8ltYgywwo6i_VzXgY"
void setup() {
Serial.begin(115200);
pinMode(D1, OUTPUT);
pinMode(D2, OUTPUT);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
Firebase.begin(FIREBASE_DB_URL, FIREBASE_DB_SECRET_KEY);
Firebase.stream("/automation");
}
void loop() {
if (Firebase.failed()) {
Serial.println("streaming error");
Serial.println(Firebase.error());
}
if (Firebase.available()) {
FirebaseObject event = Firebase.readEvent();
String eventType = event.getString("type");
eventType.toLowerCase();
Serial.print(eventType);
if (eventType == "put") {
String path = event.getString("path");
String data = event.getString("data");
if (path.equals("/fan/value")) {
if (data.equals("off")) {
digitalWrite(D1, HIGH);
} else {
digitalWrite(D1, LOW);
}
} else if (path.equals("/light/value")) {
if (data.equals("off")) {
digitalWrite(D2, HIGH);
} else {
digitalWrite(D2, LOW);
}
}
}
}
}

Troubleshooting ESP8266 not connecting to WiFi
Failure to connect to the WiFi network can be caused by some factors. Among them I highlight:
1 - The ESP8266 has a particularity of the initial state of its GPIOs during an initialization. As the intention is to make a connection to the Internet, I suggest that you leave the ESP8266 only with the power and communication connections. If you have a NodeMCU you can use only the USB cable.
2 - Wrong filling in of the access data of the router will cause an error in the connection. Please note that you have to put in your code the WLAN SSID and WLAN PASS information, which are, respectively, the name and password of your network. It is worth remembering that the capture of these characters is case sensitive.
3 - If your router is not connected to the Internet, then you will have feedback via the serial monitor of your local IP, but you will not have confirmation of access with the Google server. Test it with your smartphone or computer and check if everything is fine with your Internet connection.
4 - It is difficult, but I have already seen incompatibility with the internet provider. To solve, test on different networks. I suggest that we carry out tests with your smartphone functioning as a WiFi router. You can even check the connected devices quickly and easily.
You can learn more about it in this link (Eduardo Castro) in Brazilian Portuguese:
https://www.filipeflop.com/blog/como-conectar-o-esp8266-a-internet/

Related

Attempting MQTT connection...failed, rc=-2 try again in 5 seconds problem

A month ago, I created a code and uploaded it to the NodeMCU (ESP8266) in which the NodeMCU establishes connection with the aREST.io MQTT broker. It worked properly.
The code:
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <aREST.h>
WiFiClient espClient;
PubSubClient client(espClient);
aREST rest = aREST(client);
char* key = "the api key in aREST account";
const char* ssid = "SSID";
const char* password = "Pass";
#define trigger 5
#define echo 4
float distance;
void callback(char* topic, byte* payload, unsigned int length);
void setup(void)
{
Serial.begin(115200);
pinMode(trigger, OUTPUT);
pinMode(echo, INPUT);
rest.setKey(key);
client.setCallback(callback);
rest.variable("distance",&distance);
rest.set_name("esp8266");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
}
void loop() {
rest.handle(client);
digitalWrite(trigger, HIGH);
delayMicroseconds(10);
digitalWrite(trigger, LOW);
int timin = pulseIn(echo,HIGH);
distance = (171.5*((timin)))*10E-5;
delay(60);
rest.publish(client, "distance", distance, 60000);
}
void callback(char* topic, byte* payload, unsigned int length) {
rest.handle_callback(client, topic, payload, length);
}
At the moment, the ESP8266 can't connect to the broker. It prints the following message after it connects to WiFi on the serial monitor:
"Attempting MQTT connection...failed, rc=-2 try again in 5 seconds"
I checked the API key about 5 times. it's the right one
I analyzed the network with wireshark and obtained the following:
As shown in the photo, the ESP8266 sends a CONNECT data packet to the aREST broker. The broker responds with the CONNACK packet. It's repeated every 5 seconds the content in the CONNECT packet:
the content of the CONNACK:
I believe the issue may be that the broker is down.
Your code looks like a modified version of the 'ESP8266_cloud.ino' code found in the ArduionIDE examples. I have an ESP8266 D1 and ran that example code with my own API plugin from aREST.io and get the same error message as you.
Running example code 'mqtt_esp8266.ino' I see interaction with my board to the broker, so I don't have reason to believe there's a general hardware or connectivity issue outside of the aREST broker.
Digging into aREST.h, the MQTT broker/server is 'mqtt.arest.io'
Checking on https://downforeveryoneorjustme.com/mqtt.arest.io, they say it's down.
Sorry that's not more helpful :/
I tried contacting the developer/the aREST Instagram page and have yet to hear back. Will keep you posted - please update your findings as well!

How can I use Bonjour on iOS to let other devices connected to my iPhones hotspot know the ip address and port of the server my iOS app is hosting?

I have created an iOS app that hosts a UDP Server. It doesn't seem possible for me to know the IP address of the server before hand. I use this function to get the IP Address:
// Get IP Addresses
void getIPAddresses(std::map<std::string, std::string>& addresses) {
struct ifaddrs *interfaces = NULL;
struct ifaddrs *temp_addr = NULL;
// Retrieve the current interfaces - returns 0 on success
int success = getifaddrs(&interfaces);
if (success == 0) {
// Loop through linked list of interfaces
temp_addr = interfaces;
while (temp_addr != NULL) {
if (temp_addr->ifa_addr->sa_family == AF_INET) {
// Check if interface is en0 which is the wifi connection on the iPhone
addresses[temp_addr->ifa_name] = inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr);
}
temp_addr = temp_addr->ifa_next;
}
}
// Free memory
freeifaddrs(interfaces);
}
As can be seen this function returns an number of IP addresses and without trial and error it doesn't seem possible to determine which IP address the server actually receives UDP packets on.
Is there some way I can do this better using Bonjour ? The devices that connect to my UDP Server can do so because my iPhone acts as a Wifi Hotspot (I share the SSID and Password to the devices in advance).
EDIT:
It seems that whenever I create an Wifi Hotpspot, the UDP Server is accessible on the interface called "Bridge100". So I know what the iP address is. How can I use Bonjour so that other devices connected to my iPhones Wifi Hotspot can know the iP address of my udp server ?

ESP8266 cannot reconnect to last saved WiFi network

I'm using WifiManager library to manually add user's network on configuration portal. Already it works fine, but every time I power off and power on again, it does not connect to network I have established previous. To connect I have to pin out the 'Vcc' of ESP8266 and pin in again and then again connect with ESP8266 network and go to configure portal.
For now I have two lines in code with 'WifiManager';
Good news is that connects to Wifi by configurationPortal.
ESP8266WebServer server; //server variable
void setup() {
initializePin(); //call function
Serial.begin(74880);
delay(500);
//Connect to network
WiFiManager wifiManager;
wifiManager.autoConnect("ESP8266","password");
Serial.println("Connected.");
if (!MDNS.begin("esp8266")) { Serial.println("Error setting up MDNS responder!"); }
else { Serial.println("mDNS responder started"); }
serverSection();
server.begin();
Serial.println("Server started");
}
I need to connect to previous established network,
Also it would be fine to run Configuration Portal if there wont be connection to that network ( for example if device would be transfer to other place)
Your code is supposed to connect to the internet. What happens usually when you use auto connect and it fails is that WL_IDLE_STATUS occurs. Read more about it here: https://www.arduino.cc/en/Reference/WiFiStatus . What I would do is to check if I got that status then I would try to reconnect to the wifi with a delay of 2 seconds. Here is an example:
if (WiFi.status() == WL_IDLE_STATUS) {
delay(2000);
WiFi.begin("yourssid", "password");
}

IOS boost asio connect from ipv6 network

I am trying to connect a dvr using boost asio library in ios. The application works fine in emulator with in ipv4 network. But when I submit the application on Appstore apple rejected the application as it's not work on ipv6 network. And I can see in the apple site that application should support ipv6 network. https://developer.apple.com/news/?id=05042016a
So I think the problem comes at the section where I am trying to connect to DVR using boost library, where the ip address of the DVR is pulled from DB(hard-coded) and below is the relevant part of the code.
boost::asio::io_service io_service_;
tcp::resolver::iterator endpoint_iter_;
tcp::resolver resolver_; //to healp resolving hostname and ip
stringstream strstream;//create a stringstream
strstream << port;//add number to the stream
endpoint_iter_ = resolver_.resolve(tcp::resolver::query(ip.c_str(),strstream.str()));
start_connect(endpoint_iter_);
// Start the deadline actor. You will note that we're not setting any
// particular deadline here. Instead, the connect and input actors will
// update the deadline prior to each asynchronous operation.
deadline_timer_.async_wait(boost::bind(&dvr_obj::check_deadline, this));
//starting thread for dvr connection
io_service_.reset();
thread_ = new boost::thread(boost::bind(&boost::asio::io_service::run, &io_service_));
start_connect method
void start_connect(tcp::resolver::iterator endpoint_iter)
{
try
{
if (endpoint_iter != tcp::resolver::iterator())
{
drill_debug_info("trying to connect %s \n",name.c_str());
// Set a deadline for the connect operation.
deadline_timer_.expires_from_now(boost::posix_time::seconds(10));
// Start the asynchronous connect operation.
socket_.async_connect(endpoint_iter->endpoint(),
boost::bind(&dvr_obj::handle_connect,
this, _1, endpoint_iter));
}
else
{
// There are no more endpoints to try. Shut down the client.
connectivity = false;
}
} catch (int e) {
connectivity = false;
}
}
So I am confused how to change above code to work on IPV6 network. Could not find any solution in Internet.
You can iterate through the endpoints to find an IPv6 endpoint using the code below:
endpoint_iter_ = resolver_.resolve(tcp::resolver::query(ip.c_str(),strstream.str()));
while (endpoint_iter_ != tcp::resolver::iterator())
{
if (endpoint_iter_->endpoint().protocol() == tcp::v6())
break;
++endpoint_iter_;
}
if (endpoint_iter_ != tcp::resolver::iterator())
{
start_connect(endpoint_iter_);
...
}
else
std::cerr << "IPv6 host not found" << std::endl;

Connect to Acquisition unit(WIFI device) from iPhone/iPad programmatically

I have a hardware device Acquisition unit. This device itself act as wifi router and it will send data. I want to connect it from iPhone/iPad.
I heard that using IP address and port number we can connect to the wifi router using socket programming. But I don't have any idea about this socket program to connect to the wifi using IP address and port number.
For this I have tried to get the IP address of a connected wifi router using following code.
NSString *address = #"error";
struct ifaddrs *interfaces = NULL;
struct ifaddrs *temp_addr = NULL;
int success = 0;
// retrieve the current interfaces - returns 0 on success
success = getifaddrs(&interfaces);
if (success == 0) {
// Loop through linked list of interfaces
temp_addr = interfaces;
while(temp_addr != NULL) {
if(temp_addr->ifa_addr->sa_family == AF_INET) {
// Check if interface is en0 which is the wifi connection on the iPhone
if([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:#"en0"]) {
// Get NSString from C String
address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)];
}
}
temp_addr = temp_addr->ifa_next;
}
}
// Free memory
freeifaddrs(interfaces);
return address;
If it is possible to connect to the wifi router using ip address and port number could you please help me with some code or idea.
Please help me..
Thanks
The code you pasted basically returns the device's own IP address, which does not help at all, unless you want to guess router's IPs. You actually can get correct router IP address, see questions below:
Objective-C : How to fetch the router address?
How to get Wi-Fi router IP address on iOS?
Is it possible to get the SSID & MAC Address of Currently connected WiFi Network in an App
After you have this, you can easily connect to it via a normal TCP/IP connection socket, see the following links for more information:
Socket Connection in IOS
http://www.raywenderlich.com/3932/networking-tutorial-for-ios-how-to-create-a-socket-based-iphone-app-and-server
https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/NetworkingTopics/Articles/UsingSocketsandSocketStreams.html
https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Streams/Articles/NetworkStreams.html
Or to make things even easier for you, there are a couple of community libraries that will make connecting to a server like a breeze:
https://github.com/pkyeck/socket.IO-objc
https://github.com/dreese/FastSocket
My suggestion is to read through those documents first, so you understand the basics of networking in iOS / OS X (which is actually fairly similar to Unix in this aspect). After try the libraries and wrappers you can find on CocoaPods and GitHub. If you are stopped by some specific issue at that point, we might be able to help you. We cannot do all the work for you.
So to answer: Yes, it is possible.

Resources