Skocz do zawartości

Czujnik prędkości wiatru


SOYER

Pomocna odpowiedź

1 godzinę temu, ethanak napisał:
if (!half_costam) rpm = 0;
else rpm = ileśtam/half_cośtam;

Albo coś w tym stylu...

Czyż nie zastosowałem podobnej logiki w pierwszych linijkach mojej funkcji temporary rpm, które to linijki wkleiłem na pierwszej stronie tego tematu?

 

IMG_1451.PNG

Link do komentarza
Share on other sites

(edytowany)
Dnia 27.10.2024 o 09:16, Sylba napisał:

To wszystko to kinematyka i przeliczanie jednostek.
Zauważcie, że średnica wirnika jest podana w calach, prędkość wiatru w milach na godzinę.  1 mph = 5280 feet/h (stóp na godzinę), a jedna stopa to 12 cali.

Dlatego diameter/12 => przeliczenie cali na stopy, a 1/5280 to przeliczenie  mili na stopy.
3,14 to ludolfina czyli pi. 60 to przelicznik prędkości obrotowej 1/minutę na prędkość obrotowa w obrotach na godzinę.

Ogólnie wzór wynika z kinematyki prędkości liniowej obracającej się bryły V=w*R = pi*n *R/30

1736739464_Predkoobrotowa.thumb.png.e8171ceb6fcfcf2b965eff16a9e29869.png

gdzie:

w (omega) to prędkość kątowa = pi * n/30
n  to prędkość obrotowa 1/minutę) - jeden obrót to 2*pi
R to promień wirnika w metrach (jeśli inne jednostki np cale,  mm lub cm to trzeba je przeliczyć na mile lub metry jak kto chce)

 

Obliczenia opisane wzorem powyżej są słuszne przy założeniu, że prędkość liniowa elementu wirnika jest równa prędkości wiatru. Ale tak nie jest. Zauważ, że nie przez cały obrót wiatr wieje prosto na "miseczkę". Wiatr wieje także na pozostałe miseczki. Kształt miseczek sprawia, że opór jaki stawiają wiatrowi jest mniejszy gdy wypukłością są zwrócone do wiatru niż gdy wiatr wieje od strony wklęsłej. Można więc sądzić, że założenie iż prędkość liniowa miseczki jest równa prędkości wiatru jest błędne. Jest mniejsza stąd konieczność skorygowania - np. współczynnik 3,5. Tak naprawdę trzeba ten współczynnik wyznaczyć doświadczalnie mierząc prędkość obrotową przy znanej prędkości wiatru.

Na koniec, tego rodzaju turbiny są mało dokładne, a ich prędkość obrotowa oscyluje (to wpływ konstrukcji) nawet przy tej samej prędkości wiatru. Dlatego w przyrządach do pomiaru prędkości czy przepływu są stosowane turbiny osiowe (śmigłowe).

Zaletą takich wiatromierzy jest to, że działają niezależnie od kierunku wiatru podczas gdy turbinowe pokazują poprawnie gdy tacza turbiny jest ustawiona prostopadle do kierunku wiatru.

Promień r od środka urządzenia do środka miseczek wynosi 7.5cm.

Czy mój wzór jest prawidlowy?

kmh = 6.28 * 0.075 * averageRpm * 3.6;

?

 

Edytowano przez SOYER
Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

(edytowany)
19 godzin temu, SOYER napisał:

Czyż nie zastosowałem podobnej logiki w pierwszych linijkach mojej funkcji temporary rpm, które to linijki wkleiłem na pierwszej stronie tego tematu?

 

IMG_1451.PNG

@ethanak niestety mój i Twój przykład zakłada, że wiatraczek się obraca. Bardzo wolno ale się obraca. Jeśli wiatraczek stoi, a jego ostatni czas półobrotu wynosił poniżej 2000ms, to ten szkic nie wyzeruje nam zmiennej rpm. 

Muszę wymyslić jak to zrobić. Czy można jakoś sprawdzić czy w ciągu ostatnich 2s mieliśmy przerwanie z pinu. Bo jeśli nie mieliśmy, to znaczy, że wiatrak stoi...

Edytowano przez SOYER
Link do komentarza
Share on other sites

(edytowany)
8 minut temu, SOYER napisał:

@ethanak niestety mój i Twój przykład zakłada, że wiatraczek się obraca. Bardzo wolno ale się obraca. Jeśli wiatraczek stoi, a jego ostatni czas półobrotu wynosił poniżej 2000ms, to ten szkic nie wyzeruje nam zmiennej rpm. 

Muszę wymyslić jak to zrobić. Czy można jakoś sprawdzić czy w ciągu ostatnich 2s mieliśmy przerwanie z pinu. Bo jeśli nie mieliśmy, to znaczy, że wiatrak stoi...

Tak to zrobiłem, do funkcji przerwania dodałem zmienną last_call:

void ICACHE_RAM_ATTR rpm_fan() { //funkcja rpm_fan
  if (millis() - last_event < 5) {   //debouncing
    return;
  }
  half_revolutions_time = (millis() - last_event);
  last_event = millis();
  last_call = millis();
}

a następnie w loop sprawdzam tą zmienną:

void temporaryRPM(){
    noInterrupts(); 
    if((last_call + 2000) < millis()){    
     rpm=0;
    }
    else{ 
      rpm = (30000 / half_revolutions_time) ;
    } 
  ...........

chyba działa, poobserwuję jeszcze....

Edytowano przez SOYER
Link do komentarza
Share on other sites

6 minut temu, ethanak napisał:

Sprawdź np. last_event, jeśli był zbyt dawno to wiatraczej stoi

Faktycznie niepotrzebna ta dodatkowa zmienna bo przecież mam już taką co przechowuje dokładnie to co chcę wiedzieć...

Link do komentarza
Share on other sites

Aktualnie mój szkic do prób z czujnikiem wiatru wygląda tak:

#include <Timers.h>

Timer sekund6;
#define windPin 12 //D6
volatile int half_revolutions_time = 2; //Utworzenie zmiennej połowa pełnego obrotu (half revolutions)
volatile int rpm = 0;
unsigned long static  last_event = 0;
float tempRpm = 0;
float averageRpm = 0;
int sample = 0;
float kmh;

 void ICACHE_RAM_ATTR rpm_fan() { //funkcja rpm_fan
  if (millis() - last_event < 5) {   //debouncing
    return;
  }
  half_revolutions_time = (millis() - last_event);
  last_event = millis();
}
void temporaryRPM(){
    noInterrupts(); 
    if((last_event + 2000) < millis()){    
     rpm=0;
    }
    else{ 
      rpm = (30000 / half_revolutions_time) ;
    } 
    if(sekund6.available()){
      tempRpm = tempRpm + rpm;
      sample++;
      sekund6.restart();
     }
    if(sample==10){
      averageRpm = tempRpm / 10;
      kmh = 6.28 * 0.075 * averageRpm * 3.6;
      //wiatr->setValue(kmh);
      tempRpm = 0;
      sample=0;
      sekund6.restart();
    }
   interrupts() ; //Przywróć przerwania
}
void setup() {
  Serial.begin(9600);
  sekund6.begin(6000);
  pinMode(windPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(windPin), rpm_fan, FALLING);
 last_event = millis();
}

void loop() {
  temporaryRPM();
  Serial.print("czas p/obrotu:  ");
  Serial.println(half_revolutions_time);
  Serial.print("rpm:  ");
  Serial.println(rpm);
  Serial.print("km/h:  ");
  Serial.println(kmh);
    Serial.print("sample:  ");
  Serial.println(sample);  
  Serial.print("temporaryRPM:  ");
  Serial.println(tempRpm);

}

Co 6s robię pomiar, nastepnie zbieram 10 pomiarów, wyciągam średnią i wypisuję tą średnią prędkość z ostatniej minuty....

Link do komentarza
Share on other sites

@SOYER robiłem kiedyś prędkościomierz do motocykla, impulsy z hallotronu i magnesy na szprychach. Miałem dwie metody pomiaru: dla wolnych mierzyłem czas między impulsami, dla szybkich liczyłem impulsy w jednostce czasu. Może coś w tę stronę?

Link do komentarza
Share on other sites

Aktualnie moj szkic wyświetla prędkość chwilową i średnią z ostatniej minuty.

#include <Timers.h>

Timer sekund6;
#define windPin 12 //D6
volatile int half_revolutions_time = 2; //Utworzenie zmiennej połowa pełnego obrotu (half revolutions)
volatile int rpm = 0;
unsigned long static  last_event = 0;
float tempRpm = 0;
float averageRpm = 0;
int sample = 0;
float moment_kmh;
float average_kmh;

 void ICACHE_RAM_ATTR rpm_fan() { //funkcja rpm_fan
  if (millis() - last_event < 5) {   //debouncing
    return;
  }
  half_revolutions_time = (millis() - last_event);
  last_event = millis();
}
void temporaryRPM(){
    noInterrupts(); 
    if((last_event + 2000) < millis()){    
     rpm=0;
     moment_kmh = 0;
    }
    else{ 
      rpm = (30000 / half_revolutions_time) ;
      moment_kmh = 6.28 * 0.075 * rpm * 3.6 / 60;
    } 
    if(sekund6.available()){
      tempRpm = tempRpm + rpm;
      sample++;
      sekund6.restart();
     }
    if(sample==10){
      averageRpm = tempRpm / 10;
      average_kmh = 6.28 * 0.075 * averageRpm * 3.6 / 60; 
      //wiatr->setValue(kmh);
      tempRpm = 0;
      sample=0;
      sekund6.restart();
    }
   interrupts() ; //Przywróć przerwania
}
void setup() {
  Serial.begin(9600);
  sekund6.begin(6000);
  pinMode(windPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(windPin), rpm_fan, FALLING);
 last_event = millis();
}

void loop() {
  temporaryRPM();
  Serial.print("czas p/obrotu:  ");
  Serial.println(half_revolutions_time);
  Serial.print("rpm:  ");
  Serial.println(rpm);
  Serial.print("km/h chwilowa:  ");
  Serial.println(moment_kmh);
    Serial.print("km/h srednia:  ");
  Serial.println(average_kmh);


}

Nadal nie jestem pewny wzoru po poprawkach:

moment_kmh = 6.28 * 0.075 * rpm * 3.6 / 60;
average_kmh = 6.28 * 0.075 * averageRpm * 3.6 / 60;

 

Link do komentarza
Share on other sites

Z wzorami to nie pomogę, ja zawsze stosowałem coś w stylu

const float factor = ...;
  ...
predkosc = rpm * factor;

A co siedzi w factor to sie oddzielnie zastanawiałem.

W Twoim przypadku predkość nie jest wprost proporcjonalna do rpm, trzeba jakiejś funkcji która w miarę inteligentnie przeliczy rpm na m/s czy km/h.

Link do komentarza
Share on other sites

3 godziny temu, SOYER napisał:

Czy mój wzór jest prawidlowy?

kmh = 6.28 * 0.075 * averageRpm * 3.6;

Nie do końca tak. Według mnie to V=3,6/1000*pi*R*f  [km/h

gdzie:

pi = 3,14 (około)
R promień w mm
f częstotliwość impulsów 1/s (przyjąłem 2 impulsy na obrót)

lub jeśli nie częstotliwość tylko obroty n  1/minutę

V=1,2/10000*pi*R*n  [km/h]

 

453662818_Prdkowiatromierz_2.thumb.png.3ccf25a7392e300d113c7b3535f5f968.png

 

Link do komentarza
Share on other sites

11 minut temu, Sylba napisał:

Nie do końca tak. Według mnie to V=3,6/1000*pi*R*f  [km/h

Uhm... v = 2π rf = 6.28 [1] * 0.075 [m] * (averageRPM [1/min] / 60 [s/min]) * 3.6 [(km/h)/(m/s)]


Tak jakoś by się zgadzało, ale strasznie dziwnie to zapisałeś... czemu dzielisz 3.6 przez 1000 zamiast R przez 1000, u mojej nauczycielki programowania już by wleciały ujemne punkty za brak spójności logicznej 😄

Jedyne czego kolega zapomniał to zamienić rev/min na rev/s 😉 

Edytowano przez H1M4W4R1
Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.