What's new

Open Source PWM Fan Controller

Yep, the potentiometer is linear! For the sake of my own learning, may I ask what the benefits are of the parameterized equation over just using the mapped values? I know I'm putting my lack of understanding on full display here, but it's a great way to learn haha.
Readability and slightly faster usually, less chance for weird interpretation behavior. At least if it is a linear relationship. And it can make it easier to do things like change the range.

For the non-linear thermometer, mapping may be better.
Just blind intuition shooting from the hip, it seems like if I'm already going to have the temperature sensor mapped to relevant temperatures Fahrenheit, and then map the potentiometer to useful temperature values for tuning, I could come up with a simple code to just add the mapped potentiometer value to the preset min/max temp range. So essentially something like (not code, just theory)

mapped_potentiometer = full 0-1023 range mapped to a range of -30 to +30

Then
Minimum duty cycle temperature = 160 + mapped potentiometer
Maximum duty cycle temperature = 210 + mapped potentiometer
Different ways of doing things. If you find one more readable or easier to follow, that's the one you should use. On an extreme technical view, one may run slightly faster or use slightly less memory, but saving nanoseconds and bits is probably not important here. And what you're suggesting may be the faster one.

On a side note, it is probably a good idea to not hardcode any values in the code and instead use variables to hold any value that may need changing.

Also, some fans need an inverse pwm signal. It also could be that the fan and generator have a different understanding of what the pwm signal is. The fan could be looking at % high while the generator is % switch to ground.
 
You should be good since you have no other inputs from vehicle power. I suppose if something goes way wrong you could have the PWM output to the fan backfeed power somehow, but its probably not worth worrying about.
Sweet, If I do burn it up, you guys will be the first to know :lmao:.

Amazon parts orderded. Misunderstood the fan is a Jeep JL fan and not some fan made by some company named JL... so looking on junkyard dog for a fan.

Cool. Yep it's a Jeep JL fan. I found a great post in the Cooling Fan Tech thread (link in the original post) about them, and then found a fantastic source for the fans. One of the companies doing engine conversions in the latest jeeps are replacing the nearly new fans, and selling them dirt cheap. This one cost $135 shipped :smokin:. Even brand new they're priced pretty reasonable, but I couldn't resist when I found these guys:

Mopar Radiator Fan Cooling Module Complete with Shroud; Wrangler JL & Gladiator JT

Readability and slightly faster usually, less chance for weird interpretation behavior. At least if it is a linear relationship. And it can make it easier to do things like change the range.

For the non-linear thermometer, mapping may be better.

Different ways of doing things. If you find one more readable or easier to follow, that's the one you should use. On an extreme technical view, one may run slightly faster or use slightly less memory, but saving nanoseconds and bits is probably not important here. And what you're suggesting may be the faster one.

On a side note, it is probably a good idea to not hardcode any values in the code and instead use variables to hold any value that may need changing.

Also, some fans need an inverse pwm signal. It also could be that the fan and generator have a different understanding of what the pwm signal is. The fan could be looking at % high while the generator is % switch to ground.

Thanks for that, completely makes sense. While I'm definitely guilty of hard coding some values in with my testing, I absolutely see the value in making them a variable to be referenced, especially if they end up being referenced more than once. Minimize error and make it as intuitive as possible.

Great notes on the PWM signal too, I'm going to tap into the output of that little box and see what signal it's actually delivering. Would be a funny but bad day to find out the hard way that I have the duty cycle ranges backwards from intended haha
 
Thanks for that, completely makes sense. While I'm definitely guilty of hard coding some values in with my testing, I absolutely see the value in making them a variable to be referenced, especially if they end up being referenced more than once. Minimize error and make it as intuitive as possible.
This may be relevant:
Great notes on the PWM signal too, I'm going to tap into the output of that little box and see what signal it's actually delivering. Would be a funny but bad day to find out the hard way that I have the duty cycle ranges backwards from intended haha
I'm guessing that the little box is generating as % time high. And in my experience with some spal fans, they are looking for % time grounded.

It's even funnier when another engineer is standing right in front of the fan you thought was starting in low :homer:.
 
This may be relevant:

I'm guessing that the little box is generating as % time high. And in my experience with some spal fans, they are looking for % time grounded.

It's even funnier when another engineer is standing right in front of the fan you thought was starting in low :homer:.

I've got a few constants in the latest iterations of test code I've been tinkering with, but admittedly the min/max range aren't yet haha. To be cured soon!

I bet that was a little exciting depending on how close they were to it :laughing:
 
So dumb question about the voltage spike sensitivity, is the risk of that cured/minimized by the voltage regulator/buck converter I'm using? That's the only connection to the vehicles wiring
Good question really. No, still a problem.
A buck has a shunt diode. When negative transient causes polarity swap, the diode conducts when the switch closes. The switch will close when output voltage drops. Then catastrophic current, damage. Need protection before buck, like a clamp or path outside for energy to go instead of going into buck and damaging it.
Buck-Converter.png


some light reading :)
 
Good question really. No, still a problem.
A buck has a shunt diode. When negative transient causes polarity swap, the diode conducts when the switch closes. The switch will close when output voltage drops. Then catastrophic current, damage. Need protection before buck, like a clamp or path outside for energy to go instead of going into buck and damaging it.


some light reading :)

Cool thanks for the info and additional learning material. I still don't know enough to "know", but picking up bits and pieces. From that link, it looks like I can use an N channel mosfet for reverse polarity protection? Or is the surge from your example more unique than a more generic reverse polarity example?

https://www.infineon.com/dgdl/Rever...2.pdf?fileId=db3a304412b407950112b41887722615

After some fumbling around I've got a functional voltage divider circuit working for the temperature sensor, so all of the critical hardware components (temp sensor, potentiometer, screen) are functioning. When I get back to it tonight I can start fumbling around with the code further and get things acting/reacting to each other.

I've gotta say, this is a pretty cool way to learn this stuff for a hands on learner like me, having a specific application in mind and just going for it. I'm sure it's amusing for you guys, I'm here for your entertainment haha.
 
Version 2 of the case, probably going to print this one for the unit actually going in the jeep, but might wait in case I need to make room for another device for the reverse polarity/surge protection. It got a little wider to make more room for the additional stuff, but worth it. Also bolts together now wtih 3 screws

PWM Fan Controller - 6.JPG




PWM Fan Controller - 7.JPG
 
A little better fit and finish on this one. And learned sharpies like to bleed across layer lines with a bit of capillary action haha. it took me a while to figure out a decent compact bulkhead connection for the temp sensor and PWM output, some brass standoffs ended up working out great

PWM Fan Controller - 8.jpg


PWM Fan Controller - 9.jpg


PWM Fan Controller - 10.jpg
 
One piece at a time, have the screen live updating the effective temp range via the potentiometer. The next two items on the to-do list are making the screen toggle between displays with the momentary switch (done some research, just haven’t implemented yet), along with stepping the PWM frequency down to (appx) 100hz

IMG_9293.jpeg



IMG_9294.jpeg
 
Parts got here, besides the fan. I am gonna have to hit the pause button on the JL fan though, lots of other expenses and time sucks with the Wagoner and house/landscaping work right now... still 135 is a steal so I may get one if they are around in a couple months. I will continue to follow along, but it looks like you got it figured out.
 
Right on guys, thanks for following along with it all. I haven't been uploading the various iterations yet because I wanted to get something closer to functional, but at least hardware wise I think we're pretty much there so I'll get the case files up here soon, as well as links to all of the CAD files I found for the common components

While I've been chipping away at the code side of things, I definitely wouldn't say I've got it all figured out yet :laughing:. Going to see if I can get the momentary switch working as a display toggle this morning. This example seems in line with what I'm going to be attempting to do:

Using a button to change display information
 
Alright I am having an issue I don't understand, if you guys wouldn't mind helping me with some problem solving.

It's a gremlin with the voltage divider circuit for the temperature sensor. I'm using a 390 ohm 1/4 watt resistor as the known value (confirmed resistance right around 388 ohms). One leg goes to a 5v supply (confirmed 4.98v), and one leg goes to an analog input pin. That leg is also T'd to the output of the temperature sensor (which has appx 400 ohm max resistance), and then the other leg of the temperature sensor is grounded.

So with a known resistor value of 390 ohms and the temperature sensor right around 390 ohms at room temp, I should be getting around 2.5v to the T'd analog input leg. I'm only getting 0.4v. This was happening before so I swapped to a different 5v source and it was temporarily cured. Today, the problem is back. If I measure both legs of the known resistor one at a time, incoming is indeed getting 5v, and output is definitely 0.4v. It's not getting hot either. From what I've read the power supply from the Arduino should be capable of 40mA, I assume the fact that I can confirm 5v means I haven't hurt the power supply side of things? But I'm not sure where the drastic voltage drop is coming from.

Here's the circuit, with R1 being the known value and R2 being the temp sensor

Voltage Divider.png
 
Alright I am having an issue I don't understand, if you guys wouldn't mind helping me with some problem solving.

It's a gremlin with the voltage divider circuit for the temperature sensor. I'm using a 390 ohm 1/4 watt resistor as the known value (confirmed resistance right around 388 ohms). One leg goes to a 5v supply (confirmed 4.98v), and one leg goes to an analog input pin. That leg is also T'd to the output of the temperature sensor (which has appx 400 ohm max resistance), and then the other leg of the temperature sensor is grounded.

So with a known resistor value of 390 ohms and the temperature sensor right around 390 ohms at room temp, I should be getting around 2.5v to the T'd analog input leg. I'm only getting 0.4v. This was happening before so I swapped to a different 5v source and it was temporarily cured. Today, the problem is back. If I measure both legs of the known resistor one at a time, incoming is indeed getting 5v, and output is definitely 0.4v. It's not getting hot either. From what I've read the power supply from the Arduino should be capable of 40mA, I assume the fact that I can confirm 5v means I haven't hurt the power supply side of things? But I'm not sure where the drastic voltage drop is coming from.

Here's the circuit, with R1 being the known value and R2 being the temp sensor
So if you measure across R1 you are getting 5v? Is Vout connected? If not try disconnecting it and measuring with a multimeter. You should be using somewhere between 0 and 13 mA or less than .1 W. Have you checked R2's resistance while the circuit is powered?
 
Fucking a man nice work so far.
You are 10 years ahead of me, love the case and changes to it.

:beer:
 
Fucking a man nice work so far.
You are 10 years ahead of me, love the case and changes to it.

:beer:
Thanks man, getting there. I do alright on the CAD front, but I'm swinging blind on the code side :laughing:

So if you measure across R1 you are getting 5v? Is Vout connected? If not try disconnecting it and measuring with a multimeter. You should be using somewhere between 0 and 13 mA or less than .1 W. Have you checked R2's resistance while the circuit is powered?

So while the circuit is powered, measuring voltage from ground to Vin is just a bit shy of 5v. Ground to Vout is ~0.4v. Measuring between Vin and Vout gives me just over 4.5v. I just took the temp sensor out of the equation and replaced it with another 390 ohm resistor to match R1, and the issue persists. With R2 now being a 390 ohm resistor, I'm seeing about 5.2 million ohms across it with the circuit powered

Vout is connected and the Arduino is seeing what I'm seeing on that pin. I haven't unsoldered that leg yet, but I can go ahead and do that for further testing

Edit: I just tested with R2 disconnected, and all voltage measurements are the same as when it was connected. That seems like a big red flag, I'll pull that Vout leg off the board and see what's up
 
Thanks man, getting there. I do alright on the CAD front, but I'm swinging blind on the code side :laughing:



So while the circuit is powered, measuring voltage from ground to Vin is just a bit shy of 5v. Ground to Vout is ~0.4v. Measuring between Vin and Vout gives me just over 4.5v. I just took the temp sensor out of the equation and replaced it with another 390 ohm resistor to match R1, and the issue persists. With R2 now being a 390 ohm resistor, I'm seeing about 5.2 million ohms across it with the circuit powered

Vout is connected and the Arduino is seeing what I'm seeing on that pin. I haven't unsoldered that leg yet, but I can go ahead and do that for further testing

Edit: I just tested with R2 disconnected, and all voltage measurements are the same as when it was connected. That seems like a big red flag, I'll pull that Vout leg off the board and see what's up
I just set up the circuit on a breadboard. I'll check it with power in a little bit
 
Alright good call to have me pull that leg of the resistor off the board. I think I've narrowed it down to something wrong with the analog input pin I was using on the Arduino. . With nothing connected to that analog input pin, it's still seeing ~0.4v (measured from ground). Other available analog inputs are essentially 0v.

So it's probably something I did, but I should just be able to assign it to one of the other pins for further testing
 
Alright just rearranged it to another analog input, problem solved. No idea what caused the failure, but at least whatever it was didn't have a ripple effect on the other inputs
 
Just got done testing it with the read analog example and no issues: Read Analog Voltage | Arduino Documentation

Double check your pinout. Aref is right next to A0. And there is a mounting hole that looks like a wire hole that can throw you off.

Thanks for testing the circuit independently.

Initially I was using one of the 5v pins for my power source for the sensor, but found out about the aref pin and confirmed it was outputting 5v so I swapped to that for power the other day after my initial issues. It made wire routing far more convenient, with aref being my Vin and A0 being my Vout right next to each other. Just now I bumped the potentiometer over to A2 so I could free up A1 for the temp sensor, and now all is well


 
So thanks to the Cooling Fan Tech thread I ended up with a sweet 850w brushless fan from a JL that I'm retrofitting onto my WJ. These fans have constant hot power from the battery, then use a small PWM trigger wire so the control circuit doesn't require any actual power handling. There are plenty of sweet solutions, (Like the SPAL PWM temp sensor from that thread), so I obviously need to go and overcomplicate it :flipoff2:. I'm still an electronics newb and have no interest in doing anything production related with it, so lets open source this thing. I'll be sharing my models for the housing, any useful links and all code stuff here. I'm sure you guys will have some input to make things better and better.

I'm making a unit based on the Arduino Nano, it has 12v input, and a temperature sensor input, then has a PWM output to the fan. Has a knob for varying the temp range, and a display screen to show important data. I think cost will be around $20-25 ish

Now the funny thing (and the curse), I don't really know how to write code so we're going to figure out how terrible ChatGPT is at writing code :laughing:, and then figuring out what's broken and how to improve it as we go.

It's approximately 1.3" x 3.4" long. I don't like that the barrel plug is non locking so that may change.


PWM Fan Controller - 3.JPG


PWM Fan Controller - 4.JPG
Whats the objective here? To vary fan speed by engine temp? Anything programmable is way overkill for this. A couple of op amp circuits can handle nearly any pwm scenario like this and be very robust and adjustable.
 
Whats the objective here? To vary fan speed by engine temp? Anything programmable is way overkill for this. A couple of op amp circuits can handle nearly any pwm scenario like this and be very robust and adjustable.

Oh yeah, I've said multiple times that I'm intentionally overcomplicating the hell out of this including in the post you quoted :flipoff2:. Besides just being a fun little device, I'm also using it as a reason to finally learn Arduinos. But yeah it allows you to set the fan start point, the max duty cycle point, and whatever you want the fan to do in between those points. I figure the adjustability is nice to fine tune the range depending on where the temperature sensor ends up in the cooling system, and what actual temperatures it'll be seeing. The display isn't necessary, but a nice little addition and could help with troubleshooting because it tells you when it's outputting and at what duty cycle, so if the fan ever decides not to work when expected, you can narrow down the cause pretty rapidly
 
Oh yeah, I've said multiple times that I'm intentionally overcomplicating the hell out of this including in the post you quoted :flipoff2:. Besides just being a fun little device, I'm also using it as a reason to finally learn Arduinos. But yeah it allows you to set the fan start point, the max duty cycle point, and whatever you want the fan to do in between those points. I figure the adjustability is nice to fine tune the range depending on where the temperature sensor ends up in the cooling system, and what actual temperatures it'll be seeing. The display isn't necessary, but a nice little addition and could help with troubleshooting because it tells you when it's outputting and at what duty cycle, so if the fan ever decides not to work when expected, you can narrow down the cause pretty rapidly
if I ever have to plug a laptop into a fan controller on the trail I'm selling that vehicle. jmo.
 
if I ever have to plug a laptop into a fan controller on the trail I'm selling that vehicle. jmo.
Bro are you serious?
I am simultaneously doing the same pointless ass project...
WE are trying to learn a task, with out prior training, some of us do this type of shit all the time, sometimes we succeed sometimes we don't.

Have anything to contribute besides your opinion that it's a waste of time?
 
Yeah that's exactly it honestly. It's equal parts learning and making something functional. Learning useful skills is always fun.

So I had to put it aside for a couple days while I focused on other things, but there are only a few more pieces to the puzzle.

First, I've decided I'm doing one more case revision, I'm adding one more bulkhead connection that will force max speed when you complete a ground, for situations like when the AC is running. And I'm actually finally going to print it in black haha.

Next, I still have to figure out how I want to set the PWM frequency to 100hz. You can use the internal timers and divide down to the nearest number, but the closest you can get is 122hz. Unfortunately I just tested the fan, and it stops responding above around 114 or 115hz so that's a no-go. I've been reading about how you can "bitbang" on non-pwm digital pins by telling them to toggle high and low at the desired frequency. Though some references seem to imply the arduino can't do anything else if it's doing that?

One example:
Bitbang PWM on non-PWM pins

Another one that makes me unsure if ithe arduino can still do the other tasks?
Secrets of Arduino PWM

"This technique has the advantage that it can use any digital output pin. In addition, you have full control the duty cycle and frequency. One major disadvantage is that any interrupts will affect the timing, which can cause considerable jitter unless you disable interrupts. A second disadvantage is you can't leave the output running while the processor does something else. Finally, it's difficult to determine the appropriate constants for a particular duty cycle and frequency unless you either carefully count cycles, or tweak the values while watching an oscilloscope."
 
Yeah that's exactly it honestly. It's equal parts learning and making something functional. Learning useful skills is always fun.

So I had to put it aside for a couple days while I focused on other things, but there are only a few more pieces to the puzzle.

First, I've decided I'm doing one more case revision, I'm adding one more bulkhead connection that will force max speed when you complete a ground, for situations like when the AC is running. And I'm actually finally going to print it in black haha.

Next, I still have to figure out how I want to set the PWM frequency to 100hz. You can use the internal timers and divide down to the nearest number, but the closest you can get is 122hz. Unfortunately I just tested the fan, and it stops responding above around 114 or 115hz so that's a no-go. I've been reading about how you can "bitbang" on non-pwm digital pins by telling them to toggle high and low at the desired frequency. Though some references seem to imply the arduino can't do anything else if it's doing that?

One example:
Bitbang PWM on non-PWM pins

Another one that makes me unsure if ithe arduino can still do the other tasks?
Secrets of Arduino PWM

"This technique has the advantage that it can use any digital output pin. In addition, you have full control the duty cycle and frequency. One major disadvantage is that any interrupts will affect the timing, which can cause considerable jitter unless you disable interrupts. A second disadvantage is you can't leave the output running while the processor does something else. Finally, it's difficult to determine the appropriate constants for a particular duty cycle and frequency unless you either carefully count cycles, or tweak the values while watching an oscilloscope."
It might be worth trying the fan at a multiple of 100, like 200.

Another possible option.

Worst case, you can manually time the pwm on a digital out. Depending on how you are doing button presses, you may have to change some other parts of the code.
 
Can you adjust the overall operating frequency of your micro? Sometimes you can use that as an additional knob.
 
It might be worth trying the fan at a multiple of 100, like 200.

Another possible option.

Worst case, you can manually time the pwm on a digital out. Depending on how you are doing button presses, you may have to change some other parts of the code.

Hmm, it would be interesting to note if it can work on multiples of 100, just because. But from what I've been seeing, the pins hooked up to the timers can only do specific intervals including 30, 61, 122, 244, 490, 976 hz, and up into the Khz range. So unless it could work on 490 (which I may as well test), I may be SOL.

How To Change the PWM Frequency Of Arduino for Beginners - NerdyTechy

The manually creating PWM via one of the digital pins seems interesting. The button pushes are doing a digitalRead() on the button state, and then initiating a counter, so count 0 is one screen, count 1, is the second screen, and cound 2 is the third screen. I'm not sure if that would cause conflicts?

Can you adjust the overall operating frequency of your micro? Sometimes you can use that as an additional knob.
Like actually decrease the clock speed? I honestly have no clue, but if I could slow it down by like 18-20%, that 122hz would end up near 100hz and becomes viable. I don't have enough understanding (yet) to know if that's even a thing though hah
 
Top Back Refresh