Hi,
I am creating a state machine using 36 switches mounted on 12 ports (3swich x port) connected on 5 shiftreg 74hc165 named from U1 to U5, the latter are connected in chain using ports 9 and 10 and connected to the MISO port of the Adafruit M0, therefore I use the SPI protocol. The first in the chain is U5 on which the last 4 switches are connected (one for port 11 and 3 for port 12).
If I use this sketch to check the connections it works correctly:
#include <SPI.h>
const byte LATCH = A5;
//const byte INTER = D1;
const byte chips = 5; // number of 74HC165 (8bit) chips used(18)
static unsigned long lastMillis;
static unsigned long frameCount;
static unsigned int framesPerSecond;
const int seconds = 1;
// FIXME: finish interrupt support ...
void setup()
{
SPI.begin ();
SPI.beginTransaction(SPISettings(3000000, MSBFIRST, SPI_MODE2)); // 32MHz
Serial.begin(115200);
pinMode (LATCH, OUTPUT);
digitalWrite (LATCH, HIGH);
}
void loop() {
unsigned long now = millis();
frameCount ++; // Once around the moon ...
byte Switch[chips];
digitalWrite (LATCH, LOW);
digitalWrite (LATCH, HIGH);
for (byte i = 0; i < chips; i++)
{
Switch[i] = SPI.transfer(0);
}
if (now - lastMillis >= seconds * 1000) {
framesPerSecond = frameCount / seconds;
for (byte i = 0; i < 8; i++) {
Serial.print((Switch[0] & (1 << i)) != 0 ? 1 : 0);
}
Serial.print(" ");
for (byte i = 0; i < 8; i++) {
Serial.print((Switch[1] & (1 << i)) != 0 ? 1 : 0);
}
Serial.print(" ");
for (byte i = 0; i < 8; i++) {
Serial.print((Switch[2] & (1 << i)) != 0 ? 1 : 0);
}
Serial.print(" ");
for (byte i = 0; i < 8; i++) {
Serial.print((Switch[3] & (1 << i)) != 0 ? 1 : 0);
}
Serial.print(" ");
for (byte i = 0; i < 8; i++) {
Serial.print((Switch[4] & (1 << i)) != 0 ? 1 : 0);
}
Serial.print(" ");
Serial.print(framesPerSecond);
Serial.println(" fps");
frameCount = 0;
lastMillis = now;
}
}
However, if I use this sketch it does not detect the status of the switches connected to the U5 chip, therefore one on port 11 and three on port 12.
If I change the number of chips from 5 to 4 the numbering moves starting from U2 and ends regularly on U5 clearly missing ports 11 and 12 as above.
I also tried to shorten the chain by connecting the ICs to the bus one after the other and the problem always recurs with the aforementioned ports.
#include <SPI.h>
const int latchPin = A5; // Pin di latch
const byte numShiftRegisters = 5; // Numero di shift register utilizzati
const byte numPorts = 12; // Numero totale di porte
const byte switchesPerPort = 3; // Numero di interruttori per ogni porta
unsigned long currentState = 0;
unsigned long previousState = 0;
void setup() {
Serial.begin(115200);
pinMode(latchPin, OUTPUT);
digitalWrite (latchPin, HIGH);
SPI.begin();
SPI.beginTransaction(SPISettings(3000000, MSBFIRST, SPI_MODE2)); // Configura SPI
}
void loop() {
readInputs();
updateStateMachine();
}
void readInputs() {
digitalWrite(latchPin, LOW);
delayMicroseconds(5); // Assicura la stabilità del segnale
digitalWrite(latchPin, HIGH);
currentState = 0;
for (int i = 0; i < numShiftRegisters ; ++i) {
//for (int i = numShiftRegisters - 1; i >= 0; --i) {
currentState <<= 8;
currentState |= SPI.transfer(0);
}
}
void updateStateMachine() {
if (currentState != previousState) {
for (int port = 0; port < numPorts; ++port) {
int startIndex = port * switchesPerPort ;
int portState = (currentState >> startIndex) & 0b111;
switch (portState) {
case 0b000: // Tutti gli interruttori sono spenti
Serial.println("Porta " + String(port + 1) + ": Nessun interruttore attivo");
break;
case 0b001: // Solo il primo interruttore è attivo
Serial.println("Porta " + String(port + 1) + ": Solo In attivo");
break;
case 0b010: // Solo il secondo interruttore è attivo
Serial.println("Porta " + String(port + 1) + ": Solo Middle attivo");
break;
case 0b011: // Primo e secondo interruttore sono attivi
Serial.println("Porta " + String(port + 1) + ": In e Middle attivi");
break;
case 0b100: // Solo il terzo interruttore è attivo
Serial.println("Porta " + String(port + 1) + ": Solo Out attivo");
break;
case 0b101: // Primo e terzo interruttore sono attivi
Serial.println("Porta " + String(port + 1) + ": In e Out attivi");
break;
case 0b110: // Secondo e terzo interruttore sono attivi
Serial.println("Porta " + String(port + 1) + ": Middle e Out attivi");
break;
case 0b111: // Tutti gli interruttori sono attivi
Serial.println("Porta " + String(port + 1) + ": Tutti gli interruttori attivi");
break;
}
}
previousState = currentState;
}
}
Any idea?? Thankyou