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



Teraz jest 25 lut 2025, o 00:22


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 21 ] 
Autor Wiadomość
PostNapisane: 21 wrz 2014, o 15:34 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 18 maja 2014
Posty: 126
Pomógł: 12

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


Liczy on temperaturę na podstawie wartości poprzedniej na zmiennej 32 bitowej (potrzebuję tak naprawdę tylko 16 najstarszych bitów, uint32_t zastosowałem dla zwiększenia dokładności obliczeń). Potem, by wyliczyć natężenie promieniowania, podnoszę tą wartość do 4 potęgi i dzielę przez 65536^3, tak by końcowy wynik mieścił się znów w 16 bitach. Wszystko liczy się zgodnie z założeniami, tylko hmm... attiny potrzebuje na wykonanie tej pętli 51183 cykle :evil: Trochę za dużo. Da się coś tu jeszcze odchudzić? Tablicowanie tego odpada, nie mam 64 kB na próbki. Mogę niby dorzucić zewnętrzny kwarc, ale i tak wychodzi mi, że liczenie tego zajmie jakieś 50% czasu procesora. Z ciekawości sprawdziłem jak to wypada na pierwszym z brzegu 32 bitowcu - 287 cykli :mrgreen: więc może jakiś ARM? STM32F030 kosztuje niecałe 5 PLN ATtiny88 plus kwarc 4 PLN, sam nie wiem :roll: Ale i tak jestem ciekaw czy można tu coś ugryźć z tego kodu?

_________________
Pozdrawiam, Adrian.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 21 wrz 2014, o 15:42 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 22 cze 2013
Posty: 988
Lokalizacja: Byram, MS 39272
Pomógł: 55

A jakbys zastosowal podnoszenie do potegi za pomoca przesuniec bitowych?
To mogloby baaardzo odchudzic kod ale wymaga znajomosci arytmetyki bitowej i bawienia sie na poziomie maszynowym

_________________
Pomysły na podpis - wyślij SMSa +1 769 243 0011



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 21 wrz 2014, o 15:50 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 18 maja 2014
Posty: 126
Pomógł: 12

Podaj szczegóły. Szukałem algorytmów szybkiego potęgowania, ale to daje efekty przy wysokich wykładnikach. Choć i tak z tego korzystam, bo podnoszę do potęgi drugiej a potem wynik znów do drugiej, co daje tylko 2 mnożenia zamiast trzech.

_________________
Pozdrawiam, Adrian.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 21 wrz 2014, o 16:41 
Offline
Użytkownik

Dołączył(a): 26 lut 2014
Posty: 227
Lokalizacja: LDZ
Pomógł: 22

Ja potęgowanie rozwiązałem 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.

Możesz spróbować.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 21 wrz 2014, o 16:54 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 18 maja 2014
Posty: 126
Pomógł: 12

mokrowski napisał(a):
Attiny nie ma w procesorze wsparcia sprzętowego dla dzielenia i mnożenia.

Tego nie wiedziałem, dzięki. Zobaczę w symulatorze jak wygląda to na Atmedze. Ale cenowo się i tak nie opłaca zostawać na 8 bitach - Atmega droższa. ;) Dzielenie przez potęgi dwójki kompilator zamienia na przesunięcia chyba z automatu?
Cytuj:
Ja potęgowanie rozwiązałem w ten sposób:

Używam podobnego algorytmu, ale tutaj osobna funkcja była bez sensu - za dużo traciłem na procedurze skoku i powrotu, więc zinlineowałem sobie to na sztywno dla wykładnika równego 4 ;)

------------------------ [ Dodano po: 5 minutach ]

Dla ATmega88 - 12271 cykli

_________________
Pozdrawiam, Adrian.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 21 wrz 2014, o 19:17 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 18 maja 2014
Posty: 126
Pomógł: 12

No dobra, co do algorytmu to mam dane z pomiarów (znormalizowałem sobie, tak, że maksimum wynosi 65535) i dobrałem sobie funkcję która przybliża mi całkiem dobrze te dane. Pochodna tej czerwonej funkcji po igreku jest liniowa, więc tu poszło łatwo, gorzej z tą zieloną, której prawie nie widać pod błękitnymi punktami. Tu właśnie liczę czwartą potęgę i dzielę przez 65536^3 czyli przesuwam o 48 bitów. Myślałem nad tablicą, ale mam próbkę co 4 ms, co przy 4 sekundach daje 1000 próbek, niby nie dużo. Zakładając, że będę w nich przechowywał różnicę pomiędzy kolejnymi wartościami, mogę użyć zmiennej ośmiobitowej, bo wartość różnicy nigdy nie przekracza 255. Tylko teraz jak pobierać te próbki, bo one nie są zależne od czasu tylko od aktualnej wartości zmiennej? :roll:
Obrazek

_________________
Pozdrawiam, Adrian.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 23 wrz 2014, o 16:20 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 18 maja 2014
Posty: 126
Pomógł: 12

Nie upieram, szkoda czasu i nerwów, a przy okazji zostanie trochę zasobów na dodatkowe funkcjonalności ;) Muszę tylko zaprojektować sobie płytkę prototypową pod STM32F030, albo uśmiechnąć się do kolegi xbarego, bo chyba widziałem jego płytki z tym procesorem u Sunrivera na blogu ;)

_________________
Pozdrawiam, Adrian.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 5 paź 2014, o 21:56 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 18 maja 2014
Posty: 126
Pomógł: 12

Ok, procesory przyszły więc jedziemy dalej. Siedzę teraz na komunikacją - wymyśliłem sobie to w ten sposób, że chcę spróbować stworzyć coś w rodzaju sieci multi-master z wykrywaniem kolizji. Żeby uniknąć zwarć zamiast rs485 chcę zastosować drivery CAN - TJA1050. Zasada działania niby prosta:

1. sprawdzam czy nic nie nadaje
2. Jeżeli nie to zaczynam nadawanie od swojego identyfikatora
3. Bit po bicie porównuję czy to co nadaję jest tym samym co odbieram, jeśli nie przerywam natychmiast nadawanie (oznacza to, że coś z niższym identyfikatorem zaczęło nadawać w tym samym momencie - "1" jest stanem recesywnym)

1. i 2. jest prosta, szczególnie na STM32, gdzie jest flaga idle. Tylko jak zrealizować punkt 3? Odczytać rejestr odbiorczy mogę tylko w całości, czyli po wysłaniu całego bajtu a muszę przerwać nadawanie zaraz po wykryciu pojedynczego zmienionego bitu. Do głowy przychodzą mi tylko rozwiązania hardwarowe, z użyciem bramki podpiętej pod przerwanie zewnętrzne, ale musiałbym sprawdzić czy nie będę dostawał przypadkowych szpilek przy każdej zmianie stanu na linii, no i muszę użyć dodatkowego układu. Z software przychodzi mi do głowy tylko pętla sprawdzająca ciągle stan pinów RX i TX w czasie wysyłania bajtu, co z kolei blokuje procesor. Z mikrokontrolerów wspierających wykrywanie kolizji na linii znalazłem tylko 16 bitowe układy Renesasa, które są w stanie generować przerwanie po wykryciu kolizji na linii, chyba, że źle szukam i da się to zrobić na AVR albo STM32. ;)

_________________
Pozdrawiam, Adrian.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 5 paź 2014, o 22:43 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 01 gru 2013
Posty: 43
Lokalizacja: Toruń
Pomógł: 2

CAN Użyłeś transceivera TJA1050, a gdybyś jeszcze dorzucił controler CAN-a choćby MCP 2515 - to on wszystko zrobi za Ciebie.
Na tutejszym forum Sun spinał MCP z M8; wszystko jasno opisane http://forum.atnel.pl/topic1183.html#p8706

...,a może jakiś AVR z wbudowanym controlemem CAN-a. Np AT90CAN...

RS485 - magistrala w wielu truckach (J1708) po dziś dzień - informacja, oraz diagnostyka. Poza tym hula tam CAN.
A J1708 network uses a bus topology with “random” access to the bus. Random access means that any node can transmit when it desires, unless the bus is not already busy. The bus must have been in idle mode (logical high level) for at least a bus access time before a node may access it.

The time counting is based on the bit time which, at 9600 bps, is about 104.2 microseconds. Every message has a priority between 1 and 8, where 1 has highest priority. A bus access time is determined as the shortest idle time (at least 10 bit times) plus two times the priority of the message.

If two messages is sent at exactly the same time a collision occurs on the bus. When this happens both sending nodes have to release control of the bus, i.e. deactivate their transmitters. Both nodes then have to wait for a bus access time before they can start sending again. Consequently the node with highest priority will gain access to the bus first and can start to transmit its message.

Jeśli dobrze rozumiem dostęp do nadawania rozwiązano w taki sposób:
1. Każdy ma własne ID (wartość ID ściśle określa priorytet w nadawaniu wiadomości).
2. Min czas bezczynności t=10bit
3. Jeśli chcę nadawać, a wartość mojego priorytetu to powiedzmy t=5bit to sprawdzam dostępność po upływie t= 10+2x5 = 20bit i zaczynam nadawanie.. ?

Jeśli tak to problem może być tylko wtedy, gdy urządzenia zaczną nadawanie w tym samym czasie... (to nie powinno mieć miejsca jeśli każdy odczeka odpowiedni czas nim zacznie nadawać, czyli ID zostaną odpowiednio rozstawione w czasie, by zdążyć skontrolować dostęp i przełączyć się na nadawanie)...

Widzę wszystkie rameczki w czasie rzeczywistym i jeśli skrętka jest ok to ramki fruwają bezbłędnie.

Korzystając z okazji zapytuję, czy dobrze zrozumiałem powyższe :D

W trucku:
Silnik - ID(128)
Hamulce - ID(136)
Licznik - ID(140)
Sterownik pojazdu - ID(144)
itd..

Jest taki fajny fail safe MAX3444EESA+ ......

Pozdrawiam

_________________
Skajpaj: Zbyszek_1976



Ostatnio edytowano 6 paź 2014, o 02:10 przez coralgol1976, łącznie edytowano 1 raz

Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 6 paź 2014, o 01:57 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 18 maja 2014
Posty: 126
Pomógł: 12

Ja doskonale wiem, że mogę użyć MCP albo mikrokontrolera z CAN-em, ale zależy mi na tym, żeby nie pakować do tego procesora za kilkadziesiąt PLN ;) Dlatego szukam najprostszej metody wykrywania różnicy pomiędzy RX a TX, co w zupełności mi wystarczy. Jak nie to zrobię po ethernetowemu - wysyłam cały bajt/paczkę, a jak wykryję, że coś poszło nie tak (nie odebrałem tego co wysłałem) to czekam losowy czas i wysyłam od nowa. Wolałbym metodę z CAN, bo tu urządzenie o wyższym priorytecie w ogóle nie musi retransmitować, bo to o niższym w porę się orientuje, że nadają dwa na raz i wycofuje się z transmisji, czeka i próbuje ponownie.

_________________
Pozdrawiam, Adrian.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 10 paź 2014, o 14:28 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 01 gru 2013
Posty: 43
Lokalizacja: Toruń
Pomógł: 2

Wymyśliłeś jakiś sposób na arbitraż ? Bo w sumie dopadła mnie taka potrzeba... Zastanawiam się nad wykorzystaniem dwóch UARTów i dwóch transeiverów ..a pierwszy bajt wcisnąć w strukturę 8 pól bitowych i ramkę danych podzielić na dwie, gdzie 1wsza to ID=priorytet (nasze 8 pól), a druga to reszta ramki danych. Nie wiem, czy dobrze kombinuję. :roll:

_________________
Skajpaj: Zbyszek_1976



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 10 paź 2014, o 15:02 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 18 maja 2014
Posty: 126
Pomógł: 12

Ja wykombinowałem, że będę wysyłał najpierw jednobajtowe ID urządzenia nadającego, a potem resztę. Sprzętowo wsparcie dla wykrywania różnicy pomiędzy TX a RX znalazłem tylko w procesorach Renesasa, u siebie chce obejść to w ten sposób, że ustawię uart na tryb synchroniczny i użyję przerwania zewnętrznego na pinie sygnału zegarowego w którym będę porównywał stan końcówki RX z TX i przy wykryciu kolizji zatrzymywał nadawanie. Nie próbowałęm czy na AVR to zadziała, ale w STM32 da się odczytywać stan pinu używanego przez uart, więc powinno zadziałać. Dowiem się jak złożę układ testowy ;)

_________________
Pozdrawiam, Adrian.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 30 lis 2014, o 09:38 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 01 gru 2013
Posty: 43
Lokalizacja: Toruń
Pomógł: 2

Cześć Adrian, zadziałało poprawnie ? Tak się składa, że chciałbym skorzystać z doświadczenia :D
Pozdrawiam
Zbyszek

_________________
Skajpaj: Zbyszek_1976



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 30 lis 2014, o 16:27 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 18 maja 2014
Posty: 126
Pomógł: 12

Czekam na płytki do tych pchełek póki co ;)

_________________
Pozdrawiam, Adrian.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 23 gru 2014, o 15:05 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 18 maja 2014
Posty: 126
Pomógł: 12

Płyteczki przyszły - zminiaturyzowane bieduvery na stm32f030 i płytki pod MBI5040 :D Będzie co robić w święta ;)
ObrazekObrazekObrazek
Obrazek

_________________
Pozdrawiam, Adrian.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 29 gru 2014, o 21:15 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 18 maja 2014
Posty: 126
Pomógł: 12

mokrowski napisał(a):
Może się da, ale z rozsądkiem niewiele ma wspólnego przy tych cenach 32-bit MCU z mnożeniem :-)

Zrobiłem w końcu, 180 mikrosekund zajęło ARM-owej pchełce policzenie tego wszystkiego dla 16 diod :) Mogę brać się za komunikację.

------------------------ [ Dodano po: 27 minutach ]

Zapomniałbym, następnym razem wezmę te procesory w większych obudowach, bo te maluchy nie mają wyjścia zegara i trzeba marnować timer do generowania taktowania dla mbi. :roll:

_________________
Pozdrawiam, Adrian.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 sty 2015, o 02:04 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 18 maja 2014
Posty: 126
Pomógł: 12

Federerer napisał(a):
Sprzętowo wsparcie dla wykrywania różnicy pomiędzy TX a RX znalazłem tylko w procesorach Renesasa, u siebie chce obejść to w ten sposób, że ustawię uart na tryb synchroniczny i użyję przerwania zewnętrznego na pinie sygnału zegarowego w którym będę porównywał stan końcówki RX z TX i przy wykryciu kolizji zatrzymywał nadawanie. Nie próbowałęm czy na AVR to zadziała, ale w STM32 da się odczytywać stan pinu używanego przez uart, więc powinno zadziałać. Dowiem się jak złożę układ testowy ;)

Zrobiłem w końcu próbę, działa zgodnie z założeniami - przy zwartym RX z TX nic się nie dzieje, przy rozwartym (RX z rezystorem pulldown) debbuger diodowy daje piękne szpilki gdy TX=1 ;) Jestem ciekaw czy wpadł ktoś jak można zrobić to prościej, bez angażowania do tego celu przerwań zewnętrznych i marnowania na to pinu mikrokontrolera? Wygląda to tak:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Musiałem odpalić googla, żeby znaleźć sposób na logicznego XOR-a, bo samo != tu nie zadziała. Sposób jest jak widać genialnie prosty i działa :) Jutro postaram się już zrobić próbę z TJA1050, mam nadzieję, że przesunięcie pomiędzy TX a RX nie pokrzyżuje mi planów zastosowania tych układów. :?

P.S. Zastanawiam się, czy nie poprosić moderatora o wydzielenie/przeniesienie wątku do działu o ARM, bo na takich procesorach będę kontynuował?

_________________
Pozdrawiam, Adrian.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 sty 2015, o 02:59 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 08 gru 2013
Posty: 366
Lokalizacja: Wałbrzych
Pomógł: 7

Ja na twoim miejscu nie inicjował bym lini CAN do tego. Pomyśl o komunikacji typu ISO9141 czyli popularny w-bus . Są takie układy l9637d taniocha możesz sobie zrobić linie komunikacyjną jedno przewodową i to na wyższych poziomach napięć co jest plusem. Jedyna wada że po zastosowaniu tych układów uzyskujesz sprzętowe echo. Możesz sprzęgnąć kilka układów w jedną sieć. Nic to nie przeszkadza.

_________________
sig off ;(



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 sty 2015, o 13:46 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 18 maja 2014
Posty: 126
Pomógł: 12

U siebie też mam echo, celowo. Dokopałem się do szwedzkiego opisu ISO9141 i wychodzi na to, że robię coś bardzo podobnego, jedynie z inną warstwą fizyczna i inaczej chcę rozwiązać detekcję kolizji, niemniej przyda się. :)

_________________
Pozdrawiam, Adrian.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 sty 2015, o 20:03 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 18 maja 2014
Posty: 126
Pomógł: 12

TJA1050 pracuje poprawnie, trzeba tylko uważać na ta, by nie używać go z baudrate niższym niż 38400, bo te układy mają system time-outu który ogranicza czas trwania stanu dominującego do około 300 us i mogą być problemy przy wysyłaniu zer. Przerwanie wysyłania po wykryciu kolizji też sprawdziłem i działa, wystarczy po wykryciu kolizji ustawić pin TX jako wejście w rejestrze MODER, drugi układ o wyższym priorytecie powinien kontynuować wysyłanie, co sprawdzę po zbudowaniu drugiego zestawu ;) Próbowałem też wyłączania transmitera albo całego usartu, ale nie działało jak należy.

_________________
Pozdrawiam, Adrian.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 14 lut 2015, o 18:28 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 18 maja 2014
Posty: 126
Pomógł: 12

Mały update: testuję właśnie komunikacje pomiędzy dwoma układami. Napisałem sobie mały programik do podglądu tego co się dzieje na linii i wygląda, że wszystko działa.
Obrazek
W okienku po kolei: adres nadawcy, adres odbiorcy, ilość błędów w komunikacji (pakiety niepotwierdzone przez odbiorce), ilość pakietów których nie udało się dostarczyć (nadawca próbuje pięciokrotnie retransmitować w przypadku braku potwierdzenia), ostatnie pole to sytuacje w których oba nadajniki zaczęły nadawać jednocześnie i ten o niższym adresie się wycofał unikając kolizji. Na dole liczba przesłanych pakietów.

_________________
Pozdrawiam, Adrian.



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

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 2 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