I am trying to program a limit switch for a stepper motor with an arduino uno.
I manage to stop the motor, but the problem I have is that I want the motor to take a few steps in the opposite direction in order to release the switch, and I can't do it without breaking everything (either it doesn't stop, or it goes backwards without stopping).
Can someone help me?
thank you
Yes.
Hello multimedia999
Post your sketch, well formated, with well-tempered comments and in so called code tags "</>" and schematic to see how we can help.
Have a nice day and enjoy coding in C++.
Simple question without being able to see your code. ARE you testing for the switch BEFORE moving the stepper a single step? Are you using some library to control the stepper, rather than doing it yourself? If you do all the stepping code yourself, you can avoid the problems.
I use a magnet and a hall effect switch as a limit detector on a stepper motor system
on power up while magnet not detected stepper rotates clockwise
Without posting your sketch this question translates to
"Can somebody post a ready to use code that fits my requirements?"
Which you could easily find yourself
arduino+code+steppermotor+limitswitch
If you already have code you want to go on using
then post your complete sketch using this method
best regards Stefan
Hello,
I command the stepper without any library. I just generate high, low, high… on pull connection of the controller corresponding to a number of step. The stepper can activate the switch before to have done the requested number of steps.
When the stepper touch the switch, I would like to stop it, and to make some step on the other direction(changing the dir connection of the controller) to release the switch.
Daniel Paulus
What is so hard about posting your complete sketch as a code-section?
If you do so the work reduces on both sides
your side re-adapting the IO-pin numbers to yours, understanding all the different chosen names
helpers side reducing how much code to write
best regards Stefan
Then add code to check the switch before doing any of this!
Here is the code (which is not on the same PC)
A Nextion screnn is connected with RX and TX pin to the arduino.
On this screen I input the distance in mm and decimal of mm.
I transmit to the arduino with the direction.
The arduino receive the date, convert it and calculate the number of step to corespond to the inputed distance.
The arduino sindicate the conversion and calculation on a lcd connected with I2C on pin 4 and pin 5.
The arduino start the motor for the calculated number of step.
I try to add a switch to stop the motor if it goes to far !
`String fromnextion=" "; // string received from Nextion screen. I define number of mm to move rthe stepper on the nextion screen
String signe=" ";
String entier=" ";
String decimal=" ";
float depval;
float pas;
String deplacement;
int filetage=8;
long pasint;
long p;
// include the library code:
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // define lcd screen which receive data from nextion screen after convertion and calculation
void setup()
{
Serial.begin(9600); // define connaction to nextion screen
Serial.setTimeout(100);
lcd.init();
pinMode(9, OUTPUT); // pin connected to dir+ at stepper controler
pinMode(8, OUTPUT); // pin connected to pul+ at stepper controler
}
void loop()
{
lcd.backlight(); //setup LCD
lcd.setCursor(0, 0);
if (Serial.available() > 0) // look if something received from nextion
{
lcd.clear();
fromnextion=Serial.readString(); // read data snet by nextion
signe=fromnextion.substring(0,1); // prepare and convert data
entier=fromnextion.substring(1,6);
decimal=fromnextion.substring(7,10);
fromnextion=" ";
deplacement="";
deplacement=signe;
deplacement.concat(entier);
deplacement.concat(decimal);
lcd.setCursor(0,0);
depval=deplacement.toFloat(),0;
depval=depval/1000;
pas=depval*3200/8; // calculate number of step
lcd.print("Depl: "); // print on lcd
lcd.print(depval);
lcd.print(" mm");
lcd.setCursor(0,1);
lcd.print("Pas: ");
pasint=abs(floor(pas));
lcd.print(pasint);
//delay(1000);
if (pasint > 0) // if stepper must move
{
if(pas < 0) // setup direction to move
{
digitalWrite(9, LOW);
}
else
{
digitalWrite(9, HIGH);
}
for(p=0; p<pasint ; p++) // move the sterpper for number of step
{
digitalWrite(8,HIGH);
delayMicroseconds(50);
digitalWrite(8, LOW);
delayMicroseconds(50);
}
}
}
}
`
As I tell on my first question, I already try a lot of solution, but without succes. I can stopnthe motor, but as the switch stay on, I cannot restart the motor. What I try to do it to restaret the motor after the stop for some step to release the switch. It is not so easy to find the solution on google ! Thanks to tell me that google exist ! I also use youtube!
OK you are using a stepper-driver with step/dir-input.
The code you have posted has nothing about detecting a limit-switch.
This means you are expecting to get a code written where it is unclear
- on which IO-pins is the limit switch connected?
The basic thing is if limit-switch is closed stop the motor
reverse motordirection
do one single step
after this one single step check if switch is still closed or opened
if still closed
do one single step
after this one single step check if switch is still closed or opened
if limit-switch is opened stop seeking for position with limit-switch opened
this can be done with a while-loop where the condition to end the while-loop is
limit-switch opened
inside your for-loop you check for limit-switch closed and execute a break-statement if this condition becomes true
The break-statement makes the code jump out of the for-loop
after the for-loop you check again for limit switch closed
if limit switch is closed
execute a while-loop
while (digitalRead(limitSwitch) == HIGH) {
//do a single step
}
You should post your best attempt how you have tried to code this behaviour
best regards Stefan
Trigger a function by reading the limit switch in void loop and then have the function reverse direction and take a few steps.
Also, these might be better placed in in setup rather than continuously looping them,,,
Helo,
Thanks for your answer, but I wanrt to keep it in loop because I need to repeat the moves.
After the first move, I want to be able to make another one and agian and again...
it can stay in loop. You just make the execution conditional to a flag variable
Whenever you set the flag-variable to true ==> code inside the if-condition gets executed
Whenever you set the flag-variable to false ==> code inside the if-condition gets skipped
best regards Stefan
That's 10000 steps per second or 3000 RPM for a 200 step motor, without acceleration!
Which motor, driver and microstep setting are you using?
The switches are setup to 3200 microsteps. The move is not very fast, but I can decreaze if you thing that's toomuch
Daniel
the flag is included by the test if I receive something from the nextion screen.If I do not push on the adequate button on the nextrion screen, nothing is sent to the arduino and no move, as soon I input something, a move is generated (just the requested distance). This part work very well. I jsut want to add the final switch
If the intention of your short posts is to annoy the users until they post ready to use code.
Me personal I will not post ready to use code.
It is even impossible if you don't tell to which IO-pin you have connetected your limit-switch
and you have to speciy if your limit switch is connected with pull-down or pull-up-resistor.
You can add multiple flags to the code
if it is really needed you could add hundreds of flag-variables.
In your case a second flag-variable will be sufficient maybe two or three
You seem to prefer to proceed really slow by a lot of short postings
I invite you to post a looonger post
Sure you can have that.
for (p = 0; p < pasint ; p++) // move the sterpper for number of step
{
digitalWrite(8, HIGH);
delayMicroseconds(50);
digitalWrite(8, LOW);
delayMicroseconds(50);
// check for limit-switch closed
// if yes
// set flag-variable to true
// execute break;
}
if flag-variable == true
execute drive-away-from-limit-switch (as already described above)
As soon as you post a new code-version with your attempt to integrate the "drive motor away from limit switch"-function and ask a specific question
I will answer the question.
best regards Stefan
It is working now
I think it was because I was trying with an interrupt on pin 2 and the limit switch was generating too many bounces!
So I changed and removed the interrupt
with this code:
String fromnextion=" ";
String signe=" ";
String entier=" ";
String decimal=" ";
String dot="";
char str[6];
float depval;
float pas;
String deplacement;
int filetage=8;
long pasint;
long p;
int x =0;
// include the library code:
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
void setup() {
Serial.begin(9600);
Serial.setTimeout(100);
lcd.init();
pinMode(2, INPUT_PULLUP);
pinMode(9, OUTPUT);
pinMode(8, OUTPUT);
}
void loop() {
lcd.backlight();
lcd.setCursor(0, 0);
if (Serial.available() > 0)
{
lcd.clear();
fromnextion=Serial.readString();
signe=fromnextion.substring(0,1);
entier=fromnextion.substring(1,6);
decimal=fromnextion.substring(7,10);
fromnextion=" ";
deplacement="";
deplacement=signe;
deplacement.concat(entier);
deplacement.concat(decimal);
lcd.setCursor(0,0);
depval=deplacement.toFloat(),0;
depval=depval/1000;
pas=depval*3200/8;
lcd.print("Depl: ");
lcd.print(depval);
lcd.print(" mm");
lcd.setCursor(0,1);
lcd.print("Pas: ");
pasint=abs(floor(pas));
lcd.print(pasint);
if (pasint > 0)
{
if(pas < 0)
{
digitalWrite(9, LOW);
}
else
{
digitalWrite(9, HIGH);
}
for(p=0; p<pasint ; p++)
{
digitalWrite(8,HIGH);
delayMicroseconds(50);
digitalWrite(8, LOW);
delayMicroseconds(50);
if(digitalRead(2)==LOW)
{
p=pasint;
digitalWrite(9, !digitalRead(9));
for( x=0; x<3200 ; x++)
{
digitalWrite(8,HIGH);
delayMicroseconds(100);
digitalWrite(8, LOW);
delayMicroseconds(100);
}
}
}
}
}
}
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.