Перехват и управление устройством на 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-м канале, то слейв обязан быть таким-же. Или имеется ввиду первоначальный коннект? Ну, тогда вообще шансов нет управлять при помощи стороннего устройства.
Тут скорее всего неправильная организация передачи в скетче. Ну, или неправильно понят протокол:)