Parmaktan Nabız Okuma için Hesaplama Problemi

Başlatan omersn, 15 Haziran 2015, 03:45:20

z

Ne yaptın. Devredeki sorunu gidermeden yazılımdan mı halletmeye çalışıyorsun?

Çok az işi kaldıydı.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

omersn

yok hocam sorunu çözmeye devam bugün bazı işlerim vardı yeni bakabildim hangi değerde bir dirençle değiştirmemi önerirsiniz?

z

Kollektör direncimiz 1K idi. 5v da 2.5v da olması için 2.5mA

Yaklaşık olarak Ibé=2.5/hfe=(2.5-0.6)/R  (K)

hfeyi 100 alsak 76K

100K ile bir deneme yap.

Bana e^st de diyebilirsiniz.   www.cncdesigner.com

omersn

z hocam 2. transistördeki 500k direnci 100k ile değiştirdim, iki faklı parmaktan sinyal aldım;

İşaret Parmağından alınan sinyal;

[IMG]http://i61.tinypic.com/qq1xyo.png[/img]

Serçe Parmağından alınan sinyal;

[IMG]http://i58.tinypic.com/2cwva5f.png[/img]

z

#34
Alttaki sinyal her türlü sinyal işlemeye uygun hale geldi. Üstteki için kazancı bir miktar daha düşürmek lazım.

Bence şimdi devre tasarlanma amacına uygun hale geldi. (Eski halleri ile de palsleri sayabilirdik ama yakışık olmazdı)

Şimdi amacın palsleri tesbit edip saymak.

Palsleri nası tesbit ediyorsun?

Bir daha scop görüntüsü verecek olursan kareler 1v yüksekliğinde olsun.  Hatta son dalga şeklini 1v/div için tekrar ver.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

omersn

Palsleri, ADC ile belirlediğim bir eşik voltaj değerini elde ettiğim anda sayma yapıyorum. Timer0 ile 15sn veya daha farklı bir süre içerisinde kaç kare bu eşik voltaj değeri elde edilmiş onu tespit ediyorum. Zamanın 60 saniyeye tamamlanması için kaçla çarpmam gerekiyorsa sayılan değeri de aynı çarpanla çarpıp sonuca ulaşmaya çalışıyorum. Örneğin 15 saniyede 20 sayım yapıldıysa 60 saniye için bu değeri 4 ile çarpıyorum ve nabız değerini 80 olarak buluyorum.

Osiloskop görüntüsünde 1 konumu -2 V seviyesinde;

[IMG]http://i57.tinypic.com/258cux1.png[/img]

z

#36
Bir rutin yazmayı deneyeceğim. ADC nin 8 bit olduğunu varsayıyorum.

Yalnız scoptaki 1 seviyesi nasıl -2v olur anlamadım. Transistörün emetörü Gnd, kollektor direci de +5v da idi.


char Time;

char Olcum()
{ 
char n, ne, nabiz;
unsigned char A;


       n=0; ne=0;
       nabiz=0;
       Time=15; // Timer her 1 saniyede Time değerini 1 eksiltecek

       while (Time>0)
         {
            A=ReadAdc();
            if (A>210) n=1;
            if (A<40) n=0;
            if (n!=ne)
              {
                 ne=n;
                 if (n==1) nabiz++;
               }
          }
       returm(4*nabiz);
}
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

omersn

z hocam scoptaki 1 konumu -2 V derken, sinyal 1v/div konumda iken ekrana sığmamıştı bende ekranda görünmesi için sinyalin x eksenini -2 v seviyesinden başlattığımı anlatmak istemiştim fakat biraz yanlış anlatmışım  :) 

Hocam verdiğiniz rutini kullanarak kendi kodum da değişiklikler yaptım ve tekrar nabız sayımı yaptım. Sonuçlar önceki hesaplamalarıma göre daha doğru çıktı. Hocam lütfen kodu bir kontrol inceleyin hatalar açısından. Hocam ayrıca küçük değişiklik yaparak yeni birşey denedim. Normalde bir start butonu ile ADC kesmesini ve Timer0 ı aktif ediyordum. ADC yi sonsuz döngü içerisinde okuyordum. Sonra adc okuma kısmını sonsuz döngüden alarak timer0 döngüsüyle beraber butonla aktif olacak şekilde ayarladım. Yani butondan sonra adc okunmasını istedim. Bu değişiklikle sonuç daha gerçeğe yakın çıktı. Bu değişiklik doğru bir değişiklik midir?

Normal Kod;

#include <16f877a.h>
#device ADC=10
#fuses HS,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#use delay(clock=20000000)
#use fast_io(a)
#use fast_io(b)
#use fast_io(d)
unsigned long int A;
long t=0;
char birler=0, onlar=0;     // char tipinde değişkenler tanımlanıyor 
char n=0, ne=0, nabiz=0, s=0;
// Ortak katot display için veri değerleri
const int digit[10]={0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F};
#define   display_1   pin_d1      //display_1 ifadesi pin_a0 ifadesine eşleniyor
#define   display_2   pin_d0      // display_2 ifadesi pin_a1 ifadesine eşleniyor

///Tİmer0\\\
#int_timer0
void tmr0_kesme(){
disable_interrupts(GLOBAL);
set_timer0(158);
t++;
if(t==3000){//timer0 değeri(15sn için 3000)
nabiz=s*4;	
t=0;
disable_interrupts(INT_timer0);
disable_interrupts(INT_AD); }
enable_interrupts(GLOBAL);  }

///ADC Kesmesi\\\
#INT_AD
void adc(){
if (A>840){
n=1;
output_high(pin_b7);
delay_ms(100);
output_low(pin_b7);
}
if (A<160) 
n=0;
if (n!=ne)
   {
    ne=n;
    if (n==1) s++;
   }
}

void main()
{
set_tris_a(0b00000011);
set_tris_b(0);
set_tris_d(0);
output_a(0);
output_b(0);
output_d(0);
setup_timer_0(RTCC_DIV_256);
set_timer0(158);
setup_adc(adc_clock_div_32);
setup_adc_ports(AN0);
set_adc_channel(0);
delay_us(20);
output_high(display_1);      // 1. display aktif durumda
output_high(display_2);      // 2. display aktif durumda

while(1){
A=read_adc();
///başlatma butonu\\\
if(input(pin_a1)){
enable_interrupts(INT_timer0);
enable_interrupts(INT_AD);
enable_interrupts(GLOBAL); }
///Diplay\\\
birler=(s)%10;  // birler hanesi hesaplanıyor
onlar=(s)/10;   // onlar hanesi hesaplanıyor
output_low(display_2);  // 2. display aktif durumda
output_b(digit[birler]); // displaye bilgi gönderiliyor
delay_ms(5);             // gecikme veriliyor
output_high(display_2);   // 2. display pasif durumda
output_low(display_1);  // 1. display aktif durumda
output_b(digit[onlar]);  // displaye bilgi gönderiliyor
delay_ms(5);             // gecikme veriliyor
output_high(display_1);   // 1. display pasif durumda
}
}



Değişen Kod;

#include <16f877a.h>
#device ADC=10
#fuses HS,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#use delay(clock=20000000)
#use fast_io(a)
#use fast_io(b)
#use fast_io(d)
unsigned long int A;
long t=0;
char birler=0, onlar=0;     // char tipinde değişkenler tanımlanıyor 
char n=0, ne=0, nabiz=0, s=0;
// Ortak katot display için veri değerleri
const int digit[10]={0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F};
#define   display_1   pin_d1      //display_1 ifadesi pin_a0 ifadesine eşleniyor
#define   display_2   pin_d0      // display_2 ifadesi pin_a1 ifadesine eşleniyor

///Tİmer0\\\
#int_timer0
void tmr0_kesme(){
disable_interrupts(GLOBAL);
set_timer0(158);
t++;
A=read_adc();
if(t==3000){//timer0 değeri(15sn için 3000)
nabiz=s*4;	
t=0;
disable_interrupts(INT_timer0);
disable_interrupts(INT_AD); }
enable_interrupts(GLOBAL);  }

///ADC Kesmesi\\\
#INT_AD
void adc(){
if (A>840){
n=1;
output_high(pin_b7);
delay_ms(100);
output_low(pin_b7);
}
if (A<160) 
n=0;
if (n!=ne)
   {
    ne=n;
    if (n==1) s++;
   }
}

void main()
{
set_tris_a(0b00000011);
set_tris_b(0);
set_tris_d(0);
output_a(0);
output_b(0);
output_d(0);
setup_timer_0(RTCC_DIV_256);
set_timer0(158);
setup_adc(adc_clock_div_32);
setup_adc_ports(AN0);
set_adc_channel(0);
delay_us(20);
output_high(display_1);      // 1. display aktif durumda
output_high(display_2);      // 2. display aktif durumda

while(1){
///başlatma butonu\\\
if(input(pin_a1)){
enable_interrupts(INT_timer0);
enable_interrupts(INT_AD);
enable_interrupts(GLOBAL); }
///7seg Diplay\\\
birler=(nabiz)%10;  // birler hanesi hesaplanıyor
onlar=(nabiz)/10;   // onlar hanesi hesaplanıyor
output_low(display_2);  // 2. display aktif durumda
output_b(digit[birler]); // displaye bilgi gönderiliyor
delay_ms(5);             // gecikme veriliyor
output_high(display_2);   // 2. display pasif durumda
output_low(display_1);  // 1. display aktif durumda
output_b(digit[onlar]);  // displaye bilgi gönderiliyor
delay_ms(5);             // gecikme veriliyor
output_high(display_1);   // 1. display pasif durumda
}
}

z

#38
ADC int içinde 100ms bekleme sakıncalı.

ADC int rutinine ihtiyaç da yok görünüyor.

Timer int geldiğinde ADC yi okursun ve gerekli işleri yaparsın.
Timer int rutininde de bekleme fonksiyonu kullanmamak lazım.

Sonucu sadece 1 pals hata ile bulabilmen lazım.

char Bitti;

#int_timer0
void tmr0_kesme()
{
            set_timer0(158);
            t++;
            A=read_adc();
            if (A>840) n=1;
            if (A<160) n=0;
            if (n!=ne)
              {
                ne=n;
                if (n==1) 
                   {
                       s=s+4;
                       output_high(pin_b7);
                   } 
                else output_low(pin_b7); 
               }

            if(t==3000)                      //timer0 değeri(15sn için 3000)
               {
                  Bitti=1;
                  disable_interrupts(INT_timer0);
               }
}


void main()
{
.........
.........
         enable_interrupts(GLOBAL); 

         while(1)
            {
               Bitti=0;  s=0; t=0; nabiz=0;
               output_high(display_1);
               output_high(display_2);

               while (input(pin_a1)==0)
                  {
                     A=read_adc();
                     if (A>840) n=1;
                     if (A<160) n=0;
                     if (n!=ne)  ne=n;
                  }

               set_timer0(158);
               enable_interrupts(INT_timer0);

               while (Bitti==0);    // Olcum devam ediyor

               birler=(s)%10;      // birler hanesi hesaplanıyor
               onlar=(s)/10;        // onlar hanesi hesaplanıyor

               while (input(pin_a1)) ///7seg Diplay\\\
                  {
                     output_low(display_2);  // 2. display aktif durumda
                     output_b(digit[birler]);  // displaye bilgi gönderiliyor
                     delay_ms(5);               // gecikme veriliyor
                     output_high(display_2);// 2. display pasif durumda
                     delay_ms(1);               // gölge sorunu varsa bu sorunu yok edelim
                     output_low(display_1); // 1. display aktif durumda
                     output_b(digit[onlar]);  // displaye bilgi gönderiliyor 
                     delay_ms(5);               // gecikme veriliyor
                     output_high(display_1); // 1. display pasif durumda
                     delay_ms(1);               // gölge sorunu varsa bu sorunu yok edelim
                 }
            }
}
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

omersn

z hocam kodu denedim 2 farklı problemle karşılaştım,
1. sonuçlar her zaman 11'in katları şeklinde çıkıyor(55-66-77-88 gibi)
2. 7 seg. displayde tarama işlemini while ile butona şartladığımızda displayler çalışmadı. (while şartını kaldırınca çalıştı)

Hocam ayrıca hem timer0 ın içinde ADC okuması yapılıyor hemde sonsuz döngünün içinde butona bağlı olarak ADC okuması yapılıyor. ADC okumasını sadece timer0 içerisinde yapıp sonsuz döngü içerisinde de butona bağlı olarak timer0'ı aktif etsek mantıksal bir hata olur mu?(denedim çalışıyor).

Sonsuz döngü;

while(1){
 Bitti=0;  s=0; t=0; nabiz=0;
output_high(display_1);
output_high(display_2);
while (input(pin_a1)==0)
{
set_timer0(158);
enable_interrupts(INT_timer0);
}

while (Bitti==0);    // Olcum devam ediyor

birler=(s)%10;      // birler hanesi hesaplanıyor
onlar=(s)/10;        // onlar hanesi hesaplanıyor

output_low(display_2);  // 2. display aktif durumda
output_b(digit[birler]);  // displaye bilgi gönderiliyor
delay_ms(5);               // gecikme veriliyor
output_high(display_2);// 2. display pasif durumda
delay_ms(1);               // gölge sorunu varsa bu sorunu yok edelim
output_low(display_1); // 1. display aktif durumda
output_b(digit[onlar]);  // displaye bilgi gönderiliyor 
delay_ms(5);               // gecikme veriliyor
output_high(display_1); // 1. display pasif durumda
delay_ms(1);               // gölge sorunu varsa bu sorunu yok edelim
}

z

Ana programda sonsuz döngü içinde okuma sebebi butona başla deninceye kadar geçen zamanda parmaktan gelen sinyalden n ve ne durumlarını hazırda tutmakdı.

Ölçüm başladığında zaten o döngüden çıkılmış oluyor.

Neyse halledersin artık.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

omersn

z hocam herşey için çok teşekkür ederim sayenizde kodu çalıştırdım, doğru sonuçlar elde edebiliyorum. Tabi sinyal içinde ayrıca çok teşekkür ediyorum. Sinyal içinde çok uğraştınız. Ayrıca yardımcı olan herkese teşekkürler.

z

En son elde ettiğin sinyali ben de çok sevdim. Fakat bu iş için 2 adet 9v pil kullanmak hoş olmadı.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

omersn

haklısınız z hocam, Band Geçiren filtre ve notch filtre devrelerini simetrik beslemeyle çalıştırabilmiştim.  Aslında simetrik beslemeden kurtulmak için bu filtreleri de değiştirmeyi düşünmüştüm ama artık elimde sinyal generatörü ve osiloskop olmadığından şimdilik bu şekilde kalacak.

set123

Merhabalar hocam bende bu günlerde parmaktan nabız ölçme projesi ile uğraşıyorum.
Acaba bu yazdığınız programın isis şeması varsa paylaşabilir misiniz?