polymorph:
Dump the delays and use the accelStepper library.
Thank you, but I don't see the advantage for my application.
polymorph:
Dump the delays and use the accelStepper library.
Thank you, but I don't see the advantage for my application.
OK,
Have everything running. Using Pot to control speed through the map function and Arduino A0. Using a button to reverse direction, and another one to stop and hold and a third button to stop and allow rotation. So basically I have everything done from an Arduino/programming perspective. Many thanks to everyone for their help. I will post code as soon as I have it cleaned up a little.
What I would like to do is make the controller as a stand alone box. That way I can plug in power supplies as needed depending on the motor of course. That part is pertty easy, just use a simple DC plug like fournd on Laptop Computers. I would like to use the same power supply to drive the Arduino. I am looking for ways to reduce the voltage so I can do that. From what I have read the Arduino will accept 7-12 volts on the board using the DC plug or VIN pin.
So what I probably need to do is employ a voltage regulator to drop the voltage to 10-12 volts to power the Arduino from the same power supply.
My question is what is the best way to do this, I am concerned about heat and feasibility to do what I want.
The other question I have is how to connect the motor to a controller box. Experience has shown that not only is it important to get the coils right, but the way the coils are connected to the driver is important. So I need to test every motor to find the connections leading to the coils, then find some way of connecting the coils properly to the driver.
So basically a black box with two or more inputs. One is a 12 to ~30 volts, the other to connect the motor.
Any suggestions/ideas appreciated. Also if this is a trully bad idea that would also be appreciated.
I have tried to expand the code to include another application. After I finish wrapping a bamboo rod, I need to dip it in varnish then slowly pull it out of the varnish. I use a dip tube (1.5 inch diameter galvanized pipe) for this purpose. I need to remove the rod at about 4 inches per minute. If I am using a stepper with a 1/4 inch (6 mm) shaft, that meens I need to run the motor at about 5 rpm. So for a 1.8 degree stepper that equates to a delay between steps of somewhere in the neighborhood of 7500 miliseconds.
One of the other requirements is the need to stop the motor at specific points on the rod to allow time for the varnish to drain. Specifically I need to stop the rod at the end of each thread wrap so the varnish can drain and not form lumps in the finish. So I need to use a button to indicate stop. The problem is with a 7500 delay, the delay() function hinders reading the stop button during the 7500 miliseconds delay. I think the millis() function will work using the time difference between step start and step finish, but I would like any other suggestions someone might have. The code would use a while loop that waited until (startMillis - millis() > secondsDelay) Here's the code I am considering.
digitalWrite(pinDir,dir); // Enables the motor to move in a particular direction
startTime=millis();
digitalWrite(pinStep,HIGH);
while (startTime-millis() < Delay);
startTime=millis();
digitalWrite(pinStep,LOW);
while (startTime-millis() < Delay);
The way I would like the button to work is as follows: A button press is detected using normal coding in the loop. If the button press is detected (change the value of a variable) stop the stepper using the "enable" feature in the A4988 Driver. If another button press is detected start the stepper. I want to use the same button to stop and start the motor. Normally the rod needs to remain stationary for about 30 seconds or more depending on the viscosity of the varnish I am using.
The problem I am currently facing with the delay() function is the button press is not always recognized due to the fact that the program is in one of the 7500 MS delays, so I have to keep pressing it until the delay expires, not an optimal approach. Ideally I would like to run the program in two threads, one to be constantly checking buttons, and another to control the motor speed. But I don't think the Arduino code will allow multithread coding.
The other solution I can apply is to use a gear motor instead of a stepper. I want to use a stepper for the stop and hold ability it has, but since the rod sections are pretty light, I think a gear motor would probably work. I have a few L298N bridges that should give me what I need.
Thanks for any help or suggestions anyone might have.
This is a classic use for millis in the form of the IDE's blink without delay example or Robin2's Doing several things at once thread.
Your own while loop should be unnecessary here, just let the loop function take care of repetition.
Multithreading is not supported on the Arduino, but the above techniques will let you make it appear that it is.
Don't see the advantage, a few posts later describes delay() causing problems. OK.
wildbill:
This is a classic use for millis in the form of the IDE's blink without delay example or Robin2's Doing several things at once thread.Your own while loop should be unnecessary here, just let the loop function take care of repetition.
Multithreading is not supported on the Arduino, but the above techniques will let you make it appear that it is.
I saw the several things at once url. Thanks.
OK.
So tried the millis approach and still having difficulties reading the buttons when the delay is set to something long. In this case I have a stepper that uses 7.5 deg per step. I have the microsteps set to 16 and running at 6 rpm. That gives me a delay of around 300 miliseconds. (I am using pull-down buttons)
Here is the main loop that I am using:
void loop()
{
buttonTwo=digitalRead(startStopButton);
if(!buttonTwo) stepper.startStopMotor();
currentMillis = millis();
//Serial.println(stepper.getDirection());
stepper.run(stepper.getDirection());
while(millis() < currentMillis + msDelay ){
buttonTwo=digitalRead(startStopButton);
if(!buttonTwo) stepper.startStopMotor();
//wait approx. [msDelay] ms
}
}
Here is the startStopMotor function I am calling.
void stepperFly::startStopMotor() //Stop motor free
{
if(this->motorStop == ON)
{
this->motorStop = OFF;
digitalWrite(pinEnable, LOW);
}
else
{
digitalWrite(pinEnable, HIGH);
this->motorStop = ON;
}
}
When I press the button to start or stop the motor either it works fine, or nothing happens. I suspect the button is not being read when it is pressed, which is very strange to me.
So any of you have any ideas what can be done to make this actually stop when I press the button. Its important that I get it to stop precisely when pressed as the application I will use it for requires frequent stops at precise locations.
OK, figured it out. Needed to put a delay on the button read. Thanks.
Thanks.
Ok,
So I have encountered an interesting issue using microsteps. I want my code to determine the delay based on two things. The rpm that I select and the microstep setting I select. I am using the A4988 motor controller so I have the following microsteps available: 1, 1/2, 1/4, 1/8, and 1/16. I have found that using microsteps smooths the motor out a bit.
But here is my issue. I am using the following algoritm I am using:
1/(RPM * Number of Steps per Revolution / 60 seconds per minute) * microsteps (a value from 1 - 16 depending on how I have the microsteps configured) * 1000000 microseconds per second.
This gives me the delay between each step the motor takes. So for example if I want the motor to run at 4 RPM using a 1/16th microstep, the interval is about 41667 microseconds.
If I change just the microsteps to 8 the interval changes to 20833 as it should, however the RPM should not change as even though I have decreased the interval between steps I have also increased the step size by an equal amount.
An here's where the issue is. The mathematics says the RPM should not change with a change in microstep size assumeing I change the step size and recalculate the interval, but what is happening is the reverse. If I just change the microstep and recalculate the interval, the interval is correct, but my motor rpm doubles?
So I thought I might have a problem with the actual microstep command coming from the controller. So I just changed the microstep size without changing anything else, left the rpm constant and did not change the interval calculation. The motor speed did change as I expected it to. When I changed the microstep from 1/16 to 1/8 the motor speed doubled. So I know the microstep code is working.
So why did the rpm change when I changed the step size and recalculated the interval? I can include my code if anyone wants to see that.
Always best to include your code.
Yes on the code. I completely re-wrote it using the A4988 Library from Git Hub and all is well now. I must have not written the algorithm correctly.
All is well now. Thanks
I am finding the stepper motor has some interesting characteristics that I hadn't considered when first setting out on this project.
First, since in some applications the motor has to rotate at low speeds (5-6 rpm) for long durations (like 24 hours) I think steppers may not be the way to go. My experience so far is that after two or three minutes of constant rotation, the steppers seem to get quite hot. I haven't been able to find any information on duty cycle for these motors, but my guess is that they are not designed for long periods of rotation. And that makes sense, since most of the motors I have were used in printers and copiers, and considering most of the applications I have seen have been for 3-D printers and CNC machines which use short duty cycles. I may have to change to a gear motor to do the long duration tasks I need.
Second low speed (4 rpm or so) is pretty jumpy even with microstep set to 16. For my rod turner that's OK, but for some of the other applications I have in mind, this may be a real problem. I am considering gear motors for this type of application as well
Third, and probably the most important is coding. I want to be able to do different things using buttons. But to make the buttons work the way I want, I have to put in delays, these delays of course cause the motor to slow down. Here's an example of what I wanted to do. Use one button to do two things by pressing it either once or twice within a second. Here's the code I use:
buttonOne=digitalRead(BUTTONONEPIN);
if (buttonOne==LOW){
buttonOnePressed=true;
delay(50); //Eliminate button bounce
currentMillis=millis();
while(millis()<(currentMillis+interval)){
buttonOne=digitalRead(BUTTONONEPIN);
if(buttonOne==LOW && buttonOnePressed) return 3;
}
return 2;
}
Then the return value is throw into a switch to determine the state and take actions. I am finding the .75 second delay has (of course) a significant impact on the motor speed. The .750 was arrived at through testing of how fast I could press the button twice. and get the accuracy needed.
I think for simple functions like just rotating the rod for short durations the steppers will work great. But I am thinking for lower speeds and longer durations I will have to go to gear motors.
Any other ideas or suggestions?
Reality check time. If your motor is still working fine, even though you think it is hot, it is NOT too hot. For the length of time you ran it, it is within it's design temperature range.
Paul
Paul_KD7HB:
Reality check time. If your motor is still working fine, even though you think it is hot, it is NOT too hot. For the length of time you ran it, it is within it's design temperature range.Paul
Thanks Paul. One spec sheet I saw had a design temp rise of 80C. That's a lot of heat. So I guess I can live with it.
The other issue I found was with the buttons. I failed to add 10K resistors and the buttons were floating giving me indeterminate reading and strange behavior.
I have the first cut at this project up and running on a breadboard. I am just about done with the soldered version on a perf board. But two of the many things I wanted to do with this project was to learn how to create PCBs and how to actually use a design tool. I have been using opensource operating systems and tools for over 20 years now so decided to stick with it. I did some searching and it seems Kicad seems to be leading the pack right now in the Open Source field. So I downloaded it and have spent the last two or three weeks reading tutorials and designing the project. One thing I found right off the bat was that I could not install Kicad Ver 5 on Ubuntu. Not sure exactly why, but Ubuntu only has ver 6.0 in its repository. I could have downloaded and compiled the source code for 5, but that normally runs into dependancy issues that I really didn't want or have the time to play with.
So, I installed Ver 6 and followed a few tutorials on 5. Didn't find too many rough spots but a few that were easily resolved. I do thing 6 is a little buggy when it comes to adding traces to the PCB.
So I have attached the schematic diagram and the PCB diagram for anyone to look at and critique.
My next adventure is to have some PCBs made up to test them out and see if what I have designed really does work.
FirstSchem.pdf (34.3 KB)
FirstPCB.pdf (50.6 KB)