Skocz do zawartości

Asica10

Użytkownicy
  • Zawartość

    8
  • Rejestracja

  • Ostatnio

Wszystko napisane przez Asica10

  1. Witam, Prosiłbym o sprawdzenie schematu oraz PCB. Układ ma służyć do zarządzania pracą wentylatorów/pompy/ czujników temp/ LCD w chłodzeniu wodnym. Układ opraty na Arduino Nano V3. Voltage Regulator - regulacja napięcia w zakresie 0-12V, sygnał sterujący to PWM (wykorzystywany do regulacji tych wentylatorów które nie mają dedykowanego przewodu do PWM, wiem że istnieje sposób regulacji za pomoca PWM o czestotliwosci ponad 20kHz na zasilaniu, ale albo są problemy z odczytem obrotów, albo z liniową regulacją, o problemie pisałem na forum i niestety nie udało się tego rozwiązać, więc musi zostać taki sposób regulacji). RPM FAN - odczyt prędkości obrotowej wentylatorów (czujnik w wentylatorach typu otwarty kolektor) Voltage Monitor - odczyt napięcia od 0-12V za pomocą arduino FAN - podzielone na 5 niezależnych grup wentylatorów, każda grupa posiada odczyt obrotów dla 1 went jak i regulacje obrotów za pomocą napięcia lub PWM ( przy regulacji z PWM występuje jeszcze układ który wyłącza wentylatory ponieważ wypełnienie na poziomie 0 nie wyłącza całkowicie went - wiatrak ma wbudowane zabezpieczenia) Temp Sensor - 3 czujniki typu 1 wire D18B20 LCD + Switch + Fotoresistor - sterowanie LCD po I2C do tego przycisk funkcyjny i fotorezystor który będzie służył do regulacji podświetlania LCD (za pomocą PWM). Każda uwaga będzie dla mnie cenna, ponieważ jest to pierwszy "tak zaawansowany" projekt dla mnie. Z góry dziękuje za pomoc. Pozdrawiam
  2. Jednak muszę wrócić do sposobu wyświetlania co jakiś czas. Jak zliczam impulsy pojawia się taki problem że jak wentylator się zatrzyma jego obroty się nie zaktualizują i zatrzymają się na jakiejś wartości. Przez co np nie zadziałają zabezpieczenia... wiem że można było by to rozwiązać jakimiś dodatkowymi warunkami, ale Wiem że obarcza to wyniki błędem, ale ten błąd jest na tyle mały, że jest akceptowalny.
  3. Buduje sytem zarządzania chłodzeniem wodnym w PC ( i to jest jedn z kilku części). Wyniki te będą wyświetlane tyljo na LCD 4x20 nic więcej (przynajmniej na chwile obecną, poza pojawieniem się alarmu jak obroty pompy będą za niskie ) Prosze powiedz jescze czy taki zapis jak zaproponowałem w loop() będzie ok okiem fachowca.
  4. Dziękuje bardzo za wyczrupującą i niesamowicie przydatną wypowiedź. Dziękuje, miło to słyszeć. Dopiero wszystkiego powoli się uczę (ok 1 miesiąc), ale wiem że jeszcze długa droga przede mną. A racja przeoczyłem to, zostało to po testowaniu jak zachowuje się program gdy wykrywam zbocze opadające if(!(PIND & (1< Muszę się przyznać, że nie wiedziałem o istnieniu takich zmiennych... Muszę sobie dokładnie o nich poczytać, bo patrząc pierwsze na kod myśle sobie że coś jest nie tak a dopiero potem doczytałem że: Zastanawiałem się na stworzeniem dodatkowej funkcji by to wykonywała, ale dlaczego tego nie zrobiłem sam nie wiem... W szczególności że docelowo prędkość będzie mierzona dla 5 wentylatorów, więc głupie było by powtarzać to samo 5 razy. Wydaje się to lepszym rozwiązaniem (napewno dokładniejsze będą wyniki), ale jak odliczam 1s to wyniki pojawiają się co 1s, jak zacznę zliczać do pewnej ilości countera to dla każdego wentylatora w innym momencie osiągnięta zostanie wartość zadana. Nie za bardzo rozumiem jak to zrobić w funkcji przerwana i potem obliczać to w loop(). Ja bym to zrobił tak że w głównym loop() sprawdzam warunki (tyle ile jest wentylatorów) czy counter osiągnął zadaną wartość jeżeli tak wchodzę w if wykonuje dzielenie i wyświetlam wynik. if (counter_1 >= 100) { cli(); // Global Interrupt Disable - calculations unsigned int rpm_1 = RPMconversion / (totalTime_1 / counter_1); counter_1 = 0; totalTime_1 = 0; sei(); Serial.print ("RPM =\t"); Serial.println (rpm_1); } I tak dla każdego wentylatora... Na tą chwile nie umiem tworzyć takich rzeczy, ale dopisze to sobie do listy czego muszę się w niedługim czasie nauczyć Jeszcze raz dziękuje bardzo za pomoc. Pozdrawiam
  5. Zmodyfikowałem troche kod, teraz mierze czas pomiędzy poszczególnymi sygnałami (wyniki powinny być dokładniejsze) Prosiłbym o wskazówki co można wyżucić z przerwań by przyspieszyć ich wykonywanie? //read RPM PCINT by Asica10 //-----Define variable for measure RPM----- volatile unsigned long timeLast_1 = 0; volatile unsigned long timeLast_2 = 0; volatile unsigned long timeLast_3 = 0; volatile unsigned long deltaT_1 = 0; volatile unsigned long deltaT_2 = 0; volatile unsigned long deltaT_3 = 0; volatile unsigned long sum_of_time_1 = 0; volatile unsigned long sum_of_time_2 = 0; volatile unsigned long sum_of_time_3 = 0; volatile int counter_1 = 0; // Variable which measurement how many interrupts have occurred volatile int counter_2 = 0; volatile int counter_3 = 0; volatile uint8_t interrupt_pin = 0xFF; // Variable used to check where an interrupt occurs //Fans definition const byte sensor = 2; // Quantity of fan sensors (tacho line) const unsigned long RPMconversion = 60000000/sensor; //Used in converting pulses form sensors to RPM int rpm_1 = 0; int rpm_2 = 0; int rpm_3 = 0; unsigned long previous_millis = 0; void setup() { PCICR |= (1<<PCIE2); // define interrupt on PCIE2 - PCINT[23:16] PCMSK2 |= (1<<PCINT18) | (1<<PCINT19) | (1<<PCINT20); // Permission to interrupt Serial.begin(9600); sei(); // Global Interrupt Enable } void loop() { if ((millis() - previous_millis == 1000)) //Update every one second { previous_millis = millis(); cli(); // Global Interrupt Disable - when calculeting rpm_1 = RPMconversion / (sum_of_time_1 / counter_1); //calculating RPM for fan rpm_2 = RPMconversion / (sum_of_time_2 / counter_2); rpm_3 = RPMconversion / (sum_of_time_3 / counter_3); counter_1 = 0; counter_2 = 0; counter_3 = 0; sum_of_time_1 = 0; sum_of_time_2 = 0; sum_of_time_3 = 0; sei(); Serial.print("RPM =\t"); //print the word "RPM" and tab. Serial.println(rpm_1); // print the rpm value. Serial.print("RPM =\t"); //print the word "RPM" and tab. Serial.println(rpm_2); // print the rpm value. Serial.print("RPM =\t"); //print the word "RPM" and tab. Serial.println(rpm_3); // print the rpm value. } } ISR(PCINT2_vect) { // interrupt vector uint8_t changedbits = PIND ^ interrupt_pin; interrupt_pin = PIND; if((PIND & (1<<PD2))) //detect only rising edges { unsigned long timeNow = micros(); // Get current time if((changedbits & (1 << PD2))) //check where was interrupt { deltaT_1 = timeNow - timeLast_1; // calculate change in time since last crossing event timeLast_1 = timeNow; // store current time for next crossing event sum_of_time_1 = sum_of_time_1 + deltaT_1; counter_1++; } if((changedbits & (1 << PD3))) { deltaT_2 = timeNow - timeLast_2; timeLast_2 = timeNow; sum_of_time_2 = sum_of_time_2 + deltaT_2; counter_2++; } if((changedbits & (1 << PD4))) { deltaT_3 = timeNow - timeLast_3; timeLast_3 = timeNow; sum_of_time_3 = sum_of_time_3 + deltaT_3; counter_3++; } } }
  6. Dziękuje bardzo za wyczerpującą odpowiedź. Nie mam niestety oscyloskopu ale mam do niego dostęp. Zrobiłem dziś test tak wygląda przebieg z tacho wentylatora: Nie dziwie się dlaczego pojawiała się różnica pomiędzy zboczem narastającym i opadającym... Zastosowałem w celu przetestowania kondensator 100nF (wpięty pomiędzy masą a tacho) i przebieg wygląda tak: Taka sama zależność była dla różnych wentylatorów i różnych napięć. Po przetestowaniu tego rozwiązania z Arduino wszystko jest ok jeżeli chodzi o liczbę zboczy narastających i opadających. Zmodyfikuje program według Twoich propozycji myśle że może pomóc ponieważ znacząco skórce czas gdzie przerwania są wyłączone.
  7. Wywaliłem wysyłanie danych poprzez port szeregowy poza obszar gdzie przerwania są wyłączone, poprawa wystąpiła w granicach błędu pomiarowego. Co zauważyłem że jeżeli zrobię pomiar tylko dla 1 went i wywalę detekcje gdzie to wystąpiło to obroty skaczą o ok 10% w góre (wygląda na to że kilka lini kodu wprowadza znaczne zaburzenia). Po wywaleniu wykrywania pinu wprowadziłem detekcje zbocza opadającego/narastającego np: if(!(PIND & (1<
  8. Witam wszystkich! Mam problem z przerwaniami PCINT. Używam ich do zliczania impulsów ( do wyświetlania obrotów wentylatora komputerowego). Problem że wynik który otrzymuje jest oo ok 20% inny niż rzeczywiste obroty. Tak samo obroty bardzo skaczą przy ok 1.5k skoki są rzędu 200+/- wciągu 1 sekundy, gdzie wentylator kręci się praktycznie tak samo +/- 10rpm. Prosiłbym o weryfikacje kodu i pomoc w znalezieniu błędu.... //read RPM PCINT by Asica10 //-----Define variable for measure RPM----- volatile int rpm_counter_1 = 0; volatile int rpm_counter_2 = 0; volatile int rpm_counter_3 = 0; volatile uint8_t interrupt_pin = 0xFF; // Variable used to check where an interrupt occurs int rpm_1 = 0; int rpm_2 = 0; int rpm_3 = 0; unsigned long previous_millis = 0; //Defines the structure for multiple fans and //their dividers typedef struct{ char fantype; unsigned int fandiv; }fanspec; //Fans definitions //Varible used to select the fan and it's divider, fanspec fanspace[3]={{0,1},{1,2},{2,8}}; char fan = 2; //set 1 for unipole hall effect sensor, 2 for bipole hall effect sensor void setup() { PCICR |= (1<<PCIE2); // define interrupt on PCIE2 - PCINT[23:16] PCMSK2 |= (1<<PCINT18) | (1<<PCINT19) | (1<<PCINT20); // Permission to interrupt Serial.begin(9600); sei(); // Global Interrupt Enable } void loop() { if (millis() - previous_millis == 1000) //Update every one second { cli(); // Global Interrupt Disable - when calculeting rpm_1 = ((rpm_counter_1 * 60) / fanspace[fan].fandiv); // Calculating rpm_1 using dividers rpm_2 = ((rpm_counter_2 * 60) / fanspace[fan].fandiv); // Calculating rpm_2 using dividers rpm_3 = ((rpm_counter_3 * 60) / fanspace[fan].fandiv); // Calculating rpm_3 using dividers Serial.print("RPM_1 =\t"); //print "RPM" and tab. Serial.print(rpm_1); // print the rpm value. Serial.print("\t Hz_1=\t"); //print "Hz". Serial.println(rpm_counter_1); // print frequency value Serial.print("RPM_2 =\t"); //print "RPM" and tab. Serial.print(rpm_2); // print the rpm value. Serial.print("\t Hz_2=\t"); //print "Hz". Serial.println(rpm_counter_2); // print frequency value Serial.print("RPM_3 =\t"); //print "RPM" and tab. Serial.print(rpm_3); // print the rpm value. Serial.print("\t Hz_3=\t"); //print "Hz". Serial.println(rpm_counter_3); // print frequency value rpm_counter_1 = 0; //Restart counter rpm_counter_2 = 0; rpm_counter_3 = 0; previous_millis = millis(); sei(); // Global Interrupt Enable } } ISR(PCINT2_vect) { // interrupt vector //-----Checking which PIN reported interrupt----- uint8_t changedbits = PIND ^ interrupt_pin; interrupt_pin = PIND; if(changedbits & (1 << PD2)) { rpm_counter_1++; } if(changedbits & (1 << PD3)) { rpm_counter_2++; } if(changedbits & (1 << PD4)) { rpm_counter_3++; } } Z góry bardzo dziękuje
×
×
  • Utwórz nowe...