Picproje Elektronik Sitesi

DERLEYİCİLER => PICBasic => Konuyu başlatan: secretagent - 22 Şubat 2011, 21:30:18

Başlık: ortalama alma işlemi
Gönderen: secretagent - 22 Şubat 2011, 21:30:18
arkadaş ben dc voltmetre yapıcam fakat şu işlemi yapamadım adc yi 20 kere okuyup ortalamasını alıp sonucu göstermek istiyorum.Çünkü direk göstermek istediğimde voltmetre sürekli değişiyor sabit kalmıyor.yardımcı olabilcek varmı acaba
Başlık: Ynt: ortalama alma işlemi
Gönderen: Ankaralı - 22 Şubat 2011, 21:32:39
for i=0 to 19
toplam=toplam+adcdeğeri
next
sonuc=toplam/20

kabaca bu şekilde
Başlık: Ynt: ortalama alma işlemi
Gönderen: RcALTIN - 22 Şubat 2011, 21:33:03
Misal şöyle olabilir, okuduğunuz 20 tane veriyi bir diziye alın, diziyi büyükten küçüğe sıralayın, ilk 5 ve son 5'i atın...(yani görmezden gelin) Ortadaki 10 tanenin ortalamasını hesaplayın. Daha iyi sonuçlar alacağınızı düşünüyorum...
Başlık: Ynt: ortalama alma işlemi
Gönderen: serdararikan - 22 Şubat 2011, 21:42:15
for i=0 to 15
      ort = (ort + adcdegeri)
next
ort = ort >> 4

şeklinde hesaplayabilirsin.bu işlem diğerlerinden daha hızlı çalışacaktır.
Başlık: Ynt: ortalama alma işlemi
Gönderen: Maxim - 22 Şubat 2011, 21:57:24
Alıntı yapılan: RcALTIN - 22 Şubat 2011, 21:33:03
Misal şöyle olabilir, okuduğunuz 20 tane veriyi bir diziye alın, diziyi büyükten küçüğe sıralayın, ilk 5 ve son 5'i atın...(yani görmezden gelin) Ortadaki 10 tanenin ortalamasını hesaplayın. Daha iyi sonuçlar alacağınızı düşünüyorum...

buna bubble sort deniyor sanırım
Başlık: Ynt: ortalama alma işlemi
Gönderen: RcALTIN - 22 Şubat 2011, 23:19:49
Alıntı yapılan: Maxim - 22 Şubat 2011, 21:57:24
Alıntı yapılan: RcALTIN - 22 Şubat 2011, 21:33:03
Misal şöyle olabilir, okuduğunuz 20 tane veriyi bir diziye alın, diziyi büyükten küçüğe sıralayın, ilk 5 ve son 5'i atın...(yani görmezden gelin) Ortadaki 10 tanenin ortalamasını hesaplayın. Daha iyi sonuçlar alacağınızı düşünüyorum...

buna bubble sort deniyor sanırım

Sanırım büyükten küçüğe sıralama kısmı için evet.
http://tr.wikipedia.org/wiki/Kabarc%C4%B1k_s%C4%B1ralamas%C4%B1

arkadaşa bahsettiğim şeyin örnek kodlarınıda yazayım, tam olsun:

   //diziye öylesine 20 deger atıyorum
   int d[] = {36,1,2,4,44,7,3,7,3,9,23,43,1,24,34,23,11,72,37,15};
   int i, j, g, x = 5, toplam, ort;
   //sıralıyorum
   for (i = 0; i < sizeof(d);i++)
   {
      for(j=0; j < sizeof(d);j++)
      {
         if(d[i] > d[j])
         {
            g = d[i];
            d[i] = d[j];
            d[j] = g;
         }
      }
   }
   //başından ve sonundan x değeri kadarını yoksayıp, toplayıp ortalamalarını alıyorum
   for(i = x; i < sizeof(d) - x ; i++)
      toplam += d[i];
   ort = toplam / sizeof(d) - (x * 2);


kodları şimdi yazdım ve denemedim, diziboyutunun değişken olabileceğini düşünerek "sizeof(d)" yazdım, eğer sabitse görüldüğü yere direkt "20" yazılabilir, x değişkeni baştan ve sondan atılacak değer sayısını belirliyor...

ek: konuyu ccs c bölümünde sanıyordum, meğer basicmiş, artık mantığına bakarak uyarlarsınız...
Başlık: Ynt: ortalama alma işlemi
Gönderen: Mucit23 - 22 Şubat 2011, 23:44:16
Arkadaşlar bu trueRMS  yönteminin matematiksel adı Harmonik ortalmamı oluyor. Burada adı geçen ortalama çeşidi aritmetik ortalama oluyor galiba. Burada RMS yöntemi ile ortalma alınsa daha iyi değilmidir.
Başlık: Ynt: ortalama alma işlemi
Gönderen: serdararikan - 22 Şubat 2011, 23:55:03
Alıntı yapılan: mucit23 - 22 Şubat 2011, 23:44:16
Arkadaşlar bu trueRMS  yönteminin matematiksel adı Harmonik ortalmamı oluyor. Burada adı geçen ortalama çeşidi aritmetik ortalama oluyor galiba. Burada RMS yöntemi ile ortalma alınsa daha iyi değilmidir.

true RMS denen şey sinyalin anlık değerlerinin karelerinin ortalamasının kareköküdür.saf sinüs sinyali için RMS değer Vppx0.707 ile hesaplanabilir.Ama sinyalin formu değiştiğinde bu formül doğru değildir.bu yüzden her sinyalin gerçek etkin değerini yani RMS değerini hesaplayan ölçüm cihazlarına true  RMS ölçüm yapıyor denir.

RMS dediğimiz şeye gelince; RMS etkin değer demektir.açıklayacak olursak 10V tepe değerine sahip bir sinüs siyal ile 7.07V luk tam DC gerilim özdeş ısıtıcılara aynı sürede uygulanırsa ikiside aynı ısı enerjisini oluştururlar.
bunun anlamı 10V luk tepe gerilimine sahip sinüsün etkin değeri yani iş yapan kısmı 7.07V tur denir.
Başlık: Ynt: ortalama alma işlemi
Gönderen: secretagent - 23 Şubat 2011, 08:48:15
arkadaslar verdiğiniz cevaplar için çok saolun
Başlık: Ynt: ortalama alma işlemi
Gönderen: secretagent - 23 Şubat 2011, 09:08:59
dediğinizi yaptım ama ekranda hiçbi şekilde voltu göstermiypr ortalama alınca mikroc ile yazılmış kodu ekliyeyim belki yardımcı olursunuz.

unsigned char volt;
unsigned int volt_oku;
unsigned int i;
char *text;
long tlong,sonuc;

void main() {
  INTCON = 0;                              // Tüm kesmeler iptal edildi
  Lcd_Init(&PORTB);                        // Lcd_Init PORTB LCD için hazırlandı
  LCD_Cmd(LCD_CURSOR_OFF);                 // LCD kursör kapatıldı
  LCD_Cmd(LCD_CLEAR);                      // LCD de radtgele karekter oluşmaması için silindi

    delay_ms(500);
Lcd_Out(1,6,"ASLAN");
                                           // 1.satır6. karaktere bilgi yazıldı

  ADCON1     = 0x82;                       // ADC ayarları
  TRISA      = 0xFF;                       // PORT A  giriş yapıldı
  Delay_ms(100);
  text  = "VOLT : ";                      // BLİLGİLENDİRME TEXTleri
  while (1) {

    for(i=0;i=15;i++){
    volt_oku  =volt_oku + ADC_read(2);                // ADC 2 kanal okundu

         }
    sonuc=volt_oku/16;
    LCD_Out(2,1,text);                       //     TEXT i ekrana bas

    tlong = (long)sonuc * 3000;           // okunan volt mili volta çevriliyor
    tlong = tlong / 1022;                  // Mili volt Volta çevriliyor

    volt     = tlong / 1000;                 // X.,.. değeri atanıyor
    LCD_Chr(2,8,48+volt);                    // X değeri satır 2 8. karaktarden itibaren basılıyor

    volt = (tlong / 100)%10;             // .X,.. değeri atanıyor
    LCD_Chr_CP(48+volt);                     // X değeri satır 2 de kursörün bulunduğu yerden itibaren basılıyor



    volt = (tlong / 10) % 10;             // 0.1 volts d
    LCD_Chr_CP(48+volt);                     // satır 2 de kursörün bulunduğu yerden itibaren basılıyor
     LCD_Chr_CP('.');
    volt = tlong % 10;                    // 0.01 volt
    LCD_Chr_CP(48+volt);                     // satır 2 de kursörün bulunduğu yerden itibaren basılıyor

    LCD_Chr_CP('V');                       // elde edilen sonuca V birimi ekleniyor.

    Delay_ms(100);
    }                   // döngü kararsızlıkları için 1ms bekliyor

}
Başlık: Ynt: ortalama alma işlemi
Gönderen: secretagent - 23 Şubat 2011, 12:28:20
sorunumu çözdüm herkese teşekkürler
Başlık: Ynt: ortalama alma işlemi
Gönderen: Hattusa - 23 Şubat 2011, 16:41:38
Alıntı yapılan: RcALTIN - 22 Şubat 2011, 23:19:49
Sanırım büyükten küçüğe sıralama kısmı için evet.
http://tr.wikipedia.org/wiki/Kabarc%C4%B1k_s%C4%B1ralamas%C4%B1

arkadaşa bahsettiğim şeyin örnek kodlarınıda yazayım, tam olsun:

   //diziye öylesine 20 deger atıyorum
   int d[] = {36,1,2,4,44,7,3,7,3,9,23,43,1,24,34,23,11,72,37,15};
   int i, j, g, x = 5, toplam, ort;
   //sıralıyorum
   for (i = 0; i < sizeof(d);i++)
   {
      for(j=0; j < sizeof(d);j++)
      {
         if(d[i] > d[j])
         {
            g = d[i];
            d[i] = d[j];
            d[j] = g;
         }
      }
   }
   //başından ve sonundan x değeri kadarını yoksayıp, toplayıp ortalamalarını alıyorum
   for(i = x; i < sizeof(d) - x ; i++)
      toplam += d[i];
   ort = toplam / sizeof(d) - (x * 2);


kodları şimdi yazdım ve denemedim, diziboyutunun değişken olabileceğini düşünerek "sizeof(d)" yazdım, eğer sabitse görüldüğü yere direkt "20" yazılabilir, x değişkeni baştan ve sondan atılacak değer sayısını belirliyor...

ek: konuyu ccs c bölümünde sanıyordum, meğer basicmiş, artık mantığına bakarak uyarlarsınız...

s.a. arkadaşlar ben proton kullanıyorum, ekteki yazılım tekniği yani 20 ortalama alıp, büyükten küçüğe doğru sıralayıp, baştan ve sondaki 5 er taneyi eleyip kalanı değerlendirme şeklini bir devremde uygulamak istiyorum.
SİZDEN RİCAM;
bunu proton yazılımına göre uyarlayabilecek bir arkadaş yokmu? bu benim için önem arzediyor.
Başlık: Ynt: ortalama alma işlemi
Gönderen: picmanya - 23 Şubat 2011, 17:12:19
Alıntı yapılan: serdararikan - 22 Şubat 2011, 23:55:03
Alıntı yapılan: mucit23 - 22 Şubat 2011, 23:44:16
Arkadaşlar bu trueRMS  yönteminin matematiksel adı Harmonik ortalmamı oluyor. Burada adı geçen ortalama çeşidi aritmetik ortalama oluyor galiba. Burada RMS yöntemi ile ortalma alınsa daha iyi değilmidir.
true RMS denen şey sinyalin anlık değerlerinin karelerinin ortalamasının kareköküdür.saf sinüs sinyali için RMS değer Vppx0.707 ile hesaplanabilir.Ama sinyalin formu değiştiğinde bu formül doğru değildir.bu yüzden her sinyalin gerçek etkin değerini yani RMS değerini hesaplayan ölçüm cihazlarına true  RMS ölçüm yapıyor denir.
RMS dediğimiz şeye gelince; RMS etkin değer demektir.açıklayacak olursak 10V tepe değerine sahip bir sinüs siyal ile 7.07V luk tam DC gerilim özdeş ısıtıcılara aynı sürede uygulanırsa ikiside aynı ısı enerjisini oluştururlar.
bunun anlamı 10V luk tepe gerilimine sahip sinüsün etkin değeri yani iş yapan kısmı 7.07V tur denir.

10V tepe değerine sahip bir sinüs siyal
bu ac sinyalin frekansı nedir.
ac sinyalin frekansı farkediyormu?

birde sinyalin yalnızca 0V. ile +10V. arasında değiştiğini, salındığındığını düşünelim.
sinyal pozitif dc ama, pwm li bir dc
pwm i iş yapan=%50, iş yapmayan=%50 olarak düşünelim
işin içine orta ve yüksek frekanslar girse sonuç nasıl olur.değişirmi?

yükü yine resistans olarak düşünebiliriz.
Başlık: Ynt: ortalama alma işlemi
Gönderen: Hattusa - 23 Şubat 2011, 23:33:58
s.a.
arkadaşlar malum işlemci ile çalışıpta ADC okutması yapan arkadaşlarda her ne kadar hardware filtresi uygulasa da çoklu okuma yapıp ortalama alsada stabil bir ADC değeri yakalayamıyor. (en azından ben yakalayamadım  ;D)
yukarıda örnek kod yazmış olan RcALTIN arkadaşımızın vermiş olduğu linki incelediğimizde sıralama algoritmalarının karşılaştırılması yapılmış, ben fazla birşey anlamadım. aslında RcALTIN arkadaşımızın söylediği ve örnek yazdığı bubble sort (kabarcık ortalaması) tekniğini proton ile başarabilseydim tadından yenmezdi ya, henüz kendimizi o kadar geliştiremedik. sanırım bu işe amatör girmemizden kaynaklı...
herneyse konu ile ilgili sıralama algoritmalarının karşılaştırmasını gösteren tablo ve ilgili linki ekliyorum. bu konuda fikirlerini belirtecek arkadaşlara şimdiden teşekkür ediyorum. (biliyorum uzun uzadıya tartışmalar oldu ADC ortalaması ile ilgili yani yazılımsal filtreler ile ilgili ama ben ikna olamadım, yada kafam almadı)
bu konu ile ilgili örnek kod verecek, yöntem gösterecek arkadaşlardan yardımlarını bekliyorum.
konu ile ilgili link
http://tr.wikipedia.org/wiki/S%C4%B1ralama_algoritmas%C4%B1 (http://tr.wikipedia.org/wiki/S%C4%B1ralama_algoritmas%C4%B1)
ve tablo
[IMG]http://img511.imageshack.us/img511/4650/semmaa.jpg[/img] (http://img511.imageshack.us/i/semmaa.jpg/)

Uploaded with ImageShack.us (http://imageshack.us)
Başlık: Ynt: ortalama alma işlemi
Gönderen: t2 - 23 Şubat 2011, 23:38:41
Proton


BUBBLE_SORT:
          Repeat
            SWAP_OCCURED = 0
                               
              INDEX = 0
            Repeat
                If SAMPLE[INDEX] > SAMPLE[INDEX + 1] Then
                    SWAPTMP = SAMPLE[INDEX]
                SWAPTMP2 = ARRAY2[INDEX]
                    SAMPLE[INDEX] = SAMPLE[INDEX + 1]
                ARRAY2[INDEX] = ARRAY2[INDEX+1]
                    SAMPLE[INDEX + 1] = SWAPTMP
                ARRAY2[INDEX+1] = SWAPTMP2
                    SWAP_OCCURED = 1 
                Endif
                Inc INDEX
            Until INDEX = SAMPLES_TO_TAKE     
        Until SWAP_OCCURED = 0
        Return
Başlık: Ynt: ortalama alma işlemi
Gönderen: Hattusa - 24 Şubat 2011, 00:29:02
Alıntı yapılan: t2 - 23 Şubat 2011, 23:38:41
Proton


BUBBLE_SORT:
          Repeat
            SWAP_OCCURED = 0
                               
              INDEX = 0
            Repeat
                If SAMPLE[INDEX] > SAMPLE[INDEX + 1] Then
                    SWAPTMP = SAMPLE[INDEX]
                SWAPTMP2 = ARRAY2[INDEX]
                    SAMPLE[INDEX] = SAMPLE[INDEX + 1]
                ARRAY2[INDEX] = ARRAY2[INDEX+1]
                    SAMPLE[INDEX + 1] = SWAPTMP
                ARRAY2[INDEX+1] = SWAPTMP2
                    SWAP_OCCURED = 1 
                Endif
                Inc INDEX
            Until INDEX = SAMPLES_TO_TAKE     
        Until SWAP_OCCURED = 0
        Return


s.a. t2 ustam ilginiz için teşekkür ederim. yazmış olduğunuz kodda ADC okutmayı tanımlayan ifadeyi ve kaç adet okutacağımızı kaçını çıkaracağımızı vs anlayamadım. hocam bir daha bakabilirmisiniz. yani en azından satırların anlamlarını belirtme şansınız varmı? kusura bakmayın yaşımız geçkin anlama özürlüyüm.
Başlık: Ynt: ortalama alma işlemi
Gönderen: t2 - 24 Şubat 2011, 09:36:31
Burada ADCli bir örnek verilmiş. Akü gerilimi ölçülüyor.  Belki işinizi görür:
http://protonbasic.net/content.php/489-GPS-code-example

Başlık: Ynt: ortalama alma işlemi
Gönderen: ehliseyf - 24 Şubat 2011, 10:07:55
Standart sapma ile daha net sonuçlar alabilirsiniz.
Başlık: Ynt: ortalama alma işlemi
Gönderen: t2 - 24 Şubat 2011, 10:39:37
Nasıl alabiliriz hocam biraz anlatsana, Elimizde 1ms aralıklar ile alınmış 100 tane örnek var. standart sapma nasıl bir güzelik sağlayabilir?  Burada örneklerin başka bir değişkene bağımlığı mı analiz edilecek?.   Kel alaka gibi geldi bana. cahillğimize verin.
Başlık: Ynt: ortalama alma işlemi
Gönderen: Hattusa - 24 Şubat 2011, 12:53:28
Alıntı yapılan: t2 - 24 Şubat 2011, 09:36:31
Burada ADCli bir örnek verilmiş. Akü gerilimi ölçülüyor.  Belki işinizi görür:
http://protonbasic.net/content.php/489-GPS-code-example

t2 ustam ilginiz için teşekkür ederim. şimdi linke bakıyorum, örnek güzele benziyor, inceyeyim.
Başlık: Ynt: ortalama alma işlemi
Gönderen: Hattusa - 24 Şubat 2011, 12:58:31
Alıntı yapılan: ehliseyf - 24 Şubat 2011, 10:07:55
Standart sapma ile daha net sonuçlar alabilirsiniz.

hocam üzerinde çalıştığım bir devrede 1 ms aralıklarla yazılım aralarında adc örneklemeleri alıyorum 20 ve 50 şer adet ve ADC lerimin içerisinde pik atan yani alakasız ve yüksek değerde ADC ölçümleri var onları yazılımla atmış olursam şayet bu ve buna benzer tekniklerle devre %50 verimli çalışacak. sizin öneriniz varmıdır.
ölçümlediğim ADC leri ortalama aldırmak yani hepsini toplayıp adc toplamına bölmek işe yaramadı.
hatta
örnek olarak
ADC_sonuc = (ADC_sonuc *0.8 ) + (ADC_ornek * 0.2)
bu teknik dahi işe yaramadı
Başlık: Ynt: ortalama alma işlemi
Gönderen: Hattusa - 24 Şubat 2011, 14:40:31
s.a.
arkadaşlar bu yazılıma bir deneme yaptım, isisde kısmen çalışıyor, uygulamada sağlıklı çalışırmı bilmem, bir yerlerde eksik var ama bulamadım. birde alınan 10 örnekten baştan ve sondan 2 şer adet örneği çıkarıp kalan örneğin ortalamasını aldırma şansımız yokmu?
Device 16F877A
Xtal 4

Declare Adin_Res 10   ' Sets the number of bits in the result
Declare Adin_Tad 32_Fosc  ' Sets the ADC's clock source
Declare Adin_Stime 10   ' Allows the internal capacitors to fully charge
                                                                 
'-------------------------- LCD connection settings ------------------------
                                                                 
Declare  LCD_Type ALPHA   ' Alphanumeric LCD type
Declare  LCD_DTPin  PORTD.4   ' LCD data port
Declare  LCD_ENPin  PORTD.3   ' E line
Declare  LCD_RSPin  PORTD.2   ' RS line
Declare  LCD_Interface  4   ' 4-line or 8-line interface
Declare  LCD_CommandUs  100   ' Time to wait (in uS) between commands sent to the LCD
Declare  LCD_DataUs  50   ' Time to wait (in microseconds) between data sent to the LCD
Declare  LCD_Lines   4   ' How many lines the LCD has

ADCON1 = %10001110                                                           
'-------------------------- Ports settings ---------------------------------
   
TRISA = %00000001
PORTA = 0
TRISB = %00000000
PORTB = 0
TRISC=  %00000000
PORTC = 0
TRISD = %00000000
PORTD = 0
TRISE = %00000000
PORTE = 0


'BUBBLE SORT VARIABLES
    Symbol SaMPLeS_TO_TaKE = 10                ' numune sayısı
    Dim SwAPTmP As Word                        ' sıralama için geçici değişken
    Dim INdEX As Byte                        ' sıralamanın içine alındığı yer     
    Dim SWaP_OccUReD As Byte                ' sıralama tamamsa göster değişkeni
    Dim SaMpLE[SaMPLeS_TO_TaKE + 1] As Word ' örnekleri tutmak için oluşturulan dizi
    Dim N As Byte
    Dim SoNuC As Byte




BATTERY_LEVEL:
        For N = 0 To SaMPLeS_TO_TaKE
        SaMpLE[N] = ADIn 0
       
        DelayMS 10
    Next
    GoSub BUBBLE_SORT
    SoNuC = SwAPTmP * 0.00488
   
    Cls
    Print At 1,1, "INDEX:"
    Print At 1,7, Dec INdEX
    Print At 2,1,"SWAPTMP:"
    Print At 2,9, Dec SwAPTmP
    Print At 3,1,"SONUC:",Dec SoNuC, "  Volt"
    DelayMS 100                                                                                                                                                 
GoTo BATTERY_LEVEL

 
   
BUBBLE_SORT:
Repeat
SWaP_OccUReD = 0        ' Clear flag that indicates swap.                                 
INdEX = 0
Repeat                                            ' For each cell of the array...
If SaMpLE[INdEX] > SaMpLE[INdEX + 1] Then      ' Move larger values up.
SwAPTmP = SaMpLE[INdEX]             ' ..by swapping them.
SaMpLE[INdEX] = SaMpLE[INdEX + 1]
SaMpLE[INdEX + 1] = SwAPTmP
SWaP_OccUReD = 1  ' Set bit if swap occurred.
EndIf
Inc INdEX
Until INdEX = SaMPLeS_TO_TaKE   ' Check next cell of the array.
Until SWaP_OccUReD = 0     ' Keep sorting until no more swaps.
Return
   
    End   
   
       

(http://img19.imageshack.us/img19/5536/semai.jpg)


buda konu ile alakalı şema ve yazılım dosyası:
http://hotfile.com/dl/107150484/bc580f9/deneme.rar.html (http://hotfile.com/dl/107150484/bc580f9/deneme.rar.html)
Başlık: Ynt: ortalama alma işlemi
Gönderen: picmanya - 24 Şubat 2011, 15:24:07
bu başlığı yakından takip ediyorum.
bir adc girişini çoklu okuyup üst üste toplayıp, sonucda ortalamasını aldığımda benimde değerlerim beklediğimin dışında çıkıyor.
burda yazılan, okumada ilk 5 en küçük ve son 5 en büyük değeri hesaba katmayın mantığındaki öneriyi  uygulayacağım.

hep programdan gidilmiş adc işlemci donanımına girilmemiş.ben adc referans beslemeye bir takım filtrelemeler yaptığımda daha iyi netice aldığımı programı hiç değiştirmeden gözle görünür derecede fark ettim.bunuda opamp bölümündeki yazımda belirttim.programdan öncelikli donanım var.sorun yaşayanlar donanımına ne derecede güveniyor?donanım süper diyebilirlermi?
Başlık: Ynt: ortalama alma işlemi
Gönderen: Hattusa - 24 Şubat 2011, 15:31:12
s.a.
doanımsal olarak beslemeleri 100uF ve 100nF ve 10nF ile filtreledim. bazen 10nF fazla geliyor ama genellikle işlemciyi 100uF ve 100nF ile filtreliyorum. lcd yede 100nF takıyorum. yani +5v beslemede 2 tane 100nF 1 tane 100uF takılı, opamp girişinde yüksek geçiren filtre uyguladım yani 100uF ile sinyali alıp, 10k ile gnd ye şaseleyip veriyorum opampa, çıkışta 4k7 direnc ile 1uF cond. ve 1 tanede 1n4148 ile gnd ye şaseliyorum yani alçak geçiren filtre uygulamış oluyorum. burada hedef min. seviyede hata ile okutmak.
Başlık: Ynt: ortalama alma işlemi
Gönderen: Maxim - 24 Şubat 2011, 15:53:12
birşeyler yapmaya çalıştım ama olmadı pek

tam ortadaki örneği almak istiyoruz.

Device 16F877A
Xtal 4

Config CP_OFF, DEBUG_OFF, WRT_OFF, CPD_OFF, LVP_OFF, BODEN_ON, PWRTE_ON, WDT_OFF, XT_OSC

TRISA = %00000001
PORTA = 0
TRISB = %00000000
PORTB = 0
TRISC=  %00000000
PORTC = 0
TRISD = %00000000
PORTD = 0
TRISE = %00000000
PORTE = 0

ADCON1 = %10001110 

Declare Adin_Res 10   ' Sets the number of bits in the result
Declare Adin_Tad FRC
Declare Adin_Stime 10   ' Allows the internal capacitors to fully charge
                                                                 

Declare  LCD_DTPin  PORTD.4   ' LCD data port
Declare  LCD_ENPin  PORTD.3   ' E line
Declare  LCD_RSPin  PORTD.2   ' RS line
Declare  LCD_Interface  4   ' 4-line or 8-line interface
Declare  LCD_Lines   4   ' How many lines the LCD has
                                                       


'BUBBLE SORT VARIABLES
    Symbol SaMPLeS_TO_TaKE = 10                ' numune sayısı
    Dim SwAPTmP As Word                        ' sıralama için geçici değişken
    Dim INdEX As Byte                        ' sıralamanın içine alındığı yer     
    Dim SWaP_OccUReD As Byte                ' sıralama tamamsa göster değişkeni
    Dim SaMpLE[SaMPLeS_TO_TaKE + 1] As Word ' örnekleri tutmak için oluşturulan dizi
    Dim N As Byte
    Dim SoNuC As Byte
Symbol MIDDLE_SAMPLE = (SaMPLeS_TO_TaKE / 2) + 1 ' The middle sample of the samples taken


BATTERY_LEVEL:
        For N = 0 To SaMPLeS_TO_TaKE
        SaMpLE[N] = ADIn 0
       
        DelayMS 10
    Next
    GoSub BUBBLE_SORT
   
    SoNuC = SaMpLE[MIDDLE_SAMPLE]
    SoNuC = SoNuC * 0.00488
   
    'Cls
    Print At 1,1, "INDEX:",Dec INdEX,"  "
    Print At 2,1,"SWAPTMP:",Dec SwAPTmP,"  "
    Print At 3,1,"SONUC:",Dec SoNuC," Volt"
    DelayMS 100                                                                                                                                                 
GoTo BATTERY_LEVEL

 
   
BUBBLE_SORT:
Repeat
SWaP_OccUReD = 0        ' Clear flag that indicates swap.                                 
INdEX = 0
Repeat                                            ' For each cell of the array...
If SaMpLE[INdEX] > SaMpLE[INdEX + 1] Then      ' Move larger values up.
SwAPTmP = SaMpLE[INdEX]             ' ..by swapping them.
SaMpLE[INdEX] = SaMpLE[INdEX + 1]
SaMpLE[INdEX + 1] = SwAPTmP
SWaP_OccUReD = 1  ' Set bit if swap occurred.
EndIf
Inc INdEX
Until INdEX = SaMPLeS_TO_TaKE   ' Check next cell of the array.
Until SWaP_OccUReD = 0     ' Keep sorting until no more swaps.
Return

Başlık: Ynt: ortalama alma işlemi
Gönderen: Maxim - 24 Şubat 2011, 17:10:58
bu, bubble sort
birde median filter var onu açıklayacak kimse varmı? nasıl çalışıyor o ?
Başlık: Ynt: ortalama alma işlemi
Gönderen: Hattusa - 24 Şubat 2011, 18:46:09
Alıntı yapılan: pro-TR - 24 Şubat 2011, 14:40:31
s.a.
arkadaşlar bu yazılıma bir deneme yaptım, isisde kısmen çalışıyor, uygulamada sağlıklı çalışırmı bilmem, bir yerlerde eksik var ama bulamadım. birde alınan 10 örnekten baştan ve sondan 2 şer adet örneği çıkarıp kalan örneğin ortalamasını aldırma şansımız yokmu?
   
     

s.a.
arkadaşlar ya araştırmamda köşeli parantez içine alınan terimler en çok 255 16 bitlik işlemcilerde de 256 olabiliyormuş, bende simülasyonda neden 250 civarını geçemediğimi düşünüyordum.
acaba bunun başka bir yolu yokmu?
Başlık: Ynt: ortalama alma işlemi
Gönderen: FUNKY - 24 Şubat 2011, 20:24:48

kod gayet güzel çalışıyor.   sample[n] dizisine 0 dan 9 a kadar karışık şekilde   rakamlar girdim   0 dan 9 a  sıraladı.

[IMG]http://img121.imageshack.us/img121/7252/bubblef.jpg[/img] (http://img121.imageshack.us/i/bubblef.jpg/)

Uploaded with ImageShack.us (http://imageshack.us)



Symbol SaMPLeS_TO_TaKE = 9               ' numune sayısı
    Dim SwAPTmP As Word                        ' sıralama için geçici değişken
    Dim INdEX As Byte                        ' sıralamanın içine alındığı yer     
    Dim SWaP_OccUReD As Byte                ' sıralama tamamsa göster değişkeni
    Dim SaMpLE[SaMPLeS_TO_TaKE + 1] As Word ' örnekleri tutmak için oluşturulan dizi
    Dim N As Byte
    Dim SoNuC As Byte
    Dim sayi As Byte
    Dim a As Byte



basla:
sayi=0
  Repeat
  a =LookUp sayi ,[5,1,3,2,6,8,7,9,0,4]
  Inc sayi
  SaMpLE[N]=a                            'dizin içeriğini  sample[n] e kopyala
  Inc N
  Until sayi=10

GoSub BUBBLE_SORT
Print At 1,1,"sample:",Dec SaMpLE[0],Dec SaMpLE[1],Dec SaMpLE[2],Dec SaMpLE[3],Dec SaMpLE[4],Dec SaMpLE[5],_

                       Dec SaMpLE[6],Dec SaMpLE[7],Dec SaMpLE[8],Dec SaMpLE[9]
GoTo basla
   
BUBBLE_SORT:

Repeat
SWaP_OccUReD = 0        ' Clear flag that indicates swap.                                 
INdEX = 0
Repeat                                            ' For each cell of the array...
If SaMpLE[INdEX] > SaMpLE[INdEX + 1] Then      ' Move larger values up.
SwAPTmP = SaMpLE[INdEX]             ' ..by swapping them.
SaMpLE[INdEX] = SaMpLE[INdEX + 1]
SaMpLE[INdEX + 1] = SwAPTmP
SWaP_OccUReD = 1  ' Set bit if swap occurred.
EndIf
Inc INdEX
Until INdEX = SaMPLeS_TO_TaKE   ' Check next cell of the array.
Until SWaP_OccUReD = 0     ' Keep sorting until no more swaps.


Return
    End   
   
Başlık: Ynt: ortalama alma işlemi
Gönderen: Hattusa - 24 Şubat 2011, 21:36:28
s.a.
aşağıda 2 kanaldan adc okuması yapıyorum ADCOKU1 ve ADCOKU2 olarak bunları lookup gibi bir yere nasıl atacağım, bir türlü çözemedim. yani 10 kez okuttuğumda registerin içerisine atmalıyımki bubble sort1 ve bubble sort2 de büyükten küçüğe sıralatabileyim. bu şekliyle adc değerlerini atacağım noktayı belkirtemediğim için derleyici hata veriyor. çözüm için önerilerinizi bekliyorum arkadaşlar

Alıntı YapDevice 16F877A
Xtal 4

Declare Adin_Res 10   ' Sets the number of bits in the result
Declare Adin_Tad 32_Fosc  ' Sets the ADC's clock source
Declare Adin_Stime 10   ' Allows the internal capacitors to fully charge
                                                                 
'-------------------------- LCD connection settings ------------------------
                                                                 
Declare  LCD_Type ALPHA   ' Alphanumeric LCD type
Declare  LCD_DTPin  PORTD.4   ' LCD data port
Declare  LCD_ENPin  PORTD.3   ' E line
Declare  LCD_RSPin  PORTD.2   ' RS line
Declare  LCD_Interface  4   ' 4-line or 8-line interface
Declare  LCD_CommandUs  100   ' Time to wait (in uS) between commands sent to the LCD
Declare  LCD_DataUs  50   ' Time to wait (in microseconds) between data sent to the LCD
Declare  LCD_Lines   4   ' How many lines the LCD has

ADCON1 = %10000010                                                           
'-------------------------- Ports settings ---------------------------------
   
TRISA = %00011111
PORTA = 0
TRISB = %00000000
PORTB = 0
TRISC=  %00000000
PORTC = 0
TRISD = %00000000
PORTD = 0
TRISE = %00000000
PORTE = 0

Symbol fR = PORTE.0
Symbol OrNk1 = PORTE.1
Symbol oRnK2 = PORTE.2

Dim PaLs As Word
Dim fReK As Word
Dim OrNeK1 As Word
Dim oRnEk2 As Word

PaLs = 500
fReK = 8000
OrNeK1 = 200
oRnEk2 = 50

'-------------------BUBBLE SORT DEĞİŞKENLERİ--------------------------
Symbol NuMuNeSaY1 = 10
Symbol nUmUnEsAy2 = 10
Dim gDegIsKeNa As Word
Dim GdEgIsKeNb As Word
Dim nDeX1 As Byte
Dim NdEx2 As Byte
Dim AdCoKu1 As Word
Dim aDcOkU2 As Word
Dim StAmAm1 As Byte
Dim sTaMaM2 As Byte
Dim SaMpLe1[NuMuNeSaY1 + 1] As Word
Dim sAmPlE2[nUmUnEsAy2 + 1] As Word
Dim N1 As Byte
Dim N2 As Byte
Dim X As Byte



AyArT:
GoSub TARAMA
GoSub BUBBLE_SORTA
GoSub BUBBLE_SORTB

Cls
Print At 1,1, Dec SaMpLe1[X]
Print At 2,1, Dec AdCoKu1
Print At 3,1, Dec X
DelayMS 10
GoTo AyArT

TARAMA:
X = 0

Repeat
fR = 1
DelayUS 500
fR = 0
DelayUS 200
OrNk1 = 1
DelayUS 5
AdCoKu1[N1) = ADIn 1    '1 adc okuması'bu KISIMLARDA HATA VERİYOR
DelayUS 5
OrNk1 = 0
DelayUS 50
oRnK2 = 1
DelayUS 5
aDcOkU2[N2] = ADIn 4  '2 adc okuması 'BU KISIMLARDA HATA VERİYOR
DelayUS 5
oRnK2 = 0
DelayUS 8000


Inc N1
Inc N2

Until X = 10

Return

BUBBLE_SORTA:
Repeat           
StAmAm1 = 0                                             
nDeX1 = 0           
Repeat               
If SaMpLe1[nDeX1] > SaMpLe1[nDeX1 + 1] Then                   
gDegIsKeNa = SaMpLe1[nDeX1]               
SaMpLe1[nDeX1] = SaMpLe1[nDeX1 + 1] 
SaMpLe1[nDeX1] = gDegIsKeNa                 
StAmAm1 = 1                 
EndIf               
Inc nDeX1           
Until nDeX1 = NuMuNeSaY1             
Until gDegIsKeNa = 0         
Return

BUBBLE_SORTB:
Repeat           
sTaMaM2 = 0                                             
NdEx2 = 0           
Repeat               
If sAmPlE2[NdEx2] > sAmPlE2[NdEx2 + 1] Then                   
GdEgIsKeNb = sAmPlE2[NdEx2]               
sAmPlE2[NdEx2] = sAmPlE2[NdEx2 + 1] 
sAmPlE2[NdEx2] = GdEgIsKeNb                 
sTaMaM2 = 1                 
EndIf               
Inc NdEx2           
Until NdEx2 = nUmUnEsAy2             
Until GdEgIsKeNb = 0         
Return

Başlık: Ynt: ortalama alma işlemi
Gönderen: Hattusa - 24 Şubat 2011, 21:39:14
Alıntı yapılan: FUNKY - 24 Şubat 2011, 20:24:48

kod gayet güzel çalışıyor.   sample[n] dizisine 0 dan 9 a kadar karışık şekilde   rakamlar girdim   0 dan 9 a  sıraladı.

   

s.a. hocam lookup dizinine atılan değer adc değeri olarak belirleyebilirmiyiz. yani değişken atayabilirmiyiz. birde lookup sanırım 8 bitte 255 e kadar müsade veriyor, yani bu 8 bit demek mi oluyor yani 5v/256 gibi ;D ya kafam durdu saçmalamaya başladım...
Başlık: Ynt: ortalama alma işlemi
Gönderen: Hattusa - 24 Şubat 2011, 21:52:11
bu şekilde derleyebildim ama isisde lcd ye görüntü gelmiyor ve isisde hata veriyor

Device 16F877A
Xtal 4

Declare Adin_Res 10   ' Sets the number of bits in the result
Declare Adin_Tad 32_Fosc  ' Sets the ADC's clock source
Declare Adin_Stime 10   ' Allows the internal capacitors to fully charge
                                                                 
'-------------------------- LCD connection settings ------------------------
                                                                 
Declare  LCD_Type ALPHA   ' Alphanumeric LCD type
Declare  LCD_DTPin  PORTD.4   ' LCD data port
Declare  LCD_ENPin  PORTD.3   ' E line
Declare  LCD_RSPin  PORTD.2   ' RS line
Declare  LCD_Interface  4   ' 4-line or 8-line interface
Declare  LCD_CommandUs  100   ' Time to wait (in uS) between commands sent to the LCD
Declare  LCD_DataUs  50   ' Time to wait (in microseconds) between data sent to the LCD
Declare  LCD_Lines   4   ' How many lines the LCD has

ADCON1 = %10000010                                                           
'-------------------------- Ports settings ---------------------------------
   
TRISA = %00011111
PORTA = 0
TRISB = %00000000
PORTB = 0
TRISC=  %00000000
PORTC = 0
TRISD = %00000000
PORTD = 0
TRISE = %00000000
PORTE = 0

Symbol fR = PORTE.0
Symbol OrNk1 = PORTE.1
Symbol oRnK2 = PORTE.2

'-------------------BUBBLE SORT DEĞİŞKENLERİ--------------------------
Symbol NuMuNeSaY1 = 10
Symbol nUmUnEsAy2 = 10
Dim gDegIsKeNa As Word
Dim GdEgIsKeNb As Word
Dim nDeX1 As Byte
Dim NdEx2 As Byte
Dim AdCoKu1 As Word
Dim aDcOkU2 As Word
Dim StAmAm1 As Byte
Dim sTaMaM2 As Byte
Dim SaMpLe1[NuMuNeSaY1 + 1] As Word
Dim sAmPlE2[nUmUnEsAy2 + 1] As Word
Dim N1 As Byte
Dim N2 As Byte
Dim X As Byte



AyArT:
GoSub TARAMA
GoSub BUBBLE_SORTA
GoSub BUBBLE_SORTB

Cls
Print At 1,1, Dec SaMpLe1[N1]
Print At 2,1, Dec sAmPlE2[N2]
Print At 3,1, Dec X
DelayMS 10
GoTo AyArT

TARAMA:
X = 1

Repeat
fR = 1
DelayUS 500
fR = 0
DelayUS 200
OrNk1 = 1
DelayUS 5
SaMpLe1[N1] = ADIn 1    '1 adc okuması
DelayUS 5
OrNk1 = 0
DelayUS 50
oRnK2 = 1
DelayUS 5
sAmPlE2[N2] = ADIn 4  '2 adc okuması
DelayUS 5
oRnK2 = 0
DelayUS 8000


Inc N1
Inc N2

Until X = 10

Return

BUBBLE_SORTA:
Repeat           
StAmAm1 = 0                                             
nDeX1 = 0           
Repeat               
If SaMpLe1[nDeX1] > SaMpLe1[nDeX1 + 1] Then                   
gDegIsKeNa = SaMpLe1[nDeX1]               
SaMpLe1[nDeX1] = SaMpLe1[nDeX1 + 1] 
SaMpLe1[nDeX1] = gDegIsKeNa                 
StAmAm1 = 1                 
EndIf               
Inc nDeX1           
Until nDeX1 = NuMuNeSaY1             
Until gDegIsKeNa = 0         
Return

BUBBLE_SORTB:
Repeat           
sTaMaM2 = 0                                             
NdEx2 = 0           
Repeat               
If sAmPlE2[NdEx2] > sAmPlE2[NdEx2 + 1] Then                   
GdEgIsKeNb = sAmPlE2[NdEx2]               
sAmPlE2[NdEx2] = sAmPlE2[NdEx2 + 1] 
sAmPlE2[NdEx2] = GdEgIsKeNb                 
sTaMaM2 = 1                 
EndIf               
Inc NdEx2           
Until NdEx2 = nUmUnEsAy2             
Until GdEgIsKeNb = 0         
Return


Başlık: Ynt: ortalama alma işlemi
Gönderen: muhittin_kaplan - 24 Şubat 2011, 21:58:07
Unutulan Geçmiş Yöntemi
saygıdeğer Melih Karakelle nin bana anlattığı bir yöntem

Alıntı YapEvet benzer sebeplerden ben de başlayıp pek çok kez vazgeçtim.
Mikroişlemciye Kalman yaptıracağım diye float değişken hesaplatıp sonra da yeterli ölçüm sıklığına ulaşamadığın için kalmansız durumdan beter olmak var işin ucunda 

Benim yöntem çok basit, bilgisayar programcısının can simididir unutulan değişken filtresi, hayat boyu binlerce yerde kullanmışımdır heralde.

Yöntem şöyle;

int X[10]; // bu array değişkenimiz olsun

yeniX = sensör_verisi; // bu da okuduğumuz değer olsun

for (i=0;i<9;i++) // 9 kere döngüyü döndürelim
{
j = 8 - i; //8 den 0 e doğru geriye saydıralım
X[j+1] = X[j] ; // Her seferinde eski X[j] değerini bir eskisinin yerine taşıyalım
}

veya aynı for işleminin daha az işlemci yükü gerektireni
X[9] = X[8];
X[8] = X[7];
X[7] = X[6];
X[6] = X[5];
X[5] = X[4];
X[4] = X[3];
X[3] = X[2];
X[2] = X[1];
X[1] = X[0];

Böylece her değişkeni bir alta taşıdık (bunun daha farklı yolu da var ama bu anlatılması en kolayı)

X[0] = yeniX ; // böylece ilk değer son sensör verisi oldu

OrtalamaX = SUM(X) / 10; // tüm X değerlerini toplayıp 10 a bölüyoruz.

ve elimizde en son 10 değerin ortalaması ile elde edilmiş OrtalamaX değeri kalıyor


Yöntem bukadar basit, bu yöntemin en büyük avantajı işlemci yükünün minimum olmasında, yukarıdaki halinden daha fazla optimize etmek de mümkün ve bu hali ile saniyede binlerce kez ölçüm alıp işlemeni mümkün kıldığı için en önemli sorun olan sensör parazitlerini ve titreşimi de gidermek çok kolay oluyor.

Ayrıca sensör çıkışında lowpass filtre kullanırsan bu tip yazılımsal taklaları daha da azaltman mümkün. Ben çıkışlarda 100kOhm direnç ve 100nF kondansatör kullanıyorum, çıkış sinyalini oldukça iyi yumşatıyor (30hz civarında) , eğer daha yavaş ve yumuşak sinyaller istersen 1 megaohm direnç kullan.
Hiçbir yazılımsal filtre gerçek bir kondansatör ve dirençten daha güzel sinyal yumşatamaz, bu yüzden analog sensörler hala dijitallerden daha kullanışlı.
Başlık: Ynt: ortalama alma işlemi
Gönderen: Hattusa - 24 Şubat 2011, 22:12:16
muhiddin hocam verdiğiniz bilgiler için teşekkür ederim.
söylediğiniz tekniği emin olun deneyeceğim. benim sorunum 10 kez okuttuğum ADC değerinde pik atan (amiyane deyim sanırım) adc ölçümlerini hesaplamadan çıkartmak, yani 10 tane ADC okutma sonucum,
(100,101,99,110,108,200,96,250,102,105) işte 10 tanede benim ortalama aldırdığım sonuçtan 2 sini hiç hesaba katmamak, sanırım bu iş söylemek kolay yapmak zor... ;D
Başlık: Ynt: ortalama alma işlemi
Gönderen: pcb - 24 Şubat 2011, 23:03:45
@TR_PRO
bence aritmetik ortalama, filtre vs. ile sinyali düzeltmek yerine, böyle spike ların oluşduğu çıkış ile uğraşmak daha önemli bence.
sonuç değer kısa sürede tepki vermesi gereken başka bir sinyali tetiklemesi gerekiyorsa 10-20 kere ortalama aldırmaktan vazgeçecek ve bozuk sinyal çıkış kaynağına tekrar döneceksiniz.
Toplam zaman kaybı , sample aldığınız noktaların tekrarlama (frekans) süresinin toplamı ile alakalı. Hareket halinde veya 50-60hz parazit yüklü bir sinyalle uğraşıyorsunuz sanırım.
50-60hz parazit elimine edici adc ler var piyasada. incelemenizi tavsiye ederim.

Projeniz hakkında hiç bir fikrim yok ve diğer sayfalardaki yazıları okumadım, benimki sadece bir tavsiye
Başlık: Ynt: ortalama alma işlemi
Gönderen: Hattusa - 24 Şubat 2011, 23:10:28
Alıntı yapılan: pcb - 24 Şubat 2011, 23:03:45
@TR_PRO
bence aritmetik ortalama, filtre vs. ile sinyali düzeltmek yerine, böyle spike ların oluşduğu çıkış ile uğraşmak daha önemli bence.
sonuç değer kısa sürede tepki vermesi gereken başka bir sinyali tetiklemesi gerekiyorsa 10-20 kere ortalama aldırmaktan vazgeçecek ve bozuk sinyal çıkış kaynağına tekrar döneceksiniz.
Toplam zaman kaybı , sample aldığınız noktaların tekrarlama (frekans) süresinin toplamı ile alakalı. Hareket halinde veya 50-60hz parazit yüklü bir sinyalle uğraşıyorsunuz sanırım.
50-60hz parazit elimine edici adc ler var piyasada. incelemenizi tavsiye ederim.

Projeniz hakkında hiç bir fikrim yok ve diğer sayfalardaki yazıları okumadım, benimki sadece bir tavsiye

ustam bunlarla ilgili örnek bir entegre verebilirmisiniz, çalıştığım frekans 100 hertz ve ben bu 100 hertzlik kare dalga sinyalden her pals bitiminde 2 farklı adc okutuyorum. ve bu işlemi 10 ile 20 kez yapıyorum ortalamasını aldırıyorum. sonuçtan memnun değilim. zira 8 bit ADC de sorun yok, 10 bit ADC biraz artıyor, 12 bit ADC de dahada artacak, belki 24 bite yükseldiğimizde nasıl stabileştireceğim?
Başlık: Ynt: ortalama alma işlemi
Gönderen: pcb - 24 Şubat 2011, 23:52:12
10 bit çok hassas okumalar için yeterli bence daha yüksek çözünürlüklerde okumalar içinden çıkılmaz sonuçlar oluşturabilir.
sözünü ettiğim 50-60hz parazit elimine edici ADC ler 50-60hz de 1 kere okuma yapıyor ve delta-sigma adc olarak bilinir, tabi bu ADC lerin sample alma hızları değiştirilebliyor. sadece 50-60hz de okuma yapma durumu malum sürekli aynı noktayı okuduğundan parazitin değerinide hep aynı görüyor yani o noktadaki değeri.

Max11040 diye bir ADC var muhteşem bir ürün ama pahallı biraz, 1 mikrosaniye aralıklarla 3-4 okuma yapabiliyor bu süre daha uzatılabiliyor. delta sigma özelliği yok ama 1 mikrosaniye aralıklı okumanın birbirine çok yakın olması gerekli buradan çözüme ulaşılabilir.
LTC2480 delta-sigma ADC dir parazit önleyici özelliği var. Tabi siz 100hz frekansınızı 50-60hz e düşürmeniz gerekiyor.
Veya şöyle olabilir, siz çalışma frekansınızı 100hz değilde 120 hz e yükseltirseniz 60hz paraziti engelleyebilirsiniz ama 2 pals da bir okuma yaparak bu sabit değeri koruyabilirsiniz.
Delta sigma adc diye arama yapın onlarca bulacaksınız.
kolay gelsin
Başlık: Ynt: ortalama alma işlemi
Gönderen: Hattusa - 26 Şubat 2011, 11:24:57
Alıntı yapılan: muhittin_kaplan - 24 Şubat 2011, 21:58:07
Unutulan Geçmiş Yöntemi
saygıdeğer Melih Karakelle nin bana anlattığı bir yöntem

Alıntı YapEvet benzer sebeplerden ben de başlayıp pek çok kez vazgeçtim.
Mikroişlemciye Kalman yaptıracağım diye float değişken hesaplatıp sonra da yeterli ölçüm sıklığına ulaşamadığın için kalmansız durumdan beter olmak var işin ucunda 

Benim yöntem çok basit, bilgisayar programcısının can simididir unutulan değişken filtresi, hayat boyu binlerce yerde kullanmışımdır heralde.

Yöntem şöyle;

int X[10]; // bu array değişkenimiz olsun

yeniX = sensör_verisi; // bu da okuduğumuz değer olsun

for (i=0;i<9;i++) // 9 kere döngüyü döndürelim
{
j = 8 - i; //8 den 0 e doğru geriye saydıralım
X[j+1] = X[j] ; // Her seferinde eski X[j] değerini bir eskisinin yerine taşıyalım
}

veya aynı for işleminin daha az işlemci yükü gerektireni
X[9] = X[8];
X[8] = X[7];
X[7] = X[6];
X[6] = X[5];
X[5] = X[4];
X[4] = X[3];
X[3] = X[2];
X[2] = X[1];
X[1] = X[0];

Böylece her değişkeni bir alta taşıdık (bunun daha farklı yolu da var ama bu anlatılması en kolayı)

X[0] = yeniX ; // böylece ilk değer son sensör verisi oldu

OrtalamaX = SUM(X) / 10; // tüm X değerlerini toplayıp 10 a bölüyoruz.

ve elimizde en son 10 değerin ortalaması ile elde edilmiş OrtalamaX değeri kalıyor


Yöntem bukadar basit, bu yöntemin en büyük avantajı işlemci yükünün minimum olmasında, yukarıdaki halinden daha fazla optimize etmek de mümkün ve bu hali ile saniyede binlerce kez ölçüm alıp işlemeni mümkün kıldığı için en önemli sorun olan sensör parazitlerini ve titreşimi de gidermek çok kolay oluyor.

Ayrıca sensör çıkışında lowpass filtre kullanırsan bu tip yazılımsal taklaları daha da azaltman mümkün. Ben çıkışlarda 100kOhm direnç ve 100nF kondansatör kullanıyorum, çıkış sinyalini oldukça iyi yumşatıyor (30hz civarında) , eğer daha yavaş ve yumuşak sinyaller istersen 1 megaohm direnç kullan.
Hiçbir yazılımsal filtre gerçek bir kondansatör ve dirençten daha güzel sinyal yumşatamaz, bu yüzden analog sensörler hala dijitallerden daha kullanışlı.

s.a.
Muhiddin hocam "UNUTULAN GEÇMİŞ" işlemini anlayamadım, yani bu teknik ile nasıl bir filtreleme oluyor. yani örnek olarak elimde 10 tane ADC ölçümü var diyelim bunlar;
A0= 200
A1= 500
A2= 210
A3= 190
A4= 205
A5= 450
A6= 195
A7= 202
A8= 212
A9= 300

burda elimdeki değerlerde sorun olduktan sonra A1 ile A0 ın yerinin değişiminin filtreleme işleminde ne gibi bir faydası olacak, bu konuda bilgisi olan arkadaşların önerilerini bekliyorum.
Başlık: Ynt: ortalama alma işlemi
Gönderen: Hattusa - 26 Şubat 2011, 11:32:46
Alıntı Yap
TARAMA:
X = 1
Repeat
fR = 1
DelayUS 500
fR = 0
DelayUS 200
OrNk1 = 1
DelayUS 5
SaMpLe1 = ADIn 1    '1 adc okuması
DelayUS 5
OrNk1 = 0
DelayUS 50
oRnK2 = 1
DelayUS 5
sAmPlE2 = ADIn 4  '2 adc okuması
DelayUS 5
oRnK2 = 0
DelayUS 8000
'ben buraya repeat komutu  oluşturduğum 10 turluk döngüde her turda okuttuğum ADC değerlerini registerlerin içerisine 'kaydedemiyorum.
Until X = 10
Return
'ben buraya repeat komutu  oluşturduğum 10 turluk döngüde her turda okuttuğum ADC değerlerini Sample1[x1],sample1[x2],sample1[x3]........sample1[x10] aynı şekild sample2 değerlerini registerlerin içerisine kaydedemiyorum.  
bana bu konuda yardımcı olmanızı bekliyorum.
Başlık: Ynt: ortalama alma işlemi
Gönderen: muhittin_kaplan - 26 Şubat 2011, 13:22:33
Hocam Kodla değilde mümkün olduğunca mantığını anlatmaya çalışayım. (kodlar hatalıdır not defterinde yazıyorum)
siz 10 adet kayıtı bir değişkene atmak istiyorsunuz sanırım

dim Okunan_1[10] as byte        ;Değişken Tanımla
dim Okunan_2[10] as byte        ;Değişken Tanımla
dim Loop as byte

Oku:
      for loop=0 to 9
         okunan_1[Loop]=adin 0
         delayms 100
         okunan_2[Loop]=adin 1
         delays 100
      next


Yaparak her kanalın okuduğu 10 değeri, 10 adet derinliğindeki değişkene atarsın..

     
     
Başlık: Ynt: ortalama alma işlemi
Gönderen: Hattusa - 26 Şubat 2011, 15:20:30
Alıntı yapılan: muhittin_kaplan - 26 Şubat 2011, 13:22:33
Hocam Kodla değilde mümkün olduğunca mantığını anlatmaya çalışayım. (kodlar hatalıdır not defterinde yazıyorum)
siz 10 adet kayıtı bir değişkene atmak istiyorsunuz sanırım

dim Okunan_1[10] as byte        ;Değişken Tanımla
dim Okunan_2[10] as byte        ;Değişken Tanımla
dim Loop as byte

Oku:
      for loop=0 to 9
         okunan_1[Loop]=adin 0
         delayms 100
         okunan_2[Loop]=adin 1
         delays 100
      next


Yaparak her kanalın okuduğu 10 değeri, 10 adet derinliğindeki değişkene atarsın..

     
     

peki hocam benim anlamadığım, okunan_1 ve okunan_2  bunlar ADC değerleri ise byte boyundan büyük değil mi? yani 10 bit ADC değerimiz 1023 değerinde.
birde LCD ye bu değerleri basmak istersem mesela adin 0' ın 5. sırada okunan değerini bunu nasıl tanımlamalıyım? yani
print at 1,1,dec okunan_1[5] dediğimde hata veriyor?  ;D
sanırım bu kısmı karıştırdım ya hadi hayırlısı...
Başlık: Ynt: ortalama alma işlemi
Gönderen: muhittin_kaplan - 26 Şubat 2011, 22:01:59
pek tabiki hocam 10bit se word olmalı.
Aşağıdaki kodları derliyor.

Basla:
        For Loop=0 To 9
            Okunan_1[Loop]=loop*100
            DelayMS 100
            Print At 1,1,Dec Okunan_1[Loop]
        Next
        GoTo Basla
        Stop
Başlık: Ynt: ortalama alma işlemi
Gönderen: frederic - 03 Ağustos 2014, 17:07:01
Merhaba aşağıdaki kodu değiştirip denedim, x değeri 5 olduğunda 251 gibi alakasız bir ortalama veriyor fakat x değerini 0 yapınca ortalama değer olarak 10 değerini veriyor, yani doğru değeri veriyor. X değeri baştan ve sondan bir takım değerleri atmak için tasarlanmış konunun başında anlaşılacağı üzere, 251 değeri gibi alakasız bir değeri neden üretiyor acaba?


#include <18F46K22.h>
#device ADC=10

#FUSES INTRC_IO
#FUSES NOMCLR

#use delay(internal=16000000)

#include <4x20LCD.c>


int d[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
int i, j, g, x = 5, toplam, ort;

void main()

   
   
   setup_adc (adc_off);
   setup_adc_ports (no_analogs);
   lcd_init();

    //diziye öylesine 20 deger atıyorum
   
   //sıralıyorum
   for (i = 0; i < sizeof(d);i++)
   {
      for(j=0; j < sizeof(d);j++)
      {
         if(d[i] > d[j])
         {
            g = d[i];
            d[i] = d[j];
            d[j] = g;
         }
      }
   }
   //başından ve sonundan x değeri kadarını yoksayıp, toplayıp ortalamalarını alıyorum
   for(i = x; i < sizeof(d) - x ; i++)
      toplam += d[i];
   ort = toplam / sizeof(d) - (x * 2);
   
   lcd_gotoxy(1,1);
    printf(lcd_putc,"value    W=%u       ",ort);
   


}
Başlık: Ynt: ortalama alma işlemi
Gönderen: kantirici - 04 Ağustos 2014, 20:42:37
Alıntı yapılan: pro-TR - 24 Şubat 2011, 22:12:16
muhiddin hocam verdiğiniz bilgiler için teşekkür ederim.
söylediğiniz tekniği emin olun deneyeceğim. benim sorunum 10 kez okuttuğum ADC değerinde pik atan (amiyane deyim sanırım) adc ölçümlerini hesaplamadan çıkartmak, yani 10 tane ADC okutma sonucum,
(100,101,99,110,108,200,96,250,102,105) işte 10 tanede benim ortalama aldırdığım sonuçtan 2 sini hiç hesaba katmamak, sanırım bu iş söylemek kolay yapmak zor... ;D

Bu pik değerini neyi referans alıp atacaksın peki. 110 değeri neye göre pik değer sayılmalı ?
Başlık: Ynt: ortalama alma işlemi
Gönderen: aliveli - 04 Ağustos 2014, 22:01:33
@RcALTIN dediği radial olypic ve oldukça faydalıdır. alınan ölçümlerden en düşük ve en yüksek değerleri pik kabul edip hesaplamadan çıkarır. aşağıdaki kod c içindir basic için fikir verebilir. basic diline çeviren olursa başkasına da faydalı olacaktır.

//16 kere adcden okuma yapılır, değerler sıralanır, alttaki ve üstteki dört değer çıkarılır,ortadaki 8 değerin ortalaması alınır
unsigned int16 adchlx(void){ 

unsigned int8 i;  unsigned int16 accum=0; 
unsigned int16 s, b[16]; int1 didswap=1;

//bu döngü 16 kere okuma yapar ve b[] dizisine yerleştirir
   for ( i = 0 ; i < 16;  i++ ) {
           b[i]= read_adc(ADC_start_and_read); // ADC okunur diziye  atılır
           delay_us(8); 
     }

// bubble sort algoritması b[] dizisindeki elemanlar küçükten büyüğe sıralanır.
   while(didswap){ 
     didswap=0;
     for (i=0; i<15; i++){ // i 0-15
      if(b[(i)]>b[(i+1)]){ // eğer değer sonrakinden büyükse sırayı değiştir
           s=b[i]; // yükseği tut
           b[i]=b[(1+i)];
           b[(1+i)]=s;
           didswap=1; // yer değiştirme işi bitince döngüden çıkartır duruma göre işlemi kısaltabilir
      } // ~if
     } // ~for
    } // ~while

   //elemanları sıralanan  b[] dizisinde ortadaki 8 değerin ortalaması alınır.
   for (i=4; i<12; i++){  accum +=b[i];  }
   return(accum>>3);
}



burada verilen 16 , 4 değerleri isteğe göre artırılıp azaltılabilir.

Başlık: Ynt: ortalama alma işlemi
Gönderen: Mr.Java - 04 Ağustos 2014, 22:30:49
Diziyi sıralama algoritması geliştirilebilir.Hız faktörü hesaplanıp daha stabil programlar yazılabilir.Aşağıdaki kod yol gösterebilir.

#include<stdio.h>
#include<conio.h>

void quick_sort(int arr[20], int, int);

void main()
{
int arr[20], n, i;
clrscr();
printf("Enter the number of elements in the Array: ");
scanf("%d", &n);
printf("\nEnter %d elements:\n\n", n);

for (i = 0; i < n; i++) {
printf(" Array[%d] = ", i);
scanf("%d", &arr[i]);
}

quick_sort(arr, 0, n - 1);
printf("\nThe Sorted Array is:\n\n");

for (i = 0; i < n; i++) {
printf(" %4d", arr[i]);
}
getch();
}

void quick_sort(int arr[20], int low, int high)
{
int pivot, j, temp, i;
if (low < high) {
pivot = low;
i = low;
j = high;

while (i < j) {
while ((arr[i] <= arr[pivot])&&(i < high)) {
i++;
}

while (arr[j] > arr[pivot]) {
j--;
}

if (i < j) {
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}

temp = arr[pivot];
arr[pivot] = arr[j];
arr[j] = temp;
quick_sort(arr, low, j - 1);
quick_sort(arr, j + 1, high);
}
}
Başlık: Ynt: ortalama alma işlemi
Gönderen: frederic - 05 Ağustos 2014, 00:01:15
Alıntı yapılan: aliveli - 04 Ağustos 2014, 22:01:33
@RcALTIN dediği radial olypic ve oldukça faydalıdır. alınan ölçümlerden en düşük ve en yüksek değerleri pik kabul edip hesaplamadan çıkarır. aşağıdaki kod c içindir basic için fikir verebilir. basic diline çeviren olursa başkasına da faydalı olacaktır.

//16 kere adcden okuma yapılır, değerler sıralanır, alttaki ve üstteki dört değer çıkarılır,ortadaki 8 değerin ortalaması alınır
unsigned int16 adchlx(void){ 

unsigned int8 i;  unsigned int16 accum=0; 
unsigned int16 s, b[16]; int1 didswap=1;

//bu döngü 16 kere okuma yapar ve b[] dizisine yerleştirir
   for ( i = 0 ; i < 16;  i++ ) {
           b[i]= read_adc(ADC_start_and_read); // ADC okunur diziye  atılır
           delay_us(8); 
     }

// bubble sort algoritması b[] dizisindeki elemanlar küçükten büyüğe sıralanır.
   while(didswap){ 
     didswap=0;
     for (i=0; i<15; i++){ // i 0-15
      if(b[(i)]>b[(i+1)]){ // eğer değer sonrakinden büyükse sırayı değiştir
           s=b[i]; // yükseği tut
           b[i]=b[(1+i)];
           b[(1+i)]=s;
           didswap=1; // yer değiştirme işi bitince döngüden çıkartır duruma göre işlemi kısaltabilir
      } // ~if
     } // ~for
    } // ~while

   //elemanları sıralanan  b[] dizisinde ortadaki 8 değerin ortalaması alınır.
   for (i=4; i<12; i++){  accum +=b[i];  }
   return(accum>>3);
}



burada verilen 16 , 4 değerleri isteğe göre artırılıp azaltılabilir.



Hocam bu örneğinizdeki 16 ve 4 seçeneği ile doğru sonuçlar alınıyor fakat bu değerleri değiştirdiğimizde yanlış değerler geliyor. 25 örnek alıp bunu işleyen versiyonunda yapılacak değişiklikleri gösterebilirmisiniz acaba?
Başlık: Ynt: ortalama alma işlemi
Gönderen: aliveli - 05 Ağustos 2014, 00:17:55

nsigned int16 adchlx(void){ 

unsigned int8 i;  unsigned int16 accum=0; 
unsigned int16 s, b[25]; int1 didswap=1;

//bu döngü 16 kere okuma yapar ve b[] dizisine yerleştirir
   for ( i = 0 ; i < 25;  i++ ) {
           b[i]= read_adc(ADC_start_and_read); // ADC okunur diziye  atılır
           delay_us(8); 
     }

// bubble sort algoritması b[] dizisindeki elemanlar küçükten büyüğe sıralanır.
   while(didswap){ 
     didswap=0;
     for (i=0; i<24; i++){
      if(b[(i)]>b[(i+1)]){ // eğer değer sonrakinden büyükse sırayı değiştir
           s=b[i]; // yükseği tut
           b[i]=b[(1+i)];
           b[(1+i)]=s;
           didswap=1; // yer değiştirme işi bitince döngüden çıkartır duruma göre işlemi kısaltabilir
      } // ~if
     } // ~for
    } // ~while

   //elemanları sıralanan  b[] dizisinde ortadaki 8 değerin ortalaması alınır.
   for (i=4; i<21; i++){  accum +=b[i];  }
   return(accum/17);
}
Başlık: Ynt: ortalama alma işlemi
Gönderen: kantirici - 05 Ağustos 2014, 00:21:06
http://electronicsfreelancer.wordpress.com/2012/09/13/adc-girisine-filtre-mi-desem/ (http://electronicsfreelancer.wordpress.com/2012/09/13/adc-girisine-filtre-mi-desem/) ?
Başlık: Ynt: ortalama alma işlemi
Gönderen: frederic - 05 Ağustos 2014, 01:47:01
Hocam rica etsem şu iki satırı açıklarmısınız?

for (i=4; i<21; i++){  accum +=b;  }
   return(accum/17);
Başlık: Ynt: ortalama alma işlemi
Gönderen: aliveli - 05 Ağustos 2014, 21:45:39
25 elemanlı dizin var ilk ve son dördü hesaplamadan çıkarılır geriye kalan 17 tanesi toplanır. toplanan değerler 17ye bölünerek ortalama bulunmuş olur.
Başlık: Ynt: ortalama alma işlemi
Gönderen: Maxim - 05 Ağustos 2014, 22:04:33
bubble sort diye arayin