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

Uklad pomiarowy ADC atmega , bascom -pomocy

atmeg 11 Lis 2010 17:55 3862 10
  • #1 8730782
    atmeg
    Poziom 14  
    Witam.Chce przedstawic pewien problem i poprosic was o pomoc w rozwiazaniu.Buduje urzadzenie pomiarowe , koncowym ukladem jest Atmega 8 i jego wewnetrzny przetwornik ADC .Dokonuje on pomiarow napiecia co okolo 20msek , jesli w przeciagu 0.3sek dojdzie do odchylki wartosci mierzonej o okolo 5 % lub wiecej procesor wystawia sygnal .Niby wszystko proste ale ..
    1.Napiecie mierzone plywa zwlaszcza po wlaczeniu ukladu jakies 5% na jedna minute po 10min dryf temperaturowy zmniejsza sie ale nadal
    pozostaje na poziomie okolo 2%
    2. Istnieja wachania poziomu sygnalu spowodowane miedzy innymi drganiami mechanicznymi ukladu czujnik-medium w zakresie
    okolo 5% na 5sek
    3 Pojawiaja sie co 0.2sek pojedyncze pomiary wartosci o 15% wieksze lub mniejsze od wartosci sredniej .

    Prosze o pomoc w napisaniu programu w Baskomie :) wyliczajacego srednia wartosc napiecia a dokladniej srednia wartosc dla stalej czasowej 0.3 sek , czyli wyluskaniu z tych smieci sygnalu oraz czesci programu jesli daloby rade niwelujacego wplyw dryfu temperaturowego .

    Dodam iz tani miernik wlaczony na zakresie 2V nap stalego radzi sobie z tym .
    A drugie pytanie to jakie czesci zastosowac aby zmniejszyc dryf temperaturowy i szumy , w tej chwili uklad to zwykle stabilizatory seri 78xx , dwa wzm. operacyjne seri741 kazdy pracuje na wzmocnieniu okolo 1000 z tym ze drugi dodatkowo w ukladzie filtra dolnoprzepustowego okolo 20hz.
    Z gory dziekuje za wszelkie uwagi i pomoc.
  • #3 8731927
    atmeg
    Poziom 14  
    ZbeeGin napisał:

    Czy dobrze rozumiem iz kolega wskazuje na problemy z samym przetwazaniem ADC mikroprocesora? Zbudowalem sporo ukladow i nie mialem problemow z dokladnoscia przetwarzania oczywiscie nieoczekujac zbyt wiele uklady dzialaly poprawnie .Dla przyklady wykonalem regulator temperatury 0-250 stopni uzyskujac dokladnosc 2stopnie w zakresie od 150 do 250 stopni ( ten zakres byl stosowany w piecu przemyslowym . porownywalem kilkukrotnie wskazania z termometrem labolatoryjnym) .
    Wracajac do tematu
    Obserwowalem napiecie mierzone na oscyloskopie i nie ma w nim skladowych powyzej 10hz wiec mysle ze nie chodzi w tym przypadku o bledy pomiaru lecz o odpowiedni algorytm programu umiejacy wychwycic sygnal użytkowy.Niestety niezbyt radze sobie z matematyka i stad wynika to ze nie bardzo umiem ugryzc ten problem wlasnie od strony matematycznej.

    Swoja droga Dziekuje za wskazane materialy jest tam sporo przydatnych informacji.

    Zamieszczam program , uklad dziala ale przy zbyt niskiej wartosci zmiennej Bb powstaja falszywe alarmy a zwiekszenie wartosci Bb powyzej powstawania falszywych alarmow powoduje spadek czulosci pomiaru ponizej oczekiwanej.

    
    $regfile = "m8def.dat"
    $crystal = 8000000
    Dim Aa As Word
    Dim Aa1 As Word
    Dim Aa2 As Word
    Dim Aa3 As Word
    Dim Aa4 As Word
    Dim Aa5 As Word
    Dim Aa6 As Word
    Dim A As Bit
    Dim Bb As Word
    
    Config Portb = Output
    Config Portc = Input
    
    Config Adc = Single , Prescaler = Auto , Reference = Internal
    Start Adc
    
    
    Ss:
    Aa = 0
    Aa1 = Getadc(5)
    Aa1 = Getadc(5)
    'Waitms 15
    'Aa2 = Getadc(5)
    'Waitms 15
    'Aa3 = Getadc(5)
    'Waitms 15
    'Aa4 = Getadc(5)
    'Waitms 15
    'Aa5 = Getadc(5)
    'Waitms 15
    'Aa6 = Getadc(5)
    'Waitms 15
    Aa = Aa1
    'Aa = Aa + Aa2
    'Aa = Aa + Aa3
    'Aa = Aa + Aa4
    'Aa = Aa + Aa5
    'Aa = Aa + Aa6
    'Aa = Aa / 6
    '------------------  ustawianie progu zadzialania ------------------
    If Pinc.2 = 0 Then
    
       If Aa > 500 Then
      Portb.2 = 1
      A = 1
      Else
       Portb.2 = 0
     End If
    
     Bb = Aa + 40       ' ustalenie wartosci progu pomiaru
    End If
    
    
    ' ----------- tryb pracy (wykrywanie przekroczenia progu)--------------
    
    If Pinc.2 = 1 Then
    If Aa > Bb Then
      Portb.2 = 1
      A = 1
      Else
       Portb.2 = 0
     End If
     End If
    
    
    '--------------- reset ------------------
     If Pinc.3 = 0 Then
      A = 0
     End If
     Portb.1 = A
    
    
    Waitms 100
    Goto Ss:

    Jak widac testowalem tez proste usrednianie kilku pomiarow , poprawialo to dzialanie ukladu ale nie w stopniu zadawalajacym.
  • #4 8735849
    galusz
    Poziom 15  
    Ja bym użył mniejszego precsalera (np. 4 lub nawet 2) i zrobił maksymalny oversampling (np. 256 pomiarów).
    Aby zachować stałą czasową proponowałbym zapodanie przerwania od timera.
    Np co 0.1sek i w sposób ciągły uśredniał 3 poprzednie pomiary.

    Moim zdaniem miernik działa bo ma dużą bezwładność (zapewne nawet większą niż 0.3sek) i po prostu nie widać skoków napięćia

    Co do dryfu temperaturowego to zapodaj jakiś termometr pod następny ADC i kalibruj odczytaną wartość wartością temperatury. Oczywiście współczynnik musisz dobrać sam...
  • #5 8740412
    atmeg
    Poziom 14  
    galusz napisał:

    Aby zachować stałą czasową proponowałbym zapodanie przerwania od timera.

    Co do dryfu temperaturowego to zapodaj jakiś termometr pod następny ADC i kalibruj odczytaną wartość wartością temperatury. Oczywiście współczynnik musisz dobrać sam...

    Myslalem nad podobnym rozwiazaniem - udalo mi sie uzyskac z dodatkowego ukladu
    sygnal do przerwania mikroprocesora i dalo to pozytywny efekt poprawiajac dzialanie ukladu o jakies 50% . Dopisalem tez kawalek programu usredniajacego pomiary (nie wiem jak to sie fachowo nazywa) .Kazde nowe obliczenie sredniej uwzglednia nowa prubke a ostatnią z 20 usuwa z kolejki .Bardzo ladnie gasi to zaklucenia.W sumie uzyskalem juz zadawalajace mnie parametry.
    Co do dryfu temperaturowego to sprawdze ten patent z termistorkiem i korekcja programowa ale wczesniej dopracuje sama czesc analogowa (podzespoly o mniejszym dryfie).
    Obecny kod programiku.
    
    $regfile = "m8def.dat"
    $crystal = 8000000
    Dim Aa As Word
    Dim Aa1 As Word
    Dim Aa2 As Word
    Dim Aa3 As Word
    Dim Aa4 As Word
    Dim Aa5 As Word
    Dim Aa6 As Word
    Dim Aa7 As Word
    Dim Aa8 As Word
    Dim Aa9 As Word
    Dim Aa10 As Word
    Dim Aa11 As Word
    Dim Aa12 As Word
    Dim Aa13 As Word
    Dim Aa14 As Word
    Dim Aa15 As Word
    Dim Aa16 As Word
    Dim Aa17 As Word
    Dim Aa18 As Word
    Dim Aa19 As Word
    Dim Aa20 As Word
    Dim L As Byte
    Dim A As Bit
    Dim Licz As Bit
    
    Dim Bb As Word        '  zmienna  usrednionego napiecia
    Dim Cc As Word        ' zmienna  progu alarmu
    
    Config Portb = Output
    Config Portc = Input
    
    Config Adc = Single , Prescaler = Auto , Reference = Internal
    On Int0 Pomiar:
    
    Enable Interrupts
    Enable Int0
    
    Start Adc
    
    
    
    Ss:
    If Licz = 1 Then   ' nakaz obejscia przeliczania do momentu pobrania nowej prubki
    Goto Ss10:
    End If
    
    Stop Adc                'wylonczenie przerwan na czas obliczen
    Disable Int0
    Disable Interrupts
    L = L + 1                                                   'licznik numeru prubki
    Select Case L                                               ' tablica prubek :)
        Case 1 : Aa1 = Aa
        Case 2 : Aa2 = Aa
        Case 3 : Aa3 = Aa
        Case 4 : Aa4 = Aa
        Case 5 : Aa5 = Aa
        Case 6 : Aa6 = Aa
        Case 7 : Aa7 = Aa
        Case 8 : Aa8 = Aa
        Case 9 : Aa9 = Aa
        Case 10 : Aa10 = Aa
        Case 11 : Aa11 = Aa
        Case 12 : Aa12 = Aa
        Case 13 : Aa13 = Aa
        Case 14 : Aa14 = Aa
        Case 15 : Aa15 = Aa
        Case 16 : Aa16 = Aa
        Case 17 : Aa17 = Aa
        Case 18 : Aa18 = Aa
        Case 19 : Aa19 = Aa
        Case 20 : Aa20 = Aa
      End Select
    
    'Enable Interrupts
    'Enable Int0
    'Start Adc
    
    If L = 20 Then
    L = 0
    End If
    
    Bb = Aa1
    Bb = Bb + Aa2
    Bb = Bb + Aa3
    Bb = Bb + Aa4
    Bb = Bb + Aa5
    Bb = Bb + Aa6
    Bb = Bb + Aa7
    Bb = Bb + Aa8
    Bb = Bb + Aa9
    Bb = Bb + Aa10
    Bb = Bb + Aa11
    Bb = Bb + Aa12
    Bb = Bb + Aa13
    Bb = Bb + Aa14
    Bb = Bb + Aa15
    Bb = Bb + Aa16
    Bb = Bb + Aa17
    Bb = Bb + Aa18
    Bb = Bb + Aa19
    Bb = Bb + Aa20
    Bb = Bb / 20
    Licz = 1
    
    Ss10:
    
    '--------------------  ustawianie progu i wykrycie alarmu ------------------
    If Pinc.2 = 0 Then
    
       If Bb > 500 Then
      Portb.2 = 1
      A = 1
      Else
       Portb.2 = 0
     End If
    
     Cc = Bb + 5                                                'ustawienie progu zadzialania
    End If
    
    
    
    
    If Pinc.2 = 1 Then
    If Bb > Cc Then                                             ' wykrycie przekroczenia progu
      Portb.2 = 1
      A = 1
      Else
       Portb.2 = 0
     End If
     End If
    
    
    Enable Interrupts                                           'wlaczenie przerwan
    Enable Int0
    Start Adc
    
    '--------------- reset alarmu ------------------
     If Pinc.3 = 0 Then
      A = 0
     End If
     Portb.1 = A
    
    Goto Ss:
    '------------------   przerwanie - pomiar -------------------
    Pomiar:
    'Portb.2 = 1
    Waitus 250
    'waitms 1
    Aa = Getadc(5)
    Aa = Getadc(5)
    'Waitus 200
    Licz = 0
    Return
    
  • #6 8740453
    ZbeeGin
    Poziom 39  
    Czy kolega wie, że w BASCOM Basic są tablice? Deklarujesz mnóstwo zmiennych Aa i potem jeszcze robisz ciągi operacji Bb = Bb + Aa jak można to łatwo ztablicować i robić w pętli. Tak samo SELECT CASE zamieniłoby się w prostą pętlę. Pomyśl nad tym, bo pamięć Flash nie jest rozciągliwa.
  • Pomocny post
    #7 8742221
    poorchava
    Poziom 18  
    to co kolega zrobił, to jest bufor kołowy. Takie algorytmy średniej kroczącej robi się właśnie w ten sposób, więc pomysł kolega miał dobry. W buforach kołowych operuje się na wskaźnikach, tworząc tak na prawdę listę kierunkowa. Niech sobie kolega poczyta jak to się dokładnie koduje.
  • #8 8743395
    ZbeeGin
    Poziom 39  
    Kolego, wiem jak się koduje bufor kołowy. Ale robienie tego na wielu zmiennych i w taki rozwlekły sposób nie jest poprawne, ani zgodne ze "sztuką". Tworzenie zoptymalizowanych programów jest sprawą pierwszorzędną. To nie komputer stacjonarny posiadający mnóstwo pamięci i do tego plik/partycję wymiany, tylko mały mikrokontroler.
  • #9 8743910
    arktik1
    Poziom 27  
    A ja bym użył kondensatora elektr. i opornika by uspokoić ADC.
    Zrobiłem kilka mierników i rozwiązanie daje sobie radę z uśrednianiem wyniku.
    Działa nawet idealnie w takim niestabilnym środowisku jak samochód.
  • #10 8746306
    galusz
    Poziom 15  
    Program ok, natomiast nie musisz podawać innego źródła do przerwania... Wystarczy przerwanie od skonfigurowanego wewnętrznego Timera.

    Co do kodu to ja raczej nie widzę problemu żeby rozwodzić się nad sztuką. Jeśli działa a kod jest poprawny to czy zostanie napisany na tablicy i pętli, czy na zmiennych to nie ma w sumie znaczenia. (Wiadomo kiedyś się nauczy jak zacznie pisać coś bardziej skomplikowanego).
    Mi pomogły stare czasy ZX48 i C64, jeśli chodzi o poznanie samego języka BASIC :)
  • #11 8794127
    atmeg
    Poziom 14  
    Ostanio robilem testy urzadzenia i niestety dosc wadliwie dziala czesc sondy oraz wzmacniacze sygnalu .Okazalo sie ze uklad "zbiera" zaklucenia . Musze przemyslec
    zasade dzialania sondy pomiarowej ewentualnie zmienic jej budowe .W zasadzie uklad dziala ale niestabilnie.
REKLAMA