Go Down

Topic: Interference from Stepper Driver (Read 435 times) previous topic - next topic

devspacito

Hi. I'm trying to solve a problem with my setup.

What I have are:
A3967 V4.4 EasyDriver Stepper Motor driver
NEMA 17 stepper motor
I2c LCD
4x4 keypad membrane

The modules are all working fine except for the random Keypad read that occurs whenever the stepper driver is turned on (even without having to drive the stepper motor).

I dont have the connections/code rn but rest assured that all of it are correct. Worth noting is that the stepper driver is powered by a 12v psu while the arduino is powered through its usb 5v port. All components are connected directly to arduino mega through a mega expansion board shield using male/female etc wires.

Also worth noting is that the "random" reads doesn't occur when I disconnect the digital signal pins for the stepper driver. My guess is that interference occur within the driver which affects the inputs in my mcu.

Thank you in advance

TheMemberFormerlyKnownAsAWOL

#1
Feb 26, 2020, 05:22 pm Last Edit: Feb 26, 2020, 05:23 pm by TheMemberFormerlyKnownAsAWOL
Well, I for one will rest assured.

Your code and connections may be correct, but perhaps they're incomplete or inadequate.
Please don't PM technical questions - post them on the forum, then everyone benefits/suffers equally

Robin2

I dont have the connections/code rn but rest assured that all of it are correct.
We have heard that many times before.

Just post your program and a photo of a simple pencil drawing showing how YOU have everything connected.

A photo of your project would also be useful in case the problem is due to cross-talk between wires. NOTE that this photo is not a substitute for the drawing of the connections.

...R
Simple Image Posting Guide

Stepper Motor Basics
Simple Stepper Code
Two or three hours spent thinking and reading documentation solves most programming problems.

devspacito

#3
Feb 27, 2020, 06:49 am Last Edit: Feb 27, 2020, 06:55 am by Devspacito
The code doesn't look very professional and there are still some fixing to function properly. Anyways the main concern is the interference part occurs when the motor driver is powered.




Code: [Select]


#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,16,2);

#include <Keypad.h>

const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
//define the cymbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = {2, 3, 4, 5}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {6, 7, 8, 9}; //connect to the column pinouts of the keypad

//initialize an instance of class NewKeypad
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);

bool flagVal1 = 0, flagVal2 = 0;
int val1 = 0; //VTBI Temp name
int val2 = 0;
int val3 = 0; //rename later on
//LCD Menu Logic
const int numOfScreens = 3;
int currentScreen = 0;
String screens[numOfScreens]= {{"VTBI INPUT"}, {"Drop something man"},
{"Press X to Stop"}};

void setup() {
  Serial.begin(9600);
  lcd.init();                      // initialize the lcd
  lcd.init();
  lcd.backlight();
}

void loop() {
  vtbiCheck();
  dripChk();
  if(flagVal1==1&&flagVal2==1){
    char c;
    Serial.println("wew");
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print(screens[2]);
    lcd.setCursor(0,1);
    lcd.print("Drop Rate"); //display yung value na needed
    do{
      c = customKeypad.getKey();
      }while(c!='C');
    }
}

void vtbiCheck(){
  char c;
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(screens[0]);
  do{
    c = customKeypad.getKey();
    if(c=='*'||c=='#'){
      Serial.println("invalid input");
      clearLine(0,1);
      lcd.setCursor(2,1);
      lcd.print("INVALID INPUT");
      delay(1500);
      clearLine(0,1);
      }
     else if(c=='A'){
      //increment ml
      val1 = val1 + 100;
      clearLine(0,1);
      lcd.print(val1); // print line here
      lcd.print(" ml");
      Serial.println("hey");
      }
      else if (c=='B'){
      //decrement value of ml
      val1 = val1 - 100;
      clearLine(0,1);
      lcd.print(val1);
      lcd.print(" ml");
      Serial.println("hey1");
      }
      else if(c=='D'||c=='C'){
        break;
        }
      else{
      //output value of ml
      if(c!=NO_KEY){
        val1 = c - '0';
        val1 = val1*100;
        clearLine(0,1);
        lcd.print(val1);
        lcd.print(" ml");
        Serial.println("hey2");
        }
      }
    }while(true);

    if(c=='C'){
      flagVal1 = 0;
      val1 = 0;
      Serial.println("Cancelled");
      }
    if(val1<=0||val1>1000){
      flagVal1 = 0;
      Serial.println("Out of bounds");
      }
    else{
      flagVal1 = 1;
      Serial.println("Success");
      }
}

void dripChk(){
  char c;
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(screens[1]);
  do{
    c = customKeypad.getKey();
    if(c=='*'||c=='#'||c=='6'||c=='7'||c=='8'||c=='9'||c=='0'){
      Serial.println("invalid input");
      clearLine(0,1);
      lcd.setCursor(2,1);
      lcd.print("INVALID INPUT");
      delay(1500);
      clearLine(0,1);
      }
     else if(c=='A'){
      //increment ml
      val2 = val2 + 40;
      clearLine(0,1);
      lcd.print(val2); // print line here
      lcd.print(" drops/hr"); //recheck
      Serial.println("hey");
      }
      else if (c=='B'){
      //decrement value of ml
      val2 = val2 - 40;
      clearLine(0,1);
      lcd.print(val2);
      lcd.print(" drops/hr"); //check
      Serial.println("hey1"); //all serial prints for checking only
      }
      else if(c=='D'||c=='C'){
        break;
        }
      else{
      //output value of ml
      if(c!=NO_KEY){
        val2 = c - '0';
        val2 = val2*40;
        clearLine(0,1);
        lcd.print(val2);
        lcd.print(" drops/hr");
        Serial.println("hey2");
        }
      }
    }while(true);

    if(c=='C'){
      flagVal2 = 0;
      val2 = 0;
      Serial.println("Cancelled");
      }
    if(val2<=0||val1>200){
      flagVal2 = 0;
      Serial.println("Out of bounds");
      }
    else{
      flagVal2 = 2;
      Serial.println("Success");
      }
}

void pump(){
//stepper
}

void clearLine(int a, int b){
  lcd.setCursor(a,b);
  lcd.print("                ");
  lcd.setCursor(2,1);
}



The code is not the current version that I am using bc its with my classmate but Im telling you, the connections and the code is fine. The project is already functioning well since all codes are direct copies from the library.

The only problem is the random keypad reads (which is connected at pins 22-29) whenever the stepper driver is powered. We've originally used a tb6600 stepper driver but the manual dip switch control for the microstepping is a problem. Originally, the random key problem doesn't occur since (from what Ive searched) the tb6600 is isolated with optocouplers.

Ive searched ground loops interference, power supply coupling and etc etc but none has worked for me so far. I twisted the wires of the stepper motor in pair, placed some variety of capacitor to the 12v supply (i tried series, parallel).

If anyone asks, I'm making an Infusion pump.

And yes, my sketch didn't help i know. Lastly, please bare my english.

Robin2

#4
Feb 27, 2020, 10:03 am Last Edit: Feb 27, 2020, 10:04 am by Robin2
Images from Reply #3 so we don't have to download them. I already gave you a link to the instructions for this.





...R
Two or three hours spent thinking and reading documentation solves most programming problems.

Robin2

You need to make a much more detailed connection diagram showing all the wires and with all the pins labelled so we can tell if there is a wiring error.

Code: [Select]
The code is not the current version that I am using
Then wait until you have the latest version before posting. It's a complete waste of time looking at yesterday's code.


Help us to help you.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

devspacito

#6
Feb 29, 2020, 09:45 am Last Edit: Feb 29, 2020, 10:35 am by Devspacito
Hello again. I finally met with my classmates and had a better shot for the connections.

Anyways, the current code we are using is this one

Code: [Select]


#define xbeeCon; Serial1
#define airPin A2
#include <AH_EasyDriver.h>

//AH_EasyDriver(int RES, int DIR, int STEP, int MS1, int MS2, int SLP);
AH_EasyDriver stepper(200,4,5,2,6,3);    // init w/o "enable" and "reset" functions

const int lockPump = 9;


#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,16,2);

#include <Keypad.h>

const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
//define the cymbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = {29, 28, 27, 26}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {25, 24, 23, 22}; //connect to the column pinouts of the keypad

//initialize an instance of class NewKeypad
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);

bool flagVal1 = false, flagVal2 = false;
int val1 = 1; //VTBI Temp name
int val2 = 0;
int val3 = 0; //rename later on
//LCD Menu Logic
String screens[4]= {{"VTBI Input"}, {"Rate ml/hr Input"}, {"Press -> to Start"},
{"Press X to Stop"}};

unsigned long startTime, flowTime, totTime, delayTime;


//#include "hx711.h"
//Hx711 scale(A1, A0);

void setup() {
  Serial.begin(9600);
  lcd.init();                      // initialize the lcd
  lcd.init();
  lcd.backlight();

  xbeeCon.begin(9600);
  //pinMode(rst_pin, OUTPUT);
  //digitalWrite(rst_pin,HIGH);
  xbeeCon.println("Hello XBEE GENSAN");
  delay(50);

  pinMode (lockPump, INPUT);
  pinMode(airPin, INPUT);
  stepper.sleepOFF();

}

void loop() {
  vtbiCheck();
  dripChk();
  if(flagVal1==1&&flagVal2==1){
    char c;
    lcd.setCursor(0,0);
    lcd.print("Press > to Start"); //display yung value na needed
    while(customKeypad.getKey()!='D'){}
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print(screens[3]);
    startTime = millis();
    do{
      pumpGo();
      Serial.println("wew");
      if(airCheck()){
        Serial.println("www");
        pumpStop();
        flowTime = millis() - startTime;
        //startTime = startTime + millis();
        totTime = totTime - flowTime;
        transmitXbee(1);
        //while(customKeypad.getKey()!='D'){
        //}  
      }
      
      if(loadCheck()){
        pumpStop();
        Serial.println("load");
        flowTime = millis() - startTime;
       // startTime = startTime + millis();
        totTime = totTime - flowTime;
        transmitXbee(2);
        //while(customKeypad.getKey()!='D'){
        //}  
      }
      
      delayTime = millis();
      /*do{
        if(customKeypad.getKey()){
          c = customKeypad.getKey();
          }
        Serial.println(c);
        }while(millis()-delayTime<1000);*/
      Serial.println(millis()-startTime);  
      }while(c!='C'&&(millis()-startTime<5000));
    }
}

void vtbiCheck(){
  char c;
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(screens[0]);
  do{
    c = customKeypad.getKey();
    if(c=='*'||c=='#'||c=='0'){
      clearLine(0,1);
      lcd.setCursor(2,1);
      lcd.print("INVALID INPUT");
      delay(500);
      clearLine(0,1);
      val1 = 0;
      }
     else if(c=='A'){
      //increment ml
      val1 = val1 + 100;
      clearLine(0,1);
      lcd.print(val1); // print line here
      lcd.print(" ml");
      }
      else if (c=='B'){
      //decrement value of ml
      val1 = val1 - 100;
      clearLine(0,1);
      lcd.print(val1);
      lcd.print(" ml");
      }
      else if(c=='D'||c=='C'){
        break;
        }
      else{
      //output value of ml
      if(c!=NO_KEY){
        val1 = c - '0';
        val1 = val1*100;
        clearLine(0,1);
        lcd.print(val1);
        lcd.print(" ml");
        }
      }
    }while(true);

    if(c=='C'){
      flagVal1 = false;
      val1 = 0;
      }
    if(val1<=0||val1>1000){
      flagVal1 = false;
      }
    else{
      flagVal1 = true;
      }
}

void dripChk(){
  char c;
  int temp = 1;
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(screens[1]);
  clearLine(0,1);
  lcd.print("5 drop(s)/min");
  do{
    c = customKeypad.getKey();
    if(c==NO_KEY){
       //No input
      }
    else if(c=='A'){
      //increment ml
      if(temp==1){
        temp = 10;
        val2 = temp*4;
        clearLine(0,1);
        lcd.print(val2); // print line here
        lcd.print(" drop(s)/min"); //recheck
        }
      else{
        temp = temp + 5;
        val2 = temp*4;
        clearLine(0,1);
        lcd.print(val2); // print line here
        lcd.print(" ml/hr"); //recheck
        }
      }
      else if (c=='B'){
      //decrement value of ml
        if(temp==10){
        temp = 1;
        val2 = 5;
        clearLine(0,1);
        lcd.print(val2); // print line here
        lcd.print(" drop(s)/min"); //recheck
        }
        else{
        temp = temp - 5;
        val2 = temp*4;
        clearLine(0,1);
        lcd.print(val2); // print line here
        lcd.print(" drop(s)/min"); //recheck
        }
      }
      else if(c=='D'||c=='C'){
        break;
        }
      else{
        clearLine(0,1);
        lcd.setCursor(2,1);
        lcd.print("INVALID INPUT");
        delay(500);
        clearLine(0,1);
      }
    }while(true);

    if(c=='C'){
      flagVal2 = false;
      val2 = 0;
      }
    else{
      if(temp==1){
        val2 = 5;
        clearLine(0,1);
        flagVal2 = true;
        Serial.println("TEMP 1");
        }
      if(val2<=0||val1>200){
        flagVal2 = false;
        Serial.println("TEMP 2");
        }
        
      else{
        val2 = temp;
        clearLine(0,1);
        flagVal2 = true;
        Serial.println("TEMP 3");
        }
      }
      //final checking
    
}

void pumpGo(){
    stepper.setSpeedRPM(60);
    stepper.setMicrostepping(3);
    stepper.rotate(360);
}

void clearLine(int a, int b){
  lcd.setCursor(a,b);
  lcd.print("                ");
  lcd.setCursor(1,1);
}

bool airCheck(){
  if(analogRead(airPin)==0){
    return true;
    }
  return false;
}

bool loadCheck(){
/*  if((scale.getGram(),1)<=.15*val1);{
    return true;
    }
  return false; */
}

void pumpStop(){
    stepper.setMicrostepping(0);
    while(digitalRead(lockPump)){
    stepper.setSpeedRPM(60);
    stepper.rotate(1);
    }  
}

void transmitXbee(int state){
  switch(state){
    case 1:
      xbeeCon.println("A,"); //sa java GUI nyo pag A nareceive display air occlusion
      //long a = (scale.getGram());
      //xbeeCon.print(a); // current level na natitira
      xbeeCon.print(",")
      xbeeCon.println("computed time...."); //time remaining  may calculations pa to
    break;
    case 2:
      xbeeCon.print("W,"); //sa java GUI nyo pag B nareceive display 15% chuchu
//      a = (scale.getGram());
     // xbeeCon.print(a); // current level na natitira
      xbeeCon.print(",")
      xbeeCon.println("computed time...."); //time remaining  may calculations pa to
      /*  comma-separated value
       *   example ng sent data
       *   W,800,3600
       *   sa java code mo na i interpret ang data
       *   tapos istore nyo sa .csv file para malog nyo
       *   1,X,kg,min
       */
    break;
    }
}


In the line
AH_EasyDriver stepper(200,4,5,2,6,3);



Pins are connect as follows.
Dir -- pin 4
Step -- pin 5
Ms1 -- pin 2
Ms2 -- pin 6
Slp -- pin 3
Gnd --  Gnd

This is the picture showing how a wider perspective with other modules.

I also have other things connected such as capacitive sensor and microswitch.

gcjr

i had an I2C problem when i ran motors.     i used an I2C expander to control some low current motors.  it worked reliably w/o the motors connected.

i fixed the problem by adding pull-up resistors to the I2C clk and data lines
greg - somerset, nj
seeing well written code is the best way to learn to write well written code.

TomGeorge

i had an I2C problem when i ran motors.     i used an I2C expander to control some low current motors.  it worked reliably w/o the motors connected.

i fixed the problem by adding pull-up resistors to the I2C clk and data lines

This where you should have presented us with a proper schematic so we could see how you connected everything.
A picture does not show the two resistors missing, a proper schematic would have.
Can I suggest you draw a schematic for your own reference.
Tom... :)
Everything runs on smoke, let the smoke out, it stops running....

devspacito

i fixed the problem by adding pull-up resistors to the I2C clk and data lines
Hello user gcjr!! I tried adding a 12k pull_up resistor to each keypad inputs and somehow reduced the random inputs slightly. I've studied the keypad library and saw some internal pullup definition within the code but I'm not sure how the code works to be honest.

This where you should have presented us with a proper schematic so we could see how you connected everything.
Hi Tom! You quoted another person's comment so I'm not entirely sure hownto respond. Anyways, I still did the pullup thingy to no avail.

///

I studied the tb6600 diagram and learned that all signal pins of the driver are optically isolated from the arduino board. As stated before, we've used it previously but faced problems with the microstepping control since it required a manual switching of the dipswitch in the driver. In this connection, can anyone tell me how a stepper driver ic works? Does the ic generate some strong stray noise when powered? Does anyone have any experience in properly adding an optocoupler to a module before I waste my resource trying. Thank you


TomGeorge

Hi,
Have you  got the Arduino gnd connected to the stepper power supply gnd.

Please a proper detailed circuit diagram.

Keep your stepper motor and powersupply wires away from the Arduino wires as much as possible.

If you disconnect the stepper, does the fault still happen

Thanks.. Tom.. :)
Everything runs on smoke, let the smoke out, it stops running....

devspacito

Hi,
Have you  got the Arduino gnd connected to the stepper power supply gnd.

If you disconnect the stepper, does the fault still happen

Thanks.. Tom.. :)
1. Yes. It's through the arduino GND -- Stepper Driver GND

2. No.

Anyhow, we managed to solve the problem by using a linear 12v power supply, the psu we were using before were generic 12v switching power supplies. We were on the verge of ordering 6n137 optocouplers to isolate the circuit. To those who will someday find this thread, make sure to isolate the driver from the arduino (with optocoupler ckt/breakout boards), suppress ground loop interference by properly adding the required components (search power supply decoupling) and lastly try powering your driver with a battery cell/linear psu.

Thanks

Go Up