I've written a (mostly) Arduino compatible/style Wiring library for the GPIO pins on the Raspberry Pi. It's in C, so if your familiar with the Arudinos Wiring library, then this should "just work" for you. It lets you control all 15 pins for general purpose digital IO, and supports the PWM output too.
https://projects.drogon.net/raspberry-pi/wiringpi/
GPL code - Feedback welcome.
Gordon
Wiring for the Raspberry Pis GPIO
21 posts
That looks great, some good explanation of the GPIO and I look forward to being able to try out the library.
_________________________________
http://www.themagpi.com/
A Magazine for Raspberry Pi Users
Read Online or Download for Free.
Released at the start of each month.
Meltwater's Pi Hardware - pihardware.com
Like the MagPi? @TheMagP1 @TheMagPiTeam
http://www.themagpi.com/
A Magazine for Raspberry Pi Users
Read Online or Download for Free.
Released at the start of each month.
Meltwater's Pi Hardware - pihardware.com
Like the MagPi? @TheMagP1 @TheMagPiTeam
according to http://elinux.org/Rpi_Low-leve.....eripherals there are 17 GPIO pins, rather than 15. Are two of them not useable as GPIO?
On the production board, all the UART, SPI and I2C pins can be reconfigured as GPIO pins, to provide a total of 17 GPIO pins[3].
The complete list of chipset GPIO pinswhich are available on the GPIO connector is:
On the production board, all the UART, SPI and I2C pins can be reconfigured as GPIO pins, to provide a total of 17 GPIO pins[3].
The complete list of chipset GPIO pinswhich are available on the GPIO connector is:
0, 1, 4, 7, 8, 9, 10, 11, 14, 15, 17, 18, 21, 22, 23, 24, 25
jbeale said:
Yes, the 2 I've not used are the UART pins. To use them as general purpose pins you need to reboot Linux with the serial console disabled.
So I've quietly ignored them for now, however it's a moments work to add them in (just add the pin numbers into the wiringPi.c file in the pinRemap[] array) … Maybe I'll put them in for completeness though with another note on the specials page…
Quick update - I've done just that now.
Thanks,
Gordon
according to http://elinux.org/Rpi_Low-leve.....eripherals there are 17 GPIO pins, rather than 15. Are two of them not useable as GPIO?
On the production board, all the UART, SPI and I2C pins can be reconfigured as GPIO pins, to provide a total of 17 GPIO pins[3].
The complete list of chipset GPIO pinswhich are available on the GPIO connector is:
0, 1, 4, 7, 8, 9, 10, 11, 14, 15, 17, 18, 21, 22, 23, 24, 25
Yes, the 2 I've not used are the UART pins. To use them as general purpose pins you need to reboot Linux with the serial console disabled.
So I've quietly ignored them for now, however it's a moments work to add them in (just add the pin numbers into the wiringPi.c file in the pinRemap[] array) … Maybe I'll put them in for completeness though with another note on the specials page…
Quick update - I've done just that now.
Thanks,
Gordon
Any chance of pre-compiling something for us? I am honesty more of a PERL guy, so simply having a binary that I can call would be quite useful. Something like "getgpio" and "setgpio."
Just a humble request. It has been a LONG time since I have done any C, but I am sure that I could dust off the cobwebs and make this myself, WHEN I finally get my own Pi.
Just a humble request. It has been a LONG time since I have done any C, but I am sure that I could dust off the cobwebs and make this myself, WHEN I finally get my own Pi.
- Posts: 21
- Joined: Mon Feb 27, 2012 4:56 pm
Harrkev said:
Sure. Hm. It's slightly stateful though in that to map the IO, it needs to open a file to /dev/mem. Not sure how it would subsequently interface to Perl then... It's certainly do-able though via a set of commands as you suggest, not as efficient as using it as a library though. I'll have a look later this evening or tomorrow - at a paying job today!
Gordon
Any chance of pre-compiling something for us? I am honesty more of a PERL guy, so simply having a binary that I can call would be quite useful. Something like "getgpio" and "setgpio."
Just a humble request. It has been a LONG time since I have done any C, but I am sure that I could dust off the cobwebs and make this myself, WHEN I finally get my own Pi.
Sure. Hm. It's slightly stateful though in that to map the IO, it needs to open a file to /dev/mem. Not sure how it would subsequently interface to Perl then... It's certainly do-able though via a set of commands as you suggest, not as efficient as using it as a library though. I'll have a look later this evening or tomorrow - at a paying job today!
Gordon
Harrkev said:
OK. Here you go
At you request, I've written a command-line program that calls my Wiring Library. It's innefficient as it forks the command for every operation, but really, for what we're doing, who cares right now... It's fine. If we want to pulse LEDs on and off 100's of times a second then we'll care, but for now it's OK.
Actually, I now wish I'd written this program earlier as it's quite handy!
So, do this: (copy and paste)
Then you should be able to run it as an ordinary user without usng sudo.
(But a word of warning here, I'm asking you to download and run a program as root that I've compiled - hopefully I'm trustworthy, but this is at your own risk!)
The commands are:
So gpio then
I'll post the source to it as part of the wiringPi package shortly.
Enjoy,
Gordon
Any chance of pre-compiling something for us? I am honesty more of a PERL guy, so simply having a binary that I can call would be quite useful. Something like "getgpio" and "setgpio."
Just a humble request. It has been a LONG time since I have done any C, but I am sure that I could dust off the cobwebs and make this myself, WHEN I finally get my own Pi.
OK. Here you go
At you request, I've written a command-line program that calls my Wiring Library. It's innefficient as it forks the command for every operation, but really, for what we're doing, who cares right now... It's fine. If we want to pulse LEDs on and off 100's of times a second then we'll care, but for now it's OK.
Actually, I now wish I'd written this program earlier as it's quite handy!
So, do this: (copy and paste)
cd /tmp
wget http://project-downloads.drogon.net/files/gpio
cd /usr/local/bin
sudo mv /tmp/gpio .
sudo chown root.root gpio
sudo chmod 4755 gpio
Then you should be able to run it as an ordinary user without usng sudo.
(But a word of warning here, I'm asking you to download and run a program as root that I've compiled - hopefully I'm trustworthy, but this is at your own risk!)
The commands are:
gpio mode 0 out
gpio mode 8 in
gpio mode 1 pwm
gpio write 0 0
gpio write 0 1
gpio pwm 1 512
gpio read 8
0
gpio read 8
1
So gpio then
- mode, followed by the pin number (0-16) then in, out or pwm.
- write followed by the pin number then 0 or 1.
- pwm followed by the pin number (ie. 1) then the value 0-1023
- read followed by the pin number and it will print 0 or 1 depending on the pin state.
I'll post the source to it as part of the wiringPi package shortly.
Enjoy,
Gordon
Looks very useful so I added a link on the wiki page here:
http://elinux.org/RPi_Low-leve.....er_support
http://elinux.org/RPi_Low-leve.....er_support
GordonH said:
Thanks. Now, all that I need is a Pi.
Really, one of my first "real" uses of this will be to throw apache on there, and this will let PERL just let me know if some wires are high and some are low. That is all that I need. Thanks.
OK. Here you go
Thanks. Now, all that I need is a Pi.
Really, one of my first "real" uses of this will be to throw apache on there, and this will let PERL just let me know if some wires are high and some are low. That is all that I need. Thanks.
- Posts: 21
- Joined: Mon Feb 27, 2012 4:56 pm
jbeale said:
Thanks!
And from the "bash is not my most favourite of scripting languages" department:
While crude, it's very effective - I have 8 LEDs connected to the first 8 pins and they're flickering quite fast - 18% CPU usage though!
Gordon
Looks very useful so I added a link on the wiki page here:
http://elinux.org/RPi_Low-leve.....er_support
Thanks!
And from the "bash is not my most favourite of scripting languages" department:
#!/bin/bash
for i in `seq 0 7`;
do
gpio mode $i out
done
while true;
do
for i in `seq 0 7`;
do
gpio write $i 1
done
for i in `seq 0 7`;
do
gpio write $i 0
done
done
While crude, it's very effective - I have 8 LEDs connected to the first 8 pins and they're flickering quite fast - 18% CPU usage though!
Gordon
Harrkev said:
Apache is a standard debian package, so you'll have no issues there. mod-perl too which is good for a bit of speed. Calling the gpio program several times for each web page refersh won't be the most efficient way - but if you wanted to, you could hack the C to do specific things - e.g. output 8 input pins at once for example - in a format easier to parse for the perl, and so on.
Perl does have the mmap function, but it's been years since I did any perl work - so it might be possible to do it natively in Perl, but I don't relish that task
However you'd then need to run the script as root, but using my gpio program here, if installed setuid to root, means that you don't need to.
Gordon
GordonH said:
OK. Here you go
Thanks. Now, all that I need is a Pi.
Really, one of my first "real" uses of this will be to throw apache on there, and this will let PERL just let me know if some wires are high and some are low. That is all that I need. Thanks.
Apache is a standard debian package, so you'll have no issues there. mod-perl too which is good for a bit of speed. Calling the gpio program several times for each web page refersh won't be the most efficient way - but if you wanted to, you could hack the C to do specific things - e.g. output 8 input pins at once for example - in a format easier to parse for the perl, and so on.
Perl does have the mmap function, but it's been years since I did any perl work - so it might be possible to do it natively in Perl, but I don't relish that task
However you'd then need to run the script as root, but using my gpio program here, if installed setuid to root, means that you don't need to.
Gordon
Isn't this why the driver exports the /sys/class/gpio interface to userspace...? Seems friendlier for scripting, doesn't require root or suid binaries, and is not platform specific. I can see the appeal of an Arduino-like C++ interface, but scripts should use the standard Linux interfaces.
- Posts: 351
- Joined: Wed Dec 21, 2011 11:49 pm
error404 said:
Yeah, exactly like this python library does http://pypi.python.org/pypi/RPi.GPIO
Isn't this why the driver exports the /sys/class/gpio interface to userspace...?
Yeah, exactly like this python library does http://pypi.python.org/pypi/RPi.GPIO
AndrewS said:
Sure, but neither myself nor Harrkev are Python programmers and he asked for a command-line version, so I obliged... I know it's not efficient but I have to say it's really not that important for initial testing and simple scripts, etc.
And as usual in the unix world, there are 1000 ways of doing something
(and have you actually poked /sys/class/gpio entries yourself from a script? It's great that they exist, but a bit of a pita - the Python wrapper is a good step forwards in that department)
Personally I think we need somthing like this for the people who will be coming from Arduino land (and there are 1000's of them out there) - also, I feel that there is (or might) be a need for some sort of mapping layer between the hardware and the "pin" - if there is a Model C for exmaple with different/more IO it might be handy to have a common reference.
Anyway..
Ideally, I'd like to see a proper device driver for them - a kernel module and something in /dev that you can open and use for 2 purposes - initially to send high-level commands to (using standard read/write system calls), and secondly to allow mmap of the GPIO IO region (from user land, not root)- but checking that you're maping the right range, etc. I feel that needing a root program to do the mmap is somewhat "fragile" and a mistake could take-down your entire system, however while I'd like to do this, time is not my friend right now! The mmap method (used by wiringPi) is ultimately the fastest and most efficient way to poke the pins, if not the easiest to do in a script.
Gordon
error404 said:
Isn't this why the driver exports the /sys/class/gpio interface to userspace...?
Yeah, exactly like this python library does http://pypi.python.org/pypi/RPi.GPIO
Sure, but neither myself nor Harrkev are Python programmers and he asked for a command-line version, so I obliged... I know it's not efficient but I have to say it's really not that important for initial testing and simple scripts, etc.
And as usual in the unix world, there are 1000 ways of doing something
(and have you actually poked /sys/class/gpio entries yourself from a script? It's great that they exist, but a bit of a pita - the Python wrapper is a good step forwards in that department)
Personally I think we need somthing like this for the people who will be coming from Arduino land (and there are 1000's of them out there) - also, I feel that there is (or might) be a need for some sort of mapping layer between the hardware and the "pin" - if there is a Model C for exmaple with different/more IO it might be handy to have a common reference.
Anyway..
Ideally, I'd like to see a proper device driver for them - a kernel module and something in /dev that you can open and use for 2 purposes - initially to send high-level commands to (using standard read/write system calls), and secondly to allow mmap of the GPIO IO region (from user land, not root)- but checking that you're maping the right range, etc. I feel that needing a root program to do the mmap is somewhat "fragile" and a mistake could take-down your entire system, however while I'd like to do this, time is not my friend right now! The mmap method (used by wiringPi) is ultimately the fastest and most efficient way to poke the pins, if not the easiest to do in a script.
Gordon
I'm struggling to download the wiringPi.tgz file, keeping in mind though that I'm very much new to Linux and I'm on a virtualbox still waiting for my Pi to arrive.
However, when I run 'wget http://project-downloads.drogo......tgz' I get a 403 Access Forbidden error. Browsing to http://project-downloads.drogo......net/files I can right-click and save the file but it is only 298 bytes. Trying to tar it (is that the correct jargon?) I get an error 'gzip: stdin: not on gzip format'.
User error or is there a problem with the file?
However, when I run 'wget http://project-downloads.drogo......tgz' I get a 403 Access Forbidden error. Browsing to http://project-downloads.drogo......net/files I can right-click and save the file but it is only 298 bytes. Trying to tar it (is that the correct jargon?) I get an error 'gzip: stdin: not on gzip format'.
User error or is there a problem with the file?
- Posts: 16
- Joined: Mon Aug 29, 2011 12:25 am
floydbloke said:
Checking now... Oops. Mea maxima culpa... I uploaded the version last night to incorporate the additional UART Rx/Tx pins and my own security settings shot me in the foot. (Default is to not allow world/web access). Try now.
Gordon
I'm struggling to download the wiringPi.tgz file, keeping in mind though that I'm very much new to Linux and I'm on a virtualbox still waiting for my Pi to arrive.
However, when I run 'wget http://project-downloads.drogo......tgz' I get a 403 Access Forbidden error. Browsing to http://project-downloads.drogo......net/files I can right-click and save the file but it is only 298 bytes. Trying to tar it (is that the correct jargon?) I get an error 'gzip: stdin: not on gzip format'.
User error or is there a problem with the file?
Checking now... Oops. Mea maxima culpa... I uploaded the version last night to incorporate the additional UART Rx/Tx pins and my own security settings shot me in the foot. (Default is to not allow world/web access). Try now.
Gordon
GordonH said:
It also raises the issue of what might be the best way to distribute software - the tar.gz & compile it yourself format has been around more or less forever and it's fairly universal over different Linux platforms (e.g. Debian, Fedora, Arch, etc.) but each distribution has its own packaging format (well, deb and rpm). I'm more or less entrenched in the world of Debian, so I could produce deb packages, but that might then leave RedHat people feeling a bit left out... (and certianly, binaries produced under RedHat will not work under Linux without some deep system level manipulations - at least in the x86 land as I found out recently - a client wanted to run FlexLM - it's released as a binary for RedHat, but client only has Debian servers )-:
So I don't know whats best and am open to suggestions!
Gordon
Checking now... Oops. Mea maxima culpa... I uploaded the version last night to incorporate the additional UART Rx/Tx pins and my own security settings shot me in the foot. (Default is to not allow world/web access). Try now.
It also raises the issue of what might be the best way to distribute software - the tar.gz & compile it yourself format has been around more or less forever and it's fairly universal over different Linux platforms (e.g. Debian, Fedora, Arch, etc.) but each distribution has its own packaging format (well, deb and rpm). I'm more or less entrenched in the world of Debian, so I could produce deb packages, but that might then leave RedHat people feeling a bit left out... (and certianly, binaries produced under RedHat will not work under Linux without some deep system level manipulations - at least in the x86 land as I found out recently - a client wanted to run FlexLM - it's released as a binary for RedHat, but client only has Debian servers )-:
So I don't know whats best and am open to suggestions!
Gordon
Thanks Gordon
Working sweetly now. Only 4 weeks to wait until my Pi ships.
As for best method to distribute, the tar and compile works for me. Especially with the step by step instructions on your website, it still gives me a bit of a feeling of being in control as I can see what step does what, and learn something at the same time.
Working sweetly now. Only 4 weeks to wait until my Pi ships.
As for best method to distribute, the tar and compile works for me. Especially with the step by step instructions on your website, it still gives me a bit of a feeling of being in control as I can see what step does what, and learn something at the same time.
- Posts: 16
- Joined: Mon Aug 29, 2011 12:25 am
At the risk of getting too off-topic, let me just justify myself, I don't want to get into an argument and definitely think the library you've created is valuable.
GordonH said:
Well the reason I bring it up is more one of a hatred for specialized solutions to general problems (ie. NIH syndrome). This problem is already solved, in a platform-agnostic and generic way that should work with minimal change on any Linux machine. mmaping the I/O region is something that really should be avoided for any end user IMHO; the memory twiddling is code that belongs in the kernel except for very performance critical tasks (which obviously a shell script is not). It's dangerous, platform specific, and especially via the helper program route doesn't offer any performance gain. Also encouraging people new to Linux to just run things as root to make them work is a bit (understatement) of a step backward.
I don't really see the problem with the kernel sysfs interface, it's laid out much like any other sysfs interface is, so you're actually learning something generically useful about Linux by using it, and it's not much more awkward than calling an external helper. It only becomes a bit of a pain when you want to access blocks of GPIO at once, but that's what shell globs are for.
There has been a lot of talk about Arduino vs. the Pi and whatnot, so I think you're right about a lot of Arduino users trying out the Pi, and certainly a C++ library for GPIO is a useful thing regardless of that influx. Just to be clear, I think what you've done is very useful for exactly that, I just wouldn't be very happy to see your shell helper become popular as it adds little and makes everything using it unnecessarily tied to RaspberryPi.
As you say, anyway…
As far as packaging, I prefer Debian as well, so I'd vote for a .deb, plus a static binary .tar.gz (we're platform specific here anyway...) and source. In this space of tiny machines I think you should kind of expect people not to have build tools.
GordonH said:
I know it's not efficient but I have to say it's really not that important for initial testing and simple scripts, etc.
Well the reason I bring it up is more one of a hatred for specialized solutions to general problems (ie. NIH syndrome). This problem is already solved, in a platform-agnostic and generic way that should work with minimal change on any Linux machine. mmaping the I/O region is something that really should be avoided for any end user IMHO; the memory twiddling is code that belongs in the kernel except for very performance critical tasks (which obviously a shell script is not). It's dangerous, platform specific, and especially via the helper program route doesn't offer any performance gain. Also encouraging people new to Linux to just run things as root to make them work is a bit (understatement) of a step backward.
I don't really see the problem with the kernel sysfs interface, it's laid out much like any other sysfs interface is, so you're actually learning something generically useful about Linux by using it, and it's not much more awkward than calling an external helper. It only becomes a bit of a pain when you want to access blocks of GPIO at once, but that's what shell globs are for.
Personally I think we need somthing like this for the people who will be coming from Arduino land (and there are 1000's of them out there) – also, I feel that there is (or might) be a need for some sort of mapping layer between the hardware and the "pin" – if there is a Model C for exmaple with different/more IO it might be handy to have a common reference.
There has been a lot of talk about Arduino vs. the Pi and whatnot, so I think you're right about a lot of Arduino users trying out the Pi, and certainly a C++ library for GPIO is a useful thing regardless of that influx. Just to be clear, I think what you've done is very useful for exactly that, I just wouldn't be very happy to see your shell helper become popular as it adds little and makes everything using it unnecessarily tied to RaspberryPi.
As you say, anyway…
As far as packaging, I prefer Debian as well, so I'd vote for a .deb, plus a static binary .tar.gz (we're platform specific here anyway...) and source. In this space of tiny machines I think you should kind of expect people not to have build tools.
- Posts: 351
- Joined: Wed Dec 21, 2011 11:49 pm
GordonH said:
Actually, yes
Not on the Pi though (don't have one yet) but for a similar embedded-Linux-computer
https://sites.google.com/site/bifferboard/Home/desktop-linux-distributions/slackware/gpio/flash-red-led
(this is a deliberately over-engineered example)
And as usual in the unix world, there are 1000 ways of doing something
(and have you actually poked /sys/class/gpio entries yourself from a script? It's great that they exist, but a bit of a pita - the Python wrapper is a good step forwards in that department)
Actually, yes
Not on the Pi though (don't have one yet) but for a similar embedded-Linux-computer
https://sites.google.com/site/bifferboard/Home/desktop-linux-distributions/slackware/gpio/flash-red-led
(this is a deliberately over-engineered example)
Wow nice, thank you very very much. Would use it for my project.
- Posts: 17
- Joined: Sat Sep 10, 2011 6:48 am