I have a DC geared motor with an optical encoder. I can read MITSUMI M25N-2R-14 2241 and 25GA-370-12V-330RPM on the motor. I'm using this simple code to control the position of shaft. it works fine when I test it manually (turning shaft with hand when the motor is off) but when the motor is running by a L298N driver it shows random pulses on my output LCD so position control is impossible. What is wrong? Is there a noise source?

I'm using an Adruino Uno. 2,3 pins for 5v encoder, 6,7 pin for controlling the motor. Ground pin is connected to driver's GND.

#include <Wire.h>
#include <U8g2lib.h>
#include <LiquidCrystal_I2C.h>
#include <Encoder.h>
int motorA1 = 7 ;
int motorA2 = 6 ;
String Position, input;
int newPosition = 0; int Input = 0; long pulse2go;
LiquidCrystal_I2C lcd(0x3F, 20, 4); // Set the LCD address to 0x27 for a 16 chars and 2 line display
U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C oled(U8G2_R0, A5, A4, U8X8_PIN_NONE);

Encoder myEncoder(2, 3);

void setup() {
  oled.setI2CAddress(0x78);// 0x3C);
  oled.drawStr(45, 25, "Hello!"); oled.sendBuffer();
  delay (1000);
  pinMode(motorA1 , "OUTPUT") ;
  pinMode(motorA2 , "OUTPUT") ;
  Serial.begin(250000) ;

void loop() {
  if (Serial.available()) {
    input = Serial.readString();
    input.remove(0, 1);
    Input = input.toInt();
    pulse2go = Input - newPosition;

    while (abs(pulse2go) > 300) {
      if (pulse2go > 0) {
        digitalWrite(motorA1 , LOW)  ;
        analogWrite(motorA2 , 75)   ;
      if (pulse2go < 0) {
        digitalWrite(motorA1 , HIGH) ;
        analogWrite(motorA2 , 75)  ;
      newPosition = myEncoder.read() ;  Position = String(newPosition);
      oled.drawStr(3, 15, "Position");       oled.sendBuffer();
      oled.drawStr(3, 30, Position.c_str()); oled.sendBuffer();
      oled.drawStr(75, 15, "Input");       oled.sendBuffer();
      oled.drawStr(75, 30, input.c_str()); oled.sendBuffer();

enter image description here

enter image description here

  • \$\begingroup\$ Scope the encoder output. Or assume noise and add schmitt triggers. You probably want to add a 100nF decoupling cap close to the encoder too. \$\endgroup\$
    – DKNguyen
    Commented Sep 19, 2021 at 20:40
  • \$\begingroup\$ It wouldn't hurt to edit in a link to the encoder datasheet and mention whether it's incremental or absolute. newPosition = myEncoder.read() ; suggests that it's an absolute encoder. \$\endgroup\$
    – Transistor
    Commented Sep 19, 2021 at 20:44
  • \$\begingroup\$ @ Transistor actually I have a problem with my motor specification. I don't know encoder res and gear ratio. But it is a incremental. robotics.stackexchange.com/questions/22660/… \$\endgroup\$
    – 2012User
    Commented Sep 19, 2021 at 20:55
  • \$\begingroup\$ @ DKNguyen I don't have an oscilloscope. I'm a mechanical engineer and I had never of schmitt triggers. I just know capacitors are used for noise cancelling. I don't know how! pls explain more about 100nf cap. \$\endgroup\$
    – 2012User
    Commented Sep 19, 2021 at 20:59
  • \$\begingroup\$ @2012User Another problem (besides a lack of information about what happens when the motor runs) is that you are using an encoder library. Assuming you didn't write it, then you don't really know its specifications either. So there is a lot of exploration yet to do, I fear. That said, I'm very glad to hear that you tried it out using your hand and got good results. Can you try to use your hand and confuse it? Or does the gearbox prevent good additional testing this way? \$\endgroup\$
    – jonk
    Commented Sep 19, 2021 at 21:02

1 Answer 1


Using optocoupler solved the problem. I used a different power supply for 5v encoder. Circuits are isolated completely and there is no sign of disturbance.

enter image description here


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.