i2c with contrib-gpio

738 views
Skip to first unread message

Simon

unread,
Jul 14, 2017, 11:32:39 AM7/14/17
to Node-RED
Figured I'd split this to a separate topic... 

I need to trigger 8x relays on a UniPi. They are accessible via i2c with the address of 0x20.

How would I turn each relay on / off? Is it a single GPIO node with the 0x20 address and I inject / provide a payload of the relay number?

The i2c chip is: MCP23008 for reference.

Luis Montes

unread,
Jul 14, 2017, 11:45:40 AM7/14/17
to node...@googlegroups.com
There's two approaches:

The easier is to use a johnny-five node, and then use the code from the ready event in this example:  http://johnny-five.io/examples/expander-MCP23008/   Also, you can modify that to specify the virtual board in the relay constructor from this example:  http://johnny-five.io/examples/relay/


Otherwise you'll need to figure out the MCP23008 protocol to get the bytes that need to be sent over the i2c bus with the gpio-out node.  


--
http://nodered.org
 
Join us on Slack to continue the conversation: http://nodered.org/slack
---
You received this message because you are subscribed to the Google Groups "Node-RED" group.
To unsubscribe from this group and stop receiving emails from it, send an email to node-red+unsubscribe@googlegroups.com.
To post to this group, send email to node...@googlegroups.com.
Visit this group at https://groups.google.com/group/node-red.
To view this discussion on the web, visit https://groups.google.com/d/msgid/node-red/3fc48d7d-eb46-4a9a-98d3-6743e9bc89d0%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Dave C-J

unread,
Jul 14, 2017, 11:49:51 AM7/14/17
to node...@googlegroups.com
or maybe the node-red-contrib-i2c node can help - but it has minimal docs... so...

David Caparrós

unread,
Jul 14, 2017, 12:50:53 PM7/14/17
to Node-RED
Hello Simon

I was expecting something was implemented already however seems not to be.

You need first to install I2C on your rasberry by doing on a console:  sudo apt-get install -y i2c-tools    
Then you need to enable I2C bus on raspberry by writting on a console:  sudo raspi-config    go to option 5 intfacing and enable I2C bus.
I recomend to reboot just in case at this point
Then you need to scan in order to find the address of your plugged device:  i2cdetect -y 1

You will have something line:

pi@raspberrypi:~ $ i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: 20 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --


In this case it means your device will be address 20 so 0x20

In order to read the status of the inputs type:  i2cget -y 1 0x20, this will return you the status of your 8 bits in hexdecimal  so all to 0 is 0x00 and all to one is 0xFF.

Much easier to look for some binary to hex converter like:  https://www.mathsisfun.com/binary-decimal-hexadecimal-converter.html

If you want to use it as an output will have to do exactly the same but with i2cset.

For what I investigated seems to be all, any other advice is wellcome.

At this point on node red seems not to be any specific, at list I don't find the wat to do it.

Just inject on a exec node with the corresponding comand and get the output of the exec if required to read status, as example:


[{"id":"db48c4bd.87f6d8","type":"inject","z":"5e06df2b.eecce","name":"","topic":"","payload":"","payloadType":"date","repeat":"0.200","crontab":"","once":true,"x":120,"y":1500,"wires":[["8e270273.7cd55"]]},{"id":"8e270273.7cd55","type":"exec","z":"5e06df2b.eecce","command":"i2cget -y 1 0x20 ","addpay":false,"append":"","useSpawn":"false","timer":"","oldrc":false,"name":"","x":310,"y":1500,"wires":[["4ca0f517.6d367c"],[],[]]},{"id":"4ca0f517.6d367c","type":"debug","z":"5e06df2b.eecce","name":"","active":true,"console":"false","complete":"false","x":600,"y":1500,"wires":[]}]

This will read the status of the 8 bits each 200 miliseconds and will show you the value on a debug node.

I'm going to try to make some function with multiple outputs/inputs to make it much easier to work with, however again, if someone has already something or some advice is really wekkcome.

Regards


David Caparrós

unread,
Jul 14, 2017, 1:38:14 PM7/14/17
to Node-RED
There is someone who already made a function for this purpose?¿

The idea is from a hexadecimal 8 bit value (so from 0x00 to 0xFF) writte a function that returns value 0 or 1 on each output if the status change.

Something like:

[{"id":"edad23c4.67c87","type":"function","z":"5e06df2b.eecce","name":"","func":"var input = msg.payload\nvar oldinput = \"0x00\";\n\nif ((input === \"0x00\")&&(input !== oldinput)) {\nmsg1.payload = (0);\nmsg2.payload = (0);\nmsg3.payload = (0);\nmsg4.payload = (0);\nmsg5.payload = (0);\nmsg6.payload = (0);\nmsg7.payload = (0);\nmsg8.payload = (0);\nreturn msg;\n}\n\nif ((input === \"0x01\")&&(input !== oldinput)) {\nmsg1.payload = (1);\nreturn msg;\n}\n\nif ((input === \"0x02\")&&(input !== oldinput)) {\nmsg2.payload = (1);\nreturn msg;\n}\n\nif ((input === \"0x04\")&&(input !== oldinput)) {\nmsg3.payload = (1);\nreturn msg;\n}\n\nif ((input === \"0x08\")&&(input !== oldinput)) {\nmsg4.payload = (1);\nreturn msg;\n}\n\nif ((input === \"0x10\")&&(input !== oldinput)) {\nmsg5.payload = (1);\nreturn msg;\n}\n\nif ((input === \"0x20\")&&(input !== oldinput)) {\nmsg6.payload = (1);\nreturn msg;\n}\n\nif ((input === \"0x40\")&&(input !== oldinput)) {\nmsg7.payload = (1);\nreturn msg;\n}\n\nif ((input === \"0x80\")&&(input !== oldinput)) {\nmsg8.payload = (1);\nreturn msg;\n}\n\nvar oldinput = msg.payload","outputs":"8","noerr":0,"x":670,"y":1480,"wires":[["d614c304.305c4"],[],[],[],[],[],[],[]]},{"id":"2eeb341b.6d2d8c","type":"inject","z":"5e06df2b.eecce","name":"","topic":"","payload":"","payloadType":"date","repeat":"0.200","crontab":"","once":true,"x":260,"y":1500,"wires":[["82f1a9a6.a8cff8"]]},{"id":"82f1a9a6.a8cff8","type":"exec","z":"5e06df2b.eecce","command":"i2cget -y 1 0x20 ","addpay":false,"append":"","useSpawn":"false","timer":"","oldrc":false,"name":"","x":450,"y":1500,"wires":[["edad23c4.67c87"],[],[]]},{"id":"d614c304.305c4","type":"debug","z":"5e06df2b.eecce","name":"","active":true,"console":"false","complete":"false","x":930,"y":1480,"wires":[]}]

but something that works not like mine... hahahha

but for sure you catch the idea, you have an input string value to compare with the previous one and if data had chance write 0 or 1 on output from 1 to 8.

This is too much for my knowledge for now...

Thanks in advance

David Caparrós

unread,
Jul 14, 2017, 1:39:17 PM7/14/17
to Node-RED

*correction, if value had changed

David Caparrós

unread,
Jul 14, 2017, 3:57:46 PM7/14/17
to Node-RED


If I/o expander is used for inputs the point is to be able to write a function that converts from hex to binary and then parse each of the 8 bits on a different output msg.

If I/O expander is used for outputs then needs a function that combines the input of 8 single bit as a msg1,msg2 etc... and give a single 8 bits binary number and then is able to convert this to hex.

I don't know if someone here know how to manage this or I guess someone already dealed with this because if nothing is already done at level of specific node, then this will be the clue to be able to handle the expansion board easily.

Regards

Simon .

unread,
Jul 14, 2017, 5:36:52 PM7/14/17
to node...@googlegroups.com
Thanks, I'll try this tonight. Was happy with the progress made yesterday.

Seems like it will be a real pain if that's how you activate a relay. Every time you send a value it sets all relays to that 8 bit number. So if relay 1 and 8 are on and you want to turn on two you need to send a value that has 1,2 & 8 as 1's.. like 1100001 ? Which in turn means I need a register to see where everything is up to. Way to make it complicated! Or I could be misunderstanding.

--
http://nodered.org
 
Join us on Slack to continue the conversation: http://nodered.org/slack
---
You received this message because you are subscribed to a topic in the Google Groups "Node-RED" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/node-red/5z3swVVzv18/unsubscribe.
To unsubscribe from this group and all its topics, send an email to node-red+unsubscribe@googlegroups.com.

To post to this group, send email to node...@googlegroups.com.
Visit this group at https://groups.google.com/group/node-red.

Dave C-J

unread,
Jul 14, 2017, 6:06:36 PM7/14/17
to node...@googlegroups.com
yes that's the way it will work I suspect  - get your binary & and or fu going ;-)

David Caparrós

unread,
Jul 14, 2017, 6:20:15 PM7/14/17
to Node-RED

Take into consideration "1,2 & 8 as 1's.. like 1100001"  will really be 10000011 passed to ex will be 83 so write 0x83.... exactly as you told, painful

Simon

unread,
Jul 15, 2017, 7:43:42 AM7/15/17
to Node-RED
Still cant see the way to turn the relays on or off. The UniPi is installed now with a load on the first relay ready to be switched. i'd be happy with turning them all on for a first step. I tried this:  i2cset -y 1 0x20 0xff and it didnt work.. what am I missing?

David Caparrós

unread,
Jul 15, 2017, 7:55:40 AM7/15/17
to Node-RED
What you get when you make on a console:  i2cdetect -y 1
?????????

Simon

unread,
Jul 15, 2017, 7:58:53 AM7/15/17
to Node-RED

root@unipi:~# i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- 18 -- -- -- -- -- -- --
20: 20 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: 50 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- 6f
70: -- -- -- -- -- -- -- --

0x20 is the relay mcp chip

David Caparrós

unread,
Jul 15, 2017, 8:28:42 AM7/15/17
to Node-RED
How many bits has yours? I assumed is like mine 8 bits but maybe not...

If you make i2cset -y 1 0x20 0x01      the first bit is not set to 1?
Did you tried to read what returns you with i2cget -y 1 0x20  ????????

Simon .

unread,
Jul 15, 2017, 8:29:56 AM7/15/17
to node...@googlegroups.com
I think it returned 0x00 before I tried those other set commands.

--
http://nodered.org
 
Join us on Slack to continue the conversation: http://nodered.org/slack
---
You received this message because you are subscribed to a topic in the Google Groups "Node-RED" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/node-red/5z3swVVzv18/unsubscribe.
To unsubscribe from this group and all its topics, send an email to node-red+unsubscribe@googlegroups.com.
To post to this group, send email to node...@googlegroups.com.
Visit this group at https://groups.google.com/group/node-red.

David Caparrós

unread,
Jul 15, 2017, 8:34:55 AM7/15/17
to Node-RED

Try first to see the actual status with i2cget, then write 1 on the first bit with i2cset  -y 1 0x20 0x01   and then read again with i2cget -y 1 0x20

and lets see what you get 

Simon .

unread,
Jul 15, 2017, 8:37:36 AM7/15/17
to node...@googlegroups.com
Ran out of time tonight, but on this page it shows the register of the gpios is 0x09? 



On 15 Jul. 2017 22:35, "David Caparrós" <davi...@gmail.com> wrote:

Try first to see the actual status with i2cget, then write 1 on the first bit with i2cset  -y 1 0x20 0x01   and then read again with i2cget -y 1 0x20

and lets see what you get 

--
http://nodered.org
 
Join us on Slack to continue the conversation: http://nodered.org/slack
---
You received this message because you are subscribed to a topic in the Google Groups "Node-RED" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/node-red/5z3swVVzv18/unsubscribe.
To unsubscribe from this group and all its topics, send an email to node-red+unsubscribe@googlegroups.com.
To post to this group, send email to node...@googlegroups.com.
Visit this group at https://groups.google.com/group/node-red.

David Caparrós

unread,
Jul 15, 2017, 8:54:20 AM7/15/17
to Node-RED
I don't understand the answer, I was askng you to make this specific test to see what you had before and after.

0x09 means 00001001   suposing you have a multiplexor with 8 bits only, means first and fourth bit set to 1 and others to 0.

Regards 

Simon

unread,
Jul 16, 2017, 8:07:25 AM7/16/17
to Node-RED
This is the return of what you asked me to test. The relay didn't activate.

root@unipi:~# i2cget -y 1 0x20 
0x00
root@unipi:~# i2cset -y 1 0x20 0x01
root@unipi:~# i2cget -y 1 0x20 
0x00

Sorry - new to i2c and its not making sense yet.

David Caparrós

unread,
Jul 16, 2017, 10:00:03 AM7/16/17
to Node-RED

Hello Simon

You told me that you get:

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- 18 -- -- -- -- -- -- --
20: 20 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: 50 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- 6f
70: -- -- -- -- -- -- -- --

Frankly speaking I don't know why you see so many address as I only see 20.

Did you tried to do same test with another address to see what happens? for instance 0x18?  Maybe you assumed the one you wanted to work with is 20 and is not the correct one.

Regards

Simon .

unread,
Jul 16, 2017, 11:47:04 PM7/16/17
to node...@googlegroups.com
If you check the unipi 1.1 manual it states the addresses for all attached i2c components. This includes the MCP chip on 0x20 and eeprom on 0x57. I won't list them here, but the output is as expected at that stage.

--
http://nodered.org
 
Join us on Slack to continue the conversation: http://nodered.org/slack
---
You received this message because you are subscribed to a topic in the Google Groups "Node-RED" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/node-red/5z3swVVzv18/unsubscribe.
To unsubscribe from this group and all its topics, send an email to node-red+unsubscribe@googlegroups.com.
To post to this group, send email to node...@googlegroups.com.
Visit this group at https://groups.google.com/group/node-red.

Simon

unread,
Jul 17, 2017, 3:07:43 AM7/17/17
to Node-RED
Ok, so the following commands worked:

root@unipi:~# i2cset -y 1 0x20 0x00 0x00  (set to output)
root@unipi:~# i2cset -y 1 0x20 0x09 0x01  (turn relay 1 on)
root@unipi:~# i2cset -y 1 0x20 0x09 0x00  (turn relay 1 off)

So now I have to convert to node red, with the first line injecting once at start then a funstion to read which relays are meant to be on via a shadowing style register in node-red and the relay to be actioned, convert to hex and send.

Simon

unread,
Jul 17, 2017, 4:39:51 AM7/17/17
to Node-RED
So if i use i2cset -y 1 0x20 0x00 0xfe before the turn on command would that preserve the status of the other 7 relays whether they are on or off? Or should I send the whole 8 bit register each time with the relays that were on and the relays i want on?

David Caparrós

unread,
Jul 17, 2017, 7:17:38 AM7/17/17
to Node-RED
This is the point Simon, should be a better way to do it that allows you to read/writte a single bit at a time or is a mess..... I was doing some investigation on the net about this but still don't have it clear.

If you find something let me know.

Regards

Dave C-J

unread,
Jul 17, 2017, 8:23:54 AM7/17/17
to node...@googlegroups.com
Simon
did you see node-red-contrib-i2c
may help at some point.

I suspect that as the device itself uses registers it will be 8bit wide read and write so you will need to maintain state of the other bits/relays and send the complete byte each time.

The way to expose one bit at a time would be to create a specific node that does that - but under the covers it would have to do the same thing (keep state - get and set the whole byte).
Reply all
Reply to author
Forward
0 new messages