Sto creando una macchina a stati utilizzando36 switch montati su 12 porte ( 3swich x porta) collegati su 5 shiftreg 74hc165 nomenclati da U1 a U5 , questi ultimi sono collegati in catena utilizzando le porte 9 e 10 e connessi alla porta MISO del Adafruit M0, quindi utilizzo il protocollo SPI . Il primo della catena è U5 su cui sono connessi gli ultimi 4 interruttori ( uno per la porta 11 e 3 per la porta 12).
Se utilizzo questo sketch per la verifica delle connessioni funziona correttamente:
#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;
}
}
Se invece utilizzo questo sketch non mi rileva lo stato degli switch collegati sul chip U5 quindi uno della porta 11 e tre della porta 12.
Se modifico il numero dei chip da 5 a 4 la numerazione si sposta iniziando da U2 e finisce regolarmente sul U5 chiaramente mancando le porte 11 e 12 come sopra.
Ho provato anche a accorciare la catena collegando gli integrati al bus uno dopo l'altro e il problema si ripresenta sempre con le porte sopracitate.
#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;
}
}
Qualche idea ???