Portable WiFi Scanner with OLED Display (ESP8266): signal strength, connection test to a server

In this project, we will develop a portable WiFi scanner with an OLED display based on an ESP8266 (Wemos D1 mini). It is very easy and very economical to manufacture its own sensors and connected objects based on ESP8266. Only small problem, one always wonders whether the quality of the WiFi signal will be sufficient in the area where the object will be connected. We all have the SLR to draw his mobile phone to check the WiFi signal. This is a very good solution but the hardware used does not necessarily work identically. With this scanner (which holds in the hand), it will be possible to test in real situation the reception of the signal. A small server running Nodejs will also test whether communication is possible.

Equipment used

In this project, we will manufacture a small portable WiFi scanner based on Wemos D1 mini. The Wemos will be powered by a LiPo battery (here a 3.7 Volts – 150 mAh) using the Shield Battery presented here. We will finish stacking with the Shield OLED SSD1306 (64×48 pixels) previously presented in this article. If your battery is not equipped with a JST XH2-2.54mm connector, you can change the cable or use Dupont connectors to crimp.

esp8266 Wemos D1 mini Wemos D1 Mini
wemos d1 mini shield batterie lipo LiPo battery charger with micro USB connector.

about €2,20

wemos d1 mini oled shield I2C SSD1306 monochrome OLED Display. By default: D1 – SCL, D2 – SDA

about €4,40

batterie lipo 150mah 3V7 LiPo battery 3,7V – 400mAh

from €4,50

Wire with JST XH2-2.54mm connector

Circuit

What is magic with the Wemos … is that there is no circuit! We simply stack the modules one above the other and it works. I simply soldered a 1.5MΩ resistor between the positive battery pin and the analog input A0 to monitor the charge level of the battery. The method has already been presented in this paper.

Here is the stack obtained. From bottom to top, we find the Wemos then the Shield Battery and finally we finish the battery with the Shield OLED. I used a small LiPo battery of 150 mAh that I slipped between the Wemos and the Shield Battery.

Warning. Check or isolate the components that you are placing between the Shields. Doing so may cause short circuits

Arduino code of the WiFi scanner

To use the 64×48 pixel OLED screen, the easiest way is to use the Adafruit_ssd1306 library modified by Mike Causer. It is available on Github here. The program is very simple:

  • The list of available networks (SSIDs) is first retrieved.
  • For each network in the list
    • The strength of the signal is recovered and the number of bars to be displayed (from 0 to 5) is determined.
    • A request is sent to the test server. The server must respond within a time-limit imposed by the http.setTimeout (duration) function.
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include "Adafruit_SSD1306.h"
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>

// SSID et mot de passe des réseaux à tester - SSID and password of the networks to check
// Ajoutez autant de réseau que désiré - Add as network as desired
String ssids[3] = {"yourSSID1","yourSSID2","yourSSID3"};
String passwords[3] = {"pwdSSID1","pwdSSID2","pwdSSID3"};

// IP du serveur de test - Test server IP
const char* host = "xxx.xxx.xxx.xxx";
// Port du serveur - Server Port
const int port = 8080;

#define OLED_RESET 0  // GPIO0
Adafruit_SSD1306 display(OLED_RESET);
 
// Initialisation des Objets - Init objects
WiFiClient wifi;
HTTPClient http;

// Fonction de connexion au réseau WiFi 
void setup_wifi(String ssid, String password) {
  delay(10);
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  // Il faut convertir la String en char* - need to convert String to char*
  WiFi.begin(ssid.c_str(), password.c_str());
  // Connexion au réseau WiFi - connecting to WiFi network
  int count = 0;
  while (WiFi.status() != WL_CONNECTED) {
    count++;
    delay(500);
    Serial.print(".");
    if ( count > 10 ) { return; }
  }

  Serial.print("IP Address: ");
  Serial.println(WiFi.localIP());
}

void setup() {
  pinMode(A0, INPUT);  // Le convertisseur A/N A0 sera utilisé pour mesurer la tension de la batterie - Set A0 converter as input to measure the battery tension
  Serial.begin(115200);
  
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3C (for the 64x48)
  display.display(); 
}

float getLevel(){
  float raw = analogRead(A0);
  int level = map(raw, 140, 227, 0, 100);     // Avec une résistance 1M5 - With a 1M5 resistor
  Serial.print("A0 "); Serial.println(raw);
  
  if ( level < 0 ) { level = 0; }
  if ( level > 100 ) { level = 100; }
  Serial.print("Level: "); Serial.println(level);
  return level;
}

float getVoltage(){
  float raw = analogRead(A0);                      
  float volt = map(raw, 140, 227, 338, 511);  // Avec une résistance 1M5 - With a 1M5 resistor
  volt = volt / 100;
  Serial.print("A0 "); Serial.println(raw);
  Serial.print("Voltage "); Serial.println(volt);
  return volt;
}

void loop() {
  byte available_networks = WiFi.scanNetworks();
  if ( available_networks > 0 ) {
    for (int network = 0; network < available_networks; network++) {
      //delay(1000);
      int level = getLevel();
      long rssi = WiFi.RSSI(network);
      int bars = getBarsSignal(rssi);
      Serial.print("RSSI:");
      Serial.println(rssi);
  
      display.clearDisplay();
      display.setTextSize(1);
      display.setTextColor(WHITE);
      display.setCursor(0,0);

      // Affiche le nom du réseau, la qualité du signal et le niveau de la batteri - display network name, signal Strength and battery level
      display.print("SSID "); display.println(WiFi.SSID(network));
      display.print("RSSI:"); display.println(rssi); 
      display.print("Bat."); display.print(level); display.println("%");
      
      // Affiche les barres de réception du signal - display signal quality bars
      for (int b=0; b <= bars; b++) {
        // display.fillRect(59 + (b*5),33 - (b*5),3,b*5,WHITE); 
        display.fillRect(10 + (b*5),48 - (b*5),3,b*5,WHITE); 
      }
      
      display.display();
      delay(2000);

      // Vérifie si la connexion au serveur fonctionne - Check if connexion is correct with the server
      for ( int i = 0 ; i < 3 ; i++ ) {
        String _ssid = ssids[i];
        String _pwd = passwords[i];
        String _currentSSID = WiFi.SSID(network);
        if ( _currentSSID == _ssid) { 
          checkServerConnexion(_ssid,_pwd);
        }
      }    
    }  
  } else {
    displayMessage("No Signal !", 1000, 1);
  }
}

void checkServerConnexion(String ssid, String password){
  Serial.println("Checking server connexion...");
  displayMessage("Checking server connexion...", 250, 1);
  setup_wifi(ssid, password);
  String _status = ssid;
  http.setTimeout(1000);
  http.begin(host,port, "/checkconnexion");
  int httpCode = http.GET();
  Serial.print("HTTP Code "); Serial.println(httpCode);
  if (httpCode) {
    if (httpCode == 200) {
      Serial.println("Connexion OK");
      _status += " OK";
      displayMessage(_status, 2000,2);
    } else {
      Serial.println("Connexion KO");
      _status += " KO!";
      displayMessage(_status, 2000, 2);
    }
  } else {
    Serial.println("Connexion KO");
    _status += " KO!";
    displayMessage(_status, 2000, 2);
  }
  Serial.println("closing connection");
  http.end();
}

void displayMessage(String message, int duration, int Size){
  display.clearDisplay();
  display.setTextSize(Size);
  display.setTextColor(WHITE);
  display.setCursor(0,0);
  display.println(message);
  display.display();
  delay(duration);
}

int getBarsSignal(long rssi){
  // 5. High quality: 90% ~= -55db
  // 4. Good quality: 75% ~= -65db
  // 3. Medium quality: 50% ~= -75db
  // 2. Low quality: 30% ~= -85db
  // 1. Unusable quality: 8% ~= -96db
  // 0. No signal
  int bars;
  
  if (rssi > -55) { 
    bars = 5;
  } else if (rssi < -55 & rssi > -65) {
    bars = 4;
  } else if (rssi < -65 & rssi > -75) {
    bars = 3;
  } else if (rssi < -75 & rssi > -85) {
    bars = 2;
  } else if (rssi < -85 & rssi > -96) {
    bars = 1;
  } else {
    bars = 0;
  }
  return bars;
}

Test Web Server Code

Here is a small test server developed with Nodejs. It starts a server that listens for requests from the route /checkconnection  on port 8080. If port 8080 is already in use on your computer, just change it at the end of the program. The server responds just to the client by returning a 200 (OK) status.

Follow this tutorial to install Nodejs on your computer and discover some notions. You will need to install the expressjs package to run the server

npm install express --save

Ouvrez un éditeur de texte et collez le code ci-dessous.

/*
*   Serveur de test pour scanner WiFi portable à base d'ESP8266
*   Test server for portable ESP8266 WiFi Scanner
*   http://www.projetsdiy.fr - 2017
*/
var express = require('express');
var app = express();

app.get('/', function(req, res) {
  res.send('Test Server for ESP8266 WiFi scanner');
});

app.use('/checkconnexion', function (req, res, next) {
  console.log("check server connexion received");
  res.sendStatus(200);

});

// Port du serveur - Server Port 
app.listen(8080);

Save the file by giving it the name of server.js for example.

Open a Terminal (MacOS, Linux), Power Shell, or the command prompt (on Windows). Navigate to the directory where the server was registered and run the following command to start it.

node server.js

At each request of the WiFi scanner, a new message will be displayed

check server connexion received

You can go hunting WiFi network!

Testing the WiFi scanner

Once the server is started and the Arduino program is uploaded to the ESP8266, you are ready to map WiFi reception in your home and garden. Networks are tested one after the other.

esp8266 scanner wifi portable ssid1

As soon as a network corresponds to a private network, the program tries to connect to it and then sends a request to the server

esp8266 scanner wifi portable ssid connexion

If the server has responded within the time limit, the reception quality is sufficient to place a connected object running in WiFi

esp8266 scanner wifi portable ssid1 test serveur ok

Otherwise, the network does not offer sufficient quality. In this case, you can install a WiFi repeater that plugs into a power outlet.

esp8266 scanner wifi portable ssid2 test server ko

A small demonstration video

Subscribe to the weekly newsletter

No spam and no other use will be made of your email. You can unsubscribe anytime.

DIY Projects