8 Replies - 290 Views - Last Post: 10 May 2021 - 02:59 AM Rate Topic: -----

#1 Alhazred   User is offline

  • D.I.C Head

Reputation: 8
  • View blog
  • Posts: 222
  • Joined: 25-July 07

Interrupt service routine and not persisting variable change

Posted 09 May 2021 - 02:07 AM

I'm working on a project for a self-driving car using an ESP32, in this project, there are some variables modified into an ISR and those changes do not survive after that the ISR returns.

I have declared those variables as volatile, but that didn't help.

The code is too long to post it here, but you can read it on Github at this link:
https://github.com/L...iving-Car-ESP32

In the main.cpp file besides the pins setting and the other usual things, objects for "PID" (to control the motors speed), "Motors", "Encoders" and the "Car" classes are instantiated.

My problem is that the variable "intCount", a member of the Encoder class, is initialized to 0 at the object creation and it is (or should be) increased by 1 inside the isr() method of the same class each time that an optocoupler triggers an interrupt. The interrupt is correctly triggered, but the variable always resets to 0 after that the interrupt service routine returns. I can say this because if I put a
Serial.println(intCount);
after the intCount++ instruction, it always prints 1.
Trying to put another println() inside the if statement, it is not executed, thus the variable is not reset there.

I don't get what I am missing to have that variable to keep the updates.

Can anyone find what is my mistake?

This post has been edited by Alhazred: 09 May 2021 - 02:12 AM


Is This A Good Question/Topic? 0
  • +

Replies To: Interrupt service routine and not persisting variable change

#2 Salem_c   User is online

  • void main'ers are DOOMED
  • member icon

Reputation: 2526
  • View blog
  • Posts: 4,711
  • Joined: 30-May 10

Re: Interrupt service routine and not persisting variable change

Posted 09 May 2021 - 03:02 AM

Your Car and Motor constructors are making copies of your Encoders.

Your global instances are not the ones which get called.
Was This Post Helpful? 0
  • +
  • -

#3 Alhazred   User is offline

  • D.I.C Head

Reputation: 8
  • View blog
  • Posts: 222
  • Joined: 25-July 07

Re: Interrupt service routine and not persisting variable change

Posted 09 May 2021 - 04:43 AM

It seems I must learn more about how constructors work, I expected to pass and use the same instance of the encoders in that way.
Should I pass the encoders by reference to the motor's constructor and then the motors by reference to the car's constructor or am I wrong again?
Was This Post Helpful? 0
  • +
  • -

#4 Salem_c   User is online

  • void main'ers are DOOMED
  • member icon

Reputation: 2526
  • View blog
  • Posts: 4,711
  • Joined: 30-May 10

Re: Interrupt service routine and not persisting variable change

Posted 09 May 2021 - 05:06 AM

References sound like a good idea.

You can test by checking the value of the 'this' pointer for each of your Encoders at various points in the code.
Was This Post Helpful? 0
  • +
  • -

#5 Skydiver   User is offline

  • Code herder
  • member icon

Reputation: 7788
  • View blog
  • Posts: 26,018
  • Joined: 05-May 12

Re: Interrupt service routine and not persisting variable change

Posted 09 May 2021 - 06:21 AM

Moving to main C/C++ questions. This is not a language discussion topic.
Was This Post Helpful? 0
  • +
  • -

#6 Alhazred   User is offline

  • D.I.C Head

Reputation: 8
  • View blog
  • Posts: 222
  • Joined: 25-July 07

Re: Interrupt service routine and not persisting variable change

Posted 09 May 2021 - 12:07 PM

View PostSalem_c, on 09 May 2021 - 02:06 PM, said:

References sound like a good idea.

You can test by checking the value of the 'this' pointer for each of your Encoders at various points in the code.

Thank you, I've understood the problem, my getters returned a copy of the object, I've solved returning a pointer like as follows
Encoder *Motor::getEncoder()
{
    return encoder;
}


Was This Post Helpful? 0
  • +
  • -

#7 Skydiver   User is offline

  • Code herder
  • member icon

Reputation: 7788
  • View blog
  • Posts: 26,018
  • Joined: 05-May 12

Re: Interrupt service routine and not persisting variable change

Posted 09 May 2021 - 03:02 PM

With modern C++, you should prefer to return references rather than pointers. Of course, with embedded systems, a lot of authors seem to ignore this, and prefer something that is more C like and still use C++ as C-with-classes rather than as truly like the separate language that it is. I was hoping you would break new ground just like you are trying to break new ground with your project.
Was This Post Helpful? 0
  • +
  • -

#8 Alhazred   User is offline

  • D.I.C Head

Reputation: 8
  • View blog
  • Posts: 222
  • Joined: 25-July 07

Re: Interrupt service routine and not persisting variable change

Posted 10 May 2021 - 01:32 AM

I've changed the code
Encoder &Motor::getEncoder()
{
    return *encoder;
}


I suppose this is what you mean.
I also like more the syntax for calls, like
car.getMotorFR().getEncoder().isr(nowTime)


returning pointers I had a mix of "." and "->".
Was This Post Helpful? 0
  • +
  • -

#9 Salem_c   User is online

  • void main'ers are DOOMED
  • member icon

Reputation: 2526
  • View blog
  • Posts: 4,711
  • Joined: 30-May 10

Re: Interrupt service routine and not persisting variable change

Posted 10 May 2021 - 02:59 AM

Rather than persist with trying to modify a 10-file project on the hoof, make a small prototype to fully understand what's going on.

#include <iostream>

class Encoder
{
public:
    Encoder(uint8_t) {
    }
    int isr(unsigned long x) {
      std::cout << __PRETTY_FUNCTION__ << "(" << x << ")" << std::endl;
      return 42;
    }
};

class Motor
{
public:
    Motor(uint8_t, uint8_t, Encoder &e) : m_encoder(e) {
    }
    Encoder &getEncoder() {
      return m_encoder;
    }
private:
    Encoder &m_encoder;
};

class Car
{
public:
    Car(Motor &m) : m_motor(m) {
    }
    Motor &getMotorFL() {
      return m_motor;
    }
private:
    Motor &m_motor;
};


Encoder encoderFL{0};
Motor motorFL{0, 0, encoderFL};
Car car{motorFL};

int main ( ) {
  std::cout << car.getMotorFL().getEncoder().isr(1234) << std::endl;
}


$ g++ -std=c++11 -Wall -Wextra foo.cpp
$ ./a.out
int Encoder::isr(long unsigned int)(1234)
42

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1