PWM-Servo-Driver-Library call from within timer interrupt

Breakout boards, sensors, other Adafruit kits, etc.

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
ebeowulf17
 
Posts: 26
Joined: Tue Feb 26, 2013 12:57 am

PWM-Servo-Driver-Library call from within timer interrupt

Post by ebeowulf17 »

I've been using the PWM-Servo-Driver-Library on an Arduino Mega to control the 16-Channel 12-bit PWM/Servo Driver - I2C interface - PCA9685
(PRODUCT ID: 815.) Everything has worked beautifully for a few years now, but I have a new problem. I'm trying to work with a new proportional valve, and it needs dither in order to overcome stiction issues. I'd like to use a timer interrupt (using the Timer1 library here: http://playground.arduino.cc/Code/Timer1) to call pwm updates at regular intervals. Unfortunately, I can't get a single setPWM command to work from within the function called by the interrupt timer. The program hangs immediately.

Although I had hoped to eventually do this at high speed, right now I've got the timer interrupt operating every 1.5 seconds, so speed shouldn't be an issue in the current tests.

I know this isn't anything to do with re-assigning timers and breaking communication or anything like that - the ISR and Timer1 library work fine and the PWM library works just fine, all at the same time. The only problem is when the setPWM command is called from WITHIN the interrupt's function call. The only reason I could think of that this might be a problem is if I2C communication is happening when the timer interrupt hits, and then my function tries to start a new I2C communication in the middle of the old one. Would garbled I2C communication cause the Mega to freeze?

Is this a known issue? Am I doing something dumb here? Any ideas? Thanks!

User avatar
adafruit_support_bill
 
Posts: 88093
Joined: Sat Feb 07, 2009 10:11 am

Re: PWM-Servo-Driver-Library call from within timer interrup

Post by adafruit_support_bill »

The Mega has only one level of interrupt and interrupts are disabled on entry to an interrupt service routine. Since i2c communication requires interrupts, it is not possible to communicate with the PWM Servo driver when interrupts are disabled.

One common technique for dealing with this is to set a flag in the ISR and perform any necessary i2c communication on the next pass through the loop.

It is also possible to re-enable interrupts inside the ISR. But that can be dangerous and is not generally considered to be a good practice.

User avatar
ebeowulf17
 
Posts: 26
Joined: Tue Feb 26, 2013 12:57 am

Re: PWM-Servo-Driver-Library call from within timer interrup

Post by ebeowulf17 »

Thank you so much for your clear explanation. It makes perfect sense, but is quite BANNED. I was really hoping to use timer interrupts specifically because this is a heavy, heavy program and the main loop is quite a bit slower than the dither frequency I hoped to achieve.

I'll try some more experiments - maybe I can trim down to a bare bones version of what I've got and get the loop speed back up to a useable level. Even if it's not a long term solution, it might be a way to test the effectiveness of dither on this particular valve. As of right now, I'm not sure this valve will perform as intended even with working dither.

Regardless of how I handle this dither question, thanks again for clearing up the ISR / I2C relationship. You've saved me a lot of potential headaches! At least now I know what I'm up against. Cheers!

Locked
Please be positive and constructive with your questions and comments.

Return to “Other Products from Adafruit”