Notifications
Clear all

Arduino with Stepper and LiquidCrystal Issue

Page 1 / 21

Voltage
(@voltage)
Estimable Member
Joined: 2 months ago
Posts: 160
Topic starter  

I am trying to track down a problem with a rhythmical but not cyclical thunk noise in my Nema 23 stepper and I may have gotten as close as ever to figuring it out. But...I am still a noob and didn't write the original code so I need some help please. There is a const long interval = 1000; that if I change its value higher I can change the amount of thunks or clunks per revolution on the output which is a 4.25:1 geared stepper. Normally after setting the required stepper rpms (less reduction) to what I need for the final result (30-36 rpms), if I run it at any speed I get the thunking noise about 4 times per revolution but not in the same place on each revolution. I can hear and feel it. So after trying everything I could with different micro-stepping values etc I decided to change the const long interval = 1000; to lower number and the stepper would not run, so I went with a higher number and the thunking lessened. I went even higher and it lessened even more like one thunk per 4 revolutions etc. I will post the code to see if anybody can spot any issues. The const long interval only shows up at the bottom of the code one time.

#include <Stepper.h>
#include <LiquidCrystal.h>

// set this to the microstep value on the stepper driver
const int stepsPerRevolution = 400;
int dim=stepsPerRevolution;

LiquidCrystal lcd(8,9,4,5,6,7);
// Define our three input button pins
#define LEFT_PIN 11
#define STOP_PIN 1
#define RIGHT_PIN 0

Stepper myStepper(stepsPerRevolution, 2, 3);

int stepCount = 0;

unsigned long previousMillis = 0;

const long interval = 1000;

void setup() {
// Set up the three button inputs, with pullups
pinMode(LEFT_PIN, INPUT_PULLUP);
pinMode(STOP_PIN, INPUT_PULLUP);
pinMode(RIGHT_PIN, INPUT_PULLUP);
lcd.begin(16, 2);
lcd.setCursor(1,0);
lcd.print("Speed:");
lcd.setCursor(12,0);
lcd.print("RPM");
Serial.begin(9600);
}

void loop() {

static char sign = 0;

if (digitalRead(LEFT_PIN) == 0) {
sign = 1;
}
else if (digitalRead(RIGHT_PIN) == 0) {
sign = -1;
}
else if (digitalRead(STOP_PIN) == 0) {
sign = 0;
}

// read the sensor value:
int sensorReading = analogRead(A1);
// map it to a range from 0 to 120:
int motorSpeed = map(sensorReading, 0, 1023, 0, 3600);
// set the motor speed:
if (motorSpeed > 0) {
myStepper.setSpeed(motorSpeed);

myStepper.step(sign*stepsPerRevolution / 100);

unsigned long currentMillis = millis();

if (currentMillis - previousMillis >= interval) {

previousMillis = currentMillis;

lcd.setCursor(7,0);
lcd.print(float(float(motorSpeed)/float(12)),1);
}
}
}

Thanks,
Voltage


Quote
Voltage
(@voltage)
Estimable Member
Joined: 2 months ago
Posts: 160
Topic starter  

After further disecting the sketch it leads me to the millis() so I am on the right track I think... 😀 

https://www.arduino.cc/reference/en/language/functions/time/millis/

Thanks,
Voltage


ReplyQuote
Voltage
(@voltage)
Estimable Member
Joined: 2 months ago
Posts: 160
Topic starter  

Ok, so it definitely has to do with the LCD Shield. If I change the const long interval = 1000; to 300 it thumps a whole lot more times in rapid succession. If I set it to 10,000 it makes one thump at every 4th rpm at the gearbox or 4 times more of whatever the actual stepper rpm is. If I change it to 100,000 the problem is solved except now I have no readout on the LCD RPM output screen. So I guess the code for the LCD screen is interrupting the Stepper driver code. Well, I am getting somewhere...

edit: The LCD output I can likely fix with manipulation of the code for the LCD as I changed those other numbers to match my geared stepper. But before I worry with that I will wait to see if I am on the right track and the best way to fix it.

 

Thanks,
Voltage


ReplyQuote
robotBuilder
(@robotbuilder)
Prominent Member
Joined: 2 years ago
Posts: 883
 

If you are using the Arduino IDE and want to retain indents and color coding.

Right mouse click on Arduino IDE source code, Select All.
Right mouse click again, Copy as HTML.

On the forum post hit the Enter key a few times to make room to insert the source code and then click {:} in the top bar. Right mouse click between a <p></p> pair and Paste.

 

 

#include <Stepper.h>
#include <LiquidCrystal.h>

// set this to the microstep value on the stepper driver
const int stepsPerRevolution = 400; 
int dim=stepsPerRevolution;

LiquidCrystal lcd(8,9,4,5,6,7);
// Define our three input button pins
#define LEFT_PIN 11
#define STOP_PIN 1
#define RIGHT_PIN 0

Stepper myStepper(stepsPerRevolution, 2, 3);

int stepCount = 0;

unsigned long previousMillis = 0;

const long interval = 1000;

void setup() {
  // Set up the three button inputs, with pullups
  pinMode(LEFT_PIN, INPUT_PULLUP);
  pinMode(STOP_PIN, INPUT_PULLUP);
  pinMode(RIGHT_PIN, INPUT_PULLUP);
  lcd.begin(16, 2);
  lcd.setCursor(1,0);
  lcd.print("Speed:");
  lcd.setCursor(12,0);
  lcd.print("RPM");
  Serial.begin(9600);
}

void loop() {

  static char sign = 0;

  if (digitalRead(LEFT_PIN) == 0) {
    sign = 1;
  }
  else if (digitalRead(RIGHT_PIN) == 0) { 
    sign = -1;
  }
  else if (digitalRead(STOP_PIN) == 0) {
    sign = 0;
  }

  // read the sensor value:
  int sensorReading = analogRead(A1);
  // map it to a range from 0 to 120:
  int motorSpeed = map(sensorReading, 0, 1023, 0, 3600);
  // set the motor speed:
  if (motorSpeed > 0) {
    myStepper.setSpeed(motorSpeed);

    myStepper.step(sign*stepsPerRevolution / 100);

    unsigned long currentMillis = millis();

    if (currentMillis - previousMillis >= interval) {

      previousMillis = currentMillis;

      lcd.setCursor(7,0);
      lcd.print(float(float(motorSpeed)/float(12)),1);
    }
  }
}

 

 


Voltage liked
ReplyQuote
MadMisha
(@madmisha)
Reputable Member
Joined: 2 years ago
Posts: 319
 

@voltage

Random guess: Voltage problem? Maybe when the screen updates it's consuming enough power to affect the motors?

 

You might also think about making a variable at the top for motorSpeed and updating it in the loop. Sensor reading can go directly into the map function. Creating a new unsigned long every time it goes through the loop can cause issues over time. I am not sure how it affects the controller in Arduino but I know in other languages like Python, it has to create a new space in memory every time and can eventually lead to leakage. That is not always the case but it's good practice, particularly in small loops. Millis can go directly in the If statement as well.

 

Also, that last statement you can get rid of the first float. You are converting a float to a float at that point.


Voltage liked
ReplyQuote
Will
 Will
(@will)
Reputable Member
Joined: 3 months ago
Posts: 368
 

@voltage

Try using pins other than 1 and 0 for your stop and right buttons they're used for tx/rx for serial communications and loading sketches.

Also, you have defined stepCount but never use it.


Voltage liked
ReplyQuote
Voltage
(@voltage)
Estimable Member
Joined: 2 months ago
Posts: 160
Topic starter  

@robotbuilder

Thanks for the code pasting tip. Actually I am working on the project with a Mint based Linux OS on a laptop in the other room. I am quite new to Linux. The code I have a copy of on my Win10 PC here. But your tip is still useful. 😋 

Thanks,
Voltage


ReplyQuote
Voltage
(@voltage)
Estimable Member
Joined: 2 months ago
Posts: 160
Topic starter  
Posted by: @madmisha

@voltage

Random guess: Voltage problem? Maybe when the screen updates it's consuming enough power to affect the motors?

 

You might also think about making a variable at the top for motorSpeed and updating it in the loop. Sensor reading can go directly into the map function. Creating a new unsigned long every time it goes through the loop can cause issues over time. I am not sure how it affects the controller in Arduino but I know in other languages like Python, it has to create a new space in memory every time and can eventually lead to leakage. That is not always the case but it's good practice, particularly in small loops. Millis can go directly in the If statement as well.

 

Also, that last statement you can get rid of the first float. You are converting a float to a float at that point.

I don't think it's a voltage issue as I am using a new Meanwell 36V 9.2A supply for the stepper and driver, and I have a wall wart plugged into the UNO. Thanks for the suggestions above. I didn't write the original code but have modified mainly numbers in it. But for some more added info, with the:

const long interval = 10000;

 

I can dial it in with the proper RPMs with only a small interruption after about 10 revolutions but the display takes about 5 seconds to show the RPMs. I could live with that but when I change it to:

const long interval = 100000;

The display never updates or takes too long I didn't bother waiting. I will try to adjust per your recommendations and see how it goes. It may be tomorrow before I reply back as I already put the project away for today.

Thanks,
Voltage


ReplyQuote
Voltage
(@voltage)
Estimable Member
Joined: 2 months ago
Posts: 160
Topic starter  
Posted by: @will

@voltage

Try using pins other than 1 and 0 for your stop and right buttons they're used for tx/rx for serial communications and loading sketches.

Also, you have defined stepCount but never use it.

Thanks for the info. The code came with a project to build something so I didn't write it. I am also new to Arduino and C coding for the most part. But I used to code in VB so I have no excuse but to keep learning as I go. A variable is a variable. 😎 

 

Thanks,
Voltage


ReplyQuote
MadMisha
(@madmisha)
Reputable Member
Joined: 2 years ago
Posts: 319
 
Posted by: @voltage

I have a wall wart plugged into the UNO.

7-12V? Just making sure.

 

You could try commenting out the screen altogether to confirm and see how that goes.

 

I did notice that the screen is using an odd configuration for the pins. It might not matter but I usually see different pins used in most examples. It might be coincidence or they are just copying each other.

 

It might be helpful if we knew how it is wired and what controller you are using.


ReplyQuote
Voltage
(@voltage)
Estimable Member
Joined: 2 months ago
Posts: 160
Topic starter  
Posted by: @madmisha
Posted by: @voltage

I have a wall wart plugged into the UNO.

7-12V? Just making sure.

 

You could try commenting out the screen altogether to confirm and see how that goes.

 

I did notice that the screen is using an odd configuration for the pins. It might not matter but I usually see different pins used in most examples. It might be coincidence or they are just copying each other.

 

It might be helpful if we knew how it is wired and what controller you are using.

9V wall wart. Putting in that delay of 100,000 seems to fix it (the thumping) but renders the display useless. I will comment it out as another test. Like I said, I didn't write the code and the guy that did was probably just learning with cut and past from other examples. I will see if I can quickly draw up a Fritzing image cause I hate to post something from plans I purchased and I am not suppose to share. The image in the plans is very blurry. Or maybe I can just explain my wiring. I have an Arduino UNO, a Screw Shield, and a 1602 LCD Shield, a DM542T Driver and 36V PS 9.2A, and a 2.8A stepper Nema 23 with 4.25:1 Gearhead. The plans have the Arduino wired as follows:

Potentiometer Pin 1 to GRD, Pin 2 to Pin A1, Pin 3 to +5V

Button 1 (Right) to GRD and Pin RX (UNO)

Button 2  (Stop) to GRD and Pin TX (UNO)

Button 3 (Left) to GRD and Pin 11 (UNO)

The stepper is properly wired to DM542T

The PUL - (PUL) is connected to Pin D2 (UNO)

The DIR - (DIR) is connected to Pin D3 (UNO)

The PUL + (+5V) is connected to +5V (UNO)

The DIR + (+5V) is connected to +5V (UNO)

Is that enough info?

 

Thanks,
Voltage


ReplyQuote
Will
 Will
(@will)
Reputable Member
Joined: 3 months ago
Posts: 368
 
Posted by: @voltage

Putting in that delay of 100,000 seems to fix it (the thumping) but renders the display useless. I will comment it out as another test.

It really sounds as if the "thumping" is caused by the motor jerking into full or no motion. The reason that the frequency changes is that with your interval at 10,000 it'll take about 10 seconds for it to have to pause while it updates the LCD. When your interval is 100,000, then it'll take about 100 seconds between start/stop cycles and it seems that you've not let it run long enough for the 100 seconds to elapse before the screen updates.

Seems like the LCD update is taking long enough to interrupt the inertia of the stepper.

Are you using the same stepper/driver combo as the person from you bought this ?


ReplyQuote
Voltage
(@voltage)
Estimable Member
Joined: 2 months ago
Posts: 160
Topic starter  

 

#include <Stepper.h>
#include <LiquidCrystal.h>

// set this to the microstep value on the stepper driver
const int stepsPerRevolution = 400;
int dim=stepsPerRevolution;

LiquidCrystal lcd(8,9,4,5,6,7);
// Define our three input button pins
#define  LEFT_PIN  11
#define  STOP_PIN  1
#define  RIGHT_PIN 0

Stepper myStepper(stepsPerRevolution, 2, 3);

int stepCount = 0;  

unsigned long previousMillis = 0;        

const long interval = 10000;           

void setup() {
  // Set up the three button inputs, with pullups
  pinMode(LEFT_PIN, INPUT_PULLUP);
  pinMode(STOP_PIN, INPUT_PULLUP);
  pinMode(RIGHT_PIN, INPUT_PULLUP);
  lcd.begin(16, 2);
  lcd.setCursor(1,0);
  lcd.print("Speed:");
  lcd.setCursor(12,0);
  lcd.print("RPM");
  Serial.begin(9600);
}

void loop() {

  static char sign = 0;                     
  
  if (digitalRead(LEFT_PIN) == 0) {
    sign = 1;
  }
  else if (digitalRead(RIGHT_PIN) == 0) {    
    sign = -1;
  }
  else if (digitalRead(STOP_PIN) == 0) {
    sign = 0;
  }
  
  // read the sensor value:
  int sensorReading = analogRead(A1);
  // map it to a range from 0 to 960:
  int motorSpeed = map(sensorReading, 0.0, 1023.0, 0.0,700);
  // set the motor speed and write it to the LCD:
  if (motorSpeed > 0) {
    myStepper.setSpeed(motorSpeed);
    
    myStepper.step(sign*stepsPerRevolution / 100);

  unsigned long currentMillis = millis();
  
  if (currentMillis - previousMillis >= interval) {
    
    previousMillis = currentMillis;

    lcd.setCursor(7,0);
    // lcd.print(motorSpeed/32.0, 1);
    lcd.print(float(float(motorSpeed)/float(58.5)),1);   
}  }  }    

 

Thanks,
Voltage


ReplyQuote
Voltage
(@voltage)
Estimable Member
Joined: 2 months ago
Posts: 160
Topic starter  

Got stuck in the code box there so I am adding this. No changes to the code yet but the numbers are what works with minimal thumping every 16-18 revs of the stepper or 4-5 turns on the output shat of the geared head.

Thanks,
Voltage


ReplyQuote
Will
 Will
(@will)
Reputable Member
Joined: 3 months ago
Posts: 368
 

@voltage

Slowing the rotation will lessen the thumping because less energy will be required to start and stop the motion. Going from 3600 to 700 is a whopping change !

However, there seems to be little point is sending floating point numbers in the map() function as it deals only in integers anyway.

You should re-test it with interval of 1000 just to see how much difference the speed reduction made.


ReplyQuote
Page 1 / 21