4

I am using wiringPi Library and using this library to read data from GPIO Pins attached to a PIR Sensor.

I am using a while loop which reads input data. If there is a motion it will print motion.

while(1)
{
    while(digitalRead(1)==0)
          check=false;
    if(check==false)
    {
         cout<<"Motion Detected"<<endl;
         check=true;
    }
}

The above code uses processor 100%.

What to do in this case? How can I reduce my processor usage.?

Ghanima
  • 15,855
  • 15
  • 61
  • 119
Veer
  • 149
  • 1
  • 6

2 Answers2

7

I think your problem is that when motion is detected the loop runs at full speed. I would suggest one of the following sollutions:

  1. Use a blocking read from the GPIO pin. That way your program will hang untill there is new data ready, i.e. if the GPIO pin has changed state.

  2. When using polling you should make your program sleep at least once with run of the loop, as suggested by Gerben in the comments.

For 2 structure your code a bit differently. Change the while to an if and frame the whole thing in a while loop instead, like so:

#import <time.h>

while( 1 ) {
    if( digitalRead(1) == 0 ) {
        cout << "Motion detected." << endl;
    }
    usleep(50000);
}

That way the sleep routine will release the CPU for 50ms with each run of the loop.

Kenneth
  • 731
  • 1
  • 4
  • 11
  • Please check the edit.!! This will check the motion infinitely.! And the code you have posted and what I had written are same. It will consume the same. – Veer Aug 14 '13 at 12:36
  • Not the same. In your code the while loop will run as long as digitalRead returns 0. This is because the body of a while loop without curly braces is only the following line. Only when the returns 1 is the if statement evaluated. In my example the pin is read exactly once for each run. Does that make sense? – Kenneth Aug 14 '13 at 12:45
  • Does the op want to break out of the while (1) loop when motion is detected? – HeatfanJohn Aug 14 '13 at 12:59
  • @HeatfanJohn I don't think so. The check variable is reset to true after motion has been reported. – Kenneth Aug 14 '13 at 13:15
  • 6
    Are you sure sleep(50)? I'm not sure about Raspberry but in every normal Linux this will put the thread to sleep for 50 seconds. Use usleep for given length of microseconds sleep. (and I found even usleep(1) reduces CPU load caused by such polling to ~1-3%.) – SF. Aug 14 '13 at 14:15
  • SF is correct, the parameter to sleep() on linux (or more specifically, in the GNU C library) is seconds, not milliseconds (sleep() actually is not in the C standard at all, so implementations vary). – goldilocks Aug 14 '13 at 15:47
  • Sorry, of course you are correct. I will update the answer. – Kenneth Aug 15 '13 at 08:30
0

I believe you are looking for the nanosleep() solution:

usleep() has been removed since POSIX-2008 and recommends to use nanosleep() instead.

electron1979
  • 121
  • 11