Modified the original DRV2605 library written by Bryce Williams. Team specific uint8_t kick_start_my_heart(int intensity, int duration) function is added to the library, otherwise unchanged. FLY ARMY!!!
Fork of DRV2605 by
- include "mbed.h"
- include "DRV2605.h" DRV2605 haptics(p9, p10); *NEEDE FOR KCIKSTART*
PwmOut base(p26); *NEEDED FOR BOOSTER CIRCUIT, if required*
int main() { base.period(.000001);1MHz base=.5;50% duty cycle
*FOLLOWING NEEDED FOR KICKSTART*
haptics.init(3.3); Motor initialization will cause a 1 second vibration
wait(2);
uint8_t stats=haptics.kick_start_my_heart(10, 1); Intensity range 1-10, duratio range 1-8
printf("dig %X/n",haptics.init(3.3)); }
DRV2605.cpp@1:224404f39d98, 2016-12-02 (annotated)
- Committer:
- hkreuk
- Date:
- Fri Dec 02 00:20:14 2016 +0000
- Revision:
- 1:224404f39d98
- Parent:
- 0:3b2b4f34aaca
To integrate to the Mask, just need DRV2605.cpp and its header file. To haptic feedback, example is provided in main.cpp; ; FLY ARMY!!!
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| electromotivated | 0:3b2b4f34aaca | 1 | #include "DRV2605.h" |
| electromotivated | 0:3b2b4f34aaca | 2 | |
| electromotivated | 0:3b2b4f34aaca | 3 | DRV2605::DRV2605(PinName sda, PinName scl): i2c(sda, scl){ |
| electromotivated | 0:3b2b4f34aaca | 4 | wait_us(250); // Device datasheet specified wait time before I2C |
| electromotivated | 0:3b2b4f34aaca | 5 | // comms should be used |
| electromotivated | 0:3b2b4f34aaca | 6 | } |
| electromotivated | 0:3b2b4f34aaca | 7 | |
| electromotivated | 0:3b2b4f34aaca | 8 | void DRV2605::i2cWriteByte(char reg, char value){ |
| electromotivated | 0:3b2b4f34aaca | 9 | char buff[2] = {reg, value}; |
| electromotivated | 0:3b2b4f34aaca | 10 | i2c.write(SLAVE_ADDR_7_BIT<<1, buff, 2); |
| electromotivated | 0:3b2b4f34aaca | 11 | } |
| electromotivated | 0:3b2b4f34aaca | 12 | |
| electromotivated | 0:3b2b4f34aaca | 13 | uint8_t DRV2605::i2cReadByte(char reg){ |
| electromotivated | 0:3b2b4f34aaca | 14 | char result; // Temp result storage |
| electromotivated | 0:3b2b4f34aaca | 15 | i2c.write(SLAVE_ADDR_7_BIT<<1, ®, 1, true); |
| electromotivated | 0:3b2b4f34aaca | 16 | i2c.read(SLAVE_ADDR_7_BIT<<1, &result, 1); |
| electromotivated | 0:3b2b4f34aaca | 17 | |
| electromotivated | 0:3b2b4f34aaca | 18 | return result; |
| electromotivated | 0:3b2b4f34aaca | 19 | } |
| electromotivated | 0:3b2b4f34aaca | 20 | |
| electromotivated | 0:3b2b4f34aaca | 21 | void DRV2605::mode(Mode mode){ |
| electromotivated | 0:3b2b4f34aaca | 22 | i2cWriteByte(MODE, mode); |
| electromotivated | 0:3b2b4f34aaca | 23 | } |
| electromotivated | 0:3b2b4f34aaca | 24 | |
| electromotivated | 0:3b2b4f34aaca | 25 | int DRV2605::init(float actuator_peak_voltage, Library lib){ |
| electromotivated | 0:3b2b4f34aaca | 26 | int result = |
| electromotivated | 0:3b2b4f34aaca | 27 | auto_cal_open_loop(actuator_peak_voltage); // Perform Open-Loop ERM Cal |
| electromotivated | 0:3b2b4f34aaca | 28 | i2cWriteByte(LIBRARY_SELECTION, lib); // Select ROM Library |
| electromotivated | 0:3b2b4f34aaca | 29 | mode(STANDBY); // Put device into low- power mode |
| electromotivated | 0:3b2b4f34aaca | 30 | return result; // Cal/Init Result 0: Pass 1: Fail |
| electromotivated | 0:3b2b4f34aaca | 31 | } |
| electromotivated | 0:3b2b4f34aaca | 32 | |
| electromotivated | 0:3b2b4f34aaca | 33 | uint8_t DRV2605::diagnostics(){ |
| electromotivated | 0:3b2b4f34aaca | 34 | mode(DIAG); |
| electromotivated | 0:3b2b4f34aaca | 35 | i2cWriteByte(GO, 1); |
| electromotivated | 0:3b2b4f34aaca | 36 | while(i2cReadByte(GO)); // Wait for GO bit to clear |
| electromotivated | 0:3b2b4f34aaca | 37 | |
| electromotivated | 0:3b2b4f34aaca | 38 | return i2cReadByte(STATUS); // Return Status Reg Value |
| electromotivated | 0:3b2b4f34aaca | 39 | } |
| electromotivated | 0:3b2b4f34aaca | 40 | |
| electromotivated | 0:3b2b4f34aaca | 41 | void DRV2605::play_waveform(int waveform_effect){ |
| electromotivated | 0:3b2b4f34aaca | 42 | mode(INTERNAL_TRIG); // Bring device out of standby and set to internal trigger |
| electromotivated | 0:3b2b4f34aaca | 43 | i2cWriteByte(WAVEFORM_SEQUENCER_1, waveform_effect); // Load waveform index to play |
| electromotivated | 0:3b2b4f34aaca | 44 | i2cWriteByte(WAVEFORM_SEQUENCER_2, 0); // Insert stop condition so we don't play other registers if filled |
| electromotivated | 0:3b2b4f34aaca | 45 | i2cWriteByte(GO, 0x01); // Set GO bit to start playback |
| electromotivated | 0:3b2b4f34aaca | 46 | } |
| electromotivated | 0:3b2b4f34aaca | 47 | |
| electromotivated | 0:3b2b4f34aaca | 48 | void DRV2605::load_waveform_sequence(int effect1, int effect2, |
| electromotivated | 0:3b2b4f34aaca | 49 | int effect3, int effect4, |
| electromotivated | 0:3b2b4f34aaca | 50 | int effect5, int effect6, |
| electromotivated | 0:3b2b4f34aaca | 51 | int effect7, int effect8){ |
| electromotivated | 0:3b2b4f34aaca | 52 | i2cWriteByte(WAVEFORM_SEQUENCER_1, effect1); |
| electromotivated | 0:3b2b4f34aaca | 53 | i2cWriteByte(WAVEFORM_SEQUENCER_2, effect2); |
| electromotivated | 0:3b2b4f34aaca | 54 | i2cWriteByte(WAVEFORM_SEQUENCER_3, effect3); |
| electromotivated | 0:3b2b4f34aaca | 55 | i2cWriteByte(WAVEFORM_SEQUENCER_4, effect4); |
| electromotivated | 0:3b2b4f34aaca | 56 | i2cWriteByte(WAVEFORM_SEQUENCER_5, effect5); |
| electromotivated | 0:3b2b4f34aaca | 57 | i2cWriteByte(WAVEFORM_SEQUENCER_6, effect6); |
| electromotivated | 0:3b2b4f34aaca | 58 | i2cWriteByte(WAVEFORM_SEQUENCER_7, effect7); |
| electromotivated | 0:3b2b4f34aaca | 59 | i2cWriteByte(WAVEFORM_SEQUENCER_8, effect8); |
| electromotivated | 0:3b2b4f34aaca | 60 | } |
| electromotivated | 0:3b2b4f34aaca | 61 | |
| electromotivated | 0:3b2b4f34aaca | 62 | void DRV2605::play(){ |
| electromotivated | 0:3b2b4f34aaca | 63 | i2cWriteByte(MODE, INTERNAL_TRIG); // Internal Trigger Mode |
| electromotivated | 0:3b2b4f34aaca | 64 | i2cWriteByte(GO, 1); |
| electromotivated | 0:3b2b4f34aaca | 65 | } |
| electromotivated | 0:3b2b4f34aaca | 66 | |
| hkreuk | 1:224404f39d98 | 67 | uint8_t DRV2605::kick_start_my_heart(int inten, int dur) { //inten range 1-10, dur range 1-8 |
| hkreuk | 1:224404f39d98 | 68 | //intensity values(1-123) refer to dvr2605_waveform.pdf, page60 |
| hkreuk | 1:224404f39d98 | 69 | int left_over; |
| hkreuk | 1:224404f39d98 | 70 | uint8_t res; |
| hkreuk | 1:224404f39d98 | 71 | for ( int ind=0x04; ind<=(dur+0x003); ind++ ) { |
| hkreuk | 1:224404f39d98 | 72 | i2cWriteByte(ind, inten); |
| hkreuk | 1:224404f39d98 | 73 | left_over=ind; |
| hkreuk | 1:224404f39d98 | 74 | } |
| hkreuk | 1:224404f39d98 | 75 | for (int ind=(left_over+1); ind<=0x0B; ind++) { |
| hkreuk | 1:224404f39d98 | 76 | i2cWriteByte(ind, 0); |
| hkreuk | 1:224404f39d98 | 77 | } |
| hkreuk | 1:224404f39d98 | 78 | res=diagnostics(); |
| hkreuk | 1:224404f39d98 | 79 | printf("%X", res); |
| hkreuk | 1:224404f39d98 | 80 | play(); |
| hkreuk | 1:224404f39d98 | 81 | return res; |
| hkreuk | 1:224404f39d98 | 82 | } |
| hkreuk | 1:224404f39d98 | 83 | |
| hkreuk | 1:224404f39d98 | 84 | |
| electromotivated | 0:3b2b4f34aaca | 85 | uint8_t DRV2605::auto_cal_open_loop(float actuator_peak_voltage){ |
| electromotivated | 0:3b2b4f34aaca | 86 | // Exit Standby Mode; Enter Auto- Cal Mode |
| electromotivated | 0:3b2b4f34aaca | 87 | mode(AUTO_CAL); |
| electromotivated | 0:3b2b4f34aaca | 88 | |
| electromotivated | 0:3b2b4f34aaca | 89 | /* Set the following registers to the appropriate values: |
| electromotivated | 0:3b2b4f34aaca | 90 | • Rated Voltage (0x16) |
| electromotivated | 0:3b2b4f34aaca | 91 | • Overdrive Voltage (0x17) |
| electromotivated | 0:3b2b4f34aaca | 92 | • Feedback Control (0x1A) – Bits [1:0] can be left blank and will be |
| electromotivated | 0:3b2b4f34aaca | 93 | populated by the auto-calibration engine |
| electromotivated | 0:3b2b4f34aaca | 94 | • Control 1 (0x1B), Control 2 (0x1C), and Control 3 (0x1D) |
| electromotivated | 0:3b2b4f34aaca | 95 | • Mode (0x01) – Set mode to Auto-Calibration |
| electromotivated | 0:3b2b4f34aaca | 96 | • Auto-calibration Memory Interface (0x1E) – the auto-calibration time |
| electromotivated | 0:3b2b4f34aaca | 97 | can be increased to improve calibration, but can be left as default |
| electromotivated | 0:3b2b4f34aaca | 98 | for the initial calibration |
| electromotivated | 0:3b2b4f34aaca | 99 | */ |
| electromotivated | 0:3b2b4f34aaca | 100 | // Rated Voltage (0x16) not referenced for open-loop operation, skip calc |
| electromotivated | 0:3b2b4f34aaca | 101 | |
| electromotivated | 0:3b2b4f34aaca | 102 | // Calc and Set Overdrive Voltage Register (0x17) |
| electromotivated | 0:3b2b4f34aaca | 103 | int od_clamp = (int)(((actuator_peak_voltage*255)/5.6)+0.5); |
| electromotivated | 0:3b2b4f34aaca | 104 | i2cWriteByte(OVERDRIVE_CLAMP_VOLTAGE, |
| electromotivated | 0:3b2b4f34aaca | 105 | i2cReadByte(OVERDRIVE_CLAMP_VOLTAGE) | od_clamp); |
| electromotivated | 0:3b2b4f34aaca | 106 | |
| electromotivated | 0:3b2b4f34aaca | 107 | // Set Feedback Control Register (0x1A), use default values |
| electromotivated | 0:3b2b4f34aaca | 108 | |
| electromotivated | 0:3b2b4f34aaca | 109 | |
| electromotivated | 0:3b2b4f34aaca | 110 | // Set Control 1 Register (0x1B), use default values |
| electromotivated | 0:3b2b4f34aaca | 111 | |
| electromotivated | 0:3b2b4f34aaca | 112 | |
| electromotivated | 0:3b2b4f34aaca | 113 | // Set Control 2 Register (0x1C), use default values |
| electromotivated | 0:3b2b4f34aaca | 114 | |
| electromotivated | 0:3b2b4f34aaca | 115 | // Set Control3 Register (0x1D), Set to ERM Open-Loop Operation |
| electromotivated | 0:3b2b4f34aaca | 116 | i2cWriteByte(CONTROL3, 0xA0); |
| electromotivated | 0:3b2b4f34aaca | 117 | |
| electromotivated | 0:3b2b4f34aaca | 118 | // Set Control 4 Register (0x1E) |
| electromotivated | 0:3b2b4f34aaca | 119 | i2cWriteByte(CONTROL4, |
| electromotivated | 0:3b2b4f34aaca | 120 | i2cReadByte(CONTROL4 | 0x30)); // Max Calibration Time |
| electromotivated | 0:3b2b4f34aaca | 121 | |
| electromotivated | 0:3b2b4f34aaca | 122 | // Device already set to Auto- Cal Mode at top of this code block |
| electromotivated | 0:3b2b4f34aaca | 123 | |
| electromotivated | 0:3b2b4f34aaca | 124 | // Start auto- calibration |
| electromotivated | 0:3b2b4f34aaca | 125 | i2cWriteByte(GO, 0x01); |
| electromotivated | 0:3b2b4f34aaca | 126 | |
| electromotivated | 0:3b2b4f34aaca | 127 | // Wait for calibration to complete |
| electromotivated | 0:3b2b4f34aaca | 128 | while(i2cReadByte(GO)); |
| electromotivated | 0:3b2b4f34aaca | 129 | |
| electromotivated | 0:3b2b4f34aaca | 130 | // Read and return DIAG_RESULT in Status Register (0x00) |
| electromotivated | 0:3b2b4f34aaca | 131 | return (i2cReadByte(STATUS)); // Return the Diag_Result Bit Result |
| electromotivated | 0:3b2b4f34aaca | 132 | } |
| electromotivated | 0:3b2b4f34aaca | 133 |
