The project uses an SparkFun APDS9660 gesture sensor wired through a SparkFun BOB-12009 logic level converter to a SparkFun Redboard coupled to a SparkFun Ardumoto Shield for DC motor output. I added a potentiometer(voltage divider) to limit top speed output. It varies DC motor top speed as intended, but for some reason far gesture(stop) input is compromised. Swipe left(reverse) and swipe right(forward) gestures work. Far gesture(stop) reverses polarity only if DC motor is running after a swipe left(reverse) command. There is no stop function which is plugging the DC motor between forward and reverse. All gestures worked fine before adding code for the potentiometer. So I think it’s a code issue, but maybe it’s a wrong hardware setup for the potentiometer(voltage divider) currently using A0 as signal input, messing with I2C input.
I would also like to place a mandatory stop command between forward and reverse because of accidently plugging the DC motor while leaning over the controller. What I mean is that the motor must be stopped before receiving a forward or reverse gesture. Once moving forward or reverse, only a stop command gesture can be issued. Not sure how to do this.
I’ve been messing around with Arduino on and off for about five years and what I understand about code is that i don’t understand code! The more I read the more confused I get. Any help, suggestions or code will be appreciated. I tried to upload the code as an attachment but couldn’t get it to work so I included it here. This is my first time posting on a forum, still figuring it out.
/****************************************************************
*
* Variable Gesture Throttle
* July 2021
*
* SparkFun APDS-9960 sensor provides gesture input
* SparkFun Ardumoto board (L298 H-Bridge) provides power
* Potentiometer adjusts motor top speed
*
* Some code has been shamelessly cribbed from
* Jeff Faust, Dec. 2014
* furniturerailroads.com
* SparkFun's "GestureTest.ino" example sketch
* (Shawn Hymel, I owe you a beer.)
*
* To perform a NEAR gesture, hold your hand
* far above the sensor and move it close to the sensor (within 2
* inches). Hold your hand there for at least 1 second and move it
* away.
*
* To perform a FAR gesture, hold your hand within 2 inches of the
* sensor for at least 1 second and then move it above (out of
* range) of the sensor.
*
* To limit top speed of DC motor adjust potentiometer to desired level.
*
****************************************************************/
#include <Wire.h>
#include <SparkFun_APDS9960.h>
enum directions {
STOPPED, EASTBOUND, WESTBOUND
};
// Pins
#define APDS9960_INT 2 // Needs to be an interrupt pin
const int motorSpeed = 3;
const int motorDirection = 12;
const int pot = A0; //Assigns analog input A0 to variable pot
// Constants
const int accelerate = 15; //increment throttle value per loop
const int decelerate = 30; //decrement throttle value per loop
// Global Variables
SparkFun_APDS9960 apds = SparkFun_APDS9960();
int isr_flag = 0;
int throttle = 0;
int directionOfTravel = STOPPED;
int maxSpeed = 255;
int value; //save analog value
void setup() {
// Set interrupt pin as input
pinMode(APDS9960_INT, INPUT);
pinMode(pot, INPUT); //Declares pin A0 as input
pinMode(motorSpeed, throttle);//(output, OUTPUT);//(motorSpeed, OUTPUT);
// initialize digital pin 6 as power LED output
pinMode(6, OUTPUT);
// Initialize Serial port
Serial.begin(9600);
Serial.println();
Serial.println(F("--------------------------------"));
Serial.println(F("SparkFun APDS-9960 - GestureTest"));
Serial.println(F("--------------------------------"));
// Initialize interrupt service routine
attachInterrupt(0, interruptRoutine, FALLING);
// Initialize APDS-9960 (configure I2C and initial values)
if ( apds.init() ) {
Serial.println(F("APDS-9960 initialization complete"));
}
else {
Serial.println(F("Something went wrong during APDS-9960 init!"));
}
// Adjust the Gesture sensor gain ***4X default does not work
if ( !apds.setGestureGain(GGAIN_1X) ) {
Serial.println(F("Something went wrong trying to set GGAIN"));
}
// Start running the APDS-9960 gesture sensor engine
if ( apds.enableGestureSensor(true) ) {
Serial.println(F("Gesture sensor is now running"));
}
else {
Serial.println(F("Something went wrong during gesture sensor init!"));
}
}
void loop() {
value = analogRead(pot); //Reading the voltage from the potentiometer
value = map(value, 0, 1023, 0, 255);//reading/4; //Dividing reading by 4 to bring in range of 0-255
analogWrite(motorSpeed, value); //Send PWM value
analogWrite(6, 10); //(Power LED pin 6, brightness level 0-255)
if ( isr_flag == 1 ) {
detachInterrupt(0);
handleGesture();
setThrottle();
isr_flag = 0;
attachInterrupt(0, interruptRoutine, FALLING);
}
}
void interruptRoutine() {
isr_flag = 1;
}
void handleGesture() {
if ( apds.isGestureAvailable() ) {
switch ( apds.readGesture() ) {
case DIR_UP:
Serial.println("UP");
directionOfTravel = STOPPED;
break;
case DIR_DOWN:
Serial.println("DOWN");
directionOfTravel = STOPPED;
break;
case DIR_LEFT:
Serial.println("LEFT");
directionOfTravel = WESTBOUND;
break;
case DIR_RIGHT:
Serial.println("RIGHT");
directionOfTravel = EASTBOUND;
break;
case DIR_NEAR:
Serial.println("NEAR");
directionOfTravel = STOPPED;
break;
case DIR_FAR:
Serial.println("FAR");
directionOfTravel = STOPPED;
break;
default:
Serial.println("NONE");
directionOfTravel = STOPPED;
}
}
}
void setThrottle() {
do
{
if (directionOfTravel != STOPPED) throttle = min(throttle + accelerate, maxSpeed);
else throttle = max(0, throttle - decelerate);
analogWrite(motorSpeed, throttle);
digitalWrite(motorDirection, directionOfTravel - 1);
if (directionOfTravel == WESTBOUND) Serial.print("<");
Serial.print(throttle);
if (directionOfTravel == EASTBOUND) Serial.print(">");
Serial.println();
}
while ((0 < throttle) && (throttle < maxSpeed));
}