How to convert Wifi signal strength from Quality (percent) to RSSI (dBm)?
Asked Answered
S

13

33

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)?

Straddle answered 3/4, 2013 at 20:54 Comment(0)
B
88

Wifi Signal Strength Percentage to RSSI dBm

Microsoft defines Wifi signal quality in their WLAN_ASSOCIATION_ATTRIBUTES structure as follows:

wlanSignalQuality:

A percentage value that represents the signal quality of the network. WLAN_SIGNAL_QUALITY is of type ULONG. This member contains a value between 0 and 100. A value of 0 implies an actual RSSI signal strength of -100 dbm. A value of 100 implies an actual RSSI signal strength of -50 dbm. You can calculate the RSSI signal strength value for wlanSignalQuality values between 1 and 99 using linear interpolation.

RSSI (or "Radio (Received) Signal Strength Indicator") are in units of 'dB' (decibel) or the similar 'dBm' (dB per milliwatt) (See dB vs. dBm) in which the smaller magnitude negative numbers have the highest signal strength, or quality.


Therefore, the conversion between quality (percentage) and dBm is as follows:

    quality = 2 * (dBm + 100)  where dBm: [-100 to -50]

    dBm = (quality / 2) - 100  where quality: [0 to 100]

Pseudo Code (with example clamping):

    // dBm to Quality:
    if(dBm <= -100)
        quality = 0;
    else if(dBm >= -50)
        quality = 100;
    else
        quality = 2 * (dBm + 100);

    // Quality to dBm:
    if(quality <= 0)
        dBm = -100;
    else if(quality >= 100)
        dBm = -50;
    else
        dBm = (quality / 2) - 100;

Note:

Check the definition of Quality that you are using for your calculations carefully. Also check the range of dB (or dBm). The limits may vary.

Examples:

Medium quality:   50%      ->   -75dBm   = (50 / 2) - 100
Low quality:      -96dBm   ->   8%       = 2 * (-96 + 100)
Balneology answered 3/4, 2013 at 20:59 Comment(0)
R
16

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.

Rafiq answered 6/8, 2015 at 9:54 Comment(0)
G
13

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
Grouch answered 1/8, 2014 at 11:56 Comment(1)
how did you get this values?Joub
S
6

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"
Straightforward answered 2/6, 2015 at 1:2 Comment(1)
Can you help me? dbm_num = int(x) ValueError: invalid literal for int() with base 10: '77/100\n'Thain
S
4

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
Saturninasaturnine answered 19/3, 2018 at 19:20 Comment(0)
C
3

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).

Claret answered 7/11, 2013 at 1:19 Comment(0)
B
0

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.

Bandstand answered 22/5, 2016 at 1:48 Comment(0)
N
0

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;
}
Nauplius answered 8/7, 2016 at 6:15 Comment(0)
T
0

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.

Trichinosis answered 29/4, 2018 at 20:36 Comment(1)
There is no universally-agreed meaning of 'quality'. Microsoft has one definition, described in the accepted answer, but other software may not use this definition. For example, WiFi Explorer says that -20 dBm is 100%, and even points out that "other tools show percentage values for signal strength that are far off from what you see in WiFi Explorer."Granulocyte
B
0

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;
}
Bevins answered 27/6, 2020 at 7:2 Comment(0)
M
0

Here's a quick python script to convert from RSSi to signal strength...

import sys

def convert_rssi_to_quality(rssi):
    dbm_num = int(rssi)
    quality = 2 * (dbm_num + 100)
    print("{0} dbm_num = {1}%".format(dbm_num, quality))


if __name__ == "__main__":
    if len(sys.argv) != 2:
        rssi_value = input("Please enter an RSSI value: ")
    else:
        rssi_value = sys.argv[1]

    convert_rssi_to_quality(rssi_value)
Manslayer answered 24/7, 2023 at 7:24 Comment(0)
S
-1

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%
Shurlock answered 12/10, 2018 at 12:8 Comment(3)
Article you point is erroneous because dBm is already a nonlinear logarithmic represent of mW. So this solution is logarithm of logarithm. So we have "signal quality is double logarithm of signal power" - this is nonsense.Khedive
@Khedive You might be right, but this values were figured by real situation. What's your solution then?Shurlock
I'm prefer to use solution proposed by David Manpearl. This is simple linear convertation, it produce only even values of percent but I think we can't doing something better, because we have only integer dbm value as source.Khedive
T
-1

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)."

Tensor answered 16/2, 2022 at 18:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.