This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

DRV2667: How can we vibrate the piezo haptic actuator with DRV2667

Part Number: DRV2667
Other Parts Discussed in Thread: USB2ANY

Hi, I am trying to drive the piezo actuator (z6300z2910z1z39) with the help of drv2667 driver only sensing part is done but no vibration is coming when I press the piezo actuator. Can you please guide me what can I do now? please see the attached code and schematic. I am unable to find that which register I will use for vibration and can not understand the data sheet. Below is python code 

code is

import board

import busio

from micropython import const
import adafruit_bus_device.i2c_device as i2c_device
_DRV2667_ADDRESS = const(0x59)
i2cbus = busio.I2C(board.SCL, board.SDA)
i2c = i2c_device.I2CDevice(i2cbus, _DRV2667_ADDRESS)
def read_register(register, length):
i2c.write(bytes([register & 0xFF]))
result = bytearray(length)
i2c.readinto(result)
#print("$%02X => %s" % (register, [hex(i) for i in result]))
return result
def write_register_byte(register, value):
i2c.write(bytes([register & 0xFF, value & 0xFF]))
print("$%02X <= 0x%02X" % (register, value))
#Set to analog input mode
write_register_byte(0x02, 0x00) #Take device out of standby mode
write_register_byte(0x02, 0x02) #Set EN_OVERRIDE bit = boost and amplifier active
write_register_byte(0x01, 0x07) #Set to analog input + Gain 0-3 (0x04-0x07 25v-100v)

SCHEMATIC:

  • Hi,

    I general your schematic needs some work.

    You should tie both SW1 and 2 together as this is a high current node. 

    You need to connect BST pin with the PVDD pin. PVDD is the high voltage supply that power the Piezo driver 

    I recommend that you review the datasheet for schematic guidelines,

    Also in the DRV2667EVM users guide there is a schematic included that is known good, and you can copy.

    Regards,

    Arthur

  • Thanks for reply. did you check the code as well? Moreover I have used only drv2667 with some circuit as shown in schematic. I am not using drv2667eVm 

  • Hi,

    The I2C writes that you are using look OK.

    My main concern is that PVDD is not connected. there is no supply for the amplifier in this case.

    Regards,
    Arthur

  • I will connect this and tell you soon Thanks Arthur Brown

  • Please let me know your results

    Regards,

    Arthur

  • Hi Arthur, I have connected the Bst_1 and Bst_2 together and then BST to PVDD. I have also connected the SW1 and SW2 together but Unfortunately, When I press the Piezo actuator then Sensing part is done (Some Waveform is coming on Oscilloscope) and in return no vibration is coming.

    Regards,

    Faqeeha Khan

  • Hi Arthur, See the updated code below . We have code of our driver (DRV2667) for 50 Vpp and 200Hz. We only got  force feedback but no vibration at actuator. Can you please check and edit the code?

    import board
    import busio
    import time
    from micropython import const
    import adafruit_bus_device.i2c_device as i2c_device

    _DRV2667_ADDRESS = const(0x59)

    i2cbus = busio.I2C(board.SCL, board.SDA)
    i2c = i2c_device.I2CDevice(i2cbus, _DRV2667_ADDRESS)

    def read_register(register, length):
    i2c.write(bytes([register & 0xFF]))
    result = bytearray(length)
    i2c.readinto(result)
    print("$%02X => %s" % (register, [hex(i) for i in result]))
    return result

    def write_register_byte(register, value):
    i2c.write(bytes([register & 0xFF, value & 0xFF]))
    print("$%02X <= 0x%02X" % (register, value))

    while(1):
    #Set to analog input mode
    a=write_register_byte(0x02, 0x00) #Take device out of standby mode
    b=write_register_byte(0x02, 0x02) #Set EN_OVERRIDE bit = boost and amplifier active

    ##setting up driver for 50 Vpp at 200HZ
    c=write_register_byte(0x18, 0x40) #Amplitude for waveform ID #4, full-scale,50 Vpp at gain 3
    d=write_register_byte(0x19, 0x1A) #Frequency for waveform ID #4, 203 HZ
    e=write_register_byte(0x1A, 0x04) #Duration of waveform ID #4, play4 cycles
    f=write_register_byte(0x1B, 0x00) #Envelope for waveform ID #4, ramp up= no evelope, ramp down= no envelope
    time.sleep(0.5)

  • Hi Faqeeha,

    are you switching register pages before writing to waveform memory?

    From datasheet page 34. you should switch to page 2 (register 0xff data 0x02) before writting to 0x18-0x1b)

    then you should go back to the control space page (register 0xff data 0x00) and then write to the GO bit register 0x02 bit 0

    Regards,

    Arthur

  • Hi,

    sorry Arthur I am not getting your point. Can you please elaborate me in my code what I will write

  • there are multiple "pages" of registers in the device. you can select which page of registers you are reading or writing too using the register 0xff

    example: write 0x01 to register 0xff -> all subsequent reads/writes are done to page 1

    example: write 0x02 to register 0xff -> all subsequent reads/writes are done to page 2

    When programming this device you will need to program your header information into page 1 and the waveform information into page 2, and then you can control the waveform playback in page 0.

     You should refer to the datasheet section 8.3 and copy one of the examples exactly, and then once you understand the function you can modify it as you need 

    Regards,
    Arthur

  • hi,

    see the updated code

    import board
    import busio
    import time
    from micropython import const
    import adafruit_bus_device.i2c_device as i2c_device

    _DRV2667_ADDRESS = const(0x59)

    i2cbus = busio.I2C(board.SCL, board.SDA)
    i2c = i2c_device.I2CDevice(i2cbus, _DRV2667_ADDRESS)

    def read_register(register, length):
    i2c.write(bytes([register & 0xFF]))
    result = bytearray(length)
    i2c.readinto(result)
    print("$%02X => %s" % (register, [hex(i) for i in result]))
    return result

    def write_register_byte(register, value):
    i2c.write(bytes([register & 0xFF, value & 0xFF]))
    print("$%02X <= 0x%02X" % (register, value))

    while(1):
    #Set to analog input mode
    a=write_register_byte(0xFF, 0x02)


    ##setting up driver for 50 Vpp at 200HZ
    c=write_register_byte(0x18, 0x40) #Amplitude for waveform ID #4, full-scale,50 Vpp at gain 3
    d=write_register_byte(0x19, 0x1A) #Frequency for waveform ID #4, 203 HZ
    e=write_register_byte(0x1A, 0x04) #Duration of waveform ID #4, play4 cycles
    f=write_register_byte(0x1B, 0x00) #Envelope for waveform ID #4, ramp up= no evelope, ramp down= no envelope
    b=write_register_byte(0xFF, 0x00)
    l=write_register_byte(0x02, 0x00)
    time.sleep(0.5)

  • Your code is incomplete. Please refer to the code example in section 8.3.2.1 of the datasheet. copy those I2C write in the shown order. and see if you are able to playback a waveform https://www.ti.com/lit/ds/symlink/drv2667.pdf 

    After that you can read section 7.5.3 of the datasheet to under stand how to program the RAM with any waveform you desire.

    You schematic should be OK. you just need to program correctly,

    Regards,
    Arthur

  • i will do it and update you soon about the progress

  • Hi Arthur,

    Before starting the further coding I want little bit information, below you can see a table in which four different parts are present (Control, Header, Data, Control). Can you please just tell me which part I will used for write and read,

    For example write_register_byte()

    read_register()

     now please just elaborate /mention the part  as like this     write_regiter() for control  , read_register () for header 

    Regards,

    Faqeeha Khan

  • Hi Arthur,

    If I only use write_byte() then still no vibration is coming you can see the code below:

    This code is for 8.3.2.1 section in datasheet.

    Code:

    import board
    import busio
    import time
    from micropython import const
    import adafruit_bus_device.i2c_device as i2c_device

    _DRV2667_ADDRESS = const(0x59)

    i2cbus = busio.I2C(board.SCL, board.SDA)
    i2c = i2c_device.I2CDevice(i2cbus, _DRV2667_ADDRESS)

    def read_register(register, length):
    i2c.write(bytes([register & 0xFF]))
    result = bytearray(length)
    i2c.readinto(result)
    print("$%02X => %s" % (register, [hex(i) for i in result]))
    return result

    def write_register_byte(register, value):
    i2c.write(bytes([register & 0xFF, value & 0xFF]))
    print("$%02X <= 0x%02X" % (register, value))

    while(1):

    time.sleep(1)

    #Set to analog input mode

    #For control
    write_register_byte(0x02,0X00)
    write_register_byte(0x01,0x00)
    write_register_byte(0x03,0x01)
    write_register_byte(0x04,0x00)

    #For Header
    write_register_byte(0xFF,0x01)
    write_register_byte(0x00,0x05)
    write_register_byte(0x01,0x80)
    write_register_byte(0x02,0x06)
    write_register_byte(0x03,0x00)
    write_register_byte(0x04,0x09)
    write_register_byte(0x05,0x01)

    #For Data
    write_register_byte(0x06,0xFF)
    write_register_byte(0x07,0x19)
    write_register_byte(0x08,0x05)
    write_register_byte(0x09,0x00)

    #For Control  (Control space & Control bit)
    write_register_byte(0xFF,0x00)
    write_register_byte(0x02,0x01)
    #time.sleep(0.5)

    If I used both read_byte() and write byte for all (control,header,data,control) then error is coming code and error are below:

    Code:

    import board
    import busio
    import time
    from micropython import const
    import adafruit_bus_device.i2c_device as i2c_device

    _DRV2667_ADDRESS = const(0x59)

    i2cbus = busio.I2C(board.SCL, board.SDA)
    i2c = i2c_device.I2CDevice(i2cbus, _DRV2667_ADDRESS)

    def read_register(register, length):
    i2c.write(bytes([register & 0xFF]))
    result = bytearray(length)
    i2c.readinto(result)
    print("$%02X => %s" % (register, [hex(i) for i in result]))
    return result

    def write_register_byte(register, value):
    i2c.write(bytes([register & 0xFF, value & 0xFF]))
    print("$%02X <= 0x%02X" % (register, value))

    while(1):

    time.sleep(1)

    #Set to analog input mode
    write_register_byte(0x02,0X00)
    write_register_byte(0x01,0x00)
    write_register_byte(0x03,0x01)
    write_register_byte(0x04,0x00)
    write_register_byte(0xFF,0x01)
    write_register_byte(0x00,0x05)
    write_register_byte(0x01,0x80)
    write_register_byte(0x02,0x06)
    write_register_byte(0x03,0x00)
    write_register_byte(0x04,0x09)
    write_register_byte(0x05,0x01)
    write_register_byte(0x06,0xFF)
    write_register_byte(0x07,0x19)
    write_register_byte(0x08,0x05)
    write_register_byte(0x09,0x00)
    write_register_byte(0xFF,0x00)
    write_register_byte(0x02,0x01)

    read_register(0x02,0X00)
    read_register(0x01,0x00)
    read_register(0x01,0x00)
    read_register(0x03,0x01)
    read_register(0x04,0x00)
    read_register(0xFF,0x01)
    read_register(0x00,0x05)
    read_register(0x01,0x80)
    read_register(0x02,0x06)
    read_register(0x03,0x00)
    read_register(0x04,0x09)
    read_register(0x05,0x01)
    read_register(0x06,0xFF)
    read_register(0x07,0x19)
    read_register(0x08,0x05)
    read_register(0x09,0x00)
    read_register(0xFF,0x00)
    read_register(0x02,0x01)
    #time.sleep(0.5)

    ERROR after running the code:

    02 <= 0x00
    $01 <= 0x00
    $03 <= 0x01
    $04 <= 0x00
    $FF <= 0x01
    $00 <= 0x05
    $01 <= 0x80
    $02 <= 0x06
    $03 <= 0x00
    $04 <= 0x09
    $05 <= 0x01
    $06 <= 0xFF
    $07 <= 0x19
    $08 <= 0x05
    $09 <= 0x00
    $FF <= 0x00
    $02 <= 0x01
    $02 => []
    Traceback (most recent call last):
    File "/home/pi/Desktop/code2_driver.py", line 47, in <module>
    read_register(0x01,0x00)
    File "/home/pi/Desktop/code2_driver.py", line 13, in read_register
    i2c.write(bytes([register & 0xFF]))
    File "/usr/local/lib/python3.7/dist-packages/adafruit_bus_device/i2c_device.py", line 84, in write
    self.i2c.writeto(self.device_address, buf, start=start, end=end)
    File "/usr/local/lib/python3.7/dist-packages/busio.py", line 158, in writeto
    return self._i2c.writeto(address, memoryview(buffer)[start:end], stop=stop)
    File "/usr/local/lib/python3.7/dist-packages/adafruit_blinka/microcontroller/generic_linux/i2c.py", line 49, in writeto
    self._i2c_bus.write_bytes(address, buffer[start:end])
    File "/usr/local/lib/python3.7/dist-packages/Adafruit_PureIO/smbus.py", line 314, in write_bytes
    self._device.write(buf)
    OSError: [Errno 121] Remote I/O error

    Regards,

    Faqeeha Khan

  • Hi Faqeeha,

    I am not going to be able to debug your code for you because I do not know how it is supposed to work

    I can however provide example I2C writes/reads and you can look at your own I2C signals and see if there is anything wrong.

    Slide 1 is a write of value 0x17 to register 0x03

    Slide 2 is a read of value 0x17 from register 0x03

    DRV2667_I2C_example.pptx

    Regards,
    Arthur

  • Thanks for your help. Actually I can do code myself even I will remove this error too but my main concern is this which part (Control, Header, Data, Control) I will used for read or write commands. Or We need to use both read and write commands for this 8.3.2.1 example for each part

  • the example in 8.3.2.1 should be all read commands. you should never need to read the I2C to get the piezo to accuate

  • I am using i2c So it's mean I will only write the address ? (there is no need to read the address)

  • Hi Faqeeha.

    I apologize. I made a typo in my previous reply.

    all of those are write commands. you do not NEED to read the data. You can read it back after programming to make sure the correct values are getting programmed.

    However be aware that the GO bit will self clear after writing to it

    Each I2C command write will include the device address, then the register address, and then the data. as can be seen in the example below.

    where the device address is 0xb2, the register address is 0x03 and the data (in this case) is 0x17

    Regards,
    Arthur

  • Thanks for reply I will do this. Moreover I want to know , can we use haptic console software with our drv2667  circuit?

  • Unfortunately haptic control console needs to establish a USB connection in order to communicate. If you had a USB2ANY you may be able to use the register map portion of HCC

    Regards,

    Arthur