Come da titolo, ho diversi pca9555n della NXP. Sono dei port expander a 16bit i2c con 3 bit di indirizzo programmabili. Ovvero se metto A0=A1=A2 =0 l'indirizzo i2c di quell'integrato sarà 0100 000.
Detto questo sto cercando di far funzionare questo integrato, ma sto impazzendo!
Ho trovato questo sito http://www.neufeld.newton.ks.us/electronics/?p=241 con del codice utile. Guardiamolo insieme
#include <Wire.h>
//#define DEBUG_GPIO
// I2C device address is 0 1 0 0 A2 A1 A0
#define DIP_ADDRESS (0x4 << 3 | 0x0)
#define LED_ADDRESS (0x4 << 3 | 0x7)
Si creano gli indirizzi, shiftando di 3 a sinistra e facendo un or con 07
Nel mio codice ho messo l'indirizzo grezzo
#define GPIO1(0x27) ovvero 0100111
void setup() {
#ifdef DEBUG_GPIO
Serial.begin(9600);
//Serial.println(DIP_ADDRESS); delay(2000);
#endif
//inizializza in uscita il port dei gpio
Wire.begin();
gpio_write(LED_ADDRESS, 0xffff);
gpio_dir(LED_ADDRESS, 0x0000);
}
Qui non mi tornano 2-3 cose, sto #ifdef a cosa serve? Poi vabbè inizializza nel modo classico la i2c e inizializza il pca9555
void loop() {
int bits;
#ifdef DEBUG_GPIO
Serial.println(0xff & gpio_read(DIP_ADDRESS));
#endif
bits = gpio_read(DIP_ADDRESS) & 0x0f;
// mirror direction of bits for output display
gpio_write(LED_ADDRESS,
(
((bits & 1) << 3) | ((bits & 2) << 1) |
((bits & 4) >> 1) | ((bits & 8) >> 3)
) << 12);
#ifdef DEBUG_GPIO
delay(200);
#endif
}
Qui legge da DIP e scrive ciò che legge in LED. A dip sono collegati degli interruttori ed è configurato in modalità input, mentre l'altro è configurato in output.
#define REGISTER_INPUT (0)
#define REGISTER_OUTPUT (2)
#define REGISTER_CONFIG (6)
queste sono definizioni che vengono direttamente dal datasheet.
int gpio_read(int address) {
int data = 0;
// Send input register address
Wire.beginTransmission(address);
Wire.send(REGISTER_INPUT);
Wire.endTransmission();
// Connect to device and request two bytes
Wire.beginTransmission(address);
Wire.requestFrom(address, 2);
if (Wire.available()) {
data = Wire.receive();
}
if (Wire.available()) {
data |= Wire.receive() << 8;
}
Wire.endTransmission();
return data;
}
Funzione per leggere
void gpio_dir(int address, int dir) {
// Send config register address
Wire.beginTransmission(address);
Wire.send(REGISTER_CONFIG);
// Connect to device and send two bytes
Wire.send(0xff & dir); // low byte
Wire.send(dir >> 8); // high byte
Wire.endTransmission();
}
Questo sinceramente non l'ho capito
void gpio_write(int address, int data) {
// Send output register address
Wire.beginTransmission(address);
Wire.send(REGISTER_OUTPUT);
// Connect to device and send two bytes
Wire.send(0xff & data); // low byte
Wire.send(data >> 8); // high byte
Wire.endTransmission();
}
e in questa funzione scrive.
Io vorrei solo far blinkare qualche led. Avete un'idea?
dire REGISTER_OUTPUT(2); vuol dire che il port 0 è impostato come output mentre per impostare il port 1 il valore del registro di controllo è REGISTER_OUTPUT(3);.