• Hi all!

    I'm Kacper, new here ;) I'm working on an espruino project on MDBT42Q Module.

    I'm experiencing problems running DRV2605, which I'm using to drive a small haptic motor, together with some neopixels. They work well on their own, but I can't get them to work together. I don't mean at the same time. Let me explain.

    To drive neopixels I use:

    const neopixelDataPin = D5;
    require("neopixel").write(neopixelDataPi­n, pixelBytes)

    This works well.

    I interface with the DRV2605 via I2C. Below you can see my test code:

    const DRV2605 = {
      ADDR: 0x5a,
      REG_STATUS: 0x00,
      REG_MODE: 0x01,
      REG_LIBRARY: 0x03,
      REG_GO: 0x0c,
      REG_WAVESEQ1: 0x04,
      REG_WAVESEQ2: 0x05,
      REG_RTPIN: 0x02,
      REG_OVERDRIVE: 0x0d,
      REG_SUSTAINPOS: 0x0e,
      REG_SUSTAINNEG: 0x0f,
      REG_BREAK: 0x10,
    const sclPin = D31;
    const sdaPin = D30;
    pinMode(sclPin, "output");
    pinMode(sdaPin, "output");
    const hapticPowerPin = D28;
    const hapticMultiModePin = D29;
    digitalWrite(hapticMultiModePin, 1);
    digitalWrite(hapticPowerPin, 1);
    const i2cHaptic = I2C1;
    i2cHaptic.setup({ scl: sclPin, sda: sdaPin});
    const haptic = { address: DRV2605.ADDR, stop: false };
    const prepareHaptic = () => {
      i2cHaptic.writeTo(haptic, DRV2605.REG_STATUS, 0x00);
      i2cHaptic.writeTo(haptic, DRV2605.REG_LIBRARY, 2);
      i2cHaptic.writeTo(haptic, DRV2605.REG_MODE, 0x00);
      i2cHaptic.writeTo(haptic, DRV2605.REG_RTPIN, 0x00);
      i2cHaptic.writeTo(haptic, DRV2605.REG_OVERDRIVE, 0);
      i2cHaptic.writeTo(haptic, DRV2605.REG_WAVESEQ1, 5);
      i2cHaptic.writeTo(haptic, DRV2605.REG_WAVESEQ2, 1);
      i2cHaptic.writeTo(haptic, DRV2605.REG_SUSTAINPOS, 1);
      i2cHaptic.writeTo(haptic, DRV2605.REG_SUSTAINNEG, 0);
      i2cHaptic.writeTo(haptic, DRV2605.REG_BREAK, 0);
    const hapticPush = (i2c) => {
      i2c.writeTo(haptic, DRV2605.REG_MODE);
      const result = i2c.readFrom(DRV2605.ADDR, 1);
      i2c.writeTo(haptic, DRV2605.REG_GO, 1);
      console.log(result[0]);//for debugging
      return result;
    const hapticTripple = () => {
      let index = 0;
      setInterval(() => {
        if (index > 3) clearInterval();
      }, 250);

    In the code above I use hardware I2C, but it also works with software I2C. I'm testing if it works with hapticTripple function which produces three short vibrations and prints the status read from the status register of the DRV2605 (it returns 0 if successful).

    Now, here's the problem. In the case where I setup software I2C for DRV2605 and I call my test function it works, but if after that I call the require("neopixel") , which works properly, after that call I can't communicate with DRV2605 anymore (I'm getting 255 values from the status register in the test function console logs). This persists even after a soft reset (test function returns 255). Only after hardware reset the initial state is restored.

    In the case where I set up the hardware I2C for the DRV2605 the behavior is sort of flipped. The DRV2605 functions well, but once I call the require("neopixel") function the device freezes - the console does not respond, when I reconnect the IDE there is no prompt detected, so I basically need to hard reset the board.

    I've tried communicating with the Neopixels directly via SPI. Using software SPI I could make some pixels light up, but it wasn't working well (later I've read a post by Gordon saying that software SPI is not suitable for Neopixels). But with software SPI for neopixels and I2C for DRV2605 (both software or hardware I2C), I can successfully use DRV2605 and make neopixels "do something".

    When I switch the I2C into software and the SPI to hardware and run the code, I'm getting I2C timeout errors like below when calling my DRV2605 test function:

    in function called from system
    Uncaught Error: I2C Error: Timeout (start)
     at line 1 col 37
    i2c.writeTo(haptic, DRV2605.REG_MODE);
    in function "hapticPush" called from line 2 col 25
    in function called from system

    After I clear the intervals to stop the I2C timeout errors, I can use the hardware SPI to communicate with neopixels. It doesn't work well but at least it's not freezing. Still, since the I2C is not working, spending more time on trying to use hardware SPI to bypass the require("neopixel") makes no sense in this scenario.

    When I set both SPI and I2C as hardware, first the board disconnects right after flashing and it takes two to three attempts to reconnect with the IDE. Then, when it is connected and I try to run the DRV2605 test function it freezes, and to recover a hard reset is required. When I try to use SPI to talk to neopixels it works ("does something").

    I don't understand why after calling the require("neopixel") I'm unable to use the software I2C or even configure the hardware I2C. I couldn't understand what changes after the require("neopixel") is called that "blocks" the software I2C.

    Any Ideas? Please help :)


Avatar for Kacper @Kacper started