Unable to get 28BYJ-48 stepper motor to work with ULN2803AFWG (solved) - Page 1
Forum section: electronics / general

author: newtekuser
author_rank: Frequent Contributor
timestamp: February 12, 2023, 07:34:34 pm
content: I am following this article to get the 28BYJ-48 stepper motor to work with a PIC16F887 and a ULN2803AFWG darlington transistor array.When I power up my circuit, I can hear the stepper motor buzzing whenever the rotate function is called, but the shaft doesn't move. (using full drive method to rotate it)https://circuitdigest.com/microcontroller-projects/interfacing-stepper-motor-with-pic16f877aThe only code changes and circuit changes I've made was to use PORTA instead of PORTB. (ANSEL and ANSELH are set to 0) as well as using a different PIC. I know the PIC works because I've been using it for different tasks.I've tried two of the same motors (purchased off digikey) thus far with same results and two ULN2803AFWG. However, the transistor arrays were purchased off ebay so their functionality is suspect.Motor and PIC are powered from different 5V power rails from my multi channel power supply. When I check the power draw of the motor it takes about 300mA.Anything that comes to mind as to why the motor behaves this way?

author: luiHS
author_rank: Frequent Contributor
timestamp: February 12, 2023, 07:50:08 pm
content: Plug the Logic Analyzer into the GPIO ports that connect the PIC to the ULN2803, to rule out software problems. Then you can dedicate yourself to focus on hardware or software.

author: newtekuser
author_rank: Frequent Contributor
timestamp: February 13, 2023, 12:02:17 am
content: Bad assumption on my part, the motor didn't work properly because I had replaced the custom delay function with the one provided by the xc8 compiler thinking it should work.With this delay implementation provided in the article, the shaft rotates as expected:Code:void ms_delay(unsigned int val){unsigned int i,j;for(i=0;i<val;i++)for(j=0;j<1650;j++);}Could someone please explain?

author: thm_w
author_rank: Super Contributor
timestamp: February 13, 2023, 10:18:51 pm
content: What was the function that didn't work?Do you have compiler optimization turned on? If its on it may remove some pointless loops, although it sounds like it didn't in this case.

author: newtekuser
author_rank: Frequent Contributor
timestamp: February 14, 2023, 01:32:16 am
content: Quote from: thm_w on February 13, 2023, 10:18:51 pmIt didn't work with __delay_ms() provided by xc8, otherwise this function worked great for other stuff like LCD init etc.As I said, the problem is fixed but I'd like to understand why the custom delay function works for the motor and the official one doesn't.

author: thm_w
author_rank: Super Contributor
timestamp: February 14, 2023, 10:57:11 pm
content: Was "_XTAL_FREQ " defined correctly?You can see some recommendations here:https://www.microchip.com/forums/m673703.aspxhttps://www.eevblog.com/forum/microcontrollers/xc8-understanding-__delay_ms()/

author: Nominal Animal
author_rank: Super Contributor
timestamp: February 15, 2023, 12:16:57 am
content: Quote from: newtekuser on February 13, 2023, 12:02:17 amThis is a silly do-nothing loop that does 1650 iterations (of nothing) per specified millisecond. With a proper non-hobbled compiler, the loop will be optimized away, and the delay does no delay at all.Proper delays use either a timer (free-running timer is fine, could be SYSTICK, could be something else) or carefully timed assembly code doing NOPs (instruction that does nothing but always takes the same number of CPU cycles) in a loop, with loop counts depending on the configured CPU frequency.If you do not have delays between toggling the outputs of the Darlington array, the outputs will switch too fast for the stepper to keep up. I don't recall what the maximum step rate (minimum delay between state changes) of 28BYJ-48 is –– I havemany, they're fun little steppers ––, but if we assume it is say 2000 Hz, with a gearbox that makes the output shaft turn by 5.625 degrees per step (so full revolution of the output shaft is 64 steps), that's 31.25 turns per second, or about 1875 RPM. (28BYJ-48 can have many different gear ratios, though, up to something like 2048 steps per revolution, which would only turn at 59 RPM with the same inputs.)Obviously, the stepper cannot keep up with much faster step rate than that. As the step rate increases, it first starts losing steps, then stops completely and just "buzzes" getting hot. Eventually, even the buzzing subsides, and the stepper just heats up.That's why you need a real-world delay between state changes / steps, when using any stepper motor.

author: newtekuser
author_rank: Frequent Contributor
timestamp: February 15, 2023, 01:04:04 am
content: Quote from: thm_w on February 14, 2023, 10:57:11 pmYes, the rest of the program works fine with the xc8 delay function including LCD init which would have failed without proper delays.

author: newtekuser
author_rank: Frequent Contributor
timestamp: February 15, 2023, 01:06:54 am
content: Quote from: Nominal Animal on February 15, 2023, 12:16:57 amThat custom delay function must be keeping the MCU busy for some cycles while it's counting to simulate some sort delay and I do see the delay between rotating CW and CCW.What puzzles me is why the motor does not turn when I use the delay function provided by xc8 library.

author: thm_w
author_rank: Super Contributor
timestamp: February 15, 2023, 11:47:00 pm
content: Its possible both delays are working, just one is not quite the right time you expect.You would need to get out an oscilloscope, toggle some LEDs using either of the delay methods, and see if they work the same way or not.

author: newtekuser
author_rank: Frequent Contributor
timestamp: February 18, 2023, 04:36:26 am
content: After some experimentation I found the __delay_ms function provided with xc8 to actually working fine with the motor. It's just that I needed to tweak the value, anything less than 1.2ms between each port write was just too fast for the motor to handle.