Go Down

Topic: ESP8266 range question (Read 560 times) previous topic - next topic

notsolowki

Nov 14, 2019, 12:01 am Last Edit: Nov 14, 2019, 12:04 am by notsolowki
What is the typical range of an NodeMCUv1 esp8266 running in SoftAP mode in line of sight without noisy environment. I'm getting about 20ft without loosing connection with multiple android phones. However I am able to connect to an AP from pretty far away?!?

Klaus_K

#1
Nov 14, 2019, 02:53 am Last Edit: Nov 14, 2019, 02:57 am by Klaus_K
The range of wireless connection depends on how "loud" you are shouting, how far are sender and receiver apart, what is in between and how sensitive are the ears on the other side. If you communicate both ways, the same is true for the way back. It called the link budget and uses a love/hate logarithmic unit called Decibel (dB).

From this you can see there are a couple of points of failure.

If your WiFi access point has good antennas, a sensitive receiver and a high power transmiter you will be able to talk to it and listen to it over longer distances, without changing anything on your side.

Your mobile phone needs to be cute and cool. It can't have antennas sticking out of it and it can't use as much power.

If you want to compare the chips capability. Google 8266 data sheet. Then look for TX Power and RX Sensitivity. It's usually on the first couple of pages because these are key differentiators for wireless chips.

TX Power, a larger positive number means more power can be sent. This does not mean you are allowed to send with this much power. This is different for each country and for each frequency band.

RX Sensitivity, a more negative value means more sensitivity.

Beware: 0 dBm means 1mW and not 0 mW.

notsolowki

#2
Nov 14, 2019, 09:06 am Last Edit: Nov 14, 2019, 09:07 am by notsolowki
That is not a helpful answer. Cellphone infact do have antennas built into the case. They have multiple antennas for 5ghz an 2.4ghz. This is not a cellphone to esp8266 issue. This is a issues with the esp8266 itself. 20ft does not seem right. Or does it? Nodemcu to Nodemcu I get 20ft. I am going to assume this isn't right. What exactly is causing this. I use multiple types of modules all with the same exact result. Is this to be expected with standard nodemcu ap????

Robin2

I have had a pair of ESP8266 modules working with ESP-NOW at a range of about 100 metres outdoors. I don't see why the same range would not be possible with WiFi.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

notsolowki

#4
Nov 14, 2019, 10:13 am Last Edit: Nov 14, 2019, 10:15 am by notsolowki
I have had a pair of ESP8266 modules working with ESP-NOW at a range of about 100 metres outdoors. I don't see why the same range would not be possible with WiFi.

...R
I dont know how reliable wifioverview360 for android is but at about 20-30ft in 802.11b mode at max power inside my home about 30ft away I'm showing
-80dB. The esp8266 is in my hallway and I'm standing at the other end of the hallway. I soldered a 2.4ghz antenna from one of my nrf24 card directly to the esp8266 and I cant tell if it helped any. I may have gotten an extra 10ft out of it.

What would be the ideal esp8266 breakout board for the best possible SoftAP range?

Klaus_K

I am sorry the answer was not helpful. The fact is, antennas in mobile phones need to make compromises that antennas in wifi access point do not need to make.

WiFi access points are designed to get good connections in houses with lots of walls, steel and the fact that they are not moved around. Power usage and small housing are of second concern. Why are routers ten times the size of a mobile phones, made from cheap plastic, many have antennas sticking out of them and get warm?

Your mobile phone has metal inside is very small and you are conditioned to move when you have a bad connection.

WiFi uses 2.4GHz, which is the resonance frequency of water. That means the signals are absorbed by air moisture. That's why it is a free ISM band. You cannot use it for broadcast of TV and other commercial services. The signals are very weak and good antennas and sensitive receivers are important.

Soldering antennas to your nodes will not work in most cases. For most electrical engineers this is black magic. The ones who know this stuff, use very expensive equipment and experimentation to get the best out of every situation. Many engineers use readymade modules with build in antennas because they do not want to deal with high frequency issues. So do not feel bad about it.

There are WiFi modules with external antennas. This will give you the best chance of getting longer distances between nodes.

If it does not have to be WiFi and you do not have large amounts of data look at sub GHz technologies like LoRa. You can achieve longer distances easier.

notsolowki

#6
Nov 14, 2019, 09:13 pm Last Edit: Nov 14, 2019, 09:25 pm by notsolowki
Is there a way to override the mW output from esp8266? Is 20.5 is maximum output power period? Shouldn't this be more like 40mw? I didn't see any mention in the data sheet about the output mW of the antenna. I'm not very good at understand the sensitivity details either. I'm just assuming its 20.5 mW

srnet

WiFi uses 2.4GHz, which is the resonance frequency of water. That means the signals are absorbed by air moisture. That's why it is a free ISM band.
There is absorbtion of radio waves due to mositure in the air, but the effect is very small indeed, fractions of a dB per kilometer.
http://www.50dollarsat.info/
http://www.loratracker.uk/

notsolowki

#8
Nov 14, 2019, 10:20 pm Last Edit: Nov 14, 2019, 10:20 pm by notsolowki
There is absorbtion of radio waves due to mositure in the air, but the effect is very small indeed, fractions of a dB per kilometer.
So am I getting the expected behavior of a standard nodemcu with the PCB trace antenna?  Btw its 10 degrees where I'm at so not much moisture in the air.

notsolowki

#9
Nov 14, 2019, 11:02 pm Last Edit: Nov 14, 2019, 11:07 pm by notsolowki
Another strange thing ive noticed about the client side of the esp8266 when i connect it to my home network the ping delay is 500+ms most of the time timing out. however it still seems to be functioning? when i changed the server to STA mode and connected it to my home network the ping delay is only 5ms. any ideas?

Code: [Select]
c:\Windows\System32>ping 10.0.0.13

Pinging 10.0.0.13 with 32 bytes of data:
Reply from 10.0.0.13: bytes=32 time=1188ms TTL=255
Reply from 10.0.0.13: bytes=32 time=570ms TTL=255
Request timed out.
Request timed out.

Ping statistics for 10.0.0.13:
    Packets: Sent = 4, Received = 2, Lost = 2 (50% loss),
Approximate round trip times in milli-seconds:
    Minimum = 570ms, Maximum = 1188ms, Average = 879ms

c:\Windows\System32>

Server,
Pinging 10.0.0.12 with 32 bytes of data:
Reply from 10.0.0.12: bytes=32 time=1ms TTL=255
Reply from 10.0.0.12: bytes=32 time=1ms TTL=255
Reply from 10.0.0.12: bytes=32 time=9ms TTL=255
Reply from 10.0.0.12: bytes=32 time=1ms TTL=255

Ping statistics for 10.0.0.12:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 1ms, Maximum = 9ms, Average = 3ms

c:\Windows\System32>





Klaus_K

I do not know exactly which libraries you are using, please let me know which one, if the function calls below do not exist in your library.

First, look at the ESP8266 data sheet for TX Power. You should see

TX Power 802.11 b: + 20dBm (that is 100mW)
TX Power 802.11 g: + 17dBm (that is 50mW)
TX Power 802.11 n: + 14dBm (that is 25mW)

RX Power 802.11 b: - 91dBm (that is 8 to the power of -10 mW) most sensitive
RX Power 802.11 g: - 75dBm (that is 3 to the power of -8 mW) second most sensitive
RX Power 802.11 n: - 72dBm (that is 6 to the power of -8 mW) least sensitive but close to 2

So 802.11b should give you the longest distance, which makes sense it has the lowest bitrate. But test all three modes to see which one is the best in your environment.

There should be a function WiFi.setPhyMode(PHY_MODE_11B).

If this is set you should be able to use the WiFi.setOutputPower(20.5); to set the maximum output power of 100mW. Be careful when you call this function when you have chosen a different phy mode. I am not sure what happens. You would need to look at the source code. It could just simply call the maximum possible, the minimum or do nothing at all.

notsolowki

#11
Nov 14, 2019, 11:31 pm Last Edit: Nov 14, 2019, 11:34 pm by notsolowki
I do not know exactly which libraries you are using, please let me know which one, if the function calls below do not exist in your library.

First, look at the ESP8266 data sheet for TX Power. You should see

TX Power 802.11 b: + 20dBm (that is 100mW)
TX Power 802.11 g: + 17dBm (that is 50mW)
TX Power 802.11 n: + 14dBm (that is 25mW)

RX Power 802.11 b: - 91dBm (that is 8 to the power of -10 mW) most sensitive
RX Power 802.11 g: - 75dBm (that is 3 to the power of -8 mW) second most sensitive
RX Power 802.11 n: - 72dBm (that is 6 to the power of -8 mW) least sensitive but close to 2

So 802.11b should give you the longest distance, which makes sense it has the lowest bitrate. But test all three modes to see which one is the best in your environment.

There should be a function WiFi.setPhyMode(PHY_MODE_11B).

If this is set you should be able to use the WiFi.setOutputPower(20.5); to set the maximum output power of 100mW. Be careful when you call this function when you have chosen a different phy mode. I am not sure what happens. You would need to look at the source code. It could just simply call the maximum possible, the minimum or do nothing at all.
Im not exactly sure what im looking for in the library that happens when calling that function. However i am using those functions. I tried,b,n,g and b giving the best range i have left it there as i don't need a high data rate. at b mode at max output power 20.5 i still am at -80 - -85 db when 20-30ft away from the SoftAP. I will post my client code below. it seems something in my loop (probably the sensor read function) was causing the extremely high latency. The main issue here now is i cannot connect these to my home network as  b,g,n modes will drastically slow down the wireless network all together. This is why i would like to use the esp8266 in SoftAP mode so i don't need to use local home network resources.

Code: [Select]
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <OneWire.h>
#include <DallasTemperature.h>

IPAddress Server(10, 0, 0, 12);

bool ready = true;
const int oneWireBus = 0;
const char* ssid = "Wireless3";
const char* password = "123456!!";
char verifyStart[7];
char verifyEnd[7];
unsigned int localUdpPort = 4220;  // local port to listen on
char incomingPacket[255];  // buffer for incoming packets
int ServerPort = 4210;

byte Temp1[8] = {0x28, 0x0E, 0xD3, 0x45, 0x92, 0x15, 0x02, 0xB4 };

unsigned long now = 0;
unsigned long now2 = 0;

struct packet {
  int local;
  float temp;
};
packet localData;
WiFiUDP Udp;
OneWire oneWire(oneWireBus);
DallasTemperature sensors(&oneWire);
void setup() {
  sensors.setResolution(Temp1, 11);
  WiFi.persistent(0);
  WiFi.softAPdisconnect();
  WiFi.mode(WIFI_STA);
  Serial.begin(115200);
  Serial.println();
  WiFi.setOutputPower(20.5);
  WiFi.setAutoConnect(true);
  WiFi.setPhyMode(WIFI_PHY_MODE_11N);

  WiFi.begin(ssid, password);
  IPAddress ip(10, 0, 0, 13);
  IPAddress gateway(10, 0, 0, 1);
  IPAddress subnet(255, 0, 0, 0);
  WiFi.config(ip, gateway, subnet);
  sensors.begin();
  Serial.println(" connected");
  Udp.begin(localUdpPort);
  Serial.printf("Now listening at IP %s, UDP port %d\n", WiFi.localIP().toString().c_str(), localUdpPort);
}

void averageReading () {
  ready = false;
  Serial.println("2");
  float average = 0.0 ;
  for (byte i = 0 ; i < 20 ; i++) {
    sensors.requestTemperatures();
    average +=  sensors.getTempFByIndex(0); //get temp reading from dallas library
  }
  if (average / 20 > -10 && average / 20 < 199) {
    localData.temp = average / 20;
  }
  Serial.print(localData.temp);
  Serial.println("ºF");
  sendPacket();
}

void sendPacket() {
  Serial.println("3");
  const char delimiter[] = "NODE01";
  const char delimiter2[] = "01NODE";

  Udp.beginPacket(Server, ServerPort);
  Udp.write((const uint8_t *)delimiter, sizeof(delimiter) - 1);
  Udp.write((const uint8_t *)&localData, sizeof(localData));
  Udp.write((const uint8_t *)delimiter2, sizeof(delimiter2) - 1);
  Udp.endPacket();
  ready = true;
}
void loop()
{
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    //Serial.print(".");
  }
  if (ready) {
    if (millis() - now2 >= 550) {
      //Serial.println("1");
     // averageReading ();
      now2 = millis();
    }
  }

  int packetSize = Udp.parsePacket();
  if (packetSize) {
    Serial.printf("Received %d bytes from %s, port %d\n", packetSize, Udp.remoteIP().toString().c_str(), Udp.remotePort());
    int len = Udp.read(incomingPacket, 800);
    strncpy(verifyStart, (char*)incomingPacket, 6 );
    strncpy (verifyEnd, (char*)incomingPacket + len - 6 , 7 );
    Serial.println(verifyStart);
    Serial.println(verifyEnd);
    if (strcmp(verifyStart, "NODECM") == 0) {
      const char ACK[] = "ACKED1";
      Udp.beginPacket(Server, ServerPort);
      Udp.write((const uint8_t *)ACK, sizeof(ACK) - 1);
      Udp.endPacket();
    }
  }
}


right now i have it set to n mode just because its connected to my wireless router.

Klaus_K

Regarding the ping, I do not have a nodemcu. I have a ATWINC1500 WiFi. After a long time, I get 46ms ping delay for the first one and then just below 10ms.

The delay probably comes from the power management. Embedded WiFi modules need to save as much power as possible to compete in the market. Maybe the ESP8266 firmware developer where a bit too aggressive and choose to have longer delays in favor of saving power. It sounds like a good idea to have longer delay and lower power in one mode and use some more power but have shorter delay in another mode. That could explain the difference between AP and STA mode.

notsolowki

Regarding the ping, I do not have a nodemcu. I have a ATWINC1500 WiFi. After a long time, I get 46ms ping delay for the first one and then just below 10ms.

The delay probably comes from the power management. Embedded WiFi modules need to save as much power as possible to compete in the market. Maybe the ESP8266 firmware developer where a bit too aggressive and choose to have longer delays in favor of saving power. It sounds like a good idea to have longer delay and lower power in one mode and use some more power but have shorter delay in another mode. That could explain the difference between AP and STA mode.
I can't physically measure the transmit power. But it sure seems to me that at a 100mw I should get a lot more than 30ft range. Maybe your on to something. I will reflash the firmware and see what happens

notsolowki

So i reflashed the firmware and its the same result. i flashed the firmware from here https://github.com/espressif/ESP8266_AT/tree/master/bin  

i think i just need a better module or something. not setting the power to high resulted in a weaker connection.

Heres my code for the SoftAP.

Code: [Select]
//extern "C"{
//  #include "user_interface.h"
//}
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <LiquidCrystal_I2C.h>
IPAddress local_IP(192, 168, 4, 1);
IPAddress gateway(192, 168, 4, 1);
IPAddress subnet(255, 255, 255, 0);

IPAddress Client1(192, 168, 4, 100);
LiquidCrystal_I2C lcd(0x27, 20, 4);
WiFiUDP Udp;
unsigned long previousMillis = 0;
unsigned long minmaxwait = 0;
unsigned long minmaxwait2 = 0;
int ledState = LOW;
const long interval = 300;
bool running = false;
bool alarm = false;
const char* ssid = "weatherStation";
const char* password = "a1b2c3d4";
unsigned long now = 0;
unsigned long now2 = 0;
unsigned long now3 = 0;
unsigned long now4 = 0;
unsigned int localUdpPort = 4210;  // local port to listen on
unsigned int clientPort = 4220;
char incomingPacket[800];  // buffer for incoming packets
float maxTemp = -99;
float minTemp = 199;
struct packet {
  int local;
  float temp;
};
packet localData;

void setup() {
  WiFi.setPhyMode(WIFI_PHY_MODE_11B);
  pinMode(12, INPUT_PULLUP);
  digitalWrite(12, HIGH);
  pinMode(14, OUTPUT);
  digitalWrite(14, LOW);
  lcd.init();
  lcd.backlight();
  //WiFi.setOutputPower(20.5);
  WiFi.persistent(0);
  Serial.begin(115200);
  Serial.println();
  WiFi.mode(WIFI_AP);
 

  while (!WiFi.softAP(ssid, password, 9, false, 15)) {
    delay(500);
    Serial.print(".");
  }
  Serial.println(WiFi.softAPConfig(local_IP, gateway, subnet) ? "Ready" : "Failed!");
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("CONNECTING!!");
  Udp.begin(localUdpPort);
  Serial.printf("Now listening at IP %s, UDP port %d\n", WiFi.softAPIP().toString().c_str(), localUdpPort);
}

void sendCommand(IPAddress to, char* data,  bool requestResponse) {
  char* packetData = data;
  const char delimiter[] = "NODECM";
  const char delimiter2[] = "CMNODE";
  Udp.beginPacket(to, clientPort);
  if (requestResponse) {
    Udp.write((const uint8_t*)delimiter, sizeof(delimiter) - 1);
    Udp.write((const char*)packetData, sizeof(packetData));
    Udp.write((const uint8_t*)delimiter2, sizeof(delimiter2) - 1);
  } else {
    Udp.write((const char*)packetData, sizeof(packetData));
  }
  Udp.endPacket();
}

void loop()
{
  if (running) {
    if (millis() - now4 >= 1000) {
      if (minTemp < 57) {
        alarm = true;
        lcd.setCursor(0, 3);
        lcd.print("TOO COLD!!");
      }
      if (maxTemp > 91) {
        alarm = true;
        lcd.setCursor(0, 3);
        lcd.print("TOO HOT!!");

      }
      now4 = millis();
    }

  }
  if (alarm) {


    unsigned long currentMillis = millis();

    if (currentMillis - previousMillis >= interval) {
      previousMillis = currentMillis;
      if (ledState == LOW) {
        ledState = HIGH;
      } else {
        ledState = LOW;
      }
      digitalWrite(14, ledState);

    }
  }
  if (digitalRead(12) == LOW) {
    maxTemp = -99;
    minTemp = 199;
    alarm = false;
    lcd.setCursor(0, 3);
    lcd.print("            ");
    digitalWrite(14, LOW);
  }
  int packetSize = Udp.parsePacket();
  if (packetSize)
  {
    // Serial.println("Message");
    int len = Udp.read(incomingPacket, 800);
    char verifyStart[7];
    char verifyEnd[7];
    Serial.println((char*)incomingPacket);
    strncpy (verifyStart, (char*)incomingPacket, 7 );
    strncpy (verifyEnd, (char *)incomingPacket + len - 6 , 7 );
    if (strcmp(verifyStart, "NODE01") == 0) {
      if (strcmp(verifyEnd, "01NODE") == 0) {
        // Serial.println("Node01");
        memcpy(&localData, incomingPacket + 6, sizeof(localData));
        //Serial.print("Tempature is  ");

        if (localData.temp > -32 && localData.temp < 199) {
          if (localData.temp > maxTemp) {
            if (millis() - minmaxwait >= 3000) {
              running = true;
              maxTemp = localData.temp;
              minmaxwait = millis();
            }
          } else {
            minmaxwait = millis();
          }
          if (localData.temp < minTemp) {
            if (millis() - minmaxwait2 >= 3000) {
              running = true;
              minTemp = localData.temp;
              minmaxwait2 = millis();
            }
          } else {
            minmaxwait2 = millis();
          }
        }
        lcd.setCursor(0, 0);
        lcd.print("Temperature:");
        if (localData.temp > -32 && localData.temp < 199) {
          lcd.setCursor(12, 0);
          lcd.print("      ");
          lcd.setCursor(12, 0);
          lcd.print(localData.temp);

        }

        lcd.setCursor(0, 1);
        lcd.print("Max Temp:");
        lcd.setCursor(9, 1);
        lcd.print("      ");
        lcd.setCursor(9, 1);
        lcd.print(maxTemp);
        lcd.setCursor(0, 2);
        lcd.print("Min Temp:");
        lcd.setCursor(9, 2);
        lcd.print("      ");
        lcd.setCursor(9, 2);
        lcd.print(minTemp);

        //   Serial.println(localData.temp);
        now = millis();
      }
    }
    if (strcmp(verifyStart, "RETURN") == 0) {
      now3 = millis();
    }
    Serial.println("hello");
    Serial.println(len);
    Serial.println(verifyStart);
    Serial.println(verifyEnd);
  }
}



Go Up