Arduino Uno PWM контакты конфликт

Я построил этот моторный щит основанный на обломоке L298N для того чтобы контролировать 2 мотора бака. Он использует штыри 5 и 6 для одного мотора, и штыри 10 и 11 для другого.

при попытке добавить TSOP 4838 для управления танком с ИК-пультом я заметил, что перемещение двигателя на штифтах 10/11 в обратном направлении работает только на полной скорости - то есть высокое (255) значение на штифте 11. Все, что ниже этого значения, ничего не выводит на вывод 11 (измеренное напряжение на этих выводах 0 V).

для пульта дистанционного управления я использую библиотека. The IR приемник подключен к контакту 2 (но контакт не имеет значения). Проблема в самом библиотечном коде. Линия, которая позволяет ИК прослушивания irrecv.enableIRIn(); это то, что вызывает проблему. Я узнал, что существует конфликт внутренних таймеров Arduino и контактов, используемых для PWM щитом.

это код для питания двигателя в обратном:

#include <IRremote.h>

// IR receiver configuration
const int irPin = 2;
IRrecv irrecv(irPin);

// Motors configuration
const int mLeftPin1  = 10;
const int mLeftPin2  = 11;
const int mRightPin1 = 5;
const int mRightPin2 = 6;

void setup()
{
  // Start IR
  irrecv.enableIRIn();

  // Setup motors
  pinMode(mLeftPin1, OUTPUT);
  pinMode(mLeftPin2, OUTPUT);
  pinMode(mRightPin1, OUTPUT);
  pinMode(mRightPin2, OUTPUT);

  // Move left motor in reverse, slower speed
  analogWrite(mLeftPin2, 100); // This works only with 255 instead of 100
  digitalWrite(mLeftPin1, LOW);
}

теперь, Я нашел здесь что контакты, используемые таймерами на Arduino Uno являются:

  • штыри 5 и 6: проконтролированный Timer0
  • штыри 9 и 10: проконтролированный Timer1
  • контакты 11 и 3: контролируется Timer2

Итак, мои вопросы:

  1. почему экран в instructable использует штыри 10 и 11 для PWM ? Они соответствуют 2 различных таймеров. Почему не 9 и 10?

  2. для использования ИК вместе с экраном мотора, какой таймер должен я настроить библиотеку ИК для использования?

  3. если ответ 2, строка должна быть раскомментирована в IRremoteInt.h. Я предполагаю, что Uno возьмет else ветвь в строке 68, хотя есть только timer1 и timer2. Интересно, почему timer0 нельзя использовать для Uno.

хотя я хотел бы оставить следов резки и перепаять как последний вариант, еще одна возможность-изменить контакты, используемые щитом, но какие? И я предполагаю, что это также будет сопряжено с настройкой таймеров на PWM на других выводах, чем по умолчанию, но я ничего не знаю о таймерах/прерываниях, и мои знания Arduino и C ограничены.

Я сделал это длинный вопрос, потому что я хочу научиться не просто решить проблему, поэтому не стесняйтесь объяснять больше, чем спрашивают.

при поиске решения I также найдены другие конфликты, которые следует иметь в виду при использовании ШИМ или таймеры:

  • Timer0-это 8-битный таймер, он может удерживать максимальное значение 255. Он используется delay() и millis(), так что есть последствия, когда возиться с ним
  • Таймера1 - 16-разрядный таймер, он может содержать максимум 65535 (16-разрядное целое число без знака). Библиотека сервопривода Arduino использует этот таймер
  • Timer2 - это 8-битный таймер, используемый Arduino tone() функции

и, конечно,IRremote библиотека использует TIMER_RESET, поэтому в зависимости от того, какой таймер он использует, он может конфликтовать с соответствующими контактами.

3 ответов


  1. не все оборудование разработано наилучшим образом. Использование 10 и 11 действительно расточительно, потому что для этого требуется два таймера.

2/3. В идеале вы будете использовать таймер, который не Timer0. Вот еще некоторые подробности о таймерах / прерываниях:

чип Arduino (328P) имеет три таймера. Каждый таймер может использоваться для нескольких целей, однако важно отметить, что для каждого таймера может быть включено только одно прерывание таймера.

возьмите Timer0 для образец. Он прерывается для создания надлежащих задержек для методов delay() и delay_us (). Он также использован для выходов PWM на штырях 5 и 6. Это может произойти, потому что выходы PWM не используют прерывание таймера, они используют отдельные выходные модули сравнения.

теперь, глядя конкретно на вашу проблему, это должны работать нормально, даже если у вас есть выход PWM с помощью timer2, PWM не прерывает timer2, поэтому ИК-библиотека должна быть свободна в использовании это прерывание. Однако, глядя в код библиотеки IR, мы видим этот фрагмент кода:

ISR(TIMER_INTR_NAME)
{
   TIMER_RESET; 

похоже, что каждый раз, когда он прерывает, он сбрасывает счетчик таймера. Возможно, поэтому ваш выход PWM работает неправильно. Выходной модуль сравнения ждет определенного количества ТИКов, и он никогда не достигает этого.

что касается того, почему он каким-то образом работает на 255, мы можем взглянуть на код analogWrite:

void analogWrite(uint8_t pin, int val)
{
    // We need to make sure the PWM output is enabled for those pins
    // that support it, as we turn it off when digitally reading or
    // writing with them.  Also, make sure the pin is in output mode
    // for consistenty with Wiring, which doesn't require a pinMode
    // call for the analog output pins.
    pinMode(pin, OUTPUT);
    if (val == 0)
    {
        digitalWrite(pin, LOW);
    }
    else if (val == 255)
    {
        digitalWrite(pin, HIGH);
    }

Итак, написав 255, код analogWrite игнорирует весь PWM и выход сравнивает вещь, и просто пишет pin-код высоко.

наконец, что касается решения вашей проблемы, я бы лично пошел по маршруту не используя контакты 11 и 3 (timer2). Да, для этого потребуется небольшая перемотка, но таким образом вы можете освободить timer2 для использования библиотеки IR.

кроме того, вы можете совать вокруг ИК-библиотеки и попытаться заставить его работать без сброса счетчика.


обратите внимание на используемую плату, если вы используете Arduino Uno, то ответственный код будет: / / Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio и т. д еще // определить IR_USE_TIMER1 / / tx = pin 9 определить IR_USE_TIMER2 / / tx = pin 3 за endif


У меня была такая же проблема со встроенным L298 V2 моторный щит.

булавки были помечены вот так на щите:

Мотор1: штырь 3 и 5 Motor2: штырь 6 и 9

Я использую PIN10 вместо 3 и использую небольшой обходной путь: я кладу провод от PIN10 до PIN3 на щит. Мой проект состоял в том, чтобы управлять роботом с помощью пульта дистанционного управления SAMSUNG TV.