Search code examples
c++linuxraspberry-piraspbiansudo

A certain program only works if I do NOT use sudo when running


Problem

I have a problem where if I run a program using sudo, I do not get the desired output, but if I run without sudo, it works correctly. I am using raspberry pi with c++, using wiringPi to access the GPIO. This program will eventually involve using PWM pins to set motor powers, for which wiringPi requires the use of sudo. So, I need to use sudo when running this program.

However, any program which uses the code I am using to get readings from encoders does not work if run with sudo, but everything else works fine with sudo. For example, if I run BETA/basicInchTest.cpp, My-own-encoder/workingInOneFile.cpp, or My-own-encoder/test.cpp using sudo, they will just print 0, but if I run without sudo, they will give the desired output, printing the position of the encoder. If I run any program besides those dealing with encoders (all of my LED programs), sudo makes no difference as to the output.

When I say "running with sudo", I mean using sudo ./a.out as opposed to ./a.out. I will use workingInOneFile.cpp as an example.

g++ workingInOneFile.cpp -lwiringPi 
./a.out

The above will correctly compile and run my code so that I receive the desired output.

g++ workingInOneFile.cpp -lwiringPi 
sudo ./a.out

The above will NOT compile and run my code so that I receive the desired output. The number 0 will be printed over and over regardless of how I turn the encoder.

Possible Explanation

I think that this might have something to do with wiringPi's interrupt system which I use with the wiringPiISR() function because only encoder related programs have this issue, and that is their most unique aspect. All three of the files I mentioned deal with the encoders in slightly different ways in terms of class structure and the main similarity between them not found in other files which I can use sudo with is that they all use this interrupt. I have also already tried using -o to give a different name than a.out, with no effect on the output.

Is there any way I can use these encoders with sudo as I will eventually need to because the only way to control PWM pins is to use sudo.

Code

workingInOneFile.cpp:

#include <wiringPi.h>
#include <iostream>

int position = 0;
unsigned char state = 0;

void update(void)
{
    unsigned char currentState = state & 3;
    if (digitalRead(7))
    {
        currentState |= 4;
    }
    if (digitalRead(0))
    {
        currentState |= 8;
    }

    state = currentState >> 2;

    if (currentState == 1 || currentState == 7 || currentState == 8 || currentState == 14)
    {
        position += 1;
    }
    else if (currentState == 2 || currentState == 4 || currentState == 11 || currentState == 13)
    {
        position -= 1;
    }
    else if (currentState == 3 || currentState == 12)
    {
        position += 2;
    }
    else if (currentState == 6 || currentState == 9)
    {
        position -= 2;
    }
}

void setup()
{
    wiringPiSetup();
    pinMode(7, INPUT);
    pinMode(0, INPUT);

    if (digitalRead(7))
    {
        state |= 1;
    }
    if (digitalRead(0))
    {
        state |= 2;
    }
    wiringPiISR(7, INT_EDGE_BOTH, &update);
    wiringPiISR(0, INT_EDGE_BOTH, &update);
}

int read()
{
    return position;
}

int main()
{
    setup();
    while (true)
    {
        std::cout << read() << "\n";
    }
}

test.cpp:

#include "encoder.h"
#include <iostream>

int main()
{
    Encoder enc(0, 7);
    while (true)
    {
        std::cout << enc.read() << "\n";
    }
}

basicInchTest.cpp:

#include "encoderL.h"
#include<iostream>
#include<cmath>

int EncoderL::position = 0;
unsigned char EncoderL::state = 0;

int main()
{
    EncoderL::begin();
    while(true)
    {
        std::cout << "Left: " << (EncoderL::read()/1440.0)*2.04*M_PI << "\n";
        
    }
}

Full github source: https://github.com/droiddoes9/Tennis-Ball-Robot/tree/master/General-Testing


Solution

  • Fix: update wiringPi to newest version :)