MCP23S17 per comandare dei relay

gamby:
Grazie dei suggerimenti.

La libreria funziona in diverse modalità:

  • Impostando un pin per volta, ed i pin sono numerati da 1 a 16
  • Impostando tutti i pin in un solo colpo con una stringa di 16 bit (esempio 0B1111111111111111 per impostare tutti i pin a HIGH) oppure con una word esadecimale (0xFF se non ricordo male per tutti HIGH).
    Non ho ancora ben chiaro se ci siano anche altri modi di funzionamento. Sono partito da questi perchè sono i più semplici e proprio per questo non vedo perchè non dovrebbero funzionare.
    Ho già fatto anche un po' di prove per eccitare tutto insieme, o un pin singolo, o una sequenza. Ieri sera ho anche provato senza relay, solo con led e resistenze collegati ad un singolo pin. Il risultato è sempre lo stesso... Alcuni pin vanno, altri no, il tutto sempre in modo molto instabile.

L'unica prova che devo ancora fare è sostituire i cavetti del bus SPI con qualcosa di schermato, ma ho i miei dubbi che sia una cosa risolutiva perchè a quanto pare il bus trasmette correttamente... Comunque potrebbe essere un passo avanti per rendere il tutto più stabile.

Si ok la libreria ti da l'impressione di poter gestire il 23S17 in modo diverso, ma è una impressione o è la realtà?

Nel datasheet c'è anche scritto che è possibile impostare la polarità per ogni pin di GPIO, quindi se metti alto un pin in uscita avrai 1 negato cioè zero. Queste cose la lib non le gestisce.

Comunque, la lib che ho guardato io usa l'include:

#include <SPI.h>                 // Arduino IDE SPI library - uses AVR hardware SPI features
#include "MCP23S17.h"            // Header files for this class

Nel codice di esempio non c'è necessità di includere nuovamente SPI.
Per ultimo una cosa molto importante:

#define    SS            (10)          // SPI bus slave select output to pin 10 - READ ARDUINO SPI DOCS BEFORE CHANGING!!!

SS è definito ma non usato nella lib, in sua vece c'è una costante numerica espressa in binario, questo è il codice:

// GENERIC BYTE WRITE - will write a byte to a register, arguments are register address and the value to write

void MCP::byteWrite(uint8_t reg, uint8_t value) {      // Accept the register and byte
  PORTB &= 0b11111011;                                 // Direct port manipulation speeds taking Slave Select LOW before SPI action
  SPI.transfer(OPCODEW | (_address << 1));             // Send the MCP23S17 opcode, chip address, and write bit
  SPI.transfer(reg);                                   // Send the register we want to write
  SPI.transfer(value);                                 // Send the byte
  PORTB |= 0b00000100;                                 // Direct port manipulation speeds taking Slave Select HIGH after SPI action
}

Guarda caso PORTB |= 0b00000100 è il digital pin 10 di arduino 2009/UNO, che corrisponde al pin SS (16) del 328.

Ora tu devi cambiare sia porta che valore fino a selezionare il pin 53 della MEGA e questi cambiamenti li devi fare su tutta la lib.

Poi c'è ancora una cosa che non ho capito, il 23S17 ha dei pin chiamati A0, A1, A2 che possono essere disabilitati o abilitati, sono abilitati di default nella versione I2C perchè manca il bit HAEN e disabilitati per la versione ISP ma abilitabili grazie ad HAEN.

Il documento che ho consultato e questo che è valido per entrambe le versioni ISP e I2C, alla pagina 18 c'è la descrizine di importati bit.
DS21952B-page 18

Ciao.