Перехват и управление устройством на nRF24L01

толстый
Offline
Зарегистрирован: 10.02.2020

Есть у меня помпа типа https://aliexpress.ru/item/4001211328092.html  "У ней унутре"  - есть китайская копия nRF24L01. Помпа может работать самостоятельно, а так-же быть мастером или слейвом по отношению к другим таким-же устройствам. была мысль сделать внешнее управление с ардуины через nRF24L01, но почитав документацию на протокол с его "свой/чужой", маской и трубами понял, что тут не угадаешь:) Максимум получилось при помощи сканера определить примерный канал.

Но тут недавно промелькнула тема https://arduino.ru/forum/programmirovanie/ugon-kvadrokoptera-syma-ne-ugonyaetsya  и даже что-то получилось. Канал поймался вроде как 40(39 и 41 тоже выдают). Труба выходит типа 02202086699 а дальше пять пар значений в зависимости от настроенного режима.

59	ms: 11727	Ch: 40	Get data: 022020866998a55f90c100000000000000000000000000000000000000000000
60	ms: 11729	Ch: 40	Get data: 022020866998a55f90c100000000000000000000000000000000000000000000
61	ms: 11731	Ch: 40	Get data: 022020866998a55f90c100000000000000000000000000000000000000000000
62	ms: 11734	Ch: 40	Get data: 022020866998a55f90c100000000000000000000000000000000000000000000
63	ms: 11736	Ch: 40	Get data: 022020866998a55f90c100000000000000000000000000000000000000000000
64	ms: 11737	Ch: 40	Get data: 022020866998a55f90c100000000000000000000000000000000000000000000
65	ms: 11739	Ch: 40	Get data: 022020866998a55f90c100000000000000000000000000000000000000000000
66	ms: 11741	Ch: 40	Get data: 022020866998a55f90c100000000000000000000000000000000000000000000
67	ms: 11745	Ch: 40	Get data: 022020866998a55f90c100000000000000000000000000000000000000000000
68	ms: 11747	Ch: 40	Get data: 022020866998a55f90c100000000000000000000000000000000000000000000
69	ms: 11759	Ch: 40	Get data: 02202086699aa55f90c100000000000000000000000000000000000000000000
70	ms: 11763	Ch: 40	Get data: 02202086699aa55f90c100000000000000000000000000000000000000000000
71	ms: 11765	Ch: 40	Get data: 02202086699aa55f90c100000000000000000000000000000000000000000000
72	ms: 11767	Ch: 40	Get data: 02202086699aa55f90c100000000000000000000000000000000000000000000
73	ms: 11769	Ch: 40	Get data: 02202086699aa55f90c100000000000000000000000000000000000000000000
74	ms: 11777	Ch: 40	Get data: 02202086699aa55f90c100000000000000000000000000000000000000000000
75	ms: 11779	Ch: 40	Get data: 02202086699aa55f90c100000000000000000000000000000000000000000000
76	ms: 11791	Ch: 40	Get data: 02202086699ca55f90c100000000000000000000000000000000000000000000
77	ms: 11793	Ch: 40	Get data: 02202086699ca55f90c100000000000000000000000000000000000000000000
78	ms: 11795	Ch: 40	Get data: 02202086699ca55f90c100000000000000000000000000000000000000000000
79	ms: 11797	Ch: 40	Get data: 02202086699ca55f90c100000000000000000000000000000000000000000000
80	ms: 11801	Ch: 40	Get data: 02202086699ca55f90c100000000000000000000000000000000000000000000
81	ms: 11803	Ch: 40	Get data: 02202086699ca55f90c100000000000000000000000000000000000000000000
82	ms: 11804	Ch: 40	Get data: 02202086699ca55f90c100000000000000000000000000000000000000000000
83	ms: 11808	Ch: 40	Get data: 02202086699ca55f90c100000000000000000000000000000000000000000000
84	ms: 11810	Ch: 40	Get data: 02202086699ca55f90c100000000000000000000000000000000000000000000

Поправил скетч сканера для лучшего восприятия

//Сканер (приемник)
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <printf.h>

#define CE_PIN  9 //53   /// Change it for your board
#define CSN_PIN 10 //48  /// Change it for your board

RF24 radio(CE_PIN, CSN_PIN);

const char tohex[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
//uint64_t pipe = 0x00AA;
uint64_t pipe = 0x02202086699LL;

//uint64_t pipe = 0xa20009890fLL; //Адрес ардуино пульта (передатчика)

byte buff[32];
byte chan = 40; //Канал для Ардуино пульта
byte len = 32;
byte addr_len = 9;
bool output = true;  // остановка сериал

void set_nrf() {
  radio.setDataRate(RF24_250KBPS);  //(250KBPS, 1MBPS, 2MBPS)
  radio.setAutoAck(false);  // -------
  radio.setCRCLength(RF24_CRC_DISABLED);
//  radio.setCRCLength(RF24_CRC_16);
  radio.setAddressWidth(addr_len);
  radio.setPayloadSize(len);
  radio.setChannel(chan);
  radio.openReadingPipe(1, pipe);
  radio.startListening();
}

void setup() {
  Serial.begin(2000000);
  printf_begin();
  radio.begin();
  set_nrf();
}

long t1 = 0;
long t2 = 0;
long tr = 0;

void loop() {
  byte in;
  if (Serial.available() > 0) {
    in = Serial.read();
    if (in == 'w') {
      chan += 1;
      radio.setChannel(chan);
      Serial.print("\nSet chan: ");
      Serial.print(chan);
    }
    if (in == 's') {
      chan -= 1;
      radio.setChannel(chan);
      Serial.print("\nSet chan: ");
      Serial.print(chan);
    }
    if (in == 'q') {
      Serial.print("\n");
      radio.printDetails();
      output = false;
    }
        if (in == 'p') {
  output = !output;
    }
  }
  while (radio.available()) {
    
      t2 = t1;
      t1 = micros();
      tr += 1;
      radio.read(&buff, sizeof(buff) );
      if (output) {
      Serial.print("\n");
      Serial.print(tr);
      Serial.print("\tms: ");
      Serial.print(millis());
      Serial.print("\tCh: ");
      Serial.print(chan);
      Serial.print("\tGet data: ");
      for (byte i = 0; i < len; i++ ) {
        Serial.print(tohex[(byte)buff[i] >> 4]);
        Serial.print(tohex[(byte)buff[i] & 0x0f]);
      }
    }
  }
}

На выходе получаем более читабельное

1	ms: 8350	Ch: 40	Get data: ca55f90c10000000000000000000000000000000000000000000000000000000
2	ms: 8352	Ch: 40	Get data: ca55f90c10000000000000000000000000000000000000000000000000000000
3	ms: 8354	Ch: 40	Get data: ca55f90c10000000000000000000000000000000000000000000000000000000
4	ms: 8356	Ch: 40	Get data: ca55f90c10000000000000000000000000000000000000000000000000000000
5	ms: 8357	Ch: 40	Get data: ca55f90c10000000000000000000000000000000000000000000000000000000
6	ms: 8359	Ch: 40	Get data: ca55f90c10000000000000000000000000000000000000000000000000000000
7	ms: 8361	Ch: 40	Get data: ca55f90c10000000000000000000000000000000000000000000000000000000
8	ms: 8364	Ch: 40	Get data: ca55f90c10000000000000000000000000000000000000000000000000000000
9	ms: 8366	Ch: 40	Get data: ca55f90c10000000000000000000000000000000000000000000000000000000
10	ms: 8368	Ch: 40	Get data: ca55f90c1000000000000000000000000000000000000000000
11	ms: 8370	Ch: 40	Get data: ca55f90c10000000000000000000000000000000000000000000000000000000
12	ms: 8382	Ch: 40	Get data: ea55f90c10000000000000000000000000000000000000000000000000000000
13	ms: 8384	Ch: 40	Get data: ea55f90c1000000000000000000000000000000000000000000000000000000
14	ms: 8386	Ch: 40	Get data: ea55f90c10000000000000000000000000000000000000000000000000000000
15	ms: 8388	Ch: 40	Get data: ea55f90c10000000000000000000000000000000000000000000000000000000
16	ms: 8390	Ch: 40	Get data: ea55f90c10000000000000000000000000000000000000000000000000000000
17	ms: 8391	Ch: 40	Get data: ea55f90c10000000000000000000000000000000000000000000000000000000
18	ms: 8393	Ch: 40	Get data: ea55f90c10000000000000000000000000
19	ms: 8395	Ch: 40	Get data: ea55f90c10000000000000000000000000000000000000000000000000000000
20	ms: 8397	Ch: 40	Get data: ea55f90c10000000000000000000000000000000000000000000000000000000
21	ms: 8399	Ch: 40	Get data: ea55f90c10000000000000000000000000000000000000000000000000000000
22	ms: 8401	Ch: 40	Get data: ea55f90c10000000000000000000000000000000000000000000000000000000
23	ms: 8414	Ch: 40	Get data: 8a55f90c10000000000000000000000000000000000000000000000000000000
24	ms: 8416	Ch: 40	Get data: 8a55f90c10000000000000000000000000000000000000000000000000000000
25	ms: 8418	Ch: 40	Get data: 8a55f90c10000000000000000000000000000000000000000000000000000000
26	ms: 8420	Ch: 40	Get data: 8a55f90c10000000000000000000000000000000000000000000000000000000

Протестил на всех режимах и заметил что, что со второго по пятый байт меняется в зависимости от настроек, а вот первый всегда во всех режимах меняется каждые 30 мс. по кругу - 8a-aa-ca-ea. Решил, чем кто-то не шутит и в лоб переделал скетч передатчика 

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <stdio.h>

#define CE_PIN  9 //UNO. Для MEGA: 48
#define CSN_PIN 10 //UNO. Для MEGA:  53

//// syma

const char tohex[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
uint64_t pipe = 0x02202086699LL;

RF24 radio(CE_PIN, CSN_PIN);
int8_t packet[5];
uint32_t previousMillis = 0;
int16_t i = 138;  // изменяемое значение в посылке

//// initial
void setup() {

  //set nrf
  radio.begin();
  radio.setDataRate(RF24_250KBPS);
  radio.setCRCLength(RF24_CRC_DISABLED);
  radio.setPALevel(RF24_PA_MAX);
  radio.setAutoAck(false);
  radio.setRetries(0, 0);
  radio.setAddressWidth(5);
  radio.openWritingPipe(pipe);
  radio.setPayloadSize(50);
  radio.setChannel(40);

  //init default data
  packet[0] = i;
  packet[1] = 0x55;
  packet[2] = 0xf9;
  packet[3] = 0x9c;
  packet[4] = 0x50;


}



//// main loop
void loop() {

  uint32_t currentMillis = millis();
  if (currentMillis - previousMillis > 15) {
    previousMillis = currentMillis;
    i = i + 32;
    if (i > 234)i = 138;
  }

  packet[0] = i;
  radio.write( packet, sizeof(packet) );

}

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

Вопрос собственно в следующем: какой тайный смысл в постоянно меняющемся первом байте и вообще реально ли разобрать и повторить протокол?

толстый
Offline
Зарегистрирован: 10.02.2020
vrd
Offline
Зарегистрирован: 20.01.2022

Начну с простого. Передавать и принимать сигналы этот модуль должен на разных каналах. Ибо слейв не должен перебивать мастер.

Ищите вручную. И помните - более шести клиентов эти модули не понимают.

толстый
Offline
Зарегистрирован: 10.02.2020

Устройство работает либо как самостоятельная единица со своими уставками, либо мастером с передачей настроек, либо слейвом. Четвёртого состояния нет. Одновременности вроде нет. Нескольких мастеров в системе не допускается. Выходит, что если мастер работает на, условно, 40-м канале, то слейв обязан быть таким-же. Или имеется ввиду первоначальный коннект? Ну, тогда вообще шансов нет управлять при помощи стороннего устройства.

Тут скорее всего неправильная организация передачи в скетче. Ну, или неправильно понят протокол:)