Hello everyone,
Its my first time posting here so if i am doing something wrong please let me know and be patient with me.
I have an arduino board controlling 2 relay modules i found on the internet, they have optocouplers and a XL9535 chip which i had a bit of a hard time understanding how to call write to it but i managed. My program controls 4 motors and a VFD. My arduino is connected to an optocoupler which in turn is connected to 4 buttons. Each button is powered with 5v and closes the loop which tells my optocoupler there is a signal and incoming and in turn it grounds my arduino PULL UP pin. There are 4 motors and two limit switches and a button which is pressed to execute the action. My program is simplified as follows:
void loop() {
updateAllButtonStatuses(); // I am polling for the button statuses
if (motor1OnOffButton.getStatus()) { // I am doing this for the 4 motors...
motor1.on();
} else {
motor1.off()
.....
if (autoButton.getStatus() || autoModeActive) {
autoModeActive = true; // Set the flag to indicate auto mode is active
vfd.advance();
if (limitFront.getTriggeredStatus()) {
vfd.reverse();
}
while (!limitBack.getTriggeredStatus()) {
limitBack.updateStatus();
}
vfd.wait();
autoModeActive = false;
}
My issue comes and goes, sometimes everything works as intended for up to 8 hours straight, then the next day it crashes every 5 minutes. I cant seem to find a correlation to it.
Whenever the crash occurs my relay modules, which connect via I2C to my arduino turn all the relays off. But i can see the correct signals coming into my arduino through my optocouple. I can also see the relay modules are on. I suspect there is something going on with my I2C connection so ill share how i write to the chip:
void XV2::setup() {
Serial.begin(9600); // Initialize serial communication
Wire.begin(); // Start the I2C bus
// Set each pin as output
for (Pin pin = X0; pin < NUM_PINS; pin = static_cast<Pin>(pin + 1)) {
setPinMode(pin, OUTPUT);
digitalWrite(pin, LOW);
}
}
bool XV2::checkI2CError() {
if (Wire.endTransmission() != 0) {
Serial.println("I2C communication error!");
return true;
}
return false;
}
void XV2::setPinMode(Pin pin, bool mode) {
uint8_t port = pin < Y0 ? 0 : 1;
uint8_t pinNum = pin % 8;
Wire.beginTransmission(DEVICE_ADDRESS);
Wire.write(port ? CONFIG_PORT_1 : CONFIG_PORT_0);
Wire.endTransmission();
if (checkI2CError()) return; // Check for I2C error
Wire.requestFrom((uint8_t)DEVICE_ADDRESS, (uint8_t)1);
uint8_t config;
if (Wire.available()) {
config = Wire.read();
}
if (mode == OUTPUT) {
config &= ~(1 << pinNum);
} else {
config |= (1 << pinNum);
}
Wire.beginTransmission(DEVICE_ADDRESS);
Wire.write(port ? CONFIG_PORT_1 : CONFIG_PORT_0);
Wire.write(config);
Wire.endTransmission();
checkI2CError(); // Check for I2C error
}
void XV2::digitalWrite(Pin pin, bool value) {
uint8_t port = pin < Y0 ? 0 : 1;
uint8_t pinNum = pin % 8;
Wire.beginTransmission(DEVICE_ADDRESS);
Wire.write(port ? OUTPUT_PORT_1 : OUTPUT_PORT_0);
Wire.endTransmission();
if (checkI2CError()) return; // Check for I2C error
Wire.requestFrom((uint8_t)DEVICE_ADDRESS, (uint8_t)1);
uint8_t output;
if (Wire.available()) {
output = Wire.read();
}
if (value == HIGH) {
output |= (1 << pinNum);
} else {
output &= ~(1 << pinNum);
}
Wire.beginTransmission(DEVICE_ADDRESS);
Wire.write(port ? OUTPUT_PORT_1 : OUTPUT_PORT_0);
Wire.write(output);
Wire.endTransmission();
checkI2CError(); // Check for I2C error
}
My setup goes like this:
Optocoupler (button and limit switches signals) -> arduino mega -> i2c comms to relay board with optocoupler -> contactors-> motors/vfd