Kanał - ATNEL tech-forum
Wszystkie działy
Najnowsze wątki



Teraz jest 23 kwi 2024, o 13:53


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 13 ] 
Autor Wiadomość
PostNapisane: 1 sty 2018, o 16:49 
Offline
Nowy

Dołączył(a): 22 paź 2017
Posty: 5
Pomógł: 0

Witam :)
To mój pierwszy wątek na tym forum, mam więc nadzieję, że znajduje się w odpowiednim dziale. Potrzebuję pomocy, ponieważ nie mogę znaleźć błędu w swoim kodzie oraz nie mam pomysłu jak mogłabym go jeszcze zmodyfikować. Byłabym wdzięczna za każdą podpowiedź czy sugestię.

Realizowany przeze mnie program ma za zadanie sterowanie otwarciem kontaktronu w wyznaczonej chwili przebiegu napięcia sieciowego. Projekt realizuję nietypowo, ponieważ program testuję na układzie zmontowanym na płytce stykowej z wykorzystaniem Arduino Leonardo, a układem wyjściowym jest płytka drukowana z ATmegą328 z zewnętrznym kwarcem 16Mhz. Jest to spowodowane tym, że niestety nie potrafię (jeszcze) pisać kodu na czysty AVR. Napisany program w Arduino IDE kompiluję do pliku .hex i wgrywam za pomocą narzędzia MkAvrCalculator i programatora USBasp na płytkę drukowaną. Na płytce tej wykorzystuję również detektor przejścia przez zero zgodny ze schematem z BB. Co do strony związanej z hardwarem jestem pewna, problem więc stanowi kod.

Zamysł programu w skrócie jest taki: po wykryciu impulsu z detektora przejścia przez zero, program "czeka" przez pewien ustawiony przez użytkownika za pomocą przycisków czas (który odpowiada chwili na przebiegu, określonej jako przesunięcie względem zera w stopniach) następnie otwiera kontaktron, znowu "czeka" przez pewien czas otwarcia i ponownie go zamyka. Akcja ta ma się powtarzać co ileś okresów przebiegu, nie ma być jednorazowa.

Poniżej zamieszczam listing kodu z wykorzystaniem delayów (jedynie do zobrazowania kodu, wiem że nie mogę ich używać w programie tak czasowo zależnym ze względu na wprowadzanie opóźnienia)

Składnia: [ Pobierz ] [ Ukryj ]
język cpp
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Chcąc się pozbyć delayów postanowiłam wykorzystaj funkcję millis(), która odpowiadać będzie za czas otwarcia kontaktronu oraz przesunięcie względem zera oraz zmienną licznik do powtarzania akcji co ileś okresów.
Usunęłam z programu napisaną funkcję start(), zadeklarowałam na początku kodu nowe zmienne i zmieniłam kod w głównej pętli loop. Pozostałą część kodu pozostawiłam niezmienioną. Poniżej przedstawiam zedytowany kod programu.

Składnia: [ Pobierz ] [ Ukryj ]
język cpp
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Niestety obserwując przebieg na oscyloskopie okazuje się, że kontaktron załączany jest każdorazowo w innym punkcie przebiegu, niezależnie od nastawionego przesunięcia, a nawet przy ustawieniu sztywnej wartości dla przesunięcia cz=0. Nie rozumiem więc gdzie i na jakim etapie wprowadzane jest opóźnienie. Popełniam błąd, z którego istnienia nie zdaję sobie prawdopodobnie sprawy.

Pomyślałam, że może otwarcie kontaktronu powinno być wyzwalane zboczem impulsu przejścia przez zero i z użyciem przerwania, podobnie jak to było opisane w BB przy projekcie ze ściemniaczem. Albo być może mam problem z synchronizacją. Być może to biblioteki Arduino wprowadzają opóźnienie. I w tym wypadku może lepszym rozwiązaniem byłoby napisanie programu dla "czystej" ATmegi. Niestety nie potrafię pisać kodu operując na rejestrach.
Kończą mi się pomysły, więc proszę o jakąkolwiek pomoc.

Pozdrawiam :)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 1 sty 2018, o 19:14 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 23 paź 2014
Posty: 1021
Lokalizacja: Trójmiasto
Pomógł: 188

Jest pewna nieścisłość: albo kolega nazywa coś kontaktronem co nim nie jest albo ja czegoś nie rozumiem.
Z definicji kontaktron jest hermetycznie zamkniętą bańką szklaną w której umieszczone są styki (2 lub 3) których załączenie lub przełączenie następuje poprzez przyłożenie stałego pola magnetycznego (najczęściej magnesu trwałego).
https://pl.wikipedia.org/wiki/Kontaktron
I tu nie za bardzo wiem jak się odnieść do sformułowania
Roseven napisał(a):
Realizowany przeze mnie program ma za zadanie sterowanie otwarciem kontaktronu
- czyli co? Program generuje pole magnetyczne przy pomocy jakiejś cewki?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 1 sty 2018, o 19:36 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 26 mar 2014
Posty: 356
Lokalizacja: Pruszków
Pomógł: 15

Witam

Były kiedyś przekaźniki kontaktronowe czyli kontaktron z cewką.
Układ prawdopodobnie nie działa prawidłowo ponieważ sam kontaktron jest zbyt powolny.
Dla testu proponuje napisać program podobnie jak do migania diodą led i sterować kontaktronem impulsowo będzie wtedy można sprawdzić jak szybko jest on w stanie się włączać i załączać.
Aby przyspieszyć załączenie można zwiększać napięcie sterujące podobnie jak we wtryskiwaczach samochodowych.
Niestety nie ma możliwości przyspieszyć rozłączenia kontaktronu jest on ograniczony przez bezwładność mechaniczną.
Wydaje mi się, że kontaktron nie da rady tak szybko się rozłączyć.

Opisz co potrzebujesz uzyskać a na pewno ktoś podpowie jak do tego podejść.

Pozdrawiam Paweł.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 1 sty 2018, o 20:18 
Offline
Nowy

Dołączył(a): 22 paź 2017
Posty: 5
Pomógł: 0

Dziękuję bardzo za odpowiedzi. Już sprostowuję, ponieważ pojawiło się w moim wątku dużo niedopowiedzeń oraz ujawniło się przyzwyczajenie do potocznego słownictwa.
Jak najbardziej chodzi o przekaźnik kontaktronowy z wbudowaną cewką. Sterowanie polega na wystawieniu na jednym z wyjść odpowiedniego stanu, który podawany jest na bazę tranzystora bipolarnego BC547. W obwodzie kolektor-emiter danego tranzystora znajduje się cewka sterująca kontaktronem.
Jak najbardziej zdaję sobie sprawę z ograniczeń mechanicznych związanych z bezwładnością, jednak czas otwarcia i zamknięcia zestyku powinien być stały, a niestety otrzymywana wartość opóźnienia jest cały czas różna.
Testowałam również układ z podawaniem sygnału z tranzystora na obwód bez kontaktronu ale z diodą. I w tym wypadku widać było na oscyloskopie różne momenty załączania diody.
Chodzi właśnie o to, że opóźnienie nigdy nie miało stałej wartości, ani w przybliżeniu stałej. A rozrzut w całym przebiegu, mimo nastawionej wartości parametru cz=0 był bardzo duży (na samej diodzie).



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 1 sty 2018, o 23:05 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 11 mar 2014
Posty: 1475
Pomógł: 167

Nie analizując czy w programie masz jakieś błędy, to nie uzyskasz na nim dużej dokładności (powtarzalności), bo jest to sekwencyjne sprawdzanie kolejnych warunków. Pętla loop() jest teoretycznie wykonywana w kółko, ale czy nie jest coś dodawane oprócz Twego kodu?

--
Pozdrawiam,
Robert

------------------------ [ Dodano po: 1 minucie ]

Nie programuję w arduino, lecz sam program nie wygląda na poprawny. Czy przypadkiem nie wywołujesz funkcji akcja.process() i tworzysz za każdym przebiegiem pętli ponownie zmiennej czas_start i nie inicjalizujesz jej nowym czasem?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 2 sty 2018, o 12:33 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 15 lut 2016
Posty: 248
Lokalizacja: Norwegia
Pomógł: 16

Czytam kolego ten Twój opis i ni jak nie mogę zrozumieć co w rzeczywistości chcesz osiągnąć?
Pierwsza rzecz to kontaktron, wybacz ale to nie będzie działać. Jeżeli wykrywasz punkt zerowy sinusa o częstotliwości 50Hz, to Twój kontaktorn zamknie się po kilkunastu cyklach od wykrycia stanu zerowego. Nie wiem co tam chcesz dalej robić bo..... nie mówisz nic na ten temat :) kolejna rzecz to schemat detektora zera !! możesz go pokazać? Piszesz że przy pominięciu kontaktrona też masz zmienne czasy reakcji, to wyraźny sygnał że masz coś skopane także i w detekcji zera... Reasumując, jeżeli chcesz uzyskać pomoc, to przedstaw schemat układu i opisz jaki ma być końcowy efekt działania ten konstrukcji. Sprawdź też proszę jakie czasy otwarcia i zamknięcia oferuje Tobie zastosowany przekaźnik kontaktronowy, bo obawiam się że to niestety poroniony pomysł.

_________________
SP2LUB - LA1BUA



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 2 sty 2018, o 14:37 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 17 mar 2014
Posty: 330
Lokalizacja: Rybnik
Pomógł: 54

Będzie trochę nie na temat, ale taka mała uwaga to kolegów powyżej:

Roseven napisał(a):
Byłabym wdzięczna

Roseven napisał(a):
Pomyślałam, że może otwarcie [...]


Ja wiem, że to zapewne z przyzwyczajenie, gdyż większa ilość użytkowników to mężczyźni, ale żeby nam się zaraz koleżanka nie obraziła, że piszecie do niej "kolego" ;)

_________________
Amatorska stacje meteorologiczna



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 2 sty 2018, o 16:45 
Offline
Nowy

Dołączył(a): 22 paź 2017
Posty: 5
Pomógł: 0

rskup przemyślę twoją podpowiedź :)

Tworzę model, ponieważ chciałabym obserwować zależność wartości przepięć łączeniowych występujących podczas otwierania styków wyłącznika próżniowego od wartości chwilowej napięcia sieciowego w momencie otwarcia. Dlatego chciałabym, żeby była możliwość sterowania, w którym dokładnie miejscu ma wystąpić otwarcie, przykładowo w ''zerze" sieci lub przy wartości maksymalnej.

Co do układu detekcji zera, działa on właściwie, ponieważ uzyskuję na oscyloskopie "szpilkę" dokładnie w zerze. Schemat poniżej:

Obrazek

Niestety nie mam obecnie dostępu do oscyloskopu więc nie jestem w stanie zmierzyć czasu załączania kontaktronu, ale jest to model Magnecraft W171DIP-2 i według noty katalogowej czas ten powinien mieć wartość ok. 0.45ms. Schemat ze sterowaniem zamieszczam poniżej:

Obrazek

Myślałam, że jeżeli występujące opóźnienie związane właśnie z bezwładnością mechaniczną styków, wykonaniem programu, transmisją danych itd. byłoby wartością stałą to mogłabym ją uwzględnić w kodzie.

Dziękuję za odpowiedzi.
Pozdrawiam.

PS: Absolutnie się nie obrażam, przyzwyczajona jestem do przebywania w towarzystwie samych mężczyzn :D



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 2 sty 2018, o 17:09 
Offline
Użytkownik

Dołączył(a): 22 sty 2014
Posty: 1806
Zbananowany użytkownik

Pomógł: 168

Taki układ można wykonać ale po pierwsze trzeba mieć bardzo dokładne i deterministyczny czasowo łącznik. Jeżeli chcesz badać wyłącznik próżniowy to musisz znać dokładnie czas jaki mija od podania napięcia na wyzwalacz do rozejscia się styków. Najprościej będzie przetestować to na żywym organizmie. Zamykasz wyłącznik, styki główne są zwarte. Bierzesz rezystor 100 Om, jedna nóżka rezystora do 5V druga na pierwszy zacisk wyłącznika, drugi zacisk dajesz do masy. Podajesz sygnał sterujący na wyzwalacz i patrzysz kiedy będzie na rezystorze stan wysoki. Mierząc czas od zbocza wyzwajacego do zbocza stanu wysokiego masz czas własny wyłącznika. Teraz znając moment przejścia przez zero, i wiedząc ile otwiera się wyłącznik musisz obliczyć w jakim momencie za dwa, 3 okresy sinusoidy otworzyć wyłącznik. Częstotliwość w sieci nie zmienia się skokkowo więc te 2 3 okresy będą ok. Powiedzmy że wyłącznik otwiera się 25ms. Okres sinusoidy trwa 20 ms. Chcesz otworzyć go np w szczycie sinusoidy więc wykrywasz przejście przez zero i wyliczasz że żeby wyłącznik otworzył się gdy sinus będzie w szczycie to musisz go załączyć 25ms przed tym szczytem. Kiedy go wyzwolić? Przy najbliższym przejściu przez zero, wtedy do kolejnego przejścia przez 0 minie 20ms i kolejne 5ms to będzie szczyt Sinusa. Program napisz w C i na przerwaniach żeby był deterministyczny czasowo. Nie baw się Arduino bo to strata czasu. C jest prosty jak budowa cepa.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 sty 2018, o 01:00 
Offline
Nowy

Dołączył(a): 22 paź 2017
Posty: 5
Pomógł: 0

Bardzo dziękuję za odpowiedź. Zastosuję się do porad. Trzeba się będzie w końcu nauczyć czystego C :D A czy mógłbyś mniej więcej naszkicować zarys kodu? Bo póki co nie mam zielonego pojęcia jak mógłby wyglądać.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 sty 2018, o 10:37 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 04 paź 2011
Posty: 8583
Pomógł: 337

Zanim przejdziesz do czystego C ... zainteresuj się w Arduino biblioteką timers.h
załatwia uporczywy problem z delay() oraz niepewnośc milis().
co do detekcji zera:

Podłacz się pod Int0 lub Int1 i wywołuj przerwanie .

_________________
[b]San Escobar! Patria mia! Tu eres como la salud.[/b]



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 sty 2018, o 13:14 
Offline
Użytkownik

Dołączył(a): 22 sty 2014
Posty: 1806
Zbananowany użytkownik

Pomógł: 168

Zanim usiądziesz do całościowego kodu w C, poczytaj i opanuj te rzeczy:

- timery i liczniki, timery programowe,
- obsługa portów GPIO
- obsługa przerwań zewnętrznych pochodzących od zmian stanów logicznych na wejściach mikrokontrolera.

Pracujesz na platformie Arduino, która, moim zdaniem sprzętowo jest dosyć fajnie pomyślana. Masz na plytce mikrokontroler (w leonardo o ile pamiętam siedzi Atmega32u4 ze sprzętowym USB), zasilanie, wyprowadzone piny. Jest to dosyć fajna baza do eksperymentów.

Zamysł programu jest taki:

- inicjalizujesz jeden z pinów jako pin od przerwania od zbocza narastającego, przejście przez zero fizycznie nastąpi dopiero po jakimś czasie od od wystąpienia tego przerwania bo to wynika ze specyfiki układu detekcji zera. Znając jednak długość tego impulsu, i dzieląc go przez dwa, otrzymasz czas fizycznego przejścia przez 0 i ten czas też trzeba uzwględnić.
- przejście przez zero generuje przerwanie. przerwanie to wykonywane jest co 10ms(około, bo f sieci się zmienia w niewielkich granicach).
- z tym przerwaniem synchronizujesz inny licznik który będzie Ci generował impuls na wyzwolenie wyłącznika po upływie jakiegoś czasu. Licznik ten możesz skofigurować w trybie PWM, z okresem jakim bedziesz uważać, wykorzystując do tego timer 16 bitowy.
- jakimś potencjometrem czy enkoderem ustalasz zadaną chwilę sinusoidy w ktorej ma otworzyć się wyłącznik. Sumujesz czas własny wyłącznika oraz czas od zbocza narastającego.. Powiedzmy że impuls w zerze trwa 500us. Dzieląc to na dwa, otrzymasz 250us, i jest to czas w którym następuje rzeczywiste przejście przez 0. Wyłącznik otwiera się powiedzmy po 10ms od wyzwolnia, a moment w którym chcesz go otworzyc to szczyt sinusoidy czyli 5ms (od rzeczywsitego przejścia przez 0. Zsumujmy to. 250us + 10ms, daje nam 10,25ms. hmmm, teraz trzeba pomyśleć jak to ugryźć. Ja bym to zrobił tak, że wiedząc jaki jest czas reakcji, licząc czas od kolejnego przejścia przez 0. wyzwoliłbym wyłącznik po takim czasie od przejścia przez 0 by otworzył się za te 10.250ms. powiedzmy że ma to być te 5ms, czyli szczyt. Odejmijmy od tego czas własny, daje nam to -5.25ms. tyle czasu przed kolejnym przejściem przez 0 należy dać impuls. licząc od przejścia przez 0, bedzie to 10-5.25 = 4.75ms. Do tego dodajesz czas 10ms bo licznik zerujesz w przerwaniu od jescze wcześniejszego przejścia przez 0.

Teraz tak:
1. Załóżmy że do całej operacji potrzebujesz 3 przejścia przez 0, nazwijmy je kolejno A,B i C.

2. Ustalasz moment wyzwolenia wyłącznika od 0 sieci jakimś potencjometrem/enkoderem/przyciskiem czymkolwiek. Znasz tą wartość, bo masz ją w zmiennej.

3. W pierwszym przerwaniu od przejścia przez 0 (A) zerujesz licznik, wyłaczasz go, obliczasz czas po jakim należy otworzyć wyłącznik czyli: t = 10 + (zadany - t_wylacznika). Dodajesz to tego jeszcze 10ms. otrzymujesz 14.75ms. Przeliczasz to na ilość zliczeń licznika. powiedzmy że zlicza on impulsy co 10us. Otrzymujesz 14.75ms/10us = 1475. Odejmujesz od tego 1 bo licznik liczy od 0 i wychodzi 1474. Taką wartość wpisujesz do rejestru porównania OCR. włączasz licznik i zliczasz. Licznik jest w trybie PWM z okresem większym niż kilka przejśc przez 0, powiedzmy 60ms. teraz, kiedy licznik już liczy, ustawiasz na 0 jakąś flage która nie powtórzy opisanej procedury przy kolejnym przejsciu przez 0 i wystapieniu przerwania. Tę flagę bedziesz ustawiac tylko wtedy gdy bedziesz badać wyłącznik po raz kolejny. Kolejne przerwanie B, może nie robić nic, licznik już w tle zliczył 10ms. zostało jeszcze 4.75 sekundy. Licznik liczy dalej. Załóżmy że zliczył i wystawił stan wysoki. Wyłącznik zaczyna działać, mechanizm poszedł w ruch. mija czas własny wyłącznika, występuje przerwanie C, licznik zliczył już 20ms, od tej pory za 5ms otworzy się wyłącznik bo był wyzwolony 5.25ms temu. Po 5ms wyłacznik sie otwiera. Cały program jest banalny.

Mozesz też spróbować zrobić to w Arduino, ale to już Twój wybór. Ja nie używam go na AVR. Wolę C.


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 5 sty 2018, o 18:28 
Offline
Nowy

Dołączył(a): 22 paź 2017
Posty: 5
Pomógł: 0

Dziękuję serdecznie wszystkim za pomoc, szczególnie Tobie Nefarious19 za bardzo dokładne wyjaśnienie. Zabieram się do pracy :)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
Wyświetl posty nie starsze niż:  Sortuj wg  
Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 13 ] 

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 0 gości


Nie możesz rozpoczynać nowych wątków
Nie możesz odpowiadać w wątkach
Nie możesz edytować swoich postów
Nie możesz usuwać swoich postów
Nie możesz dodawać załączników

Szukaj:
Skocz do:  
cron
Sitemap
Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
phpBB SEO