Low Frequency PWM Example
Last Modified: 2006-11-03
find:

basket

Acroname Robotics PDF webpage version Low Frequency PWM Example PDF

Related
Products

Product image for Brainstem GP 1.0 Module
Brainstem GP 1.0 Module

Contents

Introduction

In this example, a BrainStem GP 1.0 outputs two 100Hz PWM signals on digital IO pins 3 and 4.  Two independent reflexes are used to control the PWM signals. 

Pulse Width Modulation, or PWM, is typically used to control the speed of motors or the brightness of lights.  The most basic form of PWM is a rectangular wave of a constant frequency with a carefully-controlled ratio of "on-time" to "off-time".  More "on-time" makes a motor go faster or a light appear brighter.  When using PWM for motor speed control, a high frequency gives the best performance.  Ideally, the frequency is beyond audible range, otherwise the motors may have a noticeable buzz or whine.  The GP 1.0 can not produce frequencies that high with a reflex.  However it can easily produce PWM signals of a few hundred hertz. 

The source code consists of two files.  The first file is a batch file with the reflex commands.  It can be loaded by entering batch "pwm.bag" from the Console.  The second file is a TEA file that has routines for controlling the reflex as well as a test loop.  This code uses the BrainStem libraries released with the Build 5 download. 

Source Code - Reflex

The PWM reflex sets its output pin high for time T then sets its output pin low for time P-T.  P is the period for the PWM signal.  In this example, P is 10ms so the frequency is 1/10ms or 100Hz.  T ranges from 0ms to 10ms in 0.1ms increments.  In the test program, a value of 0-100 corresponds to a 0% to 100% duty cycle.  The reflex reads a scratch pad byte to determine the current duty cycle setting.  Additional scratch pad bytes provide extra control of the output pin so that a true 0% and 100% duty cycle may be achieved.  Once started, the two reflexes that produce PWM on digital pins 3 and 4 run continually. 

It is possible to increase the PWM frequency.  Look for the following two lines in the "pwm.bag" file listed below:

/* filename: pwm.bag */ 2 12 0 2 4 39 24 0 100 2 12 0 2 4 39 22 0 100

Try changing both the 100 values to 50.  That changes the period from 10ms to 5ms and gives a PWM frequency of 200Hz.  If that value is changed to 50, the defined value PWMMAX in the "pwm.tea" program must also be changed to 50.  That limits the PWM steps to a range of 0-50.  A value of 0 will correspond to a 0% duty cycle and a value of 50 will correspond to a 100% duty cycle.  The PWM period can be decreased further, but the number of PWM control steps decreases as well.  A smaller PWM period also means the Stem will spend more time running the PWM reflex commands so TEA code will execute more slowly. 

2 11 128 43 128 128 2 11 128 125 1 148 130 128 2 11 128 124 131 149 2 11 128 42 132 128 2 11 128 123 5 148 134 128 2 11 128 122 135 165 2 11 128 41 136 128 2 11 128 121 9 148 138 128 2 11 128 120 139 149 2 11 128 40 140 128 2 11 128 119 13 148 142 128 2 11 128 118 143 165 2 12 128 0 2 3 52 125 30 2 12 128 1 2 3 27 4 0 2 12 128 2 2 3 52 124 31 2 12 0 2 4 39 23 0 0 2 12 134 3 2 12 128 4 2 3 52 123 29 2 12 128 5 2 3 27 4 0 2 12 128 6 2 3 52 122 31 2 12 0 2 4 39 24 0 100 2 12 134 7 2 12 128 8 2 3 52 121 27 2 12 128 9 2 3 27 3 0 2 12 128 10 2 3 52 120 28 2 12 0 2 4 39 21 0 0 2 12 134 11 2 12 128 12 2 3 52 119 26 2 12 128 13 2 3 27 3 0 2 12 128 14 2 3 52 118 28 2 12 0 2 4 39 22 0 100 2 12 134 15

Source Code - TEA Example

The following file is a TEA program that has routines for controlling the reflex as well as a test loop.  This code uses the BrainStem libraries released with the Build 5 download. 

/* filename: pwm.tea */ #include <aCore.tea> #include <aDig.tea> #include <aPrint.tea> #define PWMMAX 100 #define PWMPIN2 4 #define PWMPIN1 3 #define PWM2START 0x0300+125 /* raw inputs to start PWM */ #define PWM1START 0x0300+121 #define PWM2DUTY 0x0200+31 /* scratch pad control */ #define PWM2HICYC 0x0200+30 #define PWM2LOCYC 0x0200+29 #define PWM1DUTY 0x0200+28 #define PWM1HICYC 0x0200+27 #define PWM1LOCYC 0x0200+26 void init_pwm() { aDig_Config(PWMPIN2,ADIG_OUTPUT); aDig_Config(PWMPIN1,ADIG_OUTPUT); aCore_Outportc(PWM2DUTY,1); aCore_Outportc(PWM2HICYC,0); aCore_Outportc(PWM2LOCYC,0); aCore_Outportc(PWM2START,1); aCore_Outportc(PWM1DUTY,1); aCore_Outportc(PWM1HICYC,0); aCore_Outportc(PWM1LOCYC,0); aCore_Outportc(PWM1START,1); } void pwm_set2(char a) { if (a==0) { aCore_Outportc(PWM2HICYC,0); aCore_Outportc(PWM2LOCYC,0); return; } if (a>=PWMMAX) { aCore_Outportc(PWM2HICYC,1); aCore_Outportc(PWM2LOCYC,1); return; } aCore_Outportc(PWM2HICYC,1); aCore_Outportc(PWM2LOCYC,0); aCore_Outportc(PWM2DUTY, a); } void pwm_set1(char a) { if (a==0) { aCore_Outportc(PWM1HICYC,0); aCore_Outportc(PWM1LOCYC,0); return; } if (a>=PWMMAX) { aCore_Outportc(PWM1HICYC,1); aCore_Outportc(PWM1LOCYC,1); return; } aCore_Outportc(PWM1HICYC,1); aCore_Outportc(PWM1LOCYC,0); aCore_Outportc(PWM1DUTY, a); } void main() { char i; char j; aPrint_String("PWM test\n"); init_pwm(); while (1) { for (i=0; i<=PWMMAX; i++) { j=PWMMAX-i; pwm_set2(i); pwm_set1(j); aCore_Sleep(100); } aCore_Sleep(500); for (i=PWMMAX; i>=0; i--) { j=PWMMAX-i; pwm_set2(i); pwm_set1(j); aCore_Sleep(100); } aCore_Sleep(500); } }

Revision History:

  • 2002-01-24: Example Created.
 

Related Links:

Concepts: Description of Pulse Width Modulation (PWM)

Related Examples:

Creating Four Low Frequency PWM Channels on a Brainstem GP Example

voice: 720-564-0373, email: sales@acroname.com, address: 4822 Sterling Dr., Boulder CO, 80301-2350, privacy
© Copyright 1994-2008 Acroname, Inc., Boulder, Colorado. All rights reserved.