Угон квадрокоптера Syma. Не угоняется!

TukTuk
Offline
Зарегистрирован: 21.07.2022
Добрый день. 
Есть интересная статья про угон квадрокоптера Syma с помощью Ардуино и nRF24L01+. 

PHD VI: как у нас угнали дрона.

В статье описано 2-а этапа. 1) Найти сигнал пульта квадрокоптера, определить адрес для связи пульт - квадрокоптер, определить протокол управления.
2) Управлять квадрокоптером Ардуиной
 
Есть такой же квадрокоптер как и в статье. Пытаюсь повторить опыт авторов. Не получается!
Иду другим путем. На две Ардуины с nRF закачиваю программы из статьи. На одну - для управления (передатчик), а на другую  - для  сканирования (приемник).
Планирую увидеть адрес передатчика (0xa20009890f). Но нет! Вижу непонятные данные.
 
Вероятно в программе сканера есть ошибки.
Помогите, пожалуйста, их найти!
 
Сканер (приемник)
//Сканер (приемник)
#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 = 0xa20009890fLL; //Адрес ардуино пульта (передатчика)

byte buff[32];
byte chan=25; //Канал для Ардуино пульта
byte len = 32;
byte addr_len = 2;

void set_nrf(){
  radio.setDataRate(RF24_250KBPS);
  radio.setCRCLength(RF24_CRC_DISABLED);
  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();
     }  
   }
  while (radio.available()) {                      
    t2 = t1;
    t1 = micros();
    tr+=1;
    radio.read(&buff, sizeof(buff) );
    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]);      
    }    
  }
}
Пульт управления (передатчик)
 

#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
uint8_t chan[4] = {25,41,57,73}; 
const char tohex[] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
uint64_t pipe = 0xa20009890fLL; 

RF24 radio(CE_PIN, CSN_PIN); 
int8_t packet[10];
int joy_raw[7];
byte ch=0;

//// controls
uint8_t throttle = 0;
int8_t rudder = 0;
int8_t elevator = 0;
int8_t aileron = 0;

//// syma checksum
uint8_t checksum(){
    uint8_t sum = packet[0];
    for (int i=1; i < 9; i++) sum ^= packet[i];
    return (sum + 0x55);
}

//// initial
void setup() {
  //set nrf
  radio.begin();
  radio.setDataRate(RF24_250KBPS);
  radio.setCRCLength(RF24_CRC_16);
  radio.setPALevel(RF24_PA_MAX);
  radio.setAutoAck(false);
  radio.setRetries(0,0);
  radio.setAddressWidth(5);
  radio.openWritingPipe(pipe);
  radio.setPayloadSize(10);
  radio.setChannel(25);
  //set joystick
  pinMode(A0, INPUT);
  pinMode(A1, INPUT);
  pinMode(A2, INPUT);
  pinMode(A3, INPUT);
  pinMode(A4, INPUT);
  pinMode(A5, INPUT);
  pinMode(A6, INPUT);
  digitalWrite(A3, HIGH);
  digitalWrite(A4, HIGH);
  digitalWrite(A5, HIGH);
  digitalWrite(A6, HIGH);
  //init default data
  packet[0] = 0x00;
  packet[1] = 0x00;
  packet[2] = 0x00;
  packet[3] = 0x00;
  packet[4] = 0x00;
  packet[5] = 0x40;
  packet[6] = 0x00;
  packet[7] = 0x21;
  packet[8] = 0x00;
  packet[9] = checksum();
}

void read_logitech() {
  joy_raw[0] = analogRead(A0);
  joy_raw[1] = analogRead(A1);
  joy_raw[2] = analogRead(A2);
  joy_raw[3] = !digitalRead(A3);
  joy_raw[4] = !digitalRead(A4);
  joy_raw[5] = !digitalRead(A6);
  joy_raw[6] = !digitalRead(A5);
  //little calibration
  joy_raw[0] = map(joy_raw[0],150, 840, 255, 0)+10;
  joy_raw[0] = constrain(joy_raw[0], 0, 254);
  joy_raw[1] = map(joy_raw[1],140, 830, 0, 255);
  joy_raw[1] = constrain(joy_raw[1], 0, 254);
  joy_raw[2] = map(joy_raw[2],130, 720, 255, 0);
  joy_raw[2] = constrain(joy_raw[2], 0, 254);
}

//// main loop
void loop() {
  read_logitech();
  throttle = joy_raw[2];
  rudder = 64*joy_raw[4] - 64*joy_raw[5];
  elevator = joy_raw[1]-127;
  aileron = joy_raw[0]-127;
  radio.openWritingPipe(pipe);
  ch +=1;
  if (ch>3) ch = 0; 
  radio.setChannel(chan[ch]);      
  packet[0] = throttle;
  if (elevator < 0) packet[1] = abs(elevator) | 0x80; else packet[1] = elevator;
  if (rudder < 0) packet[2] = abs(rudder) | 0x80; else packet[2] = rudder;
  if (aileron < 0) packet[3] = abs(aileron) | 0x80; else packet[3] = aileron;
  packet[4] = 0x00;
  packet[5] = 0x40;
  packet[6] = 0x00;
  packet[7] = 0x21;
  packet[8] = 0x00;
  packet[9] = checksum();
  radio.write( packet, sizeof(packet) );
}
Принятые данные
2: 14262: 25: 0013121f9f9e00d60080004200bfecf6ebd953daabf4ea9d5de757e9577ead5e
3: 15059: 25: 00008401f3df157ddea6aba58d66ffef7abdabe7a7e9539574a4544317622b45
4: 28931: 25: 0013121f616e00ae00800042010d59badfbae5ed5eb599fae5aa9754b2d36ae5

Вместо:

2: 32342: 25: a20009890f0000000000400024823746837468273468237468734683746

 

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

а зачем?

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

ua6em пишет:

а зачем?

Военная тайна.

TukTuk
Offline
Зарегистрирован: 21.07.2022

ua6em пишет:

а зачем?

Нужно взять под управление собственную машинку! 2.4G

Квадрокоптер - проходной этап. Но и он пока не проходится!

Результат похож на этот:

https://www.youtube.com/watch?v=p83ooaU7QZw

TukTuk
Offline
Зарегистрирован: 21.07.2022

С помощью https://mmelchior.wordpress.com/2016/06/06/qc-360-a1-p1/ и https://github.com/m-melchior/QC-360-A1/blob/master/src/Arduino/myRF24PromiscuousReceiver/myRF24PromiscuousReceiver.ino получилось найти 1 проблему:

Вместо:
uint64_t pipe = 0x00AA;

Нужно написать: 

uint64_t pipe = 0x55;

Тогда результат такой:

0009890f007f00df004000210016970a6abad5cd4a9dd29adacebb5a5eff565b

Очень похоже на нужный адрес:

0xa20009890f

Но первых - "a2" почему то не видно!

 

-NMi-
Offline
Зарегистрирован: 20.08.2018

ТС - расшифруй протокол управления промышленными подъёмными механизмами, ну кран или люлька, например... Я те этот квадрик подарю!

ЗЫ: ачО? SDR-м можно QPSK модуляцию с криптой принимать??? Мошт кто научит??? В Мск, пульт дам. Есть "добровольцы" ??? АсЪ???

TukTuk
Offline
Зарегистрирован: 21.07.2022

Оказалось все намного проще!
Нужно отключить проверку CRC в коде сканера!
Этой строчки не достаточно.

radio.setCRCLength(RF24_CRC_DISABLED);

Нужно перед ней добавить

radio.setAutoAck(false);

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

BOOM пишет:

ua6em пишет:

а зачем?

Военная тайна.

Когда хочется иметь универсальную аппаратуру радиоуправления можно использовать Таранис под опентэикс  установивив соответствующий модуль передатчика, сдаётся мне что Syma тоже поддерживается

TukTuk
Offline
Зарегистрирован: 21.07.2022

<span style="font-weight:700;">BOOM</span> пишет:

Когда хочется иметь универсальную аппаратуру радиоуправления можно использовать Таранис под опентэикс  установивив соответствующий модуль передатчика, сдаётся мне что Syma тоже поддерживается

Благодарю. Конечная цель машинка ХАЙ НА (Hui na).

Там протокол какой то странный. Наврядли он поддерживается.

-NMi-
Offline
Зарегистрирован: 20.08.2018

Hui na гламурное название)))