Arduino: mDNS (and OTA) in STA+AP mode

Created on 20 Apr 2017  路  3Comments  路  Source: esp8266/Arduino

Hi

Is it possible to have mDNS and OTA working on the station network _and_ on the softAP network simultaneously.
When using the WIFI_AP_STA mode, mDNS and OTA don't work on the softAP network:
hostname.local is not resolved, and the Arduino IDE doesn't list the network port.

Is there a way to get it working?

This is the sketch I used to test it: comment out the first line to use AP mode only, leave it uncommented to use STA+AP mode.
As you can see, it doesn't work when STATION is defined.

Thanks in advance,
Pieter

Sketch


#define STATION // connect to a WiFi network, as well as creating an access point

#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <ArduinoOTA.h>

const char *APssid         = "SSID";
const char *APpassword     = "password123";

#ifdef STATION
#include "WiFiCredentials.h"
#endif

const char* WiFiHostname = "hostname";      // Host name of the device
const char* dnsName = "hostname";           // Domain name for the mDNS responder
IPAddress apIP(192, 168, 4, 1);             // The IP address of the access point

const char *OTAName = "ESP8266";            // A name and a password for the OTA service, to upload new firmware
const char *OTAPassword = "esp8266";

/*__________________________________________________________SETUP_________________________________________________________*/

void setup() {
  Serial.begin(115200);        // Start the Serial communication to send messages to the computer
  delay(10);
  Serial.println("\r\n\r\nSetup\r\n");

  startOTA();                  // start the Over The Air update services

  startWiFi();                 // Start an access point, and connect to the network specified above

  startMDNS();                 // Start the mDNS responder

}

/*__________________________________________________________LOOP__________________________________________________________*/

void loop() {
  ArduinoOTA.handle();                        // check for over the air updates

#ifdef STATION
  printIP();
#endif
  printStations();
}

/*_________________________________________________________NETWORK_INIT___________________________________________________*/

void startWiFi() {
  WiFi.hostname(WiFiHostname);
#ifdef STATION
  WiFi.mode(WIFI_AP_STA);
#else
  WiFi.mode(WIFI_AP);
#endif
  WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
  WiFi.softAP(APssid, APpassword);             // Start the access point
  Serial.print("Access Point \"");
  Serial.print(APssid);
  Serial.println("\" started\r\n");
#ifdef STATION
  WiFi.begin(ssid, password);            // Connect to the network
  Serial.print("Connecting to ");
  Serial.print(ssid); Serial.println(" ...");
#endif
}

void startOTA() { // start the Over The Air update services
  ArduinoOTA.setHostname(OTAName);
  ArduinoOTA.setPassword(OTAPassword);

  ArduinoOTA.onStart([]() {
#ifdef STATION  // otherwise it crashes when uploading via softAP
    if (WiFi.status() != WL_CONNECTED)
      WiFi.disconnect();
#endif
  });

  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { });

  ArduinoOTA.onEnd([]() { });
  Serial.println("Starting OTA service ...");
  ArduinoOTA.begin();
}

void startMDNS() { // Start the mDNS responder
  Serial.println("Starting mDNS responder ...");
  MDNS.begin(dnsName);
  Serial.print("mDNS responder started: http://");
  Serial.print(dnsName);
  Serial.println(".local");
}

/*__________________________________________________________MISC__________________________________________________________*/

#ifdef STATION
void printIP() {
  static boolean printed = false;
  if (WiFi.status() == WL_CONNECTED) {
    if (printed)
      return;
    Serial.println("Connected");
    Serial.print("IP address:\t");
    Serial.println(WiFi.localIP());
    printed = true;
  } else {
    printed = false;
  }
}
#endif

void printStations() {
  static int prevNumber = 0;
  if (WiFi.softAPgetStationNum() != prevNumber) {
    prevNumber = WiFi.softAPgetStationNum();
    Serial.print(prevNumber);
    Serial.println(" station(s) connected");
  }
}
bug

Most helpful comment

For others wondering about mDNS and AP, STA questions: don't forget to call MDNS.notifyAPChange() after you enable or disable the AP

All 3 comments

@tttapa I recently ran into a similar problem when trying to use an ESP8266 as an AVR programmer. There is an example sketch provided with the ESP8266 core for this named Arduino_Wifi_AVRISP.ino. When investigating this, I learned that support for multiple interfaces (i.e. simultaneously using both the station and access point interfaces) in the mDNS library was recently added. It turns out that there is a defect that is preventing mDNS services from announcing themselves on the station interface. This definitely prevents the Arduino IDE from seeing the necessary service. It seems like this also must be a contributing factor to your problem. For more information take a look at issue #3101. You might try locally applying pull request #3144 to see if it addresses your problem.

A few months ago, it was discoverable in station mode. But in version 2.3 it isn't discoverable.
The same code .. and all the code that you and the esp8266 forums have said.

wifi_station_set_hostname((char*)hstnm); 
WiFi.begin(ssids.c_str(), keys.c_str());
MDNS.begin((char*)hstnm);

Which version of the past, had no problem in this case?

For others wondering about mDNS and AP, STA questions: don't forget to call MDNS.notifyAPChange() after you enable or disable the AP

Was this page helpful?
0 / 5 - 0 ratings

Related issues

dariopb picture dariopb  路  3Comments

Chagui- picture Chagui-  路  3Comments

hulkco picture hulkco  路  3Comments

Marcelphilippeandrade picture Marcelphilippeandrade  路  3Comments

Khorne13 picture Khorne13  路  3Comments