Arduino+MotorShield+TroykaShield - непонятки с PIN2 и PIN3

Тема в разделе "Arduino & Shields", создана пользователем OlegROA, 8 фев 2018.

  1. OlegROA

    OlegROA Нерд

    Добрый день.

    Для уроков робототехники собрал из учебного набора стенд для работы с моторами и с цифровым датчиком линии в качестве тахометра. Управление потенциометром - среднее положение в качестве стопа для мотора, влево - ускорение вращения в одну сторону, вправо - ускорение вращения в другую сторону.
    Стенд.jpg
    MotorShield.jpg
    Shield-бутерброд.jpg
    мотор - 22.png

    Все работает нормально. НО!
    Случайно заметил - датчик линии подключен к пину 3, хотя в коде скетча указан пин 2!
    Проверил еще раз, загрузил - работает! Указал в коде пин 3 - работает!
    Наоборот - нет. Т.е., если подключаю датчик линии к пину 2, то работает только если в коде указан именно пин 2.
    Убрал тройку - стало еще интереснее - 2 и 3 пины работают как один!
    Т.е., несмотря на то, какой пин указан в коде 2 или 3, стенд работает одинаково как с пином 2, так и с пином 3!

    Вот сижу и гадаю - я чего не понимаю (в доке вроде бы ничего об этом не сказано) или это барахлит мотор-шильд? Или даже ардуино?
    Перемычки на мотор-шильде стоят по дефолту - 4, 5, 6, 7.

    Полный код скетча:
    Код (C++):
    // Motor shield использует четыре цифровых порта:
    // 4, 5 - для управлением моторами первого канала и 6, 7 - для управления моторами второго канала
    // 4 и 7 — направление вращения, 5 и 6 — скорость вращения
    // Мотор подключается к клеммам M1+, M1-
    #define MOTOR1_DIR    4
    #define MOTOR1_SPEED  5

    // Потенциометр для управления направлением и скоростью
    // вращения вала мотора.
    // Подключаем к аналоговому порту A0.
    #define CONTROL_PIN   A0

    // Цифровой датчик линии используем как тахометр для определения
    // скорости вращения вала мотора.
    // Подключаем к цифрому порту 2.
    #define TACH_PIN      2
    boolean               tach_blackLabel = false; // Обнаружена черная метка
    unsigned long         tach_lastBlackLabel = 0; // Время обнаружения последней четной метки

    // Подключаем библиотеку для работы с LCD-дисплеем
    #include <LiquidCrystalRus.h>

    // Инициализация дисплея - используются цифровые порты с 8 по 13
    LiquidCrystalRus lcd(8, 9, 10, 11, 12, 13);

    void setup()
    {
      Serial.begin(9600);

      // Настраивает выводы платы 4, 5 на вывод сигналов
      pinMode(MOTOR1_DIR, OUTPUT);
      pinMode(MOTOR1_SPEED, OUTPUT);
      pinMode(CONTROL_PIN, INPUT);
      pinMode(TACH_PIN, INPUT);

      // Настройка дисплея - 2 строки по 16 символов
      lcd.begin(16, 2);
      lcd.print("Тахометр:");
    }

    void loop()
    {
      // Считываем значение потенциометра
      // Диапазон аналогового сигнала от 0 до 1023
      int val = analogRead(CONTROL_PIN);

      // Потенциометр управляет одновременно и скоростью вращения и направлением вращения:
      // среднее положение (512) - нулевая скорость
      // от 511 до 0 - вращение по часовой стрелке, скорость от 0 до 255
      // от 513 до 1023 - вращение против часовой стрелки, скорость от 0 до 255
      if (val < 512) {
        // Крутим по часовой стрелке
        digitalWrite(MOTOR1_DIR, LOW);
        // Значение скорости вращения - от 255 до 0.
        analogWrite(MOTOR1_SPEED, (511-val)/2);
      } else {
        // Крутим против часов стрелки
        digitalWrite(MOTOR1_DIR, HIGH);
        // Значение скорости вращения - от 0 до 255.
        analogWrite(MOTOR1_SPEED, (val-512)/2);
      };

      boolean tach_data = digitalRead(TACH_PIN);
      if (tach_data) {
         // Черная метка
         if (!tach_blackLabel) {
            tach_blackLabel = true;
            unsigned long delta = micros() - tach_lastBlackLabel;
            tach_lastBlackLabel = micros();
            delta = 60000000 / delta;
            if (delta > 0) {
               lcd.setCursor(0, 1);
               lcd.print((String) delta +" об/мин        ");
            };
         };
      } else {
         // Белое поле
         tach_blackLabel = false;
      };
      if ((tach_blackLabel == tach_data) && ((micros() - tach_lastBlackLabel)*0.000001 > 60)) {
         // Если состояние "черной метки" не меняется уже более минуты - считаем, что колесо стоит
         tach_lastBlackLabel = micros();
         lcd.setCursor(0, 1);
         lcd.print("Меньше 1 об/мин!");
      };
    }
     
     
  2. mcureenab

    mcureenab Гуру

    Пин висящий может помех наловить в том числе от провода к соседнему пину.
     
  3. OlegROA

    OlegROA Нерд

    Не понял понятия "висящий"? И как сделать его не "висячим"?
    И речь идет не о помехах, а о четких сигналах, которые приходят на пин как бы от датчика линии!
    Т.е., в случае без тройки-шильд если один из пинов 2 или 3 принимает сигнал от датчика линии, то в ардуино поступают сигналы сразу от обоих пинов, как будто бы датчик дублировал их в оба пина!
     
  4. mcureenab

    mcureenab Гуру

    Цифровые сигналы всегда чёткие. Или есть или нет.

    Висящий, значит не подключенный к источнику сигнала с достаточно малым выходным сопротивлением. Замкните висящий пин на GND, а к другому подключите датчик.
    Например, пин 2 замкнуть, пин 3 на датчик. Потом наоборот и сравнить результат.
     
  5. OlegROA

    OlegROA Нерд

    Ваш вариант попробую чуть позже. Но сразу же - тогда, получается, что любой свободный порт будет "фонить"?!
    До того, как увидел Ваш коммент, попробовал напрямую подключить датчик линии к плате, без посредников и без лишней "обвязки" - оба порта ведут себя почти также, как описал выше в случае без тройки-шильд.
    Почти - в случае быстрой смены сигнала с датчика на "необъявленном" порту или не было сигнала или шел непрерывный сигнал. Вероятно, Вы правы и речь идет именно о шумах с незадействованных портов.
     
  6. b707

    b707 Гуру

    Дело не в том, что порты незадействованы, "задействованные" в скетче порты точно так же будут фонить, если на них нет сигнала. Чтобы при отсуствии сигнала порт не фонил - он обязательно должен быть подтянут к питанию или к "земле" через резистор большого номинала - 10-100К
     
  7. mcureenab

    mcureenab Гуру

    Резистор то зачем? Можно пустые порты в INPUT_PULLUP перевести или на GND или на Vcc подключить или в OUTPUT.