1

When I run my code, It says "velocity" was not declared in the scope. I tried to add, at the top, a declaration for velocity equal to zero and the code works but then velocity never updates. How can I make it so i'm able to call velocity in my loop function? Code:

const int trigPin = 9;
const int echoPin = 10;
int trials = 0;
bool win = true;

long duration1, distance1, duration2, distance2;

void setup() {
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  Serial.begin(9600);
}

void getDistance(){
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  long duration1 = pulseIn(echoPin, HIGH);
  long distance1 = (duration1*.0343)/2;

  Serial.print("Distance: ");
  Serial.println(distance1);
  delay(100);

  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  long duration2 = pulseIn(echoPin, HIGH);
  long distance2 = (duration2*.0343)/2;

  Serial.print("Distance: ");
  Serial.println(distance2);
  delay(100);

  }


void calculateSpeed(long dist2,long dist1,long time2,long time1){
  long numerator = dist2 - dist1;
  long denominator = time2 - time1;
  long velocity = numerator / denominator;
  return velocity;
}

void loop() {
  while (win == true){
    getDistance();
    calculateSpeed(distance2, distance1, duration2, duration1);
    Serial.println(velocity);

}
}
Yunnosch
  • 26,130
  • 9
  • 42
  • 54
  • 4
    `void calculateSpeed(...) { /*...*/ return velocity; }` do you see the problem with this? – scohe001 Jan 14 '20 at 19:34
  • Welcome to Stack Overflow! :) I would highly recommend getting a book from this list https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list and reading through it. These books have the answer to this question and many more questions you will have when learning C++. As for the answer to this particular question see my answer below. :) – tjwrona1992 Jan 14 '20 at 20:11
  • It appears (in your code sample) that you are used to some language that discourages a return value from a function. You should take another look at C++ examples. Even user defined arduino functions can return values ... I suppose it can be a style of thinking that takes some getting used to. Resistance is futile. – 2785528 Jan 14 '20 at 21:17

2 Answers2

4

Answer to the general question

You cannot access a local variable in a function from outside the function, however, there are multiple ways you can get a value from within a function. Here are a few examples. Note that I am using an int variable in the examples, but this works with other types as well such as long.

1. Return the value from the function:

int foo()
{
    int val = 42;
    return val;
}

int main()
{
    // Gets the value from foo()
    int val = foo();
}

2. Create a global variable and modify it within the function (not recommended)

There are multiple reasons why this is not good practice, but I'm not going to get into that here. Just ask Google why global variables are generally not good and you'll find a decent explanation.

// Global variable
int val;

void foo()
{
    val = 42;
}

int main()
{
    // val is accessible from here and is equal to 42
}

3. Pass the variable to the function by pointer and modify it within the function

void foo(int* val)
{
    *val = 42;
}

int main()
{
    int val;
    foo(&val);

    // val now contains 42
}

4. Pass the variable by reference and assign a value in the function

void foo(int& val)
{
    val = 42;
}

int main()
{
     int val;
     foo(val);

     // val now equals 42
}

Your specific issue:

You are trying to return a value from a void function. Change calculateSpeed to return long, and then use the returned value in your other function:

// Return long
long calculateSpeed(long dist2,long dist1,long time2,long time1){
  long numerator = dist2 - dist1;
  long denominator = time2 - time1;
  long velocity = numerator / denominator;
  return velocity;
}

void loop() {
  while (win == true){
    getDistance();

    // Get the returned value
    long velocity = calculateSpeed(distance2, distance1, duration2, duration1);

    // Use the returned value
    Serial.println(velocity);
  }
}

There are also a couple other issues though. You declare some global variables with long duration1, distance1, duration2, distance2;, but then you redeclare these variables locally within functions.

For example, in getDistance() you need to change this:

long duration1 = pulseIn(echoPin, HIGH);
long distance1 = (duration1*.0343)/2;

to this:

duration1 = pulseIn(echoPin, HIGH);
distance1 = (duration1*.0343)/2;
tjwrona1992
  • 8,614
  • 8
  • 35
  • 98
0

You cannot use the name of the local variable as visible only inside calculateSpeed.

But because you return it from that function you can do what return values are made for:

Serial.println(calculateSpeed(distance2, distance1, duration2, duration1));

As scohe001 kindly pointed out in a comment (thanks),
you need to match the function head to the fact that your return something:

long calculateSpeed(long dist2,long dist1,long time2,long time1){

Alternatively, also do the return value fix and then introduce a variable inside the calling function, fill it with the return value and then use it. But that is only needed if you want to continue using the value.

I wanted to show the code for that, too. But tjwrona1992s answer already covers that.

Yunnosch
  • 26,130
  • 9
  • 42
  • 54
  • Don't forget that `calculateSpeed` is declared `void`. – scohe001 Jan 14 '20 at 19:35
  • @scohe001 Thanks for the catch. I'd appreciate if you'd find another problem in my answer and let me know. I was already wondering about your comment on the question and was almost about to answer "No, please elaborate.", but wasn't done thinking. Thanks for being explicit. – Yunnosch Jan 14 '20 at 19:38
  • thats awesome thank you very much. How would I go about making it a variable? – Corey Predella Jan 14 '20 at 19:40