PICAXE Computer Fan Controller with speed and temperature measurement

nick12ab

Senior Member
These first posts are a guide to the making of the controller. If you want to make one yourself, remember to read the entire thread before starting construction and no liability is accepted if you break your own computer.

[SIZE=+1]Preparation[/SIZE]

Tools required:
  • Rotary tool with cutter/grinder and drill bits such as Maplin's N29HH
  • High current supply for tool above since the power supply included is rubbish and prohibits the tool from operating at its maximum capability (I used a lead acid battery)
  • Stripboard cutter
  • Soldering iron (with solder)
  • Flatblade screwdriver
  • PICAXE programming cable
  • Computer to mod and program PICAXE with - both can be done with the same computer as long as it won't overheat when both fans are stopped during programming
Components required:
  • Some stripboard - I used 46 rows of strips 24 holes long
  • PICAXE-28X2
  • 4-pin molex power socket
  • IC socket for PICAXE
  • A few 0.1" pin headers and sockets
  • Two 1A fuses to protect computer in case of failure
  • Two 100µF electrolytic capacitors
  • Two bulk capacitors of any sensible value - I used 47µF
  • Decoupling capacitor
  • Resistors
  • 16MHz Resonator
  • Two low power NPN transistors
  • Two high power PNP transistors - cheap low quality ones may also need small heatsinks
  • Wire and jumper links
  • Two thermistors
  • Three push-to-make switches for panel mounting
  • SPDT break before make toggle switch (but you can use a SPST with pull-down resistor instead)
  • Blank front panel for your computer case - you'll have an additional one spare for each other 5.25" device installed
  • Set of four M3 nuts and bolts
  • Large character 16x2 OLED (Rapid 57-2296) or LCD (Rapid 500161)
  • Two case fans preferably with tachometer signal (required for speed reading)
  • Thermal transfer tape
  • Insulation (electrical) tape
Note: Many case designs will require two spare 5.25" drive bays because the OLED module is slightly taller than a normal drive but grinding some plastic off the case, using a 5.25"-3.5" bay adaptor or using an "accessory panel" below the bay in which this will be fitted may allow you to only require one drive bay. 2.5" hard drives and SSDs can be mounted behind the controller too,
Note: A 4-pin power plug and 5V/12V power supply is recommended for initial testing before moving this to the computer.

My design uses the front panel headphone connector for programming the PICAXE as I never use it. However, everything in a PC shares one ground so the front panel PCB which has USB ports on it too has one big ground plane. Because PICAXE uses the sleeve connection on the 3.5mm cable as Serial Out and not Ground, this ground plane has to be separated in order to enable programming of the PICAXE.This can be done using a grinding disc from the rotary tool set.



You will need to install thermistors where you want to monitor the temperature. I've only got one thermistor, which is the Techsupplies one. You will need to solder some long wire to this thermistor and insulate these connections with electrical tape. You will also need to apply thermal transfer tape to the thermistor and then you need to shove the thermistor as far as possible into the northbridge heatsink and try to position it so that the fan isn't directly cooling this thermistor! On the other end of the wire, solder a two pin 0.1" socket.



Continues in next post due to four images a post limit...
 

nick12ab

Senior Member
[size=+1]Cutting the front panel for push buttons and OLED[/size]

To cut the OLED holes, use the 3mm drill bit from the drill set and use the holes in the OLED itself to align the drill. This is the easiest part of the cutting.

To cut holes for the switches, drill holes in the corners of the panel. The 3mm drill in the drill kit mentioned earlier will not be big enough so either use a big enough drill + drill bit or use a chubby philips screwdriver to make the 3mm holes big enough.

To cut the big rectangular hole to see the OLED through, I used the cutting disc that came with the rotary cutting tool. The power supply included with the mentioned rotary tool is feeble and using it with the tool will take ages to cut the front panel. A lead acid battery enabled much faster cutting.



Once all holes have been cut, use the M3 nuts and bolts to attach the OLED to the front panel and bolt in the switches. The 10K resistors can be soldered to ground points in the back of the OLED and a five hole 0.1" header is used to provide 5V power to the switches and a signal from each switch. The OLED has a 0.1" header soldered to it with pins 3, 15 and 16 removed.

Note: Using a make before break SPDT switch will intantly blow the fuse unless one of the terminals is connected to its relevant power rail through a resistor.



Then the circuit itself can be assembled on stripboard. A circuit diagram will be added in a later post. This picture lacks the wires connecting the thermistors and tachometer signals to the PICAXE because I initially forgot those.



Continues in next post due to four images a post limit...
 

nick12ab

Senior Member
On the 16-pin OLED/LCD connector on the stripboard, if using an OLED and not an LCD, you can use a soldering iron to melt hole 3 shut to prevent the OLED from being inserted incorrectly.



Finally, put some insulation tape on the stripboard assembly wherever there's a risk that anything could come in contact with any metal part that it shouldn't come in contact with.

Bottom view of stripboard:



View of stripboard attached to OLED:



And a note before I move on to installation: In newer computers, a header for connecting a serial port bracket (instead of a port on the I/O plate) is provided and its use is recommended for minimal fuss, best reliability and it works every time (and it's cheaper than a counterfeit Prolific USB adaptor). It may need to be enabled in the BIOS first but that will be easy to do (usually under Integrated Peripherals > SuperI/O, or Advanced > Device Configuration).



Continues in next post due to four images a post limit...
 
Last edited:

nick12ab

Senior Member
[size=+1]Installation[/size]

Place your fans wherever you want them. I've put one at the front of the case and the other near the northbridge heatsink which gets quite hot when passively cooled. Route the wires for the fans, the front panel audio connector, the thermistors and one 4-pin molex power connector to where the controller will be installed, and whilst you're at it, move all your drive cables to the sides of the case to improve airflow and also clean the dust out of your CPU heatsink using air duster and a small screwdriver.



Connect all cables to the controller and fix the controller back into the PC case.



Connect the PICAXE Programming cable to the headphone port of the computer, turn on the computer and program the PICAXE with this code:
Code:
#no_table
#no_end
#picaxe 28x2
#terminal off
#com 1
symbol rs = A.4
symbol enable = C.0
symbol sense1 = C.5
symbol sense2 = C.4
symbol fan1 = C.1
symbol fan2 = C.2
symbol therm1 = C.6
symbol therm2 = C.3
symbol switchdown = pinA.0
symbol switchup = pinA.1
symbol switchaction = pinA.2
symbol switchtoggle = pinA.3
symbol count1 = w2
symbol count2 = w3
symbol counter = w4
symbol lcddata = pinsb
symbol loopcounter = b10
symbol readvar = b11
symbol bta1 = b12
symbol bta2 = b13
symbol bta3 = b14
symbol bta4 = b15
symbol bta5 = b16
    setfreq em64
    settimer t1s_16
    pwmout fan1,31,127
    pwmout fan2,31,127
    dirsB = 255
    low rs
    output enable
    lcddata = %00000110 : pulsout enable,100
    lcddata = %00001100 : pulsout enable,100
    lcddata = %00111011 : pulsout enable,100
    lcddata = %00000001 : pulsout enable,100
    pause 500
    low rs
    lcddata = 128 : pulsout enable,1
    high rs
    for loopcounter = 0 to 15
        lookup loopcounter,("16 CHARS LINE 1 "),readvar
        lcddata = readvar
        pulsout enable,1
    next loopcounter
    low rs
    lcddata = 192: pulsout enable,1
    high rs
    for loopcounter = 0 to 15
        lookup loopcounter,("16 CHARS LINE 2 "),readvar
        lcddata = readvar
        pulsout enable,1
    next loopcounter
    pause 8000
    low rs
    lcddata = 128 : pulsout enable,1
    high rs
    for loopcounter = 0 to 15
        lookup loopcounter,($C7,"NB  XXXX A  YY",$B2),readvar
        lcddata = readvar
        pulsout enable,1
    next loopcounter
    low rs
    lcddata = 192: pulsout enable,1
    high rs
    for loopcounter = 0 to 15
        lookup loopcounter,(" SYS XXXX A  YY",$B2),readvar
        lcddata = readvar
        pulsout enable,1
    next loopcounter
main:
    count sense1,8000,count1
    count1 = count1 * 60
    low rs
    lcddata = 133 : pulsout enable,1
    high rs
    bintoascii count1,bta1,bta2,bta3,bta4,bta5
    lcddata = bta2 : pulsout enable,1
    lcddata = bta3 : pulsout enable,1
    lcddata = bta4 : pulsout enable,1
    lcddata = bta5 : pulsout enable,1
    count sense2,8000,count2
    count2 = count2 * 60
    low rs
    lcddata = 197 : pulsout enable,1
    high rs
    bintoascii count2,bta1,bta2,bta3,bta4,bta5
    lcddata = bta2 : pulsout enable,1
    lcddata = bta3 : pulsout enable,1
    lcddata = bta4 : pulsout enable,1
    lcddata = bta5 : pulsout enable,1
    if timer >= 4 then
        pwmduty fan1,5
        pwmduty fan2,5
    end if
    if switchtoggle = 1 then
        timer = 0
    end if
    if timer < 4 then
        pwmduty fan1,127
        pwmduty fan2,127
    end if
    goto main
This code will briefly show a welcome message, then it will show the approximate speeds of the fans that are connected. No averaging has been implemented yet. The toggle switch will change whether the fans go fast or slow. You should see this on the OLED:



The plan is for the two buttons on the left to adjust the fan speed, the one on the right to change whether temperature-controlled mode ("A") or manual mode ("M") is to be used and the toggle switch will change which fan the other buttons affect. I will be slowly completing the code and posting it in this thread. I plan to calculate the temperature of the thermistors using Peter Anderson's lookup table. And yes, Manuka (and others who fuss over Celsius being what gets measured by the readtemp command), the temperature will be in CELSIUS!!!

I will post a circuit diagram shortly.
Written by nick12ab on the computer using this PICAXE fan controller.
 

nick12ab

Senior Member
[SIZE=+1]Purpose[/SIZE]

So far I haven't stated why I am doing this. The reason is to eliminate unncecessary fan noise whilst allowing them to still be turned up when the computer gets hot without having to settle for a commercial solution.

[SIZE=+1]Schematic[/SIZE]


Click for schematic


Please comment.
 

nick12ab

Senior Member
Moving Average implemented! 5 samples are averaged to give a speed for each fan.
Code:
#no_table
#no_end
#picaxe 28x2
#terminal off
#rem                    MEMORY MAP    DOWN THEN ACROSS
               0              1               2               3               4               5
-------------------------------------------------------------------------------------------------------
0(w0) |               |  loopcounter  | moving average| moving average|               |               |
1(w0) |               |  readvar      | 1 fan 1 w10   | 1 fan 2 w15   |               |               |
2(w1) |               | bintoascii1   | moving average| moving average|               |               |
3(w1) |               | bintoascii2   | 2 fan 1 w11   | 2 fan 2 w16   |               |               |
4(w2) |               | bintoascii3   | moving average| moving average|               |               |
5(w2) |               | bintoascii4   | 3 fan 1 w12   | 3 fan 2 w17   |               |               |
6(w3) |  count1 w3    | bintoascii5   | moving average| moving average|               |               |
7(w3) |  count1       |               | 4 fan 1 w13   | 4 fan 2 w18   |               |               |
8(w4) |  count2 w4    |               | moving average| moving average|               |               |
9(w4) |  count2       |               | 5 fan 1 w14   | 5 fan 2 w19   |               |               |
-------------------------------------------------------------------------------------------------------
#endrem
symbol rs = A.4
symbol enable = C.0
symbol sense1 = C.5
symbol sense2 = C.4
symbol fan1 = C.1
symbol fan2 = C.2
symbol therm1 = C.6
symbol therm2 = C.3
symbol switchdown = pinA.0
symbol switchup = pinA.1
symbol switchaction = pinA.2
symbol switchtoggle = pinA.3
symbol lcddata = pinsB

symbol count1 = w3
symbol count2 = w4
symbol loopcounter = b10
symbol readvar = b11
symbol bta1 = b12
symbol bta2 = b13
symbol bta3 = b14
symbol bta4 = b15
symbol bta5 = b16
symbol ma11 = w10
symbol ma12 = w11
symbol ma13 = w12
symbol ma14 = w13
symbol ma15 = w14
symbol ma21 = w15
symbol ma22 = w16
symbol ma23 = w17
symbol ma24 = w18
symbol ma25 = w19

    setfreq em64
    settimer t1s_16
    pwmout fan1,31,127
    pwmout fan2,31,127
    dirsB = 255
    low rs
    output enable
    lcddata = %00000110 : pulsout enable,100
    lcddata = %00001100 : pulsout enable,100
    lcddata = %00111011 : pulsout enable,100
    lcddata = %00000001 : pulsout enable,100
    pause 500
    low rs
    lcddata = 128 : pulsout enable,1
    high rs
    for loopcounter = 0 to 15
        lookup loopcounter,("16 CHARS LINE 1 "),readvar
        lcddata = readvar
        pulsout enable,1
    next loopcounter
    low rs
    lcddata = 192: pulsout enable,1
    high rs
    for loopcounter = 0 to 15
        lookup loopcounter,("16 CHARS LINE 2 "),readvar
        lcddata = readvar
        pulsout enable,1
    next loopcounter
    pause 8000
    low rs
    lcddata = 128 : pulsout enable,1
    high rs
    for loopcounter = 0 to 15
        lookup loopcounter,($C7,"NB  XXXX A  YY",$B2),readvar
        lcddata = readvar
        pulsout enable,1
    next loopcounter
    low rs
    lcddata = 192: pulsout enable,1
    high rs
    for loopcounter = 0 to 15
        lookup loopcounter,(" SYS XXXX A  YY",$B2),readvar
        lcddata = readvar
        pulsout enable,1
    next loopcounter
main:
    ma15 = ma14
    ma14 = ma13
    ma13 = ma12
    ma12 = ma11
    count sense1,8000,ma11
    ma11 = ma11 * 60
    count1 = ma11 + ma12 + ma13 + ma14 + ma15 / 5
    low rs
    lcddata = 133 : pulsout enable,1
    high rs
    bintoascii count1,bta1,bta2,bta3,bta4,bta5
    lcddata = bta2 : pulsout enable,1
    lcddata = bta3 : pulsout enable,1
    lcddata = bta4 : pulsout enable,1
    lcddata = bta5 : pulsout enable,1
    
    ma25 = ma24
    ma24 = ma23
    ma23 = ma22
    ma22 = ma21
    count sense2,8000,ma21
    ma21 = ma21 * 60
    count2 = ma25 + ma24 + ma23 + ma22 + ma21 / 5
    low rs
    lcddata = 197 : pulsout enable,1
    high rs
    bintoascii count2,bta1,bta2,bta3,bta4,bta5
    lcddata = bta2 : pulsout enable,1
    lcddata = bta3 : pulsout enable,1
    lcddata = bta4 : pulsout enable,1
    lcddata = bta5 : pulsout enable,1
    
    if timer >= 4 then
        pwmduty fan1,5
        pwmduty fan2,5
    end if
    if switchtoggle = 1 then
        timer = 0
    end if
    if timer < 4 then
        pwmduty fan1,127
        pwmduty fan2,127
    end if
    goto main
Next things for for me to do:
  • Reduce unnecesary variable usage of averaging or change to 10-point moving average
  • Properly implement button functions
  • Implement temperature measurement
 

nick12ab

Senior Member
Moving average is now a 10-point moving average allowing for shorter count durations without losing out on precision. As a result, responsiveness has improved. I'm now developing the button interface.
Code:
#no_table
#no_end
#picaxe 28x2
#terminal off
#rem                    MEMORY MAP    DOWN THEN ACROSS
               0              1               2               3               4               5
-------------------------------------------------------------------------------------------------------
0(w0) | Bits          |  loopcounter  | moving average| moving average| moving average| moving average|
1(w0) |               |  readvar      | 1       w10   | 6       w15   | 11  w20       | 16  w25       |
2(w1) |               | bintoascii1   | moving average| moving average| moving average| moving average|
3(w1) |               | bintoascii2   | 2       w11   | 7       w16   | 12  w21       | 17  w26       |
4(w2) | moving average| bintoascii3   | moving average| moving average| moving average| moving avergae|
5(w2) | 19  w2        | bintoascii4   | 3       w12   | 8       w17   | 13  w22       | 18 w27        |
6(w3) |  count1 w3    | bintoascii5   | moving average| moving average| moving average|---------------|
7(w3) |  count1       |               | 4       w13   | 9       w18   | 14  w23       |
8(w4) |  count2 w4    | moving average| moving average| moving average| moving average|
9(w4) |  count2       | 0       w9    | 5       w14   | 10      w19   | 15  w24       |
---------------------------------------------------------------------------------------
-----------------------------------------------------------------------
 bit0 |fan1mode       |               |               |               |
 bit1 |fan2mode       |               |               |               |
 bit2 |button         |               |               |               |
 bit3 |               |               |               |               |
 bit4 |               |               |               |               |
 bit5 |               |               |               |               |
 bit6 |               |               |               |               |
 bit7 |               |               |               |               |
-----------------------------------------------------------------------
#endrem
symbol rs = A.4
symbol enable = C.0
symbol sense1 = C.5
symbol sense2 = C.4
symbol fan1 = C.1
symbol fan2 = C.2
symbol therm1 = C.6
symbol therm2 = C.3
symbol switchdown = pinA.0
symbol switchup = pinA.1
symbol switchaction = pinA.2
symbol switchtoggle = pinA.3
symbol lcddata = pinsB

symbol mode1 = bit0
symbol mode2 = bit1
symbol buttonvar = bit2
symbol count1 = w3
symbol count2 = w4
symbol loopcounter = b10
symbol readvar = b11
symbol bta1 = b12
symbol bta2 = b13
symbol bta3 = b14
symbol bta4 = b15
symbol bta5 = b16
symbol ma0 = w9
symbol ma1 = w10
symbol ma2 = w11
symbol ma3 = w12
symbol ma4 = w13
symbol ma5 = w14
symbol ma6 = w15
symbol ma7 = w16
symbol ma8 = w17
symbol ma9 = w18
symbol ma10 = w19
symbol ma11 = w20
symbol ma12 = w21
symbol ma13 = w22
symbol ma14 = w23
symbol ma15 = w24
symbol ma16 = w25
symbol ma17 = w26
symbol ma18 = w27
symbol ma19 = w2

    setfreq em64
    settimer t1s_16
    pwmout fan1,31,127
    pwmout fan2,31,127
    dirsB = 255
    low rs
    output enable
    lcddata = %00000110 : pulsout enable,100
    lcddata = %00001100 : pulsout enable,100
    lcddata = %00111011 : pulsout enable,100
    lcddata = %00000001 : pulsout enable,100
    pause 100
    low rs
    lcddata = 64 : pulsout enable,1
    high rs
    for loopcounter = 0 to 55
        lookup loopcounter,(32,32,32,32,32,32,63,32,32,32,32,32,32,63,63,32,32,32,32,32,63,63,63,32,32,32,32,63,_
                      63,63,63,32,32,32,63,63,63,63,63,32,32,63,63,63,63,63,63,32,63,63,63,63,63,63,63,32),readvar
        lcddata = readvar
        pulsout enable,1
    next loopcounter
    
    pause 500
    low rs
    lcddata = 128 : pulsout enable,1
    high rs
    for loopcounter = 0 to 15
        lookup loopcounter,("16 CHARS LINE 1 "),readvar
        lcddata = readvar
        pulsout enable,1
    next loopcounter
    low rs
    lcddata = 192: pulsout enable,1
    high rs
    for loopcounter = 0 to 15
        lookup loopcounter,("16 CHARS LINE 2 "),readvar
        lcddata = readvar
        pulsout enable,1
    next loopcounter
    pause 8000
    low rs
    lcddata = 128 : pulsout enable,1
    high rs
    for loopcounter = 0 to 15
        lookup loopcounter,($C7,"NB  XXXX A",0," YY",$B2),readvar
        lcddata = readvar
        pulsout enable,1
    next loopcounter
    low rs
    lcddata = 192: pulsout enable,1
    high rs
    for loopcounter = 0 to 15
        lookup loopcounter,(" SYS XXXX A",6," YY",$B2),readvar
        lcddata = readvar
        pulsout enable,1
    next loopcounter
main:
    ma9 = ma8
    ma8 = ma7
    ma7 = ma6
    ma6 = ma5
    ma5 = ma4
    ma4 = ma3
    ma3 = ma2
    ma2 = ma1
    ma1 = ma0
    count sense1,4000,ma0
    ma0 = ma0 * 120
    count1 = ma0+ma1+ma2+ma3+ma4+ma5+ma6+ma7+ma8+ma9 / 10
    low rs
    lcddata = 133 : pulsout enable,1
    high rs
    bintoascii count1,bta1,bta2,bta3,bta4,bta5
    lcddata = bta2 : pulsout enable,1
    lcddata = bta3 : pulsout enable,1
    lcddata = bta4 : pulsout enable,1
    lcddata = bta5 : pulsout enable,1
    gosub switches

    ma19 = ma18
    ma18 = ma17
    ma17 = ma16
    ma16 = ma15
    ma15 = ma14
    ma14 = ma13
    ma13 = ma12
    ma12 = ma11
    ma11 = ma10
    count sense2,4000,ma10
    ma10 = ma10 * 120
    count2 = ma10+ma11+ma12+ma13+ma14+ma15+ma16+ma17+ma18+ma19 / 10
    low rs
    lcddata = 197 : pulsout enable,1
    high rs
    bintoascii count2,bta1,bta2,bta3,bta4,bta5
    lcddata = bta2 : pulsout enable,1
    lcddata = bta3 : pulsout enable,1
    lcddata = bta4 : pulsout enable,1
    lcddata = bta5 : pulsout enable,1
    gosub switches
    goto main
    
switches:
    low rs
    if switchtoggle = 0 then
        lcddata = 128 : pulsout enable,1
        high rs
        lcddata = $C7 : pulsout enable,1
        low rs
        lcddata = 192 : pulsout enable,1
        high rs
        lcddata = 32 : pulsout enable,1
    else    
        lcddata = 192 : pulsout enable,1
        high rs
        lcddata = $C7 : pulsout enable,1
        low rs
        lcddata = 128 : pulsout enable,1
        high rs
        lcddata = 32 : pulsout enable,1
    end if
    if switchaction = 1 then
        if buttonvar = 0 then
            buttonvar = 1
            low rs
            if switchtoggle = 0 then
                inc mode1
                lcddata = 138 : pulsout enable,1
                high rs
                if mode1 = 1 then : lcddata = "M"
                else : lcddata = "A" : end if
                pulsout enable,1
                pwmduty fan1,5
                pwmduty fan2,5
            else
                inc mode2
                lcddata = 202 : pulsout enable,1
                high rs
                if mode2 = 1 then : lcddata = "M"
                else : lcddata = "A" : end if
                pulsout enable,1
                pwmduty fan1,127
                pwmduty fan2,127
            end if
        end if
    else
        buttonvar = 0
    end if    
    return
 

Buzby

Senior Member
In post #4 you said,

Connect the PICAXE Programming cable to the headphone port of the computer,
Is this correct ?.

If so, it opens up a whole new world of PICAXE programming opportunities !.
 

nick12ab

Senior Member
Is this correct ?.
It is correct, but not in the sense that I think you're thinking. The PICAXE itself is connected to the audio connector that would normally be connected to the motherboard. So the headphone port is the download socket which has the 3.5mm end of the programming cable connected and the other end of the PICAXE Programming cable is connected to the serial port.

If you look at picture 2 in post 4, you can see a plug marked 'Audio' plugged into the stripboard. The front panel connector is designed for the AC'97 standard and does not work on my motherboard which uses the newer 'HD Audio' standard so it's no use to me otherwise so this was the perfect application.
 

nick12ab

Senior Member
Temperature measurement is done. I used Peter Anderson's data at 0 decimal places and reversed since he decided to wire his thermistor with the 10k resistor to power and the thermistor to ground. I don't think I've done it right as I've had to adjust the ADC reading through code in order to get the temperature displayed to match that reported by a temperature monitoring computer program. Without the compensation, it was obviously wrong as the temperature shown on the OLED was well below room temperature when the computer is first turned on.

Perhaps Peter could comment on this?
Code:
#no_data
#no_end
#picaxe 28x2
#terminal off
#rem                    MEMORY MAP    DOWN THEN ACROSS
               0              1               2               3               4               5
-------------------------------------------------------------------------------------------------------
0(w0) | Bits          |  loopcounter  | moving average| moving average| moving average| moving average|
1(w0) |               |  readvar      | 1       w10   | 6       w15   | 11  w20       | 16  w25       |
2(w1) |               | bintoascii1/T | moving average| moving average| moving average| moving average|
3(w1) |               | bintoascii2   | 2       w11   | 7       w16   | 12  w21       | 17  w26       |
4(w2) | moving average| bintoascii3   | moving average| moving average| moving average| moving avergae|
5(w2) | 19  w2        | bintoascii4   | 3       w12   | 8       w17   | 13  w22       | 18 w27        |
6(w3) |  count1 w3    | bintoascii5   | moving average| moving average| moving average|---------------|
7(w3) |  count1       |               | 4       w13   | 9       w18   | 14  w23       |
8(w4) |  count2 w4    | moving average| moving average| moving average| moving average|
9(w4) |  count2       | 0       w9    | 5       w14   | 10      w19   | 15  w24       |
---------------------------------------------------------------------------------------
-----------------------------------------------------------------------
 bit0 |fan1mode       |               |               |               |
 bit1 |fan2mode       |               |               |               |
 bit2 |button         |               |               |               |
 bit3 |               |               |               |               |
 bit4 |               |               |               |               |
 bit5 |               |               |               |               |
 bit6 |               |               |               |               |
 bit7 |               |               |               |               |
-----------------------------------------------------------------------
#endrem
symbol rs = A.4
symbol enable = C.0
symbol sense1 = C.5
symbol sense2 = C.4
symbol fan1 = C.1
symbol fan2 = C.2
symbol therm1 = 18
symbol therm2 = 4
symbol switchdown = pinA.0
symbol switchup = pinA.1
symbol switchaction = pinA.2
symbol switchtoggle = pinA.3
symbol lcddata = pinsB

symbol mode1 = bit0
symbol mode2 = bit1
symbol buttonvar = bit2
symbol count1 = w3
symbol count2 = w4
symbol loopcounter = b10
symbol readvar = b11
symbol bta1 = b12
symbol bta2 = b13
symbol bta3 = b14
symbol bta4 = b15
symbol bta5 = b16
symbol ma0 = w9
symbol ma1 = w10
symbol ma2 = w11
symbol ma3 = w12
symbol ma4 = w13
symbol ma5 = w14
symbol ma6 = w15
symbol ma7 = w16
symbol ma8 = w17
symbol ma9 = w18
symbol ma10 = w19
symbol ma11 = w20
symbol ma12 = w21
symbol ma13 = w22
symbol ma14 = w23
symbol ma15 = w24
symbol ma16 = w25
symbol ma17 = w26
symbol ma18 = w27
symbol ma19 = w2
table 59,(0,0,1,1,2,2,2,3,3,4,4,4,5,5,5,6,6,7,7,7,8,8,9,9,9,10,10,10,11,11,11,12,12,13,13,13,14,14,14,15,15,15,16,16,_
    16,17,17,17,18,18,19,19,19,20,20,20,21,21,21,22,22,22,23,23,23,24,24,25,25,25,26,26,26,27,27,27,28,28,28,29,29,_
      30,30,30,31,31,31,32,32,33,33,33,34,34,35,35,35,36,36,37,37,37,38,38,39,39,40,40,40,41,41,42,42,43,43,44,44,44,_
      45,45,46,46,47,47,48,48,49,49,50,50,51,52,52,53,53,54,54,55,56,56,57,58,58,59,60,60,61,62,62,63,64,65,65,66,67,_
      68,69,70,71,72,72,73,75,76,77,78,79,80,81,83,84,86,87,89,90,92,94,96,98,100,102,105,108,111,114,118,122,126,132,_
      138,146,156,169,189,226)
      adcsetup = 16
      adcsetup2 = 4
    setfreq em64
    settimer t1s_16
    pwmout fan1,31,127
    pwmout fan2,31,127
    dirsB = 255
    low rs
    output enable
    lcddata = %00000110 : pulsout enable,100
    lcddata = %00001100 : pulsout enable,100
    lcddata = %00111011 : pulsout enable,100
    lcddata = %00000001 : pulsout enable,100
    pause 100
    low rs
    lcddata = 64 : pulsout enable,1
    high rs
    for loopcounter = 0 to 55
        lookup loopcounter,(32,32,32,32,32,32,63,32,32,32,32,32,32,63,63,32,32,32,32,32,63,63,63,32,32,32,32,63,_
                      63,63,63,32,32,32,63,63,63,63,63,32,32,63,63,63,63,63,63,32,63,63,63,63,63,63,63,32),readvar
        lcddata = readvar
        pulsout enable,1
    next loopcounter
    
    pause 500
    low rs
    lcddata = 128 : pulsout enable,1
    high rs
    for loopcounter = 0 to 15
        lookup loopcounter,("16 CHARS LINE 1 "),readvar
        lcddata = readvar
        pulsout enable,1
    next loopcounter
    low rs
    lcddata = 192: pulsout enable,1
    high rs
    for loopcounter = 0 to 15
        lookup loopcounter,("16 CHARS LINE 2 "),readvar
        lcddata = readvar
        pulsout enable,1
    next loopcounter
    pause 8000
    low rs
    lcddata = 128 : pulsout enable,1
    high rs
    for loopcounter = 0 to 15
        lookup loopcounter,($C7,"NB  XXXX A",0," YY",$B2),readvar
        lcddata = readvar
        pulsout enable,1
    next loopcounter
    low rs
    lcddata = 192: pulsout enable,1
    high rs
    for loopcounter = 0 to 15
        lookup loopcounter,(" SYS XXXX A",6," YY",$B2),readvar
        lcddata = readvar
        pulsout enable,1
    next loopcounter
main:
    ma9 = ma8
    ma8 = ma7
    ma7 = ma6
    ma6 = ma5
    ma5 = ma4
    ma4 = ma3
    ma3 = ma2
    ma2 = ma1
    ma1 = ma0
    count sense1,4000,ma0
    ma0 = ma0 * 120
    count1 = ma0+ma1+ma2+ma3+ma4+ma5+ma6+ma7+ma8+ma9 / 10
    low rs
    lcddata = 133 : pulsout enable,1
    high rs
    bintoascii count1,bta1,bta2,bta3,bta4,bta5
    lcddata = bta2 : pulsout enable,1
    lcddata = bta3 : pulsout enable,1
    lcddata = bta4 : pulsout enable,1
    lcddata = bta5 : pulsout enable,1
    gosub switches

    ma19 = ma18
    ma18 = ma17
    ma17 = ma16
    ma16 = ma15
    ma15 = ma14
    ma14 = ma13
    ma13 = ma12
    ma12 = ma11
    ma11 = ma10
    count sense2,4000,ma10
    ma10 = ma10 * 120
    count2 = ma10+ma11+ma12+ma13+ma14+ma15+ma16+ma17+ma18+ma19 / 10
    low rs
    lcddata = 197 : pulsout enable,1
    high rs
    bintoascii count2,bta1,bta2,bta3,bta4,bta5
    lcddata = bta2 : pulsout enable,1
    lcddata = bta3 : pulsout enable,1
    lcddata = bta4 : pulsout enable,1
    lcddata = bta5 : pulsout enable,1
    gosub switches
    goto main
    
switches:
    low rs
    if switchtoggle = 0 then
        lcddata = 128 : pulsout enable,1
        high rs
        lcddata = $C7 : pulsout enable,1
        low rs
        lcddata = 192 : pulsout enable,1
        high rs
        lcddata = 32 : pulsout enable,1
    else    
        lcddata = 192 : pulsout enable,1
        high rs
        lcddata = $C7 : pulsout enable,1
        low rs
        lcddata = 128 : pulsout enable,1
        high rs
        lcddata = 32 : pulsout enable,1
    end if
    if switchaction = 1 then
        if buttonvar = 0 then
            buttonvar = 1
            low rs
            if switchtoggle = 0 then
                inc mode1
                lcddata = 138 : pulsout enable,1
                high rs
                if mode1 = 1 then : lcddata = "M"
                else : lcddata = "A" : end if
                pulsout enable,1
                pwmduty fan1,5
                pwmduty fan2,5
            else
                inc mode2
                lcddata = 202 : pulsout enable,1
                high rs
                if mode2 = 1 then : lcddata = "M"
                else : lcddata = "A" : end if
                pulsout enable,1
                pwmduty fan1,127
                pwmduty fan2,127
            end if
        end if
    else
        buttonvar = 0
    end if
    readadc therm1,bta1
    bta1 = bta1 + 55
    low rs
    lcddata = 141 : pulsout enable,1
    high rs
    if bta1 < 59 then
        lcddata = "-"
        pulsout enable,1
        pulsout enable,1
    else
        readtable bta1,bta5
        bintoascii bta5,bta2,bta3,bta4
        lcddata = bta3 : pulsout enable,1
        lcddata = bta4 : pulsout enable,1
    end if
    readadc therm2,bta1
    bta1 = bta1 + 55
    low rs
    lcddata = 205 : pulsout enable,1
    high rs
    if bta1 < 59 then
        lcddata = "-"
        pulsout enable,1
        pulsout enable,1
    else
        readtable bta1,bta5
        bintoascii bta5,bta2,bta3,bta4
        lcddata = bta3 : pulsout enable,1
        lcddata = bta4 : pulsout enable,1
    end if
    return
 

nick12ab

Senior Member
A temporary standstill to this work in progress - blue screens!



This hasn't been happening before installation of the PICAXE computer mod. Looks like I'll have to remove it for a while to see if it is responsible for the crashing.

Message that appeared at startup:
Code:
Problem signature:
  Problem Event Name:	BlueScreen
  OS Version:	6.1.7601.2.1.0.768.3
  Locale ID:	2057

Additional information about the problem:
  BCCode:	f4
  BCP1:	0000000000000003
  BCP2:	FFFFFA80060A5B30
  BCP3:	FFFFFA80060A5E10
  BCP4:	FFFFF80002FCF8B0
  OS Version:	6_1_7601
  Service Pack:	1_0
  Product:	768_1
And an Action Center message:
[SIZE=+2]Troubleshoot a problem with a hard disk drive[/SIZE]
Windows was temporarily unable to read your hard disk drive. We don't know the exact cause of the problem. In most cases, this type of condition is momentary and doesn't indicate a serious problem, but sometimes it means that a hard disk is failing.

Common causes of this problem
  • Aging or failing hard disks. To prevent file corruption and data loss, we recommend that you back up all of your important files and folders immediately. See step 1 in the section below for more information.
  • Large file transfers from secondary media, such as an external hard drive, to a local hard drive.
  • Loss of power to a hard disk drive that causes inconsistent data sectors.
  • Hard disk-intensive processes such as antivirus scanners.
  • Recently installed hardware that might have compatibility and performance problems.
That last one looks like the only thing that can be the problem as the disk is a new SSD I bought a month ago (so unlikely to be failure of the drive) so noise from the PICAXE mod could be causing problems with power to the SSD in turn causing the computer crash (sometimes the error dump never starts). If the crashes stop after removing the mod then I'll try adding bigger bulk capacitors and extra decoupling capacitors to the mod. If not, then it must be the recently discussed solar flares.

@phanderson - can you assist with the temperature measurement?
 

nick12ab

Senior Member
Overheating :confused:
It seems quite unlikely that it is overheating since the chipset has been running at around 40-50 C for the last 2.5 years (which should be OK) and with the extra fans the chipset runs at around 30-35 C. The SSD runs cool and the processor runs at around 35 C.
[hr][/hr]
This has just sprung to mind - I have an extra fan fitted at the back of the computer for air extraction and this runs off 7V with + connected to +12V and - connected to 5V in order to reduce the noise of that fan. I think I'll forget disconnecting the PICAXE mod and disconnect the extraction fan as this method of powering it may be unsuitable.
 

Hansen

Member
I had the same problem some years ago, with external FAN controller
My problem was that the fans cooling temp. sensor down

my solution was to set sensor outside air flow
 

John West

Senior Member
I may have overlooked this while wandering through the lists of what size screwdrivers to use and such, but if any of the fans were originally connected directly to the PC mother bd, then it's possible the PC's BIOS isn't happy now that it isn't getting any feedback from the fan.
 

nick12ab

Senior Member
I may have overlooked this while wandering through the lists of what size screwdrivers to use and such, but if any of the fans were originally connected directly to the PC mother bd, then it's possible the PC's BIOS isn't happy now that it isn't getting any feedback from the fan.
Thank you for the suggestion. For the last couple of years the only fan that has been connected to the motherboard was the CPU fan and the new fans were only connected to the motherboard temporarily.

I removed the 7V fan yesterday and my computer's been on for 10 hours since then without any blue screen. As my normal hard drive powers its motor through 12V and not 5V, it's likely that the fan consumes enough current to make conventional current go into the 5V rail rather than out causing the SSD which uses 5V to crash.
 

inglewoodpete

Senior Member
And don't rule out the recent sunspot activity, unless you can prove it was something else. Of course if the problem repeats after the sunspots have died down....
 

nick12ab

Senior Member
I've done some searching for 'BSoD F4' and it does point to the Sandforce controller in my SSD being the culprit. There has been no crash since the fan running at 7V has been removed so the fan must have been just enough to interfere with the controller. At 5V, the fan is uselessly slow and the one pin remaining on the mod's 28X2 is not a PWM one so I'll have to buy an adjustable switching regulator to power it with 7V from the 2V line.
 

fernando_g

Senior Member
Do the fans have a three wire connector?
If so, they have a tacho output.
If the fan speed is sensed to be too low, it may trigger some protective action within the computer.
 

nick12ab

Senior Member
Do the fans have a three wire connector?
If so, they have a tacho output.
If the fan speed is sensed to be too low, it may trigger some protective action within the computer.
The fan that was connected to 7V (the one which appears to be the cause) did not have a tacho signal. Stopping it by hand would just stop it and do nothing. For the two 120mm fans, they do have tacho signals which are used by the PICAXE and these are not connected to the motherboard but when they were they could be stopped by hand without crashing the computer and the "mainboard utility" would correctly show the speed. It's likely that the motherboard doesn't even measure the current that goes into the fan. The motherboard cannot change the speed of these fans, only the CPU fan which has four wires.
 

nick12ab

Senior Member
Code update!

Count command replaced with counting system I have previously posted on the forum and the speeds are still correctly reported but now the buttons have instant response. Proper speed control hasn't been implemented yet - just a fast and slow mode for testing.
Code:
#no_data
#no_end
#picaxe 28x2
#terminal off
#rem                    MEMORY MAP    DOWN THEN ACROSS
               0              1               2               3               4               5
-------------------------------------------------------------------------------------------------------
0(w0) | Bits          |  loopcounter  | moving average| moving average| moving average| moving average|
1(w0) |               |  readvar      | 1       w10   | 6       w15   | 11  w20       | 16  w25       |
2(w1) |               | bintoascii1/T | moving average| moving average| moving average| moving average|
3(w1) |               | bintoascii2   | 2       w11   | 7       w16   | 12  w21       | 17  w26       |
4(w2) | moving average| bintoascii3   | moving average| moving average| moving average| moving avergae|
5(w2) | 19  w2        | bintoascii4   | 3       w12   | 8       w17   | 13  w22       | 18 w27        |
6(w3) |  count1 w3    | bintoascii5   | moving average| moving average| moving average|---------------|
7(w3) |  count1       |               | 4       w13   | 9       w18   | 14  w23       |
8(w4) |  count2 w4    | moving average| moving average| moving average| moving average|
9(w4) |  count2       | 0       w9    | 5       w14   | 10      w19   | 15  w24       |
---------------------------------------------------------------------------------------
-----------------------------------------------------------------------
 bit0 |fan1mode       |               |               |               |
 bit1 |fan2mode       |               |               |               |
 bit2 |button         |               |               |               |
 bit3 |sense1status   |               |               |               |
 bit4 |sense2status   |               |               |               |
 bit5 |               |               |               |               |
 bit6 |               |               |               |               |
 bit7 |               |               |               |               |
-----------------------------------------------------------------------
#endrem
symbol rs = A.4
symbol enable = C.0
symbol sense1 = pinC.5
symbol sense2 = pinC.4
symbol fan1 = C.1
symbol fan2 = C.2
symbol therm1 = 18
symbol therm2 = 4
symbol switchdown = pinA.0
symbol switchup = pinA.1
symbol switchaction = pinA.2
symbol switchtoggle = pinA.3
symbol lcddata = pinsB

symbol mode1 = bit0
symbol mode2 = bit1
symbol buttonvar = bit2
symbol sense1status = bit3
symbol sense2status = bit4
symbol count1 = w3
symbol count2 = w4
symbol loopcounter = b10
symbol readvar = b11
symbol bta1 = b12
symbol bta2 = b13
symbol bta3 = b14
symbol bta4 = b15
symbol bta5 = b16
symbol ma0 = w9
symbol ma1 = w10
symbol ma2 = w11
symbol ma3 = w12
symbol ma4 = w13
symbol ma5 = w14
symbol ma6 = w15
symbol ma7 = w16
symbol ma8 = w17
symbol ma9 = w18
symbol ma10 = w19
symbol ma11 = w20
symbol ma12 = w21
symbol ma13 = w22
symbol ma14 = w23
symbol ma15 = w24
symbol ma16 = w25
symbol ma17 = w26
symbol ma18 = w27
symbol ma19 = w2
table 59,(0,0,1,1,2,2,2,3,3,4,4,4,5,5,5,6,6,7,7,7,8,8,9,9,9,10,10,10,11,11,11,12,12,13,13,13,14,14,14,15,15,15,16,16,_
    16,17,17,17,18,18,19,19,19,20,20,20,21,21,21,22,22,22,23,23,23,24,24,25,25,25,26,26,26,27,27,27,28,28,28,29,29,_
      30,30,30,31,31,31,32,32,33,33,33,34,34,35,35,35,36,36,37,37,37,38,38,39,39,40,40,40,41,41,42,42,43,43,44,44,44,_
      45,45,46,46,47,47,48,48,49,49,50,50,51,52,52,53,53,54,54,55,56,56,57,58,58,59,60,60,61,62,62,63,64,65,65,66,67,_
      68,69,70,71,72,72,73,75,76,77,78,79,80,81,83,84,86,87,89,90,92,94,96,98,100,102,105,108,111,114,118,122,126,132,_
      138,146,156,169,189,226)
      adcsetup = 16
      adcsetup2 = 4
    setfreq em64
    pwmout fan1,31,127
    pwmout fan2,31,127
    dirsB = 255
    low rs
    output enable
    lcddata = %00000110 : pulsout enable,100
    lcddata = %00001100 : pulsout enable,100
    lcddata = %00111011 : pulsout enable,100
    lcddata = %00000001 : pulsout enable,100
    pause 100
    low rs
    lcddata = 64 : pulsout enable,1
    high rs
    for loopcounter = 0 to 55
        lookup loopcounter,(32,32,32,32,32,32,63,32,32,32,32,32,32,63,63,32,32,32,32,32,63,63,63,32,32,32,32,63,_
                      63,63,63,32,32,32,63,63,63,63,63,32,32,63,63,63,63,63,63,32,63,63,63,63,63,63,63,32),readvar
        lcddata = readvar
        pulsout enable,1
    next loopcounter
    
    pause 500
    low rs
    lcddata = 128 : pulsout enable,1
    high rs
    for loopcounter = 0 to 15
        lookup loopcounter,("16 CHARS LINE 1 "),readvar
        lcddata = readvar
        pulsout enable,1
    next loopcounter
    low rs
    lcddata = 192: pulsout enable,1
    high rs
    for loopcounter = 0 to 15
        lookup loopcounter,("16 CHARS LINE 2 "),readvar
        lcddata = readvar
        pulsout enable,1
    next loopcounter
    pause 8000
    low rs
    lcddata = 128 : pulsout enable,1
    high rs
    for loopcounter = 0 to 15
        lookup loopcounter,($C7,"NB  XXXX A",0," YY",$B2),readvar
        lcddata = readvar
        pulsout enable,1
    next loopcounter
    low rs
    lcddata = 192: pulsout enable,1
    high rs
    for loopcounter = 0 to 15
        lookup loopcounter,(" SYS XXXX A",6," YY",$B2),readvar
        lcddata = readvar
        pulsout enable,1
    next loopcounter
    settimer 49911
main:

    if sense1 = 1 then                '**   THE    **
        if sense1status = 0 then        '**   NEW    **
            inc ma0                '** COUNTING **
            sense1status = 1            '**   CODE   **
        end if                    '
    else                            '
        sense1status = 0                '
    end if                        '
    if sense2 = 1 then
        if sense2status = 0 then
            inc ma10
            sense2status = 1
        end if
    else
        sense2status = 0
    end if
    if timer = 4 then
        'FAN 
        ma0 = ma0 * 120
        ma9 = ma8
        ma8 = ma7
        ma7 = ma6
        ma6 = ma5
        ma5 = ma4
        ma4 = ma3
        ma3 = ma2
        ma2 = ma1
        ma1 = ma0
        count1 = ma0+ma1+ma2+ma3+ma4+ma5+ma6+ma7+ma8+ma9 / 10
        low rs
        lcddata = 133 : pulsout enable,1
        high rs
        bintoascii count1,bta1,bta2,bta3,bta4,bta5
        lcddata = bta2 : pulsout enable,1
        lcddata = bta3 : pulsout enable,1
        lcddata = bta4 : pulsout enable,1
        lcddata = bta5 : pulsout enable,1
        ma0 = 0
        'FAN 2
        ma10 = ma10 * 120
        ma19 = ma18
        ma18 = ma17
        ma17 = ma16
        ma16 = ma15
        ma15 = ma14
        ma14 = ma13
        ma13 = ma12
        ma12 = ma11
        ma11 = ma10
        count2 = ma10+ma11+ma12+ma13+ma14+ma15+ma16+ma17+ma18+ma19 / 10
        low rs
        lcddata = 197 : pulsout enable,1
        high rs
        bintoascii count2,bta1,bta2,bta3,bta4,bta5
        lcddata = bta2 : pulsout enable,1
        lcddata = bta3 : pulsout enable,1
        lcddata = bta4 : pulsout enable,1
        lcddata = bta5 : pulsout enable,1
        ma10 = 0
        'TEMPERATURE
        readadc therm1,bta1
        bta1 = bta1 + 55
        low rs
        lcddata = 141 : pulsout enable,1
        high rs
        if bta1 < 59 then
            lcddata = "-"
            pulsout enable,1
            pulsout enable,1
        else
            readtable bta1,bta5
            bintoascii bta5,bta2,bta3,bta4
            lcddata = bta3 : pulsout enable,1
            lcddata = bta4 : pulsout enable,1
        end if
        readadc therm2,bta1
        bta1 = bta1 + 55
        low rs
        lcddata = 205 : pulsout enable,1
        high rs
        if bta1 < 59 then
            lcddata = "-"
            pulsout enable,1
            pulsout enable,1
        else
            readtable bta1,bta5
            bintoascii bta5,bta2,bta3,bta4
            lcddata = bta3 : pulsout enable,1
            lcddata = bta4 : pulsout enable,1
        end if
        
        timer = 0
    end if
    'SWITCHES
        low rs
        if switchtoggle = 0 then
            lcddata = 128 : pulsout enable,1
            high rs
            lcddata = $C7 : pulsout enable,1
            low rs
            lcddata = 192 : pulsout enable,1
            high rs
            lcddata = 32 : pulsout enable,1
        else    
            lcddata = 192 : pulsout enable,1
            high rs
            lcddata = $C7 : pulsout enable,1
            low rs
            lcddata = 128 : pulsout enable,1
            high rs
            lcddata = 32 : pulsout enable,1
        end if
        if switchaction = 1 then
            if buttonvar = 0 then
                buttonvar = 1
                low rs
                if switchtoggle = 0 then
                    inc mode1
                    lcddata = 138 : pulsout enable,1
                    high rs
                    if mode1 = 1 then : lcddata = "M"
                    else : lcddata = "A" : end if
                    pulsout enable,1
                    pwmduty fan1,5
                    pwmduty fan2,5
                else
                    inc mode2
                    lcddata = 202 : pulsout enable,1
                    high rs
                    if mode2 = 1 then : lcddata = "M"
                    else : lcddata = "A" : end if
                    pulsout enable,1
                    pwmduty fan1,127
                    pwmduty fan2,127
                end if
            end if
        else
            buttonvar = 0
        end if
    goto main
 

nick12ab

Senior Member
Code update!



Manual fan speed control is now implemented. The two buttons on the left change the speed of the selected fan only when the selected fan is in manual mode (indicated by the big 'M'). The setting is saved to EEPROM when changed and restored at startup. The button in the top right corner changes the selected fan between manual mode and auto mode. The toggle switch in the bottom right corner obviously changes which fan is selected.

So for clarification, for each fan the display indicators are as follows: >NNN XXXX ML TTD where
> = Arrow or no arrow indicating whether the fan is selected
NNN = What the fan is cooling ("NB " = Northbridge, "SYS" = Whole system i.e. front intake fan)
XXXX = Speed of fan in RPM
M = Mode (M for manual, A for Auto)
L = Fan control level indicated by differently sized vertical blocks defined in CGRAM
TT = Temperature in celsius measured by thermistor (dashes shown if no thermistor is connected)
D = Degrees symbol

The Auto mode has not been implemented yet so if a fan is set to auto mode then the speed will stay fixed and cannot be changed even with the buttons on the left. The auto mode when implemented will change the fan speed according to temperature.

In addition to this another major change has been doubling of the sample time and halving of the amount of variables used in the moving average for each fan which frees up variables without compromising on responsiveness due to the new counting code implemented in the post above.

I've had to attach the code as it is now too big for a post.
 

Attachments

nick12ab

Senior Member
Code update!



I've implemented the ability to set what temperatures will cause the fans to change speed to each level when in auto mode. This is then saved in EEPROM, and each fan can have its own settings.

To change the settings, hold down both the up and down buttons on the left together. Pressing up and down will change the lowest temperature at which the shown level will be applied to the fan and pressing the button on the right moves on to the next level.
 

Attachments

nick12ab

Senior Member
Code Update - Auto mode now implemented

The auto mode has been implemented.

Auto mode compares the measured temperature to the user-defined values and sets the fan speed according to these values. Code attached as it exceeds 10000 characters.

The next feature I may implement is manual adjustment of the constant which skews the temperature reading since it's probably the thermistor and not Peter Anderson's code which causes the wrong values to be initially read so a different thermistor would have a different skew.
[HR][/HR]Regarding the recent problem with the BSoDs, I'm certain that it was the 7V-powered fan as I've had rock-solid stability since removing it.
 

Attachments

nick12ab

Senior Member
This code update is just addition of some comments and also efficiency of the loops which print strings on the OLED have been improved by eliminating 'readvar' and using pinsB as the variable in which the result from the lookup command.
 

Attachments

nick12ab

Senior Member
Temperature skew adjustment and menus implemented!

The menu is accessible the same way as the auto mode temperature levels setting was - press up and down at the same time.



Temperature skew setting allows the user to set what number is added to the read ADC value and no minus handling is required since a big number will just cause overflow. A setting for each temperature sensor is provided and is selected by whichever fan was selected when entering the menu.

The test OLED function turns off all pixels then turns on all pixels, then returns to the menu after each press of the 'action button'.
 

Attachments

nick12ab

Senior Member
Status updates

I've had success trying the fan speed measurement with a 3000 and 5500 RPM fan so that's confirmed that the PICAXE doesn't (unreasonably) limit how fast a fan can be measured.

Temperature measurement is done. I used Peter Anderson's data at 0 decimal places and reversed since he decided to wire his thermistor with the 10k resistor to power and the thermistor to ground. I don't think I've done it right as I've had to adjust the ADC reading through code in order to get the temperature displayed to match that reported by a temperature monitoring computer program. Without the compensation, it was obviously wrong as the temperature shown on the OLED was well below room temperature when the computer is first turned on.

Perhaps Peter could comment on this?
I connected a thermistor from a dead laptop battery to the unused temperature measurement channel and it reported the temperature accurately without needing the skew to be adjusted so there's nothing wrong with Peter Anderson's data, it's just that the Techsupplies thermistor is dodgy.

The additional thermistor is just on short wires stocking up from the connector so it measures the temperature inside the case rather than of a specific component. When starting the computer from cold, the reported temperature is the same as that reported by a cheap clock with temperature measurement but slowly rises to 30 C as the computer is used.

A temporary standstill to this work in progress - blue screens!
There hasn't been any BSoDs since the removal of the 7V fan so that's definitely ruled out the fan controller causing any problems.

[HR][/HR]
(22-05-2012)

On a side note, has anyone had any success using their motherboard IrDA connector for serial? Is it inverted compared to the RS232 serial port? Is it open drain? Is it modulated?

Which BIOS setting have you used if yes?

[HR][/HR]
(14-01-2014)

I tested two more non-Rev-Ed thermistors and they both reported the correct temperature without any temperature skew set.

Regarding the method for measuring fan speed, I've determined that the proper way of measuring it and the method used by the computer (which can measure it with much better resolution than the PICAXE) is to measure the period, not the frequency. It's so obvious now - it wasn't at the time. The PICAXE isn't quite fast enough to do this method with good enough precision and its poor mathematical capabilities make it difficult to implement it on two fans as well.

I made a new version of the fan controller using an ATmega328 and it has a similar resolution to the speed measured by the computer and no averaging is required so the response to sudden changes in fan speed is very quick. I cannot post it here because it didn't use a PICAXE. It still uses the same switches, OLED and panel as the PICAXE version but it has a new redesigned stripboard circuit which is parallel to the OLED instead of perpendicular. The new fan controller is now used instead of the PICAXE one.
 
Last edited:

john2051

New Member
Hi, Nick, interesting project. I think that if the utility "speedfan" can alter the fans speeds, even three wire fans then I assume its doing this by accessing the thermal
management chip on the motherboard. There always seems to be minimal cooling in modern equipment, and I dont like knowing that my cpu core is close to 200c. Isnt electrical
noise proportional to temperature?.
Regarding irda, my computer hasd it, I can get my multimeter to link to it. I dont know if its any help, but mikroelektronika do two irda boards.
It would be useful to have a virtual irda rs232 port, you could program picaxes etc etc.

Thanks for giving me ideas re- your project

regards john
 

nick12ab

Senior Member
Hi, Nick, interesting project. I think that if the utility "speedfan" can alter the fans speeds, even three wire fans then I assume its doing this by accessing the thermal management chip on the motherboard.
I've tried that and it's speed adjustment controls haven't worked on anything. It could not even control my 4-pin CPU fan so that has to be set in the BIOS. If you open another dialog and close it, all three speed settings in the application would reset to 100% and the CPU fan speed stayed on the 'low' setting it was on.

That mikroelektronika IrDA board looks like it has an awfully large amount of components on it compared to a plug-in mother board module but hopefully those extra components are just to enable baud rate selection rather than to significally alter the protocol.
 

john2051

New Member
Hi nick, if i remember right, there is a setting in speedfans setup you have to change, but of course its chip dependent. Speedfan wont recognise the chip
in my laptop at all.
If i can i'll check which setting you have to change, and let you know.

regards john
 
Top