接口 Arduino/RedBoard 振动器到 Python

Interface Arduino/RedBoard vibrator to Python

我正在尝试将我的 SparkFun Qwiic Haptic Driver - DA7280 与 Python3 连接起来。我目前的设置如下:

PC -USB 到微型 USB-> SparkFun RedBoard Qwiic -Qwiic 电缆-> 触觉驱动器

我已经试用了随附的 Arduino sketch 并设法启动了 C++ 代码并且 运行 没问题;调制振动器的强度和频率就好了。

那么,我想做的就是用一些Python代码及时触发振动脉冲。例如,当 python 打印出一个单词时,会触发振动脉冲。

我试过使用 pySerial 与微控制器接口,触发控制器 运行 预加载脚本。使用简单的 C++ 脚本可以很好地重复上传到微控制器的 LED 闪烁:

/*
  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');
  }
}

结合 Python 脚本来触发和关闭控制器:

# 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()

但是,当我尝试用启动和停止振动的命令替换特定于 LED 的行时(如下),存在一些问题:

  1. 虽然控制器按预期等待来自 Python 的开始信号,但 Python 会立即通过脚本,而不是等待来自控制器的停止。
  2. 控制器开始振动,但在振动脉冲之间没有预期的延迟,并且振动器永远不会停止,即使在 python 发送停止触发器之后也是如此。
/*
  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();
  }
}

我是微控制器和 C++ 的新手,所以请原谅我任何专业 misunderstandings/errors。另外,如果以上描述中有任何不清楚的地方,请告诉我。

非常感谢,
利亚姆

我怀疑至少部分问题是您没有清除读取缓冲区的内容,只是检查是否有内容。 Serial.flush() 我认为从 Arduino 1.00 开始(不要引用我的话)串行刷新对传入缓冲区没有任何作用。

尝试在 hapDrive.setVibrate(25); 之前添加一个 var = Serial.read(),看看是否会改变功能。

我也强烈推荐串行中断。有一个非常全面的串行事件示例(虽然我似乎记得它实际上并不是经典微控制器意义上的中断驱动,但它已经足够接近了!)