Hi!
I used the ubiquitous 28-BYJ-48 roughly 2 years ago with a Raspberry Pi (which one would assume is more problematic) without issue. Having studied Computer Science for two years and worked with low level systems programming, I felt comfortable delving into MCUs and having them interface with the afformentioned stepper motor. Unfortunately, over 100 rations, the achieved inaccuracy is roughly 1/4 rotation.
To have more granular control and due to the fact that I only plan to do simple projects with it, I chose to manually interface with the motor instead of using an overkill library. I also avoided using any abstractions and accessed the DDR-/PORT registers directly.
The setup:
Board: Arduino Nano (clone)
Software: Arduino IDE version 1.8.10
Motor: 28-BYJ-48
Driver: ULN2003A (ST) on the driver board which is always supplied with the stepper.
Following my code:
Initialization:
char incr = 0;
char mask = 0;
volatile char rdy = 1;
volatile int rev = 0;
void setup() {
DDRB = 15; // 4 lowest pins of B are 1, i.e. digital pins 8, 9, 10, 11
PORTB = 0;
Serial.begin(9600);
Serial.write("Initialized!\n");
}
Caller code of the actual rotation procedure. It reads an integer over serial input uses it for rotation count:
void serialEvent()
{
if(rdy && Serial.available()) // If motor not running AND new serial input.
// Not sure if Serial.available() is needed because serialEvent() only gets called if Serial bus
// reg-/FIFO queue was written by device
{
rev = Serial.parseInt(); // reads # of rotations from serial port
rdy = 0; // rdy == 0 => any further inputs over serial ignored
rotate(); // Rotate for
rdy = 1;
}
}
Wave-stepped:
void rotate()
{
while(rev-- > 0)
{
Serial.print("Revolution: ");
Serial.println(rev);
for(int i = 0; i < 512; ++i)
{
Serial.println(i);
mask = 1 << incr;
PORTB = mask;
incr = (incr + 1 ) % 4;
delay(10);
}
}
// Finishes always after LAST iteration,
// i.e. where binary mask goes from 0001 --> 0010 --> 0100 --> 1000, i.e. the last stage finishes
}
Half-stepped (ugly code, but I want to get it right before rewriting it in in a nicer way):
void rotate()
{
while(rev-- > 0)
{
Serial.print("Revolution: ");
Serial.println(rev);
for(int i = 0; i < 128; ++i)
{
PORTB = 1;
delay(10);
PORTB = 3;
delay(10);
PORTB = 2;
delay(10);
PORTB = 6;
delay(10);
PORTB = 4;
delay(10);
PORTB = 12;
delay(10);
PORTB = 8;
delay(10);
PORTB = 9;
delay(10);
}
}
}
Following is the half-stepping sequence:
Unfortunately, I have no idea where I went wrong. I would very much appreciate help in finding my error!