DA7280 Driver I2C problem

Hi,

I am trying to control multiple DA7280 Sparkfun boards from a Teensy 4.0 using the driver developed by Elias Santistevan. I know I can daisy chain the boards and use one set of I2C pins, but I don’t want to do that. I have multiple I2C channels available as in the Teensy: Wire(), Wire1(), etc, so I want to configure each board differently (e.g. frequency). However, only Wire() is working, and Wire1() etc does not work. I don’t think it is the DA7280, since the datasheet says that any I2C line that transmits the right device ID can access the chip. That leaves the driver itself. Does the driver specify which I2C line the uController will use? This doesn’t seem to be the case, since Sparkfun’s example code below shows Wire.begin() being called . Would this even be necessary if the I2C configuration was set up by the driver?

By the way, I confirmed that Wire.h is supposed to support multiple I2C lines.

#include <Wire.h>

#include “Haptic_Driver.h”

Haptic_Driver hapDrive;

//int pwmPin = 5; // Teensy

int pwmPin = 2; // Artemis

int power = 20;

int event = 0;

void setup(){

pinMode(pwmPin, OUTPUT);

//When using Teensy***************************************

//analogWriteFrequency(pwmPin, 10000); // Set to 10kHz

//When using Artemis***************************************

//analogWriteResolution(8); //This example assumes that analogWriteResolution() is set to 8-bits on the Artemis, uncomment this line if needed

analogWriteFrameWidth(1100); //Set to 10kHz (e.g. 10909Hz = 12000000/1100); too close to the boundary and the DA7280 will fault

Wire.begin();

Serial.begin(115200);

Comment-out the Artemis lines and un-comment the Teensy lines (remove and add “//” to the lines of code) - does this alter the behavior?

Sorry, I used the example code as it was provided to illustrate that the sparkfun driver was using Wire() in the example.

My actual code, which does not generate a connection with DA7280, is as follows

#include <Wire.h>

#include “Haptic_Driver.h”

// #define Wire Wire1

Haptic_Driver hapDrive;

int pwmPin32 = 6; // Teensy

int pwmPin33 = 5;

int event1 = 0;

void setup(){

pinMode(pwmPin32, OUTPUT);

pinMode(pwmPin33, OUTPUT);

//When using Teensy***************************************

analogWriteFrequency(pwmPin32, 10000); // Set to 10kHz

analogWriteFrequency(pwmPin33, 10000); // Set to 10kHz

// Wire.begin();

Wire1.begin();

Wire1.setSDA(17);

Wire1.setSCL(16);

Serial.begin(115200);

if( !hapDrive.begin())

Serial.println(“Could not communicate with Haptic Driver.”);

else

Serial.println(“Qwiic Haptic Driver DA7280 found!”);

if( !hapDrive.defaultMotor() )

Serial.println(“Could not set default settings Haptic Driver.”);

else

Serial.println(“Haptic Driver Ready.”);

// Frequency tracking is done by the IC to ensure that the motor is hitting

// its resonant frequency. I found that restricting the PCB (squeezing)

// raises an error which stops operation because it can not reach resonance.

// I disable here to avoid this error.

// hapDrive.enableFreqTrack(false);

analogWrite(pwmPin32, 120); // Apply the signal before entering PWM mode.

analogWrite(pwmPin33, 120); // Apply the signal before entering PWM mode.

delay(10); // An abundance of caution here =P

hapDrive.setOperationMode(PWM_MODE);

randomSeed(analogRead(0));

hapDrive.setActuatorABSVolt(2.75);

hapDrive.setActuatorLRAfreq(150);

}

void loop(){

int Trigger32;

int Trigger33;

int Buzzer32 = 0;

int Buzzer33 = 0;

Trigger32 = random(100);

Trigger33 = random(100);

// If uploading often the Haptic Driver IC will throw a fault when the PWM

// signal is cut off suddenly without being set into inactive mode. Let’s

// clear that error (0x10), just in case.

event1 = hapDrive.getIrqEvent();

hapDrive.clearIrq(event1);

if (Trigger32 > 50) {

analogWrite(pwmPin32, 125);

Buzzer32 = 1;

}

if (Trigger33 > 50) {

analogWrite(pwmPin33, 125);

Buzzer33 = 1;

}

delay(50);

analogWrite(pwmPin32, 0);

analogWrite(pwmPin33, 0);

delay(1000);

Serial.println(“Buzzer32”);

Serial.println(Buzzer32);

Serial.println(“Buzzer33”);

Serial.println(Buzzer33);

delay(1000);

Serial.println(“New Trial”);

Note that this code works perfectly when I replace Wire1() with Wire(). I am trying to figure out if the sparkfun driver is forcing the use of Wire() instead of Wire1()?

By default Wire is used, try changing

if( !hapDrive.begin())

to

if( !hapDrive.begin(Wire1))

Hi again,

So I am using hapDrive with both Wire() and Wire1(). When I use wire1(), I make sure to pass that to hapDrive with if( !hapDrive.begin(Wire1)), as suggested. The result is that ONLY the buzzer with Wire1() works. However, I am getting a WHOAMI from the chip using the Wire() I2C, but nothing beyond that (no buzzing). So I conclude that wire() is working even if nothing happens.

Also, please note that I tried using !hapDrive.begin(Wire)) instead of !hapDrive.begin()) and it didn’t make a difference. Also note that I cross switched the PWM pins to make sure that there wasn’t an issue with one of them, but I still got the same result.

Here is the code:

#include <Wire.h>

#include “Haptic_Driver.h”

Haptic_Driver hapDrive;

int pwmPin21 = 5; // Teensy

int pwmPin32 = 6;

int event1 = 0;

void setup(){

pinMode(pwmPin32, OUTPUT);

pinMode(pwmPin21, OUTPUT);

// Apply the signal before entering PWM mode.

analogWrite(pwmPin32, 120); // This is for buzzer 32, Wire1() I2C and 150 hz chip

analogWrite(pwmPin21, 120); // This is for buzzer 21, Wire() I2C and 300 hz chip

//When using Teensy***************************************

analogWriteFrequency(pwmPin32, 10000); // Set to 10kHz

analogWriteFrequency(pwmPin21, 10000); // Set to 10kHz

Serial.begin(115200);

randomSeed(analogRead(0));

//Set up 150 hz for buzzer 21 with Wire() I2C

Wire.begin();

if( !hapDrive.begin())

Serial.println(“Could not communicate with 150 hz Haptic Driver.”);

else

Serial.println(“Qwiic 150 Haptic Driver DA7280 found!”);

if( !hapDrive.defaultMotor() )

Serial.println(“Could not set default settings for 150 hz Haptic Driver.”);

else

Serial.println(“150 hz Haptic Driver Ready.”);

delay(10); // An abundance of caution here =P

hapDrive.setOperationMode(PWM_MODE);

hapDrive.setActuatorABSVolt(2.75);

hapDrive.setActuatorLRAfreq(150);

// Wire.end();

//Set up 300 hz for buzzer 32 with Wire1() I2C

Wire1.begin();

if( !hapDrive.begin(Wire1))

Serial.println(“Could not communicate with 300 hz Haptic Driver.”);

else

Serial.println(“Qwiic 300 hz Haptic Driver DA7280 found!”);

if( !hapDrive.defaultMotor() )

Serial.println(“Could not set default settings for 300 hz Haptic Driver.”);

else

Serial.println(“300 hz Haptic Driver Ready.”);

delay(10); // An abundance of caution here =P

hapDrive.setOperationMode(PWM_MODE);

hapDrive.setActuatorABSVolt(2.75);

hapDrive.setActuatorLRAfreq(300);

// Wire1.end();

}

void loop(){

int Trigger32;

int Trigger21;

int Buzzer32 = 0;

int Buzzer21 = 0;

Trigger32 = 51;

Trigger21 = 51;

// If uploading often the Haptic Driver IC will throw a fault when the PWM

// signal is cut off suddenly without being set into inactive mode. Let’s

// clear that error (0x10), just in case.

event1 = hapDrive.getIrqEvent();

hapDrive.clearIrq(event1);

if (Trigger32 > 50) {

analogWrite(pwmPin32, 125);

Buzzer32 = 1;

}

if (Trigger21 > 50) {

analogWrite(pwmPin21, 125);

Buzzer21 = 1;

}

delay(50);

analogWrite(pwmPin32, 0);

analogWrite(pwmPin21, 0);

delay(1000);

Serial.println(“Buzzer32”);

Serial.println(Buzzer32);

Serial.println(“Buzzer21”);

Serial.println(Buzzer21);

delay(1000);

Serial.println(“New Trial”);

}

Try creating two instances of Haptic_Driver, one for each device, and keep them separated in the code.

/mike

Haptic_Driver hapDrive1,  hapDrive2;

The second instance of the haptic driver did the trick!

Thanks everybody for all your help :slight_smile: