'How to convert Wifi signal strength from Quality (percent) to RSSI (dBm)?

How should I convert Wifi signal strength from a Quality in percentage, usually 0% to 100% into an RSSI value, usually a negative dBm number (i.e. -96db)?



Solution 1:[1]

In JS I prefer doing something like:

Math.min(Math.max(2 * (x + 100), 0), 100)

My personal opinion is that it's more elegant way to write it, instead of using if's.

Solution 2:[2]

From experience:

  1. Less than -50dB (-40, -30 and -20) = 100% of signal strength
  2. From -51 to -55dB= 90%
  3. From -56 to -62dB=80%
  4. From -63 to -65dB=75%

    The below is not good enough for Apple devices

  5. From -66 to 68dB=70%
  6. From -69 to 74dB= 60%
  7. From -75 to 79dB= 50%
  8. From -80 to -83dB=30%
    Windows laptops can work fine on -80dB however with slower speeds

Solution 3:[3]

Im glad I found this post cause I was looking for a way to convert the dbm to percentage. Using David's post, I wrote up a quick script in python to calculate the quality percentage.

#!/usr/bin/env python3
import os
import platform

system = platform.system()
if system == 'Linux':
    cmd = "iwconfig wlan0 | grep Signal | /usr/bin/awk '{print $4}' | /usr/bin/cut -d'=' -f2"
elif system == 'Darwin':
    cmd = "/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I | grep CtlRSSI | awk '{ print $NF; }"
else:
    print("Unsupported os: {}".format(system))

dbm = os.popen(cmd).read()
if dbm:
    dbm_num = int(dbm)
    quality = 2 * (dbm_num + 100)
    print("{0} dbm_num = {1}%".format(dbm_num, quality))
else:
    print("Wifi router connection signal strength not found")

In order to get the highest wifi quality from where my computer is located, I moved/rotated my antenna until I received the highest quality. To see real time quality, I ran the above script using:

watch -n0.1 "python getwifiquality.py"

Solution 4:[4]

From RSSI vs RSS:

RSSI - Received Signal Strength Indicator RSS - Received Signal Strength

RSSI is an indicator and RSS is the real value. Ok, now what do you mean by indicator, indicator mean it can be a relative value and RSSI is always a positive value and there is no unit for the RSSI.

We can say RSSI is for common man to understand. RF values are always told in dBm and the values are negative values most of the time. To make it easy for the people to understand these negative values are converted to positive values through scaling.

Say for example, if the maximum signal strength is 0 dBm and minimum is -100 dBm. We can scale it like as explained. We can put 0 dBm and more (RSS) as 100 RSSI (i. e. maximum RSSI) and -100 dBm (or less) as 0 RSSI (minimum RSS).

Solution 5:[5]

I know this may be late but this may help someone in the future.

I took the value of dBm 30-90 for RSSI and correlated it to 100-0 %.

I used the basic linear equation to get the answer.

y = mx + b

We know our x values for dBm as 30 and 90. We know our y values for % as 100 and 0.

We just need to find the slope. So we can make it linear.

m = 100-0/30-90

  = 100/-60

  = -5/3

b = y - mx

 = 0 + 5/3*90
 = 150

Final equation to put in code when you know the RSSI value.

% = 150 - (5/3) * RSSI

Note I did take the RSSI value that is normally negative and multiplied by the absolute value to get positive numbers.

quality = abs(RSSI)
% = 150 - (5/3) * quality

Solution 6:[6]

This article is a more detailed explanation of mW, dBm and RSSI

http://madwifi-project.org/attachment/wiki/UserDocs/RSSI/Converting_Signal_Strength.pdf?format=raw

According to it RSSI do not have a unit. It's a value defined in 802.11 standard and calculated by nic card and sent to OS. The nic card vendor should provide a mapping table of dBm-RSSI values.

Sorry for the direct link, but I can not found the original page for the file link.

Solution 7:[7]

Mentioned pseudocode will not work all the ranges, the ranges example (-80dBm to 0, and -40dBm to 100).

Generic simple logic to map any range to 0 to 100. Usage example, for below code ConvertRangeToPercentage(-80,-40,-50)

int ConvertRangeToPercentage (int a_value_map_to_zero, int a_value_map_to_100, int a_value_to_convert)
{

   int percentage = 0;

   if (a_value_map_to_zero < a_value_map_to_100)
   {
      if (a_value_to_convert <= a_value_map_to_zero)
      {
         percentage = 0;
      }
      else if (a_value_to_convert >= a_value_map_to_100)
      {
         percentage = 100;
      }
      else
      {
         percentage = (a_value_to_convert - a_value_map_to_zero) * 100 / (a_value_map_to_100 - a_value_map_to_zero);
      }
   }
   else if (a_value_map_to_zero > a_value_map_to_100)
   {
      if (a_value_to_convert >= a_value_map_to_zero)
      {
         percentage = 0;
      }
      else if (a_value_to_convert <= a_value_map_to_100)
      {
         percentage = 100;
      }
      else
      {
         percentage = (a_value_to_convert - a_value_map_to_zero) * 100 / (a_value_map_to_100 - a_value_map_to_zero);
      }
   }
   else
   {
      percentage = 0;
   }

   return percentage;
}

Solution 8:[8]

Ok.. I agree...but why is then:

 Quality=29/100  Signal level=-78 dBm
 Quality=89/100  Signal level=-55 dBm
 Quality=100/100 Signal level=-21 dBm

this does not agree with the formula percentage=quality/2 - 100.

Solution 9:[9]

Also, you can try inverse this Bash function which converts dBm to percentage:

#!/bin/bash

function dbmtoperc { # Convert dBm to percentage (based on https://www.adriangranados.com/blog/dbm-to-percent-conversion)
  dbmtoperc_d=$(echo "$1" | tr -d -)
  dbmtoperc_r=0
  if [[ "$dbmtoperc_d" =~ [0-9]+$ ]]; then
    if ((1<=$dbmtoperc_d && $dbmtoperc_d<=20)); then dbmtoperc_r=100
    elif ((21<=$dbmtoperc_d && $dbmtoperc_d<=23)); then dbmtoperc_r=99
    elif ((24<=$dbmtoperc_d && $dbmtoperc_d<=26)); then dbmtoperc_r=98
    elif ((27<=$dbmtoperc_d && $dbmtoperc_d<=28)); then dbmtoperc_r=97
    elif ((29<=$dbmtoperc_d && $dbmtoperc_d<=30)); then dbmtoperc_r=96
    elif ((31<=$dbmtoperc_d && $dbmtoperc_d<=32)); then dbmtoperc_r=95
    elif ((33==$dbmtoperc_d)); then dbmtoperc_r=94
    elif ((34<=$dbmtoperc_d && $dbmtoperc_d<=35)); then dbmtoperc_r=93
    elif ((36<=$dbmtoperc_d && $dbmtoperc_d<=38)); then dbmtoperc_r=$((92-($dbmtoperc_d-36)))
    elif ((39<=$dbmtoperc_d && $dbmtoperc_d<=51)); then dbmtoperc_r=$((90-($dbmtoperc_d-39)))
    elif ((52<=$dbmtoperc_d && $dbmtoperc_d<=55)); then dbmtoperc_r=$((76-($dbmtoperc_d-52)))
    elif ((56<=$dbmtoperc_d && $dbmtoperc_d<=58)); then dbmtoperc_r=$((71-($dbmtoperc_d-56)))
    elif ((59<=$dbmtoperc_d && $dbmtoperc_d<=60)); then dbmtoperc_r=$((67-($dbmtoperc_d-59)))
    elif ((61<=$dbmtoperc_d && $dbmtoperc_d<=62)); then dbmtoperc_r=$((64-($dbmtoperc_d-61)))
    elif ((63<=$dbmtoperc_d && $dbmtoperc_d<=64)); then dbmtoperc_r=$((61-($dbmtoperc_d-63)))
    elif ((65==$dbmtoperc_d)); then dbmtoperc_r=58
    elif ((66<=$dbmtoperc_d && $dbmtoperc_d<=67)); then dbmtoperc_r=$((56-($dbmtoperc_d-66)))
    elif ((68==$dbmtoperc_d)); then dbmtoperc_r=53
    elif ((69==$dbmtoperc_d)); then dbmtoperc_r=51
    elif ((70<=$dbmtoperc_d && $dbmtoperc_d<=85)); then dbmtoperc_r=$((50-($dbmtoperc_d-70)*2))
    elif ((86<=$dbmtoperc_d && $dbmtoperc_d<=88)); then dbmtoperc_r=$((17-($dbmtoperc_d-86)*2))
    elif ((89<=$dbmtoperc_d && $dbmtoperc_d<=91)); then dbmtoperc_r=$((10-($dbmtoperc_d-89)*2))
    elif ((92==$dbmtoperc_d)); then dbmtoperc_r=3
    elif ((93<=$dbmtoperc_d)); then dbmtoperc_r=1; fi
  fi
  echo $dbmtoperc_r
}

Usage:

echo $(dbmtoperc -48)% # returns 81%

Solution 10:[10]

This is what i have done :

long rssi = WiFi.RSSI();
rssi=-rssi;
int WiFiperct;
if (rssi<27){
WiFiperct =100;
}
else if(rssi>=27&&rssi<33){
  WiFiperct=150-(5/2.7)*rssi;
}
else if(rssi>=33&&rssi<36){
  WiFiperct=150-(5/3)*rssi;
}
else if(rssi>=36&&rssi<40){
  WiFiperct=150-(5/3.3)*rssi;
}
else if(rssi>=40&&rssi<80){
  WiFiperct=150-(5/3.5)*rssi;
}
else if(rssi>=80&&rssi<90){
  WiFiperct=150-(5/3.4)*rssi;
}
else if(rssi>=90&&rssi<99){
  WiFiperct=150-(5/3.3)*rssi;
}
else{
  WiFiperct=0;
}

Solution 11:[11]

Airodump RXQ is really usefull in the real world conditions... "Receive Quality as measured by the percentage of packets (management and data frames) successfully received over the last 10 seconds." "Its measured over all management and data frames. The received frames contain a sequence number which is added by the sending access point. RXQ = 100 means that all packets were received from the access point in numerical sequence and none were missing. That's the clue, this allows you to read more things out of this value. Lets say you got 100 percent RXQ and all 10 (or whatever the rate) beacons per second coming in. Now all of a sudden the RXQ drops below 90, but you still capture all sent beacons. Thus you know that the AP is sending frames to a client but you can't hear the client nor the AP sending to the client (need to get closer)."

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Thodoris Greasidis
Solution 2 Raja
Solution 3
Solution 4 MarianD
Solution 5
Solution 6
Solution 7
Solution 8 Zibri
Solution 9 Faither
Solution 10
Solution 11 Klaus Nonn