Подключение к р/у машинке Arduino, USB-руля и педалей Logitech Momo Racing 2004

Тема в разделе "Проводная и беспроводная связь", создана пользователем M0ln1a, 13 фев 2017.

  1. M0ln1a

    M0ln1a Гик

    Здравствуйте! Пару дней назад задавал на форуме этот вопрос, теперь решил пойти по узкой специальности)
    Есть модель автомобиля на радиоуправлении. Хочу управлять ей при помощи старенького игрового комплекта Logitech Momo Racing 2004ого года выпуска...
    Из опыта, полученного за эти 2 дня с форумом, и вскрытия техники, выяснил, что педали подключаются к рулю по неизвестному мне кабелю (напоминает RS-232, 3 контакта сверху, 4 снизу), а руль к компьютеру по USB.
    Все фотографии я кинул на диск: https://drive.google.com/open?id=0Bx6XCuT9H9a3c0dsbmFTbFJOSFk
    Тема с общего Arduino-форума: http://forum.amperka.ru/threads/Под...ля-и-педалей-logitech-momo-racing-2004.11020/
    Благодаря поискам mcureenab, был найден проект, где такой руль связали с PS4: https://gimx.fr/forum/viewtopic.php?t=1400
    Возможно там же можно найти и декодер, но, к сожалению, я в этих делах не силен...
    Вопрос: как мне связать руль с пультом управления, так, чтобы машинкой можно было управлять?
    После поисков в книге "Проекты с использованием контроллера Arduino" нашел там информацию о подключении к контроллеру руля Defender.

    Вот те скетчи:
    Код (C++):

    #include <avr/pgmspace.h>
    #include <avrpins.h>
    #include <max3421e.h>
    #include <usbhost.h>
    #include <usb_ch9.h>
    #include <Usb.h>
    #include <usbhub.h>
    #include <avr/pgmspace.h>
    #include <address.h>
    #include <hid.h>
    #include <hiduniversal.h>
    #include "hidjoystickrptparser.h"
    #include <printhex.h>
    #include <message.h>
    #include <hexdump.h>
    #include <parsetools.h>

    USB                                             Usb;
    USBHub                                          Hub(&Usb);
    HIDUniversal                                    Hid(&Usb);
    JoystickEvents                                  JoyEvents;
    JoystickReportParser                            Joy(&JoyEvents);

    #include <SPI.h>
    #include <Mirf.h>
    #include <nRF24L01.h>
    #include <MirfHardwareSpiDriver.h>
    #define MAX_BUFF 32 //Буфер приёма-передачи

    void setup()
    {
      Serial.begin( 115200 );
      Serial.println("Start");
      if (Usb.Init() == -1)
          Serial.println("OSC did not start.");
       
      delay( 200 );

      if (!Hid.SetReportParser(0, &Joy))
          ErrorMessage<uint8_t>(PSTR("SetReportParser"), 1  );
      Mirf.spi = &MirfHardwareSpi;
      Mirf.init();
      Mirf.setRADDR((byte *)"defender"); //Здесь задаём адрес
      Mirf.payload = MAX_BUFF; //Здесь задаём буфер
      Mirf.channel = 10;
    //Это канал приёма-передачи - должен
    //быть одинаковым у устройств.
      Mirf.config();
      Serial.println("Start..");
    }

    char buff[MAX_BUFF];
    int c_count = 0;

    void loop()
    {
        Usb.Task();
        //if()
          //{
          Serial.print(JoyEvents.X,HEX);Serial.print(" ");
          Serial.print(JoyEvents.Y,HEX);Serial.print(" ");
          Serial.print(JoyEvents.Z1,HEX);Serial.print(" ");
          Serial.print(JoyEvents.Z2,HEX);Serial.print(" ");
          Serial.print(JoyEvents.Rz,HEX);Serial.print(" ");
          Serial.println();//}
          buff[0]=map(JoyEvents.X,0,255,1,100);
          buff[1]=map(JoyEvents.Y,0,255,1,100);;
          buff[2]=map(JoyEvents.Z1,0,255,1,100);
          buff[3]=map(JoyEvents.Z2,0,255,1,100);
          buff[4]=JoyEvents.Rz+1;
          buff[5]=0;
        Mirf.setTADDR((byte *)"automobile1"); //Адрес!
        Serial.print(">");
        Mirf.send((uint8_t *)buff);
        while(Mirf.isSending()){
        }
        Serial.println(buff);
        delay(300);
    }
    Код (C++):
    #include <SPI.h>
    #include <Mirf.h>
    #include <nRF24L01.h>
    #include <MirfHardwareSpiDriver.h>
    #define MAX_BUFF 32 //Буфер приёма-передачи

    void setup(){
      Serial.begin(9600);
      Mirf.spi = &MirfHardwareSpi;
      Mirf.init();
      Mirf.setRADDR((byte *)"automobile1"); //Здесь задаём адрес
      Mirf.payload = MAX_BUFF; //Здесь задаём буфер
      Mirf.channel = 10;
    //Это канал приёма-передачи - должен
    //быть одинаковым у устройств.
      Mirf.config();
      // настраиваем выводы для моторов
      pinMode(3, OUTPUT);
      pinMode(4, OUTPUT);
      pinMode(5, OUTPUT);
      pinMode(6, OUTPUT);
      Serial.println("Start..");
    }

    char buff[MAX_BUFF];

    void loop(){
      delay(10);
      //receiving
      if(Mirf.dataReady()) {
        Mirf.getData((uint8_t *)buff);
        int fb1=buff[0];
        int lr=buff[1];
        go12(fb1,lr1);
      }
      delay(100);
    }
    //
    void go12(int fb,int lr)
      {
      //вперед-назад
      if(fb>50)
         {digitalWrite(3,HIGH);digitalWrite(4,LOW);
          digitalWrite(5,HIGH);digitalWrite(6,LOW);}
      else if(fb<50)
         {digitalWrite(3,LOW);digitalWrite(4,HIGH);
          digitalWrite(5,LOW);digitalWrite(6,HIGH);}
      else
         {digitalWrite(3,LOW);digitalWrite(4,LOW);
          digitalWrite(5,LOW);digitalWrite(6,LOW);}
      //влево-вправо
      int lr1=map(abs(50-lr),1,50,1,255);
      int fb1=map(abs(50-fb),1,50,1,255);
      if(lr<50)
        {int left=min(255,max(0,fb1-lr1/2));
         int right=min(255,fb1+lr1/2)}
      else
        {int right=min(255,max(0,fb1-lr1/2));
         int left=min(255,fb1+lr1/2)}
      analogWrite(9, left);
      analogWrite(10, right);
      }
    Код (C++):
    #include <SoftwareSerial.h>
    SoftwareSerial mySerial(4,5);

    #include <PS3USB.h>
    USB Usb;
    PS3USB PS3(&Usb);
    Button Btarr[16]={UP,RIGHT,DOWN,LEFT,SELECT,START,L3,R3,L2,R2,L1,R1,TRIANGLE,CIRCLE,CROSS,SQUARE};
    AnalogHat Joyarr[4]={LeftHatX,LeftHatY,RightHatX,RightHatY};

    int status_buttons[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
    long millis_buttons[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
    long millis_buttons1[16]={500,500,500,500,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000};

    int status_joys[4]={0,0,0,0};
    int millis_joys[4]={0,0,0,0};
    int map_joys[4]={2000,-500,2000,-500};
    int dHatLeft=0;
    int dHatRight=0;

    void setup() {
      Serial.begin(115200);
      if (Usb.Init() == -1) {
        Serial.print(F("\r\nOSC did not start"));
        while(1); //halt
      }
      Serial.print(F("\r\nPS3 USB Library Started"));

    }
    void loop() {
      Usb.Task();

       // joys
      for(int i=0;i<4;i++)
        {
        if((PS3.getAnalogHat(Joyarr[i]) != status_joys[i]) && (millis()-millis_joys[i]>200))
          {
           millis_joys[i]=millis();status_joys[i]=PS3.getAnalogHat(Joyarr[i]);
           int hat=map(PS3.getAnalogHat(Joyarr[i]),0,255,map_joys[i]*(-1),map_joys[i]);
           if(i<2) dHatLeft=1;
           else dHatRight=1;
           }
         }
       if(dHatLeft>0)
         {dHatLeft=0;}
       if(dHatRight>0)
         {dHatRight=0;
          go_irobot(status_joys[3],status_joys[2]);}
      // buttons
      for(int i=0;i<16;i++)
        {
        if(PS3.getButtonPress(Btarr[i]) && status_buttons[i]==0)
          {
           millis_buttons[i]=millis();status_buttons[i]=1;
           put_actions(i);
           }
        else
          {if(millis()-millis_buttons[i]>millis_buttons1[i]) status_buttons[i]=0;}
        }
    }

    void put_actions(int btn1)
    {Serial.println(btn1);
    switch(btn1)
      {
      case 4: mySerial.write(128);
           break;
      // start
      case 5: mySerial.write(132);
           break;
      // led
      case 8: mySerial.write((int)139);mySerial.write((int)8);mySerial.write((int)255);mySerial.write((int)255);
           break;
      case 10: mySerial.write(139);mySerial.write(4);mySerial.write((byte)0);mySerial.write(255);
           break;
      // music 6
      case 9: mySerial.write(141);mySerial.write(6);
           break;
    // 40 см и останов
      case 12: mySerial.write(152);mySerial.write(13);
           mySerial.write(137);mySerial.write(1);mySerial.write(44);mySerial.write(128);mySerial.write((byte)0);
           mySerial.write((int)156);mySerial.write((int)1);mySerial.write((int)144);
           mySerial.write(137);mySerial.write((byte)0);mySerial.write((byte)0);mySerial.write((byte)0);mySerial.write((byte)0);
           mySerial.write(153);
          break;
    // music 5
      case 11: mySerial.write(141);mySerial.write(5);
           break;
      case 13: mySerial.write(152);mySerial.write(17);
           mySerial.write(137);mySerial.write(1);mySerial.write(44);mySerial.write(128);mySerial.write((byte)0);
           mySerial.write((int)156);mySerial.write((int)1);mySerial.write((int)144);
           mySerial.write(137);mySerial.write(1);mySerial.write(44);mySerial.write((byte)0);mySerial.write(1);
           mySerial.write((int)157);mySerial.write((byte)0);mySerial.write(90);
           mySerial.write(153);
           mySerial.write(153);
           break;
      default:
           break;
      }
    }
    // отправка команд для движения робота
    void go_irobot(int v1,int r1)
      {
       int v2,r2,lf1,rt1;
       if(v1<128 && r1<128)
          {lf1=v1+abs(r1-128)/2;rt1=max(0,v1-abs(r1-128)/2);}
       else if(v1<128 && r1>=128)
          {lf1=max(0,v1-abs(r1-128)/2);rt1=v1+abs(r1-128)/2;}
       else if(v1>=128 && r1<128)
          {lf1=v1-abs(r1-128)/2;rt1=min(255,v1+abs(r1-128)/2);}
       else if(v1>=128 && r1>=128)
          {lf1=min(255,v1+abs(r1-128)/2);rt1=v1-abs(r1-128)/2;}
       else
          ;      
       //v2=map(v1,0,255,map_joys[3]*(-1),map_joys[3]);
       //r2=map(r1,0,255,map_joys[2]*(-1),map_joys[2]);
       lf1=map(lf1,0,255,250,-250);
       rt1=map(rt1,0,255,250,-250);
       mySerial.write(145);
       mySerial.write(highByte(rt1));mySerial.write(lowByte(rt1));
       mySerial.write(highByte(lf1));mySerial.write(lowByte(lf1));
      }
    Заранее спасибо! :)