Go Down

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

PaulS

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.

liudr

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.

PaulS

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

n8sbug

All, 

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!
    WAIT_FOR_SLAVE_SELECT();


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!

MattS-UK

#19
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);
 lcd.clear();
 lcd.setCursor(0,0);
 lcd.print("Setup...");

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

}

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

 // net is connected
 while(WiFi.status() == WL_CONNECTED) {
   //get connected net
   uint8_t numNets = WiFi.scanNetworks();
   lcd.clear();
   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));
     delay(1000);
   }
 }
}

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);
   delay(1000);
 } while (WiFi.status() != WL_CONNECTED);

}


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

Go Up