Uni-polar stepper motor shaft rotation inconsistent - Page 1
Forum section: electronics / general

author: newtekuser
author_rank: Frequent Contributor
timestamp: September 24, 2023, 11:48:10 pm
content: I'm using a cheap 5v uni-polar stepper motor and having issues getting consistent shaft rotations each time I call the function to perform a rotation. Say I rotate by 500 steps in either direction, each time it rotates less than the previous time as if it is missing steps.I experimented with slow and faster speeds by adjusting the delay each coil is energized to no avail.There's no load on the motor either and current draw is about 250ma during rotation.Am I doing something wrong in code, or is this motor just too weak to even sustain its own shaft rotations w/o load?This is the stepper in use:https://www.digikey.com/en/products/detail/mikroelektronika/MIKROE-1530/5724295I'm driving it using a ULN2803AFWG and PIC16F887.Code:void stepper_rotate_full_drive(char direction, int steps){for(int i=0;i<steps;i++){if (direction == CW){PORTA = 0b00000011;__delay_ms(2);PORTA = 0b00000110;__delay_ms(2);PORTA = 0b00001100;__delay_ms(2);PORTA = 0b00001001;__delay_ms(2);PORTA = 0b00000011;__delay_ms(2);}if (direction == CCW){PORTA = 0b00001001;__delay_ms(2);PORTA = 0b00001100;__delay_ms(2);PORTA = 0b00000110;__delay_ms(2);PORTA = 0b00000011;__delay_ms(2);PORTA = 0b00001001;__delay_ms(2);}}PORTAbits.RA0 = 0;PORTAbits.RA1 = 0;PORTAbits.RA2 = 0;PORTAbits.RA3 = 0;}

author: Nominal Animal
author_rank: Super Contributor
timestamp: September 25, 2023, 10:15:25 am
content: The stepper is the extremely common 28BYJ-48 with a gearbox that results in 4096 steps per turn.The most likely reason for the behaviour is incorrect wiring.The red wire is the center tap for both coils.Leave it unconnected.Connect it to 5V. (It is possible to cut a trace on the small board on behind the blue plastic to make the stepper true bipolar one, but it isn't necessary with ULN2803 or ULN2003 Darlington arrays.)One motor coil is connected between pink and orange, and the other between blue and yellow.The important bit is that the motor coil wires are interleaved, i.e. blue and yellow are not controlled by consecutive pins on your MCU, nor pink and orange.pink-yellow-orange-blue and yellow-orange-pink-blue and so on should all work, with the only difference being the direction of rotation.If your wiring puts blue and yellow and/or pink and orange in consecutive bits in port A, it would explain the weak and inconsistent rotation.The gearbox itself does have backlash, typically on the order of 20 steps or so. That is, when you rotate the shaft in one direction, it takes about 20 steps or so (but depends a lot on the gearbox and gears, thus does vary between steppers even from the same manufacturer somewhat) in the opposite direction before the shaft starts rotating in the opposite direction. If you gently move the shaft by your fingers, you can feel this 'slop'. It is only a degree or two, but with 4096 steps per rotation, it does end up being quite a few steps.However, if you keep rotating the shaft a constant number of steps in opposite directions, with say a piece of tape stuck to the shaft, it should not drift: just 'bounce' between two fixed directions.

author: H.O
author_rank: Frequent Contributor
timestamp: September 25, 2023, 12:40:35 pm
content: QuoteHmm....am I missing something? How will leaving the center tap disconnected work when driven in unipolar fashion?The darlington array sinks current, surely you need a way for the current to enter the winding(s) and that'll be thru the center tap(s) of the windings.(And driving that motor in bipolar mode will not work without first breaking the connection between the two center taps, right?)In the code there are 5 steps in sequence where the first and the last step contains the same bit pattern. This causes the timing between steps to be erratic, perhaps that's all it is.

author: Nominal Animal
author_rank: Super Contributor
timestamp: September 25, 2023, 01:28:27 pm
content: Quote from: H.O on September 25, 2023, 12:40:35 pmIt won't. (I modify mine to work in bipolar configuration and either actual bipolar stepper drivers like DRV8834, or quad half bridges like L293D.)Thanks for pointing out the goof; I fixed the post.Quote from: H.O on September 25, 2023, 12:40:35 pmCorrect. The actual winding has six taps, two of which are connected together (and to the red wire) on the small single-sided PCB behind the blue plastic. You only need to cut one trace to convert from unipolar to bipolar; I recommend using a Dremel with a cutting wheel. That way, one can simply ignore the red wire. (It will still be connected to the middle of one of the windings, but as long as it is not connected to anything, it won't do anything. At worst, it might act a bit like an antenna, but the stepper frequencies are so low it should not be an issue.)

author: Siwastaja
author_rank: Super Contributor
timestamp: September 25, 2023, 01:37:39 pm
content: Also note the sequence (assuming OP wants full step sequence) is one element too long, 0b00000011 repeats twice per cycle, hence the sudden deceleration mid-cycle, it's a sure way to make the stepper miss steps (as is the lack of acceleration/deceleration ramps). However, if you have tested this with very slow speeds / long delays, then the culprit is elsewhere.It's a good idea nevertheless to slow down stepping even more, like 1 step per second, mount something visible on the axle (like a piece of tape) and carefully look if the motor is taking uniform steps in uniform direction each time. If not, then the sequence is simply wrong.

author: newtekuser
author_rank: Frequent Contributor
timestamp: September 26, 2023, 01:54:00 am
content: Attached is my wiring schematic for reference. I had the extra "step" removed from each direction rotation but didn't see any improvement.I didn't try going as low as 1second/rotation though at that point I'm wondering if I should be using a more stronger motor. Essentially I want a cheap solution to lift a 500gram object off the ground for about 40cm in reasonable time (5 min max) and be able to control precisely how much. Unfortunately this is the cheapest motor I could find, others are ~ 6x more expensive.

author: PCB.Wiz
author_rank: Super Contributor
timestamp: September 26, 2023, 03:11:34 am
content: Quote from: newtekuser on September 26, 2023, 01:54:00 amI would first get rid of the ULN2803, and use low resistance FETs to drive the motor. Measure the motor current.You should be able to first put a pointer on the motor, and confirm you can spin that at a stable speed, then increase the speed without any gearbox, to confirm that works ok.Then add the gearbox with no external load and repeat. Finally load up the gearbox, going past your target weight to verify margins.

author: Nominal Animal
author_rank: Super Contributor
timestamp: September 26, 2023, 04:24:20 am
content: Quote from: newtekuser on September 26, 2023, 01:54:00 amLike I wrote, you have wired it exactly wrong wrt. your step sequence.Edit: With unipolar full stepping, one half of each coil is always powered. In your sequence, you have steps where one coil is completely unpowered, and the other coil is powered both ways, which means the magnetic fields are opposite and basically cancel out.

author: newtekuser
author_rank: Frequent Contributor
timestamp: September 26, 2023, 05:57:35 am
content: Quote from: Nominal Animal on September 26, 2023, 04:24:20 amI see now, so I need wire 1 from motor connected to 5v then wire 2 to pin 2 of ULN, 3 with 3, 4 with 4 and 5 with 5, correct?

author: Nominal Animal
author_rank: Super Contributor
timestamp: September 26, 2023, 06:23:29 am
content: Quote from: newtekuser on September 26, 2023, 05:57:35 amThis should do it:Motor 1 – 5VMotor 2 – o1Motor 3 – o3Motor 4 – o2Motor 5 – o4In other words, using the motor pins, the sequence you need is24351100011000111001but note the columns: as motor pins 2 and 3 are connected to the ends of the same coil, they're never energized at the same time. Similarly, as pins 4 and 5 are both connected to the other coil, they're never energized at the same time.If you don't want to rewire the motor, then change the binary sequence to 0b0101, 0b0110, 0b1010, 0b1001. This has the same effect as rewiring the motor but keeping the microcontroller pin sequence the same.If we compare to bipolar driving, you can think of pin 2 energizing the first coil one way, and pin 3 energizing it the other way; and similarly or pins 4 and 5 for the second coil. Now, in reality, only one half is ever energized, but the magnetic field the coils generate do pretty much work that way.(Because of this, if you swap motor pins 2 and 3, or motor pins 4 and 5, you'll only reverse the rotation direction. If you swap both pairs, or if you just rotate pins 2←3←4←5←2 or 2←5←4←3←2, nothing really changes.)The underlying logic is that if we label the coils A, B, C, and D, such that- A is pin 2 to 1 on the motor,- B is pin 4 to 1 on the motor,- C is pin 3 to 1 on the motor, and- D is pin 5 to 1 on the motor,then the full step sequence would be AB, BC, CD, DA.In your wiring, every second step one coil would be fully unpowered, and the other coil powered both ways. The ensuing magnetic field would tend to cancel itself, which explains the extremely weak stepping and losing steps.

author: Doctorandus_P
author_rank: Super Contributor
timestamp: September 26, 2023, 02:29:56 pm
content: Quote from: newtekuser on September 24, 2023, 11:48:10 pmThe trouble with this piece of code is that the first and the fifth step are the same, and that step is therefore done at half the speed of the others.Edit: On top of that, I also agree with Nominal Animal that you wired up the stepper motor wrong.

author: newtekuser
author_rank: Frequent Contributor
timestamp: September 27, 2023, 02:07:34 am
content: Quote from: Nominal Animal on September 26, 2023, 06:23:29 amThank you for the explanation! Unfortunately this wiring and code didn't work for me. The motor just buzzed without moving at all.I also tried with the attached wiring I found on online w/o luck:https://www.geeetech.com/wiki/index.php/Stepper_Motor_5V_4-Phase_5-Wire_%26_ULN2003_Driver_Board_for_ArduinoThe motor would move as in my original case but would miss steps.With the last wiring I tried from the link above and the sequence from your post, the shaft rotated a lot faster but still missing steps:Code:for(int i=0;i<steps;i++){if (direction == CW){ // rotate counter-clockwisePORTA = 0b1100;__delay_ms(2);PORTA = 0b0110;__delay_ms(2);PORTA = 0b0011;__delay_ms(2);PORTA = 0b1001;__delay_ms(2);}if (direction == CCW){ // rotate clockwisePORTA = 0b1001;__delay_ms(2);PORTA = 0b0011;__delay_ms(2);PORTA = 0b0110;__delay_ms(2);PORTA = 0b1100;__delay_ms(2);}}

author: newtekuser
author_rank: Frequent Contributor
timestamp: September 27, 2023, 05:29:51 am
content: Quote from: Doctorandus_P on September 26, 2023, 02:29:56 pmI'm seeing a lot of different wiring diagrams on the internet for uni-polar motors, so which is considered correct wiring?Attached is the wiring according to the datasheet for my motor.

author: PCB.Wiz
author_rank: Super Contributor
timestamp: September 27, 2023, 05:47:13 am
content: Quote from: newtekuser on September 27, 2023, 05:29:51 amMaybe you need to connect 4 switches and diodes, and a pointer on the motor, and experiment ?The link you had in #11 uses 8 steps, with intermediate ones with a single winding energized, which may be easier to debug ?

author: Nominal Animal
author_rank: Super Contributor
timestamp: September 27, 2023, 06:52:20 am
content: Quote from: newtekuser on September 27, 2023, 05:29:51 amAs this unipolar stepper motor is absolutely ubiquitous – it's not only used in Arduino stuff, but also in things like air conditioning machines to control the louvres – there is no one true answer. There is a straightforward way to find out, though.Do you have an ohmmeter or a multimeter? The coils are on the order of 25 Ω to 50 Ω. The common pin is the one that measures the same resistance to all four other pins, and is the one connected to 5V. The four other pins then correspond to the two pairs of coils, and you can quickly test/experiment to see which are on the same dual coil, and in which orientation. These you drive via four pins of the ULN2803 or ULN2003 Darlington array.To repeat, if we label the four pins A1, A2, B1, and B2, the four full steps are A1+B1, A2+B1, A2+B2, A1+B2.(The eight half-steps are A1, A1+B1, B1, A2+B1, A2, A2+B2, B2, A1+B1. Half stepping gives you more precision for the movement, but less torque, because in half the steps only one coil part is energized.)There are 24 combinations of the pin orders, but exactly two of them work best/perfectly, only in opposite directions of rotation.Consider the following code snippet:Code:#define STEPS 512#define STEP_MS 10#define BETWEEN_MS 1000for (char i1 = 0; i1 < 4; i1++) {const unsigned char a1 = 1 << i1;for (char i2 = 0; i2 < 4; i2++) if (i1 != i2) {const unsigned char a2 = 1 << i2;for (char i3 = 0; i3 < 4; i3++) if (i1 != i3 && i2 != i3) {const unsigned char b1 = 1 << i3;for (char i4 = 0; i4 < 4; i4++) if (i1 != i4 && i2 != i4 && i3 != i4) {const unsigned char b2 = 1 << i4;// Perhaps a serial monitor print here?// i1 is the bit number 0..3 for mask a1,// i2 is the bit number 0..3 for mask a2,// i3 is the bit number 0..3 for mask b1, and// i4 is the bit number 0..3 for mask b2.// None of them are equal to each other, ever.// (a1|a2|b1|b2) == (a1^a2^b1^b2) == 15.// We try all 24 combinations here, and none else.// That is, this line is executed 24 times.for (int i = 0; i < STEPS; i++) {PORTA = a1 | b1; __delay_ms(STEP_MS);PORTA = a2 | b1; __delay_ms(STEP_MS);PORTA = a2 | b2; __delay_ms(STEP_MS);PORTA = a1 | b2; __delay_ms(STEP_MS);}__delay_ms(BETWEEN_MS);}}}}When this is run, the code tests each of the 24 possible pin orders for 4*STEPS full steps at STEP_MS intervals, and then pauses for BETWEEN_MS.You just need to observe which two iterations ones turn reliably/fastest.If you can output the four bit indexes somewhere you can observe, you just note the bit indexes. Otherwise, the iteration order for the bit indexes (a1 a2 b1 b2) are 0123, 0132, 0213, 0231, 0312, 0321, 1023, 1032, 1203, 1230, 1302, 1320, 2013, 2031, 2103, 2130, 2301, 2310, 3012, 3021, 3102, 3120, 3201, 3210. I suggest you make a mark on paper or computer for each iteration, for example a number between 0 and 4 how much the stepper turned, to keep track of the iterations, and run the whole test two or three times, to ensure your results are consistent.The two correct ones should have bit indexes be left-right mirrors of each other, for example 0213 (i1=0, i2=2, i3=1, i4=3) and 3120.When you find those, you can either use your circuit as-is and modify the bit masks your code uses, or reorder your wires so the bit indexes become 0123/3210.(For 0213, you'd swap the middle two wires. For say 1302, you'd move the third wire first, first wire second, second wire fourth, and last wire third.)

author: Doctorandus_P
author_rank: Super Contributor
timestamp: September 27, 2023, 08:47:48 am
content: Quote from: Nominal Animal on September 27, 2023, 06:52:20 amThe model number is ubiquitous, but the motor itself is made in a lot of variants. There are 5V and 12V variants (and the 12V probably won't run properly on 5V) The motor can have a different gear ratio (I guess around 16:1 and around 64:1 are common, but the gear ratios are not nicely rounded numbers. It also apears that some models have a built in friction clutch, while others do not. I am also guessing there are a bunch of different manufacturers of these motors, judging from small changes between them seen on aliexpress.For the wiring scheme, it is probably easiest to just pop of the plastic lid and look under it.

author: Nominal Animal
author_rank: Super Contributor
timestamp: September 27, 2023, 09:32:08 am
content: Quote from: Doctorandus_P on September 27, 2023, 08:47:48 amOn mine, I've always destroyed its tiny tabs when opening, so it won't click back; one has to glue it back. That's why I suggested the non-destructive test approach instead.If one adds a push button (so that instead of a fixed delay, the next combination is only done after a button press) and a 4-digit I2C LED display using AIP650/TM1650 controllers that one can get off eBay for a couple of euros/dollars shipped, you have a quick testbench to verify the motor type.Add a second button, that does not change the pin order, but cycles through different numbers of steps (48, 64, 512, 2048, 4096, for example) to determine the gearing ratio, using the led display to show the number of steps, and you can identify any 5V 28BYJ-48 variant.I prefer AVRs (atmega32u4 in particular) and don't use PICs, so I don't have any tested code for this. I'm pretty sure there exist such Arduino projects that one could easily adapt.(I've got over a dozen of these steppers in a plastic tub, just because they're so useful. When the 5V versions are driven at 5V, it does have a good bit of torque for such a small stepper. I do also have even smaller stepper with metal gearboxes; I believe the highest one I have is 1:298 with 22.5°. 3D printing PLA gears that simply push on to the 28BYJ-48 shaft also allows one to use toothed belts for low speed, low power movement at relatively high precision.)