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.
gives me the address
</s>i2cdetect -y 1<e>
</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
I’m hitting the complete lock up problem when trying to use the 4-Channel SPDP Relay. Happened upon this post. I’ll give my feedback when done.
First, that tale will make a bit more sense if you reverse the registers
4 3 2 1
---------------
0x00: OFF OFF OFF OFF
0x01: OFF OFF OFF ON
0x02: OFF OFF ON OFF
0x03: OFF OFF ON ON
0x04: OFF ON OFF OFF
0x05: OFF ON OFF ON
0x06: OFF ON ON OFF
0x07: OFF ON ON OFF ON
0x08: ON OFF OFF OFF
0x09: ON OFF OFF ON
0x0a: ON OFF ON OFF
0x0b: ON OFF ON ON
0x0c: ON ON OFF OFF
0x0d: ON ON OFF ON
0x0e: ON ON ON OFF
0x0f: ON ON ON ON
Thanks for the hints.
I put together a quick python script to to some bitwise or’ing with arguments.
This is like the second python program I ever wrote so it was
google python arguments
google python bitwise or
google python byte type
etc
There is a lot of printf() debugging in here
#!/usr/bin/python
import sys
# I tried to mess with the byte objext but quit
Regs_to_turn_on = 0
# we should make sure that the arguments are numbers between 1 and 4.
print ('Number of arguments:', len(sys.argv), 'arguments.')
print ('Argument List:', str(sys.argv))
print("\nArguments passed:\n", end = " ")
for i in range(1, len(sys.argv)):
print(sys.argv[i], end = " ")
Regs_to_turn_on = Regs_to_turn_on | ( 1 << int(sys.argv[i])-1 )
print("\n")
print("Interim Byte to write is = (in hex)" + hex(Regs_to_turn_on))
print("Interim Byte to write is = (in binary)" + bin(Regs_to_turn_on))
print("\n")
print("\n")
print("Final Byte to write is = (in hex)" + hex(Regs_to_turn_on))
print("Final Byte to write is = (in binary)" + bin(Regs_to_turn_on))
print("\n")
from smbus2 import SMBus
with SMBus(1) as bus:
# 4321
bus.write_byte_data(0x11, 0x10, Regs_to_turn_on)