ProportionControl example with Ultrasonic sensor

Dear Arduino community, this is my first time using the forum. :o

I´m working on a project mixing Stepper motor with Ultrasonic Sensor. I´m using the AccelStepper library, and try the proportionalControl example with no problem.

This is the code.

// ProportionalControl.pde
// -*- mode: C++ -*-
//
// Make a single stepper follow the analog value read from a pot or whatever
// The stepper will move at a constant speed to each newly set posiiton, 
// depending on the value of the pot.
//
// Copyright (C) 2012 Mike McCauley
// $Id: ProportionalControl.pde,v 1.1 2011/01/05 01:51:01 mikem Exp mikem $

#include <AccelStepper.h>

// Define a stepper and the pins it will use
// 1 EN+ , 9 CLK+ , 8 CW+  AccelStepper stepper(1, 9, 8); 
AccelStepper stepper(1, 9, 8); 


// This defines the analog input pin for reading the control voltage
// Tested with a 10k linear pot between 5v and GND
#define ANALOG_IN A0

void setup()
{ 
  stepper.setSpeed(3000);
  stepper.setMaxSpeed(4000);
  stepper.setAcceleration(1000);

 
}

void loop()
{
  // Read new position
  int analog_in = analogRead(ANALOG_IN);
  stepper.moveTo((analog_in)*4);
  stepper.runSpeedToPosition();
  delayMicroseconds(100);
}

And in other hand I´m using a HC-SR04 ultrasonic sensor with this code.

/*
  HC-SR04 Ping distance sensor:
  VCC to arduino 5v
  GND to arduino GND
  Echo to Arduino pin 7
  Trig to Arduino pin 8

  This sketch originates from Virtualmix: http://goo.gl/kJ8Gl
  Has been modified by Winkle ink here: http://winkleink.blogspot.com.au/2012/05/arduino-hc-sr04-ultrasonic-distance.html
  And modified further by ScottC here: http://arduinobasics.blogspot.com.au/2012/11/arduinobasics-hc-sr04-ultrasonic-sensor.html
  on 10 Nov 2012.
*/



long soft;
int b = 15;
int buf[15]; // buffer de suavizado

#define echoPin 7 // Echo Pin
#define trigPin 8 // Trigger Pin
#define LEDPin 13 // Onboard LED

int maximumRange = 400; // Maximum range needed
int minimumRange = 0; // Minimum range needed
long duration, distance; // Duration used to calculate distance
int count;

void setup() {
  Serial.begin (9600);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(LEDPin, OUTPUT); // Use LED indicator (if required)

  for (int i = 0; i < b; i++) {
    buf[i] = 0;
  }
  count = 0;
  soft = 0;
}

void loop() {
  /* The following trigPin/echoPin cycle is used to determine the
    distance of the nearest object by bouncing soundwaves off of it. */
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);

  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);

  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);

  //Calculate the distance (in cm) based on the speed of sound.
  distance = duration / 52;

  if (distance >= maximumRange || distance <= minimumRange) {
    /* Send a negative number to computer and Turn LED ON
      to indicate "out of range" */
    // Serial.println("-1");
    distance = -1;
    digitalWrite(LEDPin, HIGH);
  }
  else {
    /* Send the distance to the computer using Serial protocol, and
      turn LED OFF to indicate successful reading. */
    //Serial.println(distance);
    digitalWrite(LEDPin, LOW);
  }

  calcSoft();


}

void calcSoft() {
  if (distance != -1) {
    buf[count] = distance;
    count ++;
    count %= b;
  }

  long val = 0;
  for (int i = 0; i < b; i++) {
    val += buf[i];
  }
  soft = val / b;
  Serial.println(soft);
}

With both code i have no problem at all, the problem is when I try to mix them.

// ProportionalControl.pde
// -*- mode: C++ -*-
//
// Make a single stepper follow the analog value read from a pot or whatever
// The stepper will move at a constant speed to each newly set posiiton, 
// depending on the value of the pot.
//
// Copyright (C) 2012 Mike McCauley
// $Id: ProportionalControl.pde,v 1.1 2011/01/05 01:51:01 mikem Exp mikem $

#include <AccelStepper.h>

// Define a stepper and the pins it will use
// 1 EN+ , 9 CLK+ , 8 CW+  AccelStepper stepper(1, 9, 8); 
AccelStepper stepper(1, 9, 8); 


// This defines the analog input pin for reading the control voltage
// Tested with a 10k linear pot between 5v and GND
#define ANALOG_IN A0

long soft;
int b = 15;
int buf[15]; // buffer de suavizado

#define echoPin 11 // Echo Pin
#define trigPin 12 // Trigger Pin
#define LEDPin 13 // Onboard LED

int maximumRange = 400; // Maximum range needed
int minimumRange = 0; // Minimum range needed
long duration, distance; // Duration used to calculate distance
int count;

void setup()
{ 
  stepper.setSpeed(3000);
  stepper.setMaxSpeed(4000);
  stepper.setAcceleration(1000);

  // ULTRA
    pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(LEDPin, OUTPUT); // Use LED indicator (if required)

  for (int i = 0; i < b; i++) {
    buf[i] = 0;
  }
  count = 0;
  soft = 0;
}

 


void loop()
{
  // Read new position
  int analog_in = analogRead(ANALOG_IN);
  stepper.moveTo((analog_in)*4);
  stepper.runSpeedToPosition();

    /* The following trigPin/echoPin cycle is used to determine the
    distance of the nearest object by bouncing soundwaves off of it. */
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);

  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);

  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);

  //Calculate the distance (in cm) based on the speed of sound.
  distance = duration / 52;

}


void calcSoft() {
  if (distance != -1) {
    buf[count] = distance;
    count ++;
    count %= b;
  }

  long val = 0;
  for (int i = 0; i < b; i++) {
    val += buf[i];
  }
  soft = val / b;
  Serial.println(soft);
}

The problem with this code is that the velocity of the motor goes very slow, I try to increase the:
stepper.setSpeed(3000);
stepper.setMaxSpeed(4000);
stepper.setAcceleration(1000);
But with no effect.

The idea is to use the distance instead of the pot.
stepper.moveTo((distance)*4);

If anyone could help I will really appreciate!

Thanks!

I thought the function runSpeedToPosition() is a blocking function but that is not stated in the AccelStepper documentation.

If it IS a blocking function I would expect it to operate at the speed you specify.

If it is NOT a blocking function then I suspect the reason the motor runs slow is the use of delay()s elsewhere in loop() which are preventing loop() from repeating fast enough.

You can use millis() for non-blocking timing as illustrated in Several Things at a Time

...R

duration = pulseIn(echoPin, HIGH);

pulseIn is a blocking function and may be interfering with the stepper. However, as Robin suggests, it may be the trigger delays which are causing the problem.

Here non blocking interrupt driven code for the HC-SR04. Which should help sort out the effect of the trigger delays from pulseIn().

volatile unsigned long LastPulseTime;
int duration;
const byte trigPin = 7;
const byte echoPin = 2;
//const byte echoPin = 3;
volatile boolean pulseCaptured = false;
boolean triggerFinished = false;

void setup()
{
  Serial.begin (9600);
  Serial.println("starting...");
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  attachInterrupt(0, EchoPinISR, CHANGE); // Pin 2 interrupt on any change
  // attachInterrupt(1, EchoPinISR, CHANGE);  // Pin 3 interrupt on any change
}

void loop()
{
  if (triggerFinished == false)
  {
    digitalWrite(trigPin, LOW);
    delayMicroseconds(2);
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);
    triggerFinished = true;
  }

  if (pulseCaptured == true && triggerFinished == true)
  {
    pulseCaptured = false; //reset
    triggerFinished = false;
    Serial.print((LastPulseTime / 2) / 29.1, 1);
    Serial.println("cm");
  }
}

void EchoPinISR()
{
  static unsigned long startTime;

  if (digitalRead(echoPin)) // Gone HIGH
    startTime = micros();
  else  // Gone LOW
    LastPulseTime = micros() - startTime;
  pulseCaptured = true;
}

I would imagine that before loop() was running 10,000 times a second reading the analog pin, and now its running about 200 times a second because its waiting for those pulses and not checking the pin as often.

Normally you would call run() in loop(), and moveTo () for a new position, then you don't wait for the move to complete.

Try not to hang waiting for something, because that stops run() in loop() being called.

Thanks for the Reply,

I try the code for the HC-SR04 and i have some issues, the reading stop while I´m approximating the sensor, in the serial monitor i see the following, each starting is s reset of the arduino (with reset button). I think could be the sensor, tomorrow i will try with another one.

starting...
3.3cm
3.3cm
57.2cm
57.2cm
starting...
3.3cm
3.3cm
58.0cm
58.0cm
starting...
3.3cm
3.3cm
58.1cm
58.1cm
starting...
3.3cm
3.3cm
68.2cm
68.2cm
starting...
3.3cm
3.3cm
59.2cm
59.2cm
starting...
3.3cm
3.3cm
57.2cm
57.2cm
starting...
3.3cm
3.3cm
58.0cm
58.0cm
starting...
3.3cm
3.3cm

I added the mills in the example as following without problem, so I think i could use some mills in the loop.

// ProportionalControl.pde
// -*- mode: C++ -*-
//
// Make a single stepper follow the analog value read from a pot or whatever
// The stepper will move at a constant speed to each newly set posiiton, 
// depending on the value of the pot.
//
// Copyright (C) 2012 Mike McCauley
// $Id: ProportionalControl.pde,v 1.1 2011/01/05 01:51:01 mikem Exp mikem $

#include <AccelStepper.h>

// Define a stepper and the pins it will use
// 1 EN+ , 9 CLK+ , 8 CW+  AccelStepper stepper(1, 9, 8); 
AccelStepper stepper(1, 9, 8); 


// This defines the analog input pin for reading the control voltage
// Tested with a 10k linear pot between 5v and GND
#define ANALOG_IN A0

void setup()
{ 
  stepper.setSpeed(5000);
  stepper.setMaxSpeed(7000);
  stepper.setAcceleration(2000);
 
}

void loop()
{
  // Read new position
  int analog_in = analogRead(ANALOG_IN);
  stepper.moveTo((analog_in)*4);
  stepper.runSpeedToPosition();
  delayMicroseconds(100);
}

I will use another sensor tomorrow, any advice i will really appreciate it,

Thanks