Higher move encoder stepper motor slow work, HELP!

At a Higher move encoder stepper motor slow work. Encoder at high speed to submit a lot of pulses by the program can not quickly to use. If encoder slowly move work ok. My board is Arduino mini pro 328 5v 16Mhz
Can you help me how can I fix it the problem of this code. DigitalRead() is slow - How can I replace to quickly read

#define encoder_a 2 //keep this on and interrupt pin
#define encoder_b 3 //keep this on and interrupt pin
#define motor_step 4 //can be any pin
#define motor_direction 5 //can be any pin

#include <delay.h>
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);
  // enable pullup as we are using an open collector encoder
  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; //reseet the encoder position to 0
}

void loop() {
  //do stuff dependent on encoder position here
  //such as move a stepper motor to match encoder position
  //if you want to make it 1:1 ensure the encoder res matches the motor res by dividing/multiplying
  if (encoder > 0) {
    digitalWrite(motor_direction, HIGH);// move stepper in reverse
    digitalWrite(motor_step, HIGH);
    digitalWrite(motor_step, LOW);
    delayMicroseconds(600); //_delay_us(200); //modify to alter speed
    motor_position++;
    encoder = 0; //encoder--;
  }
  else if (encoder < 0) {
    digitalWrite (motor_direction, LOW); //move stepper forward
    digitalWrite (motor_step, HIGH);
    digitalWrite (motor_step, LOW);
    delayMicroseconds(600); //_delay_us(200); //modify to alter speed
    motor_position--;
    encoder = 0; //encoder++;
  }
}

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

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

I'm sorry but I can't make sense of your question - perhaps due to machine translation.

Loop up "direct port manipulation" for a quicker alternative to digitalRead() and digitalWrite().

...R

Problem is digitalread, because it is not in such a short time to read all pulses.
so I'm looking for help because they do not know how to use direct port manipulation .
it's very difficult because I'm a beginner you do not succeed.

Mikistromar:
Problem is digitalread, because it is not in such a short time to read all pulses.
so I'm looking for help because they do not know how to use direct port manipulation .
it's very difficult because I'm a beginner you do not succeed.

If digitalRead() is too slow then you will just have to learn how to use "direct port manipulation". I'm sure Google will find plenty of examples, and it is not difficult. You will probably also need to download a copy of the Atmel datasheet for the processor on your Arduino board (the Atmega 328 if you are using a Uno).

...R

stepper motors have more power at lower speeds. they loose power at higher speeds. if your load is too great the stepper motor can miss steps or stall.

also, the coil has to discharge before it can be charged with a reverse polarity.

Problem is only to code not with power or stepper motor. I know because I signal measured by an oscilloscope. The program could not accept so many pulses in a short time. Code digitalread () has a slow response.

I used a direct port manipulation code but no change. Still stepper motor is losing the signal.
With an oscilloscope I measured the signal from the encoder and produces signals from 1000ms to 50microS depending on how fast you turn. If you turn encoder to 1300rpm produces signal 50microS. Error occurs when the encoder sends pulse of 600 microS. Does anybody know where the problem. Have arduino mini pro 16MHz 5V 328.
This is new code for direct manipulation port

#define encoder_a 2 //keep this on and interrupt pin
#define encoder_b 3 //keep this on and interrupt pin
#define motor_step 4 //can be any pin
#define motor_direction 5 //can be any pin

#include <delay.h>
volatile long motor_position, encoder;

byte inputA;
byte inputB;

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);

  // enable pullup as we are using an open collector encoder
  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; //reseet the encoder position to 0
}

void loop() {
  //do stuff dependent on encoder position here
  //such as move a stepper motor to match encoder position
  //if you want to make it 1:1 ensure the encoder res matches the motor res by dividing/multiplying
  if (encoder > 0) {
    //digitalWrite(motor_direction, HIGH);// move stepper in reverse
    PORTD = PORTD | 0b00100000;
    //digitalWrite(motor_step, HIGH);
    PORTD = PORTD | 0b00010000;

    //digitalWrite(motor_step, LOW);
    PORTD = PORTD & 0b11101111;
    delayMicroseconds(200); //_delay_us(200); //modify to alter speed
    motor_position++;
    encoder = 0; //encoder--;
  }
  else if (encoder < 0) {
    //digitalWrite (motor_direction, LOW); //move stepper forward
    PORTD = PORTD & 0b11011111; 
    //digitalWrite (motor_step, HIGH);
    PORTD = PORTD | 0b00010000;
    //digitalWrite (motor_step, LOW);
    PORTD = PORTD & 0b11101111;
    delayMicroseconds(200); //_delay_us(200); //modify to alter speed
    motor_position--;
    encoder = 0; //encoder++;
  }
}

void encoderPinChangeA() {
  inputA = (PIND & 0b00000100) >>2; // result is 0b00000001 if input is high, 0b00000000 if input is low.
  inputB = (PIND & 0b00001000) >>3; //result is 0b00000001 if input is high, 0b00000000 if input is low.

    //if (digitalRead(encoder_a)==digitalRead(encoder_b)) {
  if (inputA == inputB){
    encoder--;
  }
  else{
    encoder++;
  }
}

void encoderPinChangeB() {
  inputA = (PIND & 0b00000100) >>2; // result is 0b00000001 if input is high, 0b00000000 if input is low.
  inputB = (PIND & 0b00001000) >>3; // result is 0b00000001 if input is high, 0b00000000 if input is low.
    //if (digitalRead(encoder_a) != digitalRead(encoder_b)) {
  if (inputA != inputB){
    encoder--;
  }
  else {
    encoder++;
  }
}

I think you need to go back to basics.

Do you have any code that works, even if the speed is slower than you want?

Have you code that can control the stepper motor properly (i.e. without losing steps) without using the encoder at all.

Have you code that will correctly read the position from the encoder when the motor is unpowered and turned by an external force?

...R

Hi Robin2,
All the codes work, but only if you slowly rotate the encoder.
Here I got the code and look at the video.

All the beautiful works only if slowly rotate the encoder. I use the quick movement and I'm sorry this is not work. I would like to improve but we are not succeeding.

It's not clear from your reply (to me at least) ...

when the encoder is not used
will the motor will only work properly at slow speeds
or will the motor also work properly at high speeds

when the motor is not used
will the encoder only work properly at slow speeds
or will the encoder also work properly at high speeds

Remind me again what is the purpose of the encoder, and why you are not just relying on counting the steps for the motor.

...R

digitalRead takes about 4us, interrupt handler overhead is a few us, so pulses every
600us aren't any problem to handle this way.

Can you explain again what you are trying to do, and what is actually happening,
and post your code.

I have a potential suggestion for approaching this problem a different way. Why do you need the encoder? Is it simply because you want to know how far the motor has turned (and the motor is always powered)? Because, if so, you can get away without the encoder. If you run your hardware exclusively under conditions where the motors do not skip steps, then you simply need to keep count the number of commanded steps and you'll know exactly where your motors are. I've built a micro-positioner this way using cheap steppers and no encoders. It can execute hundreds of bidirectional motions and still return to the original starting position with a linear accuracy of under half a micron. In terms of the motor spindle, this is under 0.45 degrees of the starting position (upper bound of the error), even if the motor has turned by many revolutions. If this is what you're after, then I can post more info here.

@MarkT, I suspect the problem is with reading the encoder rather than generating pulses. But I await information from the OP.

...R

    //digitalWrite (motor_step, HIGH);
    PORTD = PORTD | 0b00010000;
    //digitalWrite (motor_step, LOW);
    PORTD = PORTD & 0b11101111;

I am pretty sure this is going to give you step pulses of 62.5ns width.
Most drivers need a longer pulse. The A3988 (for example) needs 1us minimum.

Optoisolated drives need even longer pulse widths.

I am not saying this is the problem, or that is is the only problem, but that did catch my eye.

Using signals from the encoder the signal is digital. Why! Because I drive two motor whit one encoder. Encoder signal I used to move the second motor, but i need control rotation. Code for control rotation is

  delayMicroseconds(200);  200microS is 
-  1 rotated encoder 1 rotated motor ;
 600 microS is 1 rotated encoder 1/2 rotated motor

If I change 200microS on 1 microS then everything works but I do not have the possibility of changing the speed of the motor.
If i use 200microS with fast speed encoder motor to lose impulse
If i use 1microS then the motor does not lose Impulse.
Question. How can I change the motor speed but not lose the impulse to the motor.
Meybe with new code.

Maybe it would help if you did a wait without delay? http://arduino.cc/en/Tutorial/BlinkWithoutDelay

Mikistromar:
Using signals from the encoder the signal is digital. Why! Because I drive two motor whit one encoder. Encoder signal I used to move

.......SNIP........

I'm sorry but I can't make sense of your post.

If you answer the questions in my earlier Reply #9 I will try to help.

...R

Robin2,
I do not know how to write in more detail what I need. Therefore, these shows an example.
Do you know how it works DTG printer?
This is exactly the same. Printer receives from the encoder feedback signal.
If you use this signal can be controlled in another more powerful motor to drive the table.
This is video for exsample

This guy has used the signal from the Epson encoder for move printer.
Do you know now what I need

I am not impressed by being asked to watch videos instead of reading a succinct description but I took the trouble to watch the video you linked to. I could see no sign of an encoder. I had no use for watching a tee shirt being printed.

I hope you are not (at this early stage) planning to modify a printer to work like that.

Most of the questions I asked earlier (Replies 7 and 9) only require yes/no answers. The final question asked for an explanation of how you intend to use the encoder - what is it connected to and what is its output supposed to control?

I don't intend to be unkind, but if you can't answer those questions I don't believe you will be able to build your project (whatever it is).

Thinking some more (having seen the video) what makes you think the printer in the picture uses an encoder? Where do you think the encoder is connected? And what do you think is controlled by the signal from the encoder?

...R

Hi Robin,
Send the answers to your questions

Robin2:
when the encoder is not used
will the motor will only work properly at slow speeds
or will the motor also work properly at high speeds

YES If i use a simpl code stepper motor work properly at slow speeds also work properly at high speeds

Robin2:
when the motor is not used
will the encoder only work properly at slow speeds
or will the encoder also work properly at high speeds

encoder is a new, and work properly at slow speeds also work properly at high speeds.
The signal measured with an oscilloscope.

Robin2:
Thinking some more (having seen the video) what makes you think the printer in the picture uses an encoder? Where do you think the encoder is connected? And what do you think is controlled by the signal from the encoder?

The printer in the picture used DC motor which is connected to encoder.
Encoder needs to control a dc motor. Encoder printer has the A and B signal. This signal goes to the controller which converts the digital signal to function Step and direction like the Arduino board. Step and Direction signal goes to the driver stepper motor or servo motor.
That is, the encoder printer can be controlled second motor.
rgd