Stepper Motor Spinning Slow #5406
Replies: 1 comment
-
Posted at 2015-01-10 by @gfwilliams Does it 'judder' backwards and forwards a bit? It could be the order of the pins is wrong. It is also geared, so you'd expect it to run quite slowly Posted at 2015-01-10 by fobus it is juddering, it only goes to forward never comes back. I think orders are correct. It doesn't plugged to a gear, it is working freely. Posted at 2015-01-12 by @gfwilliams Hi, I think that if anything, the fact that the LEDs blink in sequence probably means that it's wrong. See this picture So that picture shows 1,2,3,4 in sequence - but if you compare that with your datasheet the order of the coils is different. In yours, and in most steppers, opposing sides are right next to each other so the order should most likely be 1,3,2,4 instead. And it isn't connected to a gear, but there is a 64:1 gear inside it. That's why the shaft doesn't come out of the middle. Posted at 2015-01-14 by fobus Thanks for your answer @gfwilliams Stepper Pin 1-D1 My new code is below, I'm changing the sequence by code
Now leds blinking in 1-3-2-4 sequence, but now it is juddering back-forward with very very small and quick steps. It is not forwarding any more. Also, I have forgot to tell; I'm using ULN2003 driver that shown here : http://www.instructables.com/id/BYJ48-Stepper-Motor/ Addition : Posted at 2015-01-14 by russdx Think you got your sequence a bit wring is it not more like described here. Posted at 2015-01-14 by fobus Hi @russdx, As you pointed; I have converted the code to javascript.at the end It worked great :) var Pin0 = D1;
var Pin1 = D2;
var Pin2 = D3;
var Pin3 = D4;
var _step = 0;
var boolean=true;
var dir = true;
function setup()
{
pinMode(Pin0, OUTPUT);
pinMode(Pin1, OUTPUT);
pinMode(Pin2, OUTPUT);
pinMode(Pin3, OUTPUT);
}
function loop()
{
switch(_step){
case 0:
digitalWrite(Pin0, LOW);
digitalWrite(Pin1, LOW);
digitalWrite(Pin2, LOW);
digitalWrite(Pin3, HIGH);
break;
case 1:
digitalWrite(Pin0, LOW);
digitalWrite(Pin1, LOW);
digitalWrite(Pin2, HIGH);
digitalWrite(Pin3, HIGH);
break;
case 2:
digitalWrite(Pin0, LOW);
digitalWrite(Pin1, LOW);
digitalWrite(Pin2, HIGH);
digitalWrite(Pin3, LOW);
break;
case 3:
digitalWrite(Pin0, LOW);
digitalWrite(Pin1, HIGH);
digitalWrite(Pin2, HIGH);
digitalWrite(Pin3, LOW);
break;
case 4:
digitalWrite(Pin0, LOW);
digitalWrite(Pin1, HIGH);
digitalWrite(Pin2, LOW);
digitalWrite(Pin3, LOW);
break;
case 5:
digitalWrite(Pin0, HIGH);
digitalWrite(Pin1, HIGH);
digitalWrite(Pin2, LOW);
digitalWrite(Pin3, LOW);
break;
case 6:
digitalWrite(Pin0, HIGH);
digitalWrite(Pin1, LOW);
digitalWrite(Pin2, LOW);
digitalWrite(Pin3, LOW);
break;
case 7:
digitalWrite(Pin0, HIGH);
digitalWrite(Pin1, LOW);
digitalWrite(Pin2, LOW);
digitalWrite(Pin3, HIGH);
break;
default:
digitalWrite(Pin0, LOW);
digitalWrite(Pin1, LOW);
digitalWrite(Pin2, LOW);
digitalWrite(Pin3, LOW);
break;
}
if(dir){
_step++;
}else{
_step--;
}
if(_step>7){
_step=0;
}
if(_step<0){
_step=7;
}
}
setup();
var stepInterdal = setInterval(loop, 1); Posted at 2015-01-14 by fobus But I would want to understand why the code below doesn't work?It is expected to do same think but not. var step = 0;
var steps = [0b0001,0b0011,0b0010,0b0110,0b0100,0b1100,0b1000,0b1001];
var stepperPins = [D1,D2,D3,D4]; // Change these to pins for your motor driver
function doStep() {
step++;
digitalWrite(stepperPins, steps[step % steps.length]);
}
var stepInterval = setInterval(doStep, 1); Posted at 2015-01-14 by DrAzzy Hm, I don't see why that doesn't work - it should, and is a much more efficient way to do it in Espruino. Does this work? (this is more efficient than how you're doing it, but not as good as how you had it, which I think should work.
Also, what board are you using that has pins D1-D4 broken out? Most of them don't have port D available. Have you verified that the board is generally working, particularly that time is running at the right speed on it? Posted at 2015-01-14 by @allObjects @fobus, I see your aching... I cannot see any logical difference either... btw, do you have means to record the signals you send to the pins? It seems to me also a bit short to just send a 1[ms] pulse... I do not know the spec of the stepper, but a stepper has a mass... and that mass has to be moved... I recall the old days where hard drive arms (of cheaper hard disk and floppy drives) were driven by steppers... and the step frequency at begin and end and also the hold time after reaching the position mattered to actually get the motor rotor to the place where the driver electronic wanted. After all it is just physics... first the 'plain' masses, and then even the electron-masses (changing the (eletro)magnetic fields - gives you phase effects): try to do it slower... start with higher value in setInterval, and speed it up until it does not behave clean anymore. It still does not really explain why the transcribe code works and your's not, because the transcribed code uses the same 1[ms] for stepping. Could it be that there is not enough power supplied to the stepper driver (board)? If I'm totally off, let me know and 'edit' the post... ;-) Posted at 2015-01-15 by russdx I have worked with UK fruit machine (slot machines to the Americans :D) reels before and they are driven using stepper Motors like allObjects has mentioned they need a ramp up and down tables or the motor will just jump. But using a geared one shouldn't need this? (Fruit machines drive a 12inch reel drum directly) Posted at 2015-01-15 by @gfwilliams I can't see any difference either... @drazzy the pinMode isn't needed in your code - but I'd be interested to see if that makes any difference. It shouldn't :) I wonder whether the reason the 'new' code works is that it executes really slowly, and the 1kHz update rate that was requested can't be made. What have you connected the power input on your driver board to? It may be that you don't have a high enough voltage available to turn the stepper as fast as you want to? It's interesting that in your video, when the stepper motor stops, 3 of the 4 LEDs are on (which I would have said was wrong as that presumably means 3 coils are on - although it does seem to work). Is that the case for you, or is it just 1 or 2 of 4? @russdx I think it depends on the mass of the rotor and speed you're trying to get to. When I've used bigger ones I've been able to instantly start and stop at a certain speed, but if I wanted to go very fast I had to ramp the speed up and down. Posted at 2015-01-15 by @allObjects
...what a cool disguise for a non-English native! ;) Posted at 2015-01-15 by @allObjects @fobus, take a look at Step motor basics, I found it googling for 'frequency limit of stepper motor momentum'. I'm adding a print in pdf to prevent broken link on link change. PS: have no relations what so ever to www.geckodrive.com other than positive affinity due to the fact that geckodrive is no only selling (for $) but also educating (for FREE)... ;-) Is it possible that you may have a dud? You may find out - but also what type of internal implementation it is at 5 wire stepper. Attachments: Posted at 2015-01-16 by fobus Hello, There is many questions, I'm sorry if I forgot to answer anyone. At first, all 3 code work. The first code that write at the start of this thread works so slow. I think that I'm wiring up correctly. I'm using stm32F4DISCOVERY. I'm using my boards power supply(5+), today I'm going to try with +9 Volt external battery and write results here. I have catched an interesting point. Also, when I flash the code -with save()- in to the device and restart it @drazzy's code doesn't works. It's about console.log() command. I think console.log() command doesn't work if device is working stanalone. So, I thought that it needs to wait a little bit before doing next step, here is my new code works good without comments and after save() var step = 0;
pinMode(D1,'output');
pinMode(D2,'output');
pinMode(D3,'output');
pinMode(D4,'output');
var steps = [0b0001,0b0011,0b0010,0b0110,0b0100,0b1100,0b1000,0b1001];
var stepperPins = [D4,D3,D2,D1]; // Change these to pins for your motor driver
function doStep() {
step++;
i=0;
while(i!=3)i++; //delay a little bit before doing steps. Better than console.log()
var stepval=steps[step % steps.length];
digitalWrite(stepperPins[0],stepval&1);
digitalWrite(stepperPins[1],stepval&2);
digitalWrite(stepperPins[2],stepval&4);
digitalWrite(stepperPins[3],stepval&8);
}
var stepInterval = setInterval(doStep, 1); Posted at 2015-01-16 by @gfwilliams
It's in the FAQ/Troubleshooting. It'll work, but only when the device isn't powered from your PC. If it's powered from the PC you need to open a terminal app first.
Instead of adding a delay, just change
I'd really, really suggest that you try changing the polarity of the signals:
Personally, I think that the motor driver might be inverting the outputs (so 0 is 1 and 1 is 0). That would mean that you spend a lot of time with 3 coils on (two of which will be 'fighting' each other as they're opposite). Posted at 2015-01-16 by fobus Hi @gfwilliams, I don't know why, but when I remove the Also change polarity didn't do any effect; Leds and motion is the same
Posted at 2015-01-21 by @allObjects @fobus, your 'initial correct' code - post #8 - works off the bat with about 12..13 rpm (counter clock-wise looking at the spindle)... just as expected... make it two (2)[ms] stepping speed. I use pins C6, C7, C8, and C9 - driver board inputs IN1, IN2, IN3, and IN4 - driver output boards A, B, C, and D - motor wires blue, pink, yellow, orange, and red (red on 4.66V driver chip outputs, the others on driver chip outputs. I started with stepping speed/interval 1000ms - first so slow without motor to observe the LEDs, especially the overlapping ON / half stepping - and and then with motor. I kept shortening the interval down to 2[ms]. 1[ms] did not work. Since I have no forces applied (yet), I can run it powered by 5V from laptop USB / Board Bat (4.66 Volts at the driver power pin). Will do some more exploring later with separate driver powering and attempt to increase speed... under no and load... and observe the pins at the driver chip with the scope. Posted at 2015-01-21 by @allObjects Dud? right - sadly literally... some are just mechanical duds. I got myself a few of these dirt cheap things... and some they hum smoothly, some they 'rattle' - you hear a hum overlaid with another synchronous noise of much lower frequency... at higher speeds (attached sound examples are at 1[ms] stepping interval. The volume of the rattling/touching noise is from placing the an empty open tuna can upside down on top the phone and the motor on top). Hold the motor with its back onto something resonating or your ear, and you will hear it whether your motors are smooth humming runners or guard rail smashing drunken drivers (out of the 5 I got, 2 hum, 2 hit a bit, one is stuck until you give it a twist in the right direction.) The rotating magnet is not always centered and therefore touch the poles. Even a very little it touching just slows them down in getting them moving, and due to the construction, the 2nd step after the initial step just pulls the rotor back in the original position... because it did not reach the 2nd step fully when the poles change again. Pulling the rotor out you will notice marks where it touches... bending the poles a tiny tiny little bit can solve the issue... but increases the gap and reduces of course the max torque. Run them on 5 V first to separate the good from the bad one. Running them on 12 V works - in some way the duds even better when started slower and then sped up, but they get pretty quickly hotter than I like them... on the other hand, they have quite nice torque. For a running motor heat dissipation is probably not work... but in applications with duty cycles, heat dissipation may be manageable. Attached is a shot showing the marks on the rotor - exactly at the position you will notice in the touch.mp4 clip, where you actually can her and 'see' where it touches... (stepping interval - stT = 15[ms]). Attached are too additional - just audio - 'clips' with healthy and unhealthy sound. Attachments: Posted at 2015-01-21 by @allObjects Used your code modified and built some stuff around to easily control it with a global command function r(). I chose r for now because I commanding it from the console. Function r accepts the stepping interval in milliseconds as argument.
Note that a stop always stops at an even 'position' and switches all driving pins off. Code:
To get to to higher speeds, a different approach then setInterval() has to be taken. In order not to hog the Espruino just for the stepper, an interrupt driven stepping in assembler needs to be implemented to get to shorter pulses. Attached clip shows 2 seconds fastest forward The 2 seconds ticking you hear in the background comes from a digital clock standing close by... ;-) Console:
Attachments: Posted at 2015-01-22 by @gfwilliams Thanks! It's really interesting to see that some of the motors really are slightly broken. Posted at 2015-01-22 by @allObjects We know that software is never bug free... but it is of great relieve - I'm sure for @fobus - that hardware isn't perfect either... ;-) and the scope where to find the cause for an issues has to include that. @fobus' key element is the setup for this extremely terse version of interval callback (paraphrased from stp):
Posted at 2015-02-10 by fobus First thanks all, at the end I could drive it normally. Here is my code
Can you explain me please how much degrees does the motor moves for each doStep() call? Also, I have tried both 5V and 9V , 9V has a great torque. 5V some times unable to start spinning, torque is not hight. Posted at 2015-02-10 by @allObjects The data sheet of the stepper motor tells you about the angle per step. If you thought have a geared one, you have to take this in account as well. I figured it out by taping a toth pick at its end to the drive shaft and something similar on something on the desk. I did then run at slow interval and counted. You can also make a console output with the steps run. You repeat with the countex steps to verify. If your motor is not moving, you may step too fast and/or your motor may have some mechanical issues as two out of my five (cheap) ones had. Check m posts in this thread. Btw , for stop just create a step with all zeroes 0b000 and out this the same way as you do a step. You do not need to talk to each pin separately. For reference take a look at the code I attached in the post where I discuss my solution. There is really good youtube out there that explains just everything in very detail. Most important are the 3 modes to operate this motor (shown in the attached picture). I used the half step mode to get decent torque and maximum precision / smoothness. With full stepping, maximum torque is achieved with decent precision, and with that most unlikely to 'loose' or 'slip' a step. Attachments: Posted at 2015-02-11 by fobus Yes, I have counted it step by step. In order to get a full tour I need to call doStep() 512 times . This motors stride angel is 64, so it is mutliplied by 8. Thank all again, I have made it work with your helps. Posted at 2015-03-30 by @allObjects Btw, code in post #20 has to be changed to make proper direction changes in all step phases. Current code has a step sequence discontinuity / hick-up when changing direction in lines 36 and 43. After issuing a stop, there is also a small issue: if stopping in an 'instable' step phase - where two magnetic fields 'fight' for the rotor and move the rotor between the fighting poles - it may come to rest in either pole position - back or forward after digitalWrite of 0b000 / taking the power off. To compensate for that when continuing, power with the same last step phase has to be applied before moving on... - of course for the proper amount of time. Implementation depends on whether the setInterval(...) invokes the function the first time at beginning or end of the first interval, which I do not know. Simplest resolution is to remove the stop() in the direction change, change the stop, and - most important - change the sequence in the backward steps sequence and adjust the step adjustment in direction change. This are the 4 changed lines: 16. 36. 43. 49. Resulting code:
Posted at 2016-08-17 by dwallersv Old thread, pointed here by @allObjects due to some work I'm doing with this same stepper. Some quick summary precautions to add that are covered here, but buried in all the dialog:
Posted at 2016-08-17 by @allObjects ...specs may even ask for 12V... but heat / heat dissipation becomes an issue, that's why stepper drivers apply different currents at different times. Usually higher current on signal change, lowering towards the phase end, an lower on hold (when stopped). 2ms is about right... which also puts constraints on how much else code can be executed next to controlling the stepper phases, including the code 'in the loop' to determine when to cease stepping. In my 2-dim 'mega' plotter I built - will pub later - all calculations are done beforehand and only simple decrement and 'falsy' checks are applied... (plus x/y ratio, whether the 'slower' moving axis has to step or not... For the very same performance reason - and repeatable, timing insensitive - 'precision', I have only one interval going...) The experience made me seriously consider to apply slave devices - other than JS / Espruino controlled - MCS, one per axis... or 'hardware' PWM (timer directly controlling pin...) I like the acceleration / deceleration approach, but as said, code has not to slow down rhe 'intervalled' stepping code execution. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Posted at 2015-01-10 by fobus
Hello,
I'm using this code to run my step motor :
I'm using 28BYJ-48 – 5V stepper motor and controller : http://robocraft.ru/files/datasheet/28BYJ-48.pdf
But it works so slow, approximately 0.5RPM. When I set interval to 30ms it is a little bit faster, but approximately 1RPM. I have tried with 5V and 9V input.
What I am doing wrong?
Beta Was this translation helpful? Give feedback.
All reactions