Не редко в процессе разработки на arduino приходиться использовать больше количество пинов для считывания событий. Это могут быть кнопки, концевики, цифровые датчики и тд. Но ардуино имеет ограниченное количество пинов, что может стать проблемой для больших проектов. В этой статье описано, как выйти из ситуации с нехваткой входов arduino.
Добавление пинов arduino
Чтобы увеличить количество пинов есть несколько способов. Самый простой, это подключить кнопки или датчики к одному аналоговому пину через резисторы разного сопротивления, тогда в коде можно добавить условия для каждого уровня сигнала. Второй способ – использовать сдвиговый регистр, который позволяет принимать до восьми цифровых сигналов. А так же регистры можно выстраивать каскадами, один за другим, каждый раз добавляя 8 новых пинов.
Ниже будет рассмотрен второй вариант с использованием сдвигового регистра 74HC165. Я уже как-то описывал работу со сдвиговым регистром 74HC595, который может передавать данные. Сегодняшний регистр работает наоборот – принимает сигналы.
Подключение сдвигового регистра 74HC165 к arduino
Для подключения 74HC165 потребуется четыре пина ардуино, 5V и GND. Таким образом, при занятых четырех пинах появляется возможность считывать данные с восьми кнопок. А при составлении каскадов из регистров, количество возможных подключений кнопок, увеличивается на 8 штук, при тех же занятых 4х пинах. Ниже приведена схема подключения одного 74HC165 и восьми кнопок к arduino.
Каждая кнопка как обычно притянута к земле через резистор 10 кОм.
Примечание: Если количество кнопок будет меньше восьми, то свободные входы регистра нужно соединить с землей.
Пример использования 74HC165
В качестве примера я спаял а «макетке» простенький джойстик с восемью кнопками. А также напечатал для него простенький корпус на 3D принтере. Возможно, в следующих статьях и проектах он пригодится. Вот что получилось:
Скетч для arduino, который считывает данные с регистра 74HC165
В завершение прикладываю код, для считывания сигналов с регистра. Скетч с подробными комментариями, описывать что-то еще нет смысла, поэтому приведу просто листинг:
#define NUMBER_OF_SHIFT_CHIPS 1 // количество регистров #define DATA_WIDTH NUMBER_OF_SHIFT_CHIPS * 8 // количество входов #define PULSE_WIDTH_USEC 5 // задержка при считывании данных // для хранения считаных байт // если регистров больше двух, то int меняется на long #define BYTES_VAL_T unsigned int // пины для подключения регистра int ploadPin = 8; int clockEnablePin = 9; int dataPin = 11; int clockPin = 12; BYTES_VAL_T pinValues; // текущее значение пинов BYTES_VAL_T oldPinValues; // предыдущее значение пинов // функция для считывания пинов BYTES_VAL_T read_shift_regs() { long bitVal; BYTES_VAL_T bytesVal = 0; // опрашиваем регистр о состоянии пинов digitalWrite(clockEnablePin, HIGH); digitalWrite(ploadPin, LOW); delayMicroseconds(PULSE_WIDTH_USEC); digitalWrite(ploadPin, HIGH); digitalWrite(clockEnablePin, LOW); // считываем полученные данные о пинах for(int i = 0; i < DATA_WIDTH; i++){ bitVal = digitalRead(dataPin); bytesVal |= (bitVal << ((DATA_WIDTH-1) - i)); digitalWrite(clockPin, HIGH); delayMicroseconds(PULSE_WIDTH_USEC); digitalWrite(clockPin, LOW); } // возвращяем результат опроса регистра return(bytesVal); } // функция для вывода состояния пинов void display_pin_values(){ // перебор всех пинов for(int i = 0; i < DATA_WIDTH; i++){ Serial.print(" Button-"); Serial.print(i); Serial.print(": "); if((pinValues >> i) & 1){ Serial.print("ON"); }else{ Serial.print("OFF"); } Serial.println(); } Serial.println(); } void setup(){ // для вывода данных в монитор порта Serial.begin(9600); // установка режима работа пинов pinMode(ploadPin, OUTPUT); pinMode(clockEnablePin, OUTPUT); pinMode(clockPin, OUTPUT); pinMode(dataPin, INPUT); digitalWrite(clockPin, LOW); digitalWrite(ploadPin, HIGH); // считываем значения с пинов pinValues = read_shift_regs(); // выводим результат display_pin_values(); // сохраняем текущее значение oldPinValues = pinValues; } void loop(){ // считываем значения с пинов pinValues = read_shift_regs(); // если значения изменились, то выводим их if(pinValues != oldPinValues){ // выводим результат в монитор порта display_pin_values(); // сохраняем текущее значение oldPinValues = pinValues; } delay(50); }
Что использовалось:
- Arduino (я использовал arduino nano, но можно любую другую). Покупал тут: arduino nano
- Сдвиговый регистр 74HC165. Покупал тут: сдвиговые регистры 74HC165 10 штук
- Резисторы сопротивлением 10 кОм. Покупал тут:набор резисторов 700 шт. От 10 Ом до 1 МОм
- Тактовые кнопки 6x6x5мм. Покупал тут: Тактовые кнопки 6x6x5мм, 100шт
Послесловие
В этой статье не было описания составления каскадов из регистров. Если кому-то необходимо, то можете найти распиновку 74HC165 и самостоятельно собрать каскад. Подключается все довольно просто: необходимо соединить последовательный ввод SER одного регистра с последовательным выходом QH другого. Если кому-то тема интересна, то можете писать мне на почту или в комментарии, тогда я напишу отдельную статью про каскады из регистров.
С каскадным подключением более 4х штук начинаются большие проблемы. Единственное рабочее решение на 6 регистров нашёл тут — http://josvolkers.blogspot.com/2013/09/interpretator-orgelpatch-playnote.html и то с помощью костылика сделано.
Коллега! можно электрическую схему подключения