Project Hush Switch

Discussion in 'Electronics & Electrics' started by dakiller, Aug 13, 2018.

  1. dakiller

    dakiller (Oscillating & Impeding)

    Joined:
    Jun 27, 2001
    Messages:
    7,646
    Location:
    Gippsland
    I've been somewhat quiet in this forum for a while now, but I thought I would share this project I've been working on.

    I'm working on something that will require a lot of POE network switches and so I picked up second hand a heap of Cisco SF300 48 Port switches for the job. Nice units, cost me about $120ish each, bargain.

    [​IMG]

    Problem is I don't like the noise they make. Why not make a custom fan controller for them?

    The switches have 3 little 40mA fans and run on about 200mA each. The goal is to have something plug and play that doesn't alter the switches in any way and just sits between the fans and the mainboard and quietens the fans while making sure the switch doesn't complain that there are no fans present.

    I've just started to get into the Arduino development environment, previously I'd code in straight C and compile with gcc to an AVR and upload to the board. Well you can pretty much do the same now with the Arduino IDE out of the box, just with a nice simple IDE and heaps of libraries to go with it. I'm liking it; you can be lazy and use all the builtin main library commands to do stuff quickly, or if needed crack out the datasheet and fiddle with registers to get the max performance when needed.

    I picked the Attiny88 chip, mostly because I'm using the same one in another project, and there is a nice Core plugin that makes it all work with Arduinio - https://github.com/SpenceKonde/ATTinyCore

    [​IMG]

    The circuit is pretty basic. Some NTC temp sensors in, a MOSFET to PWM the fans, 12v to 3.3v regulator to power the micro, few leds to blink if needed and an FTDI USB to RS232 for debugging.

    I read in the fans tach signals and connect to the tach signals back to the switch's mainboard to feedthough a fake signal that the fans are still spinning fast.

    PCB!
    [​IMG]

    [​IMG]

    [​IMG]

    [​IMG]

    The design has female pin connectors on the PCB that mount right onto the switches fan headers for a clean little mod to sit the mainboard and the fans.

    Maybe I'll clean up my code into a state that I'm willing to share, but it is pretty simple at the minute while I've been experimenting with it. It just reads in the thermistor on an ADC line, computes the temperature and puts it into a PID control loop to hit a fixed target temperature that spits out a number that then gets written to a PWM output that regulates the fan speed.

    There are always things you don't expect to work 100% when you first design a circuit, but I thought with the experience I've had that I could get this one 100% first go. Hah, No!

    First mistake, no flyback diode on the fan. Massive voltage spikes on the power rail, thought it should have killed the mico, but it only made it lock up.

    Something weird with the tach line back from the fan, it was injecting large (8v) back into the micro, thought that would have killed it too, but it didn't.

    The next one had be buggered for a while. The micro would PWM control a fan just fine at some large speed, like 200 on an 8bit 0-255 scale, but would just cause the micro to lock up at something slower. You'd never guess but it was inadequate decoupling capacitors, you can see my bodges on the PCB pics. A large ceramic works where the small electo is at the bottom, but I lifted a pad and it was an easier fix with that electro.


    So, all good now and it works and job done and the switch runs quiet now. Hah, No!

    Basically there is a fundamental error in the assumptions on how the switch monitors the fans health, that I'm going to save for the next installment on the hush switch project.
     

    Attached Files:

    Evilhomer and fredhoon like this.
  2. aXis

    aXis Member

    Joined:
    Jun 27, 2001
    Messages:
    5,146
    Location:
    Kalgoorlie, WA
    Looks great! Where did you get the board made?
     
  3. OP
    OP
    dakiller

    dakiller (Oscillating & Impeding)

    Joined:
    Jun 27, 2001
    Messages:
    7,646
    Location:
    Gippsland
  4. aXis

    aXis Member

    Joined:
    Jun 27, 2001
    Messages:
    5,146
    Location:
    Kalgoorlie, WA
    Something you might be interested in - I built a PCB milling machine using the Cyclone PCB Factory project. Cost was about $280ish and it makes some reasonable through hole boards. Certainly nothing as professional as yours pictured above, but it's really handy for prototyping. See here for photos: DIY CNC routers/mills thread

    Great thing is whenever I pickup a fault with my boards I can spin out a new PCB in under an hour.
     
  5. Technics

    Technics Member

    Joined:
    Apr 29, 2002
    Messages:
    1,079
    Location:
    Brisbane, AU
    You're not trying hard enough if the prototype doesn't have a few bodge wires. That is some serious decoupling though. Extra points for the board mount female Molex KK connectors. I don't think I have seen them before.
     
  6. OP
    OP
    dakiller

    dakiller (Oscillating & Impeding)

    Joined:
    Jun 27, 2001
    Messages:
    7,646
    Location:
    Gippsland
    I've done the PCB prototyping of all types in the past, nothing compares to a pro made board for me, especially with the high density SMD stuff I use now.

    Pretty much every version 1 of some PCB I've done has had some bodge needed, I thought I could could get away without any this time. The decoupling was just what I had on hand to try and fix my issues.

    The reverse mount connectors are the result of trawling Digikey for the 'does this exist?' part. I've seen reverse mount smd connectors, but they fan the legs out either side of the entry mount, the fan tabs would foul on them, where these don't.

    Bodge or not, this whole PCB design is scrapped and unviable, I'm starting again on version 2 now.
     
  7. OP
    OP
    dakiller

    dakiller (Oscillating & Impeding)

    Joined:
    Jun 27, 2001
    Messages:
    7,646
    Location:
    Gippsland
    Round 2.

    After making assumptions about how the fans are monitored in the switches, it turns out that they don't look at the tach signal from the fan at all. Instead they look at the pulses of current that are generated by the fans commutation, basically there is little spikes in the current when the fan spins and energizes each little coil in turn.

    The chip they use to do all this is the Microchip TC654 - http://ww1.microchip.com/downloads/en/DeviceDoc/20001734C.pdf

    Time to update the schematic

    fan2.png

    This is the new scheme to trick the switches fan controller into thinking that the fan is there.

    Q4 is the switches fan controller that is PWM'ing the normal fan at 40hz.

    Q3 is then used to fake current pulses to fool the switch into thinking that there is a fan there. Q3 dumps current by charging through C9, which is a large 3300uF capacitor, so that C9 is storing the power that would be wasted if we were just dumping current through a resistor here.

    C9 is then used to turn around and power the fans on the new fan controller.

    R17 holds the switching ground pin 1 of the switches fan controller high when it is not switching, making Q3 disabled when Q4 is in the off part of the PWM 40hz cycle. It means we can pulse Q3 with our fake fan signal all the time without causing any issue, not just when Q4 is on.

    There will need to be some balance between how much we turn on Q3 on, for C9 to be charged up enough to run the fans on our side and not on too much such that C9 is full and we can't dump enough current through it to make our fake fan signal. The switches fan controller wants to see ~100mA spikes. To makes this balance happen, we PWM the fake tach signal into Q3 to vary the amount of ON time for it to vary teh charge build up in C9. Our micro will measure the voltage on C9 to vary the PWM output into Q3.

    Simple yea?

    New board layout -
    csch.png
    cbrd.png

    c3d.png

    I'm going to sit on it to think if I've forgotten anything before putting in an order for it to be fabbed.
     
    Evilhomer and fredhoon like this.
  8. mtma

    mtma Member

    Joined:
    Aug 12, 2009
    Messages:
    4,632
    Don't suppose there is some plug-in method that you could use to just inject the desired commands in through SMBus ?
     
  9. OP
    OP
    dakiller

    dakiller (Oscillating & Impeding)

    Joined:
    Jun 27, 2001
    Messages:
    7,646
    Location:
    Gippsland
    The controller only goes down to a minimum 30% fan speed, which is still quite loud for these delta fans.

    Also, where’s the fun in that?
     
  10. Symon

    Symon (Plugging your Socket)

    Joined:
    Apr 17, 2002
    Messages:
    4,361
    Location:
    Santiago, Chile
    Just wanted to say that's a cool little project - looks like you had fun making it too.
     
  11. OP
    OP
    dakiller

    dakiller (Oscillating & Impeding)

    Joined:
    Jun 27, 2001
    Messages:
    7,646
    Location:
    Gippsland
    Round 2 PCB's arrived. Soldered the SMD stuff tonight. The size and density was pushing my soldering skills freehanding without a microscope.

    Hope to be coding it on the weekend.

    IMG_1068.jpg
    IMG_1069.jpg
     
    aXis and Symon like this.
  12. OP
    OP
    dakiller

    dakiller (Oscillating & Impeding)

    Joined:
    Jun 27, 2001
    Messages:
    7,646
    Location:
    Gippsland
    Update and closure.

    Round 2 circuit just didn't work in the end. It was a neat concept to pulse current into the original fan headers and use that stored charge to run the fans myself. It did work at very low fan speeds for a single fan plugged in, but I just couldn't get the capacitor to stay charged enough to really run the fans properly at all.

    Redid the PCB again and just had mosfets pulse current through a resistor as the fake fan signal. Works very well and I only need something like a 2% duty cycle on the fake fans PWM signal that simulates the fans stators switching.

    Once I had that all working, the next issue was the PWM control of the fans themselves. No matter what frequency I switched them at, they made too much noise, everything between 30hz and 15khz, they just droned or whined. The solution was to LC filter the PWM, and instead of spinning the PCB's again, I just bodged up a little protoboard to hold the fan headers and the inductor and capacitor to filter out the PWM noise.

    Built 8 boards and put them in the switches.

    DSC02154.jpg DSC02327.jpg

    This is the code that runs on the micro, written in the Arduino IDE, but I like to directly manipulate the registers for the hardware, so that might be a bit off putting for those with basic Arduino experience.

    Code:
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <util/delay.h>
    
    #define F_CPU 8000000
    
    static unsigned char NTC1 = 0;//adc
    static unsigned char NTC2 = 1;//adc
    static unsigned char NTC3 = 2;//adc
    
    static unsigned char LED1 = 14;
    static unsigned char LED2 = 15;
    static unsigned char LED3 = 5;
    
    static unsigned char FanOut = 9; //oc1a
    
    static unsigned char tachout1 = 8; //pb0
    static unsigned char tachout2 = 11; //pb3
    static unsigned char tachout3 = 12; //pb4
    
    volatile unsigned char count = 0;
    ISR (TIMER0_COMPA_vect) //pwm pulse each tach out in a round robin. 30khz timer - 10khz per tach.
    {
         if(count == 0)
              PORTB |= (1<<PB0);
         else  if(count == 1)
              PORTB |= (1<<PB3);
         else if(count == 2)
              PORTB |= (1<<PB4);
              
         count++;           
        
         if(count > 2)
              count = 0;
    }
    
    ISR (TIMER0_COMPB_vect) //clear pins for tach out.
    {
         PORTB &= ~((1<<PB0) | (1<<PB3) | (1<<PB4)) ;
    }
    
    #define TempCount 50
    volatile unsigned int TempArray[TempCount];
    unsigned char TempPointer = 0;
    
    ISR (ADC_vect, ISR_NOBLOCK) //read ADC and put into array.
    {
         TempArray[TempPointer++]=ADC;
    
         if(TempPointer >= TempCount)
              TempPointer = 0;
        
         ADCSRA |= (1<<ADSC);
    }
    
    //convert ADC to celcius reading
    float temp(float adc)
    {
         float output = 1023 / (float)adc - 1;
         output = 10000 / output;
        
         output = output / 10000;     // (R/Ro)
         output = log(output);                  // ln(R/Ro)
         output /= 3984;                   // 1/B * ln(R/Ro)
         output += 1.0 / (25 + 273.15); // + (1/To)
         output = 1.0 / output;                 // Invert
         output -= 273.15;                         // convert to C
        
         return output;
    }
    void setup()
    {   
         pinMode(LED1, OUTPUT);
         pinMode(LED2, OUTPUT);
         pinMode(LED3, OUTPUT);
         digitalWrite(LED1, HIGH);
         digitalWrite(LED2, HIGH);
         digitalWrite(LED3, HIGH);
        
         pinMode(FanOut, OUTPUT);
         digitalWrite(FanOut, LOW);
              
         pinMode(tachout1, OUTPUT);
         pinMode(tachout2, OUTPUT);
         pinMode(tachout3, OUTPUT);
         digitalWrite(tachout1, LOW);
         digitalWrite(tachout2, LOW);
         digitalWrite(tachout3, LOW);
    
         //ADC Setup
         ADMUX = (1<<REFS0) |  (1<<MUX1);  //ADC Vcc ref, MUX channel 2
         DIDR0 = (1<<ADC0D) | (1<<ADC1D) | (1<<ADC2D) | (1<<ADC3D); //disable digital input circuits
         ADCSRA = (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0) | (1<<ADSC) | (1<<ADEN) | (1<<ADIE); // clk/128 = 62khz clock, enable and interrupt on, start conversion
    
         //Timer 1 setup, PWM for fan control
         TCCR1A = (1<<COM1A1) | (1<<WGM12) | (1<<WGM11) | (1<<WGM10) ; //PWM fast 10bit, OC1A PWM output
         TCCR1B =  (1<<CS10); // CLK/1 -> 15khz pwm frequency
         OCR1A = 0; //fan pwm off
    
         //Timer 0 setup - Faking the tach signal
         TIMSK0 = (1<<OCIE0A) | (1<<OCIE0B); //interrupt on OCR0A and OCR0B
         OCR0A = 128;
         OCR0B = 5;
         TCCR0A = (1<<CTC0) | (1<<CS00) | (1<<CS01); //CTC mode, Overflow 488Hz   
    
         _delay_ms(5000);     
         //Serial.begin(9600);
    }
    
    void loop()
    {
         _delay_ms(100);
    
         //average temperature readings
         float temperature = 0;
         for (int i = 0 ; i < TempCount ; i++)
              temperature += TempArray[i];
         temperature /= TempCount;
         temperature = temp(temperature);
    
         //set fan PWM based off temperature, turn on around 40C, and full fans at around 50c
         float output = 11 * temperature - 400;
         int oc = round(output);   
         if(oc < 50)
              oc = 0;
         OCR1A = oc;
    
         //Serial.print(temperature, DEC);
         //Serial.write("C ");
         //Serial.print(output, DEC);
         //Serial.write("output ");
         //Serial.print(oc, DEC);
         //Serial.write("fan ");
         //Serial.write("\n");
    }
     
    Evilhomer likes this.
  13. OP
    OP
    dakiller

    dakiller (Oscillating & Impeding)

    Joined:
    Jun 27, 2001
    Messages:
    7,646
    Location:
    Gippsland
    Used a different board house for the PCB's this time around as well. JLCPCB

    $2 for 10 boards with a 2 day turn around. I shelled out $45 for express shipping and I had them in my hands in 4 days.
     
  14. Symon

    Symon (Plugging your Socket)

    Joined:
    Apr 17, 2002
    Messages:
    4,361
    Location:
    Santiago, Chile
    Great stuff mate, thanks for sharing.
     
    Technics likes this.
  15. terrabyte

    terrabyte Member

    Joined:
    Oct 5, 2003
    Messages:
    3,051
    Location:
    Syd, 2147, near Blacktown
    Very impressive! Thanks for sharing. Something like this would be a great solution for pretty much any 1u device with those tiny 40mm screamers.
     

Share This Page