PID timing problem with interrupts

Hello,

I'm trying to control a single joint of a robotic arm using arduino nano. at first I was using this library in order to read the encoder, however since it polls the encoder at regular intervals I was missing out some encoder readings depending on the speed of rotation at the time. In order to solve this I opted to reading the encoder based on interrupts, using this code. Now it looks like I stopped missing encoder readings, however my PID which was working well (I didn't get around to tuning it to final values yet, but generally it was working as expected) started going haywire, it will start by providing a correct output, but then without even getting close to it's setpoint change direction and fluctuate around some random(?) point, giving a few outputs of +255 and then a few of -255 (output range is 255 - (-255) ). I'm suspecting that the rather high number of interrupts introduced by the encoder is somehow messing with the PID timer or proccess. I've tried pre-scaling the value between reading it and feeding it to the PID, with no results. by printing to serial, I can confirm the encoder output looks fine and it's the PID that's giving out wierd values.

Also, now that I have gazillions of interrupts from the encoder, I'm missing some I2C communications, if someone have any idea on how to make them co-exist I would appreciate the advice.

I'm considering using an Attiny to read the encoders directly and pre-scale the value before feeding it to the Arduino (the encoder is mounted on the motor shaft and there is a ~400:1 gear, so I can afford pre-scaling the reading), but would rather KISS...

Thanks, Chai

the encoder is mounted on the motor shaft and there is a ~400:1 gear

How many pulses per revolution of the motor? Can you move the encoder to the output shaft of the gearbox?

You’ve not given us any data as in motor rpm range, encoder counts per rev, etc. so all we can do is to guess. My guess is now that your encoder counts are interrupt based, the PID sees large input changes between updates. If you have any D term in the PID, this can cause large jumps in PID output (instability).

Set the D to zero and see if the output smooths out.

PaulS: How many pulses per revolution of the motor? Can you move the encoder to the output shaft of the gearbox?

The encoder I'm currently working on produces 6 PPR (that's 12 interrupts as far as the controller sees it), I've tried reducing it to 3 PPR, with no noticeable improvement. The encoder is part of the motor, I've thought about installing another encoder on the output shaft, but would rather keep the original one if possible. There are other similar motors in the project that has 20 PPR encoders, so I was hoping to find an extendable solution (though encoder replacement is possible if no other solution is found in software).

WattsThat: You’ve not given us any data as in motor rpm range, encoder counts per rev, etc. so all we can do is to guess. My guess is now that your encoder counts are interrupt based, the PID sees large input changes between updates. If you have any D term in the PID, this can cause large jumps in PID output (instability).

Set the D to zero and see if the output smooths out.

I don't have the motor RPM range (sticker doesn't say), but I can put together a quick code to see how many pulses I get in a second. I'll try setting the D value to 0 and report back, I've actually tried to raise it, but didn't try to eliminate it.

Can you describe in English (not code) how the system is intended to respond to the encoder pulses?

...R

I2C uses interrupts so you can't rely on timer interrupts for your code. This is a well known problem. I avoid I2C and use SPI when using timer interrupts.