Hey guys, just an update.
I managed to get it working with very similar code as @armor
@Rftop your suggestion does work, however I'm trying to understand the logic behind the Texas Instrument chip. Although your much shorter version works, the library of course still makes use of other logic in the back-end.
After finally getting come feedback from the NCD community, it all makes sense now, their explanation as follows:
The command to set the relay state controls all channels at once, if you break the byte into bits you can see what is happening by viewing the two lowest bits:
(both relays off) 0x00 - 00000000
(relay 1 on, 2 off) 0x01 - 00000001
(relay 2 on, 1 off) 0x02 - 00000010
(both relays on) 0x03 - 00000011
You cannot set the state of one relay at a time, so generally you would read the current status first and then adjust the value accordingly before setting it again.
The 0x02 register is the polarity inversion register, that is to say that it acts as a mask to reverse the bit control (or readout) of particular channels. Typically a set bit will turn the relay on, so when you write 0x01 the last two bits are 01, based on the normal polarity settings this means relay 1 is on, writing a 2 to the polarity register says you’d like to invert the second lowest bit, so now that bit will turn on the associated relay when it is cleared rather than set. If you wrote 0x03 to the polarity register, then sending 0x00 to register 0x01 would actually turn on both relays.
My rectified code below for those who are interested:
#include <application.h>
#include <spark_wiring_i2c.h>
#define Addr 0x41
byte relayState{0x01};
void setup()
{
initRelays();
relaysToLow();
Particle.function("relayOne", relayOne);
Particle.function("relayTwo", relayTwo);
Particle.function("allRelays", allRelays);
}
int relayOne(String relay1State)
{
Wire.beginTransmission(Addr);
if (relay1State == "On" || relay1State == "on" || relay1State == "ON" || relay1State == "oN" || relay1State == "1")
{
relayState = relayState | 1;
Wire.write(0x01);
Wire.write(relayState);
Wire.endTransmission();
Serial.println ("Relay-1 state is : HIGH");
}
else if (relay1State == "Off" || relay1State == "off" || relay1State == "OFF" || relay1State == "0")
{
relayState = relayState & ~1;
Wire.write(0x01);
Wire.write(relayState);
Wire.endTransmission();
Serial.println ("Relay-1 state is : LOW");
}
return 1;
}
int relayTwo(String relay2State)
{
//byte test{0x02};
Wire.beginTransmission(Addr);
if (relay2State == "On" || relay2State == "on" || relay2State == "ON" || relay2State == "oN" || relay2State == "1")
{
relayState = relayState | 2;
Wire.write(0x01);
Wire.write(relayState);
Wire.endTransmission();
Serial.println ("Relay-2 state is : HIGH");
}
else if (relay2State == "Off" || relay2State == "off" || relay2State == "OFF" || relay2State == "0")
{
relayState = relayState & ~2;
Wire.write(0x01);
Wire.write(relayState);
Wire.endTransmission();
Serial.println ("Relay-2 state is : LOW");
}
return 1;
}
int allRelays(String command)
{
if (command == "On" || command == "on" || command == "ON" || command == "oN" || command == "1")
{
relaysToHigh();
}
else if (command == "Off" || command == "off" || command == "OFF" || command == "0")
{
relaysToLow();
}
return 1;
}
void initRelays()
{
Serial.begin(9600);
Wire.begin();
Wire.beginTransmission(Addr);
Wire.write(0x03);
Wire.write(0x00);
Wire.endTransmission();
delay(300);
}
void relaysToLow()
{
Wire.beginTransmission(Addr);
Wire.write(0x01);
Wire.write(0x00);
Wire.endTransmission();
Serial.println ("All Relay states are : LOW");
relayState = 0x00;
}
void relaysToHigh()
{
Wire.beginTransmission(Addr);
Wire.write(0x01);
Wire.write(0x03);
Wire.endTransmission();
Serial.println ("All Relay states are : HIGH");
relayState = 0x03;
}
void loop()
{
}
Thanks for all the interest and help, much appreciated!