Как определить соединенные друг с другом контакты?

pins input pinmode

Вероятно, есть другой способ добиться желаемого, не соединяя штифты друг с другом, поэтому я объясню сценарий:

Пытаюсь собрать машину Enigma на базе Arduino. Криптография работает отлично, она запускается через последовательный монитор. Теперь хочу сделать интерфейс более реалистичным.

Оригинальная машина имела коммутационную панель: 26 клемм (промаркированных от A до Z), к которым можно было подключить кабель от одной буквы к другой, и пользователь мог сделать до 10 таких подключений.

Я застрял на этом этапе. Как это сделать электронно? Как сообщить микроконтроллеру, подключен ли вывод к другому выводу?

Если я назначу каждый терминал отдельному контакту на плате, я не смогу одновременно использовать эти контакты в режиме выхода и входа.

Моей первой идеей было создать массив резисторов для создания уникальных ассоциаций и считывания различных аналоговых значений, но это непрактично.

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

Я знаю, что это можно сделать с помощью Arduino Mega, так как в интернете продаются копии на этой плате. Есть ли другое подходящее оборудование? Буду рад узнать.

, 👍0

Обсуждение

Как сообщить микроконтроллеру, подключен ли вывод к любому другому выводу? ... вам не нужно ничего ему сообщать ... микроконтроллер может обнаружить соединения между выводами, @jsotola

Я не могу одновременно использовать эти контакты в режиме выхода и входа ... просто установите только один как выход, @jsotola


2 ответа


Лучший ответ:

3

Если у вас достаточно контактов для всех 26 терминалов, вы можете напрямую пройти все соединения итеративно:

  • Установить все контакты в положение INPUT_PULLUP
  • Установите один контакт на OUTPUT и LOW
  • Считайте все контакты рядом с этим выходным контактом и проверьте, показывает ли один из них LOW (что означает соединение между выходным контактом и этим)
  • Повторите для всех контактов (каждый контакт является выходным в одной итерации)

Вы можете сохранить это в массиве из 26 целых чисел. Позиция в массиве будет «начальным выводом» соединения, а значение — конечным выводом.

С помощью вышеописанного алгоритма вы, конечно же, получаете каждое соединение дважды. Либо просто игнорируйте второе соединение при любых действиях с данными, либо можете проверить, есть ли у этого контакта уже соединение, и установить его значение в -1 (что означает «не важно/не нужно»).

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

,

Я думаю, что полезно иметь в позиции X отображение в Y и в позиции Y отображение в X, @Juraj

Спасибо за ответ, но этот способ также непрактичен, поскольку он должен работать на реальной машине. Например, если я возьму кабель и подключу один конец к контакту 1, а затем другой кабель к контакту 2, у меня останутся два свободных конца. Если я подключу первый конец первого кабеля к контакту 3, в этот момент Arduino не сможет определить, является ли это соединением 1-3 или 2-3., @Diego Dyan

@DiegoDyan да, он бы знал, что соединение происходит между контактами 1 и 3, поскольку это соединение приведёт к подтягиванию к НИЗКОМу уровню контактов 1 и 3. Другой кабель ничего не делает, поскольку он подключён только с одной стороны, что электрически равносильно отсутствию соединения в данном случае. Так что в вашем сценарии второй кабель (подключённый только с одной стороны) может просто отсутствовать. Важна только связь, образующая цепь (путём соединения двух контактов). Поэтому я не вижу, в чём может быть проблема., @chrisl

Думаю, вы правы. Мне кажется, что триггером для начала итерации было бы первое соединение, но это не обязательно так. Я смоделировал это с меньшим количеством выводов в ThinkerCad, и это вроде работает. Код требует некоторой доработки, чтобы возвращать точный параметр, но ответ полезен. Большое спасибо., @Diego Dyan


0

Разумеется, вам не обязательно получать каждый дважды.

Во втором цикле начните с индекса текущего контакта.

Вот так:

#define START 22
#define END   45

static int lasti = -1;
static int lastj = -1;
static bool bFound;

static char buf [1024];


void setup () 
{
  // put your setup code here, to run once:
  int i;

  for (i = START; i <= END; i++)
  {
    pinMode (i, INPUT_PULLUP);
  }

  Serial.begin (115200);
}

void loop () 
{
  bFound = false;
  int i, j;

  for (i = START; i <= END;  i++)
  {
    pinMode (i, OUTPUT);
    digitalWrite (i, LOW);

    // This is the scan loop
    // Notice that we start at i + 1, not zero
    for (j = i + 1; j <= END; j++)
    {
      if (digitalRead (j) == LOW)
      {
        // Found a winner
        bFound = true;
        if (i != lasti || j != lastj)
        {
          lasti = i;
          lastj = j;

          sprintf (buf, "%d / %d", i - START + 1, j - START + 1);
          Serial.println(buf);
        }
      }
    }

    pinMode (i, INPUT_PULLUP);
  }

  // If we get here and bFound is false - all keys are up
  if (!bFound)
  {
    lasti = -1;
    lastj = -1;
  }
}
,