Since I started reviewing different boards (i.e. those other than the Raspberry Pi), one thing that has always stood out a mile has been lack of GPIO support. Well, that’s now history – at least for Node-Red users.
I cannot being to express how sick and tired I am of hearing about not being able to access GPIO without ROOT access. On the one hand you’re not supposed to use root – on the other hand if you are not root you can’t do this… you can’t do that… the Raspberry Pi and other devices are learning tools for heaven’s sake – it’s as if some folk don’t want us to succeed until we’re as clever as them!!! GRRR.
So you can imagine how pleased I was as this learning exercise started to unfold. It turns out – that there IS a way… read on…
Let me explain: For the Raspberry Pi there are a number of means of accessing GPIO – not least the standard GPIO nodes in Node-Red. These nodes however generally do not work with other boards and there are a lot of very good other boards out there. This solution seems to work with the Raspberry Pi AND other boards too. I’ve tested Orange Pi Zero, FriendlyArm Nanopi Plus2 – and I feel pretty sure it will work with many other boards too.
I think one of the first to get third party support was the Orange Pi (not from the company – I’m unaware of anyone getting direct help). But until recently, the likes of the FriendlyArm boards really had very little support – and what there was, was C code which needed to be operated by the ROOT user and that can pose problems for some programs.
Recently after certainly requests from me and no doubt others, FriendlyArm made the WIRINGNP utility (there’s a WIRINGOP version for Orange Pi) which comes with GPIO and though this still requires root – you can access the ports from Node-Red via the EXEC node using a SUDO call to the GPIO utility. It isn’t ideal or fast – but then normal Raspberry Pi GPIO isn’t fast either. Thanks to the changes that FA have made I’ve been able to use the LUMA Python library to easily access for example SD1306 OLED I2c displays from Node-Red.
As many Linux power users will know – the GPIO can be accessed as files at /sys/class/gpio – again – root access by default – just not as easy as dropping a box into Node-Red.
Well, now it is – I invite you to read https://flows.nodered.org/node/node-red-contrib-opi-gpio
So now it is possible to select a GPIO pin and turn it on or off – and read it – even with interrupts. In some cases via a drop down box, in others, via a simple gpio manual selector. Either way it is EASY.
In the instructions you’ll see in that link above, you may have to run some code to ensure that your PI user has access to the GPIO – well, that was too messy for me so I asked Antonio for a little help and we’ve just added this to “the script” – you can run it stand alone – though the logging won’t work – and that’s fine – or.
getent group gpio || sudo groupadd gpio 2>&1 | tee -a $LOGFILE
getent group gpio | grep -w -l pi || sudo adduser pi gpio 2>&1 | tee -a $LOGFILE
[ ! -f /etc/udev/rules.d/99-com.rules ] && echo “KERNEL==\”gpio*\”, RUN=\”/bin/sh -c ‘chgrp -R gpio /sys/%p /sys/class/gpio && chmod -R g+w /sys/%p /sys/class/gpio’\”” | sudo tee -a /etc/udev/rules.d/99-com.rules > /dev/null
If the editor screws that up you’ll find it near the end of “the script”. So that takes care of making sure you have access.
So I added the Node-Red node which uses a library called ONOFF which in turn allows access – and sure enough – the NanoPi M3 was NOT on the dropdown list of boards – how was I going to add a pin from the M3 so I could toggle it up and down and read it.
Turns out it is easy – there is a formula for calculating the actual port of a GPIO pin based on it’s given name. It may not surprise you to know that Pin GPIOA0 is port 0. But what of B,C,D etc… GPIOC1 for example…
For every letter after A, add 32 – then the actual number. So C1 is 32+32+2 – i.e. port 66 – it is THAT easy. On the Pi you just use the GPIO numbers.
I can’t guaranteed this works on all boards but it works on the ones I’ve tried!! And I now have fast access to GPIO! The author is keen to develop this – and if you sent the author a list of pin names, actual physical pin numbers and the calculated port along with which board you are using – he’ll add them into the list of predefined boards but he IS looking for someone to take on this project. I don’t think it is that complex so on the lookout for a budding programmer as this could do with some frills.
This is great news for Node-Red users who need port access.
So the setup and the node are now in “the script” but there is nothing to stop you adding this in manually as you would any node and running the above code (as Pi user) to add permissions.
Oh yes I tried the Nanopi M3 as well and THAT worked.
For the adventurous – the fellow who made this node relies on a NODEJS package called ONOFF for his Node-Red Node – if you go to the source of THAT you’ll find other general nodejs packages for i2c and SPI – not had time to look at SPI yet but the I2c library works a TREAT – I have it running in another blog entry with my Nano peripheral – but could it be that we’re about to be able to make full use of GPIO on the various boards out there – at last?
The only caviat at this point is that I found one board that only partly works. The Neo PLUS2 at first insisted that the user does not have permission as seen here
29 Jul 11:12:43 – [info] [opi_out:PA6] Pin: 6
29 Jul 11:12:43 – [error] [opi_out:a9041de2.0d817] Error: EACCES: permission denied, open ‘/sys/class/gpio/gpio6/value’
I rebooted the machine and now it worked but some other bits said
29 Jul 12:17:16 – [error] [opi_out:a9041de2.0d817] Error: EBUSY: resource busy or locked, write
Maybe I just happened to pick pins that had other uses already.
Using the node I had no problem with some of the other bits – and to make life easy, FriendlyArm in their WIKIs so specify the actual Linux port numbers. This example being for the Plus 2
I had no problem with ports 12, 11,2,0,2,3, 64,65,66,67 (0 is currently entered as 00 due to a bug in the node which does not store the last setting but defaults to 0) but 201, 203 and 1 gave me problems.
Meanwhile for that particular board, for those who’ve use FriendlyArm’s own software, there is of course the GPIO software which can be used by any user. However there’s a bug in that which I’ve reported.. gpio write 6 1 should turn on physical pin 6 – instead it turns on physical pin 22 (even the gpio number doesn’t match). I suspect they’ve copied the table over from another board and forgotten to update it. Physical pin 7 works. Of course it could be that they’ve messed something up in GPIO that is affecting other attempts to get to these ports.
On the Raspberry Pi it is important not to wipe out the existing 99-rule.com because in the latest version, that already has some rules to get around the (sometimes somewhat inappropriate) tight security regarding gpio – Github contributor FIVDI sent this which is found in the Raspberry Pi.
SUBSYSTEM=="input", GROUP="input", MODE="0660"
SUBSYSTEM=="i2c-dev", GROUP="i2c", MODE="0660"
SUBSYSTEM=="spidev", GROUP="spi", MODE="0660"
SUBSYSTEM=="bcm2835-gpiomem", GROUP="gpio", MODE="0660"
SUBSYSTEM=="gpio*", PROGRAM="/bin/sh -c '\
chown -R root:gpio /sys/class/gpio && chmod -R 770 /sys/class/gpio;\
chown -R root:gpio /sys/devices/virtual/gpio && chmod -R 770 /sys/devices/virtual/gpio;\
chown -R root:gpio /sys$devpath && chmod -R 770 /sys$devpath\
'"
IF ANYONE IS FEELING AMBITIOUS – if you could test the gpio ports on a board you have – and return the results here – board type – pins tested by name and actual pin number – these could be fed back to the author – everyone wins… !!!!
Testing – if you need a quick toggle to test a GPIO – I just realised I could use my own Node-Red node for the job… node-red-contrib-timeout. Set the warning to 1, the countdown to 1, the unsafe state payload to 0 and the safe state and warning states to 1… and that’s it.. you have a toggle once a second. node-red-contrib-timeout
Incidentally, in getting excited about this new ability to easily access GPIO, I got a bit frustrated with my FriendlyArm M3 board – there’s a 2mm connector on there called LVDS and no-where on their website could I find information. I thought there might be some useful GPIO I could use. I wrote off to FA and they sent me some data. Here’s the LVDS connector – I notice some potentially useful GPIO therein and possibly even another I2c channel?
Hi Pete , I am very grateful I found this blog,
I would like to say thank you for what you have done by sharing your knowledge.
With basic linux I have, I am playing with old RPI 1 model B for and Installed Node-Red
For couple days I spent and trying to get the max of GPIO Pin headers that I can use as regular onoff in/out,
as the standard RPI define by Node-Red only 7 pins.
I have tested using this library, I can have 20 all of them to connect to my relays and magnetic sensors, with secondary GPIO Header (only RPI 1 ver. B have this pins) . before I continue connecting the wires for my buttons, I stumbled with the update
https://github.com/fivdi/onoff with update of library ver3.02
the one was installed through NPM in my RPI was
├─┬ node-red-contrib-opi-gpio@0.0.5
└─┬ onoff@1.1.9
└─┬ epoll@1.0.2
├── bindings@1.3.0
└── nan@2.8.0
I am thinking if I want to apply button for my application, the updated library would be better. but don’t don’t know how to apply in Node-Red, hopefully the author can update it and fixed about the Node won’t pickup the existing working node for editing.
If you have chance and would you give comment , Thank you.
Eganov
and a new gpio access method, in newer kernels: https://www.cnx-software.com/2017/11/03/learn-more-about-linuxs-new-gpio-user-space-subsystem-libgpiod/
Indeed – the comments however are quite valid – why on EARTH did they have to make it so cryptic – hardly something beginners will welcome – for heavens sake – just to turn a port bit on and off – couldn’t they have hidden some more – the Arduino model is already out there – one line to set the port up, another to use it… they could have followed that….
regarding your comment here (https://github.com/fivdi/pigpio/issues/31#issuecomment-321685451), it seems like it’d be possible to run the pigpio *daemon* and then write something that’d talk to it. unsure if that has to be a replacement for raspi-gpio (which we can then tell node-red-contrib-gpio to use), OR if we can swap out an underlying module –since raspi-gpio is itself an adapter to raspi (https://npm.im/raspi).
I could be interested in working on such a thing if it doesn’t exist!
Hi Christopher
Yes, using the daemon would indeed be one way. The new capability we see with node-red-contrib-opi-gpio however does seem to be the way forward – it is based on ONOFF which is a nodejs library which is pulled in automatically by the node. I’ve now tested this on a Raspberry Pi 3 and it works a treat. The author of this node however is pushed for time and is happy for someone else to take it on. It comprises 2 HTML files and some javascript. Combined with the little bit of code to update the SBC (which again clearly works on the Pi3 as well as numerous other boards). Here’s what I’d like to see done to this which could then possibly become THE node to use for GPIO….
I’d like to see PWM added. As hardware PWM (the only way) is usually only one pin on most of these SBCs, I can’t see that being too hard
I would ditch the board-specific code and just have a pin number with possible initialisation.
The name suggests Orange Pi specific – I’d bing that – maybe node-red-general-gpio or similar.
Along with the i2c and SPI libraries by the author of ONOFF – which don’t go via Python but go straight to the Linux registers – it seems to me that this is heading in the right direction.
Ah, got it–was a bit confused. This onoff lib looks promising. I’ll toss it into a project I’m working on…
So the main shortcoming here is lack of PWM?
Well, I’m not sure it’s a shortcoming, Christopher – if you look at the various boards most only have one hardware PWM channel anyway, the rest are software, hardly ideal on an operating system like Linux and really not quite good enough to fade lights etc. So the same place the onoff lib comes from – is the i2c lib and that works a TREAT – as you’ll see elsewhere in the blog – so for me I’m now concentrating on using the little Nano board as an i2c “kitchen sink” peripheral – and that includes several rock-steady PWM channels. So the onoff lib is the basis of the nodes discussed here – and the only issue with these is they were originally put together for the Orange Pi and the author does not have time to add every board known to man (I’m using them on the Raspberry Pi as they are fast and can be used without the pesky “root” access. I would like to strip out board-specific stuff and simply have the port selection, possibly documenting board-specific stuff in the help – something for the future – for now – all good stuff – the nodes work – the onoff library works – one step forward…
I’m not sure why but the link right now gives 404 (https://webcache.googleusercontent.com/search?q=cache:9D8pCzPczAUJ:https://flows.nodered.org/node/node-red-contrib-opi-gpio+&cd=1&ct=clnk).
You are right alessandro. Well, I’ve looked and it is still in place but just not showing in the flows library.
https://www.npmjs.com/package/node-red-contrib-opi-gpio
So the designer has updated it to take into account a bug I pointed out and to handle the AIR which I happened to be working on when I wrote in. So current version is 0.04 published just a few hours ago.
I’ve dropped the author a line to say it is missing – but you can still install it and I’ve just updated mine now (just again by a simple install…
By the following in my case.. from the pi directory
node-red-stop
cd .node-red
npm install node-red-contrib-opi-gpio
node-red-start
You can probably do it inside node-red but that’s the way I’m used to updating nodes.
Sadly, when using OTHER (to handle devices not included) – the “output pin” field still does not show the pin you selected next time you go in to make a change – however – it works, regardless.
If the 99 file already exists, please modify last line, add a “-a” switch to that tee to append and not overwrite the file
I have an older Odroid which is setup similar but different (no …/gpioN/value) but may have something similar.
BTW, what is %p ? (as in chgrp -R gpio /sys/%p /sys/class/gpio). I’m pretty sure I can just do chgrp -R gpio /sys/*
Okay just gave that a bit of thought and the /sys/* is a very bad idea as it opens up all the devices (and files) to group gpio. While that isn’t really a problem for my device sitting at home. It is a bit looser security than I like else where.
By all means change it – for me it is the SECURITY that is my biggest problem.