Jak mógłbym zająć się programowaniem przełącznika (opartego na przekaźniku półprzewodnikowym lub triaku), który wyzwala moc przejścia przez zero?
Dla tych, którzy nie są zaznajomieni z tematem: Włącz zasilanie 230 V, gdy fala sinusoidalna linii elektroenergetycznej przekroczy zero - wynikiem jest minimalizacja zakłóceń elektromagnetycznych wynikających z szybkiego wzrostu prądu.
W szczególności wolałbym przenieść jak najwięcej do oprogramowania. Obwód wykrywający składający się z małego transformatora, diody i kilku oporników utrzymujących poziom i prądy w ryzach zapewnia „1”, gdy wejściowa moc prądu przemiennego jest w dodatniej połowie, „0” ujemna, przymocowana do wejściowego pinu GPIO. Wyjście składa się z kilku przekaźników półprzewodnikowych i podstawowych elementów niezbędnych do ich działania (podciągania itp.), Podłączonych do wyjściowych styków GPIO.
Problemem jest taktowanie: przy 50 Hz AC uzyskujemy 100 przejść przez zero w ciągu jednej sekundy, jeden półcykl to 10ms. Aby dostać się w rozsądnej odległości od przejścia przez zero w celu utrzymania wspomnianego EMI na niskim poziomie, nie powinniśmy aktywować wyjścia więcej niż 10% po (lub wcześniej) zdarzeniu przejścia przez zero, co oznacza tolerancję + -1ms. Nie oznacza to 1 ms czasu reakcji - możemy zasadnie oczekiwać, że następne przejście przez zero nastąpi dokładnie 10 ms po pierwszym lub czwartym - 40 ms. Chodzi o ziarnistość - jeśli pozwolimy na reakcję 20 ms, musi ona wynosić między 19 a 21 ms, a nie 18 lub 22.
Jak mogę zaimplementować takie wyjście GPIO z wyzwalaczem czasowym albo w ciągu 1 ms, ponieważ wejście wykrywa zbocze, lub w stałej wielokrotności 10 ms od tego czasu - najlepiej z uwzględnieniem pewnego ujemnego odchylenia (powiedzmy, transformator i przekaźnik wprowadzają opóźnienie 1,6 ms; więc chcę, aby wyzwalacz wyłączył się 8,4+ (n * 10) ms od impulsu wejściowego, w ten sposób uprzedzenie przeciwdziała opóźnieniu wprowadzonemu przez obwód.) - wszystko oczywiście „na żądanie użytkownika”, powiedzmy, użytkownik pisze „1 „do pliku / sys / class / ... i przy najbliższej (z grubsza) okazji wyjście jest„ włączone ”. Użytkownik zapisuje „0”, a gdy nadejdzie przecięcie zera, określony przekaźnik wyłącza się.
Uważam, że wymagałoby to napisania lub zhakowania modułu jądra. Czy możesz wskazać mi, co obsługuje piny GPIO Raspberry Pi w jądrze i jakiego rodzaju timerów mógłbym do niego podłączyć (chyba że są już dostępne), aby uzyskać taką funkcjonalność?
Odpowiedzi:
Nie musisz hakować jądra. Wystarczy przenieść proces z kolejki programu planującego.
Od tej chwili nasz proces odbiera
cat /proc/sys/kernel/sched_rt_runtime_us
milisekundy z każdegocat /proc/sys/kernel/sched_rt_period_us
segmentu czasowego milisekund, nieprzerwanego wykonywania bez ryzyka uprzedzenia w tym czasie (w praktyce domyślnie w BerryBoot: 0,95 s na sekundę.) Jeśli potrzebujesz więcej, zadzieraj z tymi wartościami, ale tutaj nie potrzebuję więcej.Używam funkcji timera w milisekundach (to jest potrzebna precyzja) w oparciu o
clock_gettime()
taktowanie moich opóźnień.Wywołanie
timer(1)
resetuje go, a połączenietimer(0)
zwraca czas od zresetowania.Aby
rt
to skompilować, musisz połączyć się z biblioteką - dodaj-lrt
do polecenia gcc.Teraz dla głównej pętli. Używam przełącznika do „żądania użytkownika”, ale możesz użyć sieci, timera lub cokolwiek innego. Wszystko, czego potrzebujesz, to uzyskać wartość logiczną
in
.źródło
TRIAC_PIN
sięin
, że będę musiał ustawićTRIAC_PIN
na 1, odczekać określoną ilość czasu (w proporcji do żądany poziom ściemniacza), a następnie ustaw zTRIAC_PIN
powrotem na 0. Czy to zadziała?if(in==out) continue;
naif(out==0) continue;
, prawda? Właściwie jestem zupełnie nowy w programowaniu dla pi, więc może to nie jest konieczne - domyślam się, że wszystko dzieje się synchronicznie (tj. Nie musimy się martwić wywołaniem głównej pętli, podczas gdy pętle zagnieżdżone wciąż działają)