Go Down

Topic: Sensor-controlled stepper motor problem (Read 483 times) previous topic - next topic

seba1685

Hey everyone,
I'm sort of stuck on my first physical computing project and i'm hoping some more experienced folk can grace me with their knowledge.

Hardware:
- Arduino Duemilanove
- MXP2010GP Breath Pressure Sensor (BPS)
- Step Genie Demo Board
- Unipolar Stepper Motor (1.8 degrees or 200 steps)

BPS --> Analog input 0 on Arduino

Arduino Digital Pins Output --> Step Genie Demo Board --> Stepper Motor

What I'm trying to achieve:
There is a long screw attached to the end of the Motor's shaft. There is also a nut on this screw that has a small, rectangular sheet of metal attached to it. (see picture)

When the motor turns, the nut moves up and down the screw.
The range of motion of this nut MUST run from the base (position on the screw where the nut is closest to the motor) to 64 complete revolutions away from this base (200 steps per revolution).

When I breathe into this pressure sensor, it outputs values from zero to 772. I want to control the positioning of this nut along the shaft with the output of this BPS. When there is no pressure, I want the nut to travel back to the base

For example: when my breath pressure sensor outputs a value of 386 (half of 772), i want the nut to travel to the HALF WAY point of my designated range on the shaft and STAY there until the value changes.

So far, i've only been able to affect the time between each step with an inverted form of the BPS output (for example: say the range is 0 to 1000. if the BPS output is 800, this gets inverted to 200 and stored into a variable. this variable is plugged used as the number of milliseconds to pause between steps), but this only affects the speed at which the shaft is rotating.

I think there will need to be some sort of "rotation counting function" which measures how many full rotations (200 steps) the motor has taken to determine where the nut is within the zero to 64 rotation range.


Thank you so much for taking the time to read this. I'm trying to premier this project at my recital by the end of the year before i graduate college (it is part of a musical instrument I invented). Any help would be greatly appreciated.
-Sebastian

My code (thusfar):
// this constant won't change:
const int knockSensor = 0;  // the BPS is connected to analog pin 0

int sensorReading = 0;      // variable to store the value read from the sensor pin
int step_pin = 13;          // These pins are on the Step Genie.
int dir_pin = 12;           // They are used to control the motor.
int enab_pin = 11;

int dir = 0;

void setup()
{
Serial.begin(9600);       // use the serial port

  pinMode(step_pin, OUTPUT);  // these pins will output values
  pinMode(dir_pin, OUTPUT);
  pinMode(enab_pin, OUTPUT);
 
  digitalWrite(enab_pin, LOW);
  digitalWrite(dir_pin, HIGH);     // direction LOW = ccw, HIGH = cw

}


void loop()
{
  // read the sensor and store it in the variable sensorReading:
  sensorReading = analogRead(knockSensor); // output of values is 772
                                           
                                           
  sensorReading = sensorReading - 772;    // this inverts values from low/high to high/low
  sensorReading = abs(sensorReading);      // this eliminates negative numbers
 
  if (sensorReading = 0);
  {
    digitalWrite(dir_pin, LOW);
  }
                                         

  digitalWrite(step_pin, HIGH); // tell step_pin to step
  delayMicroseconds(5);         // short pause (constant integer)
  digitalWrite(step_pin, LOW);  // tell step_pin to stop
  delay(sensorReading);         // pause       (variable that determines speed)

 
 
  Serial.println(sensorReading);
  delay(10);  // delay to avoid overloading the serial port buffer
}

PaulS

Quote
I think there will need to be some sort of "rotation counting function" which measures how many full rotations (200 steps) the motor has taken to determine where the nut is within the zero to 64 rotation range.

You need to develop this function.

Quote
if (sensorReading = 0);
  {
    digitalWrite(dir_pin, LOW);
  }

The sensorReading variable is assigned the value 0 (= is an assignment operator; == is the equality operator). The result of the assignment is the value assigned. So, the if statement is equivalent to if(0);.

The code to be executed if the test is true is ;. That is probably not what you want. I suspect you want this:
Code: [Select]
  if (sensorReading == 0)
  {
    digitalWrite(dir_pin, LOW);
  }


Code: [Select]
  delay(10);  // delay to avoid overloading the serial port buffer
There is no buffer for outgoing data, so this comment is wrong.

AWOL

Code: [Select]
// this constant won't change:
const int knockSensor = 0;  // the BPS is connected to analog pin 0

"This constant won't change".

But these ones will?
Code: [Select]
int step_pin = 13;          // These pins are on the Step Genie.
int dir_pin = 12;           // They are used to control the motor.
int enab_pin = 11;
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

MarkT

I think you should tackle this problem by breaking it down into smaller problems that can be separately developed and tested.

Firstly you have the problem of reading the BPS and determining the desired position of the nut - since I presume this can constantly change you may have to think about how often to sample, whether to low-pass-filter the sensor output. 

A separate problem is keeping track of the current position by counting the steps.

And lastly you need to turn the difference between current and desired position into stepping instructions (direction and speed of stepping).
[ I won't respond to messages, use the forum please ]

Go Up