STM32F4 adc ölçümünde tutarsızlık var

Başlatan XX_CİHAN_XX, 10 Aralık 2012, 09:49:31

muhittin_kaplan

#15
Hocam verdiginiz ornegi ya be n anlamadim yada ayni sey degil.

mesaj birleştirme:: 10 Aralık 2012, 19:15:51

yok, yazdım denedim vb.net te aynı sonucu alıyorum. Tel Fark Yer Değiştirme yok.

CLR

@muhittin_kaplan

Klein'in yaptığı algoritma senin yazdığına göre çok daha hızlı ve kod yönünden verimli, hemde 10 ortalama için hiç yakışmamış,  ya 8 yada 16 daha uygun değil mi?   
Knowledge and Experience are Power

Erhan YILMAZ

@Klein
Hocam teşekkür ederim güzel bi yöntem öğrendim. Sormak istediğim sistem ilk çalışmaya başladığında bufferdaki değişkenlerin içi sıfır yada çöp değer olacağından ilk ortalama değerleri hatalı olmaz mı? Bunu önlemek için bi yöntem var mıdır?

Tagli

Tampon azami boyutunun yanısıra, içindeki eleman sayısını da tutarsan başlangıçtaki sıfırlar işini bozmaz. Mesela boyutu 4 olan bir tampon bellek için eleman sayısı 0 1 2 3 4 4 4 ... gibi gidecek. Ortalama hesaplarken de eleman sayısına böleceksin.
Gökçe Tağlıoğlu

Erhan YILMAZ

Alıntı yapılan: Tagli - 11 Aralık 2012, 00:08:05
Tampon azami boyutunun yanısıra, içindeki eleman sayısını da tutarsan başlangıçtaki sıfırlar işini bozmaz. Mesela boyutu 4 olan bir tampon bellek için eleman sayısı 0 1 2 3 4 4 4 ... gibi gidecek. Ortalama hesaplarken de eleman sayısına böleceksin.
Ama sonuç olarak tampon boyutu kadar ölçüm yapıldıktan sonra bölen sayı sabit olacak. Buda muhtemel ek sorgular gerektirecek programın çalışma süresini uzatır. En basitinden aşağıdaki gibi bi yapı kullanmak gerekir.

if(Buffer_bir_kere_doldumu)
deger=toplam/Buffer_size;
else
deger=toplam/Eleman_sayısı;



Tagli

Benim dediğim de oydu zaten. Net olması açısından yakın zamanda yazmış olduğum bir C++ sınıfını paylaşayım. Optimize etmek için pek uğraşmadım ama şu haliyle çalışıyor gibi. C++'ta acemiyim zaten.

Averager.hpp
#ifndef AVERAGER_HPP_INCLUDED
#define AVERAGER_HPP_INCLUDED

#include <math.h>
#include <stdio.h>

class Averager
{
	public:
		Averager(int bufferSize = 8);
		~Averager();
		void addPoint(double point);
		void clear(void);
		double getAverage(void);

	private:
		double *data;
		int bufferSize, size, last;
		double sum;
};

#endif // AVERAGER_HPP_INCLUDED


Averager.cpp
#include "Averager.hpp"

Averager::Averager(int bufferSize)
: bufferSize(bufferSize), size(0), last(-1), sum(0)
{
	data = new double [bufferSize];
	counter = 0;
}

Averager::~Averager()
{
	delete [] data;
}

void Averager::clear(void)
{
	size = 0;
	last = -1;
	sum = 0;
}

void Averager::addPoint(double point)
{
	if (++last == bufferSize) last = 0;

	sum += point;

	if (size < bufferSize) ++size;
	else sum -= data[last];

	data[last] = point;
}

double Averager::getAverage(void)
{
	if (size == 0) return 0;
	else return (sum / size);
}
Gökçe Tağlıoğlu

muhittin_kaplan

@uicroarm
hocam kodları örnek olması açısından verdiğimi yazmıştım. 10 derinlik genelde yetmez. Doğrudur Klein in kodları daha hızlı çalışır.

Klein

Alıntı yapılan: Erhan YILMAZ - 10 Aralık 2012, 23:54:38
@Klein
Hocam teşekkür ederim güzel bi yöntem öğrendim. Sormak istediğim sistem ilk çalışmaya başladığında bufferdaki değişkenlerin içi sıfır yada çöp değer olacağından ilk ortalama değerleri hatalı olmaz mı? Bunu önlemek için bi yöntem var mıdır?

Evet tampon boşken ortalama hatalı çıkacaktır.  Tampon başlangıçta sıfırlanır ve @Tagli'nin söylediği gibi  tampon  dolana kadar ortalama aldırmaz veya tamponun dolu kısmı kadar ortalama aldırırsan sorun kalmaz.

Sistem enerjilendirildiğinde zaten çok kısa bir süre bu saçmalık oluşacak.
Genelde açılışta bir zamanlayıcım olur. Sistem belirli bir süre çalışıp tüm değerler yerine oturduktan sonra  "SystemReady" ismini verdiğim bayrağı çekerim.  Açılışta hatalı çalışabilecek modülleri çalıştırmadan önce bu bayrağı kontrol ederim.  Bu hem bu tamponun dolması için zaman sağlar , hem de dış donanımların enerjilendikten sonra kendine gelmesi için zaman sağlar.

tekosis

şu anda üzerinde çalıştığım bir cihazda mcp9700 analog sensörü kullanıyorum. aynı sıkıntılar bende de vardı. bu yöntemle hallettim kesinlikle bu şekilde daha istikrarlı çalışıyor.
İlim ilim bilmektir, ilim kendin bilmektir, sen kendin bilmezsin, bu nice okumaktır.

LukeSkywalker

Alıntı yapılan: Klein - 11 Aralık 2012, 12:07:18
Evet tampon boşken ortalama hatalı çıkacaktır.  Tampon başlangıçta sıfırlanır ve @Tagli'nin söylediği gibi  tampon  dolana kadar ortalama aldırmaz veya tamponun dolu kısmı kadar ortalama aldırırsan sorun kalmaz.

Sistem enerjilendirildiğinde zaten çok kısa bir süre bu saçmalık oluşacak.
Genelde açılışta bir zamanlayıcım olur. Sistem belirli bir süre çalışıp tüm değerler yerine oturduktan sonra  "SystemReady" ismini verdiğim bayrağı çekerim.  Açılışta hatalı çalışabilecek modülleri çalıştırmadan önce bu bayrağı kontrol ederim.  Bu hem bu tamponun dolması için zaman sağlar , hem de dış donanımların enerjilendikten sonra kendine gelmesi için zaman sağlar.
Bu iş kısaca delay ile yapılabilir kanısındayım.

Klein

Eğer alınan değer sadece göstergede kullanılıyorsa , hiç önemli değil.  Çok kısa sürede tampon dolacaktır.
Yok değer bir iş yaptırmakta ullanılıyorsa ve yanlış değer çok dramatik sonuçlar doğuracaksa;
Sisteme enerji verir vermez işleme başlamak zaten hata olacaktır.  İşleme başlamadan önce analog değerlerin oturması beklenmelidir.  Tamponun boş olması çok ciddi bir sorun değil yani.
Yukarıda zaten bir kaç yöntem konuşuldu. Buna ek olarak şu şekilde de yapılabilir.
İlk açılışta bir kez örnek alınır , tüm tampon bu değerle doldurulur. 

GreeN

Adc ile okuduğum verilerde  o kadar fazla salınım varki  ekrana çizdirdiğimde resmen horon tepiyorlar. Kritik bir nokta takip etmek için 100 adet verinin ortalasını aldım. ölçtüğüm adc desimal 1.3xxx , herbir x o kadar hızlı değişiyorki ekranda okunması bile zorlaşıyor.
Adc verilerini önce low-pass  filtreden geçirmeyi düşünüyorum.

Girişte sinyal yokken bile dalgalanma var , gerçektende stm32f4x adc'sinde bir problem mi?

ADC'yi trible çalıştırıyorum , 7.2Msps hız ile saniyede kaç örnek alabilirim ? Çünkü benim ölçtüğüm değerler uçuk kaçık .
Terörü Lanetliyoruz.

fgokcegoz

Alıntı yapılan: GreeN - 24 Aralık 2012, 11:19:57
Adc ile okuduğum verilerde  o kadar fazla salınım varki  ekrana çizdirdiğimde resmen horon tepiyorlar. Kritik bir nokta takip etmek için 100 adet verinin ortalasını aldım. ölçtüğüm adc desimal 1.3xxx , herbir x o kadar hızlı değişiyorki ekranda okunması bile zorlaşıyor.
Adc verilerini önce low-pass  filtreden geçirmeyi düşünüyorum.

Girişte sinyal yokken bile dalgalanma var , gerçektende stm32f4x adc'sinde bir problem mi?

ADC'yi trible çalıştırıyorum , 7.2Msps hız ile saniyede kaç örnek alabilirim ? Çünkü benim ölçtüğüm değerler uçuk kaçık .

STM32 serisinin ADC sini bende çok kötü buldum. Saçma saçma örnekler alıyor. Aşırı şekilde oynama var. Örneğin VDD yi ölçüyorum. 4095 civarı görmem gereken ADC sonucunu, 4023, 1016, 4035, 4018 vs. vs... gösteriyor. Bir problem var gibi gerçekten.. STM8 lerin 10 bitlik adc leri bile daha iyi geldi bana.

Ayrıca örnek alırken, örnek sayısını 2^n olarak seçerseniz, ortalama alma işleminiz sağa shift etmek kadar kolay olacaktır.
"Vicdanın ziyası, ulûm-u diniyedir. Aklın nuru, fünun-u medeniyedir. İkisinin imtizacıyla hakikat tecelli eder." (Bediüzzaman Said Nursi)

mozkan87

Sizin sistemde bir sorun var galiba ben sorunsuz olarak kullandım. Hatta touch screen controller yerine kullandım değerleri bir kere hesapladım daha sonra giç kalibrasyon yapmaya gerek bile kalmadı. ADC pinini değiştirerek deneyebilir misiniz birde.