Coding a Revolution Counter for a Stepper Motor.

2 functions are needed.

  • Counting down 1000 to 0.
  • Variable rotation speed.

So 1000 then 200 steps, 999 then 200 steps. and so on till zero. While a pot controls the speed faster or slower but always clockwise.

/*
 Stepper Motor Control - speed control

 This program drives a unipolar or bipolar stepper motor.
 The motor is attached to digital pins 8 - 11 of the Arduino.
 A potentiometer is connected to analog input 0.

 The motor will rotate in a clockwise direction. The higher the potentiometer value,
 the faster the motor speed. Because setSpeed() sets the delay between steps,
 you may notice the motor is less responsive to changes in the sensor value at
 low speeds.

 Created 30 Nov. 2009
 Modified 28 Oct 2010
 by Tom Igoe

 */

#include <Stepper.h>

const int stepsPerRevolution = 200;  // change this to fit the number of steps per revolution
// for your motor


// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11);

int stepCount = 0;  // number of steps the motor has taken
int RotationsNeeded = 1000; // count down display value
int Display = 0;

void setup() {
  
    Serial.begin(9600); // open the serial port at 9600 bps:
}

void loop() {
  // read the sensor value:
  int sensorReading = analogRead(A0);
  // map it to a range from 0 to 100:
  int motorSpeed = map(sensorReading, 0, 1023, 0, 100);
  // set the motor speed:
  if (motorSpeed > 0) {
    myStepper.setSpeed(motorSpeed);
    // step 1/100 of a revolution:
    myStepper.step(stepsPerRevolution / 100);
  }

 Display = RotationsNeeded--;

// new area for serial monitor code

  // print labels
  Serial.print("Count down");  // prints a label
  Serial.print("\t");         // prints a tab
  Serial.println();        // carriage return after the last label
  
    Serial.print(Display);       // print as an ASCII-encoded decimal - same as "DEC"
    Serial.print("\t\t");  // prints two tabs to accomodate the label lenght

    Serial.println();  // print as an ASCII-encoded binary
    // then adds the carriage return with "println"
    delay(200);            // delay 200 milliseconds 

}

this is sort of what i crammed together, turn up or down the speed as needed with a pot, while decrementing 1 for every 200 steps of a 200 step motor. I may use a peg or bump to press a micro-switch to do the decrement, it would guarantee the right rotation count even with lost steps. but i would rather a software solution...

It still needs to convert the "Display" variable to BCD and the assign them to pins.

PatrickZ:
2 functions are needed.

  • Counting down 1000 to 0.
  • Variable rotation speed.

You have not addressed my understanding of the problem as set out in Reply #4. It is much easier to help when your replies follow on from comments you have received so there is a stream of development of ideas rather than things popping up out of the blue. And if you don't understand something please say so - it can save a lot of wasted time.

Also you have posted a program but you have not told us what happens when your run it.

As far as I can see your program causes the motor to move 2 steps at the set speed and then print stuff and wait 200 millisecs before the next 2 steps.

Is that correct, and is it what you want it to do?

...R

You wrote: "This device is for winding coils, transformers and motors. ".

I have some experience building a coil winder. You need to factor in an emergency pause/continue switch in your coding and physical design.

Paul

Robin2:
As far as I can see your program causes the motor to move 2 steps at the set speed and then print stuff and wait 200 millisecs before the next 2 steps.

Is that correct, and is it what you want it to do?

...R

I dont know how else to describe my need... revolve once decrement by 1, revolve again decrement again until zero, then stop... all while i can speed up or slow down in real time to avoid tangles or breaking the wire. My digital logic analyzer Isnt working and serial monitor only shows the decrement count. Eventually the code would put out BCD for the LED segments as seen in the beginning pic.

And no what you describe is not what i want.

the emergency stop is easy compared to the rest of this.

PatrickZ:
I dont know how else to describe my need... revolve once decrement by 1, revolve again decrement again until zero, then stop... all while i can speed up or slow down in real time to avoid tangles or breaking the wire.

That description reads as if you would be content for the motor to move 1 rev, stop, decrement the counter, do the next rev, stop, decrement the counter etc. Keep in mind that computers are stupid and interpret instructions literally - they have no capability to figure out what you want.

My guess is that what you really want is for the motor to run continuously for (perhaps) several hundred revs decrementing the counter as each rev is completed.

If so, you need to re-read the last paragraph in Reply #1 for two options for implementing that.

I suggest you try some of the examples that come with the AccelStepper library and study its documentation so you understand how it can be used.

...R

Robin2:
My guess is that what you really want is for the motor to run continuously for (perhaps) several hundred revs decrementing the counter as each rev is completed.

Yes that is what i want.

// 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
AccelStepper stepper; // Defaults to AccelStepper::FULL4WIRE (4 pins) on 2, 3, 4, 5
// 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.setMaxSpeed(1000);
}
void loop()
{
  // Read new position
  int analog_in = analogRead(ANALOG_IN);
  stepper.moveTo(analog_in);
  stepper.setSpeed(100);
  stepper.runSpeedToPosition();
}

This code does the analog in speed control like i want. But i dont see the step/rev that all code needs to know what each steppers step per degree is. my motor is 200 steps per turn. Im trying to use the link you provided.

You have chosen an inappropriate example from the AccelStepper library because runSpeedToPosition() blocks until it completes.

You need to use run() [which uses acceleration] or runSpeed() [which does not]. Study the examples for those functions.

Suppose that you tell the motor to go 1000 steps with myStepper.move(1000); Then in every iteration of loop() you can check how far it has got with code in loop() like this

previousPosition = currentPosition;
currentPosition = myStepper.distanceToGo();
if (currentPosition > previousPosition) {
  stepsThisRev ++;
}
if (stepsThisRev >= 200) {
   numRevs --;
   stepsThisRev = 0;
}

Make sure that loop() can repeat much faster than the step rate.

...R

previousPosition = currentPosition;
currentPosition = myStepper.distanceToGo();
if (currentPosition > previousPosition) {
  stepsThisRev ++;
}
if (stepsThisRev >= 200) {
   numRevs --;
   stepsThisRev = 0;
}

Does this go in the void loop section, and more in the void setup ? ive been looking here :

https://www.airspayce.com/mikem/arduino/AccelStepper/classAccelStepper.html#aa4a6bdf99f698284faaeb5542b0b7514

PatrickZ:
Does this go in the void loop section, and more in the void setup ?

It must go in the loop() function (or be called from loop() ) as it needs to be checked regularly.

You will need to declare the relevant variable before the setup() function.

I suspect you would benefit from taking a little time to study the basics of Arduino C++ programming so you have a better idea where things need to go in programs.

...R

There is not enough information to tell you how to display a number on your 7-segment displays. A wiring diagram would help.

/*
  Stepper Motor Control - speed control


  This program drives a unipolar or bipolar stepper motor.
  The motor is attached to digital pins 8 - 11 of the Arduino.
  A potentiometer is connected to analog input 0.


  The motor will rotate in a clockwise direction. The higher the potentiometer value,
  the faster the motor speed. Because setSpeed() sets the delay between steps,
  you may notice the motor is less responsive to changes in the sensor value at
  low speeds.


  Created 30 Nov. 2009
  Modified 28 Oct 2010
  by Tom Igoe


*/


#include <Stepper.h>


const int stepsPerRevolution = 200;  // change this to fit the number of steps per revolution
// for your motor

// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11);


long int stepCount = 0;  // number of steps the motor has taken


void setup()
{
  // nothing to do inside the setup
}


void display(int value)
{
  // Display the value on the 3+ digit display
}


void loop()
{
  // read the sensor value:
  int sensorReading = analogRead(A0);
  
  // map it to a range from 0 to 100:
  int motorSpeed = map(sensorReading, 0, 1023, 0, 100);
  
  // set the motor speed:
  if (motorSpeed > 0)
  {
    myStepper.setSpeed(motorSpeed);
    
    // step 1/100 of a revolution:
    int stepsToTake = stepsPerRevolution / 100;
    
    // Only move if we have not reached the limit
    if (stepCount + stepsToTake < 1000L * stepsPerRevolution)
    {
      myStepper.step(stepsPerRevolution / 100);
      stepCount += stepsToTake;
      int revolutionsTaken = stepCount / stepsPerRevolution;
      display(1000 - revolutionsTaken);
    }
  }
}

Robin2:
I suspect you would benefit from taking a little time to study the basics of Arduino C++ programming so you have a better idea where things need to go in programs.

...R

Ive done 2 semesters of c++ in college 14 years ago. But we never turned pins on or off. i know some basic and propeller stuff. but how and in what way to use libraries and functions is something i stuggle with. thats why i appreciate your help. I do have an Arduino for dummies book.

There is not enough information to tell you how to display a number on your 7-segment displays. A wiring diagram would help.

yes, i think we can agree to figure out BCD and pinouts to 7447 ic's can wait until ive gotten the rest of my furball together. And i did find a library for seven segment leds.

How to Set up Seven Segment Displays on the Arduino - Circuit Basics some info ill need.

PatrickZ:
Ive done 2 semesters of c++ in college 14 years ago. But we never turned pins on or off.

Turning pins on and off is just detail stuff and you can look up the syntax in the Reference section. My comment was prompted by your question (in Reply #12) " Does this go in the void loop section, and more in the void setup ? "

I do have an Arduino for dummies book.

I have glanced through that in a bookshop and it looked good. Sailing for Dummies was excellent :slight_smile:

...R

Robin2:
Sailing for Dummies was excellent :slight_smile:

Those books will get you out, but getting back is a different matter.

PatrickZ:
Those books will get you out, but getting back is a different matter.

I'm here so I guess I got back :slight_smile:

...R

21 pins will be needed for the 7 segment display
1 for the pot
2 for stepper driver
1 to start / stop button

so thats 25 i/o pins. ill be using the arduino mega with a group of transistors for each segment.

I wonder if you can get a driver for the display that takes care of the current/voltage it requires and which only requires an I2C or SPI connection to the Arduino?

...R

I found this code which is perfect for the basic operation. And ill add the counter. i may count one full revolution then pulse a pin to a separate counter circuit board.

the real problem with this code is that when using a variable power supply at 9 volts its fast, but slows to a near stop at 14 volts. I think becuase the the pulses are arbitrary in length the A4988 is rolling back the current as V goes up.

// Stepper motor run code with a4988 driver
// by Superb

const int stepPin = 3;
const int dirPin = 4; 
int customDelay,customDelayMapped; // Defines variables
 
void setup() {
  // Sets the two pins as Outputs
  pinMode(stepPin,OUTPUT);
  pinMode(dirPin,OUTPUT);
 
  digitalWrite(dirPin,HIGH); //change the rotation direction HIGH for clockwise and LOW for anticlockwise
}
void loop() {
  
  customDelayMapped = speedUp(); // Gets custom delay values from the custom speedUp function
  // Makes pules with custom delay, depending on the Potentiometer, from which the speed of the motor depends
  digitalWrite(stepPin, HIGH);
  delayMicroseconds(customDelayMapped);
  digitalWrite(stepPin, LOW);
  delayMicroseconds(customDelayMapped);
}
// Function for reading the Potentiometer
int speedUp() {
  int customDelay = analogRead(A0); // Reads the potentiometer
  int newCustom = map(customDelay, 0, 1023, 300,4000); // Convrests the read values of the potentiometer from 0 to 1023 into desireded delay values (300 to 4000)
  return newCustom;  
}

PatrickZ:
the real problem with this code is that when using a variable power supply at 9 volts its fast, but slows to a near stop at 14 volts. I think becuase the the pulses are arbitrary in length the A4988 is rolling back the current as V goes up.

Stepper motors work better at higher voltages and IIRC an A4988 can go up to 36v.

If you are supplying power from a chopping power supply my guess is that it's fighting with the A4988. Use a better power supply or put a large capacitor (1000µF ?) at the input to the A4988.

...R

 int newCustom = map(customDelay, 0, 1023, 300,4000);

i think it is the 300 and 4000 part of this statement that cuases it to do this.

besides the final device will use a fixed 12v SMPS. So other than your cap idea which ill try, it seems to work well enuff as is. id also like it to stop at a preset number of revolutions, programmed in the IDE at compile and download.

I bought a separate counter which will use a 3d printed lobe/cam to tap a micro switch instead of internal code.

here it is:

OK ive got the circuit board coming together and im 3D printing parts.

the nano, a988 and potentiometer control the stepper motor speed.

the mega controls the down counting digits via a micro bump switch and rotating lobe.