So.... this is the current state of affairs.
I've now connected the original PCFs via the TCA as well, on number 2.
I tcaselect(2); to the code, as I thought the 2 referred to the number on the TCA, however, that doesn't seem to be the case. I changed the tcaselect(1) to (0) and the switch still worked exactly the same on TCA output 1.
This is my code (abridged for relevance)
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
#include <LiquidCrystal_I2C.h>
#include <Adafruit_GFX.h>
#include "Adafruit_LEDBackpack.h"
#include <FastLED.h>
#include <pcf8574.h>
#define NUM_LEDS 30
#define DATA_PIN1 46
#define DATA_PIN2 47
#define TCAADDR 0x71
CRGB leda[NUM_LEDS];
CRGB ledb[NUM_LEDS];
Adafruit_AlphaNum4 alpha4 = Adafruit_AlphaNum4();
LiquidCrystal_I2C lcd(0x27, 20, 4);
Adafruit_PWMServoDriver pwm0 = Adafruit_PWMServoDriver(0x40);
Adafruit_PWMServoDriver pwm1 = Adafruit_PWMServoDriver(0x41);
Adafruit_PWMServoDriver pwm2 = Adafruit_PWMServoDriver(0x42);
// Dunderby Junction
Adafruit_PWMServoDriver pwm3 = Adafruit_PWMServoDriver(0x43);
// lighting
Adafruit_PWMServoDriver pwm4 = Adafruit_PWMServoDriver(0x44);
PCF8574 ex1(0x20);
PCF8574 ex2(0x21);
PCF8574 ex3(0x22);
PCF8574 ex4(0x23);
PCF8574 ex5(0x24);
// via TCA channel
PCF8574 sx1(0x20);
PCF8574 sx2(0x21);
#define SERVOMIN1 265 // Servo 1 min
#define SERVOMAX1 370 //
#define SERVOMIN2 340 // Servo 2
#define SERVOMAX2 440 //
// points into TCA controlled
#define pushButton1 0
int angle1 = 0;
int angle2 = 0;
int angleStep1 = 5;
int angleStep2 = 5;
int buttonPushed1 = 0;
int buttonPushed2 = 0;
void tcaselect(uint8_t i) {
if (i > 7) return;
Wire.beginTransmission(TCAADDR);
Wire.write(1 << i);
Wire.endTransmission();
}
// activate a specific TCA channel, choose a specific PCF instance, read one pin)
int read(int tcaChannel, PCF8574 &pcf, int pcfPin )
{
tcaselect(tcaChannel);
int state = digitalRead(pcf, pcfPin);
if (state == -1) Serial.println("PCF8574 not detected");
return state;
}
void setup() {
Serial.begin(9600);
Wire.begin();
tcaselect(1);
tcaselect(2);
pinMode(sx1, 0, INPUT_PULLUP);
pinMode(sx1, 1, INPUT_PULLUP);
pinMode(sx1, 2, INPUT_PULLUP);
pinMode(sx1, 3, INPUT_PULLUP);
pinMode(sx1, 4, INPUT_PULLUP);
pinMode(sx1, 5, INPUT_PULLUP);
pinMode(sx1, 6, INPUT_PULLUP);
pinMode(sx1, 7, INPUT_PULLUP);
pinMode(ex1, 0, OUTPUT);
pinMode(ex1, 1, OUTPUT);
pinMode(ex1, 2, OUTPUT);
pinMode(ex1, 3, OUTPUT);
pinMode(ex1, 4, OUTPUT);
pinMode(ex1, 5, OUTPUT);
pinMode(ex1, 6, OUTPUT);
pinMode(ex1, 7, OUTPUT);
// lcd.init();
lcd.clear();
lcd.setBacklight(32);
lcd.print("Start up...");
pwm0.begin();
pwm1.begin();
pwm2.begin();
pwm0.setPWMFreq(60);
pwm1.setPWMFreq(60);
pwm2.setPWMFreq(60);
pwm0.setPWM(0, 0, 265);
leda[0].setRGB(8, 8, 16);
ledb[0].setRGB(0, 0, 0);
digitalWrite(ex1, 0, HIGH);
pwm0.setPWM(1, 0, 340);
leda[1].setRGB(8, 8, 16);
ledb[1].setRGB(0, 0, 0);
digitalWrite(ex1, 1, HIGH);
yield();
}
void loop() {
tcaselect(1);
tcaselect(2);
int state1 = read(1, sx1, 0);
if (state1 == LOW)
{
buttonPushed1 = 1;
}
if (buttonPushed1) {
angle1 = angle1 + angleStep1;
if (angle1 <= 0 || angle1 >= 180) {
angleStep1 = -angleStep1;
buttonPushed1 = 0;
if (angle1 <= 0) {
lcd.setCursor(0, 0);
lcd.print("Point 01 is set ");
Serial.println("Point 01 is set");
leda[0].setRGB(16, 16, 8);
ledb[0].setRGB(0, 0, 0);
digitalToggle(ex1, 0);
}
else if (angle1 >= 180) {
lcd.setCursor(0, 0);
lcd.print("Point 01 is thrown ");
Serial.println("Point 01 is back");
leda[0].setRGB(0, 0, 0);
ledb[0].setRGB(16, 16, 8);
digitalToggle(ex1, 0);
}
}
pwm0.setPWM(0, 0, angleToPulse(angle1) );
}
if (analogRead(sw1) > 510 && analogRead(sw1) < 520 )
{
buttonPushed2 = 1;
}
if (buttonPushed2) {
angle2 = angle2 + angleStep2;
if (angle2 <= 0 || angle2 >= 180) {
angleStep2 = -angleStep2;
buttonPushed2 = 0;
if (angle2 <= 0) {
lcd.setCursor(0, 0);
lcd.print("Point 02 is set ");
leda[1].setRGB(32, 16, 32);
ledb[1].setRGB(0, 0, 0);
digitalToggle(ex1, 1);
}
else if (angle2 >= 180) {
lcd.setCursor(0, 0);
lcd.print("Point 02 is thrown ");
leda[1].setRGB(0, 0, 0);
ledb[1].setRGB(32, 16, 0);
digitalToggle(ex1, 1);
}
}
pwm0.setPWM(1, 0, angleToPulse2(angle2) );
}
if (angle1 > 0 && angle1 < 180) {
leda[0].setRGB(0, 0, 0);
ledb[0].setRGB(0, 0, 0);
}
if (angle2 > 0 && angle2 < 180) {
leda[1].setRGB(0, 0, 0);
ledb[1].setRGB(0, 0, 0);
}
FastLED.show();
delay(30);
int angleToPulse(int ang) {
int pulse = map(ang, 0, 180, SERVOMIN1, SERVOMAX1);
return pulse;
}
int angleToPulse2(int ang2) {
int pulse2 = map(ang2, 0, 180, SERVOMIN2, SERVOMAX2);
return pulse2;
}
There are many more switches in there, 36 in total, but for keeping the code shorter I'm showing only 2. Number one simply bounces between thrown and set, not locking. Number 2 works fine. If I blank out digitalToggle(ex1,0); on button1, it works and latches. So I know there is a conflict, but I don't know why as I have now connected the original batch of 4 PCFs through the TCA as you can see from the photograph below. Also, the relays no longer work since I have connected it through the TCA, even though I added the additional line of tcaselect(2).
So I'm confused basically - shocking eh?