WiFiChanViz icon indicating copy to clipboard operation
WiFiChanViz copied to clipboard

Thanks for this brilliant idea

Open m1cr0lab opened this issue 3 years ago • 2 comments

Salut @tobozo,

I liked the way you represented WiFi channel saturation with your WiFiChanViz app that I discovered on Twitter:

So I challenged myself to try to remake it by myself for the ESPboy. I kept your idea of setting the height of the channels according to the number of access points occupying them. But I chose a different color scale depending on the best-observed signal quality for each channel.

And I added the ability to browse between channels to see the list of access points broadcasting a WiFi network.

Here is how it looks:

wifi-analyzers

Well, the WiFi antenna of the M5Stack is probably of better quality than the one of the Wemos D1 mini that drives the ESPboy...

I then took a look at your code to compare our approaches. They are pretty similar, although we have a different way of calculating the luminance for the historical perspective fade:

// --------------------------------------------------------
// tobozo's method
// --------------------------------------------------------

// luminosity reducer, taken from Bodmer's antialiased font
static uint16_t luminance(uint16_t color, uint8_t luminance)
{
  // Extract rgb colours and stretch range to 0 - 255
  uint16_t r = (color & 0xF800) >> 8; r |= (r >> 5);
  uint16_t g = (color & 0x07E0) >> 3; g |= (g >> 6);
  uint16_t b = (color & 0x001F) << 3; b |= (b >> 5);

  b = ((b * (uint16_t)luminance + 255) >> 8) & 0x00F8;
  g = ((g * (uint16_t)luminance + 255) >> 8) & 0x00FC;
  r = ((r * (uint16_t)luminance + 255) >> 8) & 0x00F8;

  return (r << 8) | (g << 3) | (b >> 3);
}

// Use as a gfx replacement for tft.fillScreen(TFT_BLACK).
// Produces a strobe effect by reducing luminosity on all non-black pixels.
// Limitations:
//  - 16bits colors only
//  - Only fades to black
//  - frame rate must be >15fps
//  - Sluggish when the sprite has too many (>50%) non black pixels
static void spriteFadeOut( LGFX_Sprite *sprite, uint8_t strength )
{
  int32_t w = sprite->width();
  int32_t h = sprite->height();
  int32_t l = w*h;
  uint16_t* framebuf = (uint16_t*)sprite->getBuffer();
  for( uint32_t i=0;i<l;i++) {
    if( framebuf[i]!=TFT_BLACK ) {
      uint16_t pixcolor = (framebuf[i] >> 8) | (framebuf[i] << 8);
      pixcolor = luminance( pixcolor, strength );
      framebuf[i] = pixcolor<<8 | pixcolor>>8;
    }
  }
}

// --------------------------------------------------------
// m1cr0lab's method
// --------------------------------------------------------

uint16_t * const fb  = (uint16_t*)fb1->getBuffer();
uint16_t   const len = GRAPH_WIDTH * GRAPH_HEIGHT;
uint16_t color;
uint8_t. r, g, b;
for (uint16_t i = 0; i < len; ++i) {
    if (fb[i]) {
        // swaps endianness
        color = fb[i] >> 8 | fb[i] << 8;
        // extracts the primary colors
        r = color >> 11;
        g = (color >> 5) & 0x3f;
        b = color & 0x1f;
        // lowers luminance
        r = r > 1 ? r - 1 : 0;
        g = g > 2 ? g - 2 : 0;
        b = b > 1 ? b - 1 : 0;
        // repacks the RGB565 color
        color = r << 11 | g << 5 | b;
        // restores endianness
        fb[i] = color << 8 | color >> 8;
    }
}

LovyanGFX library is outstanding!

Oh, and I have to point out a slight error in your WiFiChanViz.ino code:

for (int i = 0; i < n; ++i) {
    int32_t channel = WiFi.channel(i);
    dpc[channel]++;
}

Replace this:

dpc[channel]++;

By:

dpc[channel - 1]++;

If you are curious, you can have a look at my code.

En tout cas, merci pour ton travail inspirant ! :wink:

Steph

m1cr0lab avatar Aug 07 '22 15:08 m1cr0lab

Salutations @m1cr0lab

thanks for your feedback, I'm happy my work inspired you :-)

dpc[channel - 1]++;

could it mean the whole channels list is off by one?

this app was supposed to help me pick an idle wifi channel to have my ConBee dongle collect data from my Linky ... and I've been wondering why my zigbee network had such a big packet loss ratio :facepalm:

thanks for spotting that!

calculating the luminance for the historical perspective fade:

your changes seem to dramatically improve the frame rate :+1:

pour ma défense I initially wanted to have the luminance vary depending on the display brightness but the min-max values weren't consistent across M5 devices and the code block to handle that was removed.

however before removing this feature I found out there are 4 significant luminance levels (e.g. 1, 2, 4, 8) to map between max and min brightness in order to keep the graph horizon visible.

I believe the ESPBoy could benefit from that tweak, all you need is to set those 1/2/1 values as variables too:


  static uint8_t rl, gl, bl; // don't forget to init in setup()!

  void onBrightnessChanged( uint8_t brightness,  uint8_t min_brightness=0x00, uint8_t max_brightness=0xff )
  {
    // on brightness change
    uint8_t luminance = map( brightness, max_brightness, min_brightness, 1, 4 );
    rl = luminance;
    gl = luminance*2;
    bl = luminance;
  }

  // (...)

  for (uint16_t i = 0; i < len; ++i) {
    if (fb[i]) {
      // (... )    
      r = r > rl ? r - rl : 0;
      g = g > gl ? g - gl : 0;
      b = b > bl ? b - bl : 0;
     // (...)
    }
  }

be well

tobozo avatar Aug 08 '22 11:08 tobozo

Hello @tobozo,

could it mean the whole channels list is off by one?

That's precisely the case! No wonder you had problems with your ConBee. 😄

your changes seem to dramatically improve the frame rate 👍

La chose la plus difficile c'est d'avoir l'idée la plus simple.

Thanks for your tip about significant luminance values depending on the screen brightness. I'm keeping this in mind, even though no one uses the ESPboy's screen backlight LED. I think I'm the only one who does, but only in specific cases: to simulate fades between splash screens.

Thanks again for your constructive feedback.

Steph

m1cr0lab avatar Aug 08 '22 11:08 m1cr0lab