Hi there,
I built a syringe pump using a NEMA 17 stepper motor and DRV8825, to use in some neuroscience experiment as a reward pump. I'd like to deliver a certain amount of water in regular intervals, and whenever a pushbutton is pressed. For this I've already troubleshot and ditched a couple scripts, due to some fried devices. Now I'm trying to use the accelstepper library and bounce2 to make things right.
I pasted the whole -non working- code below, but basically what I'd like to have it do is:
- run ~10 steps (that's about what it takes to deliver a drop of water) as fast as possible so I can deliver the reward without much delay
- give these rewards every 20 seconds regularly
- also check for a pushbutton, and deliver a reward whenever it's pressed, without affecting the regular interval rewards above (so I can't use delay() )
- whenever a reward's delivered, output a square pulse to be sent to a DAQ as a reward timestamp
- ideally I'd also like to have the enable pin, as my circuit makes an audible noise (I know, it's probably not a good sign, but I don't have time to troubleshoot it right now) and I want to minimize that by cutting the power whenever the motor is not stepping
I'm a biologist who's self-taught in all these electrical stuff and arduino, and at this point I'm very much above my pay grade, so any help is highly appreciated. Thanks!
#include <AccelStepper.h>
#include <Bounce2.h>
// set the constants for experiment
int REWARDSIZE = 10; // in number of steps
int MAXSPEED = 1000; // in pins/sec
int ACCEL = 200;
int SPEED = 200;
int REWINTERVAL = 20000; // reward interval in ms
int buttonInterval = 500;
const int stepsPerRevolution = 200;
bool buttonState = false;
const int stepPin = 8; // low: no steps, high: steps
const int directionPin = 9; // low: cw, high: ccw
const int enablePin = 4; // low: no power to motor, high: motor on
const int ledPin = 2; // indicator light, turns ON in caseof reward
const int rewardTimeStamp = 3; // TTL to Intan
const byte buttonCWpin = 6; // triggers cw (reward)
const byte buttonCCWpin = 7; // triggers ccw (cleaning/adjusting pump)
// define variables
unsigned long curMillis;
unsigned long lastRewardMillis = 0;
unsigned long previousButtonMillis = 0;
// Define motor interface type as driver (used with step and dir pins)
#define motorInterfaceType 1
// Create a stepper object
AccelStepper rewardPump(motorInterfaceType, stepPin, directionPin);
// set enable pin to keep the motor from powering on unnecessarily
// setEnablePin(enablePin); // requires enable/disable outputs before/after using them
// initiate debouncing for buttons
Bounce fwdButton = Bounce();
Bounce revButton = Bounce();
//====================================================SETUP
void setup()
{
Serial.begin(115200);
Serial.println("Starting reward pump:");
Serial.println("Motor is at ");
Serial.println(rewardPump.currentPosition());
pinMode(ledPin, OUTPUT);
pinMode(rewardTimeStamp, OUTPUT);
fwdButton.attach(buttonCWpin, INPUT_PULLUP); fwdButton.interval(5);
revButton.attach(buttonCCWpin, INPUT_PULLUP); revButton.interval(5);
digitalWrite(rewardTimeStamp, LOW);
rewardPump.setMaxSpeed(MAXSPEED);
rewardPump.setAcceleration(ACCEL);
rewardPump.setSpeed(SPEED);
rewardPump.move(-REWARDSIZE);
}
//===================================================LOOP
void loop()
{
// revButton.update();
readButton();
curMillis = millis();
// enableOutputs();
if (rewardPump.distanceToGo() == 0)
{
// rewardPump.setAcceleration(ACCEL);
rewardPump.setSpeed(SPEED);
rewardPump.move(-REWARDSIZE);
Serial.println("reward");
Serial.println(rewardPump.currentPosition());
lastRewardMillis += REWINTERVAL;
}
rewardPump.run();
if (curMillis - lastRewardMillis >= REWINTERVAL)
{
}
else if (buttonState)
{
digitalWrite(ledPin, HIGH);
rewardPump.run();
Serial.println("button reward");
Serial.println(rewardPump.currentPosition());
digitalWrite(ledPin, LOW); // TODO: do this with attach interrupt + for rewardTimeStamp
}
// else if (revButton.fell())
// {
// rewardPump.move(150);
// Serial.println("turning back for cleaning");
// }
}
//======================================================================
void readButton()
{
if (millis() - previousButtonMillis >= buttonInterval)
{
fwdButton.update();
if (fwdButton.fell())
{
buttonState = true;
previousButtonMillis == millis();
}
else
{
buttonState = false;
}
}
}