-
Hi Gordon!
Thank you for such a quick response! This is amazing ;)
I've just updated the firmware from 2v08 to 2v10, but the behavior persists.
I did try calling the I2C setup after neopixel write, but that didn't help. I also tried setting I2C to other pins to "shield" the DRV2605, but also no luck. For some reason, after neopixel write, something gets "stuck". Perhaps the signal received by the haptic driver from D31 crashes it, but I can't find a way to reset it, other than resetting the whole board.
I think that you're right that it is the neopixel write affecting the D31, because in the case when the I2C for DRV2605 is set up, the motor vibrates one last time when the neopixel write is called.
Changing pins is a bit problematic for me at this point. I need to redesign and fabricate my PCB... so it'll take me a while :P
Considering the change of LRCK pin to another in the new firmware - if it is difficult to guess which pin won't be used by the user, maybe it would be possible to make it exposed from espruino. Something like:
require("neopixel").write(neopixelDataPin, [100,0,0], D31); //where D31 would be the LRCK pin //OR require("neopixel").set({LRCK : D31}); //called once before calling the write method
I don't know if that'd be possible though.
-
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(neopixelDataPin, pixelBytes)
This works well.
I interface with the DRV2605 via I2C. Below you can see my test code:
//HAPTIC 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); }; prepareHaptic(); 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(() => { index++; hapticPush(i2cHaptic); 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 hapticPush(i2cHaptic); ^ 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 :)
Yes, of course! If LRCK pin would be made configurable it should be just an option.
I'm using the bare module, and I had D24 free. I've made the custom build with the modified line and IT WORKS - no more conflicts ;)
I attach the custom build with the LRCK set to pin D24 - in case anyone would need a quick fix.
Your support is incredible! Thank you so much for your help!