Можно ли прочитать несколько кнопок с помощью CD74HC4067?

This is the image of the schematic for the project I am working onЯ работаю над проектом с когтистой машиной. Я работаю над этим чипом (CD4067BE, который эквивалентен CD74HC4067), и мне было интересно: могу ли я прочитать более одной кнопки с помощью CD4067? Я попробовал следующий код, и он отлично работает, но когда я хочу нажать две кнопки, он не будет читать их как ноль. Почему я использую чип с кнопками? Это было сделано для того, чтобы уменьшить контакты ввода-вывода на моей печатной плате для когтистой машины. Да, я мог бы использовать матрицу, но я хочу контролировать свои компоненты, включать или выключать их. Кроме того, CD4067 включает в себя все мои кнопки. У меня тринадцать пуговиц. (13 пуговиц). Кстати, этот чип является мультиплексором/демультиплексором. Я использую этот чип в качестве мультиплексора. Да, и еще у меня есть Arduino Mega 2560 rev3. Я следовал инструкциям этого вопроса, но это не дает ответа, может ли чип одновременно считывать более кнопки. Спасибо,

Остин

//Управляющие контакты Mux
int s0 = 5;
int s1 = 4;
int s2 = 3;
int s3 = 2;


//Mux in "SIG" pin
int SIG_pin = 6;

void setup() {
  
  pinMode(s0, OUTPUT);
  pinMode(s1, OUTPUT);
  pinMode(s2, OUTPUT);
  pinMode(s3, OUTPUT);
  
  pinMode(SIG_pin, INPUT_PULLUP);

  Serial.begin(9600);
}

void loop() {

  //Перебрать и прочитать все 16 значений
  for (int i = 0; i < 16; i ++) {
    Serial.print("Value at channel ");
    Serial.print(i); 
    Serial.print("is : ");
    Serial.println(readMux(i));
    delay(1000);
  }
}

int readMux(int channel) {
  int controlPin[] =       {s0, s1, s2, s3};
  int muxChannel[16][4] = { {0, 0, 0, 0},
                            {1, 0, 0, 0},
                            {0, 1, 0, 0},
                            {1, 1, 0, 0},
                            {0, 0, 1, 0},
                            {1, 0, 1, 0},
                            {0, 1, 1, 0},
                            {1, 1, 1, 0},
                            {0, 0, 0, 1},
                            {1, 0, 0, 1},
                            {0, 1, 0, 1},
                            {1, 1, 0, 1},
                            {0, 0, 1, 1},
                            {1, 0, 1, 1},
                            {0, 1, 1, 1},
                            {1, 1, 1, 1}
                          };
  //цикл через 4 sig
  for (int i = 0; i < 4; i ++) {
    digitalWrite(controlPin[i], muxChannel[channel][i]);
  }
  //считывает значение на выводе SIG
  int val = digitalRead(SIG_pin); //возвращает значение
  return val;
}

, 👍2

Обсуждение

Нет никаких причин, почему его нельзя использовать так, как вы хотите. Вы не читаете две кнопки сразу, вы читаете только одну кнопку, остальные кнопки игнорируются. Однако у вас должно быть подтягивание на *каждой* кнопке, а не только на выводе ввода-вывода Arduino., @Majenko

Зачем кнопкам нужен подтягивающий резистор? Как мне читать более одной кнопки одновременно?, @Austin

Кнопки, которые не читаются в данный момент, будут плавающими. Тебе нужны подтягивания. Вы не читаете более одной кнопки одновременно. Вы читаете только одну кнопку. Существует только одна кнопка - кнопка, которая выбрана в данный момент. Все остальные кнопки не существуют., @Majenko

Если вы пройдете по входам мультиплексора, он прочитает все, что там есть-вы читаете только одну кнопку за раз, но если она достаточно быстрая, это не будет иметь значения. Иногда вы увидите схемы с мультиплексором, которые включают агрегированное прерывание, указывающее, что процессор должен считывать данные из мультиплексора., @Dave Newton

Можно ли использовать светодиоды вместо подтягивающих резисторов? Я читал об этом в этом уроке: https://www.baldengineer.com/arduino-keyboard-matrix-tutorial.html, @Austin

Итак, это "плавающее", это то же самое, что "ореолы" из этого учебника?, @Austin

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

Я не уверен, что это проблема-иметь плавающие контакты на аналоговом мультиплексоре. Может быть, когда-нибудь я проверю, есть ли более высокий ток, если оставить его несоединенным, но он ничего не переключает между двумя состояниями (а в КМОП-коммутации нужен ток), так что одного подтягивания на мультиплексированной стороне может быть достаточно. Может быть, при большей емкости линии он может получить несколько ложных нажатий при переключении на уровень вблизи gnd?, @KIIV

Да, я не совсем уверен, что значит плавающий, и до сих пор не понимаю разницы., @Austin

Ладно, я включу подтягивающие резисторы. Но я хочу знать, как мне прочитать несколько кнопок на чипе одновременно?, @Austin

Вы этого не делаете-вы читаете их по одному; вот что делает thismux-превращает *n* сигналов в один сигнал, который вы выбираете с помощью S0-S3. Опять же, если вы читаете их последовательно, с небольшой задержкой или без нее, это вряд ли имеет значение-компьютеры быстры, люди медленны., @Dave Newton

Итак, может быть, мне следует переключиться на матрицу, учитывая, что когда я читаю данные, даже быстро, они не будут работать для того, что я делаю. Итак, в принципе, я пытаюсь использовать джойстик и некоторые другие кнопки для работы с шаговыми двигателями (для управления ими) на моей когтистой машине. Но проблема в том, что когда я использую кнопку, она сканирует ее по отдельности. Таким образом, кнопки не были бы "гладкими", степперу пришлось бы ждать, пока он доберется до определенного канала. Другими словами, это будет ухабистая поездка., @Austin

Я думаю, что вы переоцениваете человеческие способности к восприятию или недооцениваете скорость компьютера., @Dave Newton

OT: Ваша функция readMux() будет более эффективной и быстрой, если вы определите константные массивы следующим образом: static const int controlPin[] = /*...*/; и static const int muxChannel[] = /*...*/;. В настоящее время эти переменные выделяются в стеке и инициализируются каждый раз, когда вы вызываете функцию., @the busybee

Я думаю, что вы неправильно понимаете концепцию мультиплексора. Его цель состоит в том, чтобы позволить нескольким сигналам совместно использовать один сигнал. Поэтому вы можете читать только по одному за раз. Если вы хотите читать их одновременно, вам понадобится расширитель ввода-вывода. Это позволит вам сэмплировать все сигналы одновременно по команде, а затем отправлять данные либо последовательно, либо параллельно на микроконтроллер., @tim

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

Хотя я хочу поблагодарить всех за помощь. Я знаю, что понимаю, что концепция мультиплексора заключается в чтении с одним выходом/входом. Таким образом, он ДОЛЖЕН читать его по одному, потому что мне не нужно дополнительное оборудование. Это было весело. Я опубликую ссылку на учебник для моей когтистой машины на форуме Arduino по адресу arduino.cc в ближайшем будущем. Большое вам спасибо!, @Austin


1 ответ


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

0

Альтернативный способ записи на 4-битные контакты MUX select-использовать сдвиг и маскировку, что-то вроде этого:

//
byte s0 = 2;
byte s1 = 3;
byte s2 = 4;
byte s3 = 5;
byte controlPin[] = { s0, s1, s2, s3 };

. . .

byte readMux(byte channel)
{
  // Цикл через 4 сигнала
  for (byte b = 0; b < 4; b++, channel >>= 1)
  {
    digitalWrite(controlPin[b], channel & 1);
  }
  // Считайте и возвращайте значение на SIG pin
  return digitalRead(SIG_pin);
}
,