Ros_arduino_bridge and direct connected H-Bridge - IBT-2 H-bridge module, Max speed values out of PID

307 views
Skip to first unread message

gerard M Kelly

unread,
Jan 3, 2015, 4:59:53 PM1/3/15
to ros-by-...@googlegroups.com
Hi I'm trying to add support for a direct connected IBT-2 H-bridge module. I am having trouble identifying what the Min & Max values for motor speed that are output from the PID controller that I need to handle. I found this comment "// Set speed for motor 1, speed is a number betwenn -400 and 400" in  DualMC33926MotorShield.cpp but do not see where these min/max values are determined. Can someone point me to to area where this is controlled.

Thanks

Kristof Robot

unread,
Jan 4, 2015, 2:09:12 PM1/4/15
to ros-by-...@googlegroups.com
Hi Gerard,

If you want to go easy you can simply use Arduino's analogWrite()
call, which accepts a value between 0 (always off) and 255 (always on)
for the duty cycle [1]. This is also the "fallback" in
DualMC33926MotorShield.cpp in case of a chip other than ATmega168/328P
(see [0]).

The disadvantage of this approach is that this runs at a very low
frequency, either 490 Hz or 980 Hz on Arduino Uno (see [1]).

You can get much higher (better) frequencies by manipulating the
Atmega's timer registers directly - and that is what
DualMC33926MotorShield.cpp will do when it finds an Atmega168/328P
chip - in that case it will use a frequency of about 20Khz.

This magic is configured as follows in DualMC33926MotorShield.cpp:

#if defined(__AVR_ATmega168__)|| defined(__AVR_ATmega328P__)
// Timer 1 configuration
// prescaler: clockI/O / 1
// outputs enabled
// phase-correct PWM
// top of 400
//
// PWM frequency calculation
// 16MHz / 1 (prescaler) / 2 (phase-correct) / 400 (top) = 20kHz
TCCR1A = 0b10100000;
TCCR1B = 0b00010001;
ICR1 = 400;
[...]
#if defined(__AVR_ATmega168__)|| defined(__AVR_ATmega328P__)
OCR1A = speed;

This is, by the way, what Pololu means with the following feature [4]:
"PWM operation up to 20 kHz, which is ultrasonic and allows for
quieter motor operation"

Hope that helps,

Kristof

[0] https://github.com/pololu/dual-mc33926-motor-shield/blob/master/DualMC33926MotorShield/DualMC33926MotorShield.cpp
[1] http://arduino.cc/en/Reference/AnalogWrite
[2] http://arduino.cc/en/Tutorial/PWM
[3] http://arduino.cc/en/Tutorial/SecretsOfArduinoPWM
[4] http://www.pololu.com/product/2503
> --
> You received this message because you are subscribed to the Google Groups
> "ros-by-example" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to ros-by-exampl...@googlegroups.com.
> Visit this group at http://groups.google.com/group/ros-by-example.
> For more options, visit https://groups.google.com/d/optout.
Message has been deleted

gerard M Kelly

unread,
Jan 4, 2015, 4:52:59 PM1/4/15
to ros-by-...@googlegroups.com
Hi Kristof

  Thanks For the detailed reply. Yes I am using the AnalogWrite for now just at the standard rate, maybe bump up to the 20K later. As the 20K plays with Timer1 interrupt timing the  Millis tests need to be adjusted I believe as it drives off of interrupt 1.  So the Arduino standalone code for the HBridge's and SEN0038 wheel encoder is written and I am starting to integrate into the ros_arduino_bridge code.

I am trying to verify that the PID in Bridge will be sending values fro -400 to 400 so I can code the PWM correctly. In dual-mc33926-motor-shield I see

analogWrite(_M2PWM,speed * 51 / 80); // default to using analogWrite, mapping 400 to 255

And was trying to figure out where the range -400 -- 400 is defined to verify this is what my motor control code will receive.

Also thanks for all your great stuff up on GIT. I have been using it to understand what changes to make to the Bridge code!!

Gerard
Reply all
Reply to author
Forward
0 new messages