kiloleader
Posts: 10
Joined: Tue Oct 14, 2014 9:02 am

C code to read GPIO input

Mon Nov 03, 2014 11:07 am

Hi all,

Does anyone have any c code (or super speedy Python?) to read the pulse length of a GPIO input.

I am trying to read demodulated IR pulses, in the order of 1ms - 5ms. The input signal appears as active low and typically goes:
5ms low 'start' bit
1ms high space
8 x data bits (either low 1.5ms or low 2ms) separated by 1ms high space bit
1ms high space
3ms low 'stop' bit

I want to verify the length of the start bit, each of the data bits and the stop bit in an accurate way. I have a python code dealing with the transmit side of my IR link(utilising pigpio) but cannot get an accurate read of the received signal. I have experimented with trying to get the python code to call a c script, but I am struggling (I am not very competent in C)!

I am running Raspian on a pi B+.

Any thoughts / examples are appreciated!

User avatar
joan
Posts: 14936
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: C code to read GPIO input

Mon Nov 03, 2014 11:19 am

You can use pigpio to get IR signals. It certainly works with some of my remotes.

Try the Python IR receiver at http://abyz.co.uk/rpi/pigpio/examples.html#Python_code

User avatar
Ferdinand
Posts: 236
Joined: Sun Dec 01, 2013 2:24 pm
Location: Leiderdorp, NL

Re: C code to read GPIO input

Mon Nov 03, 2014 11:26 am

Hi Kiloleader,

As you already know, C is 1000 times faster then Python. I had more or less the same problem with the DTH11 humidity sensor. You have to modify the code for your application, but it is a starting point.

Do not run this program for your application, because I use the gpio pin for reading and writing. Modify your program first.

Succes with your project,
...fjk

Code: Select all

/*
 *  dht11_string.c:
 *  Simple test program to test the wiringPi functions
 *  DHT11 test
 */

#include <wiringPi.h>

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#define DHTPIN	7
#define samples  20000



main()
{
   FILE *f1, *fopen();
   char testbit, dht11_dat[samples];
   int i;

   /* pull pin down for 18 milliseconds */
   wiringPiSetup();
   delay (500);
   pinMode( DHTPIN, OUTPUT );
   delay (500);
   digitalWrite( DHTPIN, LOW );
   delay( 18 );
   /* then pull it up for 40 microseconds */
   digitalWrite( DHTPIN, HIGH );
   delayMicroseconds( 40 );
   /* prepare to read the pin */
   pinMode( DHTPIN, INPUT );

   /*read 40 bits of dht11 by sampling low and high state of the bytes*/
   /*then use python to convert the samples into bytes*/
   for (i=0;i<samples; i++)
   {
      if (digitalRead(DHTPIN))
      {
         testbit = '1';
      }
      else 
      {
         testbit = '0';
      }
      dht11_dat[i] = testbit;
   }

  
   f1 = fopen("dht11.dat", "w");

   for (i = 0; i <samples ; i++)
   {
       /*fprintf(f1,(char) dht11_dat[i]);*/
       /*fputs(*dht11_dat[1],f1);*/
       fprintf (f1,"%c",dht11_dat[i]);
   }
   fclose(f1);
   return(0);
}
Success with your project!
Ferdinand

kiloleader
Posts: 10
Joined: Tue Oct 14, 2014 9:02 am

Re: C code to read GPIO input

Mon Nov 03, 2014 2:43 pm

joan wrote:You can use pigpio to get IR signals. It certainly works with some of my remotes.

Try the Python IR receiver at http://abyz.co.uk/rpi/pigpio/examples.html#Python_code
Hi Joan,

I can detect 'hash' values using your IR_haser.py. Unfortunately, I am sending and receiving 8 bit serial ASCI characters, and am currently getting the same 'hash' value for different characters. You code is not commented (don't know if you don't want people adapting it) but can you briefly describe the process you use to generate the 'hash' integer please.
Ultimately, I want to generate a value based on the middle 8 bits (after checking the start / stop bit), is your code going to let me do this or can you see a fundamental problem of 'why not'?

Thanks for the help,

User avatar
joan
Posts: 14936
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: C code to read GPIO input

Mon Nov 03, 2014 3:51 pm

The hasher just creates a number from the length of the individual pulses which make up the IR code (by comparing the last and current pulse lengths). The hash itself uses a standard published algorithm.

Generating a hash is much simpler then trying to decode the myriad of different remote control protocols. Some remote controls don't work reliably.

However that's not much use to you if you get hash clashes.

What sort of remote is it? Does it send repeat codes?

Anyhow, all you wanted was the pulse timings. For that you could just add a print(old_val, new_val) in the _hash function.

kiloleader
Posts: 10
Joined: Tue Oct 14, 2014 9:02 am

Re: C code to read GPIO input

Mon Nov 03, 2014 4:34 pm

joan wrote:The hasher just creates a number from the length of the individual pulses which make up the IR code (by comparing the last and current pulse lengths). The hash itself uses a standard published algorithm.

Generating a hash is much simpler then trying to decode the myriad of different remote control protocols. Some remote controls don't work reliably.

However that's not much use to you if you get hash clashes.

What sort of remote is it? Does it send repeat codes?

Anyhow, all you wanted was the pulse timings. For that you could just add a print(old_val, new_val) in the _hash function.
The 'remote' is an Arduino board sending ASCI characters over a 38KHz IR link. The IR is demodulated before it reaches the RPi GPIO pin.

The ASCI characters are represented as a 5ms start pulse, 8 data pulses and a 3ms stop pulse (see original question). The data pulses are the binary representations of the ASCI value (for example ASCI 'a' is sent as binary 97 '01100001', with a short data pulse for '0' and a long data pulse as '1').

The signal always takes the form: start bit, 8 data bits, stop bit. It is sent only once per communication (button press), and is active low. Please see attached image.

If the hash is the sum of the lengths of the individual pulses that explains the overlap of different characters. The most common hash value I am getting is 1829843384; is it possible this is the minimum value of hash (would denote my signal is shorter than expected at 10 pulses)?
Attachments
THIS IMAGE.jpg
Input to RPi GPIO from sending ASCI 'a' (binary 97).
THIS IMAGE.jpg (59.08 KiB) Viewed 7238 times

User avatar
joan
Posts: 14936
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: C code to read GPIO input

Mon Nov 03, 2014 4:51 pm

Ah, okay.

The way I approach these problems is to start off with a basic callback which prints the tick and level. I then augment it by saving the last tick and printing the level and tick difference. Generally a pattern emerges quite quickly (even more so when you know what to expect.

I'd then add logic in to capture the code start and then print successive edges. Similarly to capture code end.

If I get time I'll have a closer look.

kiloleader
Posts: 10
Joined: Tue Oct 14, 2014 9:02 am

Re: C code to read GPIO input

Mon Nov 03, 2014 4:58 pm

Many thanks for you help. Understanding how an IR hash is generated has helped no end!

Return to “Beginners”