Управление двумя кулерами
- Войдите на сайт для отправки комментариев
Вс, 16/04/2017 - 18:55
Доброго дня суток и с Праздником.
Собрал я усилитель класса А, этот класс безбожно греется ,собрать то было не тяжело ,а вот в програмированиии я не силен ,нашел скетч в инете ,все работает как надо ,но он на один куллек и датчик,а хотелось бы два независимых карлсона. Помогите пожалуйста допилить код под два независимых датчика и два куллера . и в идеале еще реализовать отключение при перегреве. Спасибо
#include <OneWire.h> // OneWire DS18S20, DS18B20, DS1822 Temperature Example // // http://www.pjrc.com/teensy/td_libs_OneWire.html // // The DallasTemperature library can do all this work for you! // http://milesburton.com/Dallas_Temperature_Control_Library OneWire ds(10); // on pin 10 (a 4.7K resistor is necessary) float current_temp; int FAN = 5; // PIN int FAN_pwm; // PWM 0..255 void setup(void) { TCCR0B = TCCR0B & B11111000 | B00000001; pinMode(FAN, OUTPUT); Serial.begin(9600); } void loop(void) { current_temp = get_temp(); if(current_temp > 45) FAN_pwm = 255; else if(current_temp > 40) FAN_pwm = 200; else if(current_temp > 35) FAN_pwm = 150; else if(current_temp > 30) FAN_pwm = 100; else if(current_temp > 25) FAN_pwm = 50; else FAN_pwm = 0; analogWrite(FAN, FAN_pwm); delay(5000); } float get_temp() { byte i; byte present = 0; byte type_s; byte data[12]; byte addr[8]; float celsius, fahrenheit; if ( !ds.search(addr)) { Serial.println("No more addresses."); Serial.println(); //ds.reset_search(); //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. present = ds.reset(); ds.select(addr); ds.write(0xBE); // Read Scratchpad Serial.print(" Data = "); Serial.print(present, HEX); Serial.print(" "); for ( i = 0; i < 9; i++) { // we need 9 bytes data[i] = ds.read(); Serial.print(data[i], HEX); Serial.print(" "); } Serial.print(" CRC="); Serial.print(OneWire::crc8(data, 8), HEX); Serial.println(); // 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; fahrenheit = celsius * 1.8 + 32.0; Serial.print(" Temperature = "); Serial.print(celsius); Serial.print(" Celsius, "); Serial.print(fahrenheit); Serial.println(" Fahrenheit"); return celsius; }
Нашел рабочее решение ,то что надо для двух пропеллеров, не ступенчетое управление карлсонами как в первом скетче ,а плавное.
/* Fanduino: 2 channels DS1820 based temperature fan controller Fans are controlled by a PWM output connected on * D3 for Fan 1 (PinA) * D11 for fan 2 (PinB) Onewire lib reads is values on D10 Sample drive circuit for pwm outputs : +12V N CHANNEL FET | D11 (ex:VN67AF) ------------ | or __-----------| -fan +fan | D3 Gate / \ Drain ------------ ---\/\/\/---*---| | 12V Fan on 120ohms | \ / arduino \ -- / 10K | Source \ | / | | | GND GND DS1820 wiring : 1: GND 2: D10 on arduino. A pull up of 4K7 MUST be wired also on pin 10. 3: VCC (5V) TOP VIEW --- / \ | | ------- 1 2 3 */ #include <OneWire.h> #include <DallasTemperature.h> int pinA = 3; // pin 3 and 11 are PWM output controled by Timer2 int pinB = 11; // connect pinA/B to H-Bridge // Data wire is plugged into port 2 on the Arduino #define ONE_WIRE_BUS 10 // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) OneWire oneWire(ONE_WIRE_BUS); // Pass our oneWire reference to Dallas Temperature. DallasTemperature sensors(&oneWire); // Compute linearization constant // Fan1 float Fan1Min=50; // PWM is between 40 and 255 for that fan (8 bit pwm) float Fan1Max=255; float Temp1Min=25.0; // relinearization will be done between 20 Celcius (pwm=Fan1Min) float Temp1Max=48.0; // to 48 celcius (pwm=Fan1Max) // Fan2 float Fan2Min=50; float Fan2Max=255; float Temp2Min=25.0; float Temp2Max=48.0; // float K1=(Fan1Max-Fan1Min)/(Temp1Max-Temp1Min); float K2=(Fan2Max-Fan2Min)/(Temp2Max-Temp2Min); void setup(){ // See wxxxxxxxxxxxxxxx //__________________________________TIMER2_for_Motor_PWM_________________________________ // set TIMER2 for PWM 31 kHz // // clear all prescaler bits in TCCR2B = the last 3 Bits // leave other bits as set by arduino init() in wiring.c byte mask = B11111000; TCCR2B &= mask; // TCCR2B is now xxxxx000 // // set CS22:20 in TCCR2B see p 156 of datasheet TCCR2B |= (0<<CS22) | (0<<CS21) | (1<<CS20); // same as TCCR2B |= B00000001; TCCR2B is now xxxxx001 //__pinmode pinMode(pinA,OUTPUT); pinMode(pinB,OUTPUT); // start serial port Serial.begin(9600); Serial.println("Fanduino: DS1820 based temperature fan controller"); // Start up the library sensors.begin(); } void loop() { // call sensors.requestTemperatures() to issue a global temperature request sensors.requestTemperatures(); // Send the command to get temperatures // read sensors values float T1 = sensors.getTempCByIndex(0); float T2 = sensors.getTempCByIndex(1); // skip conversion error if ( ( T1>-127.00 ) && ( T2 > -127.0) ) { // print them on serial Serial.print("Temp1: "); Serial.print(T1); Serial.print(" Temp2: "); Serial.print(T2); // normalize values between TempXMin and TempXMax if (T1 < Temp1Min) T1 = Temp1Min; if (T1 > Temp1Max) T1 = Temp1Max; if (T2 < Temp2Min) T2 = Temp2Min; if (T2 > Temp2Max) T2 = Temp2Max; // compute pwm value // when temp will be from TempXMin celcius to TempXMax, pwm will be from FanXMin to FanXMax float Pwm1=((T1-Temp1Min)*K1)+Fan1Min; float Pwm2=((T2-Temp2Min)*K2)+Fan2Min; // print pwm values on serial for debugging Serial.print (" PWM1: "); Serial.print ( Pwm1 ); Serial.print (" PWM2: "); Serial.println ( Pwm2 ); // Assign pwm analogWrite(pinA, Pwm1 ); analogWrite(pinB, Pwm2 ); // and sleep 1s until next computation delay (1000); } }Усилки собирать умеешь, а регулятор оборотов для кулера на lm358 сделать проблема.
PS: http://cxema.my1.ru/publ/vse_dlja_quot_kulera_quot_ventiljatora/termoreguljator_s_kulerom/89-1-0-6069
У меня нано штук 5 вяляются без дела и даласов горсть ,делаю из того что есть . Да и хотелось плавное регулирование кулеров по шим ,ну и за одно и аварийное отключение при перегреве . Также через ардуино по ИК будет управление селектром и мотором резистора громкости,и вывод температуры на lcd с уровнем сигнала . Все скетчи есть ,в кучу как бы их собрать. Вообще планирую в усилок поставить два Нано, первый будет отвечать за вывод инфы на экран и терморегулятор, второе нано за управлением селектора входов и мотором резистора громкости.С управлением ИК разобрался ,все работает пока на макетке .
По коду не понял, но на своём опыте могу сказать, недавно крутил процессорыный кулер с 4мя пинами, так вот 4й пин, который шим, расчитан на 25 кГц, обычный analogWrite его практически не регулирует.
Делаю на IRF630 которых у меня куча... NTC резистор на 10к стоит 5 руб...
http://avtosxema.com/shema/410-termoregulyator-dlya-ventilyatora.html
так вот 4й пин, который шим, расчитан на 25 кГц, обычный analogWrite его практически не регулирует.
Все работает без проблем,что первый скетч ,что второй.Подвывание от шим на малых оборотах немного были,разрулил кондеем.https://www.youtube.com/watch?v=VYAdsooPao8
P.S выписка из мануала "На большинстве плат Arduino (на базе микроконтроллера ATmega168 или ATmega328) ШИМ поддерживают порты 3, 5, 6, 9, 10 и 11, на плате Arduino Mega порты с 2 по 13. На более ранних версиях плат Arduino analogWrite() работал только на портах 9, 10 и 11.
Если работает, как того хотели, то отлично )
Я руководствовался этим. Мне данная информация помогла добиться того, что мне было нужно, возможна будет полезна еще кому.
Уважаемые помогите пожалуйста ,не могу соединить два скетча ,ошибок не выдает ,но не работает , хотел в скетч кулеров воткнуть скетч управление ик, скетч управления по ик
Я вот как я их пытаюсь обьединить,
#include <IRremote.h> #include <LiquidCrystal.h> #include <OneWire.h> #include <DallasTemperature.h> LiquidCrystal lcd(7, 6, 5, 11, 3, 2); int RECV_PIN = 9; //вход ИК приемника IRrecv irrecv(RECV_PIN); decode_results results; //eventTime, для паузы, вместо delay,будем использовать функцию millis. unsigned long eventTime=0; //индикация таймера int timer = 40; int L24 = 24; //пины управляющие моторами, светодиодами, или реле, чем угодно. int L26 = 26; int L28 = 28; int L30 = 30; int L32 = 32; int L34 = 34; int L36 = 36; int L38 = 38; int pinA = 4; // куллер1 int pinB = 13; // кулер2 // Data wire is plugged into port 2 on the Arduino #define ONE_WIRE_BUS 10 // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) OneWire oneWire(ONE_WIRE_BUS); // Pass our oneWire reference to Dallas Temperature. DallasTemperature sensors(&oneWire); // Compute linearization constant // Fan1 float Fan1Min=57; // PWM is between 40 and 255 for that fan (8 bit pwm) float Fan1Max=255; float Temp1Min=25.0; // relinearization will be done between 20 Celcius (pwm=Fan1Min) float Temp1Max=44.0; // to 48 celcius (pwm=Fan1Max) // Fan2 float Fan2Min=57; float Fan2Max=255; float Temp2Min=25.0; float Temp2Max=44.0; // float K1=(Fan1Max-Fan1Min)/(Temp1Max-Temp1Min); float K2=(Fan2Max-Fan2Min)/(Temp2Max-Temp2Min); void setup(){ irrecv.enableIRIn(); // включить приемник lcd.begin(20, 4); pinMode(L24, OUTPUT); // назначаем пины как выходы pinMode(L26, OUTPUT); pinMode(L28, OUTPUT); pinMode(L30, OUTPUT); pinMode(L32, OUTPUT); pinMode(L34, OUTPUT); pinMode(L36, OUTPUT); pinMode(L38, OUTPUT); // See wxxxxxxxxxxxxxxx //__________________________________TIMER2_for_Motor_PWM_________________________________ TCCR0B = TCCR0B & B11111000 | B00000001; //__pinmode pinMode(8, OUTPUT); pinMode(pinA,OUTPUT); pinMode(pinB,OUTPUT); // Start up the library sensors.begin(); } void loop() { // call sensors.requestTemperatures() to issue a global temperature request sensors.requestTemperatures(); // Send the command to get temperatures // read sensors values float T1 = sensors.getTempCByIndex(0); float T2 = sensors.getTempCByIndex(1); // skip conversion error if ( ( T1>-127.00 ) && ( T2 > -127.0) ) // print them on serial lcd.setCursor(0,0); lcd.print("TL:"); lcd.print(T1); lcd.setCursor(0,1); lcd.print("TR:"); lcd.print(T2); //Аварийное отключение if (T1> 50 || T2 > 50) { digitalWrite( 8,HIGH); } else if ( T1< 50 || T2 < 50) { digitalWrite( 8,LOW); } // normalize values between TempXMin and TempXMax { if (T1 < Temp1Min) T1 = Temp1Min; if (T1 > Temp1Max) T1 = Temp1Max; if (T2 < Temp2Min) T2 = Temp2Min; if (T2 > Temp2Max) T2 = Temp2Max; // compute pwm value // when temp will be from TempXMin celcius to TempXMax, pwm will be from FanXMin to FanXMax float Pwm1=((T1-Temp1Min)*K1)+Fan1Min; float Pwm2=((T2-Temp2Min)*K2)+Fan2Min; // print pwm values on serial for debugging lcd.setCursor(9,0); lcd.print ("FAN1:"); lcd.print ( Pwm1 ); lcd.setCursor(9,1); lcd.print ("FAN2:"); lcd.print ( Pwm2 ); // Assign pwm analogWrite(pinA, Pwm1 ); analogWrite(pinB, Pwm2 ); // and sleep 1s until next computation // Эта конструкция нужна чтобы конвертировать пульсирующий (-) с (ИК) преемника сигнал в постоянный. //После появление и пропадания сигнала, состояние сразу не меняется! а ждет 100 миллисекунд. //Если 100 миллисекунд не прошло, и поступил еще один сигнал с пульта, тогда таймер заново запускается на 100 миллисекунд. //Проще говоря, пока кнопка на пульте нажата таймерПИН остается вКлюченным, если кнопка на пульте отпущена таймерПИН вЫключен. // Читаем данные с (ИК) преемника. В момент приема данных у (ИК) приемника на выходе появляется пульсирующий (-)отрицательный сигнал { if (digitalRead(RECV_PIN) == LOW) // Если обнаружен отрицательный сигнал запускаем таймер,и включаем таймерПИН //(timer, HIGH); eventTime=millis(),digitalWrite(timer, HIGH); // Продолжительность работы таймера >100 миллисекунд. И ТаймерПИН выключаем //(timer, LOW) if(millis()-eventTime>100) digitalWrite(timer, LOW) // и вЫключаем все ,digitalWrite(L24, LOW),digitalWrite(L26, LOW),digitalWrite(L28, LOW) ,digitalWrite(L30, LOW),digitalWrite(L32, LOW),digitalWrite(L34, LOW),digitalWrite(L36, LOW),digitalWrite(L38, LOW); if (irrecv.decode(&results)) // включаем нужный нам pin if (results.value == 0x2421 && (digitalRead(timer) == HIGH) )digitalWrite(L24, HIGH); if (results.value == 0x6421 && (digitalRead(timer) == HIGH) )digitalWrite(L26, HIGH); if (results.value == 0x5821 && (digitalRead(timer) == HIGH) )digitalWrite(L28, HIGH); if (results.value == 0x100C8C9 && (digitalRead(timer) == HIGH) )digitalWrite(L30, HIGH); if (results.value == 0x1002829 && (digitalRead(timer) == HIGH) )digitalWrite(L32, HIGH); if (results.value == 0x100A8A9 && (digitalRead(timer) == HIGH) )digitalWrite(L34, HIGH); if (results.value == 0x1006869 && (digitalRead(timer) == HIGH) )digitalWrite(L36, HIGH); if (results.value == 0x100E8E9 && (digitalRead(timer) == HIGH) )digitalWrite(L38, HIGH); irrecv.resume(); } }Термостат работает нормальо ,а вот ик никак не хочет . Спасибо
Я конечно ничего не понял, и поэтому хочу спросить автора темы: Вы что хотите получить?
1. Включать вентилятор для охлаждения радиатора с датчиком температуры?
2. Есть несколько Arduino и хочется куда-нибудь их поставить?
Если вы хотите охлаждать радиатор- то поставьте термореле типа такого. Там всего 2 провода. И будет все работать без кода.
https://ru.aliexpress.com/item/1pcs-KSD9700-40-120-oC-250V-60-Degree-Celsius-N-O-Thermostat-Kit-Temperature-Switch-normal/32746868242.html?spm=2114.03010208.3.2.nUEYoh&ws_ab_test=searchweb0_0,searchweb201602_3_10152_10065_10151_10068_10136_10137_10060_10138_10155_10062_10156_10154_10056_10055_10054_10059_10099_10103_10102_10096_10148_10169_10147_10052_10053_10142_10107_10050_10051_10084_10083_10119_10080_10082_10081_10110_10111_10112_10113_10114_10181_10037_10032_10078_10079_10077_10073_10070_10123_10120_10127_10124_10125-10120,searchweb201603_10,afswitch_1_afChannel,ppcSwitch_5&btsid=1d56eac8-c87c-4621-80d7-13c0d60a532b&algo_expid=c1ff4794-aa6f-4ff2-8244-38390a331d11-0&algo_pvid=c1ff4794-aa6f-4ff2-8244-38390a331d11
Уважаемый мне необходима плавная регулировка оборотов в зависимости от температуры нагрева ,тобишь тупо воткнуть термопару и навсю раскрутить обороты , это конечно и без кода можно . Дело в том что любой карлсон издаёт шум ,в моём случае в 50% оборотов которых достаточно для охлаждения, чтоб услышать шум это нужно постараться .От нагрева выходных транзисторов меняется Ток покоя усилителя , значимо мне необходима одинаковая температура без скачков термопары .Резкие перепады от термопары и плохо влияют на кристалы выходных транзисторов которые стоят в разы дороже ардуино. Опять же необходимо аварийное отключение при перегреве ,усилители класса -А имеют свойство черезмерно выделять тепло по причине своей прожорливости. Ну и ко всему прочему ваш датчиук сможет вывести уровень сигнала на экран и прочую инфу ,а также покрутить мото/резюк ALPS с ИК пульта. Вы код хотябу гляньте . И ардуино не такой ценный экспонат чтоб его ставить на тумбочку обложив венками, он должен работать по назначению нашим прихотям.
Вот теперь понятно.
По поводу температуры усилка А. (Он как я помню работает при постоянном токе покоя через транзисторы.) При установившемся режиме она выйдет на определенный уровень и будет постоянна. Вопрос другой. До какой температуры вы хотите нагреть транзисторы и радиатор. Я например нагревал радиатор до 120 град. Правда усилок был класса АВ. А если от нагрева меняется ток покоя выходных транзисторов, да тем более в классе А. - то у вас плохая схема термостабилизации выходных транзисторов. У меня при изменении температуры радиатора от 20 до 120 град ток покоя выходного каскада менялся от 180 до 160 ма и при этом понижался.
Поспрашайте лучше автора Усилителя по ссылке: По крайней мере если напишите в личку все должен обьяснить, как и что делать для класса А. И про температуру усилка тоже. Да и выложите ссылку хотябы на усилок. Может вопрос решится просто.
http://forum.vegalab.ru/showthread.php?t=1433
Вот теперь понятно.
По поводу температуры усилка А. (Он как я помню работает при постоянном токе покоя через транзисторы.) При установившемся режиме она выйдет на определенный уровень и будет постоянна. Вопрос другой. До какой температуры вы хотите нагреть транзисторы и радиатор. Я например нагревал радиатор до 120 град. Правда усилок был класса АВ. А если от нагрева меняется ток покоя выходных транзисторов, да тем более в классе А. - то у вас плохая схема термостабилизации выходных транзисторов. У меня при изменении температуры радиатора от 20 до 120 град ток покоя выходного каскада менялся от 180 до 160 ма и при этом понижался.
Поспрашайте лучше автора Усилителя по ссылке: По крайней мере если напишите в личку все должен обьяснить, как и что делать для класса А. И про температуру усилка тоже. Да и выложите ссылку хотябы на усилок. Может вопрос решится просто.
http://forum.vegalab.ru/showthread.php?t=1433