Сканер WIFI диапазона на основе RP2040 или ESP32 и NRF24L01

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

Адаптировал проект Сканера к модулям Rasberry PI Pico и ESP32.
Для вывода информации искользуется TFT дисплей 1.8"  128х160 на чипе ST7735.
Задействованы два SPI интерфейса, один под монитор, второй под NRF24.
Форумчане посоветовали разместить информацию в проектах, если это действительно имеет смысл,
то просьба следующий пост не цитировать, там будут размещаться актуальные версии прошивок.
 

 

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

Адаптация этого проекта

Первый пост, здесь  будут размещаться актуальные версии прошивок.

ESP32 версия 0.01b
 

#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library for ST7735
#include <Adafruit_ST7789.h> // Hardware-specific library for ST7789
#include <SPI.h>

#define HSPI // Дисплей на HSPI, NRF24L01 на VSPI

#if defined(HSPI)         // для ESP32 HSPI
#define TFT_CS        15  // GP13 - CS
#define TFT_RST       16  // GP14 - RESET
#define TFT_DC        17  // GP15 - A0
#define TFT_MISO      12  // GP12 - MISO (MISO, RX)
#define TFT_MOSI      13  // GP11 - SDA  (MOSI, TX)
#define TFT_SCLK      14  // GP10 - SCK

#else                      // для ESP32 VSPI
#define TFT_CS        5    // GP5  - CS
#define TFT_RST       20   // GP20 - RESET
#define TFT_DC        21   // GP21 - A0
#define TFT_MISO      19   // GP19 - MISO (MISO, RX)
#define TFT_MOSI      23   // GP23 - SDA  (MOSI, TX)
#define TFT_SCLK      18   // GP18 - SCK
#endif

// For ST7735-based displays, we will use this call
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);


// 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 то NRF24L01

#if defined(HSPI) // NRF24L01 на VSPI если монитор на HSPI и наоборот ;-)
#define CE_pin    21
#define CS_pin    5
#define MOSI_pin  23
#define MISO_pin  19
#define SCK_pin   18
#else // HSPI
#define CE_pin    17
#define CS_pin    15
#define MOSI_pin  13
#define MISO_pin  12
#define SCK_pin   14
#endif

#define  CE_on    digitalWrite(CE_pin, HIGH)
#define  CE_off   digitalWrite(CE_pin, LOW)
#define  CS_on    digitalWrite(CS_pin, HIGH)
#define  CS_off   digitalWrite(CS_pin, LOW)
#define  MOSI_on  digitalWrite(MOSI_pin, HIGH)
#define  MOSI_off digitalWrite(MOSI_pin, LOW)
#define  MISO_on  digitalRead(MISO_pin) // input
#define  SCK_on   digitalWrite(SCK_pin, HIGH)
#define  SCK_off  digitalWrite(SCK_pin, LOW)

// 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


// Button and Encoder
#define UsrButton 34
#define Canal 7
bool is_canal = false;
uint32_t old_millis;

#include <GyverButton.h>
GButton butt1(UsrButton);


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);
}


// функция перекодировки цвета в формат библиотеки Adafruin_GFX
//
uint16_t setColor(uint8_t red, uint8_t green, uint8_t blue) {

  //uint16_t color = ((red & 0xf8)<<11) + ((green & 0xfc) <<5) + (blue & 0xf8); //uint16_t(r5-g6-b5 bit) 
  uint16_t color = ((red & 0x0b11111000) << 11) + ((green & 0b11111100) << 5 ) + (blue & 0b11111000);
  return color;
}



void setup() {
  Serial.begin(115200); // debugging without lcd display

  //TFT
  pinMode(25, OUTPUT);
  //pinMode(UsrButton, INPUT_PULLUP);
  digitalWrite(25, HIGH); // Led


  // Use this initializer if using a 1.8" TFT screen:
  tft.initR(INITR_BLACKTAB);      // Init ST7735S chip, black tab
  tft.setRotation(1);
  tft.cp437(true);                // не пропускаем 176 символ
  tft.setSPISpeed(50000000);
  tft.fillScreen(ST77XX_BLACK);
  tft.setCursor(22, 50);
  tft.setTextColor(ST77XX_YELLOW, ST77XX_BLACK);
  tft.setTextSize(1);
  tft.print("2.4 GHz band scanner");
  tft.setCursor(3, 70);
  tft.setTextSize(1);
  tft.setTextColor(ST77XX_CYAN, ST77XX_BLACK);
  tft.print("Modified to ESP32 - UA6EM");

  // 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(5000); // Заставку отображаем 5 секунд
  tft.fillScreen(ST77XX_BLACK);

  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

  // отрисовка сетки графикой
  tft.drawLine(0, 112, 169, 112, ST77XX_WHITE);
  tft.drawLine(20, 112, 20, 120, ST77XX_WHITE);
  tft.drawLine(80, 112, 80, 120, ST77XX_WHITE);
  tft.drawLine(140, 112, 140, 120, ST77XX_WHITE);
  for (int x = 0; x < 154; x++) {
    if (!(x % 10)) {
    tft.drawLine(x, 112, x, 116, ST77XX_WHITE);
    }
  }


  // выводим надписи
  //  tft.setTextColor(0x654321/*ST77XX_MAGENTA*/, ST77XX_BLACK); // тёмно-зелёный
  //  tft.setTextColor(0x964b00/*ST77XX_MAGENTA*/, ST77XX_BLACK); // тёмно-зелёный
  //  tft.setTextColor(0x804030/*ST77XX_MAGENTA*/, ST77XX_BLACK); // тёмно-синий
  //  tft.setTextColor(0x020430/*ST77XX_MAGENTA*/, ST77XX_BLACK); // тёмно- синий
  //  tft.setTextColor(0x2d2800/*ST77XX_MAGENTA*/, ST77XX_BLACK); // тёмно- коричневый
  //  tft.setTextColor(0x2d2800/*ST77XX_MAGENTA*/, ST77XX_BLACK); // тёмно- коричневый
  tft.setTextColor(0xaa84/*ST77XX_MAGENTA*/, ST77XX_BLACK); // тёмно- кирпичный
  tft.setCursor(136, 3);  tft.print("ATT");
  //  tft.setTextColor(ST77XX_WHITE, ST77XX_BLACK);
  tft.setTextColor(setColor(247, 234, 105), ST77XX_BLACK);
  tft.setCursor(13, 120);  tft.print("2.40");
  tft.setCursor(73, 120);  tft.print("2.46");
  tft.setCursor(133, 120);  tft.print("2.52");
  tft.drawLine(0, 2, 0, 118, ST77XX_WHITE);
  tft.setCursor(1, 3);   tft.print("-10");
  tft.setCursor(1, 23);  tft.print("-20");
  tft.setCursor(1, 43);  tft.print("-30");
  tft.setCursor(1, 63);  tft.print("-40");
  tft.setCursor(1, 83);  tft.print("-50");
  tft.setCursor(1, 103); tft.print("-60"); //tft.drawChar(1,80.unsigned chat,color, color_bg,sizex,sizey)

  delay(10); // start up message

  // выводим сетку каналов
  tft.drawLine(21, 0, 43, 0, ST77XX_GREEN);  //1
  tft.drawLine(21, 1, 43, 1, ST77XX_GREEN);  //1
  tft.drawLine(26, 3, 48, 3, ST77XX_RED);    //2
  tft.drawLine(26, 4, 48, 4, ST77XX_RED);    //2
  tft.drawLine(31, 5, 53, 5, ST77XX_YELLOW); //3
  tft.drawLine(31, 6, 53, 6, ST77XX_YELLOW); //3
  tft.drawLine(36, 7, 58, 7, ST77XX_CYAN);   //4
  tft.drawLine(36, 8, 58, 8, ST77XX_CYAN);   //4
  tft.drawLine(41, 9, 63, 9, ST77XX_BLUE);   //5
  tft.drawLine(41, 10, 63, 10, ST77XX_BLUE); //5

  tft.drawLine(46, 0, 68, 0, ST77XX_WHITE);  //6
  tft.drawLine(46, 1, 68, 1, ST77XX_WHITE);  //6
  tft.drawLine(51, 3, 73, 3, ST77XX_BLUE);   //7
  tft.drawLine(51, 4, 73, 4, ST77XX_BLUE);   //7
  tft.drawLine(56, 5, 78, 5, ST77XX_RED);    //8
  tft.drawLine(56, 6, 78, 6, ST77XX_RED);    //8
  tft.drawLine(61, 7, 83, 7, ST77XX_MAGENTA);//9
  tft.drawLine(61, 8, 83, 8, ST77XX_MAGENTA);//9
  tft.drawLine(66, 9, 88, 9, ST77XX_CYAN);   //10
  tft.drawLine(66, 10, 88, 10, ST77XX_CYAN); //10

  tft.drawLine(71, 0, 92, 0, ST77XX_GREEN);  //11
  tft.drawLine(71, 1, 92, 1, ST77XX_GREEN);  //11
  tft.drawLine(76, 3, 98, 3, ST77XX_MAGENTA);//12
  tft.drawLine(76, 4, 98, 4, ST77XX_MAGENTA);//12
  tft.drawLine(81, 5, 103, 5, ST77XX_YELLOW); //13
  tft.drawLine(81, 6, 103, 6, ST77XX_YELLOW); //13
  tft.drawLine(93, 7, 115, 7, ST77XX_RED);   //14
  tft.drawLine(93, 8, 115, 8, ST77XX_RED);   //14

  // выставляем таймер на нажатие кнопки
  old_millis = millis();

} // ******* END SETUP *******


uint8_t refresh;

void loop() {
  butt1.tick();
  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 (!digitalRead(UsrButton) && millis() - old_millis >= 150){
      old_millis = millis();
    */
    if (butt1.isClick()) {
      is_canal = !is_canal;
      Serial.print("USR BOTTON is ");
      Serial.println(is_canal);
    }
    // Вывод информации
    if (!is_canal) {
      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

        tft.setTextSize(1);
        tft.drawLine(20 + MHz, 11, 20 + MHz, 110, ST77XX_BLACK);
        if (signalStrength[MHz] / 73 >= 78) {
          tft.drawLine(20 + MHz, (110 - (signalStrength[MHz] / 346)), 20 + MHz, 110, ST77XX_WHITE);
          tft.setTextColor(ST77XX_MAGENTA, ST77XX_BLACK);
          tft.setCursor(136, 3);  tft.print("ATT");
          // tft.setTextColor(ST77XX_MAGENTA, ST77XX_BLACK);
        } else {
          tft.drawLine(20 + MHz, (110 - (signalStrength[MHz] / 73)), 20 + MHz, 110, ST77XX_WHITE);
          tft.setTextColor(0xaa84/*ST77XX_MAGENTA*/, ST77XX_BLACK);
          tft.setCursor(136, 3);  tft.print("ATT");
          //  tft.setTextColor(ST77XX_WHITE, ST77XX_BLACK);
        }
        delay(0);
      }
    } else { // смотрим широкий канал (для пробы 7)
      if (!--refresh) {                             // don't refresh whole display every scan (too slow)
        refresh = 9;
        if (MHz >= 31 && MHz <= 53) {
          int i = 0;
          while (i < 5) {
            tft.drawLine(20 + (MHz - 31) * 5 + i, 11, 0 + (MHz - 31) * 5 + i, 111, ST77XX_BLACK);
            if (signalStrength[MHz] / 173 >= 90) {
              tft.drawLine(20 + (MHz - 31) * 5 + i, (110 - (signalStrength[MHz] / 346)), 20 + (MHz - 31) * 5 + i, 110, ST77XX_WHITE);
              tft.setTextColor(ST77XX_MAGENTA, ST77XX_BLACK);
              tft.setCursor(136, 3);  tft.print("ATT");
              tft.setTextColor(ST77XX_WHITE, ST77XX_BLACK);
            } else {
              tft.drawLine(20 + (MHz - 31) * 5 + i, (110 - (signalStrength[MHz] / 173)), 20 + (MHz - 31) * 5 + i, 110, ST77XX_WHITE);
              tft.setTextColor(ST77XX_WHITE, ST77XX_BLACK);
              tft.setCursor(136, 3);  tft.print("ATT");
              tft.setTextColor(ST77XX_MAGENTA, ST77XX_BLACK);
            }
            i++;
          }
        }
      }
    }
  }
 } // ******************* END LOOP ***********************



Добавил сканирование WiFi сетей, вывод информации в монитор порта (максимум) и на экран.
Объединил скетчи для Rasberry PI Pico (и иные) и ESP32 в один, иначе замучаешься шоркаться по версиям.
Скетч крайней версии, поддерживаются дисплеи ST7735 (128*160) и ILI9341 (240*320):

// 07.10.2022 - Добавлена поддержка дисплея ILI9341
//            - в локальной библиотеке ST77XX расширен набор цветов
//            - в локальной библиотеке ILI9341 исправлена последовательность пинов для &SPI
//            - добавлен вывод на большой дисплей частоты и MAC адресов обнаруженных устройств.

// 09.10.2022 - Дорисована сетка каналов, исправлены мелкие ошибки,работа проверена с конфигурацией
//              дисплея и модуля NRF24 на портах SPI по умолчанию, альтернативное подключение
//              не проверялось. (SPI0 - NRF24, SPI1 - дисплей.) Для ESP32 реализован только SOFT SPI
//              так как в ядре прописан только один SPI и по умолчанию выбран SPI3,(hard-в реализации )
//              Для ESP32 распиновка SPI выбрана в соответствии с ядром GENERIC.
//              Режим HARD SPI создаёт помехи на NRF модуль на частотах до 500Mhz (выше не проверялось)
//              При монтаже линии SPI делаем как можно короче!!!

//              Из планируемого - добавление энкодера и усилителя на вход NRF24 что даст возможность
//              видеть сигналы с уровнем -100дб и просматривать конкретный участок частотного диапазона.

 

Added scanning of WiFi networks, output of information to the port monitor (maximum) and to the screen. I combined sketches for Rasberry PI Pico (and others) and ESP32 into one, otherwise you'll get tired of blowing your nose on versions. Sketch of the extreme version:

 

#define HARD_SPI

#include <Adafruit_GFX.h>    // Core graphics library
#include <SPI.h>
#include <Arduino.h>


// ДИСПЛЕЙ
uint8_t q = 2; // пропорциональность дисплея ILI9341 по горизонтали

// Размаркировать для дисплея на контроллере ST7735
// #define ST7735

#ifdef ST7735
#include <Adafruit_ST7735.h> // Hardware-specific library for ST7735
#include <Adafruit_ST7789.h> // Hardware-specific library for ST7789

#else // ILI9341
#include <Adafruit_ILI9341.h> //  Hardware-specific library for ILI9341 240x320

// Some ready-made 16-bit ('565') color settings:
#define ST77XX_BLACK 0x0000       ///<   0,   0,   0
#define ST77XX_NAVY 0x000F        ///<   0,   0, 123
#define ST77XX_DARKGREEN 0x03E0   ///<   0, 125,   0
#define ST77XX_DARKCYAN 0x03EF    ///<   0, 125, 123
#define ST77XX_MAROON 0x7800      ///< 123,   0,   0
#define ST77XX_PURPLE 0x780F      ///< 123,   0, 123
#define ST77XX_OLIVE 0x7BE0       ///< 123, 125,   0
#define ST77XX_LIGHTGREY 0xC618   ///< 198, 195, 198
#define ST77XX_DARKGREY 0x7BEF    ///< 123, 125, 123
#define ST77XX_BLUE 0x001F        ///<   0,   0, 255
#define ST77XX_GREEN 0x07E0       ///<   0, 255,   0
#define ST77XX_CYAN 0x07FF        ///<   0, 255, 255
#define ST77XX_RED 0xF800         ///< 255,   0,   0
#define ST77XX_MAGENTA 0xF81F     ///< 255,   0, 255
#define ST77XX_YELLOW 0xFFE0      ///< 255, 255,   0
#define ST77XX_WHITE 0xFFFF       ///< 255, 255, 255
#define ST77XX_ORANGE 0xFD20      ///< 255, 165,   0
#define ST77XX_GREENYELLOW 0xAFE5 ///< 173, 255,  41
#define ST77XX_PINK 0xFC18        ///< 255, 130, 198
#endif


#if ( defined(ARDUINO_NANO_RP2040_CONNECT) || defined(ARDUINO_RASPBERRY_PI_PICO) || defined(ARDUINO_ADAFRUIT_FEATHER_RP2040) || \
      defined(ARDUINO_GENERIC_RP2040) )

// замаркировать если используем наоборот
#define SPI01             // Дисплей на SPIO1, NRF24L01 на SPI0 (выбор между SPI0 и SPI1)
#if defined(SPI01)        // для RP2040 SPI1
#define TFT_CS        13  // GP13 - CS              (hard - 13)
#define TFT_RST       10  // GP14 - RESET           (10)  
#define TFT_DC        11  // GP15 - A0              (11)  
#define TFT_MISO      12  // GP12 - MISO (MISO, RX) (hard - 12)
#define TFT_MOSI      15  // GP11 - SDA  (MOSI, TX) (hard - 15)
#define TFT_SCLK      14  // GP10 - SCK             (hard - 14)
#else                     // для RP2040 SPI0
#define TFT_CS        17  //5   // GP5 - CS               (hard - 17)
#define TFT_RST       20  //6   // GP6 - RESET
#define TFT_DC        21  //7   // GP7 - A0
#define TFT_MISO      16  //4   // GP4 - MISO (MISO, RX)  (hard - 16)
#define TFT_MOSI      19  //3   // GP3 - SDA  (MOSI, TX)  (hard - 19)
#define TFT_SCLK      18  //2   // GP2 - SCK              (hard - 18)
#endif

// SPI definitions and macros то NRF24L01
#if defined(SPI01)
#define CE_pin    21 //7
#define RST_pin   20 // не используется
#define CS_pin    17 //5
#define MOSI_pin  19 //3
#define MISO_pin  16 //4
#define SCK_pin   18 //2
#else
#define CE_pin    11 //15
#define RST_pin   10 // не используется
#define CS_pin    13
#define MOSI_pin  15 //11
#define MISO_pin  12
#define SCK_pin   14 //10
#endif
#include "api/HardwareSPI.h"

#elif ( defined(ESP32))

#define WIFI             // Используем модуль вайфая
#include "WiFi.h"
#include <Ticker.h>
Ticker blinks;
float blinkPeriod = 0.25;

// ***   ***   ***           Для ESP32 подключаем SPI так:
#define HSPIs             // Дисплей на HSPI, NRF24L01 на VSPI
#if defined(HSPIs)         // для ESP32 HSPI
#define TFT_CS        15  // GP13 - CS
#define TFT_RST       16  // GP14 - RESET
#define TFT_DC        17  // GP15 - A0
#define TFT_MISO      12  // GP12 - MISO (MISO, RX)
#define TFT_MOSI      13  // GP11 - SDA  (MOSI, TX)
#define TFT_SCLK      14  // GP10 - SCK
#else                     // для ESP32 VSPI
#define TFT_CS        5   // GP5  - CS
#define TFT_RST       20  // GP20 - RESET
#define TFT_DC        21  // GP21 - A0
#define TFT_MISO      19  // GP19 - MISO (MISO, RX)
#define TFT_MOSI      23  // GP23 - SDA  (MOSI, TX)
#define TFT_SCLK      18  // GP18 - SCK
#endif

// SPI definitions and macros то NRF24L01
#if defined(HSPIs) // NRF24L01 на VSPI если монитор на HSPI и наоборот ;-)
#define CE_pin    21
#define CS_pin    5
#define MOSI_pin  23
#define MISO_pin  19
#define SCK_pin   18
#else // HSPIs
#define CE_pin    17
#define CS_pin    15
#define MOSI_pin  13
#define MISO_pin  12
#define SCK_pin   14
#endif


#else
#error This code is intended to run on the RP2040 or ESP32 modules!
#endif

/********************/
#ifdef ST7735
/********************/
  #ifndef WIFI // Если это не ESP32 то
    #ifdef HARD_SPI
      #ifndef SPI01
      // For ST7735-based displays, we will use this call
      Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST); // Only SPI0 ???
      #else
      //hard SPI для RP2040
      Adafruit_ST7735 tft = Adafruit_ST7735(&SPI1, TFT_CS, TFT_DC, TFT_RST); //via hard SPI1
      #endif
    #else
    //Soft SPI для RP2040
    Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST); // Via Soft SPI
    #endif
  #else  //Для ESP32
  // SOFT SPI для ESP32
  Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST); // Via Soft SPI
  #endif
/********************/
#else  // * ILI9341 *
/********************/
  #ifndef WIFI // Если это не ESP32 то
    #ifdef HARD_SPI
      #ifndef SPI01
      // For ILI9341-based displays, we will use this call
      Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST); // Only SPI0 ???
      #else // define SPI01
      //hard SPI01 для RP2040
      //Adafruit_ILI9341 tft = Adafruit_ILI9341(&SPI1, TFT_DC, TFT_CS, TFT_RST); //via hard SPI1 old LIB
      Adafruit_ILI9341 tft = Adafruit_ILI9341(&SPI1, TFT_CS, TFT_DC, TFT_RST); //via hard SPI1 

      #endif
    #else // Soft SPI
    //Soft SPI для RP2040
    Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST,TFT_MISO); // Via Soft SPI
    #endif
  #else  //Для ESP32 используем только SOFT SPI
  // SOFT SPI для ESP32
  Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST,TFT_MISO); // Via Soft SPI
  #endif
/********************/
#endif
/********************/

// Образцы инициализации TFT SPI
//Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST,TFT_MISO); 
//Adafruit_ILI9341 tft = Adafruit_ILI9341(&SPI1,  TFT_DC,TFT_CS, TFT_RST);
//Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);

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

uint16_t signalStrength[CHANNELS]; // smooths signal strength with numerical range 0 - 0x7FFF
uint16_t CH[] = {2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 2467, 2472};

#define  CE_on    digitalWrite(CE_pin, HIGH)
#define  CE_off   digitalWrite(CE_pin, LOW)
#define  CS_on    digitalWrite(CS_pin, HIGH)
#define  CS_off   digitalWrite(CS_pin, LOW)
#define  MOSI_on  digitalWrite(MOSI_pin, HIGH)
#define  MOSI_off digitalWrite(MOSI_pin, LOW)
#define  MISO_on  digitalRead(MISO_pin) // input
#define  SCK_on   digitalWrite(SCK_pin, HIGH)
#define  SCK_off  digitalWrite(SCK_pin, LOW)

// 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,
};


// Button and Encoder
#define UsrButton 34
#define Canal 7
bool is_canal = false;
uint32_t old_millis;

#include <GyverButton.h>
GButton btn_01(UsrButton);


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_P         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);
}


// функция перекодировки цвета в формат библиотеки Adafruin_GFX
//
uint16_t setColor(uint8_t red, uint8_t green, uint8_t blue) {
  return ((red & 0xF8) << 8) | ((green & 0xFC) << 3) | (blue >> 3);
}

#ifdef WIFI
volatile  int n;
#define Time_WiFiScan 30000

void WiFi_Scan(void) {
  clearDisplay(); // инициализируем вывод на дисплей

  #ifdef ST7735
  tft.setCursor(20, 40);
  tft.setTextSize(2);
  tft.setTextColor(ST77XX_YELLOW, ST77XX_BLACK);
  tft.print("   SCAN");
  tft.setCursor(20, 70);
  tft.print(" NETWORKS"); 
  #else // ILI9341
  tft.setCursor(95, 80);
  tft.setTextSize(2);
  tft.setTextColor(ST77XX_YELLOW, ST77XX_BLACK);
  tft.print("   SCAN");
  tft.setCursor(95, 120);
  tft.print(" NETWORKS");
  blinks.attach(blinkPeriod,blinker);
  #endif

  Serial.println("scan start");
  // WiFi.scanNetworks will return the number of networks found
  n = WiFi.scanNetworks();
  blinks.detach();
  tft.fillScreen(ST77XX_BLACK);
  tft.invertDisplay(false);
  tft.setTextSize(1);
  tft.setTextColor(ST77XX_WHITE, ST77XX_BLACK); 
  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));
      String ssid = (WiFi.SSID(i));

      tft.setCursor(3, 20 + (i * 12));
      tft.print(i + 1);
      tft.print(": ");
      tft.print(ssid);

      // выравнивание текста
      int s = ssid.length(); //sizeof(ssid);
      s = 10 - s;
      if (s >= 0) {
        for (int j = 0; j < s; j++) {
          Serial.print(" ");
          tft.print(" ");
        }
      }
      Serial.print(" (");
      tft.print(" (");
      Serial.print(WiFi.RSSI(i));
      tft.print(WiFi.RSSI(i));
      Serial.print(" CH-");
      tft.print(" CH-");
      if (WiFi.channel(i) < 10) {
        Serial.print(" ");
        //tft.print(" ");
      }
      if(WiFi.channel(i) <10) {
        Serial.print("0");
        tft.print("0");
      }
      Serial.print(WiFi.channel(i));
      tft.print(WiFi.channel(i));
      
      #ifndef ST7735
      tft.print(" F=");
      tft.print(CH[(WiFi.channel(i)) - 1]);
      tft.print("M");
      tft.print(" ");
      //tft.print(" MAC::");
      tft.print(WiFi.BSSIDstr(i));
      //tft.print(" ");
      #endif
       
      Serial.print(" Freq=");
      Serial.print(CH[(WiFi.channel(i)) - 1]);
      Serial.print("MHz MAC::");
      Serial.print(WiFi.BSSIDstr(i));
      Serial.print(" ");
      
      int e = WiFi.encryptionType(i);
      if (e == 0) {
        Serial.print("No Encrypton");
      } else if (e == 1) {
        Serial.print("WEP");
      } else if (e == 2) {
        Serial.print("WPA");
      } else if (e == 3) {
        Serial.print("WPA2/PSK (CCMP)");
      } else if (e == 4) {
        Serial.print("WPA2/PSK (TKIP,CCMP)");
      }
      Serial.println(")");
      tft.println(")");
      delay(10);
    }
  }
  Serial.println("");
  delay(10000);
  tft.fillScreen(ST77XX_BLACK);
  dispHello();
}


void blinker() {
  static bool i;
  i= !i;
  tft.invertDisplay(i);
}

#endif


void clearDisplay() {
  tft.fillScreen(ST77XX_BLACK);
  tft.setTextColor(ST77XX_WHITE, ST77XX_BLACK);
}



/*********************************** S E T U P ************************************/

void setup() {
  Serial.begin(115200); // debugging without lcd display

#ifdef WIFI
  // WIFI
  WiFi.mode(WIFI_STA);
  WiFi.disconnect();
  delay(100);
#endif

  //TFT
#ifdef WIFI
  pinMode(25, OUTPUT);
  digitalWrite(25, HIGH); // Led DISPLAY is ON
#else
  pinMode(29, OUTPUT);
  digitalWrite(29, HIGH); // Led DISPLAY is ON
#endif
  dispInit();
  
  //pinMode(UsrButton, INPUT_PULLUP);

  // 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(5000); // Заставку отображаем 5 секунд
  tft.fillScreen(ST77XX_BLACK);

  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

  dispHello();

  // выставляем таймер
  old_millis = millis();
  

} // ******* END SETUP *******



/***************************** L O O P **************************/

uint8_t refresh;

void loop() {
  btn_01.tick(); // проверяем кнопки

#ifdef WIFI
  // Сканируем WiFi раз в 5 секунд
  if (millis() - old_millis >= Time_WiFiScan) {
    WiFi_Scan();
    old_millis = millis();
  }
#endif

  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 (!digitalRead(UsrButton) && millis() - old_millis >= 150){
      old_millis = millis();
    *
    if (btn_01.isClick()) {
      is_canal = !is_canal;
      Serial.print("USR BOTTON is ");
      Serial.println(is_canal);
    }
    */

    
    // Вывод информации
#ifdef ST7735    
    if (!is_canal) {
      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

        tft.setTextSize(1);
        tft.drawLine(20 + MHz, 11, 20 + MHz, 110, ST77XX_BLACK);
        if (signalStrength[MHz] / 73 >= 78) {
          tft.drawLine(20 + MHz, (110 - (signalStrength[MHz] / 346)), 20 + MHz, 110, ST77XX_WHITE);
          tft.setTextColor(ST77XX_MAGENTA, ST77XX_BLACK);
          tft.setCursor(136, 3);  tft.print("ATT");
          // tft.setTextColor(ST77XX_MAGENTA, ST77XX_BLACK);
        } else {
          tft.drawLine(20 + MHz, (110 - (signalStrength[MHz] / 73)), 20 + MHz, 110, ST77XX_WHITE);
          tft.setTextColor(0xaa84/*ST77XX_MAGENTA*/, ST77XX_BLACK);
          tft.setCursor(136, 3);  tft.print("ATT");
          //  tft.setTextColor(ST77XX_WHITE, ST77XX_BLACK);
        }
        delay(0);
      }
    } else { // смотрим широкий канал (для пробы 7)
      if (!--refresh) {                             // don't refresh whole display every scan (too slow)
        refresh = 9;
        if (MHz >= 31 && MHz <= 53) {
          int i = 0;
          while (i < 5) {
            tft.drawLine(20 + (MHz - 31) * 5 + i, 11, 0 + (MHz - 31) * 5 + i, 111, ST77XX_BLACK);
            if (signalStrength[MHz] / 173 >= 90) {
              tft.drawLine(20 + (MHz - 31) * 5 + i, (110 - (signalStrength[MHz] / 346)), 20 + (MHz - 31) * 5 + i, 110, ST77XX_WHITE);
              tft.setTextColor(ST77XX_MAGENTA, ST77XX_BLACK);
              tft.setCursor(136, 3);  tft.print("ATT");
              tft.setTextColor(ST77XX_WHITE, ST77XX_BLACK);
            } else {
              tft.drawLine(20 + (MHz - 31) * 5 + i, (110 - (signalStrength[MHz] / 173)), 20 + (MHz - 31) * 5 + i, 110, ST77XX_WHITE);
              tft.setTextColor(ST77XX_WHITE, ST77XX_BLACK);
              tft.setCursor(136, 3);  tft.print("ATT");
              tft.setTextColor(ST77XX_MAGENTA, ST77XX_BLACK);
            }
            i++;
          }
        }
      }
    }
#else //ILI9341
      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

        tft.setTextSize(2);
        tft.drawLine(40 + MHz*2, 40, 40 + MHz*2, 220, ST77XX_BLACK);
        if (signalStrength[MHz] / 73 >= 156) {
          tft.drawLine(40 + MHz*2, (220 - (signalStrength[MHz] / 346)), 40 + MHz*2, 220, ST77XX_WHITE);
          tft.setTextColor(ST77XX_MAGENTA, ST77XX_BLACK);
          tft.setCursor(280, 6);  tft.print("ATT");
          // tft.setTextColor(ST77XX_MAGENTA, ST77XX_BLACK);
        } else {
          tft.drawLine(40 + MHz*2, (220 - (signalStrength[MHz] / 73)), 40 + MHz*2, 220, ST77XX_WHITE);
          tft.setTextColor(0xaa84/*ST77XX_MAGENTA*/, ST77XX_BLACK);
          tft.setCursor(280, 6);  tft.print("ATT");
          //  tft.setTextColor(ST77XX_WHITE, ST77XX_BLACK);
        }
        tft.setTextSize(1);
        delay(0);
      }
#endif
  }
} // ************************** END LOOP ******************************


void dispInit() {
  
#ifdef ST7735
  // Use this initializer if using a 1.8" TFT screen:
  tft.initR(INITR_BLACKTAB);      // Init ST7735S chip, black tab
#else
  // 3.2" ILI9341  
  tft.begin();
#endif
  
  tft.setRotation(1);
  tft.cp437(true); // не пропускаем 176 символ
  
//Если используется HARD SPI устанавливаем скорость порта  
#ifdef HARD_SPI
  #ifdef WIFI 
  // SPI для ESP32  
  tft.setSPISpeed(20000000);  // отдельные экземпляры дисплеев не работают на такой скорости
  #else                       // откорректируйте под конкретный экземпляр
  // SPI для RP2040  
  tft.setSPISpeed(25000000);
  #endif
#endif  

#ifdef ST7735
  tft.fillScreen(ST77XX_BLACK);
  tft.setCursor(22, 50);
  tft.setTextColor(ST77XX_YELLOW, ST77XX_BLACK);
  tft.setTextSize(1);
  tft.print("2.4 GHz band scanner");
  tft.setCursor(3, 70);
  tft.setTextSize(1);
  tft.setTextColor(ST77XX_CYAN, ST77XX_BLACK);

  #ifdef WIFI
  tft.print("Modified to ESP32 - UA6EM");
  #else
  tft.print("Modified to RP2040 - UA6EM");
  #endif
  
#else //ILI9341
  tft.fillScreen(ST77XX_BLACK);
  tft.setCursor(50, 100);
  tft.setTextColor(ST77XX_YELLOW, ST77XX_BLACK);
  tft.setTextSize(2);
  tft.print("2.4 GHz band scanner");
  tft.setCursor(3, 140);
  tft.setTextSize(2);
  tft.setTextColor(ST77XX_CYAN, ST77XX_BLACK);

  #ifdef WIFI
  tft.print("Modified to ESP32  - UA6EM");
  #else
  tft.print("Modified to RP2040 - UA6EM");
  #endif
#endif

}


void dispHello() {
#ifdef ST7735  
  // отрисовка сетки графикой
  tft.drawLine(0, 112, 169, 112, ST77XX_WHITE);
  tft.drawLine(20, 112, 20, 120, ST77XX_WHITE);
  tft.drawLine(80, 112, 80, 120, ST77XX_WHITE);
  tft.drawLine(140, 112, 140, 120, ST77XX_WHITE);
  for (int x = 0; x < 154; x++) {
    if (!(x % 10)) {
      tft.drawLine(x, 112, x, 116, ST77XX_WHITE);
    }
  }

  // выводим надписи
  tft.setTextColor(0xaa84, ST77XX_BLACK); // тёмно- кирпичный
  tft.setCursor(136, 3);  tft.print("ATT");
  //  tft.setTextColor(ST77XX_WHITE, ST77XX_BLACK);
  tft.setTextColor(setColor(247, 234, 105), ST77XX_BLACK);
  tft.setCursor(13, 120);  tft.print("2.40");
  tft.setCursor(73, 120);  tft.print("2.46");
  tft.setCursor(133, 120);  tft.print("2.52");
  tft.drawLine(0, 2, 0, 118, ST77XX_WHITE);
  tft.setCursor(1, 3);   tft.print("-10");
  tft.setCursor(1, 23);  tft.print("-20");
  tft.setCursor(1, 43);  tft.print("-30");
  tft.setCursor(1, 63);  tft.print("-40");
  tft.setCursor(1, 83);  tft.print("-50");
  tft.setCursor(1, 103); tft.print("-60");
  
#else // ILI9341

  // отрисовка сетки графикой
  tft.drawLine(0, 220, 320, 220, ST77XX_WHITE);
  tft.drawLine(40, 220, 40, 230, ST77XX_WHITE);   // 2.40
  tft.drawLine(160, 220, 160, 230, ST77XX_WHITE); // 2.46
  tft.drawLine(280, 220, 280, 230, ST77XX_WHITE); // 2.52
  for (int x = 0; x < 308; x++) {
    if (!(x % 20)) {
      tft.drawLine(x, 220, x, 226, ST77XX_WHITE);
    }
  }

  // выводим надписи
  tft.setTextColor(0xaa84, ST77XX_BLACK); // тёмно- кирпичный
  tft.setTextSize(2);
  tft.setCursor(280, 6);  tft.print("ATT");
  tft.setTextSize(1);
  //  tft.setTextColor(ST77XX_WHITE, ST77XX_BLACK);
  tft.setTextColor(setColor(247, 234, 105), ST77XX_BLACK);
  tft.setCursor(33, 230);  tft.print("2.40");
  tft.setCursor(153, 230);  tft.print("2.46");
  tft.setCursor(273, 230);  tft.print("2.52");
  tft.drawLine(1, 50, 1, 230, ST77XX_WHITE);
  tft.setCursor(2, 55);  tft.print("-00");
  tft.setCursor(2, 80);  tft.print("-10");
  tft.setCursor(2, 105); tft.print("-20");
  tft.setCursor(2, 130); tft.print("-30");
  tft.setCursor(2, 155); tft.print("-40");
  tft.setCursor(2, 180); tft.print("-50");
  tft.setCursor(2, 205); tft.print("-60");
  
#endif

  delay(10); // start up message

 // выводим сетку каналов WiFI 2.4GHz
#ifdef ST7735

  tft.drawLine(21, 0, 43, 0, ST77XX_GREEN);   //1
  tft.drawLine(21, 1, 43, 1, ST77XX_GREEN);   //1
  tft.drawLine(26, 3, 48, 3, ST77XX_RED);     //2
  tft.drawLine(26, 4, 48, 4, ST77XX_RED);     //2
  tft.drawLine(31, 5, 53, 5, ST77XX_YELLOW);  //3
  tft.drawLine(31, 6, 53, 6, ST77XX_YELLOW);  //3
  tft.drawLine(36, 7, 58, 7, ST77XX_CYAN);    //4
  tft.drawLine(36, 8, 58, 8, ST77XX_CYAN);    //4
  tft.drawLine(41, 9, 63, 9, ST77XX_BLUE);    //5
  tft.drawLine(41, 10, 63, 10, ST77XX_BLUE);  //5

  tft.drawLine(46, 0, 68, 0, ST77XX_WHITE);   //6
  tft.drawLine(46, 1, 68, 1, ST77XX_WHITE);   //6
  tft.drawLine(51, 3, 73, 3, ST77XX_BLUE);    //7
  tft.drawLine(51, 4, 73, 4, ST77XX_BLUE);    //7
  tft.drawLine(56, 5, 78, 5, ST77XX_RED);     //8
  tft.drawLine(56, 6, 78, 6, ST77XX_RED);     //8
  tft.drawLine(61, 7, 83, 7, ST77XX_MAGENTA); //9
  tft.drawLine(61, 8, 83, 8, ST77XX_MAGENTA); //9
  tft.drawLine(66, 9, 88, 9, ST77XX_CYAN);    //10
  tft.drawLine(66, 10, 88, 10, ST77XX_CYAN);  //10

  tft.drawLine(71, 0, 92, 0, ST77XX_GREEN);   //11
  tft.drawLine(71, 1, 92, 1, ST77XX_GREEN);   //11
  tft.drawLine(76, 3, 98, 3, ST77XX_MAGENTA); //12
  tft.drawLine(76, 4, 98, 4, ST77XX_MAGENTA); //12
  tft.drawLine(81, 5, 103, 5, ST77XX_YELLOW); //13
  tft.drawLine(81, 6, 103, 6, ST77XX_YELLOW); //13
  tft.drawLine(93, 7, 115, 7, ST77XX_RED);    //14
  tft.drawLine(93, 8, 115, 8, ST77XX_RED);    //14

#else // ILI9341

  tft.drawLine(42, 24, 230, 24, ST77XX_WHITE);
  for (int x = 0; x < 14; x++) {
    if(x <12) {
      tft.drawLine(66 + 11 * x, 24, 66 + 11 * x, 28, ST77XX_WHITE);
    }
    if(x > 12) tft.drawLine(66 + 11 * x, 24, 66 + 11 * x, 28, ST77XX_WHITE);  
   }
  
   for (int x = 1; x < 14; x+=2) {
    if(x <10){
      tft.setCursor(53 + 11 * x, 32);  tft.print(x);
    }else if(x == 11) {
      tft.setCursor((53 + 11 * x)-3, 32);  tft.print(x);
    } else if(x == 13){
      tft.setCursor((64 + 11 * x)-3, 32);  tft.print(x);
      }
   }
  tft.setTextSize(2); 
  tft.setCursor(15, 27);
  tft.print("CH");
  tft.setTextSize(1);
  tft.drawLine(21*q, 1*q, 43*q, 1*q, ST77XX_GREEN);   //1
  tft.drawLine(21*q, 2*q, 43*q, 2*q, ST77XX_GREEN);   //1
  tft.drawLine(26*q, 3*q, 48*q, 3*q, ST77XX_RED);     //2
  tft.drawLine(26*q, 4*q, 48*q, 4*q, ST77XX_RED);     //2
  tft.drawLine(31*q, 5*q, 53*q, 5*q, ST77XX_YELLOW);  //3
  tft.drawLine(31*q, 6*q, 53*q, 6*q, ST77XX_YELLOW);  //3
  tft.drawLine(36*q, 7*q, 58*q, 7*q, ST77XX_CYAN);    //4
  tft.drawLine(36*q, 8*q, 58*q, 8*q, ST77XX_CYAN);    //4
  tft.drawLine(41*q, 9*q, 63*q, 9*q, ST77XX_BLUE);    //5
  tft.drawLine(41*q, 10*q, 63*q, 10*q, ST77XX_BLUE);  //5

  tft.drawLine(46*q, 1*q, 68*q, 1*q, ST77XX_WHITE);   //6
  tft.drawLine(46*q, 2*q, 68*q, 2*q, ST77XX_WHITE);   //6
  tft.drawLine(51*q, 3*q, 73*q, 3*q, ST77XX_BLUE);    //7
  tft.drawLine(51*q, 4*q, 73*q, 4*q, ST77XX_BLUE);    //7
  tft.drawLine(56*q, 5*q, 78*q, 5*q, ST77XX_RED);     //8
  tft.drawLine(56*q, 6*q, 78*q, 6*q, ST77XX_RED);     //8
  tft.drawLine(61*q, 7*q, 83*q, 7*q, ST77XX_MAGENTA); //9
  tft.drawLine(61*q, 8*q, 83*q, 8*q, ST77XX_MAGENTA); //9
  tft.drawLine(66*q, 9*q, 88*q, 9*q, ST77XX_CYAN);    //10
  tft.drawLine(66*q, 10*q, 88*q, 10*q, ST77XX_CYAN);  //10

  tft.drawLine(71*q, 1*q, 92*q, 1*q, ST77XX_GREEN);   //11
  tft.drawLine(71*q, 2*q, 92*q, 2*q, ST77XX_GREEN);   //11
  tft.drawLine(76*q, 3*q, 98*q, 3*q, ST77XX_MAGENTA); //12
  tft.drawLine(76*q, 4*q, 98*q, 4*q, ST77XX_MAGENTA); //12
  tft.drawLine(81*q, 5*q, 103*q, 5*q, ST77XX_YELLOW); //13
  tft.drawLine(81*q, 6*q, 103*q, 6*q, ST77XX_YELLOW); //13
  tft.drawLine(93*q, 7*q, 115*q, 7*q, ST77XX_RED);    //14
  tft.drawLine(93*q, 8*q, 115*q, 8*q, ST77XX_RED);    //14
 
#endif
 }

 

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

Для выравнивания текста (SSID - WiFi.SSID(i) ) необходимо получить длину строки,
если делать так получаю независимо от длины строки - 16, как это одолеть?

PS странно почему 16, по стандарту под длину SSID выделено 32 байта
 

      // выравнивание текста
      String ssid = (WiFi.SSID(i)); 
      int s = sizeof(ssid);        

 

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

ssid.length()

Не тупи, sizeof-ом ты мериишь скока байт занимают в памяти члены класса String, не более 

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

DetSimen пишет:

ssid.length()

Не тупи, sizeof-ом ты мериишь скока байт занимают в памяти члены класса String, не более 

после двух корон что-то в консерватории не то, даже сухое вино не могу...

В скетче для ESP32 одолел вывод информации в монитор порта, по максимому, что можно вытащить, с производителем оборудования пока не заморачивался и вывод на экран.
Версия бэтта вполне работает!

 

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

На ESP32 не все дисплеи заработали на 50-ти мегагерцовой шине SPI, добавил раздельную установку скорости шины для ESP32 и RP2040!
Поправил некоторые мелкие огрехи. Если кто-то захочет поэкспериментировать дайте знать о багах.

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

ua6em пишет:

На ESP32 не все дисплеи заработали

и много дисплеев пробовал?

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

b707 пишет:

ua6em пишет:

На ESP32 не все дисплеи заработали

и много дисплеев пробовал?

у меня их всего 5 штук (было, разодрал их в попытке промыть, теперь минус два ))) )

russo
Offline
Зарегистрирован: 20.11.2014

Для чего нужна кнопка в этом проекте? При нажатии загорается АТТ, которая меняет цвет АТТ, график уровня сигнала по частотам перестает строиться на 24L01, перезагрузка не помогает, перепрошивка тоже. До нажатия кнопки график нормально отображался

 

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

russo пишет:

Для чего нужна кнопка в этом проекте? При нажатии загорается АТТ, которая меняет цвет АТТ, график уровня сигнала по частотам перестает строиться на 24L01, перезагрузка не помогает, перепрошивка тоже. До нажатия кнопки график нормально отображался

задумана для отображения сигнала в узком диапазоне, в  стадии написания..., нажмите резет, всё должно работать без перепрошивки...
PS по ESP32 пока не скажу, но на RP2040 если задирать скорость SPI начинают лезть помехи в широком диапазоне, до 450 мегагерц точно, SPI в Soft режиме этим не грешит...

 

PS похоже у вас кнопка залипает

russo
Offline
Зарегистрирован: 20.11.2014

Шустро по каналам бегает ESP, опрос 128 каналов на 24L01 занимает 130 милисекунд. 

Надо сделать обнаружение дронов. Пока простое обнаружение излучения в диапазоне 2.4 - 2.52 Мгц. Железка запоминает излучения в течении минуты-пяти минут и если появляется новое излучение то сигналит. Конечно, железка не обнаружит излучение если оно попадет в существующие пакеты WiFi сигналов, поэтому надо делать с распознованием протоколов жедлезку, но это дальнейшее будет  развитие 

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

russo пишет:

Шустро по каналам бегает ESP, опрос 128 каналов на 24L01 занимает 130 милисекунд. 

Надо сделать обнаружение дронов. Пока простое обнаружение излучения в диапазоне 2.4 - 2.52 Мгц. Железка запоминает излучения в течении минуты-пяти минут и если появляется новое излучение то сигналит. Конечно, железка не обнаружит излучение если оно попадет в существующие пакеты WiFi сигналов, поэтому надо делать с распознованием протоколов жедлезку, но это дальнейшее будет  развитие 

нужна хорошая колинеарная антенна и малошумяший предусилитель (на 40 дб однако) на входе, далее сигнал подаём на циркулятор,  с циркулятора на NRF24 , а выход циркулятора нагружаем резистором 50 Ом и, будем видеть сигналы до уровня -120дб

russo
Offline
Зарегистрирован: 20.11.2014

Не могу понять, что такое АТТ? На что идет проверка if (signalStrength[MHz] / 73 >= 78)   ?

if (signalStrength[MHz] / 73 >= 78) {
          tft.drawLine(MHz * 2, (110 - (signalStrength[MHz] / 346)), MHz * 2, 110, ILI9341_WHITE);
          tft.setTextColor(ILI9341_GREEN, ILI9341_BLACK);
          tft.setCursor(200, 3);  tft.print("ATT");
        } else {
          tft.drawLine(MHz * 2, (110 - (signalStrength[MHz] / 73)), MHz * 2, 110, ILI9341_WHITE);
          tft.setTextColor(ILI9341_RED, ILI9341_BLACK);
          tft.setCursor(200, 3);  tft.print("ATT");
        }

 

Переписал под больший дисплей ili9341 2.8", надо запоминание сделать, чтобы железка сигнализировала при появлении новых радиоизлучений

 

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

АТТ это стандартный синоним включенного аттенюатора, здесь намётки на его программную реализацию, всё условно, сигнал не калибровался
По дисплею, я сам жду на ILI9341...
В принципе можно многое, особенно если подключить использование известной библиотеки для радио модулей, NRF24 там есть )))

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

russo пишет:

Не могу понять, что такое АТТ? На что идет проверка if (signalStrength[MHz] / 73 >= 78)   ?

if (signalStrength[MHz] / 73 >= 78) {
          tft.drawLine(MHz * 2, (110 - (signalStrength[MHz] / 346)), MHz * 2, 110, ILI9341_WHITE);
          tft.setTextColor(ILI9341_GREEN, ILI9341_BLACK);
          tft.setCursor(200, 3);  tft.print("ATT");
        } else {
          tft.drawLine(MHz * 2, (110 - (signalStrength[MHz] / 73)), MHz * 2, 110, ILI9341_WHITE);
          tft.setTextColor(ILI9341_RED, ILI9341_BLACK);
          tft.setCursor(200, 3);  tft.print("ATT");
        }

 

Переписал под больший дисплей ili9341 2.8", надо запоминание сделать, чтобы железка сигнализировала при появлении новых радиоизлучений

можно конечно и так, но для универсальности думаю надо определения цветов в отдельный файл вынести, тогда в скетче потребуются минимальные правки, чтобы новый дисплей применить,смотрим:
 

// Some ready-made 16-bit ('565') color settings:
#define ST77XX_BLACK 0x0000
#define ST77XX_WHITE 0xFFFF
#define ST77XX_RED 0xF800
#define ST77XX_GREEN 0x07E0
#define ST77XX_BLUE 0x001F
#define ST77XX_CYAN 0x07FF
#define ST77XX_MAGENTA 0xF81F
#define ST77XX_YELLOW 0xFFE0
#define ST77XX_ORANGE 0xFC00

// Color definitions
#define ILI9341_BLACK 0x0000       ///<   0,   0,   0
#define ILI9341_NAVY 0x000F        ///<   0,   0, 123
#define ILI9341_DARKGREEN 0x03E0   ///<   0, 125,   0
#define ILI9341_DARKCYAN 0x03EF    ///<   0, 125, 123
#define ILI9341_MAROON 0x7800      ///< 123,   0,   0
#define ILI9341_PURPLE 0x780F      ///< 123,   0, 123
#define ILI9341_OLIVE 0x7BE0       ///< 123, 125,   0
#define ILI9341_LIGHTGREY 0xC618   ///< 198, 195, 198
#define ILI9341_DARKGREY 0x7BEF    ///< 123, 125, 123
#define ILI9341_BLUE 0x001F        ///<   0,   0, 255
#define ILI9341_GREEN 0x07E0       ///<   0, 255,   0
#define ILI9341_CYAN 0x07FF        ///<   0, 255, 255
#define ILI9341_RED 0xF800         ///< 255,   0,   0
#define ILI9341_MAGENTA 0xF81F     ///< 255,   0, 255
#define ILI9341_YELLOW 0xFFE0      ///< 255, 255,   0
#define ILI9341_WHITE 0xFFFF       ///< 255, 255, 255
#define ILI9341_ORANGE 0xFD20      ///< 255, 165,   0
#define ILI9341_GREENYELLOW 0xAFE5 ///< 173, 255,  41
#define ILI9341_PINK 0xFC18        ///< 255, 130, 198

 

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

Дисплей на контроллере ILI9341 3.2"
Быстренько накидал код для проверки (ESP32 только Soft SPI):

Крайняя самая свежая версия пост #1
 

// 07.10.2022 - Добавлена поддержка дисплея ILI9341
//            - в локальной библиотеке ST77XX расширен набор цветов

#define HARD_SPI

// Размаркировать для дисплея на контроллере ST7735
// #define ST7735

#include <Adafruit_GFX.h>    // Core graphics library
#include <SPI.h>

#ifdef ST7735
#include <Adafruit_ST7735.h> // Hardware-specific library for ST7735
#include <Adafruit_ST7789.h> // Hardware-specific library for ST7789
#else
#include <Adafruit_ILI9341.h> //  Hardware-specific library for ILI9341 240x320

// Some ready-made 16-bit ('565') color settings:
#define ST77XX_BLACK 0x0000       ///<   0,   0,   0
#define ST77XX_NAVY 0x000F        ///<   0,   0, 123
#define ST77XX_DARKGREEN 0x03E0   ///<   0, 125,   0
#define ST77XX_DARKCYAN 0x03EF    ///<   0, 125, 123
#define ST77XX_MAROON 0x7800      ///< 123,   0,   0
#define ST77XX_PURPLE 0x780F      ///< 123,   0, 123
#define ST77XX_OLIVE 0x7BE0       ///< 123, 125,   0
#define ST77XX_LIGHTGREY 0xC618   ///< 198, 195, 198
#define ST77XX_DARKGREY 0x7BEF    ///< 123, 125, 123
#define ST77XX_BLUE 0x001F        ///<   0,   0, 255
#define ST77XX_GREEN 0x07E0       ///<   0, 255,   0
#define ST77XX_CYAN 0x07FF        ///<   0, 255, 255
#define ST77XX_RED 0xF800         ///< 255,   0,   0
#define ST77XX_MAGENTA 0xF81F     ///< 255,   0, 255
#define ST77XX_YELLOW 0xFFE0      ///< 255, 255,   0
#define ST77XX_WHITE 0xFFFF       ///< 255, 255, 255
#define ST77XX_ORANGE 0xFD20      ///< 255, 165,   0
#define ST77XX_GREENYELLOW 0xAFE5 ///< 173, 255,  41
#define ST77XX_PINK 0xFC18        ///< 255, 130, 198
#endif


#if ( defined(ARDUINO_NANO_RP2040_CONNECT) || defined(ARDUINO_RASPBERRY_PI_PICO) || defined(ARDUINO_ADAFRUIT_FEATHER_RP2040) || \
      defined(ARDUINO_GENERIC_RP2040) )

// замаркировать если используем наоборот
#define SPI01             // Дисплей на SPIO1, NRF24L01 на SPI0 (выбор между SPI0 и SPI1)
#if defined(SPI01)        // для RP2040 SPI1
#define TFT_CS        13  // GP13 - CS              (hard - 13)
#define TFT_RST       10  // GP14 - RESET           (10)  
#define TFT_DC        11  // GP15 - A0              (11)  
#define TFT_MISO      12  // GP12 - MISO (MISO, RX) (hard - 12)
#define TFT_MOSI      15  // GP11 - SDA  (MOSI, TX) (hard - 15)
#define TFT_SCLK      14  // GP10 - SCK             (hard - 14)
#else                     // для RP2040 SPI0
#define TFT_CS        17  //5   // GP5 - CS               (hard - 17)
#define TFT_RST       20  //6   // GP6 - RESET
#define TFT_DC        21  //7   // GP7 - A0
#define TFT_MISO      16  //4   // GP4 - MISO (MISO, RX)  (hard - 16)
#define TFT_MOSI      19  //3   // GP3 - SDA  (MOSI, TX)  (hard - 19)
#define TFT_SCLK      18  //2   // GP2 - SCK              (hard - 18)
#endif

// SPI definitions and macros то NRF24L01
#if defined(SPI01)
#define CE_pin    21 //7
#define RST_pin   20 // не используется
#define CS_pin    17 //5
#define MOSI_pin  19 //3
#define MISO_pin  16 //4
#define SCK_pin   18 //2
#else
#define CE_pin    11 //15
#define RST_pin   10 // не используется
#define CS_pin    13
#define MOSI_pin  15 //11
#define MISO_pin  12
#define SCK_pin   14 //10
#endif
#include "api/HardwareSPI.h"

#elif ( defined(ESP32))

#define WIFI             // Используем модуль вайфая
#include "WiFi.h"

// ***   ***   ***           Для ESP32 подключаем SPI так:
#define HSPIs             // Дисплей на HSPI, NRF24L01 на VSPI
#if defined(HSPIs)         // для ESP32 HSPI
#define TFT_CS        15  // GP13 - CS
#define TFT_RST       16  // GP14 - RESET
#define TFT_DC        17  // GP15 - A0
#define TFT_MISO      12  // GP12 - MISO (MISO, RX)
#define TFT_MOSI      13  // GP11 - SDA  (MOSI, TX)
#define TFT_SCLK      14  // GP10 - SCK
#else                     // для ESP32 VSPI
#define TFT_CS        5   // GP5  - CS
#define TFT_RST       20  // GP20 - RESET
#define TFT_DC        21  // GP21 - A0
#define TFT_MISO      19  // GP19 - MISO (MISO, RX)
#define TFT_MOSI      23  // GP23 - SDA  (MOSI, TX)
#define TFT_SCLK      18  // GP18 - SCK
#endif

// SPI definitions and macros то NRF24L01
#if defined(HSPIs) // NRF24L01 на VSPI если монитор на HSPI и наоборот ;-)
#define CE_pin    21
#define CS_pin    5
#define MOSI_pin  23
#define MISO_pin  19
#define SCK_pin   18
#else // HSPIs
#define CE_pin    17
#define CS_pin    15
#define MOSI_pin  13
#define MISO_pin  12
#define SCK_pin   14
#endif


#else
#error This code is intended to run on the RP2040 or ESP32 modules!
#endif

/********************/
#ifdef ST7735
/********************/
  #ifndef WIFI // Если это не ESP32 то
    #ifdef HARD_SPI
      #ifndef SPI01
      // For ST7735-based displays, we will use this call
      Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST); // Only SPI0 ???
      #else
      //hard SPI для RP2040
      Adafruit_ST7735 tft = Adafruit_ST7735(&SPI1, TFT_CS, TFT_DC, TFT_RST); //via hard SPI1
      #endif
    #else
    //Soft SPI для RP2040
    Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST); // Via Soft SPI
    #endif
  #else  //Для ESP32
  // SOFT SPI для ESP32
  Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST); // Via Soft SPI
  #endif
/********************/
#else  // * ILI9341 *
/********************/
  #ifndef WIFI // Если это не ESP32 то
    #ifdef HARD_SPI
      #ifndef SPI01
      // For ILI9341-based displays, we will use this call
      Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST); // Only SPI0 ???
      #else // define SPI01
      //hard SPI01 для RP2040
      Adafruit_ILI9341 tft = Adafruit_ILI9341(&SPI1, TFT_DC, TFT_CS, TFT_RST); //via hard SPI1
      #endif
    #else // Soft SPI
    //Soft SPI для RP2040
    Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST,TFT_MISO); // Via Soft SPI
    #endif
  #else  //Для ESP32 используем только SOFT SPI
  // SOFT SPI для ESP32
  Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST,TFT_MISO); // Via Soft SPI
  #endif
/********************/
#endif
/********************/

// TEST
//Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST,TFT_MISO); 
//Adafruit_ILI9341 tft = Adafruit_ILI9341(&SPI1,  TFT_DC,TFT_CS, TFT_RST);
//Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);

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

uint16_t signalStrength[CHANNELS]; // smooths signal strength with numerical range 0 - 0x7FFF
uint16_t CH[] = {2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 2467, 2472};

#define  CE_on    digitalWrite(CE_pin, HIGH)
#define  CE_off   digitalWrite(CE_pin, LOW)
#define  CS_on    digitalWrite(CS_pin, HIGH)
#define  CS_off   digitalWrite(CS_pin, LOW)
#define  MOSI_on  digitalWrite(MOSI_pin, HIGH)
#define  MOSI_off digitalWrite(MOSI_pin, LOW)
#define  MISO_on  digitalRead(MISO_pin) // input
#define  SCK_on   digitalWrite(SCK_pin, HIGH)
#define  SCK_off  digitalWrite(SCK_pin, LOW)

// 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,
};


// Button and Encoder
#define UsrButton 34
#define Canal 7
bool is_canal = false;
uint32_t old_millis;

#include <GyverButton.h>
GButton btn_01(UsrButton);


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_P         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);
}


// функция перекодировки цвета в формат библиотеки Adafruin_GFX
//
uint16_t setColor(uint8_t red, uint8_t green, uint8_t blue) {

  //uint16_t color = ((red & 0xf8)<<11) + ((green & 0xfc) <<5) + (blue & 0xf8); //uint16_t(r5-g6-b5 bit)
  uint16_t color = ((red & 0x0b11111000) << 11) + ((green & 0b11111100) << 5 ) + (blue & 0b11111000);
  return color;
}

#ifdef WIFI
volatile  int n;
#define Time_WiFiScan 30000

void WiFi_Scan(void) {
  clearDisplay(); // инициализируем вывод на дисплей
  Serial.println("scan start");
  tft.setCursor(20, 40);
  tft.setTextSize(2);
  tft.setTextColor(ST77XX_YELLOW, ST77XX_BLACK);
  tft.print("   SCAN");
  tft.setCursor(20, 70);
  tft.print(" NETWORKS");
  // WiFi.scanNetworks will return the number of networks found
  n = WiFi.scanNetworks();
  tft.fillScreen(ST77XX_BLACK);
  tft.setTextSize(1);
  tft.setTextColor(ST77XX_WHITE, ST77XX_BLACK);

  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));
      String ssid = (WiFi.SSID(i));

      tft.setCursor(3, 20 + (i * 12));
      tft.print(i + 1);
      tft.print(": ");
      tft.print(ssid);

      // выравнивание текста
      int s = ssid.length(); //sizeof(ssid);
      s = 10 - s;
      if (s >= 0) {
        for (int j = 0; j < s; j++) {
          Serial.print(" ");
          tft.print(" ");
        }
      }
      Serial.print(" (");
      tft.print(" (");
      Serial.print(WiFi.RSSI(i));
      tft.print(WiFi.RSSI(i));
      Serial.print(" CH-");
      tft.print(" CH-");
      if (WiFi.channel(i) < 10) {
        Serial.print(" ");
        //tft.print(" ");
      }
      Serial.print(WiFi.channel(i));
      tft.print(WiFi.channel(i));
      Serial.print(" Freq=");
      Serial.print(CH[(WiFi.channel(i)) - 1]);
      Serial.print("MHz");
      //tft.print(CH[(WiFi.channel(i)) - 1]);
      //tft.print("MHz");
      Serial.print(" MAC::");
      Serial.print(WiFi.BSSIDstr(i));
      Serial.print(" ");
      int e = WiFi.encryptionType(i);
      if (e == 0) {
        Serial.print("No Encrypton");
      } else if (e == 1) {
        Serial.print("WEP");
      } else if (e == 2) {
        Serial.print("WPA");
      } else if (e == 3) {
        Serial.print("WPA2/PSK (CCMP)");
      } else if (e == 4) {
        Serial.print("WPA2/PSK (TKIP,CCMP)");
      }
      Serial.println(")");
      tft.println(")");
      delay(10);

    }
  }
  Serial.println("");
  delay(10000);
  tft.fillScreen(ST77XX_BLACK);
  dispHello();
}
#endif


/*********************************** S E T U P ************************************/

void setup() {
  Serial.begin(115200); // debugging without lcd display

#ifdef WIFI
  // WIFI
  WiFi.mode(WIFI_STA);
  WiFi.disconnect();
  delay(100);
#endif

  //TFT
#ifdef WIFI
  pinMode(25, OUTPUT);
  digitalWrite(25, HIGH); // Led DISPLAY is ON
#else
  pinMode(29, OUTPUT);
  digitalWrite(29, HIGH); // Led DISPLAY is ON
#endif
  dispInit();
  
  //pinMode(UsrButton, INPUT_PULLUP);

  // 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(5000); // Заставку отображаем 5 секунд
  tft.fillScreen(ST77XX_BLACK);

  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

  dispHello();

  // выставляем таймер
  old_millis = millis();

} // ******* END SETUP *******



/***************************** L O O P **************************/


uint8_t refresh;

void loop() {
  btn_01.tick(); // проверяем кнопки

#ifdef WIFI
  // Сканируем WiFi раз в 5 секунд
  if (millis() - old_millis >= Time_WiFiScan) {
    WiFi_Scan();
    old_millis = millis();
  }
#endif

  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 (!digitalRead(UsrButton) && millis() - old_millis >= 150){
      old_millis = millis();
    *
    if (btn_01.isClick()) {
      is_canal = !is_canal;
      Serial.print("USR BOTTON is ");
      Serial.println(is_canal);
    }
    */
    // Вывод информации
    if (!is_canal) {
      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

        tft.setTextSize(1);
        tft.drawLine(20 + MHz, 11, 20 + MHz, 110, ST77XX_BLACK);
        if (signalStrength[MHz] / 73 >= 78) {
          tft.drawLine(20 + MHz, (110 - (signalStrength[MHz] / 346)), 20 + MHz, 110, ST77XX_WHITE);
          tft.setTextColor(ST77XX_MAGENTA, ST77XX_BLACK);
          tft.setCursor(136, 3);  tft.print("ATT");
          // tft.setTextColor(ST77XX_MAGENTA, ST77XX_BLACK);
        } else {
          tft.drawLine(20 + MHz, (110 - (signalStrength[MHz] / 73)), 20 + MHz, 110, ST77XX_WHITE);
          tft.setTextColor(0xaa84/*ST77XX_MAGENTA*/, ST77XX_BLACK);
          tft.setCursor(136, 3);  tft.print("ATT");
          //  tft.setTextColor(ST77XX_WHITE, ST77XX_BLACK);
        }
        delay(0);
      }
    } else { // смотрим широкий канал (для пробы 7)
      if (!--refresh) {                             // don't refresh whole display every scan (too slow)
        refresh = 9;
        if (MHz >= 31 && MHz <= 53) {
          int i = 0;
          while (i < 5) {
            tft.drawLine(20 + (MHz - 31) * 5 + i, 11, 0 + (MHz - 31) * 5 + i, 111, ST77XX_BLACK);
            if (signalStrength[MHz] / 173 >= 90) {
              tft.drawLine(20 + (MHz - 31) * 5 + i, (110 - (signalStrength[MHz] / 346)), 20 + (MHz - 31) * 5 + i, 110, ST77XX_WHITE);
              tft.setTextColor(ST77XX_MAGENTA, ST77XX_BLACK);
              tft.setCursor(136, 3);  tft.print("ATT");
              tft.setTextColor(ST77XX_WHITE, ST77XX_BLACK);
            } else {
              tft.drawLine(20 + (MHz - 31) * 5 + i, (110 - (signalStrength[MHz] / 173)), 20 + (MHz - 31) * 5 + i, 110, ST77XX_WHITE);
              tft.setTextColor(ST77XX_WHITE, ST77XX_BLACK);
              tft.setCursor(136, 3);  tft.print("ATT");
              tft.setTextColor(ST77XX_MAGENTA, ST77XX_BLACK);
            }
            i++;
          }
        }
      }
    }
  }
} // ************************** END LOOP ******************************


void dispInit() {
  
#ifdef ST7735
  // Use this initializer if using a 1.8" TFT screen:
  tft.initR(INITR_BLACKTAB);      // Init ST7735S chip, black tab
#else
  // 3.2" ILI9341  
  tft.begin(2000000);
#endif
  
  tft.setRotation(1);
  tft.cp437(true);                // не пропускаем 176 символ
#ifdef WIFI // SPI для ESP32  
  tft.setSPISpeed(20000000);      // отдельные экземпляры дисплеев не работают на такой скорости
#else                             // откорректируйте под конкретный экземпляр
  tft.setSPISpeed(20000000);
#endif
  tft.fillScreen(ST77XX_BLACK);
  tft.setCursor(22, 50);
  tft.setTextColor(ST77XX_YELLOW, ST77XX_BLACK);
  tft.setTextSize(1);
  tft.print("2.4 GHz band scanner");
  tft.setCursor(3, 70);
  tft.setTextSize(1);
  tft.setTextColor(ST77XX_CYAN, ST77XX_BLACK);

#ifdef WIFI
  tft.print("Modified to ESP32 - UA6EM");
#else
  tft.print("Modified to RP2040 - UA6EM");
#endif
}

void dispHello() {
  // отрисовка сетки графикой
  tft.drawLine(0, 112, 169, 112, ST77XX_WHITE);
  tft.drawLine(20, 112, 20, 120, ST77XX_WHITE);
  tft.drawLine(80, 112, 80, 120, ST77XX_WHITE);
  tft.drawLine(140, 112, 140, 120, ST77XX_WHITE);
  for (int x = 0; x < 154; x++) {
    if (!(x % 10)) {
      tft.drawLine(x, 112, x, 116, ST77XX_WHITE);
    }
  }

  // выводим надписи
  tft.setTextColor(0xaa84, ST77XX_BLACK); // тёмно- кирпичный
  tft.setCursor(136, 3);  tft.print("ATT");
  //  tft.setTextColor(ST77XX_WHITE, ST77XX_BLACK);
  tft.setTextColor(setColor(247, 234, 105), ST77XX_BLACK);
  tft.setCursor(13, 120);  tft.print("2.40");
  tft.setCursor(73, 120);  tft.print("2.46");
  tft.setCursor(133, 120);  tft.print("2.52");
  tft.drawLine(0, 2, 0, 118, ST77XX_WHITE);
  tft.setCursor(1, 3);   tft.print("-10");
  tft.setCursor(1, 23);  tft.print("-20");
  tft.setCursor(1, 43);  tft.print("-30");
  tft.setCursor(1, 63);  tft.print("-40");
  tft.setCursor(1, 83);  tft.print("-50");
  tft.setCursor(1, 103); tft.print("-60");

  delay(10); // start up message

  // выводим сетку каналов WiFI 2.4GHz
  tft.drawLine(21, 0, 43, 0, ST77XX_GREEN);   //1
  tft.drawLine(21, 1, 43, 1, ST77XX_GREEN);   //1
  tft.drawLine(26, 3, 48, 3, ST77XX_RED);     //2
  tft.drawLine(26, 4, 48, 4, ST77XX_RED);     //2
  tft.drawLine(31, 5, 53, 5, ST77XX_YELLOW);  //3
  tft.drawLine(31, 6, 53, 6, ST77XX_YELLOW);  //3
  tft.drawLine(36, 7, 58, 7, ST77XX_CYAN);    //4
  tft.drawLine(36, 8, 58, 8, ST77XX_CYAN);    //4
  tft.drawLine(41, 9, 63, 9, ST77XX_BLUE);    //5
  tft.drawLine(41, 10, 63, 10, ST77XX_BLUE);  //5

  tft.drawLine(46, 0, 68, 0, ST77XX_WHITE);   //6
  tft.drawLine(46, 1, 68, 1, ST77XX_WHITE);   //6
  tft.drawLine(51, 3, 73, 3, ST77XX_BLUE);    //7
  tft.drawLine(51, 4, 73, 4, ST77XX_BLUE);    //7
  tft.drawLine(56, 5, 78, 5, ST77XX_RED);     //8
  tft.drawLine(56, 6, 78, 6, ST77XX_RED);     //8
  tft.drawLine(61, 7, 83, 7, ST77XX_MAGENTA); //9
  tft.drawLine(61, 8, 83, 8, ST77XX_MAGENTA); //9
  tft.drawLine(66, 9, 88, 9, ST77XX_CYAN);    //10
  tft.drawLine(66, 10, 88, 10, ST77XX_CYAN);  //10

  tft.drawLine(71, 0, 92, 0, ST77XX_GREEN);   //11
  tft.drawLine(71, 1, 92, 1, ST77XX_GREEN);   //11
  tft.drawLine(76, 3, 98, 3, ST77XX_MAGENTA); //12
  tft.drawLine(76, 4, 98, 4, ST77XX_MAGENTA); //12
  tft.drawLine(81, 5, 103, 5, ST77XX_YELLOW); //13
  tft.drawLine(81, 6, 103, 6, ST77XX_YELLOW); //13
  tft.drawLine(93, 7, 115, 7, ST77XX_RED);    //14
  tft.drawLine(93, 8, 115, 8, ST77XX_RED);    //14
}


void clearDisplay() {
  tft.fillScreen(ST77XX_BLACK);
  tft.setTextColor(ST77XX_WHITE, ST77XX_BLACK);
}

 

marshallab
Offline
Зарегистрирован: 15.02.2019

Привет. Тоже задумал детектор коптеров. К вашему железу можно добавить rx5808 приемник, чтобы сканировать диапазон 5G8. Эти модули используются в дешевых приемниках RG02 там их два и отдельно продаются на али. Модуль выдает композитный видео и аудио, RSSI, частоты настраиваются по SPI или дискретно. 

https://aliexpress.ru/item/763399767.html?spm=a2g2w.orderdetails.0.0.79764aa6hyZygP&sku_id=54234247208&_ga=2.44980196.1532547175.1666633671-692580827.1652964311

Но для начала попробую повторить ваш скетч на m5stack модуле, там вроде ili9341

https://shop.robotclass.ru/item/1496

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

marshallab пишет:

Привет. Тоже задумал детектор коптеров. К вашему железу можно добавить rx5808 приемник, чтобы сканировать диапазон 5G8. Эти модули используются в дешевых приемниках RG02 там их два и отдельно продаются на али. Модуль выдает композитный видео и аудио, RSSI, частоты настраиваются по SPI или дискретно. 

https://aliexpress.ru/item/763399767.html?spm=a2g2w.orderdetails.0.0.79764aa6hyZygP&sku_id=54234247208&_ga=2.44980196.1532547175.1666633671-692580827.1652964311

Но для начала попробую повторить ваш скетч на m5stack модуле, там вроде ili9341

https://shop.robotclass.ru/item/1496

хороший девайс! Какой дисплей без разницы, у меня есть версия под десяток дисплеев и пяток тачскринов )))
Добавить можно, я так понимаю нужен один аналоговый пин для измерения RSSI и три пина для переключения диапазонов

Кстати модуль 5803 получше будет, у него 48 каналов (на самом деле 47) и чувствительность на 5 децибел выше, но пинов для управления потребуется поболее аж 6!

Тему перенёс на новый форум, там один из самых свежих скетчей

 

marshallab
Offline
Зарегистрирован: 15.02.2019

Для 5808 есть возможность выбирать точно частоту через SPI шину вместо грубого шага через CS

https://kt-315.livejournal.com/5376.html 

https://bitbucket.org/atmega128/reciver-module-rx5808/src/67d9a9660b9d3f...

А вот по 5803 информации намного меньше. Но на али они продаются и я закажу одну штучку на поиграться. 

PS. Писать в новый форум или сюда?

 

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

marshallab пишет:

Для 5808 есть возможность выбирать точно частоту через SPI шину вместо грубого шага через CS

https://kt-315.livejournal.com/5376.html 

https://bitbucket.org/atmega128/reciver-module-rx5808/src/67d9a9660b9d3f...

А вот по 5803 информации намного меньше. Но на али они продаются и я закажу одну штучку на поиграться. 

PS. Писать в новый форум или сюда?

я перенёс тему в новый, этот скоро прикроют

russo
Offline
Зарегистрирован: 20.11.2014

Для определения БПЛА проект на nrf24l01 подойдет при загородных  условиях при отсутствии WiFi сетей. В городе много помех на этой частоте и чувствительность модуля оставляет желать лучшего. В общем для БПЛА я его не буду использовать.

Сам взял RX5808, пока разбираюсь с прошивками, модуль пришел без сопротивления, которое надо отпаивать для включения SPI. 

Еще заказал приемник Flysky 2.4G 6CH i-bus PPM, для телеметрии. Ждем. Не знаю какие еще модули заказать. Как передается видео в цифровом виде на 2.4 и 5 ГГЦ? Какие модули для этого нужны. По телеметрии какие еще модули других протоколов можно взять на Али? Понятно, что с этим  Flysky 2.4G 6CH будут трудности, там надо ключ прописывать передатчика и как без ключей мониторить эфир надо будет думать. 

Есть еще 1-1.3 ГГц частоты, потом 868-927 частоты и слышал еще на 433 что-то летает. Нужна инфа по модулям телеметрии и передачи видео для БПЛА 

marshallab
Offline
Зарегистрирован: 15.02.2019

Отвечу пока здесь. 

Летают во всех диапазонах, сейчас моделистов стало намного меньше, чем 10 лет назад. Возможно поэтому используют обычно готовые модули на 2,4 для управления и 5,8 для видео. Управление считается приоритетней и связь должна быть стабильнее, поэтому обычно для пульта выбирали частоту ниже, меньше помех от видео передатчика на борту. 

Цифровое управление DJI использует DSSS для канала. Обычные аппы использовали FHSS. Ключи если они вообще используются, у всех производителей разные.

Полноценный детектор БПЛА - думаю это сложнейшая система с направленными антеннами, работающая на многих диапазонах, декодирующая разные протоколы, перебирающая ключи.... И возможно они строятся на мощных системах с многоканальными SDR и моощными процами. Но можно поигратся с gnuradio и свистком SDR ) 

Этот проект зацепил своей автономностью и простотой.

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

marshallab пишет:

 Но можно поигратся с gnuradio и свистком SDR

 для частот выше 1700MHz что-то не попадались (именно свистки)

marshallab
Offline
Зарегистрирован: 15.02.2019

HackRF до 6 ГГц

это саамый доступный и действительно крутой для такой низкой цены ! Плюс к нему есть допы с того же али, можно портативный чехол купить, но не знаю насколько он практичный. 

Mike-M
Offline
Зарегистрирован: 24.01.2019

Доброго времени суток!

Полностью согласен с тем, что этот проект в первую очередь интересен своей простотой и малой стоимостью. Учитывая специфику подобного устройства - оно должно быть очень простым (наверно достаточно просто видеть наличие радиоизлучения на 2,4 ГГц и возможно отображение занятости условных каналов - это для упрощенного определения "своя-чужая птичка"). Должно быть универсальное питание и компактные размеры. Минимум индикации - "всё спокойно и внимание!" и номера каналов может условный уровень сигнала. И всё, большего пока не надо. 

Более сложные и навороченные устройства тоже нужны, но это уже совсем другой уровень.