Go Down

### Topic: Tank Robot Sr. Design - PWM questions (Read 7584 times)previous topic - next topic

#### jdeck004

##### May 05, 2011, 08:16 pmLast Edit: May 09, 2011, 01:15 am by jdeck004 Reason: 1
Introduction
I am working on a Mechanical Engineering senior design project building a 40lb tank robot driven by a wireless PS2 controller. Following is a basic schematic of the control plan:

The microcontroller is an Arduino Uno.

The motor contollers are Cytron 10A, 3-25V Single DC Motor Controller (http://www.robotshop.com/ca/cytron-single-dc-motor-controller-2.html)

The motors are standard OEM windshield wiper motors (http://monsterguts.com/index.php?act=viewProd&productId=4)

The battery is an AGM motorcycle battery (12V, 18AH).

Questions
For Arduino, the base frequency for pins 3, 9, 10, and 11 is [corrected] 490.196078 Hz. The base frequency for pins 5 and 6 is [corrected] 976.5625 Hz. The divisors available on pins 5, 6, 9 and 10 are: 1, 8, 64, 256, and 1024. The divisors available on pins 3 and 11 are: 1, 8, 32, 64,128, 256, and 1024.  (http://www.arduino.cc/playground/Code/PwmFrequency)

"The Cytron motor controllers is capable of "speed control PWM frequency up to 10KHz" and "supports both locked-antiphase and sign-magnitude PWM operation."

I need to know:
1) What effect will there be if I output 31250 Hz or 62500 Hz from the Arduino to the Cytron? Will there be overheating or just dropping signals/signal distortion?

2) What effect will there be (on the signal, power usage, etc) of using lower PWM frequencies such as 31250/8 = 3906.25 Hz?

3) What will the effect be on motor performance? Is there tabulated data about the resistance and inductance of these common motors?

4) How do I use locked-antiphase versus sign-magnitude PWM operation using Arduino?

Thank you for your help. Hopefully the answers to these questions don't just make new questions!

John

#1
##### May 05, 2011, 08:38 pm
Quote
For Arduino, the base frequency for pins 3, 9, 10, and 11 is 31250 Hz.

No, it isn't.  The default frequency for those pins is ~488 Hz.

Quote
The base frequency for pins 5 and 6 is 62500 Hz.

Nope.  ~976 Hz.

#### jdeck004

#2
##### May 05, 2011, 09:09 pm
I was citing www.arduino.cc/playground/Code/PwmFrequency is it just plain wrong? Could you please explain? How would a 10KHz switching frequency be attained?

#3
##### May 05, 2011, 09:29 pmLast Edit: May 05, 2011, 09:31 pm by Coding Badly Reason: 1
I was citing www.arduino.cc/playground/Code/PwmFrequency is it just plain wrong?

It is certainly possible I made a mistake so let's take a look at the source code.  The code that initializes PWM is in "wiring.c"; specifically the "init" function.

sbi(TCCR0A, WGM01);
sbi(TCCR0A, WGM00);

...sets timer 0 to "Fast PWM".

sbi(TCCR0B, CS01);
sbi(TCCR0B, CS00);

...sets the prescaler to 64.

The frequency is fOCnxPWM = fclk_I/O / ( N ? 256 ) = 16000000 / ( 64 * 256 ) = 976.5625 Hz.

sbi(TCCR1B, CS11);
sbi(TCCR1B, CS10);

...sets the prescaler to 64.

sbi(TCCR1A, WGM10);

...sets timer 1 to "PWM, Phase Correct, 8-bit".

The frequency is fOCnxPCPWM = fclk_I/O / ( 2 ? N ? TOP ) = 16000000 / ( 2 * 64 * 255 ) = 490.196078 Hz.

The answer is "yes".  The "base frequency" listed on that page is wrong.

Quote
How would a 10KHz switching frequency be attained?

http://arduino.cc/forum/index.php?topic=58757.0

#### jdeck004

#4
##### May 05, 2011, 10:45 pm
Thank you. I see that you are configuring pins 9 and 10. I have 3 motor outputs total. Can the Arduino Uno be configured to work for 3 simultaneous PWM outputs? The most important aspect for me is getting power to the wheels. What effect will the switching frequency have on the power output?

#5
##### May 06, 2011, 12:21 am
Thank you

You are welcome.

Quote
Can the Arduino Uno be configured to work for 3 simultaneous PWM outputs?

The Uno can provide up to six simultaneous PWM outputs.  The four outputs associated with timer 1 and timer 2 can be configured any way you wish.  Any changes to he two outputs associated with timer 0 will effect millis / micros / delay / delayMicroseconds; I suggest leaving timer 0 alone.

Quote
What effect will the switching frequency have on the power output?

I have no idea.  Someone else will have to help with that question.

#### jdeck004

#6
##### May 06, 2011, 01:55 am
Ok thanks again hopefully someone else chimes in as well.

If I modify only timer1 how many fast switching outputs will be available?

Thanks

#7
##### May 06, 2011, 02:03 am
If I modify only timer1 how many fast switching outputs will be available?

Two.  There are two outputs associated with each timer.

#### jdeck004

#8
##### May 06, 2011, 02:52 am

If I modify only timer1 how many fast switching outputs will be available?

Two.  There are two outputs associated with each timer.

Will the program you posted modify both timer1 and timer2 so that I can achieve fast switching on 3 pins? Could you briefly explain what it does? If not, could you direct me how to achieve this result?

Unfortunately my programming experience is only in MATLAB.

Thanks,
John

#9
##### May 06, 2011, 07:12 am
Will the program you posted modify both timer1 and timer2 so that I can achieve fast switching on 3 pins?

The usable code...
http://arduino.cc/forum/index.php/topic,58757.msg424549.html#msg424549
...only modifies timer 1.

Quote
Could you briefly explain what it does?

The code changes timer 1 to mode 14 (one of the "fast" modes; details in the datasheet), sets output A to normal, and sets output B to inverted.  If you want both outputs to be normal, make this change...

Quote
// Set Compare Output Mode and part of the Waveform Generation Mode (mode 14)
TCCR1A =
(1 << COM1A1) | (0 << COM1A0)  // Clear OC1A on Compare Match, set OC1A at BOTTOM (non-inverting mode)
|
(1 << COM1B1) | (0 << COM1B0)  // Clear OC1B on Compare Match, set OC1B at BOTTOM (non-inverting mode)
|
(1 << WGM11) | (0 << WGM10);  // Mode 14: Fast PWM, TOP = ICR1, Update of OCR1x at BOTTOM, TOV1 Flag Set on TOP

The value is 0 through 199 for both outputs.  These lines of code change the output (for non-inverting)...

Code: [Select]
`  // Full on  OCR1A = 199;  OCR1B = 199;  // Full off  OCR1A = 0;  OCR1B = 0;  // Half  OCR1A = 99;  OCR1B = 99;`

Quote
If not, could you direct me how to achieve this result?

The big steps for changing timer 2 are identical.  The details (bit values) are different.  I suggest copying the code in setup and then working through it line-by-line checking the datasheet as you go.  If you get stuck, I suspect you'll find help here.

#### jdeck004

#10
##### May 09, 2011, 04:42 am
I am clearly in over my head here. What is the function of this section? Is it merely a test?

Code: [Select]
`void loop( void ){  delay( 1000 );  // A full on  OCR1A = 199;  delay( 1000 );    // B full on  OCR1B = 0;  delay( 1000 );  // A twinkling  OCR1A = 1;  delay( 1000 );  // B twinkling  OCR1B = 198;  delay( 1000 );  // A off  OCR1A = 0;  delay( 1000 );  // B off  OCR1B = 199;}`

When you reference the datasheet, does that mean the datasheet for the atmega328p?

Keep in mind I don't know this programming language at all and have no experience with using datasheets.

Hope you don't mind spoonfeeding a little bit. Thanks again for your help.

John

#11
##### May 09, 2011, 06:46 am
Quote
Is it merely a test?

Yes.  It is meant to exercise the two output pins attached to timer 1 and to illustrate how to set the output value.  Normally, PWM values range from 0 to 255.  To achieve 10 KHz output, the range is reduced.  The new range is from 0 to 199.

Note: Timer 1 is a 16 bit timer so it should be possible to extend the range beyond 0 to 199 (and beyond 0 to 255).  @Arman did not seem interested so I didn't bother.

What is the function of this section?

Every Sketch must have two functions: setup and loop.  setup is called first and only once.  In most cases, setup is used to prepare the hardware.  loop is called second and forever after.  loop is typically where the action is; in your case where robot behaviour code goes.

Code: [Select]
`void loop( void ){  delay( 1000 );  // Pauses execution for 1000 milliseconds  // A full on  OCR1A = 199;  // Sets the timer 1 channel A "Output Compare Register" to 199.  The earlier code configured timer 1 to generate "fast PWM" signals and enabled output on the OC1A pin so this assignment changes the pulse width.  delay( 1000 );  // Another 1 second pause    // B full on  OCR1B = 0;  // Sets the timer 1 channel B "Output Compare Register" to 0.  This channel was configured for inverted output so zero is full on.  delay( 1000 );  // 1 second  // A twinkling  OCR1A = 1;  // Sets timer 1 channel A output to the smallest possible pulse width (1 / 200 or just barely on).  delay( 1000 );  // B twinkling  OCR1B = 198;  // Because channel B is inverted, this sets the smallest possible pulse width ((199-198)/200 or just barely on).  delay( 1000 );  // A off  OCR1A = 0;  delay( 1000 );  // B off  OCR1B = 199;}`

Quote
When you reference the datasheet, does that mean the datasheet for the atmega328p?

Yes.

Quote
Keep in mind I don't know this programming language at all

Fortunately, you have LOTS of working examples and there seem to be helpful folks here.

Quote
and have no experience with using datasheets

The Atmel + AVR GCC folks did a great job of binding the programming language to the datasheet.  For example, this line of code sets the value of the OCR1A register...

OCR1A = 0;

Search the datasheet for "OCR1A" and you will learn everything you need to know (and probably some things you don't care to know  ) about the OCR1A register.  Need to assign a value to the DIDR1 register?  No sweat.  It's just like assigning a value to a variable...

DIDR1 = 0;

Quote

You are welcome.

#### jdeck004

#12
##### May 09, 2011, 09:59 am
The resolution from 0 to 199 seems fine for my purpose as well.

Code: [Select]
`void setup( void ){  // Turn off the timer while we make changes  TCCR2B = TCCR2B & ~ ((1 << CS22) | (1 << CS21) | (1 << CS20));    // Ensure the Timer 2 output pins are configured for output  pinMode( ???, OUTPUT );  pinMode( ????, OUTPUT );    // Set Compare Output Mode and part of the Waveform Generation Mode (mode 14)  TCCR2A =       (1 << COM2A1) | (0 << COM2A0)        |      (1 << COM2B1) | (0 << COM2B0)              (1 << WGM21) | (0 << WGM20);          // Set the other half of the Waveform Generation Mode (mode 14) and ensure a few things are disabled  TCCR2B =      (0 << FOC2A)        |      (0 << FOC2B)        |      (1 << WGM23) | (1 << WGM22)       |      (0 << CS22) | (0 << CS21) | (0 << CS20);    ICR2 = 199;    // Start with both outputs turned off  OCR2A = 0;  OCR2B = 0;    // Start the clock  TCCR2B =       TCCR2B       |      (0 << CS22) | (1 << CS21) | (0 << CS20);  }`

How does this look? According to the register summary many of the bits transfer over directly by changing n=1 to n=2.

I was not able to determine which output pins timer2 controls.

#13
##### May 09, 2011, 09:02 pmLast Edit: May 09, 2011, 09:04 pm by Coding Badly Reason: 1
I was not able to determine which output pins timer2 controls.

How to decode the OCnx pin identifier ... Timer / Counter n Output Compare Match x Output ... the number (n) indicates which timer ... the letter (x) indicates which channel.  So, we need to search the datasheet for "OC2A" (Output Compare for Timer 2 Channel A) and "OC2B" (Output Compare for Timer 2 Channel B)...

Open the datasheet.  Navigate to "Pin Configurations".  Search for "OC2A" and "OC2B".

Quote
How does this look?

I'll try to look at it this evening.

#### jdeck004

#14
##### May 09, 2011, 10:44 pm

I was not able to determine which output pins timer2 controls.

How to decode the OCnx pin identifier ... Timer / Counter n Output Compare Match x Output ... the number (n) indicates which timer ... the letter (x) indicates which channel.  So, we need to search the datasheet for "OC2A" (Output Compare for Timer 2 Channel A) and "OC2B" (Output Compare for Timer 2 Channel B)...

Open the datasheet.  Navigate to "Pin Configurations".  Search for "OC2A" and "OC2B".

Looks like OC2a leads into Pin 17, or PB3, of the PDIP. OC2b leads to Pin 5, or PD3, of the PDIP.

It looks like PB3 means Port B pin 3, and PD3 is Port D pin 3.

I still cannot find documentation in the datasheet about what pins lead to these. I think this is because the datasheet is not specific to the Arduino Uno.

Looking up the Arduino Uno schematic it looks like PD3 leads to either pin 3, and PB3 leads to pin 11.

The same schematic leads me to see that OC1a and OC1b lead to pins 9 and 10 respectively, which appears to verify my conclusion.

Quote

Quote
How does this look?

I'll try to look at it this evening.

Ok. I will be checking back here often. I am quite sure it will need help.

John

Go Up

Please enter a valid email to subscribe