[solved] Drive 4-Channel SPDT Relay via I2C/smbus2 python

I believe I misunderstand the communication protocol for the 4-channel SPDT Relay. The relays are connected to +5; SDA on pin 3; SCL on pin 5, and ground. So that is fine.
</s>i2cdetect -y 1<e> gives me the address </s>0x11<e>
I had anticipated, that I could simply send data binary to switch on and off the channels one by one.
</s><i> </i>from smbus2 import SMBus with SMBus(1) as bus: # Write a byte to address 80, offset 0 data = 0x01 bus.write_byte_data(0x11, 1, data) <e>
the above - in my mind would switch on channel 1, if I had chosen data to be F, all channels should be switched.

The code executed, but none of the relais reacts (measured with multimeter)

Can anybody help? Many thanks!

ah sorry. Reverse engineered it from the cpp example linked. Almost as I thought, but we need to send 0x10 to first stell that we want to control channels. So this does the job for me.

</s>i2cset -y 1 0x11 0x10 0x0f <e>

closed.

Hi fal414, did you solve the issue? im trying to use the same relay dev board and find the address to be 0x11. do you have any sample code or library i could take a look at?

Thanks

I have one of these and will clarify additional information for controlling this 4-channel relay in python.

The Quick Answer

In python, we can do this using the smbus2 module and the write_byte_data() function in the SMBus class.

from smbus2 import SMBus

with SMBus(1) as bus:
    bus.write_byte_data(0x11, 0x10, 0x0b)
    bus.write_byte_data(0x11, 0x10, 0x0f)

The Long Answer

I experimented with writing data using the i2cset command:
i2cset -y 1 0x11 0x10 <DATA>

When looking at the side with the I2C connector, with the left-most relay as #1 (COM1), here is the relay state when sent the hex DATA value to the device. Note that this is the coil state (relay coil ON and red LED ON).


       1   2   3   4
       ---------------
0x00:  OFF OFF OFF OFF
0x01:  ON  OFF OFF OFF
0x02:  OFF ON  OFF OFF
0x03:  ON  ON  OFF OFF
0x04:  OFF OFF ON  OFF
0x05:  ON  OFF ON  OFF
0x06:  OFF ON  ON  OFF
0x07:  ON  ON  ON  OFF
0x08:  OFF OFF OFF ON
0x09:  ON  OFF OFF ON
0x0a:  OFF ON  OFF ON
0x0b:  ON  ON  OFF ON
0x0c:  OFF OFF ON  ON
0x0d:  ON  OFF ON  ON
0x0e:  OFF ON  ON  ON
0x0f:  ON  ON  ON  ON

Unfortunately I could not find a way to get the state of a relay. Reading 0x11 0x10 always locked up my whole I2C bus requiring a cold power cycle of my GrovePi+.

Let us say everything ON is our default state which is 0x0f and I want to power cycle relay 3. I would set state 0x0b then set 0x0f. Using i2cset:

i2cset -y 1 0x11 0x10 0x0b
i2cset -y 1 0x11 0x10 0x0f

In python, we can do this using the smbus2 module and the write_byte_data() function in the SMBus class.

from smbus2 import SMBus

with SMBus(1) as bus:
    bus.write_byte_data(0x11, 0x10, 0x0b)
    bus.write_byte_data(0x11, 0x10, 0x0f)

SMBus(1) is I2C bus 1 (/dev/i2c-1)
0x11 is the I2C address of the relay
0x10 is (I think but not sure) the register we’re sending data to
0x0b is the data from the table above that defines the state of all relays