Hi, I am trying to make one axis linear actuator with NEMA 17 stepper motor, Ultrasonic range finder HCSR 04, and motor driver A4988.
When I powered the whole thing, the motor was a bit weird (going a little bit) before it functioned right. How do I fix this?
Also, I have a sample of the sensor distance reading (when the motor is off) as follow:
216 216 220 215 216 200 216. That causes my actuator to prematurely stop before it reaches the target (The motor stops as soon as the sensor senses 200mm, even though the actual distance is 216mm).
Is there anyway we can improve the consistency of reading? Is it because of the sensed surface? The perpendicularity of the sensor and the surface?
I have attached the code, and the pic of the setup here, and I really appreciate any helpful feedbacks.
#define trigPinx 11
#define echoPinx 10
#define enbx 4
#define stpx 3
#define dirx 2
void setup()
{
Serial.begin (9600);
pinMode(trigPinx, OUTPUT);
pinMode(echoPinx, INPUT);
pinMode(enbx,OUTPUT);
pinMode(stpx,OUTPUT);
pinMode(dirx,OUTPUT);
digitalWrite(enbx,HIGH); // Set Enable low
int targetx = 250;
delay(1000);
digitalWrite(enbx,LOW);
motor_control(trigPinx,echoPinx,stpx,dirx,targetx); // reach the target in x direction
delay(2000);
motor_control(trigPinx,echoPinx,stpx,dirx,targetx +50); // reach the target in x direction
delay(2000);
motor_control(trigPinx,echoPinx,stpx,dirx,200); // reach the target in x direction
}
void loop()
{
}
long distance_sensing(int trigPin,int echoPin)
{
long duration, distance;
digitalWrite(trigPin, LOW); // Added this line
delayMicroseconds(2); // Added this line
digitalWrite(trigPin, HIGH);
delayMicroseconds(10); // Added this line
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = (duration/2) / 2.91;
return distance;
}
int motor_control(int trig, int echo, int stp,int dir,int target)
{
int od = distance_sensing(trig, echo); // Measure the original distance
int distance = od;
while ((od-target)*(distance-target)>0) { // Meaning the the beam has not passed the target point (OD and distance on the same side)
if (od <= target) {
digitalWrite(dir,HIGH); // Set Dir high rotate clockwise
}
else {
digitalWrite(dir,LOW); // Set Dir low rotate Counterclockwise
}
digitalWrite(stp,HIGH); // Output high
delayMicroseconds(500); // Wait 1/2 a ms
digitalWrite(stp,LOW); // Output low
delayMicroseconds(500); // Wait 1/2 a ms
Serial.print(distance);
Serial.println(" mm");
distance = distance_sensing(trig,echo);
}
}
Sorry, but your photo is useless for showing connections. Make a pencil drawing (NOT Fritzing) and post a photo of the drawing.
Post a link to the datasheet for your stepper motor.
What stepper motor driver are you using>
What power supply are you using for the motor (volts and amps).
You could put more Serial.println() statements in your code to allow you to see what is happening.
I can see how your ultrasonic sensor could be confused - its not pointing into free-space, but along the
base board, so there will be lots of small reflections from that and the wires dangling in front of it.
Normally for a stop-switch you would use a microswitch or inductive proximity sensor, which is much
more accurate and reliable. Ultrasonic sensors also pick up stepper motor winding noise (which is
ultrasonic typically), which won't help I think.
Twisted pair (or twisted quad) for all motor / power wiring is a wise precaution against pick-up and
EMI generation. Use a handdrill or cordless drill and a vice to make your own twisted pairs, its simple
and neat and reduces interference a lot.