Arduino + L293 нужен совет.

Тема в разделе "Моторы, сервоприводы, робототехника", создана пользователем ivandu, 5 апр 2015.

  1. ivandu

    ivandu Нуб

    Имею: Arduino Uno , L293D, платформу с двумя движками, радиоаппа Turnigy 9XR, приемник Orange.

    Код:

    Код (Text):
     int IN1 = 8; //input1 подключен к выводу 8
      int IN2 = 9;
      int IN3 = 12;
      int IN4 = 13;
      int EN1 = 10;
      int EN2 = 11;
      int drive_1;
      int drive_2;

    void setup()
    {
      pinMode (EN1, OUTPUT);
      pinMode (IN1, OUTPUT);
      pinMode (IN2, OUTPUT);
      pinMode (EN2, OUTPUT);
      pinMode (IN4, OUTPUT);
      pinMode (IN3, OUTPUT);
     
      // Все пины порта D кроме нулевого(TX) устанавливаем как входы
      DDRD = 1;
      // Настраиваем таймер 1 на отсчет 0.5 мкс
      TCCR1B  =  0;
      TCCR1A  =  0;
      TCNT1  =    0;
      TCCR1A  =  0;
      TCCR1B  =  0<<CS12 | 1<<CS11 | 0<<CS10;//0x1A; //start timer with 1/8
      // Разрешаем прерывания порта D по изменению уровня
      PCICR |= (1 << PCIE2);
      // настраиваем маску прерывания - пины 2-7
      PCMSK2 = 0xFC;
      // открываем UART для вывода результата
      Serial.begin(9600);
    }

    typedef struct {
      unsigned long riseTime; // время перехода 0->1
      unsigned int  lastWidth; // ширина импульса
    } tPinTimingData;
    volatile static tPinTimingData pinData[6]; //массив каналов
    volatile static uint8_t PCintLast;

    uint8_t bit;
    uint8_t curr;
    uint8_t mask;
    uint16_t currentTime;
    uint16_t time;

    // обработчик прерывания порта D
    ISR(PCINT2_vect)
    {
      // текущее время по таймеру 1 в мкс
      currentTime = TCNT1>>1;
      // Получаем состояние интересующих нас пинов
      curr = PIND & 0xFC;
      // пины, изменившие состояние
      mask = curr ^ PCintLast;
      PCintLast = curr;
      // в цикле просматриваем каждый пин
      for (uint8_t i=0; i < 6; i++) {
        // маска текущего пина цыкла
        bit = 0x04 << i;
        if (bit & mask) {
          // если 0->1
          if (bit & PCintLast)
            // сохраняем текущее время для канала
            pinData[i].riseTime = currentTime;
          else {
            // рассчитываем ширину импульса
            time = currentTime - pinData[i].riseTime;
            // и сохраняем ее, если таймер не наврал
            if ((time >= 800) && (time <= 2200)) {
              pinData[i].lastWidth = time;
            }
          }
        }
      }
    }

    void loop()
    {
      int drive_1 = (pinData[0].lastWidth - 986) / 4.05;
      int drive_2 = (pinData[1].lastWidth - 986) / 4.05;
     
      if (pinData[2].lastWidth < 1500)
        {
          digitalWrite (IN1, HIGH);
          digitalWrite (IN2, LOW);
          digitalWrite (IN3, HIGH);
          digitalWrite (IN4, LOW);
          analogWrite(EN1, drive_1);
          analogWrite(EN2, drive_2);
        }
      else
        {
          digitalWrite (IN1, LOW);
          digitalWrite (IN2, HIGH);
          digitalWrite (IN3, LOW);
          digitalWrite (IN4, HIGH);
          analogWrite(EN1, drive_1);
          analogWrite(EN2, drive_2);
        }
     
        /* Serial.println();
        Serial.print("Ch 1:");
        Serial.print(drive_0);
        Serial.print("Ch 2:");
        Serial.print(drive_1);
        Serial.print("Ch 3:");
        Serial.print(pinData[2].lastWidth);
       
        delay(500);*/
    }
    Не крутится вообще 1й двигатель (пины 8,9,10), 2й работает как задумано.

    На мониторе последовательного порта все переменные идут нормально.

    Если убрать изи кода код чтения сигнала с приёмника и на двигатели, на ENABLE, подавать константы или через цикл наращивать\снижать- оба движка работают как надо.

    Подскажите в чем проблема.

    Спасибо.
     
  2. А переменные направления для Н-Моста где?
     
  3. cody_c++

    cody_c++ Нерд

    Скинь схему, там будет ясно. Ну или поменяй моторчики местами, может брак. не сработает,проверь сам чип