2

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.begin();
  oled.setFont(u8g2_font_ncenB10_tr);
  oled.clear();
  oled.setDrawColor(0xFF);
  oled.drawStr(45, 25, "Hello!"); oled.sendBuffer();
  delay (1000);
  pinMode(motorA1 , "OUTPUT") ;
  pinMode(motorA2 , "OUTPUT") ;
  Serial.begin(250000) ;
  oled.clearDisplay();
}

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.clearDisplay();
      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

Transistor
  • 168,990
  • 12
  • 186
  • 385
2012User
  • 135
  • 1
  • 7
  • 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. – DKNguyen Sep 19 '21 at 20:40
  • 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. – Transistor Sep 19 '21 at 20:44
  • @ Transistor actually I have a problem with my motor specification. I don't know encoder res and gear ratio. But it is a incremental. https://robotics.stackexchange.com/questions/22660/how-to-measure-an-optical-encoder-resolution-and-gear-ratio – 2012User Sep 19 '21 at 20:55
  • @ 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. – 2012User Sep 19 '21 at 20:59
  • @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? – jonk Sep 19 '21 at 21:02
  • I'd be thinking about powering my motor from someplace that's not the Arduino board. – Scott Seidman Sep 19 '21 at 21:04
  • @ jonk I need to upload a video to show what happens when motor runs. I get positive and negative random values. I didn't dare to use my hand when the motor is running I thought it can damage it. gear box doesn't prevent turning the shaft by hand when motor is off. – 2012User Sep 19 '21 at 21:08
  • @Scott Seidman I am using a 12v power supply for the motor. not the Arduino ! – 2012User Sep 19 '21 at 21:11
  • Tip: Use `@username` with no spaces or your ping will not be sent. – Transistor Sep 19 '21 at 21:46
  • I'm not familiar with the encoder library but does it keep track of encoder pulses while the main loop is busy doing other stuff? If not I would have thought you'd need to use interrupts. Maybe they're set up by the library with the `Encoder myEncoder(2, 3);` command. – Transistor Sep 19 '21 at 22:01
  • Since you stated that the encoder seems to be working as expected without the motor being enabled it looks like a noise issue. Consider separating the encoder GND (black in your sketch) as much as possible from the L298N board GND connection. Try different GND arduino pin if possible. Decoupling capacitor between the DND and encoder power (red) is also worth trying. – Martin Vana Sep 19 '21 at 22:18
  • @Transistor the library suggests use A,B on interrupt pins for best results. It says using other pins is possible but we may not get the best. About keeping track of pulses, a good point. But it does when the motor is off! – 2012User Sep 19 '21 at 22:25
  • @2012User If you're a mechanical engineer, you probably work with or near electrical engineers; see if someone can let you use a scope. It would help figure out what's going on here. Or, if you plan on doing much more electrical stuff and you can spare about $400, get a scope of your own--it's an essential tool and much more affordable these days than they used to be. Hell, search around on ebay for a bit and you might get a used analog scope for like $50 even. – Hearth Sep 20 '21 at 00:37
  • @Hearth unfortunately I live in Iran. We have the least valued currency in the world and a lot of sanctions because we have a terrorist government. 400$ is equal to my 2-3 months salary. I have to ask my friends to borrow one. :( – 2012User Sep 20 '21 at 06:32
  • @2012User It is very generous of you to mention Iran as your location. I mean that in a very good way. Thanks. So things are difficult with respect to just sending out USD for some product. If I were nearby, I'd just drop over and help. Sadly, I'm pretty much on the opposite side of the Earth. But my question wasn't about a *powered* motor. I was asking you if, unpowered in the same circumstances you said as "turning shaft with hand when the motor is off", you could jiggle it around and cause any errors at all. Does it always work perfectly unpowered? Or can you make it fail, in some way? – jonk Sep 20 '21 at 09:29
  • @jonk I tried again. When it is unpowered, encoder works fine. – 2012User Sep 20 '21 at 10:19
  • @2012User Ah, that does make things more complicated then. Sorry! Your answer to jonk's question is rather enlightening, however--it sounds to me like you're almost certainly dealing with noise introduced by the motor itself. – Hearth Sep 20 '21 at 12:29
  • @Hearth how should I use 100nf capacitors? one side to GND and other side to encoder pins or... I have no idea!!! Please help me out. – 2012User Sep 20 '21 at 20:33
  • *that*, I'm afraid, is a little hard to answer without knowing how your setup works, but putting it between ground and the encoder output would be a good first try. One cap for each encoder output, specifically, both going to ground. – Hearth Sep 20 '21 at 23:43
  • @Hearth I tried 100nf caps parallel to encoder A,B. Didn't work. I still get random values but they don't change much when motor is running. I also put caps on motor control wires, nothing happened. – 2012User Sep 21 '21 at 18:34
  • @Transistor I changed the motor (a NF5475E ). Still the same problem exists. So the problem should be the Arduino or the code I've written. – 2012User Sep 22 '21 at 08:41

1 Answers1

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

2012User
  • 135
  • 1
  • 7