Read rotary encoder and copy it to output

Hello everyone, this is my first query to this forum, and also, it's my first project with Arduino.

I need to slow the forward and backward movement of a printer paper, my first attempt was to add a resistor to the motor, but the printer gave "fatal error" and did not work.

In my second attempt I am trying to capture the encoder motor and send the signal back to the printer via i2c bidirectional level shifter, but I go back to having a "fatal error".

Could anyone guide me to solve the error?
Thanks!

UPDATE:
The printer is an Epson Stylus Photo P50

#define Y_ENCODER_PIN_A 2
#define Y_ENCODER_PIN_B 3
#define FAKE_Y_ENCODER_PIN_A 4
#define FAKE_Y_ENCODER_PIN_B 5

void setup() {
  pinMode(Y_ENCODER_PIN_A, INPUT);
  pinMode(Y_ENCODER_PIN_B, INPUT);

  digitalWrite(Y_ENCODER_PIN_A, HIGH);
  digitalWrite(Y_ENCODER_PIN_B, HIGH);

  attachInterrupt(0, updateEncoderA, CHANGE); 
  attachInterrupt(1, updateEncoderB, CHANGE);

}

void loop() { 
}

void updateEncoderA() {
  int durationLpinA = pulseIn(Y_ENCODER_PIN_A, LOW);
  int durationHpinA = pulseIn(Y_ENCODER_PIN_A, HIGH);
  int pinA = ((durationLpinA)/(durationLpinA + durationHpinA));

  analogWrite(FAKE_Y_ENCODER_PIN_A, pinA);
}

void updateEncoderB() {
  int durationLpinB = pulseIn(Y_ENCODER_PIN_B, LOW);
  int durationHpinB = pulseIn(Y_ENCODER_PIN_B, HIGH);
  int pinB = ((durationLpinB)/(durationLpinB + durationHpinB));

  analogWrite(FAKE_Y_ENCODER_PIN_B, pinB);
}

Could anyone guide me to solve the error?

Without knowing what printer you are talking to? No.

You should NOT be using pulseIn() in an interrupt service routine. That is NOT how to determine the speed of the encoder.

Thank you very much for your reply.

I've updated the post with the printer model.

I also tried using PulseIn in loop function.

No need to calculate the speed, just knowing how many pulses moves and where it.

I've updated the post with the printer model.

I don't read posts after people have done that. If you are asked to supply missing information, don't revise the original post, and then tell us you did that. Just supply the data.

Doing what you did causes someone else to come along and wonder what the hell I'm talking about, when the original post contains the information that I claim is missing, so I end up looking like an idiot. I don't help people that do that to me.

Assuming you're reading the encoders properly with your Arduino, I really don't see how getting your printer to understand what you send back to it, is an Arduino programming question. At least not at this stage....

Seems to me you need info on the innards of the printer, at least a schematic, so that you can see how the printer currently (ie before your anticipated mods) reads and interprets those encoders. (Am I right in thinking the motors already have the encoders or have you retrofitted them?)

In any case, you're trying to inject a signal from Arduino into a device which even if it's a small cheapy, has pretty sophisticated control inside already. The co-ordination of the paper and the drum to transfer the toner with the correct tolerances is not trivial. What you're trying to do is undo that control, so you can have the paper travel at your chosen speed.

I think the task is to reverse-engineer the existing control, so that you can understand how you can circumvent it with your new signal. That new signal is going to get the existing control to accept an error condition, ie a speed outside what it wants to do, and its going to do its best to rectify the error and get back to speed.

Then, once you understand what the printer wants -or will accept- in the way of signal that becomes an Arduino issue to engineer a signal the printer likes.

@PaulS My intention was to put all the information there so others do not have to go browsing all the threads to get all the information. Sorry for the inconvenience.

@JimboZA Yes, read the encoder well, I am able to count each of the pulses. If the code is right, maybe I should use some opto coupler to use self-powered encoder and send back through the PIN A or B.

facine:
@JimboZA Yes, read the encoder well, I am able to count each of the pulses. If the code is right, maybe I should use some opto coupler to use self-powered encoder and send back through the PIN A or B.

What's a "self powered encoder".... a servo? That makes some sense if you have dismantled or disconnected the existing mechanisms.

You need to give more info here.... is the printer's as-is control disconnected or is this printer still a working printer? If the latter, you're going to knock heads with its internal control which exists for the sole purpose of moving the paper at the speed and timings it wants, not what you want.

If you slow or speed the paper feed mechanism and it's still measuring all of that with its existing control, it's going to fight you I''m sure.

Let's step back a bit, this might be an XY problem: what are you actually trying to achieve here?

If the printer (like a small Canon that I recently dismantled) has a cheap DC motor and a very finely printed encoder disc then I suspect it has some very expensive software to make it work properly. I think it would be a major challenge to trick it without screwing things up. Saving 50p on the hardware for 1,000,000 printers will pay for a lot of software.

Why do you want to slow the paper feed?

Have you considered changing the gearing between the motor and the encoder disk? But I suspect even that could foul things up because the speeds and accelerations are designed for the existing gearing.

...R

@Robin2 I want to make a DIY DTG printer, and the inertia of my structure is larger than a sheet of paper. With so once moved my structure will send the movement back to the printer.

Finally I did it, I was doing a few things wrong in my code.

Thanks all!

#define Y_ENCODER_PIN_A 2
#define Y_ENCODER_PIN_B 3
#define FAKE_Y_ENCODER_PIN_A 4
#define FAKE_Y_ENCODER_PIN_B 5

volatile int lastYEncoded = 0;
volatile long encoderYValue = 0;

long lastencoderYValue = 0;

int lastYMSB = 0;
int lastYLSB = 0;

void setup() {
  Serial.begin(9600);

  pinMode(Y_ENCODER_PIN_A, INPUT);
  pinMode(Y_ENCODER_PIN_B, INPUT);
  pinMode(FAKE_Y_ENCODER_PIN_A, OUTPUT);
  pinMode(FAKE_Y_ENCODER_PIN_B, OUTPUT);

  digitalWrite(Y_ENCODER_PIN_A, HIGH); //turn pullup resistor on
  digitalWrite(Y_ENCODER_PIN_B, HIGH); //turn pullup resistor on

  //call updateEncoder() when any high/low changed seen
  //on interrupt 0 (pin 2), or interrupt 1 (pin 3) 
  attachInterrupt(0, updateYEncoder, CHANGE);
  attachInterrupt(1, updateYEncoder, CHANGE);
}

void loop() {
  Serial.println(encoderYValue);
  delay(1000); //just here to slow down the output, and show it will work  even during a delay
}


void updateYEncoder() {
  int MSB = digitalRead(Y_ENCODER_PIN_A); //MSB = most significant bit
  int LSB = digitalRead(Y_ENCODER_PIN_B); //LSB = least significant bit

  int encoded = (MSB << 1) | LSB; //converting the 2 pin value to single number
  int sum  = (lastYEncoded << 2) | encoded; //adding it to the previous encoded value

  if(sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) {
    encoderYValue ++;
    // Move my motor.
  }
  if(sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011) {
    encoderYValue --;
    // Move my motor.
  }

  digitalWrite(FAKE_Y_ENCODER_PIN_A, MSB);
  digitalWrite(FAKE_Y_ENCODER_PIN_B, LSB);

  lastYEncoded = encoded; //store this value for next time
}

facine:
Finally I did it, I was doing a few things wrong in my code.

Great. Can you post a short video?

I suspect others would be interested if you have the time to describe the whole project.

...R

Robin2:

facine:
Finally I did it, I was doing a few things wrong in my code.

Great. Can you post a short video?

I suspect others would be interested if you have the time to describe the whole project.

...R

I will try to put a video next week.

Thanks!

Hello facine;

I hope you can put the video, to see the result, thanks

Video please

After almost 2 years with no video I think the OP has no intention to disclose the results of this project or he is still trying ...

Just in case others stumble upon this and want to know the answer.

You are basically wanting to read the Epson Printer encoder wheel with an Arduino to take that count and convert it into stepper motor steps. By doing this you can synchronize the motor step at a ratio to the encoder wheel movement and move a larger flat surface under the printhead to print on. Most of the time t-shirts.

I've posted full source code to do just that. The newest version is always here: http://www.opendtg.com/viewtopic.php?f=2&t=2

This could be adapted to any project where you need to read an encoder wheel and translate it into stepper steps at a ratio other than 1:1.

Hope this helps.