Skocz do zawartości
Elvis

Przeliczanie ADC na V - dzielenie przez 1023 czy 1024?

Pomocna odpowiedź

Cóż, wygląda na to że nie wszystko co jest napisane w internecie jest idealne.

Nadal podtrzymuję pytanie - czy w literaturze fachowej, publikacji naukowej, itd. itp. znajdziemy podpowiedź, czy należy dzielić/mnożyć przez 1023, czy 1024?

Udostępnij ten post


Link to post
Share on other sites

A czy wszystko musi być podane jak krowie na patelni w publikacjach naukowych?

Wystarczy chyba, że przy n-bitowym przetworniku AD dla wartości maksymalnej mierzonego sygnału analogowego wynik cyfrowy będzie wynosić 2^n-1. Ile to wyniesie dla wartości n równej 10 chyba większość z czytelników potrafi policzyć sama...

Udostępnij ten post


Link to post
Share on other sites

Akurat ile publikacji w internecie tyle wersji. Jedni dzielą przez 1023, inni przez 1024. Szczerze mówiąc sam w tej chwili już "zgłupiałem" i chętnie poczytam opinie innych osób. Tutaj przykład od SparkFuna, gdzie zalecają "1023": https://learn.sparkfun.com/tutorials/analog-to-digital-conversion Na oficjalnym forum Arduino też jest dość długi wątek o tym: https://forum.arduino.cc/index.php?topic=303189.0

Udostępnij ten post


Link to post
Share on other sites

Problem polega na tym, że w internecie znajdziemy wiele sprzecznych informacji. Dlatego zaproponowałem jako "autorytet" przyjmować coś nieco bardziej naukowego.

Oczywiście pytanie można uogólnić na n-bitów, ale nawet dla naszego n=10, to nadal ciekawy problem.

Mamy przetwornik 10 bitowy, więc odczyty są z zakresu 0-1023. Ale jak należy je przeliczać?

Proponuję dla ustalenia uwagi przyjąć następujące założenia: napięcie referencyjne 5V (idealne), przetwornik 10-bitów.

Teraz jest pytanie: jaka powinna być formuła obliczania napięcia wejściowego?

Vwe = magiczna_funkcja( odczyt_z_ADC )

Na razie mamy dwa typy:

Vwe = 5.0 * odczyt_z_ADC / 1023.0 
Vwe = 5.0 * odczyt_z_ADC / 1024.0

Może są inne? No i która jest "lepsza", poprawniejsza, piękniejsza?

Udostępnij ten post


Link to post
Share on other sites

Co znaczy "poprawniejsza"? Poprawność to w tym przypadku wartość binarna, wzór albo jest poprawny albo nie.

Mamy dwa typy:

2 * 2 = 4
2 * 2 = 5

Który jest lepszy, piękniejszy i prawidłowszy?

Udostępnij ten post


Link to post
Share on other sites

Ten przetwornik ma 10 bitów więc rozróżnia 1024 przedziały napięcia, od 0/1024 do 1023/1024 jego Vref. Zatem liczba otrzymana z przetwornika nie oznacza konkretnego napięcia, ale jego przedział o szerokości Vref/1024. Nawet pierwsza z brzegu dokumentacja procesora AVR w rozdziale "ADC" podaje wzór:

ADC = (Vin * 1024) / Vref

co w prostej linii, po przekształceniu, prowadzi do współczynnika 1024.

To oznacza, że dla Vref=5V wynik ADC=1023 przeliczy się na 1023/1024*5V=4.995V, bo ADC "pokazuje" początek przedziału. Jeśli chcesz być akuratny w środku przedziału, musisz po przeliczeniu na mV dodać jeszcze połowę LSB, ale to oczywiście bez sensu bo błędy nieliniowości i zera tego bloku sumują się do 2LSB więc i tak najmłodszy bit jest raczej do kosza.

Udostępnij ten post


Link to post
Share on other sites

ethanak, przeczytaj to co napisał marek1707 - odczyt zwraca wynik z błędem oraz wartość z przedziału. Więc tutaj nie ma zero-jedynkowej logiki prawda / fałsz.

Co sprawia, że dyskusja może być tylko ciekawsza, oczywiście o ile nie zmieni się jak zwykle w gó.no-burzę.

Udostępnij ten post


Link to post
Share on other sites

Jeśli trudno to pojąć na przykładzie przetwornika 10-bitowego, to weźmy jego 2 najstarsze bity i mamy ADC 2-bitowy. Takie coś oddaje tylko 4 przedziały, dla Vref=5V są to:

00 dla 0 < Vin < 1.25V

01 dla 1.25V <= Vin < 2.5V

10 dla 2.5V <= Vin < 3.75V

11 dla 3.75V <= Vin < 5V

Oczywiście najniższy zakres rozciąga się też w dół i dostaniemy 00 gdy zapodamy na wejście np. -0.1V (nie, nic nie zepsujemy, ale już przy -1V tak). To samo w górę: Vin >= 5V daje 11 z podobnymi ograniczeniami (czyli nie przekraczamy Vcc procesora o więcej jak 0.1-0.2V).

Tutaj widać wyraźnie, że przyjęcie współczynnika 3 jest bez sensu, prawda? Przy 2 bitach wyniku przedział wynosi Vref/4 a sprawa interpretacji obliczeń jest zupełnie osobną kwestią. Dla odczytu 01 dostajemy (1/4)*5V czyli 1.25V. Znów - ADC oddał nam początek swojego przedziału. Jeśli chcemy, możemy dodawać do każdego wyniku pół LSB (czyli 0.625V) i wtedy zamiast pokazywanych na wyświetlaczu 0.00, 1.25, 2.50 i 3.75 dostaniemy 0.625, 1.875, 3.125 i 4.375 które są wycentrowane na środkach przedziałów więc błąd jest symetrycznie rozłożony po obu stornach a nie tak tendencyjny jak w przypadku pierwszego ciągu. Mi jednak bardziej podoba się proste liczenie bez offsetu LSB/2.

Udostępnij ten post


Link to post
Share on other sites

Nadrabiam już zaległości w czytaniu Waszych postów. Niedługo wprowadzę poprawki we wzorach w kursie, aby wszystko się zgadzało. Dziękuję wszystkim za "podchwycenie" tematu, a WRata gratuluję czujności, że wyłapał tę nieścisłość. Przy okazji przeszukałem jeszcze internet i tutaj jest ten temat ładnie na wykresach jeszcze pokazany: https://forum.allaboutcircuits.com/threads/why-adc-1024-is-correct-and-adc-1023-is-just-plain-wrong.80018/

Udostępnij ten post


Link to post
Share on other sites

Marek już trochę ubiegł moje kolejne dociekania - ale i tak spróbuję. Zgadzam się w zupełności, że należy dzielić/mnożyć przez 1024.

Ale wtedy jeden z końców zakresu zostaje "nieużywany". Czyli nigdy nie będziemy mieli odczytu 5V (albo nigdy 0V). Więc kolejne pytanie, czy można jakoś poprawić nasz wzór, żeby skrajne wartości uzyskać?

[ Dodano: 27-06-2018, 22:23 ]

A jeszcze wracając do "piękna" użytych wzorów - okazuje się, że mnożenie i dzielenie przez potęgi 2 jest znacznie szybsze, i to zarówno w przypadku liczb całkowitych, jak i zmienno-pozycyjnnych.

Więc nawet gdybyśmy doszli do wniosku, że współczynnik 1023 jest "lepszy", czasem warto użyć 1024 - bo i tak inne błędy mogą mieć większe znaczenie, a poświęcając nieco dokładność oszczędzamy sporo cykli procesora.

To tylko dygresja odnośnie "piękna" rozwiązań. Warto wiedzieć jakie są za i przeciw różnych opcji, stąd wydaje mi się że warto kontynuować ten wątek.

Udostępnij ten post


Link to post
Share on other sites

Nic nie zostaje "nieużywane". Każdy z 1024 zakresów dostajesz a jedynie przetwornik informuje Cię, że napięcie przekroczyło początek przedziału. Potem są już tylko przeliczenia i tak:

- możesz wyświetlać napięcie początku przedziału, czyli to co wprost wychodzi ze wzoru ADC*Vref/1024 (ale brakuje wyniku 5.00V bo ADC "zaokrągla" w dół),
- możesz wyświetlać środek przedziału po dodaniu do wyniku obliczeń LSB/2 czyli Vref/2048 (sprawiedliwe, nie ma ani 0.00V ani 5.00V a wynik ma najmniejszy błąd względem Vin),
- możesz wyświetlać koniec dodając cały LSB czyli Vref/1024 (brakuje 0.00V bo zaokrąglamy w górę przedziału)

- a możesz wyświetlać zakres od-do 🙂

Żeby mieć jednocześnie i 0.00 i 5.00 V musiałbyś mieć 1025 przedziałów, przy czym ten ostatni musiałby wychodzić poza Vref a nie mieścić się w nim jak wszystkie dotychczasowe... 🙁

BTW: Akurat mnożenie 1023*N możesz zrobić jako przesuwanie N o 10 bitów i odjęcie N, więc też nie jest takie straszne 🙂

EDIT: A w AVRach przesuwanie int-ów 16-bitowych i dłuższych jest tak żmudne, że biorąc pod uwagę dostępność szybkiego mnożenia 8x8 wcale nie jestem przekonany iż operacja << 10 jest szybsza niż *1024. Zupełnie inaczej jest w zmiennym przecinku, gdzie wystarczy zmienić cechę w ogóle bez ruszania 24-bitowej mantysy. Tam generalnie nie możesz przesuwać, bo liczba na wyjściu zawsze musi być znormalizowana.

Udostępnij ten post


Link to post
Share on other sites

Ja wiem jak to działa, ale chciałem trochę podrążyć temat, bo wydaje mi się ciekawy.

Więc teraz chciałbym popatrzeć nie jako inżynier, ale zwykły użytkownik - załóżmy że kupuję multimetr.

Jeśli nie podłączyłem zasilania, oczekiwałbym wyniku 0V. A po podłączeniu do 5V będę mocno obrażony widząc 4.995V - więc teraz pytanie inżynierskie, jak sprawić żeby użytkownik był zadowolony?

Zaokrąglanie 0.5LSB niewiele pomoże - jeśli w dół to dostaniemy 0V, ale zabraknie 5V. Jak w górę to "wiszące" przewody zwrócą 0.005V.

Dlatego wspominałem o nieco mało inżynierskim podejściu do wzorów kryteriami elegancji - jeśli rozumiemy jak działają, wiemy że zawierają wiele niedociągnięć. Z drugiej strony czasem musimy dostarczyć "produkt", który będzie używał humanista. Stąd moje pytania - czy jeden wzór jest dobry na wszystko, czy czasem lepiej wybrać inny, a jeśli tak to który i kiedy 🙂

Udostępnij ten post


Link to post
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »

×