I'm trying to develop a simple version of a bi-pap my friend uses, which isn't exactly used as a bi-pap but more like a hookah she takes a "hit" off of to help her breathe.
To do this I bought a bi-pap blower which comes with it's own control board (it's a 3-phase DC motor), and the board simply needs a simple PWM signal as a speed control. It specifies it can take PWM frequency 16-32kHz, but is best to send it 25kHz.
I downloaded the PWM.h library as well as tried changing the PWM frequency via some other methods I've found online, and each method I use has a similar problem. I am finding that the fans speed does not respond linearly to the pulse width. Instead it seems to wrap around it's endpoints, oscillating between a lower speed and higher speed as I vary the pulse width from 0-255. I also saw I should maybe change my PWM range to 0-320. I've tried both. I know from the data sheets on the blower that it shouldn't do this, and that it should come to a halt around 3-5% duty cycle.
Any ideas on why this is happening? I've uploaded my code here but I suspect this issue is more of a fundamental thing I don't understand about how PWM works. This is being done on an arduino UNO.
Here's my code:
#include <PWM.h>
const int potPin = A0; //Pin to read potentiometer voltage
//const int signalPin = 8; //Pin to read motor driver speed pulses
const int speedPin = 9; //Pin to send speed control PWM signal
int32_t frequency = 25000;
int potVal;
int speedVal;
void setup() {
//initialize all timers except for 0, to save time keeping functions
InitTimersSafe();
//sets the frequency for the specified pin
bool success = SetPinFrequencySafe(speedPin, frequency);
//if the pin frequency was set successfully, turn pin 13 on
if(success) {
pinMode(13, OUTPUT);
digitalWrite(13, HIGH);
}
Serial.begin(9600);
//pinMode(signalPin, INPUT);
pinMode(speedPin, OUTPUT);
}
void loop() {
potVal = analogRead(potPin);
Serial.print("potVal= ");
Serial.print(potVal);
speedVal = map(potVal, 0, 1023, 0, 320);
Serial.print(", speedVal= ");
Serial.println(speedVal);
pwmWrite(speedPin, speedVal);
delay(100);
}
I tried both 255 and 320. Neither of them solve it they just shift the center point of the oscillation. The fundamental behavior is the same for both values, where the blower behaves as if it's never receiving a duty cycle of 0, and as if the lowest duty cycle it receives is around the center of the PWM range. Meaning, PWM = 0 and PWM = 255 both result in the fastest blower speed, and around the center of the PWM range results in the lowest speed.
I think @paulpaulson is correct, the pwmWrite() function expects a value between 0 and 255. If you give it a value outside that range, you will get unexpected and confusing results.
Have you tried disconnecting the motor from pin 9 and attaching an ordinary led (+ series resistor of course)? This should enable you to check that the PWM output is as expected, with the led varying between off and maximum brightness when you adjust the pot. It might not look linear, because of the way the human eye perceives brightness, that is normal. Better still, if you have access to a 'scope...
If the led works as expected, then I suspect the strange behaviour you are seeing could be due to the way your motor works. Please post a link to the data sheet. Perhaps we can help you understand how to control it once we have read that data sheet.
using analogWrite() will not achieve the 25KHz PWM frequency that @touchbot needs for the motor they are using. With analogWrite(), the frequency will be only 0.5~1KHz, which is far outside the recommended range mentioned in post #1, and even if it did work would be likely to cause unpleasant sounds. Using a PWM frequency of 25KHz would avoid that problem since it is above human hearing range.
@touchbot please confirm where/how you downloaded the PWM library you are using. I may be able to try your sketch myself and use my 'scope to verify if the PWM signal is produced correctly.
It's not that one, so I will give that one a try and get back to you.
I did try an LED and it does pretty smoothly transition from off to full brightness, so I am confident I'm sending the right duty cycle. I am just unable to verify that the pulse frequency is correct.
I just ordered an oscilloscope cause I'm going to need one for other projects, so I will be able to verify that way.
I suspect that I am not actually sending a pulse frequency within the motor drivers acceptable range (16-32kHz with 25kHz ideal) but the coming scope will tell me for sure. And the motors/driver combos spec sheets show a very linear RPM vs duty-cycle curve, with a statement that the threshold for motor start/stop is 3-5% duty cycle. So I definitely should be able to get the motor to stop when sending a 0% duty cycle, and I definitely can't. Yet the LED test shows it will go fully off. This is what leads to think the UNO isn't sending the right frequency. If it turns out is (when verified by a scope) then I'd bet the control board is defective somehow.
Can't upload a drawing (forum won't let me since I'm so new). But it's extremely simple.
Arduino UNO is powered by USB directly from PC where I'm scripting.
The motor driver is being powered by a programmable power supply, set to CV at 24V (it wants 18-26VDC (and yes it can supply the current the driver would need). There's a single 10K potentiometer between 5V and ground coming off the UNO. The sense pin on the pot is coming into A0. Pin 9 on the UNO is going to the PWM input on the motors control board.
The only input the control board needs is a PWM signal.
It's so important to specify what libraries are being used when you ask for help on the forum, including their author and version, otherwise so much time can be wasted. But I don't think that's happened today.
Exactly. But as you can see from the bottom right corner of the images I posted, the library I used gave an absolutely rock-steady 25.00KHz throughout. I suspect the version you used will be the same.
Thank you for the tips. I will be sure to specify where I found the library in the future.
I suspect now that I may have damaged the control board. I did accidentally send the PWM signal to another lead it has, which sends pulses to calculate the exact motor speed. Looking at it more carefully, it says to put a resistor in series so that no more than 20mA can flow on that lead, and I put a digital pin output directly onto it which can push a bit more than that (I think the UNOs digital pins can push 80mA?).
Thanks for your help I'll update when I know more!
I verified with an oscilloscope that I am sending 25kHz pulses (40us period) via Pin 9, and that my duty cycle is linearly moving from 0 to 100%, so I am convinced it's a problem with the control board.