помогите нубу

Тема в разделе "Arduino & Shields", создана пользователем Igor68, 26 июн 2016.

  1. Igor68

    Igor68 Гуру

    В моём случае плата ComMotion motor driver for 4 motors столкнулся с проблемой - при настройке её в режим автономного управления каждым мотором без энкодера моторы М1 и М3 управляются нормально(с реверсом), а М2 и М4 при любом задании вращаются в одну сторону. Собственно это первый вопрос, хотя понимаю что это не от AMPERKA и ответа не смогу дождаться.
    Вопрос второй - при анализе кода (привожу фрагмент):
    Код (C++):
     if(command==3 && (packsize==7 || packsize==9)) //============================ Motor Control =======================================================================
      {
        if((configuration==3 || configuration==19) && packsize==9)               // Individual motor control
        {
          for(byte i=0;i<4;i++)
          {
            mspeed[i]=datapack[i*2+1]*256+datapack[i*2+2];
          }
        }
        else                                                                     // Omni or Mecanum Wheels
        {
          velocity=datapack[1]*256+datapack[2];
          angle=datapack[3]*256+datapack[4];
          rotation=datapack[5]*256+datapack[6];

          if(velocity>255) velocity=255;
          if(velocity<-255) velocity=-255;

          while(angle>=360)
          {
            angle-=360;
          }
          while(angle<0)
          {
            angle+=360;
          }

          if(rotation>255) rotation=255;
          if(rotation<-255) rotation=-255;

          Trigonometry();
        }
        command=255;
        return;
      }
     
    выявил что
    mspeed=datapack[i*2+1]*256+datapack[i*2+2];
    по идее надо заменить на
    mspeed=(datapack[i*2+1] <<8)+datapack[i*2+2];
    или даже
    mspeed=(datapack[i*2+1] <<8) | datapack[i*2+2];
    я не могу ориентироваться на Атмегу, т.к. не знаю его специфики а занимаюсь только ARM. допускается ли делать сдвиг на 8 бит влево вместо умножения на 256 - это увеличит скорость обработки более чем в 8 раз (исходя из битового анализа). В ARM подобная операция выполняется за один машинный такт (регистр-регистр). Про Атмега сказать не могу - не разбирался - может умножение тоже есть с результатом в 16 бит из двух операнодв по 8 бит. Если это можно, то я изменю везде эти ненужные умножения на сдвиг - это нормально?
    Заранее спасибо!!!
     
    Последнее редактирование: 26 июн 2016
  2. ostrov

    ostrov Гуру

    Сдвиг - это нормально. Главное чтобы биты не выпали за размерность переменной и не встали на знаковое место, если переменная знаковая. Только нужно ли увеличивать скорость в 8 раз? Моторы штука инерционная.
     
  3. Igor68

    Igor68 Гуру

    Нет - имеется ввиду выполнение сдвига всётаки более чем в 8 раз быстрее выполняется, чем умножение на 256 - операция сдвиг-анализ бита-сложение и повтор, пока 8 бит не пройдёт.
    а размерность:
    mspeed=(datapack[i*2+1] <<8) | datapack[i*2+2];
    решается так:
    mspeed=(signed short)(datapack[i*2+1] <<8) | (signed short)(datapack[i*2+2]);
    т.е. ткнуть компилятор носом.
    Спасибо! Буду пилить шилд!
     
  4. AlexU

    AlexU Гуру

    В AVR нет операции сдвига на определённое число разрядов, а есть только операция сдвига на 1 разряд. И если надо сдвинуть на 8 разрядов, то такой сдвиг выполняется в цикле, что увеличивает время выполнения.
    В то же время операция умножения занимает 2 такта, не зависимо от операндов. Поэтому эту операцию применяют в место операции сдвига.
     
    Igor68 нравится это.
  5. Igor68

    Igor68 Гуру

    Спасибо: подсмотрел - есть :
    MUL
    MULS
    MULSU
    FMUL
    FMULS
    FMULSU
    и 16-битный результат в регистры R0,R1.
    Ещё раз спасибо, а то наварнакал бы!
     
  6. Igor68

    Igor68 Гуру

    Нечаянное продолжение - по работе приводов.
    В том устройстве, над которым ковыряюсь ошибка в прошивке - ComMotion_Shield_V2.0.
    Именно в том месте, где мне надо - режим автономного управления одним из 4 двигателей без применения энкодера. А именно моторы 1 и 2 всегда вращаются в одном направлении, когда 3 и 4 согласно заданию -255...255 - с реверсом. ну это только мои испытания:
    Код (C++):

    if(command<32) Commands();                                                  // respond to command from I²C bus or Serial interface
      if(encoders)
      {
        Motors();                                                                 // if encoders are enabled then use then to control motor speeds
      }
      else                                                                        // if encoders are disabled then feed speed values directly to PWM output
      {                                                                          
        analogWrite(pwmapin,abs(mspeed[mcu*2]));                                  // set motor A speed
        digitalWrite(dirapin,mspeed[mcu*2]>0);                                    // set motor A direction
        analogWrite(pwmbpin,abs(mspeed[mcu*2+1]));                                // set motor B speed
        //digitalWrite(dirаpin,mspeed[mcu*2+1]>0);   //до исправления
        digitalWrite(dirbpin,mspeed[mcu*2+1]>0);      //после                            // set motor B direction
      }
    теперь нормально!