Как определить соединенные друг с другом контакты?
Вероятно, есть другой способ добиться желаемого, не соединяя штифты друг с другом, поэтому я объясню сценарий:
Пытаюсь собрать машину Enigma на базе Arduino. Криптография работает отлично, она запускается через последовательный монитор. Теперь хочу сделать интерфейс более реалистичным.
Оригинальная машина имела коммутационную панель: 26 клемм (промаркированных от A до Z), к которым можно было подключить кабель от одной буквы к другой, и пользователь мог сделать до 10 таких подключений.
Я застрял на этом этапе. Как это сделать электронно? Как сообщить микроконтроллеру, подключен ли вывод к другому выводу?
Если я назначу каждый терминал отдельному контакту на плате, я не смогу одновременно использовать эти контакты в режиме выхода и входа.
Моей первой идеей было создать массив резисторов для создания уникальных ассоциаций и считывания различных аналоговых значений, но это непрактично.
Я также пытался нарисовать логическую схему для точного считывания ассоциаций, но это тоже не работает.
Я знаю, что это можно сделать с помощью Arduino Mega, так как в интернете продаются копии на этой плате. Есть ли другое подходящее оборудование? Буду рад узнать.
@Diego Dyan, 👍0
Обсуждение2 ответа
Лучший ответ:
Если у вас достаточно контактов для всех 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
Разумеется, вам не обязательно получать каждый дважды.
Во втором цикле начните с индекса текущего контакта.
Вот так:
#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;
}
}
- Использовать выводы PWM в качестве обычных цифровых входов/выходов?
- Как можно ограничить чувствительность емкостных сенсоров?
- Невозможно использовать аналоговые контакты в качестве цифровых входов
- Почему контакт должен быть установлен как вход, если он может считывать ввод, когда он установлен как выход?
- Использование вывода светодиода для ввода
- Доступ к физическим контактам Arduino Due из Arduino IDE
- Остается ли контакт (входной контакт Arduino) плавающим при подключении к GPIO на RPI?
- Как подключить клавиатуру Luxorparts к Arduino?
Как сообщить микроконтроллеру, подключен ли вывод к любому другому выводу?... вам не нужно ничего ему сообщать ... микроконтроллер может обнаружить соединения между выводами, @jsotolaЯ не могу одновременно использовать эти контакты в режиме выхода и входа... просто установите только один как выход, @jsotola