(Current) Stepper Motor with Peristaltic Head
Pump
I found a peristaltic pump with a Stepper Motor on Amazon:
https://www.amazon.com/gp/product/B01KLWHR1G/ref=oh_aui_detailpage_o03_s00?ie=UTF8&psc=1
I bought one for just under $50; since then it has been marked as "Currently unavailable".
Controller
The motor controller is an EasyDriver Stepper Motor Driver for $15.
https://www.amazon.com/gp/product/B004G4XR60/ref=oh_aui_detailpage_o08_s00?ie=UTF8&psc=1
I hooked this up to an Arduino Mega:
Software Tools
I have been converting to JetBrains products from Eclipse and Netbeans IDEs. I used the CLion IDE from Jetbrains https://www.jetbrains.com/clion/ and installed a couple of plugins:
- Serial Port Monitor - allows you to see UART output from the Arduino within CLion
- Arduino - allows you to write and compile Arduino code from CLion
Check Setup
First, I wrote a bit of code for the Arduino to ensure the controller worked ok. All it did was pulse the controller pin and then sleep for 500ms. That double-checked these were functioning ok:
- controller
- all wiring to the correct Mega GPIO pin
- compilation, download, etc. and the Mega Arduino itself
The motor "ticked" every half second as expected. I tried faster speeds and the system behaved as expected. This test code setup was done in the main loop
Next I needed to check that this pulsing could be done in an Interrupt. I created an ISR (interrupt handler) based on a 1ms timer which incremented a counter. Every 500 counts, it would tick as the stepper was pulsed, again the system behaved as expected.
I also checked the timer. I toggled another GPIO line every interrupt and checked the frequency on that pin with an oscilloscope. It matched the expected frequency within a few decimal places.
I wanted to be able to set the pulse rate from a Ruby script over a Serial Port/UART line I wrote some test code to simply receive a few bytes over the UART line, add a couple of other bytes and respond back to the sender. I wrote the sending code in a Ruby script and the communication worked as expected.
Main Loop
At this point, all the pieces were in place, and I was sure they were working correctly.
The overall design is simple.
-
In setup()
- initialize the IRQ timer to run every milli-second
- initialize the UART
- initialize a global array with 1000 entries to 0s; it holds the pulse count for every ms
- initialize a global index into the array
-
in ISR:
- increment the global index; if past the end of the array, set to 0
- pulse the Stepper GPIO pin with the number of pulses (0 - 255) in the array
-
in loop()
- If there is an incoming character on the UART
- read the incoming character string until the end of the packet; this holds the total number of pulses to set up per second
- check for a valid Pulses Per Second (pps) value
- if valid, distribute those pulses evenly throughout the array
(Previous) 12VDC Motor with Peristaltic Head
Pump
I found this 12V DC pump with a peristaltic head on Amazon for less than $20.
https://www.amazon.com/gp/product/B0196LDFJQ/ref=oh_aui_detailpage_o07_s00?ie=UTF8&psc=1
It is a simple 12V DC motor, no encoder or other feedback is available.
The peristaltic head has 3 rollers that are rotated by friction via the motor's shaft. The pump has some flexible tubing that wraps around the rollers. The tubing and rollers are in a hard plastic outer case.
When the motor turns the shaft which cause the rollers to rotate. This action pinches the tubing against the outer case. The fluid in the tubing is trapped in the spaces between the rollers. Since the tubing does not move (except to get pinched) the fluid is pushed through the tubing.
The seal between the rollers, tubing and outer case is quite good. It can self-prime, in other words, it can pump air and the negative pressure on the incoming inlet is sufficient to pull water from the reservoir.
The motor shaft is chrome so there is a high potential for slip.
Controller
The motor controller is a Pololu Jrk 21v3 USB Motor Controller
https://www.pololu.com/product/1392
A control value from 1 to 255 is sent to the controller via a USB port and then DC motor runs at whatever speed it goes at - more or less proportional to the voltage applied to it by the controller. A control value of 0 means stop and the controller also has a special stop instruction. Negative numbers can be used to cause the motor to reverse direction.
This controller can run open loop or closed loop. Since the pump had no feedback mechanism (i.e. no shaft encoder) it was run open loop. A control value was sent to the controller which turned the DC motor at a particular speed. There was no mechanism to detect that the motor was turning at that speed or even if it was turning at all.
Lack of feedback caused some problems. For example, at very low speeds the motor stalled and there was no way for me to detect that condition within the control software.
The controller has a serial interface that uses a binary (non-Ascii) serial protocol. This caused some small problems since I used Ruby to talk to it, but they were easily overcome using the correct serial IO calls.