Я построил этот моторный щиток на базе микросхемы L298N для управления двумя моторами танка. Он использует контакты 5 и 6 для одного двигателя и контакты 10 и 11 для другого.
Пытаясь добавить TSOP 4838 для управления резервуаром с помощью ИК-пульта, я заметил что движение двигателя на контактах 10/11 в обратном направлении работает только на полной скорости, то есть при ВЫСОКОМ (255) значении на контакте 11. Все, что ниже этого значения, ничего не выводит на контакт 11 (измеренное напряжение на этих контактах равно 0 V).
Для пульта дистанционного управления я использую эту библиотеку. Приемник IR подключен к контакту 2 (но контакт не имеет значения). Проблема в самом коде библиотеки. Линия, которая включает ИК-прослушивание irrecv.enableIRIn();
, является причиной проблемы. Я узнал, что существует конфликт внутренних таймеров Arduino и контактов, используемых щитом для ШИМ.
Это код для включения двигателя в обратном направлении:
#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
Итак, мои вопросы:
Почему экран в инструкции использует контакты 10 и 11 для ШИМ? Они соответствуют 2 разным таймерам. Почему не 9 и 10?
Какой таймер мне нужно настроить в библиотеке IR, чтобы использовать ИК вместе с моторным щитом?
Если ответ - 2, следует раскомментировать строку в
IRremoteInt.h
. Я предполагаю, что Uno возьмет веткуelse
в строке 68, хотя там есть только timer1 и timer2. Интересно, почему timer0 нельзя было использовать для Uno.
Хотя я хотел бы оставить следы резки и пайку в качестве последнего варианта, другой возможностью было бы изменить контакты, используемые щитом, но какие? И я предполагаю, что это также будет связано с настройкой таймеров на ШИМ на других выводах, кроме по умолчанию, но я ничего не знаю о таймерах / прерываниях, а мои знания об Arduino и C ограничены.
Я задал этот длинный вопрос, потому что хочу научиться, а не просто решать проблему, поэтому не стесняйтесь объяснять больше, чем то, о чем просят.
В поисках решения я также обнаружил другие конфликты, о которых следует помнить при использовании PWM или таймеры:
- Timer0 - это 8-битный таймер, он может содержать максимальное значение 255. Он используется
delay()
иmillis()
, поэтому есть последствия, если с ним возиться. - Timer1 - это 16-разрядный таймер, он может содержать максимум 65535 (16-разрядное целое число без знака). Библиотека Arduino Servo использует этот таймер
- Timer2 - это 8-битный таймер, используемый функцией Arduino
tone()
.
И, конечно же, библиотека IRremote использует TIMER_RESET
, поэтому в зависимости от того, какой таймер он использует, он может конфликтовать с соответствующими контактами.