Go Down

Topic: Code help Stepper motor control encoder 1 turn stepper motor 100 turn !! (Read 392 times) previous topic - next topic

cell27

Hello to everyone ...

A stepper motor
an arduino mega
stepper motor driver
and I have a 360 degree encoder

Encoder Pulse value 100

Stepper motor 1 full turn 200 step (1.8 degrees) Nema 34

I want Stepper motor must provide 100 turns when encoder 1 full turn


Arduino code help please !!



I wish everyone a good day.


Robin2

It's not clear from your description. Am I correct to assume that the encoder is something that you rotate by hand?

And is it correct that the encoder produces 100 pulses per revolution?

If you want the stepper motor to move 100 revolutions for every single revolution of the encoder then I reckon you are going to have to allow for a lag between the encoder movement and the motor.

I could turn an encoder with my fingers far too fast for a motor that is intended to move 100 times as far.

I think you will need a program that detects the change in position of the encoder (for example 37 encoder pulses) and then directs the motor to move 37 * 200 steps.

Have you already written a simple program that detects the encoder pulses and displays them on the Arduino Serial Monitor and another separate simple program that makes your motor move N steps? If not, start with those.

...R
Stepper Motor Basics
Simple Stepper Code
Two or three hours spent thinking and reading documentation solves most programming problems.

cell27

Suppose we rotate the encoder by hand. 

The encoder produces 100 pulses per revolution.

No time needed The motor will cycle 100 full cycles when the encoder rolls 1 turn.

We don't need to dial the encoder very fast. I'm thinking of managing the number of floors, but how?

When the encoder rotated, I made the motor spin. but I couldn't make it 100 times.


Robin2

When the encoder rotated, I made the motor spin. but I couldn't make it 100 times.
Post your program and tell us in detail what happens when you run it.

Quote
Suppose we rotate the encoder by hand.
That makes me think you have something else in mind. What? This could be very important.

Quote
We don't need to dial the encoder very fast. I'm thinking of managing the number of floors, but how?
You would have to turn the encoder very slowly to allow time for the motor to do one revolution for every click of the encoder. To my mind that is impractical which is why I made the suggestion in the 5th paragraph of Reply #1

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

MarkT

Please take the time to explain your problem carefully in detail, providing full details of any hardware
(datasheets if at all possible).   All details may matter.
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

cell27

 
Code: [Select]
#define encoder_a 2    
#define encoder_b 3    
#define motor_step 4    
#define motor_direction 5  

volatile long motor_position, encoder;

void setup ()
{

//set up the various outputs

pinMode(motor_step, OUTPUT);
pinMode(motor_direction, OUTPUT);

// then the encoder inputs

pinMode(encoder_a, INPUT);
pinMode(encoder_b, INPUT);

digitalWrite(encoder_a, HIGH);
digitalWrite(encoder_b, HIGH);

// encoder pin on interrupt 0 (pin 2)

attachInterrupt(0, encoderPinChangeA, CHANGE);

// encoder pin on interrupt 1 (pin 3)

attachInterrupt(1, encoderPinChangeB, CHANGE);

encoder = 0;
}

void encoderPinChangeA()
{
if (digitalRead(encoder_a) == digitalRead(encoder_b))
{
 encoder--;
}
else
{
 encoder++;
}
}

void encoderPinChangeB()
{
if (digitalRead(encoder_a) != digitalRead(encoder_b))
{
 encoder--;
}
else
{
 encoder++;
}
}


void loop()

{

if (encoder > 0)
{
 digitalWrite(motor_direction, HIGH);
 digitalWrite(motor_step, HIGH);
 digitalWrite(motor_step, LOW);

 motor_position++;
 encoder = 0;
}
else if (encoder < 0)
{
 digitalWrite(motor_direction, LOW);
 digitalWrite(motor_step, HIGH);
 digitalWrite(motor_step, LOW);
 motor_position--;
 encoder = 0;
}
}



This is the code I wrote.
Stepper motor rotates when encoder rotates.
But I want the motor to make 100 turns when the encoder makes a full rotation.
We can rotate the encoder slowly.
In this code , One turn of the encoder makes the step motor 2 turns.
I'm going to use it on a wind turbine.
The instrument has an encoder inside the wind direction meter. with the rotation of this encoder, the stepper motor will be activated. but it doesn't have to turn all the time it can check every 5 minutes.
Because the engine must be rested.
I used the stepping motor to control the wind turbine blades.
The stepper motor will direct the wind turbine blades according to the wind.
The reason I want 100 times is our proportion.

How should I make changes to this code ?


Robin2

It is much easier for everyone if you post code using the code button </>  and if you use the AutoFormat tool to indent it consistently so it looks like this

Code: [Select]
#define encoder_a 2   
#define encoder_b 3   
#define motor_step 4   
#define motor_direction 5   

volatile long motor_position, encoder;

void setup ()
{
        //set up the various outputs
    pinMode(motor_step, OUTPUT);
    pinMode(motor_direction, OUTPUT);

        // then the encoder inputs
    pinMode(encoder_a, INPUT);
    pinMode(encoder_b, INPUT);

    digitalWrite(encoder_a, HIGH);
    digitalWrite(encoder_b, HIGH);

        // encoder pin on interrupt 0 (pin 2)
    attachInterrupt(0, encoderPinChangeA, CHANGE);

        // encoder pin on interrupt 1 (pin 3)
    attachInterrupt(1, encoderPinChangeB, CHANGE);

    encoder = 0;
}


void encoderPinChangeA()
{
    if (digitalRead(encoder_a) == digitalRead(encoder_b))
    {
        encoder--;
    }
    else
    {
        encoder++;
    }
}


void encoderPinChangeB()
{
    if (digitalRead(encoder_a) != digitalRead(encoder_b))
    {
        encoder--;
    }
    else
    {
        encoder++;
    }
}


void loop()
{
    if (encoder > 0)
    {
        digitalWrite(motor_direction, HIGH);
        digitalWrite(motor_step, HIGH);
        digitalWrite(motor_step, LOW);

        motor_position++;
        encoder = 0;
    }
    else if (encoder < 0)
    {
        digitalWrite(motor_direction, LOW);
        digitalWrite(motor_step, HIGH);
        digitalWrite(motor_step, LOW);
        motor_position--;
        encoder = 0;
    }
}


You should not refer to the encoder position like this
Code: [Select]
if (encoder > 0)
It is a 4-byte variable and a new interrupt could change it while one of the bytes is being read. The correct way is to copy the value into a working variable while interrupts are temporarily disabled - for example
Code: [Select]
noInterrupts();
    latestEncoderValue = encoder;
interrupts();

and then use the variable latestEncoderValue in your calculations.

Your program makes no attempt to figure out the actual value of the encoder and how that relates to the value in motor_position

Before I can give any more detailed advice you MUST describe your project fully as requested in Reply #4. At the moment this is a typical XY problem. I just don't know what the solution might be.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

cell27

I couldn't apply what she said to the program.
Someone else's ideas about implementation are important to me.

Robin2

I couldn't apply what she said to the program.
Who is "she" and what problem did you have applying the advice?

And I doubt if "she" has prevented you from providing a detailed description of your project.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

raymw

surely, all you need to do is count 100 pulses from the encoder, and then send 100*200 pulses to the motor in the correct direction, or count 10 encoder pulses and fire off 100* 20 pulses. You need to remember the last encoder position, compare with current position, to get the direction to set the motor driver. (assuming no micro-stepping) .
The detail in the code you need to write, depends on the type of encoder you have.
https://www.dynapar.com/Technology/Encoder_Basics/Gray_Code_Encoders/


Go Up