Главная » Хабрахабр » Полупассивное охлаждение компьютерного БП

Полупассивное охлаждение компьютерного БП

Привет! Это устройство применимо не только в компьютерном БП, но мы будем про компьютерный, как насущный 🙂

Процессоры последних поколений содержат в себе пригодную для повседневных задач графическую видео систему.
Техпроцесс производства процессоров неуклонно уменьшается, вместе с ним уменьшается и энергопотребление. Если вы не сильно требовательны к производительности в видео играх то за относительно скромный бюджет можно задуматься о тихом компьютере который будет издавать звуки только под большой нагрузкой, что случается не часто.

Далее идёт моё видение конфигурации компа для полупассивного охлаждения.

Средний CPU в пике своей загрузки выделяет 65 Вт тепла, охладить его можно заводским кулером с большей (нежели штатный) мощностью 120-150 Вт выставив настройки в BIOS чтобы он начинал крутиться только при загрузке 30-40% CPU либо температурой выше 40°С.

Ещё один источник шума это HDD, но тут всё просто, я заменил его на SSD.

Можно купить полностью пассивный либо полу пассивный изначально, но тут цена вопроса: (от $150) возможно, есть смысл направить эти средства на бОльшую производительность? Остался вентилятор блока питания который крутится постоянно.

Но при длительной работе под большой нагрузкой радиаторы внутри стали разогреваться свыше 60°С, так что решено было вернуть вентилятор но сделать его обороты контролируемыми. Обычный, 500 Вт блок питания ($50) имеет огромный запас по мощности в моём случае, поэтому я решил отключить вентилятор полностью.

За основу был взят Arduino nano на базе ATMEGA168PA, из разных кусков чужих проектов составлен свой.

Поскольку ресурсы контроллера позволяют, решено было сделать трёхцветный светодиодный индикатор по типу smart LED с различным миганием и цветом в зависимости от температуры.

При достижении >67°С включается звуковой извещатель. Температуру измеряет датчик DS18B20, в зависимости от температуры увеличиваются либо уменьшаются обороты вентилятора. Также я пробовал управлять трёхпроводным вентилятором, всё получилось, но никак не мог заставить его полностью остановиться. Транзистор — любой NPN с током > тока вашего вентилятора.

Поэтому программно частота ШИМ поднята до 25 кГц. Изначально использовал дефолтную частоту ШИМ (448,28 Гц) но на низких оборотах кулер издавал едва заметный звон, что никак не вяжется с концепцией бесшумного охлаждения.

Вот видео демонстрирующее работу устройства

А вот собственно, скетч, прошу сильно не пинать это мой первый скетч для Ардуины 🙂

// 2 - DS18x20 data
// 3 - green LED (a 330 Ohm resistor is necessary)
// 5 - orange LED (a 330 Ohm resistor is necessary)
// 6 - red LED (a 330 Ohm resistor is necessary)
// 9 - PWM Fan
// 8 - Buzzer #include <OneWire.h> byte temp; // temperature of sensor
byte greenLED = 3;
byte orangeLED = 5;
byte redLED = 6;
byte FanSpeed = 0;
int piezoPin = 8;
// Массив режимов работы светодиода
byte modes[] = { 0B00000001, //Светодиод выключен 0B00000101, //Горит постоянно 0B00010101, //Мигание по 0.5 сек 0B01010101, //Короткая вспышка раз в секунду 0B10101010, //Две короткие вспышки раз в секунду 0B00010101, //Три короткие вспышки раз в секунду 0B01010101 //Частые короткие вспышки (4 раза в секунду)
}; uint32_t ms, ms1 = 0, ms2 = 0, ms3 = 0, ms4 = 0, ms5 = 0;
uint8_t blink_loop = 0;
uint8_t blink_mode = 0;
uint8_t modes_count = 0; bool FirstRun = 0; OneWire ds(2); // on pin 10 (a 4.7K resistor is necessary) void analogWrite25k(int pin, int value)

} void setup(void) { pinMode(redLED, OUTPUT);
pinMode(greenLED, OUTPUT);
pinMode(orangeLED, OUTPUT);
pinMode(9, OUTPUT); modes_count = 1;
blink_mode = modes[modes_count]; TCCR1A = 0; // undo the configuration done by... TCCR1B = 0; // ...the Arduino core library TCNT1 = 0; // reset timer TCCR1A = _BV(COM1A1) // non-inverted PWM on ch. A | _BV(COM1B1) // same on ch; B | _BV(WGM11); // mode 10: ph. correct PWM, TOP = ICR1 TCCR1B = _BV(WGM13) // ditto | _BV(CS10); // prescaler = 1 ICR1 = 200; // TOP = 320 // Serial.begin(9600); } void loop() { byte i; byte present = 0; byte type_s; byte data[12]; byte addr[8]; float celsius; if ( ( ms - ms3 ) > 1000 || ms < ms3 ){ ms3 = ms; if ( !ds.search(addr)) { // Serial.println("No more addresses."); // Serial.println(); ds.reset_search(); if ( ( ms - ms4 ) > 250 || ms < ms4 ){ ms4 = ms; //delay(250); return; } } // Serial.print("ROM ="); for( i = 0; i < 8; i++) { // Serial.write(' '); // Serial.print(addr[i], HEX); } if (OneWire::crc8(addr, 7) != addr[7]) { // Serial.println("CRC is not valid!"); return; } // Serial.println(); // the first ROM byte indicates which chip switch (addr[0]) { case 0x10: Serial.println(" Chip = DS18S20"); // or old DS1820 type_s = 1; break; case 0x28: Serial.println(" Chip = DS18B20"); type_s = 0; break; case 0x22: Serial.println(" Chip = DS1822"); type_s = 0; break; default: Serial.println("Device is not a DS18x20 family device."); return; } ds.reset(); ds.select(addr); ds.write(0x44, 1); // start conversion, with parasite power on at the end } //delay(1000); // maybe 750ms is enough, maybe not // we might do a ds.depower() here, but the reset will take care of it. if ( ( ms - ms2 ) > 900 || ms < ms2 ){ ms2 = ms; present = ds.reset(); ds.select(addr); ds.write(0xBE); // Read Scratchpad for ( i = 0; i < 9; i++) { // we need 9 bytes data[i] = ds.read(); } // Convert the data to actual temperature // because the result is a 16 bit signed integer, it should // be stored to an "int16_t" type, which is always 16 bits // even when compiled on a 32 bit processor. int16_t raw = (data[1] << 8) | data[0]; if (type_s) { raw = raw << 3; // 9 bit resolution default if (data[7] == 0x10) { // "count remain" gives full 12 bit resolution raw = (raw & 0xFFF0) + 12 - data[6]; } } else { byte cfg = (data[4] & 0x60); // at lower res, the low bits are undefined, so let's zero them if (cfg == 0x00) raw = raw & ~7; // 9 bit resolution, 93.75 ms else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms //// default is 12 bit resolution, 750 ms conversion time } celsius = (float)raw / 16.0; temp = celsius; // Serial.println("TEMPERATURE IS:"); // Serial.println(temp); } ms = millis();
// Событие срабатывающее каждые 125 мс if( ( ms - ms1 ) > 125|| ms < ms1 ){ ms1 = ms; // Режим светодиода ищем по битовой маске if ( temp <= 50 ) { digitalWrite(orangeLED, LOW); digitalWrite(redLED, LOW); if( blink_mode & 1<<(blink_loop&0x07) ) digitalWrite(greenLED, HIGH); else digitalWrite(greenLED, LOW); blink_loop++; if ( temp <= 40 ) { blink_mode = modes[0]; analogWrite25k ( 9, 0); FirstRun = 0; } if ( temp >= 41 && temp <= 45 ) { blink_mode = modes[1]; // Make a push impulse for starting fan (1 sec) if ( FirstRun == 0 ) { ms5 = ms; FirstRun = 1; } if (FirstRun == 1 && (2000 > (ms - ms5))) { analogWrite25k ( 9, 33); // Fan start impulse } if (FirstRun == 1 && (2000 < (ms - ms5))) { analogWrite25k ( 9, 28); // first speed } } if ( temp >= 46 && temp <= 50 && FirstRun == 1) { blink_mode = modes[2]; analogWrite25k ( 9, 29); } } if ( temp >= 51 && temp <= 61 ) { digitalWrite(greenLED, LOW); digitalWrite(redLED, LOW); if( blink_mode & 1<<(blink_loop&0x07) ) digitalWrite(orangeLED, HIGH); else digitalWrite(orangeLED, LOW); blink_loop++; if ( temp >= 51 && temp <= 54 ) { blink_mode = modes[0]; analogWrite25k ( 9, 30); } else if ( temp >= 55 && temp <= 58 ) { blink_mode = modes[1]; analogWrite25k ( 9, 31); } else if ( temp >= 59 && temp <= 61) { blink_mode = modes[2]; analogWrite25k ( 9, 32); } } if ( temp >= 62 && temp <= 120 ) { digitalWrite(greenLED, LOW); digitalWrite(orangeLED, LOW); if( blink_mode & 1<<(blink_loop&0x07) ) digitalWrite(redLED, HIGH); else digitalWrite(redLED, LOW); blink_loop++; if ( temp >= 62 && temp <= 66 ) { blink_mode = modes[0]; analogWrite25k ( 9, 33); } if ( temp >= 67 && temp <= 70 ) { blink_mode = modes[1]; analogWrite25k ( 9, 34); } if ( temp >= 71 && temp <= 120) { blink_mode = modes[2]; analogWrite25k ( 9, 50); tone(piezoPin, 2500, 30); } } } }


Оставить комментарий

Ваш email нигде не будет показан
Обязательные для заполнения поля помечены *

*

x

Ещё Hi-Tech Интересное!

Особенности работы в интернациональной команде. Япония

Причины переезда всегда разные, но чаще всего люди просто хотят перемен. Поработать в другой стране это, как говорят сейчас, challenge (вызов) для многих российских специалистов: сможешь ли «найти» себя в новой стране, в новой роли. И хорошо, если они к ...

[Перевод] Как работают браузеры — введение в безопасность веб-приложений

Давайте начнем серию статей по безопасности веб-приложений с объяснением того, что делают браузеры и как именно они это делают. Поскольку большинство ваших клиентов будут взаимодействовать с вашим веб-приложением через браузеры, необходимо понимать основы функционирования этих замечательных программ. Chrome и lynx ...