Trouble getting multiple fan RPM speed

Hi all,
I'm working on a pc fan controller to replace my manual controlled laptron fc-5.

I'm a professional programmer so fortunately I'm strong on programming side but I'm kinda new in electronics and microcontrollers, so I really need your help.

After some weeks on google, and many many tests combining all that I red and the circuits of this two guides:

this one also was interesting:
https://www.maximintegrated.com/en/app-notes/index.mvp/id/1784

I managed to control the speed of 3wire pc fan (actually 3x0.62A connected in parallel or just one 1000rpm fan) and correctly reading rpm speed!
The easy part was control the speed, the real trouble was filter out the pwm generated EMI in the tacho.
You can see the working schematic in the attached picture (qfet-schema.png).
5v from the schema is arduino +5v out, ground is common between pc power supply and arduino.

After that I made another circuit to control 4wire pwm fans, really easy this time, rpm red with no problem. Schema attached (picture pwm-schema.png)

For both the circuit I needed also to change, on the Arduino Mega that I'm using, the pwm frequency to 31Khz to moving the electrical noise in the not audible range.

The problem in which I'm stuck right now, is when I connect the two fans together I get wrong rpm, but right real speed control in every situation.
Detail of the problem:

  • both PWM at 100% duty cycle, rpm red correctly
  • pwm of PWM fan at 0%, rpm of 3wire fan at any pwm duty cycle
  • both PWM at about 50% duty cycle, rpm of PWM fan is correct, rpm of 3wire fan alligned or over the pwm fan
  • same circuit, but pwm fan with just ground disconnected, 3 wire fan rpm red correctly at any pwm duty cycle
  • same circuit, but pwm fan with just tacho disconnected, 3 wire fan rpm red alligned or over the pwm fan

Code that I use to red fan rpm is also attached, I instantiate two object of my FanTachometer class with the two input pins and two different interrupt index (0 and 1). My guess is that EMI from PWM fan arrives to 3wire fan tacho from the common ground. But I have no idea how to fix this.

Any suggestion or help is really appreciated! I hope that things is clear and if anyone need more details or other stuff to understand my work I'm ready to explain all that is not clear.

Thanks

FanTachometer.cpp (3.01 KB)

FanTachometer.h (2.08 KB)

In these small environments avoid dynamic allocation like it's ebola. No Strings for your own sake, C strings are easy and stable.

We have a way of running tasks cooperatively with no OS (write your Own bugs!) slicing time but rather taking time by means of independent blocks of code running over and over in void loop() all coded to run quickly and not block execution.

What can I say? It's -not- how you code when you have a MTOS nor is dealing with cigar-box size RAM! There is plenty to an Uno chip but very little to waste, you can make bits count as more than an exercise here.

It's not hard to make a task for each motor as a code object either.

If you get serious with AVRs you will likely want to get Atmel Studio.

Thanks for your advises! In fact i'm dynamic allocating those two objects, but fortunately that's all that is allocated in this application.
I'm already using the time slicing technique to avoid using delays and doing a lot of stuff in the loop. Like updating my 2.8" ips screen with the lastest data. I update fan rpm's every 0.5 second.

Do you have any idea for this specific problem that I'm trying to solve?

"My guess is that EMI from PWM fan arrives to 3wire fan tacho from the common ground. But I have no idea how to fix this."

You have the tacho line pulled up to 5V pretty strongly.

How heavy are your ground wires?

Did you put decoupling caps across power and ground, DC motor leads? They reduce noise.

The ground wires, like all other wires that I'm using are normal prototyping wires used with breadboards. My circuit is built on top of two breadboards.
This evening (on my time zone, I'm in italy utc +2) I'll post a complete scheme of the connections and some picture to clarify all!

About decoupling capacitors, no, I've none of them in my circuits, this is actually the first time I heard about them, so I took a first glance on the subject and maybe it could help with my problem. I'll try add some even if it's not perfectly clear how should I add them having two +V sources (+5v from arduino and +12v from power supply) in my circuits. I'll study better the subject this evening!

Decoupling caps go across power and ground to dampen out fluctuations between them in DC circuits. Arduino runs on 16 MHz clock, uses 2 (1 per VCC and GND) to tame the 'noise' from fast on/off power use by the clocked chip.

I someway managed to make things working. But I suspect that works only whit this cabling setup.

Here what happened.

I started reorganizing the board, to make things clearer in order to can take a picture to post here and I found that just reorganizing things on the board changes the intensity of the issue. I had the circuit whit that Qfet on a second breadboard, just moving it on the main board made the issue worse!

So I started with coupling caps as you suggested, adding on on the +5V to Ground seemed at start to not making any difference. Adding the other one on the +12v to ground, instead made things a lot worse!

Then I found that if I replace the capacitor near the tacho in the qfet schema from 0.47uf to 0.068uf(68nf) made things working, but as I said before I suspect that I will need to change again the capacitance power expanding the circuit to support all the fans there's on my pc (actually 5+water pump). In the final circuit that now is working adding 100nf capacitor in +5v helps fine tuning the result a little more in terms of oscillation of the tacho reading.

Do you know why adding any capacitance value that I have on the +12V to ground make things worse? Any other suggestion?

Really thanks for your help GoForSmoke! It really helped my moving further on this issue!

Attached the photo of the circuit now.

How did you choose your de-coupling capacitors? Where did you put them?

I have to follow "cookbooks" to get these things right.

One thing very often suggested to stabilize a project is to put a decoupling cap across the power source leads and smaller decoupling caps across chip VCC and GND pins.

There are several precautions you can take to help reduce the effects of motor noise on your system:

  1. Solder capacitors across your motor terminals. Capacitors are usually the most effective way to suppress motor noise, and as such we recommend you always solder at least one capacitor across your motor terminals. Typically you will want to use anywhere from one to three 0.1 µF ceramic capacitors, soldered as close to the motor casing as possible. For applications that require bidirectional motor control, it is very important that you do not use polarized capacitors!

If you use one capacitor, solder one lead to each of the motor’s two terminals as shown to the right above.

For greater noise suppression, you can solder two capacitors to your motor, one from each motor terminal to the motor case as shown in the picture to the right.

For the greatest noise suppression, you can solder in all three capacitors: one across the terminals and one from each terminal to the motor case.

  1. Keep your motor and power leads as short as possible. You can decrease noise by twisting the motor leads so they spiral around each other.

  2. Route your motor and power wires away from your signal lines. Your motor lines can induce currents in nearby signal lines. We have observed voltage spikes as high as 20 V induced in completely separate circuits near a noisy motor.

  3. Place decoupling capacitors (also known as “bypass capacitors”) across power and ground near any electronics that you want to isolate from noise. The closer you can get them to the electronics, the more effective they will be, and generally speaking, the more capacitance you use, the better. We recommend using electrolytic capacitors of at least several hundred µF. Note that electrolytic caps are polarized, so take care to install them with the negative lead connected to ground and the positive lead connected to VIN, and make sure you choose one with a voltage rating high enough to tolerate the noise spikes you are trying to suppress. A good rule of thumb is to select one that is rated for at least twice your input voltage.

I've read the article, interesting!

It is definitely a noise problem I think at this point, as I suspected adding a third 3 wire fun in the setup broken it. All three working perfect when alone, but with just the two 3wires alone it start being broken (always the newest one qfet circuit output rpm is broken, even if I switch the fans) and it's a disaster when all three are at about mid power.

From the article that you posted I tried adding some several hundred capacitors between +12 and ground and +5v and ground but seems not being enough to fix the problem. I haven't had the time to add the 0.1uf capacitor near the engines (fans in my case) terminals, but I's the next thing that I will try tomorrow evening.

Again from the article, being the fans case made in plastic how am I supposed to connect the additional 2 caps?

I don't know what you're doing. It shouldn't take more than a few caps total.

I haven't looked at your code which could have timing problems of its own. Does it have delay() calls or other commands or loops that keep waiting until done?

What you want should not be a problem but I see you overdo things and no surprise to me it has bugs.

You need better help.

I think that there was a misunderstanding. For some serveral hundred caps, I meant that I tried some different caps sizes (on several hundred uf sizes range) but always only one at time for each +12v and +5v lines.

So far with two fans (1pwm and 1 3wire) the system was working. So I tried to add a third fan 3wire circuit to see if the system was stable. What was wrong with that? I'm just asking to understand what not to do the next time.

I didn't use any delay function in my code, apart from one 10ms delay when I turn on the 5v on a analog pin that goes to the 4 thermistors to read temps (and that it's turned off to don't overheat the thermistors), this every two seconds. Yes could be also a code bug, could be.

If you want to take a glance at the entire code this is the link to the repo. I haven't cleaned up completely the loop function but should be easy to read.

So in order to fix the problem and don't overdo things as you said. This eve I'll try just to connect things as your guide for reduce noise suggested and ? Debugging this kinda of stuff it's different from debugging software, what step do you suggest to do?

Thanks again

Get a hardware person to help. I can't get you farther.

I have been struggling with this same problem for a while. I have found that the hall sensor inside the 3 wire fans are normally powered by the input voltage of the fan. Since a 3 wire fan is not normally PWM controlled but controlled with a constant voltage which is raised or lowered to measure speed the hall sensor is always powered. If you run the fan with a PWM signal at 12v but changing duty cycle to change speed, the hall sensor is also being turned on and off at the same rate as the fan motor. This causes the tach square wave to float high when the PWM signal is low. You will need to implement pulse stretching, where every so many pulses of the PWM signal you need to hold it high for a longer period so the tach signal generated by the hall sensor can be read accurately.

this explains it better than me.

Thanks for your reply!
At this time I've abandoned the project but, thing was that when I was connecting just one three wire fun the readings worked cause I've kinda of smoothed the pwm function to a flat wave (to power up the hall sensor has you said), the problem was when I was adding more funs in the system the tacho reading starts to be broken, the aim was to control up to 4 funs.