This section applies to LinkIt Smart 7688 development board only. For LinkIt Smart 7688 Duo development board , use the Arduino IDE to control PWM.
This section introduces controlling PWM with MRAA APIs. The implementation is provided in Node.js, but the same approach can be applied to Python and C/C++ versions.
Pulse-width modulation allows a digital pin to send digital pulse signals characterized by pulse width (duty cycle) and period. Many actuators take PWM signal as an input, notably servo motors and electronic motor drivers.
Configure PWM pin
To use PWM, initialize it on a certain pin such as GPIO. Note that only GPIO 18, GPIO 19, GPIO 20 and GPIO 21 support PWM on LinkIt Smart 7688 development board. First, create a PWM object and assign the desired GPIO pin number.
var mraa = require('mraa'); var pwmPin = new mraa.Pwm(19);
The pinout diagram illustrates the exact mapping between GPIO pin numbers and the actual on-board pins. GPIO 19 maps to P27 on LinkIt Smart 7688 board development board, as shown below:
Configure PWM settings
To control the PWM signal pattern, several parameters are required, including:
This defines the carrier frequency of the modulation. It’s controlled by period(), period_ms() and period_us() APIs, such as:
var mraa = require('mraa'); var pwmPin = new mraa.Pwm(19); pwmPin.period_ms(20); // 20ms period ==> 500Hz
Using only period() API is not enough to designate a PWM signal.
Duty cycle and pulse width
These two parameters are related and usually you only need to set one of them. Duty cycle is controlled by write API with a value in a range from 0.0 to 1.0, where 0.0 is 0% of duty cycle and 1.0 is 100% of duty cycle. Pulse width also defines the pattern in a different unit; the "uptime" of the signal in time units. This is defined by pulsewidth(), pulsewidth_ms() and pulsewidth_us() APIs.
The following example generates a 500Hz PWM signal with 25% duty cycle on pin P27 (GPIO 19).
var mraa = require('mraa'); var pwmPin = new mraa.Pwm(19); // GPIO19 (P27) pwmPin.period_ms(20); // 20ms period ==> 500Hz pwmPin.pulsewidth_ms(10); // 10ms pulse width over 20ms period ==> 50% duty cycle
Call config_percent() to directly assign period and duty cycle:
var mraa = require('mraa'); var pwmPin = new mraa.Pwm(19); // GPIO19 (P27) pwmPin.config_percent(20, 0.5); // 20ms period with 50% duty cycle
Enable the output
Once the PWM is configured, call the function enable(true) to enable it, as shown below.
var mraa = require('mraa'); var pwmPin = new mraa.Pwm(19); // GPIO19 (P27) pwmPin.period_ms(20); // 20ms period ==> 500Hz pwmPin.pulsewidth_ms(10); // 10ms pulse width over 20ms period ==> 50% duty cycle pwmPin.enable(true); // Start sending PWM signal
Attach a logic analyzer to P27 the output is a pulse signal with 50Hz frequency and 50% (10 ms out of 20ms) duty cycle:
Control a Servo
An application of using PWM signals is controlling a servo. A pulse width of 1500µs means the neutral position, while usually 1000ms and 2000ms being the minimum and maximum positions. The following code resets the servo motor to a neutral position:
var mraa = require('mraa'); var pwmPin = new mraa.Pwm(19); // GPIO19 (P27) pwmPin.period_ms(20); pwmPin.pulsewidth_us(1500); // change to 1000 / 2000 for min/max positions pwmPin.enable(true);
Powering up a Servo
Driving a motor requires a larger current, it's recommended to use either a separate voltage regulator, or at least use a USB power adapter that provides larger current, such as 1A. If you supply the power from 3V3 or 5V pins of the LinkIt Smart 7688 development board directly with a USB power adapter that provides only 500mA current, you may experience board malfunctions, such as sudden resets of the board.
Controlling an RC Car with PWM
You can find an example that uses PWM to steer a remote control card (RC Car) here: https://github.com/MediaTek-Labs/7688-fpv-rccar/