Arduino UNO PCF8575TS 16-Bit I/O Expander

Aruino UNO R3
2x PCF8575

I thake 10 inputs per PCF
if i go with the GND to the pins of 0x20 everything is working fine
for 0x22 1 to 5 work but 6 to 10 dont

if i change 0x22 to 0x20 and 0x20 to 0x22 the hole problem shifts to the other device

it is always the second one in the Array PCF[2]{ 0x20 , 0x22 };

does anyone know the origin of the problem

if i read out the value of short DatenInB; the value goes to "-1?"

#include <AccelStepper.h>
#include <Wire.h>
#include <EEPROM.h>

#define Start 10  // Start
#define Reset 11  // Reset

const int Null[4] {(12),(A0),(A2),(A4)};  // Motor Endschalter 0
const int Max[4] {(13),(A1),(A3),(A5)};   // Motor Endschalter Max

const uint8_t PCF[2]{ 0x20 , 0x22 };
const uint8_t Slaves[2]{ 0x90 , 0x91 };

AccelStepper Mot[4][3] { {2, 2, 3} , {2, 4, 5} , {2, 7, 6} , {2, 8, 9} };

int MotMax[4]; // Motor Maximalwert
int pos[4]; // Berechnete Motorposition
const int Offset = 200; // Einzug für Max und Min

int punkteSpieler[4];
const int Maximalpunktzahl = 60;
int Gewinner = 0;

bool Status[2]; // Vorlauf , Spiel

bool Ein[20];
bool Neu[12];
bool Alt[12];
short DatenInA;
short DatenInB;

unsigned long Zeitspeicher[2];
const unsigned long VorlaufZeit[2] { 5000 , 2000 };

void setup() {

  Serial.begin(9600);

  Wire.begin();

  for (int i = 0; i < 2; i++) {
    Wire.beginTransmission(PCF[i]);
    Wire.write(0xFFFF);
    Wire.endTransmission();
  }

  pinMode(Start, INPUT_PULLUP);
  pinMode(Reset, INPUT_PULLUP);

//  MotorEndpunkteKalibrieren();

}


void loop() {

  while (Status[1]) {
    if (digitalRead(Reset) == LOW) {
      for (int i = 0; i < 4; i++) { punkteSpieler[i] = 0; }
      Status[1] = false;
    }
    ReadIn1();
    ReadIn2();
    Punkte();
    led();
    Motor();
Serial.println(punkteSpieler[0]);
Serial.println(punkteSpieler[1]);
Serial.println(punkteSpieler[2]);
Serial.println(punkteSpieler[3]);
delay(1000);
  }  

  while (Status[0]) {
    if (millis() - Zeitspeicher[0] >= VorlaufZeit[0]) {
      Status[1] = true;
      Status[0] = false;
    }
    led();
    Motor();
  }
  while (!Status[0] && !Status[1]) { 
    if (digitalRead(Start) == LOW) {
      for (int i = 0; i < 4; i++) {
        Zeitspeicher[0] = millis();
        punkteSpieler[i] = 0;
        Status[0] = true;
      }
    led();
    Motor();
    }
  }
}
void ReadIn1() {

  Wire.beginTransmission((uint8_t)PCF[0]);
  Wire.requestFrom((uint8_t)PCF[0],(uint8_t) 2);
    if (Wire.available() >= 2) { 
      byte lowByteA  = Wire.read();
      byte highByteA = Wire.read();
      DatenInA = (highByteA << 8) | lowByteA;
    }
  Wire.endTransmission();
Serial.println(DatenInA);

  for (int n = 0; n < 6; n+=5) {
    if ((DatenInA & (1 << n))     == 0) { Ein[(n)]      = true; } else { Ein[(n)]      = false; }
    if ((DatenInA & (1 << (n+1))) == 0) { Ein[(n+1)]    = true; } else { Ein[(n+1)]    = false; }
    if ((DatenInA & (1 << (n+2))) == 0) { Ein[(n+2)]    = true; } else { Ein[(n+2)]    = false; }
    if ((DatenInA & (1 << (n+3))) == 0) { Ein[(n+3)]    = true; } else { Ein[(n+3)]    = false; }
    if ((DatenInA & (1 << (n+4))) == 0) { Ein[(n+4)]    = true; } else { Ein[(n+4)]    = false; }
  }
}

void ReadIn2() {

  Wire.beginTransmission((uint8_t)PCF[1]);
  Wire.requestFrom((uint8_t)PCF[1],(uint8_t) 2);
    if (Wire.available() >= 2) { 
      byte lowByteB  = Wire.read();
      byte highByteB = Wire.read();
      DatenInB = (highByteB << 8) | lowByteB;
    }
  Wire.endTransmission();
Serial.println(DatenInB);  
    
  for (int n = 0; n < 6; n+=5) {  
    if ((DatenInB & (1 << n))     == 0) { Ein[10+n]       = true; } else { Ein[10+n]       = false; }
    if ((DatenInB & (1 << (n+1))) == 0) { Ein[(n+11)]   = true; } else { Ein[(n+11)]   = false; }
    if ((DatenInB & (1 << (n+2))) == 0) { Ein[(n+12)]   = true; } else { Ein[(n+12)]   = false; }
    if ((DatenInB & (1 << (n+3))) == 0) { Ein[(n+13)]   = true; } else { Ein[(n+13)]   = false; }
    if ((DatenInB & (1 << (n+4))) == 0) { Ein[(n+14)]   = true; } else { Ein[(n+14)]   = false; }
  }
}

void Punkte() {
  for (int i = 0, j = 0; i < 16 && j < 10; i+=5, j+=3) {
    if (Ein[i]   || Ein[i+1]) { Neu[j]   = true; } else { Neu[j]   = false; }
    if (Ein[i+2] || Ein[i+3]) { Neu[j+1] = true; } else { Neu[j+1] = false; }
    if (Ein[i+4])             { Neu[j+2] = true; } else { Neu[j+2] = false; }
  }
  for (int i = 0, j = 0; i < 10 && j < 4; i+=3, j++) {
    if (Neu[i]   && !Alt[i])   { punkteSpieler[j] += 1; }
    if (Neu[i+1] && !Alt[i+1]) { punkteSpieler[j] += 2; }
    if (Neu[i+2] && !Alt[i+2]) { punkteSpieler[j] += 3; }
    if (punkteSpieler[j] >= Maximalpunktzahl) { Status[1] = false; }
  }
  for (int i = 0; i < 12; i++) {
    Alt[i] = Neu[i];
  }
}
void led() {
  if (millis() - Zeitspeicher[1] >= VorlaufZeit[1]) {
    Zeitspeicher[1] = millis();
    int Sendedaten[5] = {punkteSpieler[0],punkteSpieler[1],punkteSpieler[2],punkteSpieler[3],Maximalpunktzahl};
    for (int i = 0; i < 2; i++) {
      Wire.beginTransmission(Slaves[i]);
      for (int j = 0; j < 5; j++) {
        Wire.write((byte*)&Sendedaten[j], sizeof(int));
      }
      for (int i = 0; i < 2; i++) {
        Wire.write(Status[i]);
      }
    }
  }
}
void Motor() {

  for (int i = 0; i < 4; i++) {
    pos[i] = map(punkteSpieler[i],0,Maximalpunktzahl,Offset,MotMax[i] - Offset);
    Mot[i][3].moveTo(pos[i]);
    Mot[i][3].run();
  }
}
void MotorEndpunkteKalibrieren() {

  int readValue[4];
  EEPROM.get(0, readValue[0]);
  EEPROM.get(sizeof(int), readValue[1]);
  EEPROM.get(sizeof(int) * 2, readValue[2]);
  EEPROM.get(sizeof(int) * 3, readValue[3]);

  for (int i = 0; i < 4; i++) {
    pinMode(Null[i], INPUT_PULLUP);
    pinMode(Max[i], INPUT_PULLUP);

    Mot[i][3].setMaxSpeed(200);
    Mot[i][3].setAcceleration(100);

    MotMax[i] = readValue[i];
  }
  while (digitalRead(Start) == HIGH) {}
  for (int i = 0; i < 4; i++) {
    Mot[i][3].setSpeed(-20);
    while ((digitalRead(Null[i])) == HIGH && (digitalRead(Reset) == HIGH)) {
      Mot[i][3].runSpeed();
    }
    Mot[i][3].stop();
    Mot[i][3].setCurrentPosition(0);
    Mot[i][3].moveTo(MotMax[i]);
    while (Mot[i][3].currentPosition() < MotMax[i] && ((digitalRead(Max[i])) == HIGH) && (digitalRead(Reset) == HIGH)) {
      Mot[i][3].run();
    }
    Mot[i][3].stop();
    Mot[i][3].setSpeed(20);
    while (digitalRead(Max[i]) == HIGH && (digitalRead(Reset) == HIGH)) {
      Mot[i][3].runSpeed();
    }
    Mot[i][3].stop();
    MotMax[i] = Mot[i][3].currentPosition();
    Mot[i][3].moveTo(10);
    while (Mot[i][3].currentPosition() > 10 && ((digitalRead(Null[i])) == HIGH) && (digitalRead(Reset) == HIGH)) {
      Mot[i][3].run();
    }
    Mot[i][3].stop();
    Mot[i][3].setSpeed(0); 
  }
//  EEPROM.put(0, MotMax[0]);
//  EEPROM.put(sizeof(int), MotMax[1]);
//  EEPROM.put(sizeof(int) * 2, MotMax[2]);
//  EEPROM.put(sizeof(int) * 3, MotMax[3]);
}

Perhaps you meant to type:

const uint8_t PCF[2] = { 0x20 , 0x22 };

does not fix my problem

That should be two separate writes of 0xFF

  for (int i = 0; i < 2; i++) {
    Wire.beginTransmission(PCF[i]);
    Wire.write(0xFF);
    Wire.write(0xFF);
    Wire.endTransmission();
  }

Stays the same

looks like 0xFFFF works

So everything works OK with 0xFFFF?

The devices work fine

if i singel use them they work

it is always the one in the secont readout ReadIn2

ReadIn1 works with 0x20 and 0x22


  Wire.beginTransmission((uint8_t)PCF[0]);
  Wire.requestFrom((uint8_t)PCF[0],(uint8_t) 2);
    if (Wire.available() >= 2) { 
      byte lowByteA  = Wire.read();
      byte highByteA = Wire.read();
      DatenInA = (highByteA << 8) | lowByteA;
    }
  Wire.endTransmission();
Serial.println(DatenInA);

  for (int n = 0; n < 6; n+=5) {
    if ((DatenInA & (1 << n))     == 0) { Ein[(n)]      = true; } else { Ein[(n)]      = false; }
    if ((DatenInA & (1 << (n+1))) == 0) { Ein[(n+1)]    = true; } else { Ein[(n+1)]    = false; }
    if ((DatenInA & (1 << (n+2))) == 0) { Ein[(n+2)]    = true; } else { Ein[(n+2)]    = false; }
    if ((DatenInA & (1 << (n+3))) == 0) { Ein[(n+3)]    = true; } else { Ein[(n+3)]    = false; }
    if ((DatenInA & (1 << (n+4))) == 0) { Ein[(n+4)]    = true; } else { Ein[(n+4)]    = false; }
  }
}

void ReadIn2() {

  Wire.beginTransmission((uint8_t)PCF[1]);
  Wire.requestFrom((uint8_t)PCF[1],(uint8_t) 2);
    if (Wire.available() >= 2) { 
      byte lowByteD  = Wire.read();
      byte highByteD = Wire.read();
      DatenInD = (highByteD << 8) | lowByteD;
    }
  Wire.endTransmission();  
  Serial.println(DatenInD);
    
  for (int n = 0; n < 6; n+=5) {  
    if ((DatenInD & (1 << n))     == 0) { Ein[(n+10)]   = true; } else { Ein[(n+10)]   = false; } Serial.println("1");
    if ((DatenInD & (1 << (n+1))) == 0) { Ein[(n+11)]   = true; } else { Ein[(n+11)]   = false; } Serial.println("2");
    if ((DatenInD & (1 << (n+2))) == 0) { Ein[(n+12)]   = true; } else { Ein[(n+12)]   = false; } Serial.println("3");
    if ((DatenInD & (1 << (n+3))) == 0) { Ein[(n+13)]   = true; } else { Ein[(n+13)]   = false; } Serial.println("4");
    if ((DatenInD & (1 << (n+4))) == 0) { Ein[(n+14)]   = true; } else { Ein[(n+14)]   = false; } Serial.println("5");
  }
}

wire.write() can only send a single 8 bit byte.
The PCF need two bytes.

i beleve it is but it does not change anything

` Wire.beginTransmission(PCF[0]);
Wire.write(0xFF);
Wire.write(0xFF);
Wire.endTransmission();

Wire.beginTransmission(PCF[1]);
Wire.write(0xFF);
Wire.write(0xFF);
Wire.endTransmission();`

I don't see anything else wrong.
For debugging purposes, would it be easy to use addresses 0x20 and 0x21 just to see if the problem persists?

i alread tried an other device

i have 3 set to 0x20 0x21 0x22 all 3 have the same problem

it is alwast the second one in the array

PCF[1]

Maybe you should print out the return value of Wire.endTransmission();
Might give you an idea of what is going wrong.

only when n gets 5

so its still in lowByteD

the Serial.println(DatenInD); gets to ( -1.?..undefined )

if i tuch the not used pins with GND it gets an propper readout

its directly cuppled to n

is Ein[(n+10)] the problem?

void ReadIn2() {

  Wire.beginTransmission((uint8_t)PCF[1]);
  Wire.requestFrom((uint8_t)PCF[1],(uint8_t) 2);
    if (Wire.available() >= 2) { 
      byte lowByteD  = Wire.read();
      byte highByteD = Wire.read();
      DatenInD = (highByteD << 8) | lowByteD;
    }
  Wire.endTransmission();  
  Serial.println(DatenInD);
    
  for (int n = 0; n < 6; n+=5) {  
    if ((DatenInD & (1 << n))     == 0) { Ein[(n+10)]   = true; } else { Ein[(n+10)]   = false; }
    if ((DatenInD & (1 << (n+1))) == 0) { Ein[(n+11)]   = true; } else { Ein[(n+11)]   = false; }
    if ((DatenInD & (1 << (n+2))) == 0) { Ein[(n+12)]   = true; } else { Ein[(n+12)]   = false; }
    if ((DatenInD & (1 << (n+3))) == 0) { Ein[(n+13)]   = true; } else { Ein[(n+13)]   = false; }
    if ((DatenInD & (1 << (n+4))) == 0) { Ein[(n+14)]   = true; } else { Ein[(n+14)]   = false; }
  }
}

I'm confused.
You are not printing out DatenInD when n=5.
Maybe you should define DatenInD as a uint16_t rather than a short

i am confused too

uint16_t just gives me a diffrent readoutvalue on the monitor but the rest is unchanged

(uint16_t)
bevore 65519 = 1111111111101111
and after 64511 = 1111101111111111
work fine

1111110000011111 => all theese 0 make a problem

Problem Found

i dont know why it behaved like this but im void motor() i set an offset of 200 witch set the mot pos value to minus

i corrected it from 200 to 2 now it works

i am confused i dont understand why but its working

I know that on the Adafruit board they have 10K pull-down resistorson the A pins
Do you know if your board has any pull-up or pull-downs on the A0, A1, A2 pins?

i have the original UNO R3 it has multiple pulldown resistors i also put pull ups in the sda scl

I meant on the PCF8575 board

You have limit switches connected to the I2C bus, SDA and SCL?