Go Down

Topic: Choosing right motor shield (& other components) (Read 665 times) previous topic - next topic

Driez

Dear everyone,

I'm looking on hardware advice since I am a noob on this subject. Programming questions will follow after I picked the correct components ;') in a different topic.

For a project I am working on I want to use a nema 17 sized stepper motor to drive an extruder of some kind. The rotational speed of the extruder will lie approximately between 10 and max 100 RPM.

The RPM will have to be controleable through a potentiometer and be displayed on a 16x2 LCD display.

I would like to do this with an Arduino uno Rev 3 and a motorshield.

Being a mechanical engineer I calculated the required torque and picked this motor: Nema 17 Bipolar 1.8deg 65Ncm (92oz.in) 2.1A 3.36V 42x42x60mm 4 Wires

So far I have ordered the following components:
- On-off switch
- The Nema 17 motor mentioned above
- Original Arduino uno rev 3
- Original Arduino motor shield rev 3
- 16x2 LCD display with male headers
-10kOhm 0.125 Potentiometer

I still need to pick and order:
- Wall socket Power supply, how many amps do I need to run everything?

Starting with the wiring diagram I ran into a few problems which I would really appreciate some advice on.

-First of all the original arduino motor shield (an L298) is probably too small for the chosen motor? is there a better motorshield better suited for the job which I could use?

-Second the chosen LCD and current motorshield use the same pins so I can't use them together. Either I take a different motorshield (Which I need anyway to get the most out of the motor?) or a different LCD (IC2?).

-Third, what is the (easiest and) most reliable way to wire all of this together?

All help and advice is very welcome! Thanks in advance.

Yours sincerely,

Driez


Robin2

None of the motor shields is suitable for your 2.1 amp stepper motor -  the DRV8825 stepper drivers (which fit the stepper motor shields) cannot provide enough current.

You need to get a specialized stepper motor driver that can provide (say) 3 amps so as to give yourself some headroom. The drivers with the TB65xx or TB66xx chip will probably be the most economical. Also IIRC from another Thread the Pololu website now has a new high-current stepper driver - it would be worth checking.

Under no circumstances consider using a pair of H-bridges to drive the motor.

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

Driez

Dear Robin,

Thanks a lot! I have bought a TB6600. All the components should arrive today. The final component list is as follows:
- 12V 10A laptop power supply
- TB6600 3.5A | 1/32 microsteps | 9-40V
- I2C 16X2 LCD
- 10kΩ potentiometer
- Arduino Uno Rev 3
- Nema 17 Bipolar 1.8deg 65Ncm (92oz.in) 2.1A 3.36V 42x42x60mm 4 Wires

The plan is to power the Arduino uno rev 3 and TB6600 from the same power supply.

Next thing to do is the wiring. I made a simple diagram in Fritzing since there aren't many components. I used an IC for the TB6600 because I couldn't find it in Fritzings parts library.


Any advice is welcome! I'll start looking into code now, wish me luck.

Robin2

The plan is to power the Arduino uno rev 3 and TB6600 from the same power supply.
Without knowing details of the power supply I can't really comment. The input to an Arduino Uno is recommended not to exceed 12v and that should work for your stepper motor but if you need higher speeds a higher voltage would be better.

Yours is not the worst Fritzing diagram I have seen but there are no labels on most of the connections. A photo of a simple pencil drawing with the relevant pins clearly labelled will be a lot clearer (even if you are not a good artist).

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

Driez

The power supply is a 12V 10A laptop power supply: Power supply (Dutch website)

"This 10A switching PSU is protected against short-circuiting, overpowering and too high temperatures, and overvoltage (12,6-16,2V). This PSU has a 90 degree DC plug (5,5 mm x 2,1 mm)

The PSU delivers 12V DC-current upto a maximum of 120W."

I don't need high speeds, I need torque at low RPM's between 15 and 100 max.

Here is a picture of the fritzing schematic connection, I hope this helps.


Robin2

I still can't read the labels on your image.

Is there any reason to think you have the wiring wrong?

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

Driez

I think the wiring is allright. I just measured the voltage from the PSU however and it's 12,17V.

The TB6600 can handle 9-42V so it will be fine. The Arduino however rates 7-12V... will the 0,17 kill it? It will most likely run hot.

Robin2

The Arduino however rates 7-12V... will the 0,17 kill it?
No. The max for an Uno is actually 20v, but that might put too much stress on the voltage regulator.

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

Driez

Cheers, I didn't want to stress the voltage regulator so I bought a 9V 2.5A wall adapter for test purposes. Finishing up code now, hope it works ;').

Driez

Got everything connected (except for the the I2C LCD since it hasn't arrived yet.) Been trying to get my code to work the whole day but can't get it to. I'm an absolute newbie at this so please help me out. I've had the motor spin so I know it works and is connected correctly.

I want to input an RPM value between 0-100 with the potentiometer. I have the stepper motor setup at 200 pulses per revolution.

The potentiometer gives good readings between 0-1023 when I serial print the values.

I calculated the corresponding RPM using this formula: RPM =(Pot/1023)*100;

The RPM formula came up with 0 all the time when I checked it with serial print. I was thinking it had to do with the numbers being integers. I changed both to float which helped and gave me readings from 000.00 tot 1023.00 and 0.00 to 100.00. This however  gave me problems with the delayMicroseconds(10^6/((RPM/60)*200*2)); formula where I convert the set RPM value into the corresponding delay.

Current code with RPM and Pot as integers.

Code: [Select]
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address

//defines pins
const int stepPin = 6;  //PUL -Pulse
const int dirPin = 7; //DIR -Direction
const int enPin = 8; //ENA -Enable
int Pot = A1; // Input pin for the potentiometer.
int RPM; // Declares variable for RPM

void setup(){
  Serial.begin(9600); //Initiate Serial communication.
  lcd.begin(16,2); //Defining 16 columns and 2 rows of lcd display.
  lcd.backlight(); //To Power ON /OFF the back light.
 
  //Sets the pins as Outputs
  pinMode(Pot,INPUT);
  pinMode(stepPin,OUTPUT);
  pinMode(dirPin,OUTPUT);
  pinMode(enPin,OUTPUT);
  digitalWrite(enPin,LOW);
}

void loop(){
  Pot = analogRead(A1);
  //Serial.print(Pot);
  //RPM =(Pot/1023)*100;
  Serial.print(RPM);
  lcd.setCursor(0,0); //Defining position to write from first row, first column.
  lcd.print ("RPM"); // Showing the letters RPM
  lcd.setCursor(0,1); //Defining position to write from second row, first column.
  lcd.print (RPM); // Showing current RPM value
 
  //Enables the motor direction to move in a certain direction.
  digitalWrite(dirPin,HIGH);
  //Makes 200 Pulses for making one full cycle (1.8 degree stepper).
  for(int x = 0; x < 200; x++){
    digitalWrite(stepPin,HIGH);
    delayMicroseconds(10^6/((RPM/60)*200*2));
    digitalWrite(stepPin,LOW);
    delayMicroseconds(10^6/((RPM/60)*200*2));
}
}


Any advice is welcome!!

Robin2

I've had the motor spin so I know it works and is connected correctly.
What is the difference between your non-working program and the program you used to prove that the motor works? The problem will be somewhere in the difference.

It's a good practice to start with a working program and add extra bits in small pieces, testing as often as possible. That way the problem comes to light easily.

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

Driez

What is the difference between your non-working program and the program you used to prove that the motor works? The problem will be somewhere in the difference.
The code that made the motor spin:
Code: [Select]
void loop(){
  //Enables the motor direction to move in a certain direction.
  digitalWrite(dirPin,LOW);
  //Makes 200 Pulses for making one full cycle (1.8 degree stepper).
  for(int x = 0; x < 200; x++){
    digitalWrite(stepPin,HIGH);
    delayMicroseconds(500);
    digitalWrite(stepPin,LOW);
    delayMicroseconds(500);
}
}


Now I wanted to add the functionality of it being RPM controlled between 0 and 100 RPM so I changed it to:

Code: [Select]
void loop(){
  Pot = analogRead(A1);
  RPM =(Pot*100L)/1023;

  //Enables the motor direction to move in a certain direction.
  digitalWrite(dirPin,LOW);
  //Makes 200 Pulses for making one full cycle (1.8 degree stepper).
  for(int x = 0; x < 200; x++){
    digitalWrite(stepPin,HIGH);
    motor =((((RPM*1000000)/60)/200)/2);
    delayMicroseconds(motor);
    digitalWrite(stepPin,LOW);
    motor =((((RPM*1000000)/60)/200)/2);
    delayMicroseconds(motor);
}
}


I checked the RPM value with serial.print and it varies between 0 and 100 nicely when turning the potentiometer. I am sure the reason the motor doesn't spin has to do with the code after the RPM has been defined. Any pointers or tips on standard code to control a motors RPM? Having a hard time to find something similar and useful on the forum.

Yours sincerely,

Driez

Robin2

Take things step by step.

First, change this (from the first program)
Code: [Select]
digitalWrite(stepPin,HIGH);
    delayMicroseconds(500);
    digitalWrite(stepPin,LOW);
    delayMicroseconds(500);

to this
Code: [Select]
unsigned long microsBetweenSteps = 1000;
 digitalWrite(stepPin,HIGH);
    delayMicroseconds(10);
    digitalWrite(stepPin,LOW);
    delayMicroseconds(microsBetweenSteps);

Now you can change the speed by changing the value of the variable microsBetweenSteps

Next thing is to calculate (with a calculator) what should be the max and min values for that variable to give you the slowest and fastest speed that you want.

Then you can use the map() function to convert the 0 to 1023 from analogRead() to the max and min values that you have calculated.

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

Driez

Take things step by step.

Next thing is to calculate (with a calculator) what should be the max and min values for that variable to give you the slowest and fastest speed that you want.

Then you can use the map() function to convert the 0 to 1023 from analogRead() to the max and min values that you have calculated.
Dear Robin,

Thanks for your time and swift reply. I would like to display the RPM value on an LCD display. An option would be to source the RPM value directly from the potentiometer value if I use your code and not use it anywhere else in the program.

The slowest speed I want is RPM 0 so the delayMicroseconds should be ∞ high (wouldn't this cause a problem and an endless loop and stop the motor from turning?)

The fastest speed I want is RPM 100 which would be 100/60 RPS which would correspond to (100/60)*200 pulses which is 333,3333333 so lets say 333 pulses per second, correct?.

The map function would then look like this:

Code: [Select]

  Pot = analogRead(A1);
  RPM = (Pot*100L)/1023;
  microsBetweenSteps = map(Pot, 0, 1023, 0, 333);

  digitalWrite(stepPin,HIGH);
  delayMicroseconds(10);
  digitalWrite(stepPin,LOW);
  delayMicroseconds(microsBetweenSteps);


Is this what you meant?


Robin2

The slowest speed I want is RPM 0 so the delayMicroseconds should be ∞ high (wouldn't this cause a problem and an endless loop and stop the motor from turning?)
Stationary always needs to be treated as a special case.

Quote
The fastest speed I want is RPM 100 which would be 100/60 RPS which would correspond to (100/60)*200 pulses which is 333,3333333 so lets say 333 pulses per second, correct?.

The map function would then look like this:

Code: [Select]

  Pot = analogRead(A1);
  RPM = (Pot*100L)/1023;
  microsBetweenSteps = map(Pot, 0, 1023, 0, 333);

I think your maths needs a refresher.

333 steps per second is one step every 3003 microsecs according to my calculator.

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

Go Up