Picproje Elektronik Sitesi

MİKRODENETLEYİCİLER => ARM => Cortex ARM => Konuyu başlatan: XX_CİHAN_XX - 10 Aralık 2012, 09:49:31

Başlık: STM32F4 adc ölçümünde tutarsızlık var
Gönderen: XX_CİHAN_XX - 10 Aralık 2012, 09:49:31
Aşağıdaki gibi bir kod yazdım. Amacım 4 farklı kanaldan istediğim zamanlarda çevrim yaptırabileceğim bir fonksiyon oluşturmak.


//Single mode adc çevrimi için gerekli ayarlamalar yapilir
void adc_setup (ADC_TypeDef* ADCX)
{
ADC_InitTypeDef  ADC_InitStructure;
if(ADCX==ADC1)
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
if(ADCX==ADC2)
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE);
if(ADCX==ADC3)
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE);

ADC_DeInit();
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 1;
ADC_Init(ADCX, &ADC_InitStructure);
ADC_Cmd(ADCX, ENABLE);
}

uint16_t adc_read (ADC_TypeDef* ADCX, uint8_t channel)
{
ADC_RegularChannelConfig(ADCX, channel, 1, ADC_SampleTime_56Cycles);
ADC_SoftwareStartConv(ADCX);
while(ADC_GetFlagStatus(ADCX, ADC_FLAG_EOC) == RESET);
return ADC_GetConversionValue(ADCX);
}


Fonksiyonu kullanım şeklim:


batV = adc_read(ADC1, ADC_Channel_8);
delay_ms(50);
fotoV = adc_read(ADC1, ADC_Channel_5);
delay_ms(50);
supV = adc_read(ADC1, ADC_Channel_1);
delay_ms(50);
lnbV = adc_read(ADC1, ADC_Channel_2);
delay_ms(50);


Bağlı olduğu pinler:
/*
Pin A1 -> (Charge_On_Off) Adaptör Voltaji
Pin A2 -> LNB Akimi
Pin A5 -> Foto Detector Voltaji
Pin B0 -> Batarya Voltaji
*/


Ölçüm alıyorum ancak çok oynak değerler geliyor ve 12 bitlik çevrimde yaklaşık 150-200 değer kadar sapması olabiliyor. Sizce sebebi yazılımsal mı yoksa donanımsal mıdır?
Başlık: Ynt: STM32F4 adc ölçümünde tutarsızlık var
Gönderen: Klein - 10 Aralık 2012, 10:58:51
150-200 çok yüksek değer. AVDD-AVSS arsından  bir gerilim bölücü ile ADC için giriş al. Eğer yine bu kadar oynak ise, yazılımla ilgili olabilir. Değilse giriş işaretin oynaktır. Taş çatlasın 3 bitlik ( 7-8 ) oynama olması gerek.

Yazılımda ilk bakışta bir anormallik görünmüyor. Ama ADC enable yapıldıktan sonra bir müddet kendine gelmesini beklemek gerektiğine ilişkin bir şeyler okuduğumu hatırlıyorum. Eğer ADC deinit yapıldığında ADC kapatılıyorsa, yeniden açıldığında bu süreyi beklemek geekebilir. 

Bu işlemcide  çok kanal okuma yapmak için her seferinde janal değiştirip , çevirim bitene kadar beklemek bana çok anlamlı gelmiyor.  Adam çoklu çevirim seçeneği koymuş. DMA kullanıp tüm kanalları okumak bence daha iyi bir yöntem.
Başlık: Ynt: STM32F4 adc ölçümünde tutarsızlık var
Gönderen: XX_CİHAN_XX - 10 Aralık 2012, 11:49:49
Peki hocam  DMA kullanmayı deneyeceğim ancak birşey dikkatimi çekti.
Benim kullandığım ADC pinleri bu şekilde.

Pin A1 -> ADC123_IN1
Pin A2 -> ADC123_IN2
Pin A5 -> ADC12_IN5
Pin B0 -> ADC12_IN8

Burada iki tanesi ADC123 kısmında diğer iki kanal da ADC12 kısmında ben bunların hepsini ADC1 olarak ölçüyorum.
Bunun bir sakıncası var mı yoksa ben ADC123 mantığını yanlış mı anladım?
ADC123 demek ADC1, ADC2 ve ADC3 ten bu kanala erişebilirsin,
ADC12 de sadece ADC1 ve ADC2 den erişebilirsin demek oluyor değil mi?

Bu şekilde düşünerek tüm kanallara sadece ADC1 den erişmeyi uygun gördüm.
Başlık: Ynt: STM32F4 adc ölçümünde tutarsızlık var
Gönderen: Klein - 10 Aralık 2012, 12:22:04
Evet doğru düşünmüşsün.
Başlık: Ynt: STM32F4 adc ölçümünde tutarsızlık var
Gönderen: pisayisi - 10 Aralık 2012, 12:58:43
Ben basit bir gerilim bölücü pot devresi ile analog değer okumuştum değerler de hiç sapma yoktu, muhtemelen analog olarak girilen işaretlerde sıkıntı vardır. Birde böyle basit bir gerilim bölücü ile ölçüm yapmayı deneyin, sonra yazılımda skııntılar olabilirmi düşünmek lazım.
Başlık: Ynt: STM32F4 adc ölçümünde tutarsızlık var
Gönderen: muhittin_kaplan - 10 Aralık 2012, 17:32:58
bugün ben bir şarj ünitesinin giriş ve çıkışını ölçmek istedim. değerler çok oynak (300mV kadar) sabitlemek için unutulan geçmş algoritması kullandım. 30 lu dizi ile çalıştım.

mesaj birleştirme:: 10 Aralık 2012, 17:34:28

şarj devresinde bulunan bir röle çektiğinde devre reset atıyor ve çalışmıyor tekrar.(ters diyot var) sebebi MClear dan kaynaklanabilir mi ? siz MClear ı nasıl donanımlandırıyorsunuz ?
Başlık: Ynt: STM32F4 adc ölçümünde tutarsızlık var
Gönderen: Klein - 10 Aralık 2012, 17:46:30
30'lu dizi ile düzelltebildiysen çok oynama yoktur zaten.
Programlayıcıbağlı değilken de resetleniyor mu?   
Başlık: Ynt: STM32F4 adc ölçümünde tutarsızlık var
Gönderen: muhittin_kaplan - 10 Aralık 2012, 17:49:03
hocam programlayıcı bağlı değil. MCU var sadece ve diğer devre. beslemeyi de diğer devreden aldım.
Başlık: Ynt: STM32F4 adc ölçümünde tutarsızlık var
Gönderen: Klein - 10 Aralık 2012, 17:56:01
Reset pini ile programlama soketi arasındaki mesafe çok mu uzak?
genellikle 4u7,4K7 ikilisi bir de hızlı deşarj için diyot kullanırım. 
Şu an üzerinde çalıştığım kart, bu işlemci ile yaptığım ilk kart. Reset devrem dışarıda. Bu yüzden standart yapı kullanmadım. Uçma kaçma testlerine gelmedim daha. Şimdilik böyle bir sorun yaşamadım.
Başlık: Ynt: STM32F4 adc ölçümünde tutarsızlık var
Gönderen: Erhan YILMAZ - 10 Aralık 2012, 18:01:29
Hocam unutulan geçmiş algoritması nedir?
Başlık: Ynt: STM32F4 adc ölçümünde tutarsızlık var
Gönderen: muhittin_kaplan - 10 Aralık 2012, 18:11:37
Hafızalı bir ortalama alma algoritması. örneğin 10 luk bir dizi ile yapalım.

int Deger[10];
int LoopValue;
int Toplam;

//dizinin yerlerini değiştirelim
for (LoopValue=0;LoopValue<10;LoopValue++)
{
Deger[LoopValue]=Deger[LoopValue+1]
}

Deger[9]=OlculenDeger

// Dizi değerlerini toplayalım
for (LoopValue=0;LoopValue<10;LoopValue++)
{
Toplam+=Deger[LoopValue]
}

//sonucu bulalım
Toplam=Toplam/10


http://muhittinkaplan.com/2012/02/unutulan-gecmis/ (http://muhittinkaplan.com/2012/02/unutulan-gecmis/)
Başlık: Ynt: STM32F4 adc ölçümünde tutarsızlık var
Gönderen: Klein - 10 Aralık 2012, 18:13:10
Şimdi bir test yaptım.
Reset devremi  ve programlayıcıyı ayırdım. Resette sadece 100n kapasite kaldı. (Pull-Up direnci işlemcinin içinde var)
Beslemeyi verdiğim  switching güç kaynağının 230V girişinden kontaktör ile seri arklar oluşturdum.
Kontaktörün bobininin 2 ucu da kontaktörün NC kontağına bağlı. Enerji verildiğinde sürekli açık kalmıyor. 15-20Hz civarında sürekli açıp kapama yapıyor.
Kontaktörün tek ucunu açıp kapatınca oluşan ark yeterince zorlamıyor. iki ucunu birden kesmek ve bağlamak çok daha yüksek gürülyü oluşturuyor. Aynı zamanda kontaktörü elimle tuttuğum için elimin titreşmesi nedeniyle açma kapama süreleri düzensizleşiyor. Böylece düzensiz arklar elde ediyorum.

Sistemi zorlamak adına RS485 haberleşme hzını 256000 bauda çıkardım. Her sorgulamada 132 bayt veri okuyorum. 2300 kez sorguladım.  12 kez haberleşme hatası aldım. ( kaç bayt veri yanlış gitti bilmiyorum. CRC yanlış gelince haberleşmehatası alıyorum).

Resetlenme yaşamadım.

Başlık: Ynt: STM32F4 adc ölçümünde tutarsızlık var
Gönderen: muhittin_kaplan - 10 Aralık 2012, 18:16:49
arkadaşın konusunuda kirlettik ama kusrumuza bakmasın artık.
hocam ben doğrudan 3.3v a bağladım. muhtemel hata bende değil ama tabiki tereddütlerim var. 100n ile şaseleyeceğim yarın.
(ayrıca mclre ye pullup bağlamaya gerek yok diye biliyorum doğrumuyum ?)
Başlık: Ynt: STM32F4 adc ölçümünde tutarsızlık var
Gönderen: Erhan YILMAZ - 10 Aralık 2012, 18:22:40
Sağolun hocam. Belli sayıda okuma yapıp bunların ortalamasını alıyoruz doğru mu anlamışım? Kullanılan bi yöntem mi hocam ne kadar verimlidir öğrenmek açısından soruyorum.
Başlık: Ynt: STM32F4 adc ölçümünde tutarsızlık var
Gönderen: Klein - 10 Aralık 2012, 18:23:16
@muhittin

Her seferinde yeniden tüm değerleri toplamana ve tüm diziyi kaydırmana gerek yok. Bu işlem çok uzun zaman alır.
Tablo için bir index tut.  Her işlemden sonra indeksi bir artır.
Her yeni veri geldiğinde  tablonun indexin gösterdiği adresindeki  veriyi genel toplamdan çıkar , yeni gelen veriyi genel toplama ekle , aynı zamanda da  son gelen veriyi tablonun aynı adresine yaz. indeksi bir artır.

örnek:
 
Total -=  Buf[Index];
Total += new_adc_value;
Buf[Index]= new_adc_value;

FilteredValue = Total / FILTERSIZE;

if(++Index == FILTERSIZE)
{
       Index=0;
}

Filtre tampununun büyüklüğünü 2'nin katları şeklinde ayarlarsan bölme daha kolay olur.



mesaj birleştirme:: 10 Aralık 2012, 18:38:24

Alıntı yapılan: Erhan YILMAZ - 10 Aralık 2012, 18:22:40
Sağolun hocam. Belli sayıda okuma yapıp bunların ortalamasını alıyoruz doğru mu anlamışım? Kullanılan bi yöntem mi hocam ne kadar verimlidir öğrenmek açısından soruyorum.

Kullanılan bir yöntemdir. Oldukça etkili ve basittir ancak çok fazla ram gerektirir.  Kayan ortalama yöntemi de denir.
Klasik ortalama almadan biraz farklıdır. 
Klasik ortalamada kaç  ortalama alacaksanız, o kadar veri gelene kadar toplar sonra ortalamasını alırsınız ve yeni verilerin gelmesini beklersiniz. Ancak çok az ram kullanırsınız.
Kayan ortalamada ise ,  bir diziniz olur.  Her yeni veri geldiğinde dizideki ilk kayıt atılır , son gelen veri dizinin sonuna eklenir.
Başlık: Ynt: STM32F4 adc ölçümünde tutarsızlık var
Gönderen: muhittin_kaplan - 10 Aralık 2012, 18:52:00
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.
Başlık: Ynt: STM32F4 adc ölçümünde tutarsızlık var
Gönderen: CLR - 10 Aralık 2012, 23:34:06
@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?   
Başlık: Ynt: STM32F4 adc ölçümünde tutarsızlık var
Gönderen: 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?
Başlık: Ynt: STM32F4 adc ölçümünde tutarsızlık var
Gönderen: 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.
Başlık: Ynt: STM32F4 adc ölçümünde tutarsızlık var
Gönderen: Erhan YILMAZ - 11 Aralık 2012, 00:20:23
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ı;


Başlık: Ynt: STM32F4 adc ölçümünde tutarsızlık var
Gönderen: Tagli - 11 Aralık 2012, 00:32:25
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);
}
Başlık: Ynt: STM32F4 adc ölçümünde tutarsızlık var
Gönderen: muhittin_kaplan - 11 Aralık 2012, 11:56:39
@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.
Başlık: Ynt: STM32F4 adc ölçümünde tutarsızlık var
Gönderen: Klein - 11 Aralık 2012, 12:07:18
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.
Başlık: Ynt: STM32F4 adc ölçümünde tutarsızlık var
Gönderen: tekosis - 11 Aralık 2012, 13:54:49
ş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.
Başlık: Ynt: STM32F4 adc ölçümünde tutarsızlık var
Gönderen: LukeSkywalker - 11 Aralık 2012, 15:21:33
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.
Başlık: Ynt: STM32F4 adc ölçümünde tutarsızlık var
Gönderen: Klein - 11 Aralık 2012, 15:33:11
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. 
Başlık: Ynt: STM32F4 adc ölçümünde tutarsızlık var
Gönderen: 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 .
Başlık: Ynt: STM32F4 adc ölçümünde tutarsızlık var
Gönderen: fgokcegoz - 24 Aralık 2012, 11:38:36
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.
Başlık: Ynt: STM32F4 adc ölçümünde tutarsızlık var
Gönderen: mozkan87 - 24 Aralık 2012, 12:03:23
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.