pbp de 32 bit register ve işlem

Başlatan gogoce, 20 Mayıs 2023, 21:09:52

gogoce

Herkese selamlar,
sinüs 220v ac yi okuyup TRUE RMS voltmetre yapmam gerekiyor.
220v ac yi doğrultup gerilim bölücüler ile 16f1827 nin analog portuna girdim. Bu porta 330uf kondansatör de taktım.
True rms hesabını yaptırabilmem için 32 bitlik registerler gerekecek. PBP de 32 bit register oluşturabiliyor muyuz?


veri=ADC_Read(2); //Kanal 2 seçildiğinde ADC_Read(2) olur.kanal 1'de ADC_Read(1) olurdu
        voltaj=(0.004887586*veri); 
        voltaj=voltaj-2.527;  //Gerilim Öteleme
        gerilim=124.8*voltaj; // Gerilim bölücüyle  gerilimi küçültük.Yazılımla büyütüyoruz.
        gerilim=gerilim*gerilim;
        acgerilim=acgerilim+gerilim;

bir kaynakt a böyle bir kod buldum bunu pbp ile yapabilirmiyim açıkçası ona uğraşıyorum. Daha önce adv değeri neyse çevrim tablosu oluşturarak ekranda yazdırmıştım fakat bunun hesabını öğrenip uygulamak istiyorum

Saygılarımla

Ne ukalayı affederim nede yapılan haksızlığı ...
Ya sus adam sansınlar , yada adam gibi kouş ilham alsınlar

ete

#1
PBP da 18F serisini kullanmak şartı ile 32 bit register (LONG) tanımlayabilirsin. Ancak float yani ondalıklı işlem yapamazsın. Bu nedenle sayıları odalıktan kurtarmak için önce büyütmen sonra işlemi yapman ve daha sonrada büyüttüğün kadar küçültmen gerekir.

Örnek vereyim. 0,0234 sayısı ile 5678 sayısını çarpman gerekiyor ise önce 0,0234 sayısını 10.000 ile çarpıp sayıyı 234 rakamına ulaştırman daha sonra bu iki sayıyı 32 bit olarak çarpan (** ile) ve daha sonra sonucu hiç görmeden direk 10.000 e bölmen gerekir.
0,0234 x 10000=234
234 ** 5678= xxxx
sonuc=xxxx div32 10000

Senin verdiğin işlem başka türlü şöyle yapılabilir.
voltaj=(0.004887586*veri); işlemini ele alalım önce,

0.004887586 sayısını 256 ile çarpalım. 0,004887586 * 256=1,252 bu sayıyı da 1000 ile çarpalım
1,252* 1000=1252
Bu bizim 32 bit çarpanımız olacak. Şimdi işlemin ikinci kısmına geçelim.
VOLTAJ=(Veri */1252)/1000 = bize ilk işlemin sonucunu verecektir doğru şekilde.
Çünki */ çarpanı sayıyı veri ile çarpacak ve sonucu 256 ya bölerek bize verecektir. Önceden sayımızı 256 ile çarptığımız için sonuç değişmeyecektir. Ancak bu işlemde sayıyı 1000 e bölmemeyi tercih edecğiz. Çünki bir sonraki işlemde bulduğumuz sayıdan 2,527 sayısı çıkartılacak olup bu çıkartılacak sayıyı da 1000 ile çarpıp çıkartmayı yaptıktan sonra 1000 e bölmek bizi bir adım öteye taşıyacaktır.
Dolayısıyla formül, Voltaj=(Veri*/1252) şeklinde kalacak
İkinci adımda şu işlem var. (voltaj=voltaj-2.527;  //Gerilim Öteleme)
İkinci adımda 2,527 sayısını 1000 ile çarpıyoruz. ve 2527 sayısını elde ediyoruz.
Sonra Voltaj=(voltaj-2527)/1000 yapıyoruz. Bu işlemin sonucu yine doğru olacak. Çünki Voltaj değerimiz 1000 bölünmesi gerekiyor idi. 2527 sayısıda 1000 e bölünmesi gerekiyor ve dolayısıyla sonuç da 1000 e bölünürse işlem doğru olacaktır.

Böylece gerilim öteleme işinide yapmış olduk. Şimdi bir sonrak işleme geçebiliriz.
gerilim=124.8*voltaj; // Gerilim bölücüyle  gerilimi küçültük.Yazılımla büyütüyoruz.
Burada 124,8 sayısını virgülden kurtarıyoruz. 124,8*10=1248 sonucu bozmamak adına Voltaj değerimizde 10 ile çarpmamız gerekecek.
Voltaj=voltaj*10 ve sonra formülü uygulayalım.
Gerilim=(1248 ** Voltaj)
Gerilim=Gerilim div10    sonucu 32 bit olarak 10 a bölerek işlem doğruluğunu sağlıyoruz.
Şimdi bir sonraki adıma geçebiliriz.
-  gerilim=gerilim*gerilim;
- ve sonra bir sonraki işleme geçersek acgerilim=acgerilim+gerilim;
şeklinde işlemi yapıp sonucu alırız.

Hepsi bu kadar. Biraz zahmetli gibi gözükmesine rağmen o kadarda zor değil. Üzerinde çalışırsan kolay olduğunu göreceksin.

Bu gibi durumlarda daima örnek hesap yapmak lazım. VERI değeri muhtemelen ADC den okunan değer olacak ve 0-1023 aralığında olacaktır. Öteleme işleminde sonucun eksi çıkma ihtimali olacak.
Bunu göz önünde bulundurarak şu ilaveleri yapman gerekir.
Belkide örnekle açıklamak daha doğru olur.
Veri değerin 500 olsun. Voltaj=(Veri*/1252)  işleminde yerine koyarsak;
Voltaj=(500*/1252)= (bu işlemde 500 sayısı 1252 ile çarpılacak ve sonuç 256 ya bölünecektir)
Voltaj=2445 olacak. Bir sonraki işlemde;
Voltaj=Voltaj-2527 hesaplanacak olup Sonuç Voltaj=2445-2527 =-82 çıkacaktır. Bu nedenle bu işlemin başına;
IF voltaj<2527 then
  Voltaj=2527-Voltaj : voltaj=-Voltaj
endif
eklemek gerekir.
Daha sonra bu sayı 1000 e bölünecek olup iş gittikçe karmaşık bir hal alacak. Belkide 1000 e bölme işini en sonlara bırakmak daha doğru olur.

Tercih senin ben yolunu gösterdim.

Aslında ben olsam şöyle yapardım.
Önce bir Sıfır geçiş algılama devresi yapıp sıfır geçişleri yakalardım.
İki sıfır geçiş arasında normal şartlarda 20 ms lik bir süre vardır. Bu sürenin ilk 10 ms lik peryodu pozitif yönde diğer 10ms lik peryot ise nagatif yöndedir. Bu durumda sıfır geçiş devreni 100 hz lik sinyal yakalayacak şekilde bir köprü diyottan sonra uygularsan yanlızca pozitif peryotta ölçüm alabilir böylece eksi değerler ile uğraşmazsın.
Birinci sıfır noktasını yakaladıktan sonra her 1ms de bir (yada her 500us de bir) ölçüm alacak şekilde bir kod yazıp yazıp aldığın ölçümlerin karelelerini alarak toplarsın. Daha sonra bunu ölçüm adedine bölüp çıkan sonucun karekökünü alursan True RMS değerini hesaplamış olursun diye düşünüyorum.


Ete

gogoce

Alıntı yapılan: ete - 21 Mayıs 2023, 09:00:39PBP da 18F serisini kullanmak şartı ile 32 bit register (LONG) tanımlayabilirsin. Ancak float yani ondalıklı işlem yapamazsın. Bu nedenle sayıları odalıktan kurtarmak için önce büyütmen sonra işlemi yapman ve daha sonrada büyüttüğün kadar küçültmen gerekir.

Örnek vereyim. 0,0234 sayısı ile 5678 sayısını çarpman gerekiyor ise önce 0,0234 sayısını 10.000 ile çarpıp sayıyı 234 rakamına ulaştırman daha sonra bu iki sayıyı 32 bit olarak çarpan (** ile) ve daha sonra sonucu hiç görmeden direk 10.000 e bölmen gerekir.
0,0234 x 10000=234
234 ** 5678= xxxx
sonuc=xxxx div32 10000

Senin verdiğin işlem başka türlü şöyle yapılabilir.
voltaj=(0.004887586*veri); işlemini ele alalım önce,

0.004887586 sayısını 256 ile çarpalım. 0,004887586 * 256=1,252 bu sayıyı da 1000 ile çarpalım
1,252* 1000=1252
Bu bizim 32 bit çarpanımız olacak. Şimdi işlemin ikinci kısmına geçelim.
VOLTAJ=(Veri */1252)/1000 = bize ilk işlemin sonucunu verecektir doğru şekilde.
Çünki */ çarpanı sayıyı veri ile çarpacak ve sonucu 256 ya bölerek bize verecektir. Önceden sayımızı 256 ile çarptığımız için sonuç değişmeyecektir. Ancak bu işlemde sayıyı 1000 e bölmemeyi tercih edecğiz. Çünki bir sonraki işlemde bulduğumuz sayıdan 2,527 sayısı çıkartılacak olup bu çıkartılacak sayıyı da 1000 ile çarpıp çıkartmayı yaptıktan sonra 1000 e bölmek bizi bir adım öteye taşıyacaktır.
Dolayısıyla formül, Voltaj=(Veri*/1252) şeklinde kalacak
İkinci adımda şu işlem var. (voltaj=voltaj-2.527;  //Gerilim Öteleme)
İkinci adımda 2,527 sayısını 1000 ile çarpıyoruz. ve 2527 sayısını elde ediyoruz.
Sonra Voltaj=(voltaj-2527)/1000 yapıyoruz. Bu işlemin sonucu yine doğru olacak. Çünki Voltaj değerimiz 1000 bölünmesi gerekiyor idi. 2527 sayısıda 1000 e bölünmesi gerekiyor ve dolayısıyla sonuç da 1000 e bölünürse işlem doğru olacaktır.

Böylece gerilim öteleme işinide yapmış olduk. Şimdi bir sonrak işleme geçebiliriz.
gerilim=124.8*voltaj; // Gerilim bölücüyle  gerilimi küçültük.Yazılımla büyütüyoruz.
Burada 124,8 sayısını virgülden kurtarıyoruz. 124,8*10=1248 sonucu bozmamak adına Voltaj değerimizde 10 ile çarpmamız gerekecek.
Voltaj=voltaj*10 ve sonra formülü uygulayalım.
Gerilim=(1248 ** Voltaj)
Gerilim=Gerilim div10    sonucu 32 bit olarak 10 a bölerek işlem doğruluğunu sağlıyoruz.
Şimdi bir sonraki adıma geçebiliriz.
-  gerilim=gerilim*gerilim;
- ve sonra bir sonraki işleme geçersek acgerilim=acgerilim+gerilim;
şeklinde işlemi yapıp sonucu alırız.

Hepsi bu kadar. Biraz zahmetli gibi gözükmesine rağmen o kadarda zor değil. Üzerinde çalışırsan kolay olduğunu göreceksin.

Bu gibi durumlarda daima örnek hesap yapmak lazım. VERI değeri muhtemelen ADC den okunan değer olacak ve 0-1023 aralığında olacaktır. Öteleme işleminde sonucun eksi çıkma ihtimali olacak.
Bunu göz önünde bulundurarak şu ilaveleri yapman gerekir.
Belkide örnekle açıklamak daha doğru olur.
Veri değerin 500 olsun. Voltaj=(Veri*/1252)  işleminde yerine koyarsak;
Voltaj=(500*/1252)= (bu işlemde 500 sayısı 1252 ile çarpılacak ve sonuç 256 ya bölünecektir)
Voltaj=2445 olacak. Bir sonraki işlemde;
Voltaj=Voltaj-2527 hesaplanacak olup Sonuç Voltaj=2445-2527 =-82 çıkacaktır. Bu nedenle bu işlemin başına;
IF voltaj<2527 then
  Voltaj=2527-Voltaj : voltaj=-Voltaj
endif
eklemek gerekir.
Daha sonra bu sayı 1000 e bölünecek olup iş gittikçe karmaşık bir hal alacak. Belkide 1000 e bölme işini en sonlara bırakmak daha doğru olur.

Tercih senin ben yolunu gösterdim.

Aslında ben olsam şöyle yapardım.
Önce bir Sıfır geçiş algılama devresi yapıp sıfır geçişleri yakalardım.
İki sıfır geçiş arasında normal şartlarda 20 ms lik bir süre vardır. Bu sürenin ilk 10 ms lik peryodu pozitif yönde diğer 10ms lik peryot ise nagatif yöndedir. Bu durumda sıfır geçiş devreni 100 hz lik sinyal yakalayacak şekilde bir köprü diyottan sonra uygularsan yanlızca pozitif peryotta ölçüm alabilir böylece eksi değerler ile uğraşmazsın.
Birinci sıfır noktasını yakaladıktan sonra her 1ms de bir (yada her 500us de bir) ölçüm alacak şekilde bir kod yazıp yazıp aldığın ölçümlerin karelelerini alarak toplarsın. Daha sonra bunu ölçüm adedine bölüp çıkan sonucun karekökünü alursan True RMS değerini hesaplamış olursun diye düşünüyorum.


Ete

Mesajınız için teşekkür ederim hocam. Sıfır geçiş devrem var. her iki dediğinizi de deneyeceğim
sonucu burdan yazarım
Ne ukalayı affederim nede yapılan haksızlığı ...
Ya sus adam sansınlar , yada adam gibi kouş ilham alsınlar

gogoce

Hocam tekrar merhaba,
ilgili sayfada resimler görülmüyordu farklı tarayıcıda açtığımda ise gerilim bölücü devresinin benim yaptığımdan farklı olduğunu ve 2,5v ötelemenin ne olduğunu farkettim. Dolayısıyla bu hesap işi karelerinin toplamının karekökünü almakla olacak sanırım



Kaynak sayfa:
http://komhedos.com/pic-ile-ac-voltmetre-yapimi/
Ne ukalayı affederim nede yapılan haksızlığı ...
Ya sus adam sansınlar , yada adam gibi kouş ilham alsınlar

Powered by EzPortal