вторник, 25 марта 2014 г.

Телеметрия и конфигурирование MultiWii посредством XBee (XBP24BZ7)

Опробованный мною вариант использования модулей XBee в качестве средства обмена данными между коптером и MultiWiiWinGUI еще не прошел полноценные испытания.
Однако, это может оказаться кому то полезным.

Шаг первый.
Добавляем строку в Config.h


  /******                Serial com speed    *********************************/
  /* This is the speed of the serial interfaces */
  #define SERIAL0_COM_SPEED 115200
  #define SERIAL1_COM_SPEED 115200
  #define SERIAL2_COM_SPEED 115200
  #define SERIAL3_COM_SPEED 115200
  #define ZigbeePort        3


Шаг второй.
Изменяем строку в Protocol.cpp

//static uint8_t CURRENTPORT=0;
static uint8_t CURRENTPORT=ZigbeePort;


Шаг третий.
Добавляем строки в MultiWii.cpp. Это инициализация режима "Байпас" при запуске приложения. Если модуль XBee не программируемый - этот шаг можно пропустить.

 #endif
  plog.armed_time = 0;   // lifetime in seconds
  //plog.running = 0;       // toggle on arm & disarm to monitor for clean shutdown vs. powercut
#endif

  debugmsg_append_str("initialization completed\n");

   #if defined(ZigbeePort) && defined(MEGA)
      SerialOpen(ZigbeePort,SERIAL3_COM_SPEED);
      delay(200);
      SerialWrite(ZigbeePort,'B');
      SerialWrite(ZigbeePort,13);
      SerialWrite(ZigbeePort,'B');
      SerialWrite(ZigbeePort,13);
      SerialWrite(ZigbeePort,'O');
      SerialWrite(ZigbeePort,'k');
      SerialWrite(ZigbeePort,'!');
    #endif
}

Шаг четвертый.
  • Подсоедините Координатора к компьютеру, запустите любой терминал, соединитесь с модулем, переведите его в режим "Байпас" (литера 'B' и Enter). Отключите терминал.
  • Подсоедините Роутера к Srial 3 Arduino как это показано на фото. Подайте питание на Arduino.



Настройка закончена.
Запустите WinGui  и подключитесь к Координатору.



!!! Длительный тест показал неудовлетворительный результат соединения на скоростях 115200. Рекомендую использовать 9600.

XBee XBP24BZ7 WITB003 DIGI

В целом настройка XBee модуля не составляет особого труда, но стоит обратить внимание на несколько обстоятельств.

Шаг первый. 
  • Запустите дважды программу H-CTU. 
  • В каждом окне выберите по модулю, установите скорость обмена и перейдите во вкладку терминала.



Шаг второй.
Если у Вас программируемый модуль (например, как у меня), следует включить режим "Байпас". Для этого введите литеру 'B' и нажмите Enter. Это нужно сделать в окне каждого модуля. Далее перейдите во вкладку настройки конфигурации.

Шаг третий.
  • Поставите галочку в поле "Always Update...".
  • Установите в обоих окнах одинаковый PAN ID. Это объединит их в одну сеть.
  • Значения полей SH и SL роутера запишите в соответствующие поля DH и DL координатора*.
*Последний пункт важен для обеспечения высокой скорости обмена данными.

Сохраните настройки.



Ваше оборудование готово к работе.
Об организации взаимодействия с MultiWii расскажу в следующем сообщении.

!!! Длительный тест показал неудовлетворительный результат соединения на скоростях 115200. Рекомендую использовать 9600.

пятница, 14 марта 2014 г.

Использование лазерного дальномера UT380B

Не дает покоя мысль об оснащении коптера системой автономного полета.
Одна из подзадач - это взлет/посадка.
Перепробовал различные ультразвуковые датчики, но ни один из опробованных (и SRF02, и SR04) не дали удовлетворительного результата. Работают они уверенно только в случае ровной поверхности, расположенной практически перпендикулярно биссектрисе излучателя. Совсем со счетов их не сбрасываю, но только в случае использования в группе для контроля периметра.

Поиск альтернатив в интернете привел сюда:
Все бы ничего, но попытка повторить эксперимент дала неутешительный результат. В самом лучшем случае удалось получить лишь одно измерение в секунду.

Проблема в поиске команды непрерывного сканирования.

Но логика и эксперименты дали результат.
Вот видео:

Заказал и жду твердотельные реле для подачи команды на включение датчика взамен кнопок и буду
экспериментировать. Надеюсь обойтись одним датчиком. Для этого собираюсь установить зеркало на сервоприводе дабы при посадке видеть землю, а в полете контролировать фронт.



P.S. Посмотрел на приведенную выше ссылку  -  глухо. Видимо автор решил удалить записи. А жаль.... Неплохая было темка.
Тогда выкладываю то, что накопилось у меня.
Вот фото соединения лазерного дальномера с Arduino MEDA 2560:

Вот скетч, для желающих поэкспериментировать:
Подключаем дальномер на Serial1.
Будьте внимательны - дальномер питается от 3v!!!!

/*===========================================================================
http://youtu.be/qUgFji4Figw
3v!!!!!!!
*/

boolean recdata = true;
boolean data;
int buf[64];
int rc=0;


void setup()
{
    Serial.begin(115200);
    Serial1.begin(115200);
    //Serial.println("Start...");
}

void loop()
{
  static unsigned long t = 0;
  if (millis() > (t + 2000)){ // Таймер запуска при отсутствии данных от датчика
    Serial1.write("*00084553#");
    t = millis();
  }
  getdist();
  if (recdata) t = millis(); // сброс таймера при получении данных от датчика
}


int getdist(){
  int litera;
  
  if (Serial1.available() > 0){
    while (Serial1.available() > 0){
      litera = Serial1.read();
      if (litera == 42) { //Если принят знак "*"
        data = true;      //то устанавливаем признак начала пакета
      }

      if (litera == 35) { //Если принят знак "#"
        data = false;     //то устанавливаем признак окончания пакета...
        recdata = true;   //и устанавливаем признак получения данных для управления (сбросом) таймера и дальнейшей обработки пакета
      }
      if(data==true && rc<40 && litera>47){ //Если есть признак начала пакета, длина пакета в разумных пределах и litera имеет цифровое значение по ASCII, то...
        litera = litera-48;// Преобразуем ASCII в цифру...
        buf[rc] = litera;  // и добавляем ее в массив.
        rc++;
      }
    }
  }else{
    if (recdata == true){
      boolean dig=true;   //Эта переменная будет работать для разделения пакета на разряды по 2 цифры
      int countdata=0;    //Эта переменная будет считать разряды
      int data=0;         //Эта переменная будет принимать значения разрядов
      int sum=0;          //Это сумма всех разрядов за исключения последнего
      int src=0;          //Это значение последнего разряда (10), в котором прописана контрольная сумма
      int countLaser=0;   //Это значение внутреннего счетчика в 5-м разряде
      int dist=0;         //Это дистанция, которую мы подсчитаем
      for(int p = 0; p<rc; p++){
        if(dig){
          data = buf[p]*10;//Здесь мы первый знак каждого нового разряда умножаем на 10....
          countdata++;
        }else{
          data += buf[p]; //... а здесь к нему прибавляем второе значение.
          if(countdata<10)sum+=data;//здесь подсчитваем контрольную сумму
          if(countdata==5)countLaser=data;//здесь информация о счетчике
          if(countdata==7)dist=data*10000;//здесь считаем дистанцияю---------|
          if(countdata==8)dist+=data*100;//                                  |
          if(countdata==9)dist+=data;//--------------------------------------|
          if(countdata==10)src=data;//здесь извлекаем контрольную сумму из пакета
          Serial.print(data);
          Serial.print(" ");
          data=0;
        }
        buf[p]='\0';
        dig=!dig;
      }
    
      if(sum >= 100) {//Если контрольная сумма больше 99, то отсекаем лишнее, оставляя только последние два знака
        int a=sum;
        sum=sum/100;
        sum=sum*100;
        sum =a-sum;
      }
      if(sum==src){//Если сумма разрядов (за исключением последнего) равна контрольной сумме (последний разряд) то...
//        Serial.print(" ");
//        Serial.print(sum);
//        Serial.print(" ");
//        Serial.print(src);
        Serial.print("\t");
        Serial.print(countLaser); //Выводим данные внутреннего счетчика
        Serial.print("\t");
        Serial.print(dist);//Выводим дистанцию и...
        if(countLaser==99){//если счетчик достиг предельного значения, то...
         Serial1.write("*00084553#"); //даем команду на начало нового цикла
        }
      }
      src = 0;
      countdata = 0;
      countLaser = 0;
      rc=0;
      recdata = false;
      Serial.println();
    }
  }
}
//==========================================================================







Turnigy 9x и AUX3

Сегодня решил еще одну небольшую задачу:
Как назначить действия на AUX3 Turnigy 9x.
1. Menu -> Setttings ->AUX-CH
     CH5.    GEAR
     CH6.    THRO HOLD
     CH7.    NULL
     CH8.    PIT TRIM
     CH9.    NULL
2. PROG.MIX
     MIX 1=============================================================
     STATE.     ACT.      Активация MIX1
     MASTER. FLP.       Канал-Донор
     SLAVE.     AUX.     Наш новый канал
     OFFSET.    000
     UPRATE.   -100.      Когда донор в состоянии ВКЛ задать новому каналу значение -100
     DNRATE.  100.        Когда донор в состояний ВЫКЛ задать новому каналу значение 100
     SW.             NOR.     Это будет соответствовать положению тумблера AUX3 N (normal)

     MIX 2=============================================================
     STATE.     ACT.      Активация MIX2
     MASTER. FLP.       Канал-Донор
     SLAVE.     AUX.     Наш новый канал
     OFFSET.    000
     UPRATE.   000.      Когда донор в состоянии ВКЛ задать новому каналу значение 000
     DNRATE.  000.      Когда донор в состояний ВЫКЛ задать новому каналу значение 000
     SW.            ID1.     Это будет соответствовать положению тумблера AUX3 1

     MIX 3=============================================================
     STATE.     ACT.      Активация MIX3
     MASTER. FLP.       Канал-Донор
     SLAVE.     AUX.     Наш новый канал
     OFFSET.    000
     UPRATE.   100.      Когда донор в состоянии ВКЛ задать новому каналу значение 100
     DNRATE.  -100.        Когда донор в состояний ВЫКЛ задать новому каналу значение -100
     SW.             NOR.     Это будет соответствовать положению тумблера AUX3 2

Как мы видим - принцип настройки не сложен.
Особенность в том, что при такой настройке AUX3 работает независимо от других каналов.