Скетч сканера сети для ESP8266 и NRF24l01

Smart_maikl
Offline
Зарегистрирован: 30.08.2022

Люди, помогите разобраться. Понимаю что мало шансов тут найти подсказку, но другого варианта пока не вижу.
В общем есть готовый проект для ардуино - сканер сети 2.4Ghz
Схема, скетч. Там всё понятно. Но вопрос в том что надо собрать это на esp8266/ Или esp32
Причина в том что эти модули более перспективны, компактны, дешевле и обладают всем фунционалом для таких задач.
Ну и они есть в наличии, в отличие от ардуины.
Итак, в среде ардуино IDE добавляю поддержку esp8266
скачиваю библиотеки, в описании к которым вроде упоминается поддержка esp.
Вставляю скетч но.. выдает ошибку.
Я нашел другой проект с аналогичным сканером и немного другим кодом и он тоже не компилируется при выборе ESP.
Ссылка на проект

Вот такие ошибку выдает при компиляции - nRF24L01pScannerOled:31:19: error: 'PORTB' was not declared in this scope
31 | #define CE_off PORTB &= 0xFD
Наставьте на путь истинный пожалуйста. Готов оплатить помощь.
 

#include "SSD1X06.h"

/* nRF24L01+ module connections
 *  
 * module   Arduino
 * 1 GND ---- GND
 * 2 VCC ---- 3.3V  Note: 5V on VCC will destroy module (but other pins are 5V tolerant)
 * 3 CE ----- D9
 * 4 CSN ---- D10
 * 5 SCK ---- D13 (SCK)
 * 6 MOSI --- D11 (MOSI)
 * 7 MISO --- D12 (MISO)
 * 8 IRQ ---- not connected
 */

// the nRF24L01+ can tune to 128 channels with 1 MHz spacing from 2.400 GHz to 2.527 GHz.
#define CHANNELS 128

// SPI definitions and macros
#define CE_pin    9
#define CS_pin   10
#define MOSI_pin 11
#define MISO_pin 12
#define SCK_pin  13

#define  CE_on    PORTB |= 0x02
#define  CE_off   PORTB &= 0xFD
#define  CS_on    PORTB |= 0x04
#define  CS_off   PORTB &= 0xFB
#define  MOSI_on  PORTB |= 0x08
#define  MOSI_off PORTB &= 0xF7
#define  MISO_on  (PINB & 0x10)  // input
#define  SCK_on   PORTB |= 0x20
#define  SCK_off  PORTB &= 0xDF

// nRF24 Register map
enum {
    NRF24L01_00_CONFIG      = 0x00,
    NRF24L01_01_EN_AA       = 0x01,
    NRF24L01_02_EN_RXADDR   = 0x02,
    NRF24L01_03_SETUP_AW    = 0x03,
    NRF24L01_04_SETUP_RETR  = 0x04,
    NRF24L01_05_RF_CH       = 0x05,
    NRF24L01_06_RF_SETUP    = 0x06,
    NRF24L01_07_STATUS      = 0x07,
    NRF24L01_08_OBSERVE_TX  = 0x08,
    NRF24L01_09_CD          = 0x09,
    NRF24L01_0A_RX_ADDR_P0  = 0x0A,
    NRF24L01_0B_RX_ADDR_P1  = 0x0B,
    NRF24L01_0C_RX_ADDR_P2  = 0x0C,
    NRF24L01_0D_RX_ADDR_P3  = 0x0D,
    NRF24L01_0E_RX_ADDR_P4  = 0x0E,
    NRF24L01_0F_RX_ADDR_P5  = 0x0F,
    NRF24L01_10_TX_ADDR     = 0x10,
    NRF24L01_11_RX_PW_P0    = 0x11,
    NRF24L01_12_RX_PW_P1    = 0x12,
    NRF24L01_13_RX_PW_P2    = 0x13,
    NRF24L01_14_RX_PW_P3    = 0x14,
    NRF24L01_15_RX_PW_P4    = 0x15,
    NRF24L01_16_RX_PW_P5    = 0x16,
    NRF24L01_17_FIFO_STATUS = 0x17,
    NRF24L01_1C_DYNPD       = 0x1C,
    NRF24L01_1D_FEATURE     = 0x1D,
    //Instructions
    NRF24L01_61_RX_PAYLOAD  = 0x61,
    NRF24L01_A0_TX_PAYLOAD  = 0xA0,
    NRF24L01_E1_FLUSH_TX    = 0xE1,
    NRF24L01_E2_FLUSH_RX    = 0xE2,
    NRF24L01_E3_REUSE_TX_PL = 0xE3,
    NRF24L01_50_ACTIVATE    = 0x50,
    NRF24L01_60_R_RX_PL_WID = 0x60,
    NRF24L01_B0_TX_PYLD_NOACK = 0xB0,
    NRF24L01_FF_NOP         = 0xFF,
    NRF24L01_A8_W_ACK_PAYLOAD0 = 0xA8,
    NRF24L01_A8_W_ACK_PAYLOAD1 = 0xA9,
    NRF24L01_A8_W_ACK_PAYLOAD2 = 0xAA,
    NRF24L01_A8_W_ACK_PAYLOAD3 = 0xAB,
    NRF24L01_A8_W_ACK_PAYLOAD4 = 0xAC,
    NRF24L01_A8_W_ACK_PAYLOAD5 = 0xAD,
};

// Bit mnemonics
enum {
    NRF24L01_00_MASK_RX_DR  = 6,
    NRF24L01_00_MASK_TX_DS  = 5,
    NRF24L01_00_MASK_MAX_RT = 4,
    NRF24L01_00_EN_CRC      = 3,
    NRF24L01_00_CRCO        = 2,
    NRF24L01_00_PWR_UP      = 1,
    NRF24L01_00_PRIM_RX     = 0,

    NRF24L01_07_RX_DR       = 6,
    NRF24L01_07_TX_DS       = 5,
    NRF24L01_07_MAX_RT      = 4,

    NRF2401_1D_EN_DYN_ACK   = 0,
    NRF2401_1D_EN_ACK_PAY   = 1,
    NRF2401_1D_EN_DPL       = 2,
};

enum TXRX_State {
    TXRX_OFF,
    TX_EN,
    RX_EN,
};

uint16_t signalStrength[CHANNELS]; // smooths signal strength with numerical range 0 - 0x7FFF

void setup() {
  SSD1X06::start();
  delay(300);
  SSD1X06::fillDisplay(' ');
  SSD1X06::displayString6x8(1, 4, F("2.4 GHz band scanner"), 0);
  SSD1X06::displayString6x8(4, 4, F("By ceptimus. Nov '16"), 0);
  // prepare 'bit banging' SPI interface
  pinMode(MOSI_pin, OUTPUT);
  pinMode(SCK_pin, OUTPUT);
  pinMode(CS_pin, OUTPUT);
  pinMode(CE_pin, OUTPUT);
  pinMode(MISO_pin, INPUT);
  CS_on;
  CE_on;
  MOSI_on;
  SCK_on;
  delay(70);
  CS_off;
  CE_off;
  MOSI_off;
  SCK_off;
  delay(100);
  CS_on;
  delay(10);
      
  NRF24L01_Reset();
  delay(150);

  NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // switch off Shockburst mode
  NRF24L01_WriteReg(NRF24L01_06_RF_SETUP, 0x0F); // write default value to setup register
  NRF24L01_SetTxRxMode(RX_EN); // switch to receive mode
  // Serial.begin(115200); // debugging without lcd display

  
  for (int x = 0; x < 128; x++) {
    uint8_t b = 0x01;  // baseline
    if (!(x % 10)) {
      b |= 0x06; // graduation tick every 10 MHz
    }
    if (x == 10 || x == 60 || x == 110) {
      b |= 0xF8; // scale markers at 2.41, 2.46, and 2.51 GHz 
    }
    SSD1X06::displayByte(6, x, b);
  }
  SSD1X06::displayString6x8(7, 0, F("2.41"), 0);
  SSD1X06::displayString6x8(7, 50, F("2.46"), 0);
  SSD1X06::displayString6x8(7, 100, F("2.51"), 0);
  delay(1500); // start up message
}

uint8_t refresh;

void loop() {
  for (uint8_t MHz = 0; MHz < CHANNELS; MHz++ ) { // tune to frequency (2400 + MHz) so this loop covers 2.400 - 2.527 GHz (maximum range module can handle) when channels is set to 128.
    NRF24L01_WriteReg(NRF24L01_05_RF_CH, MHz);
    CE_on; // start receiving
    delayMicroseconds(random(130, 230)); // allow receiver time to tune and start receiving 130 uS seems to be the minimum time.  Random additional delay helps prevent strobing effects with frequency-hopping transmitters.
    CE_off; // stop receiving - one bit is now set if received power was > -64 dBm at that instant
    if (NRF24L01_ReadReg(NRF24L01_09_CD)) { // signal detected so increase signalStrength unless already maxed out
      signalStrength[MHz] += (0x7FFF - signalStrength[MHz]) >> 5; // increase rapidly when previous value was low, with increase reducing exponentially as value approaches maximum
    } else { // no signal detected so reduce signalStrength unless already at minimum
      signalStrength[MHz] -= signalStrength[MHz] >> 5; // decrease rapidly when previous value was high, with decrease reducing exponentially as value approaches zero
    }
    // Serial.print((signalStrength[MHz] + 0x0100) >> 9, HEX); // debugging without lcd display
    // Serial.print(" "); // debugging without lcd display

    if (!--refresh) { // don't refresh whole display every scan (too slow)
      refresh = 19; // speed up by only refreshing every n-th frequency loop - reset number should be relatively prime to CHANNELS
      int strength = (signalStrength[MHz] + 0x0040) >> 7;
      if (strength > 48) {
        strength = 48; // limit to maximum height that fits display
      }
      
      for (uint8_t row = 0; row < 6; row++) { // loop down 6 rows of display (6 x 8 pixels)
        uint8_t b = 0x00;
        if (strength > (6 - row) << 3) { // all 8 pixels on this row of display to be set
          b = 0xFF;  
        } else if (strength > (5 - row) << 3) { // some pixels on this row to be set
          b = 0xFF << (((6 - row) << 3) - strength);
        }
        SSD1X06::displayByte(row, MHz, b);
      }
    }
  }
  // Serial.print("\n"); // debugging without lcd display
}

uint8_t _spi_write(uint8_t command)
{
    uint8_t result=0;
    uint8_t n=8;
    SCK_off;
    MOSI_off;
    while(n--) {
        if(command & 0x80)
            MOSI_on;
        else
            MOSI_off;
        if(MISO_on)
            result |= 0x01;
        SCK_on;
        _NOP();
        SCK_off;
        command = command << 1;
        result = result << 1;
    }
    MOSI_on;
    return result;
}

void _spi_write_address(uint8_t address, uint8_t data)
{
    CS_off;
    _spi_write(address);
    _NOP();
    _spi_write(data);
    CS_on;
}

uint8_t _spi_read()
{
    uint8_t result=0;
    uint8_t i;
    MOSI_off;
    _NOP();
    for(i = 0; i < 8; i++) {
        if(MISO_on) // if MISO is HIGH
            result = (result << 1) | 0x01;
        else
            result = result << 1;
        SCK_on;
        _NOP();
        SCK_off;
        _NOP();
    }
    return result;
}

uint8_t _spi_read_address(uint8_t address)
{
    uint8_t result;
    CS_off;
    _spi_write(address);
    result = _spi_read();
    CS_on;
    return(result);
}

/* Instruction Mnemonics */
#define R_REGISTER    0x00
#define W_REGISTER    0x20
#define REGISTER_MASK 0x1F
#define ACTIVATE      0x50
#define R_RX_PL_WID   0x60
#define R_RX_PAYLOAD  0x61
#define W_TX_PAYLOAD  0xA0
#define W_ACK_PAYLOAD 0xA8
#define FLUSH_TX      0xE1
#define FLUSH_RX      0xE2
#define REUSE_TX_PL   0xE3
#define NOP           0xFF

uint8_t NRF24L01_WriteReg(uint8_t address, uint8_t data)
{
    CS_off;
    _spi_write_address(address | W_REGISTER, data);
    CS_on;
    return 1;
}

uint8_t NRF24L01_FlushTx()
{
    return Strobe(FLUSH_TX);
}

uint8_t NRF24L01_FlushRx()
{
    return Strobe(FLUSH_RX);
}

static uint8_t Strobe(uint8_t state)
{
    uint8_t result;
    CS_off;
    result = _spi_write(state);
    CS_on;
    return result;
}

uint8_t NRF24L01_ReadReg(uint8_t reg)
{
    CS_off;
    uint8_t data = _spi_read_address(reg);
    CS_on;
    return data;
}

void NRF24L01_SetTxRxMode(uint8_t mode)
{
    if(mode == TX_EN) {
        CE_off;
        NRF24L01_WriteReg(NRF24L01_07_STATUS, 
                    (1 << NRF24L01_07_RX_DR)    // reset the flag(s)
                  | (1 << NRF24L01_07_TX_DS)
                  | (1 << NRF24L01_07_MAX_RT));
        NRF24L01_WriteReg(NRF24L01_00_CONFIG, 
                    (1 << NRF24L01_00_EN_CRC)   // switch to TX mode
                  | (1 << NRF24L01_00_CRCO)
                  | (1 << NRF24L01_00_PWR_UP));
        delayMicroseconds(130);
        CE_on;
    } else if (mode == RX_EN) {
        CE_off;
        NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);        // reset the flag(s)
        NRF24L01_WriteReg(NRF24L01_00_CONFIG, 0x0F);        // switch to RX mode
        NRF24L01_WriteReg(NRF24L01_07_STATUS,
                    (1 << NRF24L01_07_RX_DR)    //reset the flag(s)
                  | (1 << NRF24L01_07_TX_DS)
                  | (1 << NRF24L01_07_MAX_RT));
        NRF24L01_WriteReg(NRF24L01_00_CONFIG,
                    (1 << NRF24L01_00_EN_CRC)   // switch to RX mode
                  | (1 << NRF24L01_00_CRCO)
                  | (1 << NRF24L01_00_PWR_UP)
                  | (1 << NRF24L01_00_PRIM_RX));
        delayMicroseconds(130);
        CE_on;
    } else {
        NRF24L01_WriteReg(NRF24L01_00_CONFIG, (1 << NRF24L01_00_EN_CRC)); // PowerDown
        CE_off;
    }
}

uint8_t NRF24L01_Reset()
{
    NRF24L01_FlushTx();
    NRF24L01_FlushRx();
    uint8_t status1 = Strobe(0xFF); // NOP
    uint8_t status2 = NRF24L01_ReadReg(0x07);
    NRF24L01_SetTxRxMode(TXRX_OFF);
    return (status1 == status2 && (status1 & 0x0f) == 0x0e);
}

 

rkit
Offline
Зарегистрирован: 23.11.2016

Smart_maikl пишет:
проект для ардуино

Smart_maikl пишет:
Ну и они есть в наличии, в отличие от ардуины.

В чем же тут проблема? Шансы допереть невелики

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Smart_maikl пишет:

Вот такие ошибку выдает при компиляции - nRF24L01pScannerOled:31:19: error: 'PORTB' was not declared in this scope

Ну, правильно. Откуда у esp8266 PORTB?

Smart_maikl пишет:

Наставьте на путь истинный пожалуйста.

Вы взяли код/библиотеку не поддерживающую esp8266. Найдите такую, которая поддерживает.

Smart_maikl пишет:

Готов оплатить помощь.

Вы не по адресу. Вам вот сюда.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

ну держи, с тебя пиво )))
 

/*
    This sketch demonstrates how to scan WiFi networks.
    The API is almost the same as with the WiFi Shield library,
    the most obvious difference being the different file you need to include:
*/
#include "ESP8266WiFi.h"

void setup() {
  Serial.begin(115200);

  // Set WiFi to station mode and disconnect from an AP if it was previously connected
  WiFi.mode(WIFI_STA);
  WiFi.disconnect();
  delay(100);

  Serial.println("Setup done");
}

void loop() {
  Serial.println("scan start");

  // WiFi.scanNetworks will return the number of networks found
  int n = WiFi.scanNetworks();
  Serial.println("scan done");
  if (n == 0) {
    Serial.println("no networks found");
  } else {
    Serial.print(n);
    Serial.println(" networks found");
    for (int i = 0; i < n; ++i) {
      // Print SSID and RSSI for each network found
      Serial.print(i + 1);
      Serial.print(": ");
      Serial.print(WiFi.SSID(i));
      Serial.print(" (");
      Serial.print(WiFi.RSSI(i));
      Serial.print(")");
      Serial.println((WiFi.encryptionType(i) == ENC_TYPE_NONE) ? " " : "*");
      delay(10);
    }
  }
  Serial.println("");

  // Wait a bit before scanning again
  delay(5000);
}

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

ESP8266 говорите...
 

"C:\\ARDUINO\\arduino-1.8.19\\portable\\packages\\esp8266\\tools\\python3\\3.7.2-post1/python3" "C:\\ARDUINO\\arduino-1.8.19\\portable\\packages\\esp8266\\hardware\\esp8266\\2.7.1/tools/sizes.py" --elf "C:\\temp\\arduino_build_374048/Scaner_NRF24L01_ESP8266.ino.elf" --path "C:\\ARDUINO\\arduino-1.8.19\\portable\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506/bin"
Executable segment sizes:
IROM   : 229948          - code in flash         (default or ICACHE_FLASH_ATTR) 
IRAM   : 26872   / 32768 - code in IRAM          (ICACHE_RAM_ATTR, ISRs...) 
DATA   : 1248  )         - initialized variables (global, static) in RAM/HEAP 
RODATA : 688   ) / 81920 - constants             (global, static) in RAM/HEAP 
BSS    : 25136 )         - zeroed variables      (global, static) in RAM/HEAP 
"C:\\ARDUINO\\arduino-1.8.19\\portable\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506/bin/xtensa-lx106-elf-size" -A "C:\\temp\\arduino_build_374048/Scaner_NRF24L01_ESP8266.ino.elf"
Скетч использует 258756 байт (24%) памяти устройства. Всего доступно 1044464 байт.
Глобальные переменные используют 27072 байт (33%) динамической памяти, оставляя 54848 байт для локальных переменных. Максимум: 81920 байт.

 

Smart_maikl
Offline
Зарегистрирован: 30.08.2022

Да, пиво без вопросов) Но дружище, это же совсем не то что надо.
Этот пример просто сканирует wifi сети и выдает их список, насколько я понял.
А в исходном примере, модуль сканирует сам диапазон 2.4ггц и отображает уровни любых сигналов.
Это надо для того чтоб найти и локализовать любые помехи на этом несчастном диапазоне.
Хоть от роутера хоть от микроволновки.
И обычный скан сетей вообще тут не актуален.
Но всё равно спасибо что скинул пример. 
И что выше подсказали на счет библиотеки..
Правда не знаю какую и где брать и как ее потом применить.
Эх.. далек я от программирования, только готовые примеры пока даются.

rkit
Offline
Зарегистрирован: 23.11.2016

Smart_maikl пишет:

А в исходном примере, модуль сканирует сам диапазон 2.4ггц и отображает уровни любых сигналов.

нет

b707
Offline
Зарегистрирован: 26.05.2017

Smart_maikl пишет:

Это надо для того чтоб найти и локализовать любые помехи на этом несчастном диапазоне.

а нафик это надо? НРФ24 не работает? - так это не из-за помех

Этот сканер нужен один раз - просканировать и убедится, что смысла в нем нет. И для этого совсем не обязательно переписывать его на ЕСП, проще достать нормальную ардуину, они вроде, сильно подешевели

Smart_maikl
Offline
Зарегистрирован: 30.08.2022

rkit пишет:

Smart_maikl пишет:

А в исходном примере, модуль сканирует сам диапазон 2.4ггц и отображает уровни любых сигналов.

нет

Ну как же нет когда да. В моем посте есть ссылка, там и код и видео и описание проекта.
Дисплей отображает сигнал от включенной рации на 2.4ггц. Вайфай сканеры ничего такого не способны выдать.
 

Smart_maikl
Offline
Зарегистрирован: 30.08.2022

А вот вы зачем пишете? Проще ведь сказать - иди купи готовый анализатор спектра и сканируй. Ну вопрос был в коде. Если вам по делу нечего сказать то зачем вы тратите свое время?

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

я тебе в #4 показал, что у меня твой код компилируется, если исправить, на дисплей не выводил, так как недосуг было искать библиотеку под оный, у меня такого нет )))

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Smart_maikl пишет:
А вот вы зачем пишете?

Аптамуш, у нас есть пальцы. 

b707
Offline
Зарегистрирован: 26.05.2017

Smart_maikl пишет:

Ну вопрос был в коде.


понятно, человеку не нужен сканер, ему нужен код. Вероятно , чтобы выложить где-то на своем сайте или на форуме от своего имени и все дивились, как он о сообществе печется

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Smart_maikl пишет:

Люди, помогите
Вставляю скетч но.. выдает ошибку.
Я нашел другой проект с аналогичным сканером и немного другим кодом и он тоже не компилируется при выборе ESP.

Ссылка на проект

Наставьте на путь истинный пожалуйста. Готов оплатить помощь.

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018
Smart_maikl
Offline
Зарегистрирован: 30.08.2022

ua6em пишет:

ESP8266 говорите...
 

"C:\\ARDUINO\\arduino-1.8.19\\portable\\packages\\esp8266\\tools\\python3\\3.7.2-post1/python3" "C:\\ARDUINO\\arduino-1.8.19\\portable\\packages\\esp8266\\hardware\\esp8266\\2.7.1/tools/sizes.py" --elf "C:\\temp\\arduino_build_374048/Scaner_NRF24L01_ESP8266.ino.elf" --path "C:\\ARDUINO\\arduino-1.8.19\\portable\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506/bin"
Executable segment sizes:
IROM   : 229948          - code in flash         (default or ICACHE_FLASH_ATTR) 
IRAM   : 26872   / 32768 - code in IRAM          (ICACHE_RAM_ATTR, ISRs...) 
DATA   : 1248  )         - initialized variables (global, static) in RAM/HEAP 
RODATA : 688   ) / 81920 - constants             (global, static) in RAM/HEAP 
BSS    : 25136 )         - zeroed variables      (global, static) in RAM/HEAP 
"C:\\ARDUINO\\arduino-1.8.19\\portable\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506/bin/xtensa-lx106-elf-size" -A "C:\\temp\\arduino_build_374048/Scaner_NRF24L01_ESP8266.ino.elf"
Скетч использует 258756 байт (24%) памяти устройства. Всего доступно 1044464 байт.
Глобальные переменные используют 27072 байт (33%) динамической памяти, оставляя 54848 байт для локальных переменных. Максимум: 81920 байт.

 

А как удалось его скомпилить? Что исправить? Это если убрать вывод на дисплей?
ps - нет там никакого вируса, ну вы чего. 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Smart_maikl пишет:

А как удалось его скомпилить? Что исправить? Это если убрать вывод на дисплей?

ps - нет там никакого вируса, ну вы чего. 

для этого надо иметь светлую (я бы даже сказал блестящую) голову, как у меня и прямые руки )))

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

ua6em пишет:
светлую (я бы даже сказал блестящую) голову, как у меня и прямые руки )))
А вот за это, за твою светлую (я бы даже сказал блестящую) голову и прямые руки, я вечерком обязательно выпью!

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

ЕвгенийП пишет:

ua6em пишет:
светлую (я бы даже сказал блестящую) голову, как у меня и прямые руки )))
А вот за это, за твою светлую (я бы даже сказал блестящую) голову и прямые руки, я вечерком обязательно выпью!

а чёж не пить когда уют и не накладно...

rkit
Offline
Зарегистрирован: 23.11.2016

Smart_maikl пишет:

rkit пишет:

Smart_maikl пишет:

А в исходном примере, модуль сканирует сам диапазон 2.4ггц и отображает уровни любых сигналов.

нет

Ну как же нет когда да. В моем посте есть ссылка, там и код и видео и описание проекта.
Дисплей отображает сигнал от включенной рации на 2.4ггц. Вайфай сканеры ничего такого не способны выдать.
 

Нет, не уровни любых сигналов, а пойманные уровни. Что есть большая разница, потому что одной дешевой антеннкой любые сигналы не поймать.

Smart_maikl
Offline
Зарегистрирован: 30.08.2022

rkit пишет:

Smart_maikl пишет:

rkit пишет:

Smart_maikl пишет:

А в исходном примере, модуль сканирует сам диапазон 2.4ггц и отображает уровни любых сигналов.

нет

Ну как же нет когда да. В моем посте есть ссылка, там и код и видео и описание проекта.
Дисплей отображает сигнал от включенной рации на 2.4ггц. Вайфай сканеры ничего такого не способны выдать.
 

Нет, не уровни любых сигналов, а пойманные уровни. Что есть большая разница, потому что одной дешевой антеннкой любые сигналы не поймать.

Хорошо, вы правы. Но тем не менее уровень сигнала в каждом канале, може быть очень полезно увидеть.
Ведь этим простым и дешевым модулем можно провести общую диагностику зашумленности среды, найти источник помехи. 
Так может чем обсуждать назначение, подскажете как это реализовать на esp с NRF ?

SAB
Offline
Зарегистрирован: 27.12.2016

Скачай с плеймаркета на свой смартфон любой WiFi monitor  и он в несколько раз лучше покажет тебе твою хотелку. И с NRF нет ни какой гарантии, что этот модуль вообще линеен во всём диапазоне, да и скорость сканирования вряд ли удовлетворит вашей хотелке. Модуль предназначен для работы не определённой заданной вами частоте, а не заниматься девиацией.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Smart_maikl пишет:

Так может чем обсуждать назначение, подскажете как это реализовать на esp с NRF ?

исправить код, тут подсказывают тем, кто сам что-то делает, если хочешь готовое решают за денежку...
От тебя никаких потуг к адаптации кода пока не видно )

Smart_maikl
Offline
Зарегистрирован: 30.08.2022

ua6em пишет:

Smart_maikl пишет:

Так может чем обсуждать назначение, подскажете как это реализовать на esp с NRF ?

исправить код, тут подсказывают тем, кто сам что-то делает, если хочешь готовое решают за денежку...
От тебя никаких потуг к адаптации кода пока не видно )

Справедливо. Время, опыт должны цениться. Сам я пока скомпилил всего пару примеров. 
Уже рад что с железом получается, залить на платку и собрать смогу. 
Я здесь что-то не вижу как написать в личку. Вы может почту напишите, я думаю светлая голова и руки из нужного места, это то что нужно)

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

 лички тут нет

надо жеж под RP2040 скомпилировалось и если и делать то пожалуй на ней штатными средствами интерфейсов, выжимать то не надо, всё доступно из коробки, но это будет уже совсем другой проект...

Цель? Какова цель?
"...если в обществе нет цветовой дифференциации штанов, то нет и цели..."
В твоём окружении есть цветовая дифференциация штанов?

b707
Offline
Зарегистрирован: 26.05.2017

Smart_maikl пишет:

подскажете как это реализовать на esp с NRF ?

зачем на ЕСП? Возьми ардуину, раз 5 уже советовали

Smart_maikl
Offline
Зарегистрирован: 30.08.2022

Да, пожалуй вы правы. Особенно благодарю за наводку про RP2040. Уже больше подходит чем другие варианты. Хотя с ней не сталкивался.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Smart_maikl пишет:

Да, пожалуй вы правы. Особенно благодарю за наводку про RP2040. Уже больше подходит чем другие варианты. Хотя с ней не сталкивался.

оригинал есть в DNS около 700 рублей, у китайцев и дешевле от 170р и лучше, памяти до 16 мегабайт, заодно и неопиксель на борту, напоиграться

b707
Offline
Зарегистрирован: 26.05.2017

Smart_maikl пишет:

благодарю за наводку про RP2040. Уже больше подходит чем другие варианты. Хотя с ней не сталкивался.


обьясни, чем она больше подходит? На 200р дешевле наны?
Я не пойму, если ты своего времени не ценишь, так чужое поцени. Заказать портирование этого скетча на рп2040 выйдет тебе в 3-5 тыс. За эти деньги ты 5 ардуин купил бы и давно решил свой вопрос, а ты тут околачиваешься которую неделю

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

b707 пишет:
Smart_maikl пишет:

благодарю за наводку про RP2040. Уже больше подходит чем другие варианты. Хотя с ней не сталкивался.

обьясни, чем она больше подходит? На 200р дешевле наны? Я не пойму, если ты своего времени не ценишь, так чужое поцени. Заказать портирование этого скетча на рп2040 выйдет тебе в 3-5 тыс. За эти деньги ты 5 ардуин купил бы и давно решил свой вопрос, а ты тут околачиваешься которую неделю

Он может производство хочет наладить...кстати там с наны выжимали по максимуму, но ведь можно и не корячиться...
А вот применять ESP плохая идея, я даже не смотрел как там WiFi выключить,загадит жеж всё...

RP2040 )))

b707
Offline
Зарегистрирован: 26.05.2017

ua6em пишет:

Он может производство хочет наладить...

тогда тем более пусть идет в платный раздел

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

b707 пишет:

ua6em пишет:

Он может производство хочет наладить...

тогда тем более пусть идет в платный раздел

ну так бесплатно никто не обещал...мне было интересно на RP2040 запустить, скетч работает, осталось найти где у Adafruit шрифты и в частности 5Х7 и поправить, чтоб как у автора, квадратиками рисовал, следущая версия - без этих танцев с бубном, а чисто средствами SPI, скорости тут более чем достаточно, сейчас задействую оба SPI контроллера, SPI1 выводит на экран

b707
Offline
Зарегистрирован: 26.05.2017

ua6em пишет:

мне было интересно на RP2040 запустить, скетч работает, осталось найти где у Adafruit шрифты и в частности 5Х7 и поправить, чтоб как у автора, квадратиками рисовал, следущая версия - без этих танцев с бубном, а чисто средствами SPI, скорости тут более чем достаточно, сейчас задействую оба SPI контроллера, SPI1 выводит на экран

отлично

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Ошибка, матрица 6х8 а вот сам шрифт имеет размерность 5Х8, первый шрифт у adafruit аналогичный, осталось разобраться с таблицей шрифтов, что на что заменить, не совпадают (((

Вывел таблицу символов, чешу репу )))
 

32 -  
33 - !
34 - "
35 - #
36 - $
37 - %
38 - &
39 - '
40 - (
41 - )
42 - *
43 - +
44 - ,
45 - -
46 - .
47 - /
48 - 0
49 - 1
50 - 2
51 - 3
52 - 4
53 - 5
54 - 6
55 - 7
56 - 8
57 - 9
58 - :
59 - ;
60 - <
61 - =
62 - >
63 - ?
64 - @
65 - A
66 - B
67 - C
68 - D
69 - E
70 - F
71 - G
72 - H
73 - I
74 - J
75 - K
76 - L
77 - M
78 - N
79 - O
80 - P
81 - Q
82 - R
83 - S
84 - T
85 - U
86 - V
87 - W
88 - X
89 - Y
90 - Z
91 - [
92 - \
93 - ]
94 - ^
95 - _
96 - `
97 - a
98 - b
99 - c
100 - d
101 - e
102 - f
103 - g
104 - h
105 - i
106 - j
107 - k
108 - l
109 - m
110 - n
111 - o
112 - p
113 - q
114 - r
115 - s
116 - t
117 - u
118 - v
119 - w
120 - x
121 - y
122 - z
123 - {
124 - |
125 - }
126 - ~
127 - 
128 - ⸮
129 - ⸮
130 - ⸮
131 - ⸮
132 - ⸮
133 - ⸮
134 - ⸮
135 - ⸮
136 - ⸮
137 - ⸮
138 - ⸮
139 - ⸮
140 - ⸮
141 - ⸮
142 - ⸮
143 - ⸮
144 - ⸮
145 - ⸮
146 - ⸮
147 - ⸮
148 - ⸮
149 - ⸮
150 - ⸮
151 - ⸮
152 - ⸮
153 - ⸮
154 - ⸮
155 - ⸮
156 - ⸮
157 - ⸮
158 - ⸮
159 - ⸮
160 - ⸮
161 - ⸮
162 - ⸮
163 - ⸮
164 - ⸮
165 - ⸮
166 - ⸮
167 - ⸮
168 - ⸮
169 - ⸮
170 - ⸮
171 - ⸮
172 - ⸮
173 - ⸮
174 - ⸮
175 - ⸮
176 - ⸮
177 - ⸮
178 - ⸮
179 - ⸮
180 - ⸮
181 - ⸮
182 - ⸮
183 - ⸮
184 - ⸮
185 - ⸮
186 - ⸮
187 - ⸮
188 - ⸮
189 - ⸮
190 - ⸮
191 - ⸮
192 - ⸮
193 - ⸮
194 - ⸮
195 - ⸮
196 - ⸮
197 - ⸮
198 - ⸮
199 - ⸮
200 - ⸮
201 - ⸮
202 - ⸮
203 - ⸮
204 - ⸮
205 - ⸮
206 - ⸮
207 - ⸮
208 - ⸮
209 - ⸮
210 - ⸮
211 - ⸮
212 - ⸮
213 - ⸮
214 - ⸮
215 - ⸮
216 - ⸮
217 - ⸮
218 - ⸮
219 - ⸮
220 - ⸮
221 - ⸮
222 - ⸮
223 - ⸮
224 - ⸮
225 - ⸮
226 - ⸮
227 - ⸮
228 - ⸮
229 - ⸮
230 - ⸮
231 - ⸮
232 - ⸮
233 - ⸮
234 - ⸮
235 - ⸮
236 - ⸮
237 - ⸮
238 - ⸮
239 - ⸮
240 - ⸮
241 - ⸮
242 - ⸮
243 - ⸮
244 - ⸮
245 - ⸮
246 - ⸮
247 - ⸮
248 - ⸮
249 - ⸮
250 - ⸮
251 - ⸮
252 - ⸮
253 - ⸮
254 - ⸮
255 - ⸮

И его шрифт:
 

// standard ASCII 5x8 font (6 pixel spacing including the one-pixel space best added on left side)

#include <avr/pgmspace.h>

const uint8_t font[] PROGMEM = {
  0x00, 0x00, 0x00, 0x00, 0x00, // space
  0x00, 0x00, 0x5F, 0x00, 0x00, // !
  0x00, 0x07, 0x00, 0x07, 0x00, // "
  0x14, 0x7F, 0x14, 0x7F, 0x14, // #
  0x24, 0x2A, 0x7F, 0x2A, 0x12, // $
  0x23, 0x13, 0x08, 0x64, 0x62, // %
  0x36, 0x49, 0x56, 0x20, 0x50, // &
  0x00, 0x08, 0x07, 0x03, 0x00, // '
  0x00, 0x1C, 0x22, 0x41, 0x00, // (
  0x00, 0x41, 0x22, 0x1C, 0x00, // )
  0x2A, 0x1C, 0x7F, 0x1C, 0x2A, // *
  0x08, 0x08, 0x3E, 0x08, 0x08, // +
  0x00, 0x80, 0x70, 0x30, 0x00, // ,
  0x08, 0x08, 0x08, 0x08, 0x08, // -
  0x00, 0x00, 0x60, 0x60, 0x00, // .
  0x20, 0x10, 0x08, 0x04, 0x02, // /
  0x3E, 0x51, 0x49, 0x45, 0x3E, // 0
  0x00, 0x42, 0x7F, 0x40, 0x00, // 1
  0x72, 0x49, 0x49, 0x49, 0x46, // 2
  0x21, 0x41, 0x49, 0x4D, 0x33, // 3
  0x18, 0x14, 0x12, 0x7F, 0x10, // 4
  0x27, 0x45, 0x45, 0x45, 0x39, // 5
  0x3C, 0x4A, 0x49, 0x49, 0x31, // 6
  0x41, 0x21, 0x11, 0x09, 0x07, // 7
  0x36, 0x49, 0x49, 0x49, 0x36, // 8
  0x46, 0x49, 0x49, 0x29, 0x1E, // 9
  0x00, 0x00, 0x14, 0x00, 0x00, // :
  0x00, 0x40, 0x34, 0x00, 0x00, // ;
  0x00, 0x08, 0x14, 0x22, 0x41, // <
  0x14, 0x14, 0x14, 0x14, 0x14, // =
  0x00, 0x41, 0x22, 0x14, 0x08, // >
  0x02, 0x01, 0x59, 0x09, 0x06, // ?
  0x3E, 0x41, 0x5D, 0x59, 0x4E, // @
  0x7C, 0x12, 0x11, 0x12, 0x7C, // A
  0x7F, 0x49, 0x49, 0x49, 0x36, // B
  0x3E, 0x41, 0x41, 0x41, 0x22, // C
  0x7F, 0x41, 0x41, 0x41, 0x3E, // D
  0x7F, 0x49, 0x49, 0x49, 0x41, // E
  0x7F, 0x09, 0x09, 0x09, 0x01, // F
  0x3E, 0x41, 0x41, 0x51, 0x73, // G
  0x7F, 0x08, 0x08, 0x08, 0x7F, // H
  0x00, 0x41, 0x7F, 0x41, 0x00, // I
  0x20, 0x40, 0x41, 0x3F, 0x01, // J
  0x7F, 0x08, 0x14, 0x22, 0x41, // K
  0x7F, 0x40, 0x40, 0x40, 0x40, // L
  0x7F, 0x02, 0x1C, 0x02, 0x7F, // M
  0x7F, 0x04, 0x08, 0x10, 0x7F, // N
  0x3E, 0x41, 0x41, 0x41, 0x3E, // O
  0x7F, 0x09, 0x09, 0x09, 0x06, // P
  0x3E, 0x41, 0x51, 0x21, 0x5E, // Q
  0x7F, 0x09, 0x19, 0x29, 0x46, // R
  0x26, 0x49, 0x49, 0x49, 0x32, // S
  0x03, 0x01, 0x7F, 0x01, 0x03, // T
  0x3F, 0x40, 0x40, 0x40, 0x3F, // U
  0x1F, 0x20, 0x40, 0x20, 0x1F, // V
  0x3F, 0x40, 0x38, 0x40, 0x3F, // W
  0x63, 0x14, 0x08, 0x14, 0x63, // X
  0x03, 0x04, 0x78, 0x04, 0x03, // Y
  0x61, 0x59, 0x49, 0x4D, 0x43, // Z
  0x00, 0x7F, 0x41, 0x41, 0x41, // [
  0x02, 0x04, 0x08, 0x10, 0x20, // backslash
  0x00, 0x41, 0x41, 0x41, 0x7F, // ]
  0x04, 0x02, 0x01, 0x02, 0x04, // ^
  0x40, 0x40, 0x40, 0x40, 0x40, // _
  0x00, 0x03, 0x07, 0x08, 0x00, // `
  0x20, 0x54, 0x54, 0x78, 0x40, // a
  0x7F, 0x28, 0x44, 0x44, 0x38, // b
  0x38, 0x44, 0x44, 0x44, 0x28, // c
  0x38, 0x44, 0x44, 0x28, 0x7F, // d
  0x38, 0x54, 0x54, 0x54, 0x18, // e
  0x00, 0x08, 0x7E, 0x09, 0x02, // f
  0x18, 0xA4, 0xA4, 0x9C, 0x78, // g - note first use of 8th (bottom) row
  0x7F, 0x08, 0x04, 0x04, 0x78, // h
  0x00, 0x44, 0x7D, 0x40, 0x00, // i
  0x20, 0x40, 0x40, 0x3D, 0x00, // j
  0x7F, 0x10, 0x28, 0x44, 0x00, // k
  0x00, 0x41, 0x7F, 0x40, 0x00, // l
  0x7C, 0x04, 0x78, 0x04, 0x78, // m
  0x7C, 0x08, 0x04, 0x04, 0x78, // n
  0x38, 0x44, 0x44, 0x44, 0x38, // o
  0xFC, 0x18, 0x24, 0x24, 0x18, // p - uses 8th row
  0x18, 0x24, 0x24, 0x18, 0xFC, // q - uses 8th row
  0x7C, 0x08, 0x04, 0x04, 0x08, // r
  0x48, 0x54, 0x54, 0x54, 0x24, // s
  0x04, 0x04, 0x3F, 0x44, 0x24, // t
  0x3C, 0x40, 0x40, 0x20, 0x7C, // u
  0x1C, 0x20, 0x40, 0x20, 0x1C, // v
  0x3C, 0x40, 0x30, 0x40, 0x3C, // w
  0x44, 0x28, 0x10, 0x28, 0x44, // x
  0x4C, 0x90, 0x90, 0x90, 0x7C, // y - uses 8th row
  0x44, 0x64, 0x54, 0x4C, 0x44, // z
  0x00, 0x08, 0x36, 0x41, 0x00, // {
  0x00, 0x00, 0x77, 0x00, 0x00, // |
  0x00, 0x41, 0x36, 0x08, 0x00, // }
  0x02, 0x01, 0x02, 0x04, 0x02, // ~
  0x3C, 0x26, 0x23, 0x26, 0x3C  // house shape: up pointer better than ^ 
};

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Похоже он в таблице 5 символов перерисовал

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Обычно шрифт 5*8 выводится в матрицу 6*8 с одним пустым столбцом, чтобы буквы визуально отделялись друг от друга.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

andriano пишет:

Обычно шрифт 5*8 выводится в матрицу 6*8 с одним пустым столбцом, чтобы буквы визуально отделялись друг от друга.

да, так и есть, вникнуть в алгоритм отрисовки не могу, мысли путаются )))
PS там то и строк всего два десятка по сути

void loop() {
  for (uint8_t MHz = 0; MHz < CHANNELS; MHz++ ) { // tune to frequency (2400 + MHz) so this loop covers 2.400 - 2.527 GHz 
                                                  // (maximum range module can handle) when channels is set to 128.
    NRF24L01_WriteReg(NRF24L01_05_RF_CH, MHz);
    CE_on; // start receiving
    delayMicroseconds(random(130, 230));          // allow receiver time to tune and start receiving 130 uS seems to be the minimum time.
                                                  // Random additional delay helps prevent strobing effects with frequency-hopping transmitters.
    CE_off;                                       // stop receiving - one bit is now set if received power was > -64 dBm at that instant
    if (NRF24L01_ReadReg(NRF24L01_09_CD)) {       // signal detected so increase signalStrength unless already maxed out
      
      signalStrength[MHz] += (0x7FFF - signalStrength[MHz]) >> 5;
                                                  // increase rapidly when previous value was low, with increase reducing
                                                  // exponentially as value approaches maximum
    } else {                                      // no signal detected so reduce signalStrength unless already at minimum
      
      signalStrength[MHz] -= signalStrength[MHz] >> 5; 
                                                  // decrease rapidly when previous value was high, with decrease reducing
                                                  // exponentially as value approaches zero
    }
     //Serial.print((signalStrength[MHz] + 0x0100) >> 9, HEX); // debugging without lcd display
     //Serial.print(" ");                                      // debugging without lcd display

    if (!--refresh) {                             // don't refresh whole display every scan (too slow)
      refresh = 19;                               // speed up by only refreshing every n-th frequency loop - reset number 
                                                  // should be relatively prime to CHANNELS
                                                  
      int strength = (signalStrength[MHz] + 0x0040) >> 7;
      if (strength > 48) {
        strength = 48;                            // limit to maximum height that fits display
      }

      for (uint8_t row = 0; row < 6; row++) {     // loop down 6 rows of display (6 x 8 pixels)
        uint8_t b = 0x00;
        if (strength > (6 - row) << 3) {          // all 8 pixels on this row of display to be set
          b = 220;//было 0xFF;
        } else if (strength > (5 - row) << 3) {   // some pixels on this row to be set
          b = 220 /*0xFF*/ << (((6 - row) << 3) - strength);
        }
        // SSD1X06::displayByte(row, MHz, b);
         tft.setTextSize(1);
        tft.setCursor(MHz, abs(row - 83));  tft.print(char(b));
      }
    }
  }
  // Serial.print("\n"); // debugging without lcd display
}

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

сдаётся мне, что надо выкинуть всю эту срань с псевдографикой и отрисовывать по человечески, линиями, да и децибелы от 64 совсем не айс, чистый канал он за 100 и более, надо порыться, где-то были спектрограммы

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

вот и потёмкинские деревни нарисовались, я об алгоритме обработки сигнала с модуля и вывода информации на экран!
Хотели шашечки - получите...только к реальному сигналу это не имеет никакого отношения...
Пора читать даташит на модуль  )))

Переписал вывод информации на дисплей, в графическом виде, сетка 1 мегагерц однако, скетч занимает всего 61 килобайт памяти из 16 мегабайт доступных )))

Модуль туповат однако, всего 82 дб да еще и программно выводится отображение сигналов с уровнем более 60 децибел, покурил покурил даташит, но так и не нашел как снять это ограничение... может не тот даташит нашёл, кто плотненько занимался этим модулем, подскажите плиз...

PS А картинко красивая, аж самому понравилось...
 

Smart_maikl
Offline
Зарегистрирован: 30.08.2022

Люди, ну какое производство. Тут форум по интересам. Для коммерческих разработок есть бюджет, есть те кто разработают и будут отвечать за корректную работу устройства.
А тут что? Ну подскажет кто где ошибся и всё. Дальше сам ковыряйся. 
Да и никто не спорит, проще всего просто взять адруину и повторить уже все готовое.
Но для меня это чисто ради собственого интереса. Есть в свободном распоряжении кучка esp, хочется попробовать его применить, чему то научиться. Но зачем делать лишь бы что. Решил что-то полезное для себя сделать.
А оно блин, на ардуино. Ну ладно, можно и ардуино взять, но просто не думал что сложно перекинуть готовый код.
В общем поковыряюсь еще. Пока денег свободных нет. Потом наверно за кеш попрошу помощи и хоть посмотрю по итогу что делал не так.
p.s. ua6em - крут!

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Всё, мысли, что ещё можно улучшить кончились, добавил автоматическое включение аттенюатора, индикация загорается в правом верхнем углу.
Для проверки пришлось включить 5 точек доступа )))
 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Так может, имеет смысл разместить предварительно-окончательный вариант в "Проектах"?

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

andriano пишет:

Так может, имеет смысл разместить предварительно-окончательный вариант в "Проектах"?

можно, сейчас GPS прикручиваю, время и координаты взять...дисплейчик бы поболее 480х320 был бы что надо

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

ua6em пишет:

...дисплейчик бы поболее 480х320 был бы что надо

Мой любимый размер!

Даже один из проектов на этом экране публиковал:

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

andriano пишет:

ua6em пишет:

...дисплейчик бы поболее 480х320 был бы что надо

Мой любимый размер!

Даже один из проектов на этом экране публиковал:

да, всё прекрасно видно...а я тут в раздумьях, что надо и вайфай модуль обыграть... вообщем дисплей на ES32 уже завёл, всё отображается, может завтра радиомодуль подключу, (в скетче уже всё прошито) памяти скушало 19% в текущей конфигурации, появляется простор для полёта фантазии, к примеру можно клиентом к расшаренному сотовому подключиться, выставить время, а дальше перевести и вайфай модуль в сканирование...

Открыл тему в проектах, если будет заинтересованность, займусь наполнением.