DRV2605

This module is for controlling a DRV2605 motor driver. Use the DRV2605 (About Modules) module for it. It has its origins as a port of Ladyada's Arduino library.

More more on the chip, see the datasheet and the guide by Adafruit. This Espruino module has been only tested with Adafruit's DRV2605 breakout.

You can wire this up as follows:

Device Pin Espruino
1 (VIN) 3.3
2 (GND) GND
3 (SCL) SCL
4 (SDA) SDA

As an example, for an Espruino Pico, use B6 for SCL and B7 for SDA. This corresponds to I2C1.

Initialisation

Assuming the breakout is wired up to the B6 and B7 (I2C on the Pico):

I2C1.setup({scl: B6, sda: B7 });
var hap = require('DRV2605').connect(I2C1);

Basic usage

Triggering a single effect can be done by numeric index (see section 11.2 in the datasheet), or by effect name.

// By index:
hap.trigger(6);

// Or by name:
hap.trigger('sharp click 30%');

Sequencer

Effects can be assembled into a sequence of up to eight steps (positions 0-7). The sequencer stops if any step is empty. setWaveform(step, effect) sets a particular sequence step:

// Set sequencer step 0 to be effect 6
hap.setWaveform(0, 6);

// Or by name:
hap.setWaveform(0, 'sharp click 30%');

Once steps are filled in, the sequence can be started or stopped

// Start sequence
hap.start();

// Stop
hap.stop();

setSequence(steps) allows you to set all the steps at once:

// Make a sequence of three effects (by index)
hap.setSequence([70, 106, 47]);
hap.start();

Names can be used to make code more readable:

hap.setSequence([
  'ramp down long smooth 1',
  'ramp up long smooth 1 half',
  'buzz 1 100%'
  ]);
hap.start();

Effect names

Effect names are based on names from the datasheet. To list them:

for (let i=0;i<hap.EFFECTS.length;i++) {
  console.log( (i+1) + '. '+ hap.EFFECTS[i]);
}

Fetch the index of an effect by name. -1 is returned if the name was not found.

hap.getWaveform('soft fuzz 60%'); // Returns 13

Real-time mode

Real-time mode allows for direct control of motor. To use, first call setMode('rtp'). Note that motor will continue running, use setMode('internal-trigger') to stop it and return to the default behaviour.

In the example below, two arrays are used, defining amplitude (ie. power, on a 0-127 range) and delay periods (ie. how long to run for each step). It's a good idea not to run the motor continuously for very long, it's designed for very short intervals.

hap.setMode('rtp');

// Motor power, per step
let powers =  [30, 100, 30, 200, 90, 100];

// Duration (ms), per step
let durations = [100, 200, 100, 300, 200, 100];

// Current step
let index = 0;

const fire = function() {
  if (powers.length !== durations.length) throw new Error('powers and delays arrays must be same length');
  let i = index;
  if (i < powers.length) {
    hap.setRealtimeValue(powers[i]);
    index++;
    setTimeout(fire, durations[i]);
  } else {
    hap.setMode('internal-trigger');
    console.log('Done.');
  }
};
fire();

Configuration

By default, the it's assumed an ERM (Eccentric Rotating Mass) motor is wired up. If you're using a LRA (Linear Resonance Actuator) motor, call useLRA() after initialisation.

There are a few modes of operation. See the datasheet for more info on this. internal-trigger is the initial mode.

// 'internal-trigger', 'external-trigger-rising', 'external-trigger-falling',
// 'pwm', 'audio',
// 'rtp', 'diagnostics', 'calibration'

// Real-time mode
hap.setMode('rtp)'

Reference

/* Assign a waveform to a sequencer slot. 
 * See the datasheet, section 11.2 for a list of effects.
 * https://cdn-shop.adafruit.com/datasheets/DRV2605.pdf
 * @param {number} slot Slot to set, 0-7
 * @param {string|number} nameOrIndex Waveform sequence value. Either 1-123, or string to use a named effect.
 */
DRV2605.prototype.setWaveform = function (slot, nameOrIndex) { ... }

/* Set up to eight steps. Unused steps are emptied.
 * @param {string[]|number[]} steps An array of indexes or effect names
 */
DRV2605.prototype.setSequence = function (steps) { ... }

/* Assigns a waveform to the initial sequencer slot and plays it
 * @param {string|number} nameOrIndex Name of effect or numerical index
 */
DRV2605.prototype.trigger = function (nameOrIndex) { ... }

/* Looks up a waveform index by name
 * @param {string} name Name of effect
 * @returns Index, or -1 if not found
 */
DRV2605.prototype.getWaveform = function (name) { ... }

/* Select library
 * @param {number} lib 0 is empty, 1-5 ERM, 6 is LRA
 */
DRV2605.prototype.selectLibrary = function (lib) { ... }

/* Run sequence
 */
DRV2605.prototype.start = function () { ... }

/* Stop sequence
 */
DRV2605.prototype.stop = function () { ... }

/* Sets a mode by integer value, see datasheet
 * Section 7.6.2 http://www.adafruit.com/datasheets/DRV2605.pdf
 * @param {number} mode Mode (0-7)
 */
DRV2605.prototype.setModeInt = function (mode) { ... }

/* Sets mode by string. Use `setModeInt` to assign by number
 * Available modes are: 
 *  internal-trigger, external-trigger-rising,
 *  external-trigger-falling, pwm, audio, rtp,
 *  diagnostics, calibration
 * @param {string} mode String mode
 */
DRV2605.prototype.setMode = function (mode) { ... }

/* Sets amplitude of motor when in real-time mode.
 * @param {number} Amplitude 0-127
 */
DRV2605.prototype.setRealtimeValue = function (rtp) { ... }

/* Use ERM (Eccentric Rotating Mass) mode.
 */
DRV2605.prototype.useERM = function () { ... }

/* Use LRA (Linear Resonance Actuator) mode.
 */
DRV2605.prototype.useLRA = function () { ... }

/* Connects to module
 * @param {1} i2c I2C instance
 * @param {*} opts Options
 * @returns
 */
exports.connect = function (i2c, opts) { ... }

This page is auto-generated from GitHub. If you see any mistakes or have suggestions, please let us know.