如何将Wifi信号强度从质量百分比(通常为0%至100%)转换为RSSI值,通常为负dBm数(即-96db
)?
Wifi信号强度对RSSI dBm的百分比
微软在其WLAN_ASSOCIATION_ATTRIBUTES结构中定义Wifi信号质量如下:
wlanSignalQuality :
表示网络信号质量的百分比值。WLAN_SIGNAL_QUALITY的类型为ULONG。该成员包含一个值在0到100之间。值为0表示RSSI信号的实际强度-100 dbm。值为100表示RSSI信号的实际强度为-50 dbm。您可以计算RSSI信号强度值为wlanSignalQuality值在1到99之间使用线性插值。
RSSI(或"无线电(接收)信号强度指示器")的单位为"dB"(分贝)或类似的"dBm"(dB/毫瓦)(参见dB vs. dBm),其中较小的负值具有最高的信号强度或质量。
因此,quality
(百分比)与dBm
的换算为:
quality = 2 * (dBm + 100) where dBm: [-100 to -50]
dBm = (quality / 2) - 100 where quality: [0 to 100]
伪代码(带样夹):
// 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;
注意:
仔细检查用于计算的Quality
的定义。还要检查dB
(或dBm
)的范围。限制可能会有所不同。
:
Medium quality: 50% -> -75dBm = (50 / 2) - 100 Low quality: -96dBm -> 8% = 2 * (-96 + 100)
在JS中我更喜欢这样做:
Math.min(Math.max(2 * (x + 100), 0), 100)
我个人的看法是,这是更优雅的方式来写,而不是使用if
的
从经验来看:
- 小于-50dB(-40, -30和-20)= 100%的信号强度
- -51 ~ -55dB= 90%
- 从-56到-62dB=80%
- 从-63到-65dB=75%
下面的内容对于Apple设备来说不够好
- -66 ~ 68dB=70%
- 从-69到74dB= 60%
- 从-75到79dB= 50%
- 从-80到-83dB=30%
Windows笔记本电脑可以正常工作在-80dB,但在较慢的速度
我很高兴我找到了这篇文章,因为我正在寻找一种将dbm转换为百分比的方法。使用David的帖子,我用python编写了一个快速脚本来计算质量百分比。
#!/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")
为了从我的电脑所在的地方获得最高的wifi质量,我移动/旋转我的天线,直到我收到最高的质量。为了查看实时质量,我使用以下命令运行上面的脚本:
watch -n0.1 "python getwifiquality.py"
我知道这可能有点晚了,但这可能会对将来的人有所帮助。
我取了RSSI的dBm 30-90的值,并将其与100- 0%相关。
我用基本的线性方程得到了答案。
y = mx + b
我们知道dBm的x值为30和90。我们知道%的y值为100和0。
我们只需要求出斜率。所以我们可以把它变成线性的
m = 100-0/30-90
= 100/-60
= -5/3
b = y - mx
= 0 + 5/3*90
= 150
当您知道RSSI值时,将最终方程放入代码。
% = 150 - (5/3) * RSSI
注我确实取了通常为负的RSSI值,并乘以绝对值得到正数。
quality = abs(RSSI)
% = 150 - (5/3) * quality
From RSSI vs RSS:
RSSI -接收信号强度指标RSS -接收信号强度
RSSI为指标,RSS为实值。好的,现在你所说的指标是什么意思,指标意味着它可以是一个相对值,而RSSI总是一个正值,RSSI没有单位。
我们可以说RSSI是一般人可以理解的。RF值总是以dBm表示,大多数情况下这些值都是负值。为了便于人们理解,这些负值通过缩放转换为正值。
例如,最大信号强度为
0 dBm
,最小信号强度为-100 dBm
。我们可以像解释的那样缩放它。我们可以把0 dBm
及以上(RSS)作为100
RSSI(即最大RSSI),把-100 dBm
(或更少)作为0 RSSI
(最小RSS)。
我是这样做的:
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;
}
本文对mW, dBm和RSSI进行了更详细的解释
http://madwifi-project.org/attachment/wiki/UserDocs/RSSI/Converting_Signal_Strength.pdf?format=raw根据它,RSSI没有单位。它是802.11标准中定义的一个值,由网卡计算并发送给操作系统。网卡厂商应提供dBm-RSSI值的映射表
很抱歉直接链接,但是我找不到文件链接的原始页面
所提到的伪代码将不能在所有范围内工作,例如范围(-80dBm到0和-40dBm到100)。
将任何范围映射到0到100的通用简单逻辑。使用示例,下面的代码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;
}
Ok…我同意……但为什么是:
Quality=29/100 Signal level=-78 dBm
Quality=89/100 Signal level=-55 dBm
Quality=100/100 Signal level=-21 dBm
这与公式不一致百分比=质量/2 - 100。
这是一个快速的python脚本从RSSi转换到信号强度…
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)
此外,您可以尝试反向Bash函数,将dBm转换为百分比:
#!/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
}
用法:
echo $(dbmtoperc -48)% # returns 81%
airdump RXQ在现实世界中真的很有用…接收质量,衡量数据包(管理帧和数据帧)在过去10秒内成功接收的百分比。它是通过所有管理和数据框架来衡量的。所接收的帧包含由发送接入点添加的序列号。RXQ = 100表示从接入点按数字顺序收到所有数据包,没有丢失。这就是线索,这允许你从这个值中读取更多的东西。假设你有100%的RXQ和所有10个(或任何速率)信标每秒进入。现在RXQ突然降到90以下,但你仍然捕获所有发送的信标。因此,您知道AP正在向客户端发送帧,但您听不到客户端也听不到AP向客户端发送帧(需要靠近)。"