esp8266 / Arduino

ESP8266 core for Arduino
GNU Lesser General Public License v2.1
16.01k stars 13.33k forks source link

WiFiClient fails to connect to ESP8266 access point #2548

Closed vks007 closed 8 years ago

vks007 commented 8 years ago

Basic Info

WiFiClient fails to connect to ESP8266 access point (I hope I am posting it at the right place)

Hardware: ESP8266-01 Core Version: 2.3.0

Description

I am trying to connect between two ESP8266-01 chips using one as an access point and another in the station mode connecting to the AP. I am using a simple WiFiClient (from the examples) to create a connection to an access point hosted by another ESP01 It fails to connect to it.

I have tried using my router WiFi as an access point and the ESP8266 client connects to it fine. It is able to request URLs and response from the same but when I just change the settings to an access point hosted by a ESP01 , it fails with an error. Can you please help me identify why does it fail only for the ESP8266-01 access point. Please note that I am able to connect to this access point ESP02 using my browser and request for a page, It works well with no issues but not with another ESP Client.

Settings in IDE

Module: Generic ESP8266 Module Flash Size: 512K CPU Frequency: 80Mhz Flash Mode: DIO Flash Frequency: 40Mhz Upload Using: SERIAL Reset Method: ck

Sketch

/*
 *  This sketch sends data via HTTP GET requests to data.sparkfun.com service.
 *
 *  You need to get streamId and privateKey at data.sparkfun.com and paste them
 *  below. Or just customize this script to talk to other HTTP servers.
 *
 */

#include <ESP8266WiFi.h>

const char* ssid     = "ESP02";
const char* password = "pswdesp002";
//const char* ssid     = "EAGLE_EXT";
//const char* password = "0123456789";

const char* host = "192.168.4.1";
//const char* host = "192.168.1.1";
const char* streamId   = "";
const char* privateKey = "";

void setup() {
  Serial.begin(115200);
  delay(10);
  monitorWiFi();
}

void monitorWiFi()
{
  // We start by connecting to a WiFi network
  if(WiFi.status() != WL_CONNECTED){
    Serial.println();
    Serial.println();
    Serial.print("Connecting to ");
    Serial.println(ssid);

    WiFi.begin(ssid, password);

    while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
    }

    Serial.println("");
    Serial.println("WiFi connected");  
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
  }
}

int value = 0;

void loop() {
  delay(5000);
  ++value;

  monitorWiFi();
  Serial.print("connecting to ");
  Serial.println(host);

  // Use WiFiClient class to create TCP connections
  WiFiClient client;
  const int httpPort = 80;
  if (!client.connect(host, httpPort)) {
    Serial.println("connection failed");
    return;
  }

  // We now create a URI for the request
  String url = "/setlevel/";
  url += "&value=";
  url += "50";

  Serial.print("Requesting URL: ");
  Serial.println(url);

  // This will send the request to the server
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" + 
               "Connection: close\r\n\r\n");
  unsigned long timeout = millis();
  while (client.available() == 0) {
    if (millis() - timeout > 5000) {
      Serial.println(">>> Client Timeout !");
      client.stop();
      return;
    }
  }

  // Read all the lines of the reply from server and print them to Serial
  while(client.available()){
    String line = client.readStringUntil('\r');
    Serial.print(line);
  }

  Serial.println();
  Serial.println("closing connection");
}

Debug Messages


Connecting to ESP02
.......
WiFi connected
IP address: 
192.168.4.2
connecting to 192.168.4.1
:err -8
connection failed
connecting to 192.168.4.1
:err -8
connection failed
connecting to 192.168.4.1
:err -8
connection failed
connecting to 192.168.4.1
:err -8
connection failed
chg_B1:-40
connecting to 192.168.4.1
:err -8
connection failed
chg_B2:0
connecting to 192.168.4.1
:err -8
connection failed
connecting to 192.168.4.1
:err -8
connection failed
vks007 commented 8 years ago

I was able to solve this issue by including the line WiFi.mode(WIFI_STA); before WiFi.begin(ssid, password); in my client ESP8266 code. and whola! the problem solved. Although if you go into the code of WiFi.begin(ssid, password); , I think it sets the station mode to STA but not sure why does it need to be set explicitly. I got this suggestion from another website where people faced the same issue.

arlaor commented 8 years ago

@vks007 for me does not work connection failed connecting to 192.168.4.1

Do you know if there is another solution?

vks007 commented 8 years ago

Hi, "connection failed" is a generic error, Have you tried getting the actual error code returned for failure? You can modify the file C:\Users\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266WiFi\src\ESP8266WiFiSTA.cpp and put in custom codes, if you need ,to get the exact error code. I have pasted part of the code below from ESP8266WiFiSTA.cpp from the place where it returns the error codes. The file may be at a different path for you, you will have to find it.

wl_status_t ESP8266WiFiSTAClass::status() { station_status_t status = wifi_station_get_connect_status();

switch(status) {
    case STATION_GOT_IP:
        return WL_CONNECTED;
    case STATION_NO_AP_FOUND:
        return WL_NO_SSID_AVAIL;
    case STATION_CONNECT_FAIL:
    case STATION_WRONG_PASSWORD:
        return WL_CONNECT_FAILED;
    case STATION_IDLE:
        return WL_IDLE_STATUS;
    default:
        return WL_DISCONNECTED;`
arlaor commented 8 years ago

@vks007 Fails to make it work with the mentioned file. Now I'm trying to connect with websocketclient_demo.ino file, with which achievement connection to 192.168.4.1 but the handshake fails. Now I'm trying to solve this problem. If you know anything about this problem, I thank

KD4Z commented 8 years ago

@vks007 , Thanks for posting the workaround you found regarding forcing the WiFi.mode(WIFI_STA) before the .begin() That worked for me. Phew. Same situation. Using WiFiClient Example to connect to another ESP webserver. Must be something needing initialization. I blew 3 hours fighting this.

arlaor commented 8 years ago

Hi @vks007 I have managed to solve it by using WebSocketClient. thanks

vks007 commented 8 years ago

Good that you were able to solve your issue but the core reason remains unsolved.... maybe you'll worry about it some other day :)

diaverde commented 7 years ago

Thanks for sharing your solution, it worked like a charm!

royseberg commented 6 years ago

I have a similar problem where the WiFiClient client.connect fails when switching to another SSID but works on the initial one. I have two ESP 12F servers to provide temperatures from two different locations, and a 3rd one to read the data from each one and display it on a Nokia 5110 .The first connection works but the second one (within the same sketch) fails. Any ideas?

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // To display temperatures from 2 servers in basement and // kitchen on Nokia 5110 //------------------------------------------------------ Apr 30 2018

include

include

include

include

Adafruit_PCD8544 display = Adafruit_PCD8544(2, 5, 4); //DC, CE, RST (MOSI=DIN on pin 13, SCLK on pin 14) char* ssid; bool flip = false; //toggle flag to switch from one SSID to the other

void setup() { display.begin(); display.setContrast(60); display.setTextSize(1); display.setTextColor(BLACK); display.setCursor(0,0); display.clearDisplay(); Serial.begin(9600); Serial.setDebugOutput(true); WiFi.mode(WIFI_STA);// station mode }

unsigned long startWait; const char* host = "192.168.4.1"; const int httpPort = 80; String url;

void loop() { if(!flip)ssid= "ESP 01";//if the flag is 0 start with basement server else ssid = "ESP 12F"; //if flag is 1 switch to kitchen WiFi.begin(ssid);// connect to either one of the two ESP8266 servers (no password) if(!flip){ display.setCursor(0,0); display.clearDisplay(); } startWait = millis(); while ((WiFi.status() != WL_CONNECTED) && (millis() - startWait) < 5000 ){ delay(500); Serial.print(".");
} url=(String)WiFi.localIP(); if(flip) display.print("Ktch "); else display.print("Bsmt "); display.display(); WiFiClient client; if(!client.connect(host, httpPort)){ display.print("fail");//this always fails on second pass display.display(); flip=!flip; return;//back to begining of loop() } //// send the request to the server (it works without url also) client.print(String("GET /") + url+ " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "Connection: close\r\n" + "r\n"); startWait=millis(); while(!client.available() && (millis()-startWait) < 5000); if(client.available()){ String line = client.readStringUntil('\r'); String val=line.substring(0,2);//get only the first 2 characters 0,1 display.print(val); display.println(" F"); display.display(); client.stop(); } flip=!flip; WiFi.disconnect(); }

pipi61 commented 6 years ago

try: use two client, and connect to one server

devyte commented 6 years ago

@royseberg Every time you switch ssid, the credentials get written to flash, at the same place. Switching back and forth like that wears the flash sector. Did your code ever work? If so, and it doesn't work any more, it means your flash is burned. If you're going to do that, at least use persistent false.

royseberg commented 6 years ago

What do you mean by persistent false? And is there any way to modify the Wifi library so the credentials are written to ram instead of EEPROM ? Thanks for your comments.