SoftPWMServo | |
---|---|
Quick Look | |
Hardware | (External hardware) |
Include | SoftPWMServo.h |
This library allows every single pin on a PIC32 Based ChipKit Board to be used (simultaneously) for PWM output or RC Servo output.
The SoftPWMServo library was written primarily to allow existing Arduino sketches to be more easily ported to the ChipKIT boards. Since the PIC32 does not have as many available PWM outputs or RC Servo outputs, this library implements in software what would normally be done almost entirely in hardware. It allows for every single pin on a PIC32 based boards to be used (simultaneously) for PWM output or RC Servo output. Since it is a software based library, it does come with some negatives such as increased CPU usage and jitter.
Because the pin transitions are driven by software, there are limits to how accurate the pulses are, but for almost all uses, this library will work just fine, even with a large number of pins being used for PWM or Servo. Also, this library does add CPU load to the system, which is proportional to the number of pins being used for PWM or Servo output.
This library can utilize any pin on a PIC32 based ChipKit Board enabling it to produce a PWM (Pulse Width Modulation) signal. Therefore the following wiring information is only one example of how you could use this library.
Servos have 3 wires (Power, Ground, and Signal). They consume a considerable amount of power and therefore the Power and Ground wires should be connected to a suitable power source and are often connected to an external power source instead the 5V pin on the ChipKit as shown here. Signal wires need a return path. Therefore, make sure the ground wire of the power power supply is connected to the ground pin of the ChipKit. The Signal wire of the servo should connected to an unused digital pin. Refer to the Fritzing Wiring Diagram.
The following sketch examples demonstrated how to use the SoftPWMServo library object.
Ramps the value on up to 3 different pins from 0 to 255 (0 to 100%). Simply un-comment the line(s) of code which corresponds to the pins you would like to increment.
// Simple PWM demonstration using SoftPWMServo library
// by Brian Schmalz http://www.schmalzhaus.com
// This example code is in the public domain.
// We take 3 pins (could be any at all) and slowly
// ramp them up from 0% to 100%. You could put
// red, green and blue LEDs on these pins and have a neat
// little color fader.
#include <SoftPWMServo.h>
// Pick 3 pins, any 3 pins, and use them for our PWM output
const int PinOne = 10;
const int PinTwo = 35;
const int PinThree = 22;
// Start each pin out at a different PWM value
char PinOneValue = 0;
char PinTwoValue = 100;
char PinThreeValue = 200;
void setup()
{
}
void loop()
{
// Set each of our three pins as PWM outputs, with their respective values
SoftPWMServoPWMWrite(PinOne, PinOneValue);
SoftPWMServoPWMWrite(PinTwo, PinTwoValue);
SoftPWMServoPWMWrite(PinThree, PinThreeValue);
// Incriment each PWM value - they will roll over after 255 due to being chars
// PinOneValue++;
// PinTwoValue++;
// PinThreeValue++;
// Wait just a tad so we don't go too fast.
delay(15);
}
Tells a servo to go from a position defined by a 1ms pulse to a position defined by a 2ms pulse in increments of 10us with a 25ms delay between each step. This routine then repeats forever.
// Simple Servo demonstration using SoftPWMServo library
// by Brian Schmalz http://www.schmalzhaus.com
// This example code is in the public domain.
// We take a pin (could be any pin) and use it as a servo
// output. We sweep from 1ms pulse to 2ms pulse to show
// that the servo can be controlled.
// Note that you could easily write a little function to
// convert from 'desired angle in degrees' to 'microseconds'
// so that you could specify a degree value to your servo.
#include <SoftPWMServo.h>
int pos = 0; // variable to store the servo position, in microseconds
const int pin = 10; // Choose _any_ pin number on your board
void setup()
{
}
void loop()
{
for(pos = 1000; pos < 2000; pos += 10) // goes from 1ms to 2ms
{ // in steps of 10us
SoftPWMServoServoWrite(pin, pos); // tell servo to go to position in variable 'pos'
delay(25); // waits 25ms for the servo to reach the position
}
}
int32_t SoftPWMServoInit(void);
Returns: SOFTPWMSERVO_OK
Initializes the SoftPWMServo library. It clears out all internal variables to their default states, and hooks the SoftPWMServo CoreTimer ISR function into the main CoreTimer interrupt. Call this function before calling any others from this library (optional, as SoftPWMServoPinEnable and SoftPWMServoWrite calls will call this function on their own if necessary.)
Name | Default Value | Description |
---|---|---|
SOFTPWMSERVO_VERSION | [version] | Software version of this library |
SOFTPWMSERVO_MAX_PINS | NUM_DIGITAL_PINS | Max number of pins the library can handle (from variant Board_Defs.h) |
SOFTPWMSERVO_ERROR | -1 | Returned when a function fails |
SOFTPWMSERVO_OK | 0 | Returned when a function passes |
SOFTPWMSERVO_SERVO | 1 | Used to enable a pin for servo operation |
SOFTPWMSERVO_PWM | 0 | Used to enable a pin for PWM operation |
MIN_PULSE_WIDTH | 544 | The shortest pulse sent to a servo (us) |
MAX_PULSE_WIDTH | 2400 | The longest pulse sent to a servo (us) |
DEFAULT_PULSE_WIDTH | 1500 | Default pulse width when servo is attached (us) |
DEFAULT_FRAMES_PER_SECOND | 400 | 2.5ms per frame |
SOFTPWMSERVO_DEFAULT_FRAME_TIME | (F_CPU / 2 / DEFAULT_FRAMES_PER_SECOND) | Number of 40MHz CoreTimer ticks of the default frame time |
CORE_TICKS_PER_US | (F_CPU / 2 / 1000000) | How many CoreTimer ticks are there per microsecond |
SOFTPWMSERVO_DEFAULT_SERVO_FRAMES | 10 | Default number of frames between servo rising edges |
usToTicks(_us) | (CORE_TICKS_PER_US * _us) | converts microseconds to 40MHz CoreTimer ticks |
ticksToUs(_ticks) | (((uint32_t)_ticks ) / (float)CORE_TICKS_PER_US) | Converts from 40MHz ticks to microseconds |
int32_t SoftPWMServoUnload(void);
Removes the SoftPWMServo CoreTimer ISR function hook from the main CoreTimer ISR in wiring.c
int32_t SoftPWMServoPinEnable(uint32_t Pin, bool PinType);
Sets up a particular pin for use with the SoftPWMServo library. Pin is set to valid pin number for the board you are using (0 to SOFTPWMSERVO_MAX_PINS). PinType is set to either SOFTPWMSERVO_SERVO or SOFTPWMSERVO_PWM.
int32_t SoftPWMServoPinDisable(uint32_t Pin);
Disables a pin from use by the SoftPWMServo library
int32_t SoftPWMServoRawWrite(uint32_t Pin, uint32_t Value, bool PinType);
Sets a particular pin to have a new PWM or Servo pulse high-time and sets the pin to be a Servo or PWM pin. Pin is set to valid pin number for the board you are using (0 to SOFTPWMSERVO_MAX_PINS). PinType is set to either SOFTPWMSERVO_SERVO or SOFTPWMSERVO_PWM. Value is specified in Ticks. Hint: use usToTicks(Value) to specify the value in microseconds.
This function is called internally by ServoWrite and PWMWrite. You do not need to call it unless you want full control over the pin's high time. This function allows you to specify the high time of the pin in 40MHz units.
int32_t SoftPWMServoServoWrite(uint32_t Pin, float Value);
Use this function to set a pin to be a servo output, and to specify the pin's pulse width. Pin is set to valid pin number for the board you are using (0 to SOFTPWMSERVO_MAX_PINS). Value is specified in microseconds.
Note that if Value is greater than the current FrameTime (normally around 2ms) then FrameTime is used (since that's the longest pulse that can be generated.) Use SoftPWMServoSetFrameTime() to use a longer frame time if you need your servo to go further.
int32_t SoftPWMServoPWMWrite(uint32_t Pin, uint8_t Value);
Use this function to set a pin to be a PWM pin, and specify its pulse width. Equivalent to the normal analogWrite() call. Pin is set to valid pin number for the board you are using (0 to SOFTPWMSERVO_MAX_PINS). Value is specified as an integer between 0 and 255 (0% t0 100%) representing the time you want your pin to stay high.
int32_t SoftPWMServoRawRead(uint32_t Pin);
Returns the current pulse width, in 40MHz ticks, of Pin.
float SoftPWMServoServoRead(uint32_t Pin);
Returns the current pulse width, in microseconds, of Pin.
int8_t SoftPWMServoPWMRead(uint32_t Pin);
Returns the current pulse width, from 0 to 255, of Pin.
int32_t SoftPWMServoSetFrameTime(uint32_t NewTime);
Sets a new frame time, in 40MHz ticks for the library
int32_t SoftPWMServoSetServoFrames(uint32_t NewFrameCount);
Sets a new value for how many frames between rising edges of the servo pins.
List some links to external resources, such as: