Hello, I'm currently still making my first coding project. It is hopefully going to be an Iron man helmet that uses my arduino nano rp2040 connect with the arduino voice recognition engine to open and close the helmet. The problem that I am having is that whenever I use the code with the voice recognition engine, my servos start jittering a lot when they're extended. I have no problems with servo jitter when running a basic move, delay, function without the voice recognition engine. Here is my code if anyone can give me some insight or feedback. I currently have an unimplemented doubletap feature just so I can debug the voice recognition section. Thank you!
#include <Arduino_LSM6DSOX.h>
#include <Arduino.h>
#include <DSpotterSDK_MakerHL.h>
#include <LED_Control.h>
#include <Servo.h>
#include "CybLicense_1729631303.h"
const unsigned long doubleTapTime = 300; // Time in milliseconds for double-tap detection
const unsigned long cooldownTime = 3000; // Cooldown time in milliseconds after a successful double tap
unsigned long lastTapTime = 0; // To track the last tap time
unsigned long lastActionTime = 0; // To track the last action time
int tapCount = 0; // Count the number of taps
#define DSPOTTER_LICENSE g_lpdwLicense
// The DSpotter Keyword Model Data.
#if defined(TARGET_ARDUINO_NANO33BLE) || defined(TARGET_PORTENTA_H7) || defined(TARGET_NICLA_VISION)
#include "Model_1729631303.h" // The packed level one model file.
#elif defined(TARGET_NANO_RP2040_CONNECT)
#include "Model_1729631303.h" // The packed level zero model file.
#endif
#define DSPOTTER_MODEL g_lpdwModel
// The VR engine object. Only one instance can exist.
static DSpotterSDKHL g_oDSpotterSDKHL;
Servo myservo1; // Declare servo objects
Servo myservo2;
bool servoposition() {
return myservo1.read() >= 90;
}
// Callback function for VR engine
void VRCallback(int nFlag, int nID, int nScore, int nSG, int nEnergy) {
// Existing callback implementation
if (nFlag == DSpotterSDKHL::InitSuccess) {
// Initialization successful
} else if (nFlag == DSpotterSDKHL::GetResult) {
switch(nID) {
case 100:
Serial.println("The Trigger was heard");
break;
case 10000:
Serial.println("The Command -open- was heard");
myservo1.write(15);
myservo2.write(165);
break;
case 10001:
Serial.println("The Command -close- was heard");
myservo1.write(150);
myservo2.write(30);
break;
case 10002:
Serial.println("The Command -share- was heard");
break;
default:
break;
}
} else if (nFlag == DSpotterSDKHL::ChangeStage) {
switch(nID) {
case DSpotterSDKHL::TriggerStage:
LED_RGB_Off();
LED_BUILTIN_Off();
break;
case DSpotterSDKHL::CommandStage:
LED_BUILTIN_On();
break;
default:
break;
}
} else if (nFlag == DSpotterSDKHL::GetError) {
if (nID == DSpotterSDKHL::LicenseFailed) {
// Handle license failure
}
g_oDSpotterSDKHL.Release();
}
}
void setup() {
// Init LED control
LED_Init_All();
// Init Serial output for debug info
Serial.begin(9600);
DSpotterSDKHL::ShowDebugInfo(true);
// Init VR engine & Audio
if (g_oDSpotterSDKHL.Init(DSPOTTER_LICENSE, sizeof(DSPOTTER_LICENSE), DSPOTTER_MODEL, VRCallback) != DSpotterSDKHL::Success)
return;
if (!IMU.begin()) {
Serial.println("Failed to initialize the IMU!");
while (1);
}
// Attach servos here
myservo1.attach(10);
myservo2.attach(9);
}
// Function to perform on double-tap
void performAction() {
Serial.println("Double tap detected! Performing action...");
if (servoposition()) {
myservo1.write(15);
myservo2.write(165);
} else {
myservo1.write(150);
myservo2.write(30);
}
delay(1000); // Allow time for servos to move
}
bool detectTap() {
float x, y, z; // Declare variables to hold acceleration data
if (IMU.gyroscopeAvailable()) {
IMU.readGyroscope(x, y, z);
// Check for a significant change in Y-axis acceleration
if (abs(y) < 40 && abs(y) > 20) { // Corrected logic
delay(100); // Simple debounce delay
IMU.readGyroscope(x, y, z); // Read again for confirmation
if (abs(y) < 40 && abs(y) > 20) {
return true; // Tap detected
}
}
}
return false; // No tap detected
}
void Doubletap() {
// Check if cooldown is active
if (millis() - lastActionTime < cooldownTime) {
return; // Ignore new input during cooldown
}
// Check if a tap is detected
if (detectTap()) {
unsigned long currentTime = millis();
// Check if enough time has passed since the last tap
if (currentTime - lastTapTime < doubleTapTime) {
tapCount++;
} else {
tapCount = 1; // Reset count for a new tap sequence
}
lastTapTime = currentTime;
// Check for double-tap
if (tapCount == 2) {
performAction(); // Call the function on double tap
lastActionTime = millis(); // Set the last action time
tapCount = 0; // Reset the count after the action
}
}
}
void loop() {
// Do VR
g_oDSpotterSDKHL.DoVR();
// Call Doubletap function in loop
}