2

I tried the following:

In rc.local, I have:

echo 24 > /sys/class/gpio/export
echo 25 > /sys/class/gpio/export
echo in > /sys/class/gpio/gpio24/direction
echo in > /sys/class/gpio/gpio25/direction

In: incrontab -l

/sys/class/gpio/gpio24/value IN_MODIFY date > /var/alarm/motion
/sys/class/gpio/gpio25/value IN_MODIFY date > /var/alarm/tamper

But when I wave the hand in front of motion detector, nothing happens. Its supposed to create a file in the directory /var/alarm/ containing the date & time of when the last change of the GPIO pin happened.

However, when I "cat /sys/class/gpio/gpio24/value" I get a "1" when theres no motion, and "0" when theres motion.

And when I do "cat /sys/class/gpio/gpio25/value", I get a "1" when the cover on the motion detector is closed, and "0" when the cover is open.

So what im doing wrong? The file "value" IS CHANGED so why aren't incrontab executing the command I told it to execute?

4
  • did you get it work?
    – Ghanima
    Sep 26, 2014 at 14:30
  • As per the FAQ there are "some limitations" WRT monitoring sysfs files with inotify; a bit of reading implies this has to do with implementation in kernel space. Sysfs (and procfs) "files" aren't real files and won't appear to change (timestamps, etc), but when you actually read them, they may contain different values. It's the act of reading that does this, it's a request for information from the kernel. If you want to do something like this, you should use poll() as per the sysfs gpio docs.
    – goldilocks
    Dec 25, 2014 at 12:42
  • WRT? what are you talking about? This is about GPIO on a raspberry PI. Dec 25, 2014 at 17:33
  • 1
    WRT = "with respect to".
    – goldilocks
    Dec 31, 2014 at 6:06

2 Answers 2

2

There's no problem with the GPIO system. The problem is that inotify, to which incron is an interface, won't necessarily work on all sysfs files, and it seems that this includes these.

If you skim down the inotify FAQ, you'll find this perhaps overly optimistic note:

Q: Can I watch sysfs (procfs, nfs...)?

Simply spoken: yes, but with some limitations. These limitations vary between kernel versions and tend to get smaller. Please read information about particular filesystems.

See also a similar sentiment here. If you search online for "inotify sysfs", you'll find lots of actual reports of this.

Inotify is a userspace entity; it monitors filesystem inodes.

Sysfs, a kernelspace subsystem and the basis of the entire /sys directory, is not a normal filesystem. It exists in memory, and functions as an interface to the kernel. The way the individual files work is this: when opened and read, the kernel provides whatever information they represent. For example, when you read /sys/class/gpio/gpio25/value, this is asking the kernel, "What is the current state of GPIO pin 25?". It will then tell you.

However, that information is not actually stored there. It's a fake file. Inotify was not really intended for this purpose; in one of the discussions from that internet search you'll find a remark from someone who is presumably one of the inotify devs:

With sysfs, it does not work as expected for some reason.

Well, I'm rather surprised inotify works with sysfs at all ;) [...] Anyway, if you'd like to add fsnotify() support into sysfs, sysfs maintainer (Greg - added to CC) is the one to ask.

Here the point is made that there's nothing inotify can do about this -- to make this kind of monitoring work, something needs to be implemented in sysfs which is a kernel subsystem. Presumably this has been done to some extent, which is why the FAQ is optimistic.

The reason it probably hasn't been done with the GPIOs is because those files already have a specialized API to do exactly what you are trying to do. While it is no help to inotify, it is more flexible, at least from a programming perspective.

"value" ... reads as either 0 (low) or 1 (high). If the GPIO
    is configured as an output, this value may be written;
    any nonzero value is treated as high.

    If the pin can be configured as interrupt-generating interrupt
    and if it has been configured to generate interrupts (see the
    description of "edge"), you can poll(2) on that file and
    poll(2) will return whenever the interrupt was triggered. If
    you use poll(2), set the events POLLPRI and POLLERR. If you
    use select(2), set the file descriptor in exceptfds. After
    poll(2) returns, either lseek(2) to the beginning of the sysfs
    file and read the new value or close the file and re-open it
    to read the value.

Note "you can poll(2) on that file and poll(2) will return whenever the interrupt was triggered". That's the normative technique and it does work. If you aren't familiar with poll() see man 2 poll. These are all native C library system calls (i.e., they go through the kernel) and should have equivalents in higher level languages such as python.

I would have hoped there was established software to provide for those who don't program at all (note that if you can, this is very very simple), but sadly, searching around I could not find anything general purpose.1 Don't let that stop you from searching yourself, however.


1. I'm happy to write a daemon for this, since it should exist, but I will not have time for a month or so.

0

You need to be root to execute those commands. You current crontab is executed as the pi user.

Put the command inside the root's crontab instead by using sudo crontab -e

As to the inverted input values. This is quite common for sensors. These sensors will pull the output to ground, when an event occurs, instead of outputting a voltage. This has the advantage that that it doesn't matter what voltage the receiver requires. This makes it safer to use.

Just change you code to account for this inversion.

1
  • I did intentionally did it inverted. The motion detector is a 3.3v one and I added pull-down resistors to GND. The motion detector is set at to output inverted values (NC) just as a tamper resistance, so if someone cut the line, the alarm goes off. I just pointed out that it WORKS Reading the values that way, so somebody does not Point out that my detector is hooked up incrrectly. So theres 3.3v on the input when the detector is not doing any motion. Its a Little solid-state relay so its a NC Connection. About the root issue, i WAS logged in as root (su) when running incrontab -e. Jun 29, 2014 at 1:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.