Skocz do zawartości

Czujniki Sharpha, a oprogramowanie ich ?


BlackJack

Pomocna odpowiedź

Udało mi się wreszcie zrobić eksperymenty z moim czujnikiem Sharpa, ale nie bardzo potrafię sobie poradzić z napisaniem programu, który by wyświetlał mi dane w cm.

Znalazłem TAKĄ stronę o tych czujnikach, ale nie znam za dobrze angielskiego, więc nie rozumiem do końca wszystkiego co tam napisano.

Charakterystyka którą zdjąłem z mojego czujnika jest taka:

Jest to czujnik o zasięgu od 4 do 30cm, tylko nie wiem jak wyprowadzić końcowy wzór do obliczeń ? Konkretnie nie bardzo rozumiem skąd nagrzmocili te współczynniki w nim.

Co do języka programowania to na razie męczę to w BASCOM AVR.

Link do komentarza
Share on other sites

Możesz zrobić dwie linearyzacje, jedną od 3 do 9 cm, drugą od 9 do 30 cm, błąd będzie niewielki w stosunku do tego co masz teraz.

Albo jak się nie mylę, to będzie pasowało do jakiejś hiperboli 🙂, ale mogę się mylić.

Link do komentarza
Share on other sites

Znaczy się tę funkcję liniową wyznaczyłem w Exelu jako trend, ale jak ją przekształciłem do takiej postaci : x = (457,26 - y) / 13, 478 to i tak uzyskane wyniki były dalekie od prawidłowych ? Oczywiście wiadomo że wyniki w zakresie od 0 do 6cm będą dziwne, bo to praktycznie nie jest już zakres pracy tego czujnika, no i sam funkcja liniowa powoduje pewne błędy. Pierwotnie myślałem o aproksymacji tych 2 funkcji ale z maty to raczej mierny jestem, wiec nie wiem jak za to się zabrać ?

Ale z samego czujnika SHARPA też mam pewien problem uzyskać dobre wyniki. Uśredniam niby 8 kolejnych pomiarów, ale i talk wynik mi skacze, w przedziale liczba +/- 10 ?

Ogólnie na razie używam takiego programu:

PS. w tym programie próbowałem zastosować wzór z podanej wcześnie strony.

'SHARP 2D120X tester
$crystal = 1000000            'CPU 1MHz
$regfile = "attiny861.dat"

'konfiguracja wyświetlacza LCD
Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , E = Portb.5 , Rs = Portb.4
Config Lcd = 16 * 2
'konfiguracja portów I/O
Config Porta = Input

On Oc0a Probka


Dim Wynik As Word At &H60
Dim Ad_low As Byte At &H60 Overlay
Dim Ad_high As Byte At &H61 Overlay
Dim Temp As Word
Dim Licz_czasu As Byte
Dim Licz_probek As Byte
Dim Wolty As Single
Dim Error As Bit
Const Podstawa = 0.0049
Const Dzielnik = 13.478
Const T0_mode = &H01          ' tryb 8 bitowy z samo restartem CTC Mode
Const T0 = &H00          ' stop timera0
Const T0_time = &HFA          ' wartośc przeładowania dla Timera 0 (250)
Const Adc_start = &B11000110  ' start  ADC

'Program główny
Enable Interrupts
Enable Oc0a
Ocr0a = T0_time
Tccr0a = T0_mode
Tccr0b = T0_start
Didr0 = 1
Admux = &B00000000
Adcsra = &B10000110
Adcsrb = &H0
Adcsra = Adc_start
Licz_czasu = 0
Temp = 0
Wolty = 0
Error = 0
Cls
Lcd "2D120X TEST"
Do
 If Licz_probek > 7 Then
    Shift Temp , Right , 3
    Locate 2 , 2
    Lcd "     "
    Locate 2 , 2
    Lcd Temp
    Locate 2 , 8
    Lcd "         "
    Locate 2 , 8
    Wolty = Temp + 5
    Wolty = 2614 / Wolty
    Wolty = Wolty - 1
    Lcd Wolty
    Locate 2 , 15
    Lcd "cm"
    Licz_probek = 0
    Temp = 0
 End If
Loop

End

Probka:
  Incr Licz_czasu            ' zwieększ Licz_czasu
  If Licz_czasu > 50 Then    ' jeżeli mineło 20ms
     Licz_czasu = 0          ' zeruj licznik czasu
     If Adcsra.6 = 0 Then    ' czy konwersja zakończona ?
        Ad_low = Adcl        ' TAk odczytaj wynik i uśrednij
        Ad_high = Adch
        Temp = Temp + Wynik
        Incr Licz_probek
        Adcsra = Adc_start   ' ponowny start konwersji
     Else
        Set Error
     End If
  End If
Return
Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Używaj wielomianu wyższego rzędu, albo tablicy wyników i interpoluj pomiędzy nimi. Obie metody są dosyć proste, chociaż tablicowanie wyników sprawdza się zawsze, a wielomian niekoniecznie (zależy od rzędu i skomplikowania funkcji).

Link do komentarza
Share on other sites

Czujnik mam zasilany z płytki ZL4AVR w której siedzi ATTiny861. Ale odkłucam zasilanie, na samym czujniku przylutowalem elektrolit 100uF. Przewody z samego czujnika też splotłem na wór plecionki. Napięciem odniesienia jest napięcie zasilania, ale na PCB jest filtr z dławikiem.

Co do wzorów to próbowałm także z logrytmiczna funkcją, która jest niby bliższa oryginałowi, ale też mi to bardzo nie wychodziło.

Wielomianu nie próbowałem, bo nie bardzo wiem jak go przekształcić ?

A na tą stronę ktorą podalem ktoś z was zerkał ? Tam jest jakiś wywód o tych czujnikach i ich kalobracji, ale niestety sam sobie z tym bardzo portadzić nie umiem.

Link do komentarza
Share on other sites

Jak klikniesz ppm na wykres tego sygnału i dasz trend (mówię o MSie) to tam będziesz miał opcje wyboru trendu- kwadratowy, wielomianowy itd. Wybierz sobie trend kwadratowy. Wtedy ta funkcja trendu będzie wygląda ax^2+bx+c . Z tego co pamiętam, MS do danego zbioru wartości wyświetla możliwe trendy- bo nie każdy trend można wszędzie zastosować. Jak chcesz mogę Ci przesłać 2 króciutkie skrypty jakie miałem na pomiarach sygnałów i metrologii na laboratorium. Co prawda nie ma tam dokładnych rozwiązań, ale taka podstawowa teoria na 5stron a4.

Link do komentarza
Share on other sites

Akurat w Exelu w tym konkretnym przypadku funkcja kwadratowa nie jest dostępna.

Ale chyba najpierw spróbuję zastosować tablicowanie wyników w pamięci EEPROM i zmodyfikowany algorytm wyszukiwania.

Przeszukiwanie chcę zacząć od określenia kierunku poszukiwań względem środka tablicy, prawdopodobnie zmodyfikuję po prostu QuickSort, aby zamiast algorytmu sortującego stał się szybkim algorytmem poszukującym.. 🙂

Link do komentarza
Share on other sites

A po co Tobie to?

Robisz tablicę z wynikami co np. 100mV i teraz jak szukasz napięcia 1250mV to wiesz, że jest ono między 13 a 14 wartością w tablicy i liniowo aproksymujesz dokładny wynik. Trzy linijki kodu.

Link do komentarza
Share on other sites

MirekCz napisał

.....że jest ono między 13 a 14 wartością w tablicy i liniowo aproksymujesz dokładny wynik. Trzy linijki kodu.

Z takimi stwierdzeniami spotkałem się już kilka razy szukając odpowiedzi, tylko jakoś nikt nigdy nie chciał się podzielić tymi trzema linijkami kodu. Język mi jest obojętny nawet z C sobie poradzę.

Sądzę że faktycznie to banalny problem tylko wszędzie, używa się stwierdzeń matematycznych. lub wywodów na temat aproksymacji, a nikt tego nie potrafi pokazać na chłopski rozum.

Niestety domeną współczesnych opracowań jest, jak ja to nazywam Sudyjność, czyli wyciąganie kilometrów wzorów i dowodów matematycznych, żeby tak naprawdę poza nabiciem stron tekstu, niczego w sposób prosty i klarowny nie wyjaśnić. Dla kogoś kto jest laikiem matematycznym jak ja to bezużyteczne wywody. Dla tego np. ja osobiście lubię zbierać stare książki z przełomu lat 80/90, bo tam jeszcze zagadnienia tłumaczono po ludzku, a nie robiono często z prostych tematów, batalie matematyczne.

gohandi

Bardzo fajne opracowanie. Mam tylko pytanie jak obliczam współczynnik α to dobrze rozumiem że zapis V(Xpoczątkowe) oznacza po prostu wartość napięcia dla X początkowego w moim przypadku 4cm.

Link do komentarza
Share on other sites

Tak, V(Xpoczatkowe) oznacza napięcie jakie jest na wyjściu dla Xpoczątkowe u Ciebie dla 4cm. Czyli ok. 2.8V

Co do metody z tabelą wyników ja bym to widział tak.

Wpisujesz w tabeli pomiary dla określonych wartości napięcia. Posortowane rosnąco co np. 100mV.

Czujnik pracuje 4-30 pracuje w przedziale 0.4V do 2.8V więc będziesz miał następującą tabelę.

Dystans =   { 34 	28	 23	... 	7 	6 	6	 5 	4};
//pomiar dla 0.4V	0.5V	0.6V	{...}	2.4V	2.5V	2.6V	2.7V	2.8V
//Teraz warto sobie zrobić zmienną pomocnicza 
int Voff = 0.4 * K;
gdzie K to stała wynikająca z przetwornika (maksymalna wartość / napięcie odniesienia)
// zmienna w której przechowuje krok w jakim zmienialiśmy napięcie
int delta = 0.1*K;
//Załóżmy, że ADC to pomiar z przetwornika. W takim wypadku mamy
int indeks,waga;
float pomiar;
indeks = (ADC-Voff)/delta; //Wszystko jest w wartościach całkowitych
waga =(100* ((ADC-Voff)%delta))/delta //Reszta z dzielenia (określi nam procentowa zawartość liczb z poszczegolnych przedzialow.
//Srednia wazona.
Pomiar = (Dystans[indeks] * (100-waga) +  Dystans[indeks+1]*waga)/100
//Pomiar już jest zmienna która przechowuje nasz konkretny wymiar

Ja bym to widział mniej wiecej tak jak wyżej. Nie sprawdzałem kodu w kompilatorze ale wydaje mi się, że koncepcja jest właśnie taka.

Link do komentarza
Share on other sites

Aproksymacja liniowa na chłopski rozum działa tak: Jeżeli wiem, że pomiędzy punktami położonymi w jakiejś znanej odległości funkcja wzrasta o znaną wartość. A chcę znać wartość pomiędzy innymi punktami o znanej odległości ale nieznanej wartości funkcji to dzięki aproksymacji liniowej przewiduję,, że poszukiwana wartość funkcji będzie proporcjonalna do tej poprzedniej.

Czyli w skrócie: A/f(A) = B/f(B) => f(B) = B*f(A)/A gdzie A to jakiś argument funkcji w którym znamy wartość funkcji, f(A) to ta znana wartość, B to inny argument, a f(B) to szukana wartość funkcji dla tego argumentu

Mam nadzieję, że wystarczająco jasno mimo że jednak posłużyłem się matematycznym słownictwem dla zachowania ogólności.

Oczywiście jeśli już opanujesz tę prostą metodę, możesz dodawać jakieś bajery typu uśrednianie na podstawie większej ilości pomiarów itp

Link do komentarza
Share on other sites

Dzisiaj znalazłem czas przeprowadzić parę eksperymentów. Oparłem się na wzorze z PDfu od kolegi gohandi, aczkolwiek nieco go zmodyfikowałem i wyniki okazały sie całkiem zachęcające, dokładność nie jest może powalająca, ale powinna wystarczyć.

Ale podczas dokonywania obliczeń współczynników jest ważny to jakie faktycznie jest napięcie odniesienia, szczególnie jak jest to VCC i to jak się zaokrągla współczynniki.

Nie bez znaczenia jest także jaki przedmiot był użyty do kalibracji wyników.

Ja użyłem jak widać budzika, ale to dla tego że nic lepszego nie miałem a jednocześnie ma ciekawą budowę, bo jego ścianka jest odchylona o ok 8° od pionu.

Oryginalny wzór zmodyfikowałem do postaci Kα / ADC - (Kβ + α) czyli 1881 / ADC - 21, co daje dosyć dobrą dokładność w odległości 20cm, niestety 30 cm to już wskazania w granicy 37-40 cm. Ogólnie ciężko tą metodą uzyskać dobre wyniki w całym zakresie czujnika. Co ciekawe przy tworzeniu tabel, zawsze mi wychodziło że minimalny dystans (znaczy sie odległość dla której U czujnika jest równe MAX czyli ok 3V.) nie jest w deklarowanych 4cm, a w okolicy między 2 a 3 cm. Podobnie Maximum zasięgu czujnika to też więcej niż deklarowane 30cm, spokojnie można jeszcze wykryć obiekt znajdujący się 50, a nawet 60 cm od czujnika.

Ps. jutro jeszcze będę próbował z tym tablicowaniem, ale nie bardzo wiem jak ja zapisać, bo łatwiej mi dokonać pomiarów n-ty cm => wartość ADC, a nie jak kolega proponował pomiar co 100mV.

Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.