Note that there are some explanatory texts on larger screens.

plurals
  1. POOne interrupt function to modify a dynamically determined instance?
    primarykey
    data
    text
    <p>As usual, I know how to bypass this problem with some ugly patch work, but I want to make it elegant: I would like to make a small wrapper for motors commanded by an Arduino, which would unfortunately mean writing a distinct interrupt routine for each instance of motor because it has to modify the right step counter (member variable of the motor class) to determine its rate. However those functions would obviously have the same processing... My question is: how can I determine which counter to modify in a unique interrupt routine?</p> <p>Here is what I have so far, I'd like to hide interrupts from the user.</p> <pre><code>class Motor { volatile int counter; unsigned long lastUpdate; //Last timestamp update (for calculating the rate) static const unsigned int RESOLUTION = 1024; //Number of steps in one rev static const unsigned int RPMS_TO_RPM = 60000; //Convers rev/ms to rpm public: Motor() : counter(0) { lastUpdate = millis(); } void encoderInput(bool pinA, bool pinB) { counter += (pinA ^ pinB)*(-1)+!(pinA ^ pinB); } int getRate() { int ret = float(counter)/RESOLUTION/(millis() - lastUpdate)*RPMS_TO_RPM; lastUpdate = millis(); counter = 0; return ret; } }; /* Example: * Motor motor1; * * void motor1_isr(void) { * motor1.encoderInput(PIN_A, PIN_B); * } * * void setup() { * attachInterrupt(PIN_I, motor1_isr, CHANGE); * Serial.begin(9600); * } * * void loop() { * Serial.println(motor1.getRate()); * delay(1000); * } */ </code></pre> <p>Thanks for your help, I think it would be useful to other people as well once it's done with :) </p> <p>Regards, Mister Mystère</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. COTypically you'd want your ISR to get information from atomically updateable volatile variables (or non-atomic mailbox ones it copies only upon seeing an atomic "updated" flag). To handle multiple motors, you either have the ISR do all of them at once, or if that means too long in the ISR, you can have it round robin service one on each successive interrupt, and increase the interrupt frequency by the number of motors.
      singulars
    2. COYou mean make a pointer to the member variable volatile, and call that pointer in the ISR? But the ISR can be called randomly... Would you mind to answer with an example? I can't do them all in the interrupt since a priori I don't know the number of motors (I want to make it generic). I've updated my question above with a code that normally works (I don't have Arduino this weekend), you think that's the best (simplest for the dev and the user) we can do?
      singulars
    3. COHonestly, I'd recommend that you not use C++ in an ISR, especially on a system this tiny. Consider using static functions operating on compact data structures, and be very careful of atomicity and volatility concerns when changing those. Speaking generally, you could have a variable size array of structs each giving data for one motor. You can't atomicaly update a struct, so you'd probably have to go with flagging when it has been changed.
      singulars
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload