ADC code effecting motor outs???

Our robot’s motors seem to be receiving some sort of signal even when all pwm outs are hardcoded to zero. We systematically turned off sensors and bits of code, until we isolated the problem with the adc software. Unless we disable the adc code, (by commenting out the adc initialization or the adc/timer interrupt routines) the drive wheels act as if they are set to 10 or 20 above neutral, instead of 127. If we enable the joystick and pull it back about 10 or so, the wheels stop. If we set one wheel to be mapped as (255-p2_y) then ten forward or so stops one wheel and speeds up the other, and vice versa. If we change the sampling rate from 200Hz that we were using to 800Hz, then the wheels spin much faster, but in the same manner.

If anyone has any clue what’s going on, I would be very grateful for insight. I realize that both ways that we have found to stop the motor movement have the net effect of not causing any adc interrupts, but I don’t see what could be going wrong. The dashboard viewer continues to read neutral pwm values for all RC pwm outs. The gyro is on analog in 1, and the motors are on pwms 13 and 15. We have patched in Kevin Watson’s gyro and adc code, version 0.4. Once again, if any one can help, we’d all appreciate it.

Controls Software Lead,
Team 1014, Dublin Robotics (Bad Robots)

This explains the symptoms we’ve been seeing as well. Our current code (which uses Kevin’s ADC code for the gyro, DAA, and one other channel) shows a slightly positive value on the PWMs, but the default code doesn’t. It 's not causing us any problems, but it’s enough to cause the CIMs to hum even when everything is set to 127.

This is news to me…

Have you tried recalibrating the speed controllers?

This is more than a slight hum. At 800Hz, the robot drives about 3 m/s when we take it off blocks.

The problem is that PWM channels 13-16 are “bit banged” by code running on the user processor. When you have a lot of interrupts firing-off in the background, IFI’s code get’s interrupted while running, which causes jitter in the outputs. The only solution is to not use PWMs 13-16.


Thanks. That makes sence. I tried to find the source for the Generate_pwms function, but it was in a library. Between the adc, timer, serail comms, and encoders, we probably get about 400 interrupts a second. We’ll just switch to a different pwm out. Thanks again,

Ours are calibrated. For us, the problem is slight (it’s just a few steps outside of the Victor’s deadband).

That’s rather what I suspected. I’ll try having the guys shuffle around the PWMs.


If you still want to use PWMs 13-16, you can try this piece of code (hopefully this is the working version…). It replaces the Generate_Pwms function call and utilizes Timer 3 and the CCP modules to control the pwm 13-16 pulse width. Since the pulse is controlled by hardware, it should be independent of other interrupts. My team was planning on using PWM 13, 15 & 16 this year in order to improve the Victor response time since PWMs 1-12 seem to put around a 50 millisecond delay between setting the pwm output variable and for the Victor to respond (communication to the master processor plus some other delay). But based on the recent comments I’ve read on CD, having a jittery PWM output would not be unacceptable.

I have not had a chance to do any extensive testing on this code other than a quick check to be sure that it is indeed generating a 1-2 millisecond pulse, so it may still have some bugs. I plan on running more tests over the next week but if you decide to use it and have any questions or problems, let me know.

Mike (2.41 KB) (2.41 KB)

Thanks for posting that code. I will be trying it out sometime soon, but I will have to port it to Timer 2, as Timer 3 is in use already.

Mike, this is cool. If someone has some free time <grin>, a good experiment would be to use Mike’s code to see if you can wring-out a little more pointing accuracy from the camera servos.


I’m working on that as a side project.

This made me smile:

pwm13 * 40;										// Calculate the time delay for PWM13
CCPR2 = PROD + 9913;


Can someone explain what this does, particularly the first line?


	pwm13 * 40;		// Calculate the time delay for PWM13
	CCPR2 = PROD + 9913;

The first line does a multiplication. When you do a multiplication on the PIC, it is stored in the PROD register. The second line gets the value from the PROD and uses it. He does it this way so he has one less section to save before servicing the interrupt.

Refreshing the victors faster will not help. It’s a limitation of the vectors. However, by generating the pulses with hardware could accomplish somethings with the hobby servos. The period could go below 1 ms and above 2 ms. This can give about 170 degree’s on the model Hitec servo I have. The period generation can also be finer than the 8 bit values available with the default code. That may help with the resolution of the camera aiming.


Actually I wrote the code that way more for efficiency and to keep the footprint as small as possible. The first line, as Joel says, performs a multiplication that when used with the timer and CCP module determines the duration of the pulse. It is written in that particular manner to ensure that the compiler uses the 8x8 hardware multiplier (chapter 9 of the PIC18F8722 data sheet) rather than one of the math library routines to perform the operation. The result of the 8 bit multiply is automatically placed in the PROD register pair (this is a 1 instruction clock cycle operation). While I could have assigned a variable to receive the result of this multiplication (and cast the variables as ints), it was an unnecessary step as the next line can just as easily use the result from the PROD registers (10,000 = 1 millisecond). If you want, you can look in the generated .lst file to see how these statements are converted into assembly code. The relevant operation is the MULWF instruction and additional information on that can be found in chapter 26 (Instruction Set Summary) of the data sheet. (If you have some free time, take a look at what the C18 “WREG tracking” optimization does to the assembly code and how that would change the pulse width slightly)