logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Jak zaprojektować ramkę transmisji 125kHz dla 8-bit MCU: CRC czy proste operacje bitowe?

ken-wawa 12 Sie 2026 23:03 237 9
REKLAMA
  • #1 21954160
    ken-wawa
    Poziom 13  
    Posty: 938
    Pomógł: 1
    Ocena: 143
    Hejka!

    Nie do końca wiedziałem, gdzie dać mój post, więc mam nadzieję, że to będzie dobre forum. :)

    Do rzeczy.

    Wyobraźcie sobie, że macie zadanie zaprogramować układ transmisji z użyciem pola magnetycznego i częstotliwością 125 kHz (coś jak rfid).

    I teraz macie bardzo prosty, wręcz 8-bitowy mikroprocesor. Macie zaprojektować ramkę takiej transmisji, tak by szybko ją nadawać/odbierać i nie obciążać za bardzo mikrokontrolera.

    Jak byście w tej ramce zapisali adres urządzenia (który normalnie jest 4 bajtowy). Czy w transmisji dalibyście np.

    id1 id2 id3 id4 dane crc


    Czy raczej szlibyście w jakieś rozwiązania w stylu nie używać w ogóle klasycznego crc, a zrobić jakąś kontrolę prawidłowości transmisji danych w stylu id1 not(id1) albo coś podobnego. Mnie się wydaje, że w tak prostym układzie to raczej operacje bitowe niż crc? Wtedy ramka miałaby strukturę:

    id1 not(id1) id2 not(id2) id3 not(id3) id4 not(id4) dane


    I właśnie, czy raczej szlibyście w kolejność:

    id1 not(id1) id2 not(id2) itd.


    Czy może bardziej w:

    id1 id2 id3 id4 not(id1) not(id2) itd.


    Mnie się ta pierwsza wydaje lepszym rozwiązaniem. Łatwiej kontrolować przy odbiorze czy przy nadawaniu. Biorę id1, sprawdzam czy kolejny bajt to not (id1) i dopiero jeśli jest OK wrzucam do jakiegoś rejestru/bufora. A jak nie jest, to robię break na reszcie transmisji, bo już wiem, że jest źle.

    A może znacie jakiś gotowy system transmisji, który w jakiś ciekawy sposób to rozwiązał i jak? Może jeszcze coś innego wchodzi w grę? Inny sposób zapisu tego id w ramce? Chętnie bym poznał jakieś gotowe rozwiązania i zobaczył, jak taki problem rozwiązali inni.

    Dodam urządzenie bateryjne, więc ma być oszczędne (takie "skromniutkie" rozwiązanie). :P
  • REKLAMA
  • #2 21954208
    TvWidget
    Poziom 39  
    Posty: 4429
    Pomógł: 472
    Ocena: 700
    ken-wawa napisał:
    tak by szybko ją nadawać/odbierać i nie obciążać za bardzo mikrokontrolera.[...]
    Dodam urządzenie bateryjne, więc ma być oszczędne (takie "skromniutkie" rozwiązanie).

    Czy chodzi o symetryczne rozwiązanie gdy dwie strony mają być energooszczędne ?
  • REKLAMA
  • #3 21954463
    gps79
    Poziom 37  
    Posty: 2214
    Pomógł: 495
    Ocena: 799
    Ciężko odpowiedzieć na tak ogólne pytanie. Brak szczegółów implementacyjnych, zatem należałoby przyjąć jakieś założenia, np.:
    - układ odbiornika demoduluje sygnał i wystawia go na nóżkę mikrokontrolera
    - pomiędzy odbiornikiem, a mikrokontrolerem stosujesz filtr dolnoprzepustowy dostosowany do najkrótszego impulsu odbieranego sygnału
    - sygnał zakodowany jest z użyciem szerokości impulsów, np. logiczna jedynka, to 100us, a logiczne zero, to 50us.

    Dla przykładu, (rzadko spotykany) standard ITT w pilotach zdalnego sterowania:
    Jak zaprojektować ramkę transmisji 125kHz dla 8-bit MCU: CRC czy proste operacje bitowe?
    Implementowałem kiedyś taki odbiornik dla kolegi z tego forum ( https://www.elektroda.pl/rtvforum/topic4012875.html#20802924 ).

    Wtedy mikrokontroler obsługuje przerwanie rozpoznające zbocze narastające. W przerwaniu mierzy czas od poprzedniego wystąpienia przerwania i dzięki temu wie, czy odebrał 0, 1, znacznik początku, czy końca transmisji.
    Podczas kolejnych przerwań ISR wypełnia bufor danych (kolejne bity) lub resetuje transmisję i bufor, gdy długość sygnału jest nieprawidłowa. Oznacza to wykrycie błędu transmisji lub "zbłąkany" sygnał w eterze.
    W takim rozwiązaniu mikrokontroler może być uśpiony do czasu odebrania kolejnego przerwania, ale zauważ, że jest wybudzany do odbioru każdego bitu, który przyszedł z odbiornika, co powoduje, że nie ma możliwości na oszczędzenie energii poprzez zignorowanie reszty ramki po odczytaniu adresu (gdy ramka zaadresowana jest do innego urządzenia).
    Rozwiązania optymalne można znaleźć np. przy transmisji CAN lub Ethernet, gdzie elektronika odczytuje adres odbiorcy i wybudza mikrokontroler przerwaniem tylko, gdy odbiorcą ramki ma być właśnie ten mikrokontroler.

    Każda ramka powinna mieć weryfikację poprawności danych, czyli bit parzystości (dla ramek do 8 bitów) lub CRC dla ramek dłuższych. Dla mikrokontrolera 8-bitowego liczenie CRC nie będzie wyzwaniem, ani wydajnościowym, ani energetycznym, a pozwala odrzucić niepoprawne ramki.

    Czyli:
    - najwięcej energii zaoszczędziłbyś, gdybyś użył chipu odbiornika, który odebrałby pełną ramkę, porównał adres i dopiero wtedy wybudził Twój mikrokontroler. W każdym innym przypadku mikrokontroler musi być aktywny w czasie odbioru każdego bitu ramki, nawet jeśli to urządzenie nie jest docelowym jej odbiorcą.
    - użyj przerwań do odbioru danych i usypiaj mikrokontroler w międzyczasie. Akcję mikrokontroler wykona dopiero po odebraniu pełnej ramki i potwierdzeniu adresu odbiorcy. W tym przypadku położenie adresu odbiorcy w ramce jest bez znaczenia. Warto jednak dać adres na początku ramki dla możliwych usprawnień systemu odbiorczego w przyszłości.
    - spróbuj znaleźć mikrokontroler, który sam zajmie się odbiorem danych i przekaże je do programu i wybudzi mikrokontroler dopiero o odczytaniu pełnej ramki. Wiele mikrokontrolerów jest w stanie tak zrobić dla I2C, 1-wire, SPI, CAN. Musiałbyś wtedy jednak dostosować swój protokół do tej właśnie technologii.


    ken-wawa napisał:
    id1 not(id1) id2 not(id2) id3 not(id3) id4 not(id4) dane

    uważam za zbędną stratę pasma. Im dłuższa ramka, tym większe prawdopodobieństwo wystąpienia błędnych ramek.

    Sugeruję taką ramkę na warstwie danych (na warstwie fizycznej dojdzie bit startu i stopu, itp.):
    id1 id2 id3 id4 dane crc

    Jeśli ramka nie jest długa, to wystarczy CRC-8. Przy długich ramkach lepsze będzie CRC-16.
  • #4 21954595
    krzbor
    Poziom 29  
    Posty: 1787
    Pomógł: 43
    Ocena: 1073
    Ja kiedyś zrobiłem termometr zewnętrzny z nadajnikiem. Użyłem powielenia sygnału (czyli dwa razy to samo id1 id2 id3 id4 id1 id2 id3 id4). Jeśli ramka nie jest długa to prosta i skuteczna metoda. Przy odbiorze po prostu sprawdzałem, czy oba ciągi są takie same. Do transmisji użyłem kodu 1/3 2/3. Tam zero to impuls o długości 1/3 i 2/3 przerwy, a jedynka to 2/3 i 1/3 przerwy. Kod jest samosynchronizujący na każdym bicie. Wykrywamy start i sprawdzamy stan w czasie 1/2. Jeśli 0, to 0, jeśli 1 to 1. Mikrokontroler nadający był na dworze (a więc zmienne warunki temperaturowe) i udało się utrzymać parametry przy wewnętrznym generatorze RC.
  • REKLAMA
  • #5 21954601
    TvWidget
    Poziom 39  
    Posty: 4429
    Pomógł: 472
    Ocena: 700
    Liczenie CRC, nadmiarowe dane, korekcje itp. zależą od rodzaju i statystyki ew. błędów. Nie ma jednego uniwersalnego rozwiązania. Zwróć uwagę, że z pytania nie wynika nawet czy ma być to transmisja jedno czy dwukierunkowa. Skupiłeś się na szczegółach pomijając kluczowe założenia.
  • REKLAMA
  • #6 21954629
    oscil1
    Poziom 24  
    Posty: 679
    Pomógł: 50
    Ocena: 184
    jak chcesz najprościej to dodaj parzystość po kazdym bajcie czy calej ramce -
  • #7 21954679
    ken-wawa
    Poziom 13  
    Posty: 938
    Pomógł: 1
    Ocena: 143
    TvWidget napisał:
    Czy chodzi o symetryczne rozwiązanie gdy dwie strony mają być energooszczędne ?


    Tak. Choc jedna jakby bardziej niz druga. :) Ta odbierajaca ma byc bardziej energooszczędna.

    Dodano po 3 [minuty]:

    gps79 napisał:
    Jeśli ramka nie jest długa, to wystarczy CRC-8. Przy długich ramkach lepsze będzie CRC-16.


    Samo fizyczne kodowanie póki co mnie nie interesuje. Ale wiem, ze crc-8 czy crc-16 w przypadku prostego mikrokontrolera je dużo prądu i też zajmuje czas. Stąd często właśnie w takich rozwiązaniach stosuje się często jakieś zabawy bitowe. I tego dotyczyło głównie moje pytanie. Czy jednak prosta struktura ramki, ale z crc, czy jakaś redundancja i przesyłanie tego samego bajtu kilka razy, ale bez crc a w różnej formie, choćby z tą negacją.

    Dodano po 16 [minuty]:

    krzbor napisał:
    Użyłem powielenia sygnału (czyli dwa razy to samo id1 id2 id3 id4 id1 id2 id3 id4). Jeśli ramka nie jest długa to prosta i skuteczna metoda. Przy odbiorze po prostu sprawdzałem, czy oba ciągi są takie same. Do transmisji użyłem kodu 1/3 2/3. Tam zero to impuls o długości 1/3 i 2/3 przerwy, a jedynka to 2/3 i 1/3 przerwy. Kod jest samosynchronizujący na każdym bicie. Wykrywamy start i sprawdzamy stan w czasie 1/2. Jeśli 0, to 0, jeśli 1 to 1. Mikrokontroler nadający był na dworze (a więc zmienne warunki temperaturowe) i udało się utrzymać parametry przy wewnętrznym generatorze RC.


    Jak rozumiem numerowałeś te ramki? To była transmisja na 433MHz? Ta na 125kHz jest chyba bardziej zawodna (w sensie większe ryzyko błędów)?

    Dodano po 2 [minuty]:

    TvWidget napisał:
    Liczenie CRC, nadmiarowe dane, korekcje itp. zależą od rodzaju i statystyki ew. błędów. Nie ma jednego uniwersalnego rozwiązania. Zwróć uwagę, że z pytania nie wynika nawet czy ma być to transmisja jedno czy dwukierunkowa. Skupiłeś się na szczegółach pomijając kluczowe założenia.


    Tylko, by ewentualnie zebrać te statystyki, trzeba coś zrobić i zobaczyć, jak się sprawuje, a więc przyjąć na początku jakieś założenia. Dwa zastanawiam się jak to robią profesjonaliści? Dlaczego uważasz, że to, czy transmisja jedno czy dwukierunkowa ma znaczenie?
  • #8 21954684
    TvWidget
    Poziom 39  
    Posty: 4429
    Pomógł: 472
    Ocena: 700
    Niska częstotliwość i wykorzystanie sprzężenia magnetycznego zdecydowanie nie jest energooszczędne. Zobacz w celach edukacyjnych jak realizowana jest komunikacja w Bluetooth Low Energy. Jeśli chodzi o pobór prądu w klasycznej wersji rozwiązanie nie jest symetryczne. Jedno urządzenie pobiera średni prąd na poziomie kilkunastu uA przy 3V a druga strona szacunkowo tysiąc razy więcej czyli rzędu 10mA. Strona energooszczędna okresowo np. co 1 sek. nadaje ramkę i na bardzo krótki czas włącza odbiór. Duża częstotliwość nośna to duża prędkość bitową transmisji (1Mb/s). W konsekwencji stosunek czasu włączenia nadajnika/odbiornika do czasu przerwy (uśpienia) jest bardzo mały np. 1:1000. To co z pozoru wydaje się nieekonomiczne czyli ciągłe nadawanie w trybie 24/7 jest energetycznie bardzo energooszczędne.
    Jeśli chodzi o zagadnienia związane z CRC są tu dość złożone. Po pierwsze stosuje się tzw. whitening. Czy koduje się nadawane dane aby rozmyć widmo sygnału. Z jednej strony wzrasta odporność na zakłócenia a drugiej my mniej zakłócamy inne transmisje.
  • #9 21954715
    gps79
    Poziom 37  
    Posty: 2214
    Pomógł: 495
    Ocena: 799
    ken-wawa napisał:
    Ale wiem, ze crc-8 czy crc-16 w przypadku prostego mikrokontrolera je dużo prądu i też zajmuje czas.

    To nie jest prawda. Dużo więcej energii zje nadawanie i odbiór 2x większej ilości danych, niż liczenie i weryfikacja CRC.
  • #10 21954836
    krzbor
    Poziom 29  
    Posty: 1787
    Pomógł: 43
    Ocena: 1073
    ken-wawa napisał:
    Jak rozumiem numerowałeś te ramki? To była transmisja na 433MHz?

    Tak, to był moduł Telecontroli na 433MHz. Po odczytaniu temperatury wysyłałem ją 2 razy, a później procesor zasypiał. Podwojenie transmisji (zamiast CRC) ułatwi Ci ustalenie skali problemów przy odbiorze bez konieczności wiedzy na temat aktualnie nadawanej wartości. Po prostu widzisz, że jakiś bit się przekłamał, albo że połowa bitów jest przekłamanych (możesz wysyłać odebrane dane na UART) . Z CRC masz tylko info dobrze/źle.

Podsumowanie tematu

LABEL_AI_GENERATED
Tematem jest projekt ramki transmisji z użyciem pola magnetycznego o częstotliwości 125kHz dla bardzo prostego, 8-bitowego mikroprocesora, przy ograniczeniu szybkości nadawania i odbioru oraz obciążenia mikrokontrolera. Rozważany jest sposób zapisania czterobajtowego adresu urządzenia w ramce, na przykład jako id1, id2, id3, id4, dane i crc. Alternatywą ma być rezygnacja z klasycznego CRC na rzecz prostych operacji bitowych, takich jak przesyłanie każdej części adresu razem z jej negacją: id1, not(id1), id2, not(id2), id3, not(id3), id4, not(id4), dane. Taka kontrola miałaby umożliwiać sprawdzanie prawidłowości odebranych danych przy mniejszym koszcie obliczeniowym w 8-bitowym mikrokontrolerze. Kontekst stanowi transmisja podobna do RFID, wykorzystująca pole magnetyczne i częstotliwość 125kHz. Pytanie dotyczy wyboru między klasycznym CRC a kontrolą komplementarnych bajtów oraz wpływu tego wyboru na strukturę ramki, szybkość transmisji i obciążenie procesora. Ostateczny wybór metody kontroli poprawności i struktury ramki pozostaje przedmiotem rozważań.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA