-1

I'm fairly new to coding, and I've been trying to write something to write a placeholder to a text document whenever a button attached to a GPIO pin on my RasPi is pressed:

//Write date function//
void record() {

    ofstream myFile;
    myFile.open("report.txt");
    myFile << "Input at SPAM \n";
    myFile.close();

}

//myRead function//
void myRead(int i){

    if((digitalRead(4) == HIGH) && (i<5)) {
        record();
        digitalWrite(14, HIGH);
        delay(500);
        digitalWrite(14, LOW);  
        ++i;
        delay(500);
        myRead(i);
    }   
    else{
        if((digitalRead(4) != HIGH) && (i<5)){      
            myRead(i);
        }
    }

}   

int main() {
    wiringPiSetup();
    pinMode(12, OUTPUT);
    pinMode(14, OUTPUT);
    pinMode(4, INPUT);
    digitalWrite(12, HIGH);
    digitalWrite(14, LOW);

    myRead(1);
    digitalWrite(14, HIGH);
    delay(5000);
    digitalWrite(14, LOW);

    return 0;
}

The code compiles without any complaints, but if I run it in terminal without a sudo command, I get a "segmentation fault" error.
When I run it with a sudo command, the program starts and then ends almost immediately.

For reference:

  • Pin 12 is providing power to a potential divider on the breadboard.
  • Pin 4 should take the input from this divider.
  • Pin 14 causes an LED to light whenever there is an input on pin 4.

Whenever I run the program and VERY QUICKLY press the button on the potential divider, the LED will light if I hold the button.

How can I get this to run properly without it stopping as soon as it starts?

TriskalJM
  • 2,393
  • 1
  • 19
  • 20
Merk
  • 1
  • 3
  • The `myRead` probably recurses to much in the time it takes you to press the button. To find out build with debug information (add the `-g` flag when compiling and linking) and then run in a debugger to find out when and where the crash happens, and see if the function call-stack is full of calls to `myRead`. – Some programmer dude Jul 26 '17 at 13:02
  • Thanks, I'll try that. My code was indented in the source file, but I wasn't sure about the format here. Edited the indentation for now, but I've been teaching myself c++ for less than a month, so I get that my code's pretty messy and hard to read. – Merk Jul 26 '17 at 13:09
  • That seems to be the issue. I get the output: "Program received signal SIGSEGV, Segmentation fault. 0x00010b6c in myRead (i=) at inputReport.cpp:18 18 void myRead(int i){". I'm not really sure what to do about it. Any suggestions on how I could have the system check for an input every few seconds? – Merk Jul 26 '17 at 13:24
  • Do it in a *loop* instead of recursive calls? – Some programmer dude Jul 26 '17 at 13:27
  • I'll try using a "while" loop. I had tried using a "while" loop in conjunction with my "if else" commands, but not by itself. Thanks! – Merk Jul 26 '17 at 13:29
  • Thanks, it works perfectly using the "while" loop! I was really stumped by that one, but I'll learn from it. – Merk Jul 26 '17 at 13:35

1 Answers1

0

I think there are several possible problems with myRead.

A minor rewrite could be:

void myRead(int i)
{
    if((digitalRead(4) == HIGH) && (i<5)) {
        record();
        digitalWrite(14, HIGH);
        delay(500);
        digitalWrite(14, LOW);  
        ++i;
        delay(500);
        myRead(i);
    } else if((digitalRead(4) != HIGH) && (i<5)) {
        myRead(i);
    }
}

Notice that you have two calls to digitalRead -- this may lead to problems since the first one my return something different from HIGH and the second may return HIGH, meaning neither conditions are true.

You make a call to myRead with the same i in the alternative branch as the original call. If digitalRead returns something different from HIGH suffeciently many times, your stack will be full very fast and you'll get a segfault.

I'll propose a different version, that should be identical (baring any misunderstanding on my part):

void myRead(int i)
{
    // as long as i is less than 5
    while (i < 5) {
        // busy wait for digitalRead(4) to be HIGH
        while (digitalRead(4) != HIGH);
        // do the main thing
        record();
        digitalWrite(14, HIGH);
        delay(500);
        digitalWrite(14, LOW);  
        ++i;
        delay(500);
    }
}

Also please note that this is just plain C, not C++ (well, technically it's valid C++, but it's making no use of C++)

Clearer
  • 2,166
  • 23
  • 38
  • That seems like it would work, but I just changed it up and used while loops, on the advice of Some programmer dude, which seems to work just fine. Thanks for the answer! As for the whole C/C++ thing... I don't know a single thing about C. I wanted to start learning a programming language, and a few people recommended C++. I picked up the basics from the Sololearn course, but I've never had someone directly teach me. Any suggestions on how I could get better at C++, aside from the obvious "Keep taking more challenging projects"? – Merk Jul 26 '17 at 13:50
  • Get a good book on C++ instead of some random internet course. Usually they're written by people who have learned C in the 1980's or where taught by someone who learned C in the 1980's. They have all sort of bad stuff that you don't want to learn to begin with. I recommend getting Bjarne Stroustroup's latest book that's relevant to your compiler. Hopefully that's C++11 or later (C++17 preferably). There are other good books too, but I don't know any of them so I can't comment on them. – Clearer Jul 26 '17 at 13:58
  • Thanks, I'll look into it. I'm a year away from going to uni, and I've never done computing in school. The course I want to do involves a fair bit of programming, but claims to teach it for complete beginners. Despite this, I want to have a bit of an idea of what I'm doing before I go on. – Merk Jul 26 '17 at 14:02