Modified VNH5019 shield library for 20kHz PWM with Mega

Thank you for the explicit clarifications. I got a little confused by the thread but the original and these instructions make more sense and work just fine for me now. I wanted this ultrasonic PWM library so that I could remove the loudly audible PWM whine coming from my motors. I’ve just used simple H-bridge circuits in the past and there are nicely built functions to set the PWM frequency on Arduino PWM pins, but this motor driver shield is very handy and quite powerful. Thanks for the speedy and clear help. Cheers.

Hello,

I’m working with the VNH5019 on a Mega 1280. I’ve found that when I set the speed to 399, I only get around 62 to 64% Duty Cycle. When I set it to 400, I get 100% Duty Cycle. What am I missing? Were did my other 40% go?

Okay. Update… I did some massive testing tonight with the Library… I changed the max PWM value to 625. I ran a looping test that count from 0 to 625. The duty cycle on my oscilloscope spike at a 100% when the counter hit 400 and 401… then resumed normal progression at 402 up through 625. I’m not sure what’s magical about the 400 and 401 values for the PWM… but, what ever the reason… those 2 numbers cause the issue… I wrote some extra code to make it skip those two numbers and my program works fine now. Anyone have ANY insight into why this may be? Where did that initial 400 value come from? I find it strange that that’s the default top PWM value and that’s the value that causes the duty cycle to spike… Could they’re be something strange with the timer values and some sort of strange relationship with 20Khz ??

Thanks, Connor

Hello, Connor.

Are you getting the same behavior with both channels?

- Ben

Yes, I am. I was trying to figure out where the “400” came from to begin with… I couldn’t figure that out… But, like I said, at 399 it’s round 62-64% duty, 400 and 401 it spikes to 100%, 402 it picks back up at the 64-65% mark and is good all the way up till it hits 625 which is 100% duty again… What’s stranger is… I would think it would be 512 or 1024 for the top value for the PWM depending on if it was a 9 bit or 10 bit counter for the clock…

A top value of 400 produces a 20 kHz PWM. What frequency do you see when you look at the PWM on your scope?

- Ben

Okay, Found the problem… issues is in the following areas…

#if defined(AVR_ATmega168)|| defined(AVR_ATmega328P)
OCR1B = speed;
#elseif defined(AVR_ATmega128) || defined(AVR_ATmega1280) || defined(AVR_ATmega2560)
// Mega board specific stuff here - assumes assigning timer3, using pins 3 &5
OCR3B = speed;
#else
analogWrite(_PWM2,speed * 51 / 80); // default to using analogWrite, mapping 400 to 255
#endif

#elseif isn’t valid, it should be #elif

also, OCR3B should be OCR1B… The elseif problem is throughout the file, but the OCR3B is only on line 116.

I think it was falling through to the analogWrite part of the code… which would work correctly up to the 400 or 401 which = 255 when rounded up. analogWrite then must put the pin in a high state regardless of the PWM value… which is why it was acting strangely.

Continuing on with the math… 625 = 398, 626 & 627 = 399 and 628 & 629 = 400… Which was the cut off value I found…

So, that explains the strange behavior. Please update your libraries to reflect the bug fixes. :slight_smile:

One think that would be nice would be a easy way to switch the motor orders… In my setup. Do to wire lengths… I had to go through and swap all the pins… and the OCR1A and OCR1B… and of course, the _PWM1 and _PWM2 have no effect with this library, as we’re not using the analogWrite function… (or shouldn’t be)

Thanks, Billy

Hi, Billy.

Thank you for pointing those mistakes out; I really appreciate it. You are right about it not recognizing the elseif statement and falling through to the else statement. I have tested the library with both of the changes you indicated and updated it in my original post. I also fixed the second code block in that post, which used to have the header file instead of the C++ file in it.

-Claire

I wouldn’t say mistakes… I would say bugs. :slight_smile: Bugs happen… I’m a magnet for them… Glad to have figured it out… it was driving me crazy. I thought I had a problem with my PID loop.

Thanks, Billy

I would like to modify the library to disable some of the optional driver functions, like M2EN, to free up some of the PWM outputs on the MEGA. (I am new to modifying libraries).

Can I simply change the line in the .CPP file :

_EN2DIAG2 = 5;

To some unused digital output (not PWM):

_EN2DIAG2 = 30;

?

Chris

Hi, Chris.

Yes, that is the only change that you should have to make in the library to change the pin used for EN2DIAG2. However, you do not need to make any changes to the library if you use the alternate constructor documented on the libraries github page.

DualVNH5019MotorShield(unsigned char INA1, unsigned char INB1, unsigned char EN1DIAG1, unsigned char CS1,
unsigned char INA2, unsigned char INB2, unsigned char EN2DIAG2, unsigned char CS2)

This constructor lets you remap pins directly from your Arduino sketch; that way you do not have to remember to modify the library every time you want to change a pin. For your particular case, you could just find the line in your sketch that creates the shield object and change it to the following:

DualVNH5019MotorShield md(2, 4, 6, A0, 7, 8, 30, A1);

-Claire

In case you haven’t already done it, you will also have to physically disconnect the EN2DIAG2 pin from the Arduino pin it is connected to by default. You can do this by cutting the trace going to it on the shield, as shown in the Remapping the Arduino Connections section of the shield’s user’s guide. You can then rewire it to whatever pin on the Arduino you want to use.

-Claire

Hi guys

I went to use this library and found that, while all the required info is here, I found no single source to download it from; the zip file in the first post still has the bugs that are discussed, and the github site doesn’t have the Mega-20kHz version at all (as far as I can see).

…so I’ve had a go at editing, but don’t have a board I can cut traces & run jumpers on to test it right now.

files are here:
dl.dropboxusercontent.com/u/508 … ldMega.zip

Hi.

I just checked the zip file and it seemed to have the bug fixes that were mentioned earlier in this thread. From the file you posted, it does look like you somehow got an older version. Could you try downloading the zip file from the first post in this thread again?

This modified version of the library is not on our github page, because it is just modification of our original VNH5019 libraries.

-Claire

Hi CLaire

thanks for your reply. I tried several times just now, even using a different browser in case there is some cache issue. The zip file linked in your post at the head of this thread
"https://forum.pololu.com/download/file.php?id=1514"
is still links to the old version, at least for me. Maybe there’s some issue with cacheing at your end ?

I tried downloading the zip file for the library on a few other computers and it looked fine on them too. Is it possible that it might be caching issue on your end? Here is a different link to download the updated library. Could you try that?

Also, after taking another look at the zip file you posted earlier, I am no longer sure if the version of the library you are downloading is an old version or if the modifications you made to the library changed some of the lines that were corrected to refer to timer 1 back to timer 3. Could you specify exactly what bugs you think the library that you downloaded has?

-Claire

Hi there,
I wonder why not just to change the frequency of pin 9 & 10 to match the UNO?
We added the following:

//set Arduino Mega pin 9 & 10 to frequ 31250.
TCCR2B = TCCR2B & 0b11111000 | 0x01;

it seems to work just as expected without the howling of the motors. As I’m not an advanced register-haxxor I would be glad if anybody could explain potential objections with that?
thxalot,
david

Hi, David.

Thank you for sharing! I tried adding your line of code to our unmodified VNH5019 library and it did change the PWM frequency. I had not thought of doing something so simple to change the default PWM frequency of certain pins. Unfortunately, just setting the prescaler for Timer2 to zero changes the frequency of analogWrite to around 30kHz, which is faster than the maximum PWM frequency specified for the VNH5019.

I modified our library to use Timer1 because it is a 16-bit timer and easy to get 20 kHz (the fastest PWM frequency the VNH5019 can do) with. If you wanted to use Timer2 (which is 8-bit), you could use fast PWM mode, a prescaler of 8, and a top value of 100 in order to get 20 kHz. However, that would only let you have 100 different motor speeds.

-Claire

Hello Claire,

I have bought the motor driver to use to roll up my greenhouse walls. Unfortunately, although i can get motors working, I have no idea what the difference in hertz means for the motors. Will the 500Hz with the mega set up normally with the motor shield actually damage the motor, or will it just sound funny? I don’t care about the sound, but the motors are $300 a piece, and there’s two for each greenhouse, so I wouldn’t want to fry them. What do you think?

Thanks!