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

KURS HOME ASSISTANT

Chcesz zautomatyzować swój dom bez skomplikowanego kodowania?
Zastanawiasz się nad wyborem sprzętu, oprogramowania i aplikacji?
Od czego zacząć przygodę z HA? Co będzie najlepsze na start?

Nasz kurs Home Assistant nauczy Cię krok po kroku, jak łatwo zautomatyzować swój dom i oszczędzić na rachunkach za prąd i ogrzewanie. Bez chmur, bez zbędnych abonamentów. Twoja przygoda z Home Assistant zaczyna się tutaj!

↓↓↓

    Szanujemy Twoją prywatność. Możesz wypisać się w dowolnym momencie.




    Teraz jest 11 lip 2025, o 10:18


    Strefa czasowa: UTC + 1





    Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 13 ] 
    Autor Wiadomość
    PostNapisane: 25 lis 2018, o 19:16 
    Offline
    Użytkownik
    Avatar użytkownika

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

    Witam wszystkich forumowiczów.

    Robię sobie samemu wzmacniacz audio DIY w skład którego postanowiłem wmontować procesor audio oparty na powszechnie stosowanym wa radiach samochodowych układzie TDA7418 który posiada przełącznik wejść, regulację tonów wysokich, średnich, basów, loudness i 4 wyjścia plus wyjście dla subwoofer-a.

    Podglądając biblioteki arduino i inne w internecie napisałem swoja biblioteke do obsługi tego scalaka.
    Samo wysyłanie i zmiana parametrów nie jest jakoś szczególnie skomplikowana ale pisząc sam program obsługi utknąłem na jednej rzeczy.

    Stanąłem na regulacji balansu oraz fadera czyli regulacji każdego z czterech kanałów wyjściowych.
    O ile nie jest problemem zmienić głośność w którymkolwiek kanale osobno,
    to już sterowanie i uzależnienie wszystkich kanałów od ustawienia balansu i fadera już nie jest takie proste.

    Chciałby zobaczyć jakie wy macie sugestie na temat takiej regulacji.
    Nie chodzi mi o jakiś konkretny kod a jedynie o sposób realizacji czegoś takiego.

    Być może ktoś z was już się z tym spotkał i ma jakieś doświadczenia.

    Sama regulacja ma polegać na zmianie wartości odpowiednio czterech zmiennych przypisanych dla każdego z kanałów za pomocą dwóch zmiennych balans i fader o zakresie int przyjmujących wartości od -x przez 0 do x.

    Czyli każdy kanał może być przyciszony o wartość jego zmiennej 0 do np. 50 gdzie 0 to maksymalna głośność a 50 to wyciszenie.
    O ile nie ma najmniejszego problemu aby regulować na podstawie balansu czy faderu odpowiednie dwa kanały,
    to już uzależnienie jednej regulacji od drugiej już nie jest dla mnie takie proste.
    Czyli jeśli w faderze ustawimy pewne poziomy to w w balansie można tylko przyciszyć a nie można zgłośnić.

    Czekam na wasze sugestie i pozdrawiam Paweł.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 2 gru 2018, o 22:24 
    Offline
    Użytkownik
    Avatar użytkownika

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

    Witam ponownie

    Udało mi się napisać przeliczanie dzięki pomocy mojego kolegi który na co dzień programuje.
    Samo przeliczanie okazało się bardzo proste, zupełnie jak przypuszczałem.
    Jak skończę pisać program nie omieszkam się podzielić tu na naszym forum.

    Mam jeszcze jeden problem, ponieważ się uczę a do tej pory nie za bardzo używałem wskaźników.
    Jedynie kopiowałem jakieś fragmenty kodów z Mirkowych programów i poradników i wszystko działało.
    Choś nie zabardzo wiedziałem w jaki sposób.

    Pisząc swój program praktycznie zawsze ma się inny pomysł na to jak go napisać i okazuje się, że to co pokazał Mirek w poradniku owszem działa ale ja bym chciał zrobić to w troszkę innaczej i tu tworzą się schody.
    Na początku chyba każdy kto uczy się programować nie widzi potrzeby używania wskaźników.
    Ja generalnie zrozumiałem zasadę ich działania jednak do pełnych możliwości ich używania w swoich programach jeszcze mi dużo brakuje.

    Do czego zmierzam:
    Mamy dwie zmienne a i b ale innych typów!
    int zmienna_b

    Drugą

    uint8_t zmienna_a

    i teraz chciałbym napisać swoją uniwersalną procedurę do wykonywania obliczeń na tych zmiennych.
    Jednak sama procedura ma być bardzo uniwersalna i chciałbym aby robiła operacje w obie strony.
    Czyli mogła odczytywać i przypisywać wartości jednocześnie do obu zmiennych.

    Żaden problem prawda?!
    Normalnie każda procedura może zwrócić tylko jeden argument a ja bym chciał aby zwracała 2 i tu właśnie przydadzą się wskaźniki.

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



    Później w samym programie piszę;
    moje_obliczenia( (uint8_t *)&zmienna_a, (int *)&zmienna_b, 0);

    I taki kod działa prawidłowo kompiluje się bez problemu

    Jednak ja raz bym chciał podstawiać zmienną a typu uint8_t jako Var_in a następnym razem jako Var_out

    Czyli tak a wtedy kompilator od razu krzyczy.
    Można chyba zadeklarować tą procedurę ze wskaźnikami void


    Czyli tak:


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


    ale kiedy w programie próbuję użyć tak zadeklarowanej procedury to kompilator i tak się burzy.

    Czy nie można jakby zadeklarować samej procedury z nieznanym typem wskaźnika czyli void a dopiero podczas jej użycia rzutować jego typu?????

    Kurczę nie wiem czy ktokolwiek zrozumie moje pytanie.
    No chyba, że całkowicie nie rozumiem jak działa void?

    Pozdrawiam Paweł.

    ------------------------ [ Dodano po: 13 minutach ]

    Czy przypadkiem prawidłowo mozna zadeklarować

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



    hmm????



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 2 gru 2018, o 23:18 
    Offline
    Moderator
    Avatar użytkownika

    Dołączył(a): 03 paź 2011
    Posty: 27415
    Lokalizacja: Szczecin
    Pomógł: 1043

    P3ndz3l3k napisał(a):
    ale kiedy w programie próbuję użyć tak zadeklarowanej procedury to kompilator i tak się burzy.

    ale jak tak piszesz, to dokończ zawsze i napisz co to znaczy, że się burzy - czyli pokaż komunikat bo trudno się domyśleć .... a przecież tak może wyglądać nagłówek funkcji - w czym problem?

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

    _________________
    zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 3 gru 2018, o 18:33 
    Offline
    Użytkownik
    Avatar użytkownika

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

    Dopiero z pracy wróciłem.

    No więc doszedłem do tego, że prawidłowo powinno chyba być być tak:

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


    Ale nie wiem teraz jak prawidłowo użyć tych wskaźników wewnątrz procedury:

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


    Już mi się zwoje mózgowe całkowicie poplątały.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 3 gru 2018, o 20:18 
    Offline
    Użytkownik

    Dołączył(a): 07 cze 2016
    Posty: 563
    Pomógł: 143

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


    Postaram się wytłumaczyć jak najprościej. Wskaźnik void to wskaźnik do zmiennej o nieokreślonym typie, więc również o nieokreślonym rozmiarze (w bajtach). Kiedy przypisujesz zmiennej wartość 10 - *input = 10; - skąd kompilator ma wiedzieć do jakiego typu zmiennej wpisuje/czyta dane, czyli ile bajtów ma wpisać/wczytać?
    Dereferencję powinieneś zrobić w ten sposób:
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

    Jeśli chcesz natomiast, aby rzutować wskaźniki raz na jeden typ, a innym razem na drugi typ, musisz dodać argument, dzięki któremu funkcja będzie wiedziała jakiego rzutowania ma dokonać:
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    By było czytelniej można użyć unii:
    Składnia: [ Pobierz ] [ Ukryj ] [ Zaznacz wszystko ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    Autor postu otrzymał pochwałę


    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 3 gru 2018, o 21:16 
    Offline
    Użytkownik
    Avatar użytkownika

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

    Witam kolegę

    andrews napisał(a):
    Wskaźnik void to wskaźnik do zmiennej o nieokreślonym typie, więc również o nieokreślonym rozmiarze (w bajtach).


    No widzisz bardzo mocno mi tym rozjasniłeś byłem święcie przekonany, że to void nie będzie wskaźnikiem na nieokreśloną zmienną ale, że własnie ten mój wskaźnik bedzie nieokreślonego typu i wtedy kiedy np. używając w pętli mojej procedury, będę mógł zrobić własnie rzutowanie dopasowane do mojej zmiennej czyli tak:

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


    i wtedy kompilator by wiedział jaki typ zmiennej ale to nie działa niestety.

    Oczywiście tak jak mi napisałeś sposób z wewnętrznym rzutowaniem działa jednak w tym momencie procedura traci idee uniwersalności.

    Drugiego sposobu z podmianą typów jeszcze nie sprawdzałem ale napewno działa jednak dzięki temu można obsłużyć tylko 2 typy i podczas użycia tej procedury trzeba by było zawsze wybierać ten kierunek. Jak by dorzucić switcha to mozna by wszystkie typy uzywać ale wtedy to ta procedura by nieźle się rozrosła.

    Czyli generalnie mój pomysł z jakby automatycznym dopasowaniem typów jest nie wykonalny.

    Szkoda trochę bo przecież ta zmienna jest gdzieś w programie zdeklarowana więc kompilator powinien sobie znaleźć jej typ.
    Mogło by być tak dafaultowo, że jesli nie rzutujemy wskaźnika na inny typ zawsze jest tym samym co zmienna.
    Przecież podczas użycia normalnej zmiennej jako parametru nie trzeba podawać typu.

    Troche trudno mi opisać dokładnie co bym chciał zrobić.
    Zawsze poczatkujący próbują zrobić coś czego nie da się zrobić bo nie widzą innego rozwiazania.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 3 gru 2018, o 21:42 
    Offline
    Użytkownik
    Avatar użytkownika

    Dołączył(a): 01 lis 2015
    Posty: 1448
    Lokalizacja: okolice Warszawa
    Pomógł: 149

    zastanawiam się czy nie dałoby się coś pokombinować z sizeof.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 3 gru 2018, o 22:17 
    Offline
    Użytkownik
    Avatar użytkownika

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

    Poczytam jak działa sizeof ale on podaje chyba tylko rozmiar czyli ilość bajtów a nie typ.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 4 gru 2018, o 09:13 
    Offline
    Użytkownik

    Dołączył(a): 07 cze 2016
    Posty: 563
    Pomógł: 143

    P3ndz3l3k napisał(a):
    Szkoda trochę bo przecież ta zmienna jest gdzieś w programie zdeklarowana więc kompilator powinien sobie znaleźć jej typ.

    A co jeśli np. wywołanie funkcji jest w innym pliku *.c. Pliki *.c śa kompilowane osobno do plików obiektowych, dopiero linker je łączy w jeden plik wykonywalny...
    Nie tak łatwo wytłumaczyć, dlaczego tak się nie uda, a ja w tej chwili nie mam czasu, żeby się rozpisywać (może później). W każdym razie funkcja musi znać typ danych wewnątrz definicji, nie w momencie wywołania.
    Jeśli chcesz ewentualnie zwiększyć funkcjonalność funkcji możesz użyć switch zamiast if:
    Składnia: [ Pobierz ] [ Ukryj ] [ Zaznacz wszystko ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

    Wtedy będziesz mógł przekazać więcej kombinacji różnych typów, ale tak czy inaczej to rozwiązanie dość kłopotliwe. Można też przekazać osobno typ każdego z argumentów.

    W przypadku stosunkowo prostych funkcji, można je zastąpić makrami (function-like macro):
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

    Powinno zadziałać z (prawie) dowolnym typem (w tym przypadku kompilator będzie znał typ), ale takie rozwiązanie też ma swoje wady, jak np. to, że każde użycie takiego makra może znacząco zwiększać rozmiar kodu wynikowego. Makro działa trochę podobnie do funkcji inline, wstawiając za każdym razem kod w miejscu wywołania. Normalna funkcja to fragment kodu wielokrotnego użytku, dzięki czemu kod wynikowy jest zwykle mniejszy, szczególnie w przypadku częstego wywoływania takiej funkcji w różnych miejscach programu.

    Daro69 napisał(a):
    zastanawiam się czy nie dałoby się coś pokombinować z sizeof.

    sizeof nic nie da w tym przypadku. Kompilator tutaj musi znać nie tylko rozmiar, ale dokładny typ zmiennych, bo (jeśli dobrze zrozumiałem) ma wykonywać na nich jakieś operacje arytmetyczne. Zmienne typu int32_t, uint32_t i float mają ten sam rozmiar, ale kompilator musi użyć innych algorytmów i instrukcji asm, żeby zrealizować operacje arytmetyczne na poszczególnych typach.


    Autor postu otrzymał pochwałę


    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 4 gru 2018, o 17:53 
    Offline
    Użytkownik
    Avatar użytkownika

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

    Witaj

    Widzę, że jesteś już zaawansowanym programistą ja jak już pisałem uczę się i właśnie zaczynam używać wskaźników.
    No i właśnie przyszedł mi taki pomysł z tymi różnymi typami bo Mirek zawsze w poradnikach mówi aby myśleć przyszłościowo i nie pisać
    dziesięciu prawie jednakowych procedur a napisać jedną jak najbardziej uniwersalną.
    Chyba chciałem za bardzo ją uniwersalną zrobić.
    Z tąd ten pomysł, w moim programie gdzie potrzebuję użyć tej procedury będę wykorzystywał tylko dwa typy i aby nie kombinować, w wywołaniu tej procedury będę zamieniał poprostu miejscami te zmienne wstawiane jako argumenty.
    A samą procedurę zadeklaruję poprostu na konkretne typy i będzie chulało.

    Nie pisałem tego wcześniej ale te zmienne mam umieszczone wewnątrz struktury ale z punktu widzenia wskaźników nie ma to znaczenia chyba?

    Bardzo ci dziękuję za wyjaśnienia.

    Pozdrawiam Paweł.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 4 gru 2018, o 18:43 
    Offline
    Użytkownik

    Dołączył(a): 07 cze 2016
    Posty: 563
    Pomógł: 143

    P3ndz3l3k napisał(a):
    Nie pisałem tego wcześniej ale te zmienne mam umieszczone wewnątrz struktury ale z punktu widzenia wskaźników nie ma to znaczenia chyba?

    Obydwa argumenty są elementami tej samej struktury? A może chociaż takiej samej struktury? Można przecież przekazywać do funkcji wskaźnik(i) na całą strukturę i dopiero wewnątrz operować na konkretnych elementach struktury w zależności np. od wartości argumentu direction. Jeśli przekażesz do funkcji wskaźnik na strukturę, to typy poszczególnych jej elementów będą znane wewnątrz definicji funkcji. Przekazywane do funkcji wskaźniki są 16-bitowe niezależnie od tego, na co wskazują, więc nie wpłynie to jakoś niekorzystnie na rozmiar kodu czy szybkość wykonania.

    Niestety Twój opis jest zbyt ogólny, żeby doradzić coś konkretnego.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 4 gru 2018, o 19:23 
    Offline
    Użytkownik
    Avatar użytkownika

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

    No wiesz nie zabardzo chciałem zawracać głowy tym moim całym projektem ale jak go skończę to postaram sie opisać o co chodzi wstawić do DIY.
    A także ciężko jednak pisząc przekazać dokładnie co się chce zrobić.
    To jak pisanie 100 SMS-ów duzo szybciej można przekazać w 30s rozmowy.

    A apropo przekazania wskaźnika do całej struktury to musiał bym dużo kombinować bo mam w tej strukturze kopię wszystkich rejestrów tego układu TDA7418 a jest ich 14 każdy to uint8_t i do tego 10 intów do przechowywania wartości i zmiany.

    Jeszcze raz bardzo ci dziękuję fajnie, że masz wiedzę i chęć pomocy takim początkującym.

    Pozdrawiam Paweł.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 4 gru 2018, o 20:16 
    Offline
    Użytkownik

    Dołączył(a): 07 cze 2016
    Posty: 563
    Pomógł: 143

    P3ndz3l3k napisał(a):
    A apropo przekazania wskaźnika do całej struktury to musiał bym dużo kombinować bo mam w tej strukturze kopię wszystkich rejestrów tego układu TDA7418 a jest ich 14 każdy to uint8_t i do tego 10 intów do przechowywania wartości i zmiany.

    Wprawdzie nie znam szczegółów, ale wydaje mi się, że to raczej nie jest problem. Przecież i tak musisz pobrać adresy odpowiednich elementów struktury, więc czy zrobisz to przed wywołaniem funkcji, czy też dopiero wewnątrz funkcji nie powinno stanowić większej różnicy, a przekazanie całej struktury mogłoby rozwiązać problem kolejności argumentów i uczyniło funkcję bardziej uniwersalną.

    No ale mogę się mylić, bo nie znam dokładnie Twojej ogólnej koncepcji programu. Nie będę już w takim razie narzucał się ze swoją pomocą i psuł Ci frajdy z odkrywania zawiłości języka C oraz satysfakcji z samodzielnego napisania kodu.

    Życzę powodzenia w kodowaniu i pozdrawiam :-)
       Andrzej



    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 8 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:  
    Sitemap
    Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
    phpBB SEO