Go Down

Topic: WiFi.RSSI(); Not updating? (Read 6152 times) previous topic - next topic


But, you could put Serial.print() statements in the code, to find out where the code does or does not get to. At least then, when reporting a bug, you have a lot more information on what is happening/is not happening.
The art of getting good answers lies in asking good questions.


In this case there is not anything the OP could have printed other than the WiFi.RSSI(). The WiFi.RSSI() has one line of code, which calls another function. That function sends out an SPI command to ask for current RSSI. The rest is in the WiFi firmware. I really hate to see the Arduino team come up with zero documentation again on this expensive piece of toy that you can only use very lightly and not be able to depend on it seriously since there is no documentation of its complete even partial behavior. As a programmer, not knowing the complete behavior or a library is the biggest problem.
Serial LCD keypad panel,phi_prompt user interface library,SDI-12 USB Adapter


In this case there is not anything the OP could have printed other than the WiFi.RSSI().

Why not print "In getCurrentRSSI!", in getCurrentRSSI(). That would have, at a minimum, answered the question of whether getCurrentRSSI() was even called.

Then, one could go into the SpiDrv class, and see what waitResponseCmd() is doing. I'm sure that it calls a function specific to the GET_CURR_RSSI_CMD command. One could figure out what that function is doing.

Certainly it is not trivial to determine why WiF.RSSI() isn't updating, but it certainly beats just complaining. Even if one gets stuck, and can't determine the solution, providing more data is almost always better than providing less data.

Or maybe I'm just being too sensitive to the "it didn't work; fix it for me" posts.
The art of getting good answers lies in asking good questions.



I was having the same problem and noticed the same thing.  I have found two ways of handling this, but the below seems to be the best.  I have to tip my hat to huckleberry for the great tip on the work around as it lead to my,... I guess you could call it, a solution.  What I noticed from huckleberry's solution, however, is that it doubled my loop time, this is because the WiFi.begin(ssid,passphrase); calls other functions which impose multiple layers of delays.  However, what I found is if you modify the wifi_drv.cpp to be the following:

Code: [Select]

int32_t WiFiDrv::getCurrentRSSI()
    startScanNetworks(); //<-This is all I added!

It will jog the wifi chip to get a new RSSI value.  I don't think the originally programmed code that follows this change is actually functioning as intended, but it works with a minimal trade-off in performance.  The other fix would be to replace the line I added above to be the setPassPhrase command found in the same file, but that requires a whole host of changes to store the pass phrase and it can just get ugly.  I think this is cleaner, as far as workarounds go.  I suspect the issue with this code is how the wifi chip handles the receipt of _dummy which is 0xFF.  I don't think it does anything with it.  One might want to play with getRSSINetoworks(uint8_t networkItem) function in the same class, but I haven't found a way to know or determine what parameter to pass it in the sketch file that would represent my network (It wants a freaking unsigned int?).  Tips here would be appreciated, but only if someone KNOWS that the RSSI value is being updated.  :P

Hopefully, a proper fix will make it into the next release.

(BTW, I am using the mega2560rev3 with the WiFiShield in case that matters, but seeing this solution, I can't see how it would!)

Hope this helps!


Jun 05, 2013, 05:17 pm Last Edit: Jun 05, 2013, 06:16 pm by MattS-UK Reason: 1

WiFi.scanNetworks(); returns the number of visible networks
Each network can then be enumerated like so

Note:  It's not really a network, it's an access point.

Code: [Select]

#include <LiquidCrystal.h>
#include <WiFi.h>

LiquidCrystal lcd(13, 12, 11, 10, 9, 8);
char ssid[] = "myssid";
char password[] = "password";

void setup() {
 lcd.begin(16, 2);

 if (WiFi.status() == WL_NO_SHIELD) {
   lcd.setCursor(0, 0);
   lcd.print("No Shield");
   lcd.setCursor(0, 1); lcd.print("Fatal stop!");


void loop() {
 //try connect forever
 if (WiFi.status() != WL_CONNECTED) {

 // net is connected
 while(WiFi.status() == WL_CONNECTED) {
   //get connected net
   uint8_t numNets = WiFi.scanNetworks();
   lcd.setCursor(0, 0); lcd.print(WiFi.SSID());
   lcd.setCursor(13, 0); lcd.print(WiFi.RSSI());
   //enumerate all nets
   for (uint8_t thisNet = 0; thisNet < numNets; thisNet++) {
     lcd.setCursor(0, 1); lcd.print("                ");
     lcd.setCursor(0, 1); lcd.print(thisNet); lcd.print(" "); lcd.print(WiFi.SSID(thisNet));
     lcd.setCursor(13,1); lcd.print(WiFi.RSSI(thisNet));

void doConnect() {
 //attempt to connect to WLAN forever
 uint8_t tryNum = 1;
 do {
   lcd.setCursor(0, 0); lcd.print("Try connect     ");
   lcd.setCursor(13, 0); lcd.print(tryNum++);
   WiFi.begin(ssid, password);
 } while (WiFi.status() != WL_CONNECTED);


Tips here would be appreciated, but only if someone KNOWS that the RSSI value is being updated.  :P

The RSSI number is valid immediately after the call to scanNetworks.
How long it remains valid...Most likely, until something changes or scanNetworks is called again.

Strange how perspectives differ though.  I am primarily a network engineer who sometimes develops software.
I never assumed the the WiFi shield would update RSSI automagically.  
Typically it an O/S scans for access points periodically, as a background service.
It just appears to happen automagically to an end user.

Arduino is more an API than O/S.  
If you want to expend precious runtime, RAM and power
scanning for access points in the background,
you have to write the functionality yourself.



Thanks for demo-ing how to find the network enumeration.

I initially started out with your perspective that this was probably some get method and would find an associated set method in the library.  However, while investigate the RSSI() function I noticed it calls, and returns the result of "getCurrentRSSI()".  This naming convention puzzled me.  So, I checked for documentation and comments.  The header file describes it as,
Code: [Select]
     * Return the current RSSI /Received Signal Strength in dBm)
     * associated with the network
     * return: signed value

... So I believed that I am going to get the current RSSI measurement. 

So, to me and I'm assuming the other 5 or so contributors here, it was "automagic" when the old value was not being updated to a "current" measurement by the call to the SPI driver to send the wifi chip a message enumerated as "GET_CURR_RSSI_CMD". 

But, like I said, I see your perspective as that is how I started out.

However, I'm not sure how the distinction between an API or OS is salient, because the API is exactly that: an interface.  Regardless of valuable resources, the interface should do what it is documented to do, and I'm not sure that I believe it to "return the current RSSI". 

Your example is much appreciated.  I will play with the function I mentioned using this technique.  Thanks again!


However, I'm not sure how the distinction between an API or OS is salient, because the API is exactly that: an interface.  Regardless of valuable resources, the interface should do what it is documented to do, and I'm not sure that I believe it to "return the current RSSI".

I ought to first explain, 'automagical' is a word I use (specifically) to describe code and process which is taken for granted.  For example, end users rarely think about all the things which need to happen automatically, before they see a web page in their browser, so it often appears to be somewhat 'magical' to them.

The distinction I was making, is that an O/S is a collection of processes (code which is executing), whereas an API is a collection of functions (code which could be executed).  

If you were to dig into how Windows, OSX, iOS etc work with wifi, you would find that between the O/S and the network interface driver, there is a network discovery background service, which periodically polls the wifi hardware in order to maintain the various data structures associated with an access point.  End user applications then call API functions to interrogate the structures maintained (automatically) by the O/S.  In this way, the O/S provides applications with a layer of abstraction (encapsulation), so application developers don't have to worry about the hardware specific, Layer 2 (data link) stuff.

The costs of abstraction are always, runtime, RAM and power consumption.  On a host like a PC or smart phone, which has Ghz of runtime, MB of RAM and potentially Amps of power to draw on, the cost of automating various network services is trivial.  On an Arduino with it's Mhz, KB and milli-Amps, the cost of automating just network discovery would be relatively huge, leaving little resource left to do much else.

In the case of the WiFi shield, the distinction between API and O/S is not quite perfect, because the WiFi shield has it's own  MCU which is running some code and providing some abstraction.  However, the lack of resources can not be escaped and I think it is safe to presume the shield firmware, is mainly concerned with the bare essentials of Layer 2; managing radio transmission and the like.


Your example is much appreciated.  I will play with the function I mentioned using this technique.  Thanks again!

Happy to help.  

I don't know whether this helps but as regards documentation and once again, this is just my view of the World.  I always try to remember the English language is quite vague, compared to the programming languages it is used to document.  


Has anyone had any luck in sorting this? (after a firmware update)



Read the exchange between me and MattS.  For your problem (not the quesiton i posed to the community), his method would be much preferred (no mods to the librarys), though I haven't gotten to playing with it.  My method just drops the same call into the library and it will work the same. 

Go Up

Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

via Egeo 16
Torino, 10131