Goal
I am building a bead dispenser, and I made some good progress so far. Users can input the number of plastic beads they want to receive. Let’s say a user enters 3. The stepper motor will start to rotate and if a single bead is falling through a hole in the dispenser, it will break the IR beam and the counter gets incremented. If the counter is equal to the user’s input the motor will stop.
Problem
During development, I noticed that if Arduino is turning the stepper motor it is blocking subsequent code. Subsequently, I am actually performing the check if the IR beam was broken. Because of the blocking behavior, I ended up making the step size as little as possible (i.e., 1 — (see lines 90 and 91).
This code is working okay. Let’s say the accuracy is around 80%; however, I am looking for a different approach:
Solution
I am a freshman in the Arduino sphere but I guess there must be a solution to instruct the Arduino to rotate the stepper motor independently from IR beam breaker. However, once the input is satisfied, the motor should also stop and wait for new input.
I am trying to make a video now, I guess this could be helpful.
UPDATE:
of course, but as there is some latency between a bead falling in the hole and it's detection by the IR beam, you need to be careful how fast you rotate the motor or when you arrive at the expected count there might be already a new bead "in transit".
This is correct, controlling the speed is another issue, because at step size 1, values for the setSpeed(X) method have no effect... But I guess once the motor moves independently I regain control of speed...
while (isCounting) {
myMotor->step(1, FORWARD, SINGLE); // ➜ perform 1 step
➜ then do a state change detection
if you want independent behavior, you need to use a library that is non blocking (if I remember correctly Adafruit_MotorShield is blocking). Using AccelStepper for example would let you achieve this
--> once you get a count from the Serial console you ask the motor to spin (set a very far step count) and then you await for the beads. Once you got the right count, you stop the motor.
bonus point, as you get closer to the count, you slow down the motor up to a point you go very slowly between two steps to ensure you don't get one extra bead.
Thanks for the cue; I’ll check out AccelStepper — btw. is there any go-to library for stepper motors? I was just using the Adafruit Motorshield Library because it was used in some tutorial.
Hey @J-M-L; I added a few in my script to use the AccelStepper library, which indeed increases the accuracy a lot — Yet, I got a strange bug, and hope it is okay to follow up within this thread. Once I enter the first number in my Serial Monitor everything rotates at the given speed as it is supposed to be, and when the expelled beads equal the provided number the motor stops. Yet, if I enter the second number; the motor turns at a really slow pace (iooks like 1 step (1.8°) per second) slow.
Any idea why the first run is normal and consecutive runs are acting weird?
No, the Accelstepper cannot directly drive a motor by means of the Adafruit_Motor_Shield_V2. This motorshield uses I2C commands for stepping. The Accelstepper lib needs assistance from the Adfruit_StepperMotor to do the steps.
Thanks, @MicroBahner for chiming in. And thank you @J-M-L for that suggestion putting setSpeed() before runSpeed()! That actually did the trick! Love it!