GizmoB73
Posts: 80
Joined: Fri Jan 27, 2012 12:51 pm

Re: Reading values from GPIO input pins?

Thu Apr 26, 2012 6:48 pm

I have got the LED blinking sorted out using a modified version of the sample C++ code from the wiki. http://elinux.org/RPi_Low-leve.....e_examples

I am trying to figure out how to read inputs though.

If I have GPIO Pin 0 (P1-07 on the Pi) which is GPIO 4 on the SoC, wired to 3.3v via a 10K resistor for example, how do I read that value from the registers?

I get that the register values are stored in the volatile unsigned *gpio.  But how do I decode the contents of *gpio to figure out the state of the input pin I am interested in?

Can anybody point me in the right direction?

GizmoB73
Posts: 80
Joined: Fri Jan 27, 2012 12:51 pm

Re: Reading values from GPIO input pins?

Thu Apr 26, 2012 8:33 pm

Anybody know how to change the annoying typo in the topic title?

Bugger.

User avatar
Gert van Loo
Posts: 2485
Joined: Tue Aug 02, 2011 7:27 am
Contact: Website

Re: Reading values from GPIO input pins?

Thu Apr 26, 2012 9:32 pm

I assume you have set GPIO 4 to input mode.

Then you have to read the level register something like:

gpio_state = *gpio_level;

As it is GPIO 4 it must bit bit 4:

if (gpio_state & (1<<4))

printf("GPIO 4 is high\n");

else

printf("GPIO 4 is low\n");

Check the demo SW from the gertboard it sets GPIO pins to input, enables the pull up (So you don't need a resistor) reads it and displays a 'virtual' button on the screen. To see all that in motion look for gertboard2 on youtube.

Techmeology
Posts: 30
Joined: Wed Mar 28, 2012 8:52 pm
Contact: Website

Re: Reading values from GPIO input pins?

Thu Apr 26, 2012 11:50 pm

In my opinion, the easiest way to use the GPIO is the way implied by the shell script (should work from any language that supports file IO) as it"s just file IO, and has no need to know special knowledge of BCM2835 (and therefore less likely to have subtle bugs):

void init_gpio(int n)
{
char filename[256];
snprintf(filename, 256, "/sys/class/gpio/gpio%i/direction", n);

FILE *f = fopen("/sys/class/gpio/export", "w");
if (!f){
//some kind of error handling
}
fprintf(f, "%i", n);
fclose(f);

f = fopen(filename, "w");
if (!f){
//some kind of error handling
}
fprintf(f, "in", n);
fclose(f);
}

void deinit_gpio(int n)
{
FILE *f = fopen("/sys/class/gpio/unexport", "w");
if (!f){
//some kind of error handling
}
fprintf(f, "%i", n);
fclose(f);
}

int read_gpio(int n)
{
char filename[256];
snprintf(filename, 256, "/sys/class/gpio/gpio%i/value", n);
FILE *f = fopen(filename, "r");
if (!f){
//some kind of error handling
}
char c = 0;
if (1 != fread(&c, 1, 1, f)){
//some kind of error handling
}
fclose(c);
return c;
}

void write_gpio(int n, int v)
{
char filename[256];
snprintf(filename, 256, "/sys/class/gpio/gpio%i/value", n);
FILE *f = fopen(filename, "w");
if (!f){
//some kind of error handling
}
fprintf(f, "%i", v);
fclose(c);
return c;
}

Yeah, I guess file IO like this is long winded in C, but you get the idea.
Check out cool stuff I'm doing, e.g my PIC Programmer for the Raspberry Pi: http://www.techmeology.co.uk/rpipic/

User avatar
Dave_G_2
Posts: 196
Joined: Sat Apr 14, 2012 7:04 pm

Re: Reading values from GPIO input pins?

Fri Apr 27, 2012 9:36 am

Techmeology said:


In my opinion, the easiest way to use the GPIO is the way implied by the shell script (should work from any language that supports file IO) as it"s just file IO, and has no need to know special knowledge of BCM2835 (and therefore less likely to have subtle bugs):


Yes it would allow one port access without special knowledge of the chip set but it does make the code much longer and complicated.

Surely direct register access is much easier and faster using:

inw((unsigned long)REG_ADDRESS);

and

outw(REG_DATA,(unsigned long)REG_ADDRESS);

Could even take this one step further and make say 3 or 4 compiled apps that do the following:

1) Something called GPIO_SETUP that sets the appropriate pins to either inputs or outputs

2) GPIO_IN which reads the pins.

3) GPIO_OUT which outputs the required data to the pins

4) GPIO_RST which puts the registers back into their "normal" boot up state.

These could then be simply called via a script with parameters thus allowing someone starting out with GPIO experimentation to concentrate on the hardware at first without worrying about the nitty-gritty of the software.

Example:

# ======================================

#!/bin/sh

./GPIO_SETUP 10000001

# GPIO 7 and 0 are inputs and all others outputs

# it also writes the config to a file which subsequent GPIO_OUT and IN

# can read.

sleep 1

./GPIO_OUT 128

# sets both GPIO 0 and 7 high

Sleep 2

./GPIO_IN

# reads the config file created by GPIO_SETUP and reads and returns

# only those pins/bits set as inputs.

# =====================================

GizmoB73
Posts: 80
Joined: Fri Jan 27, 2012 12:51 pm

Re: Reading values from GPIO input pins?

Fri Apr 27, 2012 10:38 am

Thanks Gert and Techmeology.

As I am writing in C I think I will stick with the registers if I can.  They are more difficult to understand, but that it kind of the point (for me) I think anyway.  I like the idea of the better efficiency too.

Gert I have been looking through the Gert-Board code and cross-referencing it with the BCM2835 Datasheet for clarity.  Very helpful, thanks.

Good to see the alternative methods though, and always nice to have a fallback.

Hopefully we will soon have a Gert-Board too...  I thought something was happening this week? Any news?

Return to “Beginners”