Problema con libreria MCP23S17

Ciao a tutti,
ho un problema con questa libreria, MCP23S17

Uso un arduino micro i pin sono correttamente collegati e come CS uso il pin SS.
Il primo chip ha i pin A0,A1,A2 a GND, mentre il secondo ha A0 a Vcc.

In pratica sembra non leggere l’indirizzamento.

Ecco il mio sketch!

/*
 Keyboard test

 */

#include <SPI.h>
#include <MCP23S17.h>
#include <Keyboard.h>

#define    CLOCK_DIVIDER (2)

String Command;

int TEST = 11;  // Lato P1
int SERVICE = 11;// Lato P2
int TILT = 12; // Lato P2

int UP = 1;
int DOWN = 2;
int LEFT = 3;
int RIGHT = 4;
int T1 = 5;
int T2 = 6;
int T3 = 7;
int T4 = 8;
int T5 = 9;
int T6 = 10;
int START = 15;
int COIN = 16;


MCP P_ONE(1,SS);
MCP P_TWO(2,SS);

void setup() {
  SPI.begin();
  SPI.setClockDivider(CLOCK_DIVIDER);
  Serial.begin(9600); // Attivo porta seriale arduino a 9600baud/s
  //  while (!Serial) {
  //  ; // wait for serial port to connect. Needed for native USB
  //}
  Keyboard.begin(); // Inizializzo la tastiera
  
  P_ONE.pinMode(0xFFFF); //Abilita tutti i pin come input
  P_ONE.pullupMode(0xFFFF); //Attiva il pullup su tutti i pin
  P_TWO.pinMode(0xFFFF); //Abilita tutti i pin come input
  P_TWO.pullupMode(0xFFFF); //Attiva il pullup su tutti i pin
  
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH);
  Serial.write("Inizializzazione completa!");
}

void loop() {
  if (P_ONE.digitalRead(UP) == LOW) { Keyboard.write(218); } // Freccia SU
  if (P_ONE.digitalRead(DOWN) == LOW) { Keyboard.write(217); } // Freccia GIU
  if (P_ONE.digitalRead(LEFT) == LOW) { Keyboard.write(216); } // Freccia SX
  if (P_ONE.digitalRead(RIGHT) == LOW) { Keyboard.write(215); } // Freccia DX
  if (P_ONE.digitalRead(T1) == LOW) { Keyboard.write(90); } // Tasto Z
  if (P_ONE.digitalRead(T2) == LOW) { Keyboard.write(88); } // Tasto X
  if (P_ONE.digitalRead(T3) == LOW) { Keyboard.write(65); } // Tasto A
  if (P_ONE.digitalRead(T4) == LOW) { Keyboard.write(83); } // Tasto S
  if (P_ONE.digitalRead(T5) == LOW) { Keyboard.write(81); } // Tasto Q
  if (P_ONE.digitalRead(T6) == LOW) { Keyboard.write(87); } // Tasto W
  if (P_ONE.digitalRead(START) == LOW) { Keyboard.write(53); } // Tasto 5
  if (P_ONE.digitalRead(COIN) == LOW) { Keyboard.write(49); } // Tasto 1
  
  if (P_TWO.digitalRead(UP) == LOW) { Keyboard.write(82); }  // Tasto R
  if (P_TWO.digitalRead(DOWN) == LOW) { Keyboard.write(70); } // Tasto F
  if (P_TWO.digitalRead(LEFT) == LOW) { Keyboard.write(68); } // Tasto D
  if (P_TWO.digitalRead(RIGHT) == LOW) { Keyboard.write(71); } // Tasto G
  if (P_TWO.digitalRead(T1) == LOW) { Keyboard.write(78); } // Tasto N
  if (P_TWO.digitalRead(T2) == LOW) { Keyboard.write(77); } // Tasto M
  if (P_TWO.digitalRead(T3) == LOW) { Keyboard.write(72); } // Tasto H
  if (P_TWO.digitalRead(T4) == LOW) { Keyboard.write(74); } // Tasto J
  if (P_TWO.digitalRead(T5) == LOW) { Keyboard.write(89); } // Tasto Y
  if (P_TWO.digitalRead(T6) == LOW) { Keyboard.write(85); } // Tasto U
  if (P_TWO.digitalRead(START) == LOW) { Keyboard.write(54); } // Tasto 6
  if (P_TWO.digitalRead(COIN) == LOW) { Keyboard.write(50); } // Tasto 2
  
  if (P_ONE.digitalRead(TEST) == LOW) { Keyboard.write(56); } // Tasto 8
  if (P_TWO.digitalRead(SERVICE) == LOW) { Keyboard.write(57); } // Tasto 9
  if (P_TWO.digitalRead(TILT) == LOW) { Keyboard.write(194); } // Tasto F1
  
  delay(50);
  
}

Qualche consiglio?

Ho anche fatto una prova senza la libreria ma niente!!!

/*
 Keyboard test

 */

#include <SPI.h>
#include <Keyboard.h>

byte P1 = B000;
byte P2 = B001;

#define    ADDR_ENABLE   (0b00001000)
#define    IODIRA    (0x00)
#define    IODIRB    (0x01)
#define    IOCON     (0x0A)
#define    GPPUA     (0x0C)
#define    GPPUB     (0x0D)

String Command;

int TEST = 11;  // Lato P1
int SERVICE = 11;// Lato P2
int TILT = 12; // Lato P2

int UP = 1;
int DOWN = 2;
int LEFT = 3;
int RIGHT = 4;
int T1 = 5;
int T2 = 6;
int T3 = 7;
int T4 = 8;
int T5 = 9;
int T6 = 10;
int START = 15;
int COIN = 16;

void byteWrite(byte addr, uint8_t reg, uint8_t value) {      // Accept the register and byte
  digitalWrite(SS, LOW);                            // Take slave-select low
  SPI.transfer(B01000000 | addr<<1 | 0<<0);             // 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
  digitalWrite(SS, HIGH);                           // Take slave-select high
}

void wordWrite(byte addr, uint8_t reg, unsigned int word) {  // Accept the start register and word 
  digitalWrite(SS, LOW);                            // Take slave-select low
  SPI.transfer(B01000000 | addr<<1 | 0<<0);             // Send the MCP23S17 opcode, chip address, and write bit
  SPI.transfer(reg);                                   // Send the register we want to write 
  SPI.transfer((uint8_t) (word));                      // Send the low byte (register address pointer will auto-increment after write)
  SPI.transfer((uint8_t) (word >> 8));                 // Shift the high byte down to the low byte location and send
  digitalWrite(SS, HIGH);                           // Take slave-select high
}

void setup() {
  SPI.begin();
  SPI.setClockDivider(SPI_CLOCK_DIV8);
  byteWrite(P1, IOCON, ADDR_ENABLE);
  byteWrite(P2, IOCON, ADDR_ENABLE);
  wordWrite(P1, IODIRA, 0xFFFF);
  wordWrite(P2, IODIRA, 0xFFFF);
  wordWrite(P1, GPPUA, 0xFFFF);
  wordWrite(P2, GPPUA, 0xFFFF);
  
  Serial.begin(9600); // Attivo porta seriale arduino a 9600baud/s
  //  while (!Serial) {
  //  ; // wait for serial port to connect. Needed for native USB
  //}
  Keyboard.begin(); // Inizializzo la tastiera
  
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH);
  Serial.write("Inizializzazione completa!");
}

uint8_t leggistato(byte addr, int pin) {
  unsigned int value = 0;                   // Initialize a variable to hold the read values to be returned
  digitalWrite(SS, LOW);                 // Take slave-select low
  SPI.transfer(B01000000 | addr<<1 | 1<<0);  // MCP23S17_READ  = B0100AAA1 
  Serial.println(B01000000 | addr<<1 | 1<<0, BIN);
  SPI.transfer(0x12);                      // Send the register we want to read
  value = SPI.transfer(0x00);               // Send any byte, the function will return the read value (register address pointer will auto-increment after write)
  value |= (SPI.transfer(0x00) << 8);       // Read in the "high byte" (portB) and shift it up to the high location and merge with the "low byte"
  digitalWrite(SS, HIGH);                // Take slave-select high
  if (pin < 1 | pin > 16) return 0x0;                   // If the pin value is not valid (1-16) return, do nothing and return
  Serial.print(addr);
  Serial.print("-");
  Serial.println(value, BIN);
  //delay(500);
  //return HIGH;
  return value & (1 << (pin - 1)) ? HIGH : LOW;  // Call the word reading function, extract HIGH/LOW information from the requested pin
}

void loop() {
  if (leggistato(P1, UP) == LOW) { Keyboard.write(218); } // Freccia SU
  if (leggistato(P1, DOWN) == LOW) { Keyboard.write(217); } // Freccia GIU
  if (leggistato(P1, LEFT) == LOW) { Keyboard.write(216); } // Freccia SX
  if (leggistato(P1, RIGHT) == LOW) { Keyboard.write(215); } // Freccia DX
  if (leggistato(P1, T1) == LOW) { Keyboard.write(90); } // Tasto Z
  if (leggistato(P1, T2) == LOW) { Keyboard.write(88); } // Tasto X
  if (leggistato(P1, T3) == LOW) { Keyboard.write(65); } // Tasto A
  if (leggistato(P1, T4) == LOW) { Keyboard.write(83); } // Tasto S
  if (leggistato(P1, T5) == LOW) { Keyboard.write(81); } // Tasto Q
  if (leggistato(P1, T6) == LOW) { Keyboard.write(87); } // Tasto W
  if (leggistato(P1, START) == LOW) { Keyboard.write(53); } // Tasto 5
  if (leggistato(P1, COIN) == LOW) { Keyboard.write(49); } // Tasto 1
  
  if (leggistato(P2, UP) == LOW) { Keyboard.write(82); }  // Tasto R
  if (leggistato(P2, DOWN) == LOW) { Keyboard.write(70); } // Tasto F
  if (leggistato(P2, LEFT) == LOW) { Keyboard.write(68); } // Tasto D
  if (leggistato(P2, RIGHT) == LOW) { Keyboard.write(71); } // Tasto G
  if (leggistato(P2, T1) == LOW) { Keyboard.write(78); } // Tasto N
  if (leggistato(P2, T2) == LOW) { Keyboard.write(77); } // Tasto M
  if (leggistato(P2, T3) == LOW) { Keyboard.write(72); } // Tasto H
  if (leggistato(P2, T4) == LOW) { Keyboard.write(74); } // Tasto J
  if (leggistato(P2, T5) == LOW) { Keyboard.write(89); } // Tasto Y
  if (leggistato(P2, T6) == LOW) { Keyboard.write(85); } // Tasto U
  if (leggistato(P2, START) == LOW) { Keyboard.write(54); } // Tasto 6
  if (leggistato(P2, COIN) == LOW) { Keyboard.write(50); } // Tasto 2

  if (leggistato(P1, TEST) == LOW) { Keyboard.write(56); } // Tasto 8
  if (leggistato(P2, SERVICE) == LOW) { Keyboard.write(57); } // Tasto 9
  if (leggistato(P2, TILT) == LOW) { Keyboard.write(194); } // Tasto F1
  
  delay(50);
  
  // Possibile agguingere programmazione led via seriale
  // Pin disponibili da D4 a D13 e da A0 a A5
  if (Serial.available() > 0) {
    Command = Serial.read();
    }

 if (Command == 1) { // Accendo i 4 led dei tasti
  //Serial.write("0k");
  digitalWrite(4, HIGH);
  digitalWrite(5, HIGH);
  digitalWrite(6, HIGH);
  digitalWrite(13, HIGH);
 }
  
  
}

Quando mando a gnd un qualsiasi pin del primo ic, la lettura del secondo va in tilt!!!

  1. presentati
    Eessendo il tuo primo post, nel rispetto del regolamento (… punto 13, primo capoverso), ti chiedo cortesemente di presentarti QUI (spiegando bene quali conoscenze hai di elettronica e di programmazione ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con MOLTA attenzione il su citato REGOLAMENTO ... Grazie.

  2. il ATmega32U4 non ha la SPI sugli stessi piedini come il ATmega238.

Ciao Uwe

Ciao e grazie per la risposta!
L'arduino micro ha i pin dedicati al protocollo SPI direttamente sull'header ICSP oppure su piedinatura nel lato opposto all'usb.
Infatti io ho collegati pin su piedinatura e ho usato il pin dedicato al RXLED come CS!
Se uso un solo MCP23S17 funziona tutto benissimo, ma come collego il secondo mi crea problemi.
Non posso usare nessun altro pin come CS (così da avere la doppia abilitazione), sono già tutti usati!

A qualcuno è capitato qualcosa di simile?

Hai settato a 1 il bit HAEN del registro IOCON dell'MCP? Devi farlo come prima cosa.

Grazie per la risposta!
Con la libreria dovrebbe settarsi automaticamente(giusto?), mentre nel mio sketch ho fatto così:

#define    ADDR_ENABLE   (0b00001000)
#define    IOCON     (0x0A)
void byteWrite(byte addr, uint8_t reg, uint8_t value) {      // Accept the register and byte
  digitalWrite(SS, LOW);                            // Take slave-select low
  SPI.transfer(B01000000 | addr<<1 | 0<<0);             // 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
  digitalWrite(SS, HIGH);                           // Take slave-select high
}

poi nel void setup:

void setup() {
  SPI.begin();
  byteWrite(P1, IOCON, ADDR_ENABLE);
  byteWrite(P2, IOCON, ADDR_ENABLE);

Dovrebbe essere corretto!?

Sembra tutto corretto, anche se non sono un esperto del pilotaggio a basso livello di questo chip, mi fido della libreria ;).

L’unica cosa che suggerisco è di mettere qualche parentesi in più qui:

SPI.transfer(B01000000 | (addr<<1) | (0<<0));

A volta l’associatività degli operatori che lavorano sui bit fa brutti scherzi, ma non so se sia questo il caso.

Ho provato, niente da fare!
Ho anche controllato di essere con entrambi in BANK 0, non so più cosa fare!!!
Qualche altro consiglio?

>vincenzobini: in conformità al REGOLAMENTO, punto 13, il cross-posting è proibito (anche tra lingue diverse) e tu hai posto la stessa domanda in una sezione dell'area Inglese.

Dato che è in violazione del regolamento, tale tua domanda duplicata è stata rimossa e ti prego di prestare più attenzione al su citato regolamento. Grazie.

Guglielmo