How do I read the feedback signal from a brushless peristaltic pump using an Arduino

Hello,

I recently purchased a brushless peristaltic pump and have a question about it, which I'm hoping someone on this forum can answer. As you can see from the attached image, the pump has 5 wires. I've already figured out how to send a PWM signal and change the flow direction of the pump using an Arduino UNO, but the wire I am specifically enquiring about in this post is the green one, or the feedback signal. I am trying to control the peristaltic pump with a PID controller, and from what I understand, I need a measured process variable to help the controller determine how to minimize error, which I'm assuming the feedback signal can provide me with. 1.) How exactly would I go about reading/interpreting the signal from the green wire using an Arduino UNO? Is there a standard protocol to follow when attempting to read the feedback signal of a brushless motor? 2.) I'm aware that I need to know the pulses per revolution of the motor, which I already know, in order to calculate the RPM, but what equation should I be using after I've figured out how to interpret the feedback signal from the green wire?

Thanks in advance,

You need to identify what type of signal the green wire is carrying. It's likely an encoder or tachometer signal.

If it's an encoder signal, you could use an interrupt-based method to count the number of pulses generated by the encoder. This will help you track the actual revolutions of the motor.

If it's a tachometer signal you could use the pulseIn() function to measure the pulse duration, which will also give you information about the motor speed.

do you have the spec of the pump?

never use pulseIn() its a blocking function and will prevent you from doing anything else. use an interrupt along with a timer to measure the time it takes for a full revolution

KPHM100 Product Manual A1.pdf (754.5 KB)

The specs of the motor is in section 2.2, but it does not state whether the feedback wire is a tachometer or encoder signal. I guess I could try both methods to determine what signal it is.

what if its a tachometer signal? or should I just use an interrupt with a timer regardless if its a tachometer or encoder signal

You should read and study the product manual of the pump refers to.

seems this is your post too on another forum

if you get your hands on an oscilloscope then you can assess what's this feedback wire does

I found this in cache with google

so it would seem it's an encoder signal

Thanks for finding that.

So I should use your suggestion of using an interrupt based method to count the number of pulses? I'm assuming I need to attach the green wire to one of the interrupt pins on the Arduino board right? so for the UNO that would be either pin 2 or 3?

For testing purposes you could use polling

try something like this (typed here, untested)

const byte feedbackPin = 2;     // green wire
const byte directionPin = 4;    // yellow wire
const byte speedPin = 5;        // blue wire (needs to be a PWM pin. on UNO pins 3,9,10,11 are at 490,20 Hz and pin 5 and 6 are at 976,56 Hz. Required 5-20KHz => 5 or 6 better suited)

int currentPWMSpeed = 0;

void setup() {
  pinMode(feedbackPin, INPUT);
  pinMode(directionPin, OUTPUT);
  pinMode(speedPin, OUTPUT);

  analogWrite(speedPin, currentPWMSpeed);
  digitalWrite(directionPin, LOW);

  Serial.begin(115200);
  Serial.println(F("FEEDBACK"));
}

void loop() {
  int command = Serial.read(); // will return -1 if nothing to read
  switch (toupper(command)) {

    // set speed 0 = stop, 9 = full speed, 1..8 linear interpolation in between
    case '0' ... '9':
      currentPWMSpeed = map(command, '0', '9', 0, 255);
      analogWrite(speedPin, currentPWMSpeed);
      // Serial.print(F("PWM set to ")); Serial.println(currentPWMSpeed); // if you don't use the Serial plotter
      break;

    // stop
    case 'S':
      analogWrite(speedPin, 0);
      // Serial.println(F("STOP")); // if you don't use the Serial plotter
      break;

    // full speed
    case 'F':
      analogWrite(speedPin, 255);
      // Serial.println(F("FULL SPEED")); // if you don't use the Serial plotter
      break;

    // ignore anything else
    default:
      break;
  }

  Serial.println(digitalRead(feedbackPin) == LOW ? 0 : 100); // for the Serial plotter
}

  • you wire the power to the motor (don't power from your arduino), join grounds.
  • connect the green wire to pin 2
  • connect the yellow wire to pin 4
  • connect the blue wire to pin 5

Then upload open the code and open the Serial plotter (in the tools) at 115200 bauds

you can type a number from 0 to 9 and enter to set the speed or S for stop or F for full speed.

the plotter will be like a cheap oscilloscope showing what's going on (at the speed of the loop) with the green wire output.

1 Like

Thanks for writing the code. I will try this out tmr and report back here to let you know what the plot looks like.

Above is a segment of what the plot looks like. From a layman's interpretation it looks like a pulse of some sort. Does this mean that it is an encoder signal?

yes it seems you get a pulse from time to time. it's not regular - did you modify the speed when capturing the snapshot ? (at constant speed if this is indeed one pulse per rotation you should get spikes at regular intervals unless the spike is so short that the polling method does not work and then we need to go to ISR)

do you have access to an oscilloscope?

I left it at full speed the whole time. I do not have an oscilloscope right now but I can get a cheap one.

https://www.aliexpress.com/item/1005005954334084.html?spm=a2g0o.productlist.main.11.1c06HJsGHJsGsI&algo_pvid=05a65692-22d5-4ac4-87b6-af5b30f2dc2a&algo_exp_id=05a65692-22d5-4ac4-87b6-af5b30f2dc2a-5&pdp_npi=4%40dis!HKD!437.89!175.12!!!55.96!!%402101f04d16979619252888648e1d2f!12000035010568156!sea!TH!140100699!&curPageLogUid=cRCMtKcLCUvZ

Would the above oscilloscope suffice?

I don't know how good that is for that price... they sample at 200kHz that should be plenty enough for capturing spikes if you get one per rotation

It's always a good tool to have in a toolbox but I would not buy it if your only use is to confirm the nature of the signal...

can you type 1 or 2 in the serial plotter text entry to set the speed to something low and share the look of the diagram ?

This is what the plot looks like when typing 1

This is what the plot looks like when typing 2

I should note that the segments shown above repeats

it's not very convincing... either there is bouncing happening or it's not a pulse signal but a PWM.

let's try a different code counting the number of RISING (LOW to HIGH) transitions on that pin and reporting it every 5s

const byte feedbackPin = 2;     // green wire
const byte directionPin = 4;    // yellow wire
const byte speedPin = 5;        // blue wire (needs to be a PWM pin. on UNO pins 3,9,10,11 are at 490,20 Hz and pin 5 and 6 are at 976,56 Hz. Required 5-20KHz => 5 or 6 better suited)

int currentPWMSpeed = 0;
volatile unsigned long pulseCount = 0;
unsigned long startTime;
unsigned long samplingDuration = 5000;  // 5 seconds in milliseconds

void countPulse() {
  pulseCount++;
}

void setup() {
  pinMode(feedbackPin, INPUT);
  pinMode(directionPin, OUTPUT);
  pinMode(speedPin, OUTPUT);
  analogWrite(speedPin, currentPWMSpeed);
  digitalWrite(directionPin, LOW);
  Serial.begin(115200);
  attachInterrupt(digitalPinToInterrupt(feedbackPin), countPulse, RISING);
}

void loop() {
  int command = Serial.read(); // will return -1 if nothing to read
  switch (toupper(command)) {

    // set speed 0 = stop, 9 = full speed, 1..8 linear interpolation in between
    case '0' ... '9':
      currentPWMSpeed = map(command, '0', '9', 0, 255);
      analogWrite(speedPin, currentPWMSpeed);
      break;

    // stop
    case 'S':
      analogWrite(speedPin, 0);
      break;

    // full speed
    case 'F':
      analogWrite(speedPin, 255);
      break;

    // ignore anything else
    default:
      break;
  }


  if (millis() - startTime >= samplingDuration) {
    // --- critical section, we simply detach the ISR to keep things simple ---
    detachInterrupt(digitalPinToInterrupt(feedbackPin));
    unsigned long pulseCountCopy = pulseCount;
    pulseCount = 0;
    attachInterrupt(digitalPinToInterrupt(feedbackPin), countPulse, RISING);
    // --- end of critical section
    Serial.print("Pulse count: "); Serial.println(pulseCountCopy);
    startTime = millis();
  }

}

run that with the Serial monitor (not the plotter) opened at 115200 bauds

it should report the number of pulses seen every 5s and this should be consistent
try to increase the speed to 1, 2, 3, 4, ... and see if there is a change in the pulse count

copy and paste the Serial monitor output (as text, with code tags) here

I should note that after running the code and changing the PWM, the pulse count takes a while to stabilize (about 30 seconds to a minute). Also, I'm not sure if it's a characteristic of the motor, but the PWM level is reversed, so a PWM level of 1 is full speed and a PWM level of 9 is zero speed.

The following is the first 50 seconds of pulse count after the readings have somewhat stabilized:

PWM - 8:
Pulse count: 2445
Pulse count: 2448
Pulse count: 2443
Pulse count: 2447
Pulse count: 2450
Pulse count: 2450
Pulse count: 2438
Pulse count: 2497
Pulse count: 2453
Pulse count: 2442

PWM - 7:
Pulse count: 3530
Pulse count: 3544
Pulse count: 3491
Pulse count: 3542
Pulse count: 3524
Pulse count: 3551
Pulse count: 3544
Pulse count: 3516
Pulse count: 3528
Pulse count: 3561

PWM - 6:
Pulse count: 4680
Pulse count: 4690
Pulse count: 4688
Pulse count: 4587
Pulse count: 4657
Pulse count: 4639
Pulse count: 4658
Pulse count: 4550
Pulse count: 4649
Pulse count: 4707

PWM - 5:
Pulse count: 4848
Pulse count: 4852
Pulse count: 4786
Pulse count: 4897
Pulse count: 4832
Pulse count: 4786
Pulse count: 4897
Pulse count: 4832
Pulse count: 4864
Pulse count: 4887

At a pwm level of 9, the pulse count consistently stays at 0.

So you are getting multiple hundreds pulses in 1s - like ~245 at speed 8.

If that was an encoder (1 pulse at every turn) it would mean your pump is running at ~15000 RPM at slow speed and would go to ~30000 RPM at speed 5

Does it sound realistic? Can it spin that fast? The flow rate graph in your doc does not indicate that - so it’s likely a PWM signal.