I am trying to interface my SparkFun Qwiic Haptic Driver - DA7280 with Python3. My current set-up is as follows:
PC -USB to micro-USB-> SparkFun RedBoard Qwiic -Qwiic Cable-> Haptic Driver
I've trialed the accompanying Arduino sketch & managed to get the C++ code up and running fine; modulating the vibrator's intensity & frequency just fine.
Then, what I would like to do is to trigger a vibration pulse in time with some Python code. Such that, when python prints out a word, for example, a vibratory impulse would be triggered.
I have tried using pySerial to interface with the microcontroller, trigger the controller to run a pre-loaded script. This was worked fine with a simple C++ script to repeat an LED blink uploaded to the micro-controller:
/*
Blink
Turns an LED on for one second, then off for one second, repeatedly for 6 seconds
*/
void setup() {
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
// Open serial connection.
Serial.begin(9600);
Serial.write('1');
}
// the loop function waits until it receives an input from the serial port & will stop again when it receives a stop signal.
void loop() {
if(Serial.available() > 0){ // if data present, blink
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
Serial.write('0');
}
}
In conjunction with a Python script to trigger & close the controller:
# import necessary modules
import os
import serial
# connect to the arduino
## Boolean variable that will represent whether or not the arduino is connected
connected = False
## open the serial port that your ardiono is connected to.
ser = serial.Serial("COM8", 9600) # you may need to change this pending on how the board connects to the PC
## loop until the arduino tells us it is ready
while not connected:
serin = ser.read()
connected = True
## trigger the arduino to run the uploaded code
ser.write(1)
## Wait until the arduino tells us it is finished
while ser.read() == '1':
ser.read()
print(ser.read())
## trigger the arduino to run the uploaded code
ser.write(0)
## close the port and end the program
ser.close()
However, when I try replacing the LED-specific lines with commands to start and stop vibration (below) there are a few issues:
/*
Python triggered vibration.
Waits for Python to send a go signal at which point the vibration starts for a given duration of time.
*/
#include <Wire.h>
#include "Haptic_Driver.h" # this module is from the aforementioned Arduino sketch
Haptic_Driver hapDrive;
int event = 0;
void setup() {
// Open serial connection.
Wire.begin();
Serial.begin(9600);
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.");
// 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);
Serial.println("Setting I2C Operation.");
hapDrive.setOperationMode(DRO_MODE);
Serial.println("Ready.");
Serial.write('1');
}
void loop(){
if(Serial.available() > 0){
hapDrive.setVibrate(25);
delay(1500);
hapDrive.setVibrate(0);
delay(1500);
Serial.write(0);
Serial.flush();
}
}
I am a novice when it comes to both micro-controllers & C++ so, forgive me for any major misunderstandings/errors. Also if anything is unclear in the above description please let me know.
Many Thanks,
Liam
I suspect at least part of the problem is that you are not clearing the contents of the read buffer, only checking if something is there. Serial.flush()
i think that as of Arduino 1.00 (don't quote me on that) serial flush doesn't do anything to the incoming buffer.
try adding a var = Serial.read()
in before your hapDrive.setVibrate(25);
and see if that changes the functionality.
I also HEAVILY recommend interrupts for serial. There's a serial event example that's really comprehensive (although i seem to remember that's not actually interrupt driven in the classical microcontroller sense, but it's close enough!)