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 w 2025? 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 3 kwi 2025, o 19:38


    Strefa czasowa: UTC + 1





    Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 17 ] 
    Autor Wiadomość
    PostNapisane: 29 cze 2013, o 17:50 
    Offline
    Uzytkownik zasłużony dla forum.atnel.pl
    Avatar użytkownika

    Dołączył(a): 16 lip 2012
    Posty: 2088
    Lokalizacja: Leżajsk / Kraków
    Pomógł: 411

    Obrazek
    Przeglądając sieć natrafiłem na fajny trik. Typowe podejście na tablicę wartości funkcji wygląda tak, że chcąc skorzystać z przykładowo sinusa, dołączamy do programu kod np. z tej strony albo sami obliczamy to w arkuszu kalkulacyjnym i przenosimy łatwiej lub trudniej do kodu programu. Można to zrobić też jak pokazano poniżej:
    Plik main.c:
    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.

    Plik values.txt:
    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.


    Jeśli tak jak w przykładzie potrzeba 24 wartości sinusa to w pliku values.txt 24 razy powtarza się dokładnie tą samą linię. Parametr __LINE__ zwraca numer linii (tutaj 1-24). Jako, że zaczyna się numeracja od 1 to we wzorze na sinus odejmowana jest najpierw 1 i wtedy argument ma wartość 0-23. Przeliczając to na stopnie mnoży się razy krok czyli 15, bo akurat potrzeba 24 wartości z całego zakresu 0-360 stopni. Następnie konieczna jest zamiana stopni na radiany (/180.0*M_PI) dlatego, że funkcja sinus na takich wartościach operuje. Kolejnym krokiem jest dopasowanie wyniku do wartości 0-255 co jest realizowane poprzez pomnożenie razy 128 i dodanie 127. No i już nie potrzeba korzystać z innych programów :)

    _________________
    Dragonus Cracovus: Biomagia



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 29 cze 2013, o 18:56 
    Offline
    Moderator
    Avatar użytkownika

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

    O matko ;) jak pierwszy raz to przeczytałem i zobaczyłem to - powiedziałem tylko hyyyyy i nic nie zrozumiałem ;) .... więc jeszcze raz, i jeszcze raz .... i jeszcze raz .... i tak jeszcze n razy jak w tej tabeli ;)

    a jak zaskoczyłem ;) .... hahahaha - no mega super trick - ale popraw mnie jeśli się mylę bo może jednak coś na końcu przeoczyłem

    rezultatem tego myku jest fakt że, tzn postaram się to podsumować tak na mój rozum:

    1. w programie nie zostaną użyte funkcje zmiennoprzecinkowe z math.h ;)
    2. w programie zostanie stworzona ładna tablica sinusów w pamięci FLASH
    3. a wartości tej tablicy przygotuje grzecznie sługa PREPROCESOR ;)
    4. plik values.txt jest tylko taki pomocniczy .... ;) żeby zadać fuchę preprockowi ;)

    dobrze myślę ?

    jeśli tak to działa to na prawdę Krauser super mega TRICK obczaiłeś w necie ! ;) gratulacje

    no i super że się nim podzieliłeś

    _________________
    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: 29 cze 2013, o 18:58 
    Offline
    Użytkownik

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

    Ano właśnie ... kiedyś to widziałem i gdzieś przepadło w przepastnych czeluściach sieci zaiste .
    dzięki za przypomnienie , bo robienie na piechotę czasem dobija :)

    _________________
    Zbuduj swój system [url=https://helion.pl/ksiazki/w-labiryncie-iot-budowanie-urzadzen-z-wykorzystaniem-ukladow-esp8266-i-esp32-andrzej-gromczynski,wlablo.htm#format/d]IOT[/url]



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 29 cze 2013, o 19:58 
    Offline
    Użytkownik
    Avatar użytkownika

    Dołączył(a): 14 lis 2011
    Posty: 534
    Lokalizacja: Mierzyn
    Pomógł: 9

    genialne :)

    _________________
    pozdrawiam
    Jachu



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 29 cze 2013, o 20:29 
    Offline
    Nowy

    Dołączył(a): 29 cze 2013
    Posty: 1
    Pomógł: 0

    Ja ostatnio spotykając się z tym problemem, mając naprawdę mało czasu napisałem sobie po prostu programik który generował kod.
    Generuje on sinusy o 6 różnych amplitudach w dwuwymiarowej tablicy i nie ma problemu z wygenerowaniem za pomoca tego kodu innych funkcji z math.c po lekkim przerobieniu, treść jego jest taka:

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


    Pod linuksem odpalam skompilowany program np.
    Kod:
    ./sinus_gen > sinus.h

    więc nie potrzebuje zapisu do pliku, ale pod windowsem mogłoby się to przydać.

    Ponieważ miałem problemy z przetwornikiem, dodatkowo zrobiłem opcję generowania przebiegu do matlaba, aby porównać sobie tablicę do tego, co widze na oscyloskopie.

    Wykorzystanie preprocesora napewno jest bardziej "hackerskie", ale i trudniejsze w zrozumieniu (chociaż mnie strasznie podobają się takie tricki :) )



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 29 cze 2013, o 22:22 
    Offline
    Nowy

    Dołączył(a): 29 cze 2013
    Posty: 1
    Pomógł: 0

    @mirekk36
    Te wartości nie znajdą się tam w magiczny sposób, bez wywołania funkcji sin(x) z biblioteki math.
    Mniej więcej będzie to wyglądać tak:
    1. Preprocesor wpierw zamieni __LINE__ w pliku values.txt na odpowiadające im numery linii
    2. Następnie w miejsce #include "values.txt" wklei zawartość tego pliku czyli:
    Kod:
    const uint8_t sin_tab[TAB_SIZE] PROGMEM ={
        VALUE(1),
        VALUE(2),
        ...,
        VALUE(24),
    };

    2. Wszystkie miejsca gdzie użyte jest makro VALUE(a) przed kompilacją zamieni na:
    Kod:
    const uint8_t sin_tab[TAB_SIZE] PROGMEM ={
        (sin( ( ( (1-1) * STEP )/180.0 )*M_PI )*128 + 127 ),
        (sin( ( ( (2-1) * STEP )/180.0 )*M_PI )*128 + 127 ),
        ...,
        (sin( ( ( (24-1) * STEP )/180.0 )*M_PI )*128 + 127 ),
    };

    3. Kompilator wygeneruje kod w asemblerze, który inicjalizuje tę tablicę, czyli do każdej wartości z tablicy przypisze wartość otrzymaną po wywołaniu tego wyrażenia.

    Tak przy okazji wydaje mi się, że ten wzór na zamianę <-1.0f, 1.0f> na <0, 255> jest zły.
    Jak sin(x) wyjdzie -1 to otrzymasz (-1.0f)*128 + 127 => -128.0f + 127 => -1.0f i po rzutowaniu na unsigned short int wyjdzie 255.
    Imo lepiej użyć wzoru:
    Kod:
    (sin((a-1)*STEP*PI/180.0f)*127.5f + 127.5f)


    Wg mnie zamiast kombinować z takimi hackami lepiej jest po prostu wygenerować sobię tę tablicę i ręczne przekleić do kodu. Niestety takie stuczki zmniejszają czytelność i jak nie znamy dokładnego zachowania kompilatora to mogą prowadzić do powstania błędów w programie.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 29 cze 2013, o 23:46 
    Offline
    Moderator
    Avatar użytkownika

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

    krz napisał(a):
    Te wartości nie znajdą się tam w magiczny sposób, bez wywołania funkcji sin(x) z biblioteki math


    Nie pisałem, że magiczny ;) pisałem że w programie nie zostanie użyta biblioteka math.h - i nie zostanie bo całe wyliczenia zostaną zrobione na etapie preprocesora właśnie i to jest fajne.

    Dobrze, że rozpisałeś to po swojemu w punktach bo dzięki temu jeszcze łatwiej będzie zrozumieć ideę działania tego tricku wielu ludziom ;)

    krz napisał(a):
    Wg mnie zamiast kombinować z takimi hackami lepiej jest po prostu wygenerować sobię tę tablicę i ręczne przekleić do kodu


    łeeeej ;) no bez przesady - po to są właśnie takie sposoby, jako alternatywa i tak należy to rozumieć. Sposób działa i to się liczy - jak się już go zrozumie - to okazuje się że wcale nie jest skomplikowany a wręcz banalnie prosty - i to jest siła takich rozwiązań w niektórych przypadkach.

    krz napisał(a):
    Niestety takie stuczki zmniejszają czytelność i jak nie znamy dokładnego zachowania kompilatora to mogą prowadzić do powstania błędów w programie


    To by oznaczało, że w zasadzie jak coś wygląda dziwnie - to lepiej tego nie ruszać. To jest dla osób które już zaskoczą o co tu chodzi - a myślę że sporo zaskoczy dzięki temu całemu wątkowi ... i nic nie będzie się działo ze zmniejszeniem czytelności kodu ;) ... tym bardziej, że działa to TYLKO na poziomie preprocesora. Dlatego ja akurat uważam, że warto na pewno czasem to wykorzystywać ;) jak najbardziej.

    _________________
    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: 30 cze 2013, o 11:15 
    Offline
    Uzytkownik zasłużony dla forum.atnel.pl
    Avatar użytkownika

    Dołączył(a): 16 lip 2012
    Posty: 2088
    Lokalizacja: Leżajsk / Kraków
    Pomógł: 411

    krz napisał(a):
    Tak przy okazji wydaje mi się, że ten wzór na zamianę <-1.0f, 1.0f> na <0, 255> jest zły.
    Jak sin(x) wyjdzie -1 to otrzymasz (-1.0f)*128 + 127 => -128.0f + 127 => -1.0f i po rzutowaniu na unsigned short int wyjdzie 255.
    Imo lepiej użyć wzoru:
    Kod:
    (sin((a-1)*STEP*PI/180.0f)*127.5f + 127.5f)

    Tak wzór jest zły (pozdrawiam panią od matematyki :oops: ), ale w wyniku działań na liczbach zmiennoprzecinkowych sin(270) > -1 i po odcięciu części ułamkowej wychodzi 0. To osobny temat poruszony już przy okazji omawiania obliczania UBRR. W związku z tym lepiej użyć jeszcze innego wzoru (tylko dla preprocesora, gdzie wynik jest większy o 0,5):
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

    Teraz wartości są jak te z arkusza po zaokrągleniu. Dodanie do wzoru 360 nic nie zmienia, ale wtedy obie wartości dla 0 i 180 stopni są równe i wynoszą 128 (jak w arkuszu kalkulacyjnym). Chociaż z drugiej strony bardziej symetryczne wyniki są, gdy dla 180 mamy wartość 127. Co kto woli. Środek jest na poziomie 127,5, a takiej wartości nie można wybrać. Zwiększenie rozdzielczości do 16 bitów też nic nie zmieni, bo znowu środek jest na poziomie 511,5 .

    _________________
    Dragonus Cracovus: Biomagia



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 15 wrz 2013, o 20:05 
    Offline
    Nowy

    Dołączył(a): 20 sie 2013
    Posty: 7
    Pomógł: 0

    Czy da się się w tym "tricku" podstawić inną funkcję zamiast sinusa z math.h? Konkretnie chodzi mi o funkcję przez siebie zdefiniowaną spoza biblioteki standardowej.?



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 15 wrz 2013, o 20:39 
    Offline
    Uzytkownik zasłużony dla forum.atnel.pl
    Avatar użytkownika

    Dołączył(a): 16 lip 2012
    Posty: 2088
    Lokalizacja: Leżajsk / Kraków
    Pomógł: 411

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

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

    Można używać innych makr (makro to nie funkcja, ale może ją zastąpić) np.
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

    _________________
    Dragonus Cracovus: Biomagia



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 15 wrz 2013, o 20:53 
    Offline
    Nowy

    Dołączył(a): 20 sie 2013
    Posty: 7
    Pomógł: 0

    Czy chcesz powiedzieć, że preprocesor umie policzyć wartość sinusa z liczby? Raczej nie. Zakomentowanie lini #include<math.h> spowoduje błędy, zatem wartość sinusa obliczana jest na podstawie algorytmu zawartego w bibliotece math.h.

    Cytuj:
    Zauważ, że:
    Składnia: [ Pobierz ] [ Ukryj ]
    język c

    #define VALUE(a) (sin( ( ( (a-1) * STEP)/180.0 )*M_PI )*127.5 + 128 )/* wzór na wartość sinusa */

    GeSHi

    to nie jest po prostu:
    Składnia: [ Pobierz ] [ Ukryj ]
    język c

    #define VALUE(a) (sin(a))


    w sumie pierwsze sprowadza się do drugiego



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 15 wrz 2013, o 20:59 
    Offline
    Moderator
    Avatar użytkownika

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

    rafrew napisał(a):
    Czy chcesz powiedzieć, że preprocesor umie policzyć wartość sinusa z liczby?


    Kolego naprawdę poczytaj troszkę o preporcesorze gdzieś ;) ... pewnie że preprocesor oblicza sin() i to bez żadnego inkludowania <math.h> bo ta biblioteka jest potrzebna tylko gdy obliczeń trzeba dokonywać w kodzie w procku.

    Co to za problem dla preprocesora obliczyć sin czy podobną funkcję - na PC? miałby to być kłopot ?

    a makro VALUE() działa tu TYLKO i wyłącznie w taki sposób że zwraca stałą dosłowną która zostanie wyliczona przez preprocesor właśnie

    _________________
    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: 15 wrz 2013, o 21:25 
    Offline
    Nowy

    Dołączył(a): 20 sie 2013
    Posty: 7
    Pomógł: 0

    Ok, jeśli tak to już wszystko jasne. Faktycznie muszę coś poszukać bo o funkcjach jakie umie wyliczyć preprocesor jakoś nigdzie się nie natknąłem. Dzięki za odpowiedzi. Pozdrawiam.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 11 lut 2014, o 00:18 
    Offline
    Użytkownik

    Dołączył(a): 25 sty 2014
    Posty: 185
    Lokalizacja: Działoszyn
    Zbananowany użytkownik

    Pomógł: 8

    Tamta stronka juz wygasła wiec pomyslalem ze moze dobrze bedzie zgrac z google webcache tametego generatora poki jeszcze jest dostepne.


    Załączniki:

    Aby zobaczyć załączniki musisz się zalogować. Tylko zalogowani użytkownicy mogą oglądać i pobierać załączniki.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 21 maja 2014, o 09:53 
    Offline
    Użytkownik
    Avatar użytkownika

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

    Witam,

    Właśnie natknąłem się na inny ciekawy sposób tworzenia tablicy z wartościami wyliczanymi przez preprocesor. Nie trzeba robić dodatkowego pliku do includowania a wykorzystać rekurencję:
    Kod:
    #define XTAB0(n) func(n),
    #define XTAB1(n) XTAB0(n) XTAB0(n+1)  XTAB0(n+2)  XTAB0(n+3)
    #define XTAB2(n) XTAB1(n) XTAB1(n+4)  XTAB1(n+8)  XTAB1(n+12)
    #define XTAB3(n) XTAB2(n) XTAB2(n+16) XTAB2(n+32) XTAB2(n+48)
    #define XTAB4(n) XTAB3(n) XTAB3(n+64) XTAB3(n+128) XTAB3(n+192)

    const uint8_t TABLE[] PROGMEM = { XTAB4(0) };


    Dla powyższego kodu dostajemy w TABLE[] wartości będące wynikiem func(n) dla n od 0 do 255. Ale można to bardzo łatwo zmodyfikować na inne wielkości tablic oraz zmienić wartość początkową n na inną (zmiana w wywołaniu XTAB4(start_value)).

    --
    Pozdrawiam,
    Robert



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 21 maja 2014, o 10:04 
    Offline
    Moderator
    Avatar użytkownika

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

    no fajne ciekawostki i smaczki ;)

    _________________
    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: 26 gru 2014, o 11:08 
    Offline
    Użytkownik

    Dołączył(a): 08 gru 2014
    Posty: 53
    Lokalizacja: Sz-n
    Pomógł: 0

    A ja dłubałem program w Delphi, co mi zmienia format Excelowego słupka na format Pgm Space. Szlo to dość szybko, ale ta metoda jest niezła. Będę musiał ją przetrenować bo w perspektywie jest wpisanie okolo 30 tablic po 2048 elementów 16-bitowych by zrobić wavetable.
    Jak będzie zainteresowanie, udostępnię wspomniany programik.



    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: 17 ] 

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