RISOLTO : Problema con 5 shiftreg 74HC165

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 ???

Buongiorno e benvenuto nella sezione Italiana del forum,

cortesemente, come prima cosa, leggi attentamente il REGOLAMENTO di detta sezione, (... e, per evitare future possibili discussioni/incomprensioni, prestando molta attenzione al punto 15), dopo di che, come da suddetto regolamento (punto 16.7), fai la tua presentazione NELL'APPOSITA DISCUSSIONE (... quello che vedi in blu è un link, fai click su di esso per raggiungere la discussione) spiegando bene quali esperienze hai in elettronica e programmazione, affinché noi possiamo conoscere la tua esperienza ed esprimerci con termini adeguati.

Grazie,

Guglielmo

P.S.: Ti ricordo che, purtroppo, fino a quando non sarà fatta la presentazione nell’apposita discussione, nel rispetto del succitato regolamento nessuno ti risponderà (eventuali risposte o tuoi ulteriori post, verrebbero temporaneamente nascosti), quindi ti consiglio di farla al più presto. :wink:

Ciao, scusa ma ero convinto di averlo già fatto....
Grazie

Risolto!!!
Grazie.

Se hai risolto, spiega come ... un giorno potrebbe essere utile a qualche utente che fa una ricerca e capita sulla tua discussione :wink:

Guglielmo

Il problema era qui:

il comando unsigned long gestisce solo 4 bytes e quindi:

non poteva funzionare in quanto gli switch sono 5;
modificato quindi anziche unsigned long in uint64_t.
Avevo provato in precedenza uint8_t ma non funzionava.

Grazie alla dritta di alto777.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.