
Zdravím vás, kutilové a výzkumníci.
Dnes vám předkládám svoji verzi rozšiřování digitálních vstupů pro Arduino Nano.
Použil jsem hojně rozšířený obvod 74hc165. Na internetu se dočtete v mnoha diskusích, jaké jsou problémy s časováním, použití knihoven a podobně, proto zde předkládám použití bez knihoven a jednoduchý příklad.
Schéma zapojení mého modulu:

Jak můžete vidět na obrázku níže, rozmístění vstupů je takové, aby šly připojit moduly, které potřebují „servo“ napájení: zem-plus-signál (8 vstupů), přepínače pro nastavování parametrů programu (4 vstupy) a vstupy pro spínače proti zemi (gnd) s pomocnými tlačítky, když si třeba potřebujete ověřit nějakou funkčnost při ladění (4 vstupy).
Moduly se dají řetězit, limitem je jen paměť použitého procesoru/arduina. Počet čipů nastavujete na začátku programu nebo si můžete nastavit i dynamické rozšiřování pomocí Jumperů či DipSwitchů – přepínačů.
Možná vás překvapil druhý konektor na vstup – ten je jen kvůli tomu, kdybyste potřebovali připojit kabeláž z druhé strany. Pokud byste použili oba najednou, nic neshoří – je použit ochranný odpor, ale nebude to fungovat správně. Řekl bych prapodivně, někdy vyzkouším 🙂
Velikost desky je 60x30mm, v případě zájmu se můžeme domluvit 😉

/* název souboru: shift_in_165x2_test3
* použit obvod: SN74HC165N
* inspirace: https://dduino.blogspot.com/2012/04/arduino-74hc165-psio-shift-regsiter.html
*
* upravil a odladil: L. Vohralík, MerkurRobot.cz, (c)2025
*
*/
// Počet zapojených posuvných registrů 74HC165
#define NUMBER_OF_SHIFT_CHIPS 6
// Zpoždění v mikrosekundách pro signály
#define PULSE_WIDTH_USEC 5
// Interval mezi čteními v milisekundách
#define CEKEJ 100
// Připojení pinů k Arduinu
int dataPin = 2; // Výstup Q7 z 74HC165
int ploadPin = 3; // Paralelní načtení (LOAD)
int clockPin = 4; // Hodinový vstup (CLOCK)
// Pole pro uchování hodnot z registrů
byte vstupy[NUMBER_OF_SHIFT_CHIPS];
// Funkce pro načtení hodnot z řetězce 74HC165
void read_shift_regs()
{
byte bitVal;
byte bytesVal = 0;
// Spustit paralelní načtení – zachycení stavu vstupů
digitalWrite(ploadPin, LOW);
delayMicroseconds(PULSE_WIDTH_USEC);
digitalWrite(ploadPin, HIGH);
// Postupné načítání jednotlivých bajtů z registrů
for (int j = 0; j < NUMBER_OF_SHIFT_CHIPS; j++) {
bytesVal = 0;
for (int i = 0; i < 8; i++) {
bitVal = digitalRead(dataPin);
bytesVal |= (bitVal << (7 - i)); // Uložení bitu do bajtu (MSB první)
// Taktování hodin – přechod na další bit
digitalWrite(clockPin, HIGH);
delayMicroseconds(PULSE_WIDTH_USEC);
digitalWrite(clockPin, LOW);
}
vstupy[j] = bytesVal; // Uložení načteného bajtu do pole
}
}
// Výpis hodnot všech vstupů do Serial monitoru
void display_pin_values()
{
for (int j = 0; j < NUMBER_OF_SHIFT_CHIPS; j++) {
for (int i = 0; i < 8; i++) {
if ((vstupy[j] >> i) & 1)
Serial.print("|"); // Logická 1
else
Serial.print("-"); // Logická 0
}
Serial.print(".");
}
Serial.println();
}
// Funkce vrátí hodnotu vstupu podle pořadí od procesoru (0 = nejbližší bit od MCU)
bool vstup(int cislo_vstupu)
{
if (cislo_vstupu < 0 || cislo_vstupu >= NUMBER_OF_SHIFT_CHIPS * 8)
return false; // mimo rozsah, bezpečnostní kontrola
int index = cislo_vstupu / 8; // který čip (bajt)
int bit_pozice = cislo_vstupu % 8; // který bit v bajtu (0 = LSB, 7 = MSB)
return (vstupy[index] >> bit_pozice) & 1;
}
// setup ****************************************************************************
void setup()
{
Serial.begin(115200);
pinMode(ploadPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, INPUT);
digitalWrite(clockPin, LOW);
digitalWrite(ploadPin, HIGH);
display_pin_values(); // První výpis hodnot po startu
}
// loop ****************************************************************************
void loop()
{
read_shift_regs(); // Načtení hodnot ze všech registrů
display_pin_values(); // Výpis na sériový monitor
if (vstup(0)) {
Serial.print("Vstup 0 je HIGH");
} else {
Serial.print("Vstup 0 je LOW");
}
delay(CEKEJ);
}
