2
\$\begingroup\$

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

\$\endgroup\$
21
  • \$\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\$ 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\$ 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\$ 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\$ 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\$ Commented Sep 19, 2021 at 21:02

1 Answer 1

1
\$\begingroup\$

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

\$\endgroup\$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.