Перехват и управление устройством на nRF24L01
- Войдите на сайт для отправки комментариев
Есть у меня помпа типа 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) );
}
Типа передаётся остановка помпы на кормление. Визуально сканер ловит те же самые посылки, что и от помпы в режиме мастер, но, если перевести помпу в слейв, то реакции никакой нет(ожидаемо, но хотелось верить:) Понимаю что режим работы передатчика неправильный, но...
Вопрос собственно в следующем: какой тайный смысл в постоянно меняющемся первом байте и вообще реально ли разобрать и повторить протокол?
Помпа - https://aliexpress.ru/item/4001211328092.html?sku_id=10000015316192372
Тема про угон - https://arduino.ru/forum/programmirovanie/ugon-kvadrokoptera-syma-ne-ugonyaetsya#comment-661145
Начну с простого. Передавать и принимать сигналы этот модуль должен на разных каналах. Ибо слейв не должен перебивать мастер.
Ищите вручную. И помните - более шести клиентов эти модули не понимают.
Устройство работает либо как самостоятельная единица со своими уставками, либо мастером с передачей настроек, либо слейвом. Четвёртого состояния нет. Одновременности вроде нет. Нескольких мастеров в системе не допускается. Выходит, что если мастер работает на, условно, 40-м канале, то слейв обязан быть таким-же. Или имеется ввиду первоначальный коннект? Ну, тогда вообще шансов нет управлять при помощи стороннего устройства.
Тут скорее всего неправильная организация передачи в скетче. Ну, или неправильно понят протокол:)