воскресенье, 18 августа 2013 г.

Управление гусеничным роботом с пульта ДУ от чего-то там (IR Rider)

Не то, что бы я решил изобрести велосипед и показать как это клёво, примеров ездящих шасси управляемых пультом от телевизора в и-нете дофигась. Просто вырвался наконец-то на берег и купил желанных четыре пальчиковых аккумулятора для шасси. И в честь этого в ближайший свободный вечер было собрано из стандартных Blockduino'вских средств такое чудо. Конечно же без использования паяльника.
Итак в него входят:
Пульт можно использовать практически любой из тех что под рукой, у меня оказался такой:
ИК пульт от ДВД плеера
Удобное расположение кнопок для управления траком
А далее все просто:


  • Берем BlockMotor и втыкаем в BlockDuino, в винтовой зажим подключаем проводки от моторчиков, один моторчик к [M1+, M1-], второй в [M2+, M2-]. Где тут плюс, а где минус сразу разобраться будет не легко, просто когда шасси по команде вперед поедет не туда, из-за крутящейся гусеницы не в ту сторону, проводки от того моторчика надо будет поменять местами.
  • Затем в BlockDuino подключаем PlugDIO и в него втыкаем провода, в порта D10, D11 и D12. Не забываем про стандарт [G V S] - Groud Volt Signal, т.е. если по русски, то - Земля Напряжение Сигнал. Сигнал (зеленый проводок) смотрит в сторону платы BlockDuino. 
  • К проводам подключаем платки CleClo: в порта D10 и D11 по светодиоду CleClo:LED, а в порт D12 инфракрасный приемник CleClo:IR.
  • Далее загружаем библиотеку IRremote и загружаем в микроконтроллер такой код:
#include <IRremote.h>
int RECV_PIN = 12;
IRrecv irrecv(RECV_PIN);
decode_results results;
void setup(){
  Serial.begin(9600);
  irrecv.enableIRIn();
}
void loop() {
  if (irrecv.decode(&results)) {
    Serial.print("  0x");
    Serial.println(results.value, HEX);
    delay(100);
    irrecv.resume();
  }
}
И нажимая интересные нам кнопки смотрим в мониторе серийного порта какой код им соответствует. В моем случае это следующие коды:
0x1CE358A7 - Стоп / Stop
0x1CE330CF - Вперед / Forward
0x1CE3C837 - Вперед и вправо / FRight
0x1CE3708F - Вперед и влево / FLeft
0x1CE36897 - Раворот по часовой / Clocwise
0x1CE3E817 - Разворот против часовой / Contrclockwise
0x1CE3B04F - Назад / Back
0x1CE3F00F - Назад и вправо / BRight
0x1CE38877 - Назад и влево / BLeft
А так как для каждой кнопки последний байт кода не повторяется, то одним байтом я и решил ограничиться:
0xA7 - Стоп / Stop
0xCF - Вперед / Forward
0x37 - Вперед и вправо / FRight
0x8F - Вперед и влево / FLeft
0x97 - Раворот по часовой / Clocwise
0x17 - Разворот против часовой / Contrclockwise
0x4F - Назад / Back
0x0F - Назад и вправо / BRight
0x77 - Назад и влево / BLeft
  • Далее нужные коды прописуем в нужные места в скетче:

Код под спойлером:

#include <IRremote.h>
#include <BDMotor.h>  //для BlockDuino и BlockMotor
//#include <AFMotor.h>  //для Arduino/Freeduino и MotorShield

//Received NEC Value:0x1CE358A7 - Stop
//Received NEC Value:0x1CE330CF - Forward
//Received NEC Value:0x1CE3C837 - FRight
//Received NEC Value:0x1CE3708F - FLeft
//Received NEC Value:0x1CE36897 - Clocwise
//Received NEC Value:0x1CE3E817 - Contrclockwise
//Received NEC Value:0x1CE3B04F - Back
//Received NEC Value:0x1CE3F00F - BRight
//Received NEC Value:0x1CE38877 - BLeft

#define M_FORWARD BACKWARD
#define M_BACKWARD FORWARD
#define HI_MOVE 255
#define LOW_MOVE 64
AF_DCMotor mL(1);  // #1 моторчик левый  | Left  motor
AF_DCMotor mR(2);  // #2 моторчик правый | Right motor

int RECV_PIN = 12;
IRrecv irrecv(RECV_PIN);
decode_results results;

void setup() {
//  Serial.begin(9600);
  irrecv.enableIRIn(); // Запускаем ИК приемник
  
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
  
}

void loop() {

    if (irrecv.decode(&results)) {
//      Serial.println(results.value, HEX);
      go(results.value);
      delay(100);  
      irrecv.resume(); // Считываем код с ИК приемника
    }
    delay(100);
}

//
// Подпрограмма управления двигателями
//
void go(unsigned char direction){

//  Serial.println(direction, HEX);
  switch (direction) {
    
  case 0xA7://Код кнопки СТОП 
      mL.run(RELEASE);
      mR.run(RELEASE);
      digitalWrite(10, LOW);
      digitalWrite(11, LOW);
    break;
    
  case 0xCF://Код кнопки ВПЕРЕД
      mL.setSpeed(HI_MOVE);
      mR.setSpeed(HI_MOVE);
      mL.run(M_FORWARD);
      mR.run(M_FORWARD);
      digitalWrite(10, HIGH);
      digitalWrite(11, HIGH);
    break;

  case 0x37://Код кнопки ВПЕРЕД и ВПРАВО
      mL.setSpeed(HI_MOVE);
      mR.setSpeed(LOW_MOVE);
      mL.run(M_FORWARD);
      mR.run(M_FORWARD);
      digitalWrite(10, LOW);
      digitalWrite(11, HIGH);
    break;

  case 0x8F://Код кнопки ВПЕРЕД и ВЛЕВО
      mR.setSpeed(HI_MOVE);
      mL.setSpeed(LOW_MOVE);
      mR.run(M_FORWARD);
      mL.run(M_FORWARD);
      digitalWrite(10, HIGH);
      digitalWrite(11, LOW);
    break;
    
  case 0x97://Код кнопки РАЗВОРОТ ПО ЧАСОВОЙ
      mL.setSpeed(HI_MOVE);
      mR.setSpeed(HI_MOVE);
      mL.run(M_FORWARD);
      mR.run(M_BACKWARD);
      digitalWrite(10, LOW);
      digitalWrite(11, HIGH);
    break;

  case 0x17://Код кнопки РАЗВОРОТ ПРОТИВ ЧАСОВОЙ
      mR.setSpeed(HI_MOVE);
      mL.setSpeed(HI_MOVE);
      mR.run(M_FORWARD);
      mL.run(M_BACKWARD);
      digitalWrite(10, HIGH);
      digitalWrite(11, LOW);
    break;

  case 0x4F://Код кнопки НАЗАД
      mL.setSpeed(HI_MOVE);
      mR.setSpeed(HI_MOVE);
      mL.run(M_BACKWARD);
      mR.run(M_BACKWARD);
      digitalWrite(10, LOW);
      digitalWrite(11, LOW);
    break;

  case 0x0F://Код кнопки НАЗАД и ВПРАВО
      mL.setSpeed(HI_MOVE);
      mR.setSpeed(LOW_MOVE);
      mL.run(M_BACKWARD);
      mR.run(M_BACKWARD);
      digitalWrite(10, LOW);
      digitalWrite(11, LOW);
    break;

  case 0x77://Код кнопки НАЗАД и ВЛЕВО
      mR.setSpeed(HI_MOVE);
      mL.setSpeed(LOW_MOVE);
      mR.run(M_BACKWARD);
      mL.run(M_BACKWARD);
      digitalWrite(10, LOW);
      digitalWrite(11, LOW);
    break;
  }
}

  • И загружаем обновленный скетч в микроконтроллер, подключаем питание и жмем на кнопки на пульте.
Должно получиться что-то типа этого (небольшой видео-отчет):

ps Снимал снаружи, где нет отраженного сигнала от стен и потолка - машинка плохо управлялось издалека. В помещении таких проблем не наблюдалось.
pss Во время съемки села батарейка и поэтому видео такое короткое и резко обрывается.

Ссылки: