Hi All-
I would like to use an ultrasonic range finder to dictate the position of a stepper motor. In essence, if an object is 1' away from the sensor and moves to 2', the motor advances 1 revolution (or 1/12th of a revolution / inch). If the object returns to 1', the motor reverses 1 revolution.
The motion should be smooth, whether through hysteresis, and or by using rate of change of distance sensor reading to determine motor velocity.
I will be using a NEMA 17 stepper and a linear ball screw assembly such as this: http://www.seeedstudio.com/depot/B04F-5V-DC-18-Stepper-Motor-p-1901.html?cPath=39_40 but bigger obvi. This will allow for the use of limit switches which I foresee being necessary without a way to keep track of motor position other than steps. Maybe I need a rotary encode for this project, I hope not.
Right now for bench testing this idea, i am using a 28BYJ-48 stepper, connected to my Arduino via a ULN2003 driver board. My Ping sensor is from radioshack.
I have gotten the stepper to work well, after messing with the pin assignments for a minute. I've determined that the rangefinder works too.
What is a good way to approach this? At the most basic level, the stepper motor control part of the code needs to be able to use realtime data from the sensor, the delay interval, to determine the amount of steps to take. With my sample code, this would be done through passing that variable into the delay function here:
myStepper.step(stepsPerRevolution); delay(500);
which does not seem ideal.
The speed of the motor:
myStepper.setSpeed(100);
would be determined by the rate of change of the delay interval, right?
It would seem to me, a code n00b, that this will be a significantly different program from the one i used to test the stepper. Should I try and adapt the test code below, or start with a clean slate? If I am to start anew, I really have no idea how to begin.
Any advice or direction is much appreciated.
all the best,
-Rev
test code for stepper:
/*
Stepper Motor Control - one revolution
This program drives a unipolar or bipolar stepper motor.
The motor is attached to digital pins 8 - 11 of the Arduino.
The motor should revolve one revolution in one direction, then
one revolution in the other direction.
Created 11 Mar. 2007
Modified 30 Nov. 2009
by Tom Igoe
*/
#include <Stepper.h>
const int stepsPerRevolution = 200; // change this to fit the number of steps per revolution
// for your motor
//Stepper myStepper(stepsPerRevolution,8,10,9,11); //good
//Stepper myStepper(stepsPerRevolution,8,10,11,9); //good
// Stepper myStepper(stepsPerRevolution,9,11,8,10);// good
// Stepper myStepper(stepsPerRevolution,9,11,10,8);//good
// Stepper myStepper(stepsPerRevolution,10,8,9,11); //good
//Stepper myStepper(stepsPerRevolution,11,9,8,10); //good?
Stepper myStepper(stepsPerRevolution,11,9,10,8); //good
void setup() {
// set the speed at 60 rpm:
myStepper.setSpeed(100);
// initialize the serial port:
Serial.begin(9600);
}
void loop() {
// step one revolution in one direction:
Serial.println("clockwise");
myStepper.step(stepsPerRevolution);
delay(500);
// step one revolution in the other direction:
Serial.println("counterclockwise");
myStepper.step(-stepsPerRevolution);
delay(500);
}
I've gotten the Ping sensor to work with numerous sketches, such as the following:
/* Ping))) Sensor
This sketch reads a PING))) ultrasonic rangefinder and returns the
distance to the closest object in range. To do this, it sends a pulse
to the sensor to initiate a reading, then listens for a pulse
to return. The length of the returning pulse is proportional to
the distance of the object from the sensor.
The circuit:
* +V connection of the PING))) attached to +5V
* GND connection of the PING))) attached to ground
* SIG connection of the PING))) attached to digital pin 7
http://www.arduino.cc/en/Tutorial/Ping
created 3 Nov 2008
by David A. Mellis
modified 30 Aug 2011
by Tom Igoe
This example code is in the public domain.
*/
// this constant won't change. It's the pin number
// of the sensor's output:
const int pingPin = 7;
void setup() {
// initialize serial communication:
Serial.begin(9600);
}
void loop()
{
// establish variables for duration of the ping,
// and the distance result in inches and centimeters:
long duration, inches, cm;
// The PING))) is triggered by a HIGH pulse of 2 or more microseconds.
// Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
pinMode(pingPin, OUTPUT);
digitalWrite(pingPin, LOW);
delayMicroseconds(2);
digitalWrite(pingPin, HIGH);
delayMicroseconds(5);
digitalWrite(pingPin, LOW);
// The same pin is used to read the signal from the PING))): a HIGH
// pulse whose duration is the time (in microseconds) from the sending
// of the ping to the reception of its echo off of an object.
pinMode(pingPin, INPUT);
duration = pulseIn(pingPin, HIGH);
// convert the time into a distance
inches = microsecondsToInches(duration);
cm = microsecondsToCentimeters(duration);
Serial.print(inches);
Serial.print("in, ");
Serial.print(cm);
Serial.print("cm");
Serial.println();
delay(100);
}
long microsecondsToInches(long microseconds)
{
// According to Parallax's datasheet for the PING))), there are
// 73.746 microseconds per inch (i.e. sound travels at 1130 feet per
// second). This gives the distance travelled by the ping, outbound
// and return, so we divide by 2 to get the distance of the obstacle.
// See: http://www.parallax.com/dl/docs/prod/acc/28015-PING-v1.3.pdf
return microseconds / 74 / 2;
}
long microsecondsToCentimeters(long microseconds)
{
// The speed of sound is 340 m/s or 29 microseconds per centimeter.
// The ping travels out and back, so to find the distance of the
// object we take half of the distance travelled.
return microseconds / 29 / 2;
}