32bit işlemi lcd'de gösteremiyorum

Başlatan transistor, 12 Mayıs 2018, 02:14:29

transistor

Merhaba arkadaşlar, acs712-30a ile akım ölçmeye çalışıyorum. Ancak amper cinsinden 32bit hesaplamayı ondalıklı olarak lcd'ye yazdırmak istiyorum. DIV32 ve */ kullandıysam da olmadı. Yardımcı olursanız sevinirim.


TRISA=255
TRISC=%00000011 : PORTC=0
;*******************************************************************************
DEFINE LCD_DREG PORTB
DEFINE LCD_DBIT 4
DEFINE LCD_RSREG PORTB
DEFINE LCD_RSBIT 2
DEFINE LCD_EREG PORTB
DEFINE LCD_EBIT 3
DEFINE LCD_BITS 4
DEFINE LCD_LINES 4
;*******************************************************************************
DEFINE ADC_BITS 10
DEFINE ADC_CLOCK 3
DEFINE ADC_SAMPLEUS 50
ADCON1=%10000000
;*******************************************************************************
adc     VAR WORD
amps    VAR WORD
voltage    VAR WORD
toplam var word
y var word
x var byte

CLEAR
;*******************************************************************************
BASLA:

for x=0 to 9
ADCIN 1, ADC
toplam=toplam+adc
next x

adc=toplam/10

voltage=(ADC*48)/10         'adc*4.88V
if voltage>=2500 then
amps=(voltage-2500)
y=(66/100)
amps=amps/y                 'amps/0.66 (30a için)
endif
if voltage<=2500 then
amps=(voltage-2500)
y=(66/100)
amps=amps/y
endif

'Buraya akım hesabı için yazmam gereken 32bit işlem sonucunu yazmam gerek.

LCDOUT $FE,$80," -I:",#amps
LCDOUT $FE,$C0," -V:",#voltage,"mV"
LCDOUT $FE,$94," -ADC:",#ADC
PAUSE 250

goto BASLA

END





ete

#1
ACS712 sensörü akım yönüne bağlı olarak 0-2,5V ve 2,5-5V arasında çekilen akıma bağlı olarak bir voltaj verir.
Bu voltajı herşeyden önce akım yönünden bağımsız okuyabilmek gerekir. Bunun yolu,
ADCIN 0,ADC
ADC=ABS(512-ADC) şeklindedir.  Bu komut okunan değer 512 den küçük ise 512-ADC karşılığını büyük ise adc-512 karşılığını verir.
Daha sonra çekilen maksimum akım 30 amper ise bunu direk ADC değerinden hesaplamak mümkündür. Bununda yolu,
300/511 =0,587084 (virgülden sonra 1 hane ondalık istiyoruz o nedenle 30 değil 300 ü böldüm.)
Bunu 256 ile çarparsak 150,29  gibi bir rakam elde ederiz bunu 1503 kabul edip sonucu 10 bölerek işimizi hallederiz.
Bu durumda akım hesabımız,
AKIM=(ADC */1503)/10  formülü ile hesaplanacaktır.
Basit bir örnek yapalım. Diyelimki okunan değer 511 olsun bunun karşılığında ben 30,0 amper akım hesaplamalıyım.
511 x 1503=768033    */ işlemi bize bu sayının 256 ya bölünmüş halini vereceği için 256 ya böleriz  3000 sayısını buluruz. Bunuda 10 a bölmeliyiz çünki 150,29 yerine 1503 kullandık yani 10 ile çarpılmış halini kullandık bir yerde.
Sonuç 300 olarak çıkacaktır.  Tam=300/10  Ondalık=300//10 şeklinde hesaplanabilir. Ekrana da;
LCDOUT $FE,$80,dec TAM,",",dec1 ONDALIK şeklinde yazdırılır.
Voltaj hesabına gerek yok aslında ama onuda anlatayım tam olsun.
511 değeri 2,5V karşılığı ADC den okunacak değer olacaktır. 25/511=0,0489236790606654 ve bunu 256 ile çarparsak 12,5244 gibi bir rakam buluruz. Bunu 1253 alıp sonucu 10 e bölersek virgülden sonra 2 hanesi olan ondalıklı voltaj değerini hesaplamış oluruz.
Senin sisteme bunu adapte etmek istersek;

BASLA:
TOPLAM=0 'bu komut eksik sende toplam değeri her okumadan önce sıfırlamaz isen bir sonraki hesap şaşar.
FOR X=0 to 9
ADCIN 1,ADC
TOPLAM=TOPLAM+ ABS(512-ADC)
NEXT
ADC=TOPLAM/10
Voltage=(ADC*/1253)/10

AMPS=(ADC*/1503)/10
LCDOUT $FE,$80," I= ",DEC amps,",",DEC1 AMPS//10
LCDOUT $FE,$C0," V= ",DEC VOLTAGE,",",DEC1 VOLTAGE//10
LCDOUT $FE,$94," ADC=",DEC ADC
PAUSE 100
GOTO BASLA


şeklinde olacaktır.

Ete


transistor

Merhaba Ete bey anlatımlarınızdan dolayı öncelikli olarak teşekkür etmek istiyorum.

Aslında 2 günden beri aralıklı olarak uğraşıyordum. Hesaplama formülü için birçok yöntem denemeye çalıştım belki doğru, belki yanlış ama sonuç olarak hep saçma rakamlar elde ettim. Şu verdiğiniz formül uygulandığında tek motor çalışıyor iken,

I=7,7
V=6,6
ADC=13

çift motor iken,

I=0
V=0
ADC=03

üç motor iken,

I=8,8
V=6,6
ADC=13

Halbuki proteus örneği verecek olursam bana şöyle diyor;

1 motor için değerler

I=1.0A
V=2.56V
ADC=525

2 motor için değerler ise

I=2.0A
V=2.63V
ADC=538

gibi değerler veriyor. Yani bir tuhaflık var gibi geliyor bana. Derleyicinin 32bit ve float olarak işlem yapamasından kaynaklanıyor sanki. Ne kadar 32bitlik sayıyı bir sonraki satıra kadar geçici tutsada genede bir yanlışlıklar oluyor herhalde. Değerler anormal yani çok ilgisiz görünüyor.


ete

#3
Programı ve isis devresini buraya koy bakayım. Tutarsızlık olduğu belli. Aynı ADC değeri ile farklı Akım değeri hesaplanmış olması dahada enteresan. Ya şemada bir terslik var yada programda. Programı çok iyi incelemedim tamamı bu ise incelerim buradan.
Aslında ACS712 sensörünün hangi düzeltilmemiş değerleri ekrana yazdırıp onları önce bir almak ona görede gerekirse dğzeltme faktörü eklemek gerekir. Teorik olarak bu sensör boşta 2,5 V ve karşılığında ADC değeri olarak da 511 vermesi gerekir. Ama pratikte aşağı veya yukarı doğru sapmaları olabiliyor. Üstelik işlemcinin ref voltajına bağlı olarak da değer değişebiliyor. Çok stabil bir beslemeniz olması ve yeterince güçlü olması gerekir.
Motora start verdikten sonra ilk 500 ms de okuma yapmamak gerekiyor. Çünki kalkış akımı motorlarda yüksektir. Daha sonra stabil hale gelir akım ondan sonra okunmalıdır.

Ete

transistor

Tamam Ete bey, dediğiniz gibi yaptım. Dosya ektedir.

ete

#5
Sorun programda en başta değişken tanımlama da imiş.

Aşağıdaki programı dene bakalım.

@ __config _BODEN_OFF  & _PWRTE_ON & _WDT_OFF & _LVP_OFF & _XT_OS

PORTA=0:TRISA=255
PORTB=0:TRISB=0
TRISC=%00000011 : PORTC=0
PORTD=0:TRISD=0
PORTE=0:TRISE=0

;*******************************************************************************
DEFINE LCD_DREG        PORTB   
DEFINE LCD_DBIT        4       
DEFINE LCD_RSREG    PORTB   
DEFINE LCD_RSBIT    2   
DEFINE LCD_EREG        PORTB   
DEFINE LCD_EBIT        3       
DEFINE LCD_BITS        4   
DEFINE LCD_LINES    4
;*******************************************************************************
DEFINE ADC_BITS 10
DEFINE ADC_CLOCK 3
DEFINE ADC_SAMPLEUS 50

ADCON1=%10000100  'ilk 3 kanal analog giriş oluyor mecburen.
;*******************************************************************************
adc       VAR WORD
amps      VAR WORD
voltage   VAR WORD
toplam    var word
x var byte
CLEAR
lcdout $fe,1
pause 500
;*******************************************************************************
BASLA:

TOPLAM=0 'bu komut eksik sende toplam değeri her okumadan önce sıfırlamaz isen bir sonraki hesap şaşar.
FOR X=0 to 9
ADCIN 1,adc
TOPLAM=TOPLAM+adc
NEXT
ADC=TOPLAM/10
adc=abs(511-adc)
Voltage=(ADC*/1253)/10

AMPS=(ADC*/1503)/10
LCDOUT $FE,$80," I= ",DEC amps,",",DEC1 AMPS//10," "
LCDOUT $FE,$C0," V= ",DEC VOLTAGE,",",DEC1 VOLTAGE//10," "
LCDOUT $FE,$94," ADC=",DEC ADC ," "
pause 200

GOTO BASLA

END

ABS(511-ADC) döngü içinde de olabilir sonradan da tatbik edilebilir. Aynı sonucu alırsın. Bu örnekte sonradan tatbik ettim.

ete

ete

gerçek devrede boşta bütün değerler sıfır olarak görülmez ise sensör boşta fazladan bir değer veriyordur.
Bazen 2,6v lara kadar boşta çıkış verebiliyor.  Bu durumda 511 denbüyük olan değeri çıkarman gerekecek .
Örnek vereyim boşta iken ADC=0 değilde  1-2-3-4-5 gibi bir değer veriyor ise bu farkı formülde çıkarman gerekecek. Diyelimki boşta, 5 çıkıyor.
TOPLAM=TOPLAM+(adc-5)
şeklinde uygularsan doğru sonuç elde edersin.

Ete

transistor

toplam değişkeni byte değil de word cinsinden de yazmıştım. Adcon1 registeri üzerinde ki değişiklikte herhangi bir değişiklik yaratmadı. Sonuç aynı görünüyor. Sensör boşta iken ham değer 511 olarak okunuyordu zaten. Bu değerleri kağıt kalemle yerlerine koyduğumda sonuçlar iyi görünüyor. Pic'in matematiğinde iş bozuluyor. Diğer derleyicilerde sorun olmuyor zaten. Bende matematiksel hesap yerine ham değerler üzerinden işlem yapmayı denedim çok yer kaplıyor ama ne kadar mantıklı bilmiyorum. Gerçekte ne yansıtır onuda bilmiyorum. Siz ne dersiniz?


IF HAM<=513 THEN AKIM=00 : IOND=0 : k=0 : w=0 : h=0 : p=0
IF HAM= 514 THEN AKIM=00 : IOND=1 : k=0 : w=0 : h=0 : p=0
IF HAM= 515 THEN AKIM=00 : IOND=2 : k=0 : w=0 : h=0 : p=0
IF HAM= 516 THEN AKIM=00 : IOND=3 : k=0 : w=0 : h=0 : p=0
IF HAM= 517 THEN AKIM=00 : IOND=4 : k=0 : w=0 : h=0 : p=0
IF HAM>=518 THEN AKIM=00 : IOND=5 : k=0 : w=0 : h=0 : p=0
IF HAM>=525 THEN AKIM=01 : IOND=0 : k=0 : w=0 : h=0 : p=0
IF HAM>=532 THEN AKIM=01 : IOND=5 : k=0 : w=75 : h=1 : p=0
IF HAM>=538 THEN AKIM=02 : IOND=0 : k=0 : w=75 : h=1 : p=0
IF HAM>=545 THEN AKIM=02 : IOND=5 : k=1 : w=1 : h=1 : p=5
IF HAM>=552 THEN AKIM=03 : IOND=0 : k=1 : w=1 : h=1 : p=5
IF HAM>=559 THEN AKIM=03 : IOND=5 : k=1 : w=5 : h=2 : p=0
IF HAM>=565 THEN AKIM=04 : IOND=0 : k=1 : w=5 : h=2 : p=0
IF HAM>=572 THEN AKIM=04 : IOND=5 : k=1 : w=5 : h=2 : p=0
IF HAM>=579 THEN AKIM=05 : IOND=0 : k=1 : w=5 : h=2 : p=0
IF HAM>=586 THEN AKIM=05 : IOND=5 : k=2 : w=2 : h=3 : p=0
IF HAM>=592 THEN AKIM=06 : IOND=0 : k=2 : w=2 : h=3 : p=0
IF HAM>=599 THEN AKIM=06 : IOND=5 : k=2 : w=2 : h=3 : p=0
IF HAM>=606 THEN AKIM=07 : IOND=0 : k=3 : w=2 : h=4 : p=0
IF HAM>=612 THEN AKIM=07 : IOND=5 : k=3 : w=2 : h=4 : p=0
IF HAM>=619 THEN AKIM=08 : IOND=0 : k=3 : w=2 : h=4 : p=0
IF HAM>=626 THEN AKIM=08 : IOND=5 : k=4 : w=0 : h=5 : p=5
IF HAM>=633 THEN AKIM=09 : IOND=0 : k=4 : w=0 : h=5 : p=5
IF HAM>=640 THEN AKIM=09 : IOND=5 : k=4 : w=0 : h=5 : p=0
IF HAM>=646 THEN AKIM=10 : IOND=0 : k=4 : w=0 : h=5 : p=0
IF HAM>=653 THEN AKIM=10 : IOND=5 : k=4 : w=0 : h=5 : p=0
IF HAM>=660 THEN AKIM=11 : IOND=0 : k=4 : w=0 : h=5 : p=0
IF HAM>=666 THEN AKIM=11 : IOND=5 : k=5 : w=5 : h=7 : p=5
IF HAM>=673 THEN AKIM=12 : IOND=0 : k=5 : w=5 : h=7 : p=5
IF HAM>=680 THEN AKIM=12 : IOND=5 : k=5 : w=5 : h=7 : p=5
IF HAM>=687 THEN AKIM=13 : IOND=0 : k=5 : w=5 : h=7 : p=5
IF HAM>=693 THEN AKIM=13 : IOND=5 : k=5 : w=5 : h=7 : p=5
IF HAM>=700 THEN AKIM=14 : IOND=0 : k=5 : w=5 : h=7 : p=5
IF HAM>=707 THEN AKIM=14 : IOND=5 : k=5 : w=5 : h=7 : p=5
IF HAM>=713 THEN AKIM=15 : IOND=0 : k=5 : w=5 : h=7 : p=5
IF HAM>=720 THEN AKIM=15 : IOND=5 : k=7 : w=5 : h=10 : p=0
IF HAM>=727 THEN AKIM=16 : IOND=0 : k=7 : w=5 : h=10 : p=0
IF HAM>=734 THEN AKIM=16 : IOND=5 : k=7 : w=5 : h=10 : p=0
IF HAM>=740 THEN AKIM=17 : IOND=0 : k=7 : w=5 : h=10 : p=0
IF HAM>=747 THEN AKIM=17 : IOND=5 : k=7 : w=5 : h=10 : p=0
IF HAM>=754 THEN AKIM=18 : IOND=0 : k=7 : w=5 : h=10 : p=0
IF HAM>=760 THEN AKIM=18 : IOND=5 : k=7 : w=5 : h=10 : p=0
IF HAM>=767 THEN AKIM=19 : IOND=0 : k=7 : w=5 : h=10 : p=0
IF HAM>=774 THEN AKIM=19 : IOND=5 : k=7 : w=5 : h=10 : p=0
IF HAM>=781 THEN AKIM=20 : IOND=0 : k=7 : w=5 : h=10 : p=0
IF HAM>=787 THEN AKIM=20 : IOND=5 : k=7 : w=5 : h=10 : p=0
IF HAM>=794 THEN AKIM=21 : IOND=0 : k=7 : w=5 : h=10 : p=0
IF HAM>=801 THEN AKIM=21 : IOND=5 : k=7 : w=5 : h=10 : p=0
IF HAM>=807 THEN AKIM=22 : IOND=0 : k=11 : w=0 : h=15 : p=0
IF HAM>=814 THEN AKIM=22 : IOND=5 : k=11 : w=0 : h=15 : p=0
IF HAM>=821 THEN AKIM=23 : IOND=0 : k=11 : w=0 : h=15 : p=0
IF HAM>=827 THEN AKIM=23 : IOND=5 : k=11 : w=0 : h=15 : p=0
IF HAM>=834 THEN AKIM=24 : IOND=0 : k=11 : w=0 : h=15 : p=0
IF HAM>=841 THEN AKIM=24 : IOND=5 : k=11 : w=0 : h=15 : p=0
IF HAM>=848 THEN AKIM=25 : IOND=0 : k=11 : w=0 : h=15 : p=0                       
IF HAM>=854 THEN AKIM=25 : IOND=5 : k=11 : w=0 : h=15 : p=0
IF HAM>=861 THEN AKIM=26 : IOND=0 : k=11 : w=0 : h=15 : p=0
IF HAM>=868 THEN AKIM=26 : IOND=5 : k=11 : w=0 : h=15 : p=0
IF HAM>=874 THEN AKIM=27 : IOND=0 : k=11 : w=0 : h=15 : p=0
IF HAM>=881 THEN AKIM=27 : IOND=5 : k=11 : w=0 : h=15 : p=0
IF HAM>=888 THEN AKIM=28 : IOND=0 : k=15 : w=0 : h=20 : p=0
IF HAM>=894 THEN AKIM=28 : IOND=5 : k=15 : w=0 : h=20 : p=0
IF HAM>=901 THEN AKIM=29 : IOND=0 : k=15 : w=0 : h=20 : p=0
IF HAM>=908 THEN AKIM=29 : IOND=5 : k=15 : w=0 : h=20 : p=0
IF HAM>=915 THEN AKIM=30 : IOND=0 : k=15 : w=0 : h=20 : p=0

ete

Sorun nedir anlamadım doğrusu. ? isis de sistem kusursuz çalışıyor gerçekte de çalışması gerekir. Bu sensörü gerçek devrelerde pek çokkez kulladım. Sorunum olmamıştı hiç. İsis de ne gördün ise gerçektede benzerini görebiliyorsun devrende bir kusur yok ise tabiiki.
Ete

transistor

Sorun nerede bende anlayamadım sadece tek bildiğim virgüllü sayılar ve 65535'i geçen sayılardan dolayı kaliteli olarak bir hesap gerçekleştiremiyorum. Her neyse, aşağıdaki devre tam sonuç vermese de yaklaşık değerleri gösterebilir gibi geliyor bana.  Yardımlarınız için teşekkür ederim.


ete

Kendi bildiğinde ısrarlısın anlaşılan. O zaman bildiğin yolda devam et demekten başka bir şey söyleyemem.
Programında olan eksiklikleri tamamlıyorum sen hala kendi eksik halini kullanmaktada ısrar ediyorsun.
Belki kusurların farkında değilsin.
Her programın bir açılış gecikmesi olur. Bu ortalama 150-300 ms arasında olmalıdır. Sebebi ise pic kendi registerlerini yerli yerine koyabilmek için zamana ihtiyacı vardır. Üstelik birde LCD kullanıyor isen onun ayrıca bir zamana ihtiyacı olur. Sana denk gelmemiş ama LCD yi initalize etmez isen bazen absuk subuk karekterler ile açılabilir yada hiç açılmayabilir. Bunun yolu LCDOUT $FE,1 komutunu verip peşine 150 ms gecikme koymaktan geçer.
Programda sigorta ayarları olmalıdır. Programlayıcılar veya derleyiciler default değerleri kullanır sana uymayabilir.

Verdiğim program sıkıntısız değerleri hesaplayıp ekrana veriyor idi. Sende ne oluyorda onu kullanmıyorsun ve bir sürü IF satırı ile idare etmeye çalışıyorsun bunu açıklamadın henüz. Yada açıklaman yetersiz. Sorun nedir derken bana sorunlu bir ekran görüntüsü verki anlayabileyim.
Anlamak zor değil. Varsa bir sorun bir sebebi vardır ve ekran görüntüsüne bakıp kolaylıkla bulunabilir.

PBP virgüllü sayılarla çalışmaz ama 32 bit matematik yapabilir. Sana yolunu gösterdim ama kafan başka yerde sanırım. Onuda anlamadın herhalde.
Devrende sensörden geçen akım saat yönünde ise okunan ADC değerleri 511 den büyük olur. Tersi ise 511 den küçük olur. Bunuda açıklmış idim.  Boşta adc değerin değişmez 511 dir. AKım çekildiğinde okunan değerler sıfıra doğru da gidebilir (akım yönüne bağlı olarak) 1023 e doğruda gidebilir.
Ya okunan adc değerine bakım 511 den büyük ise ADC=ADC-511 demen yada 511 den küçük ise bu seferde ADC=511-ADC demen gerekir.
Ama ADC=ABS(511-ADC) bu ikisinin yerine geçen bir komut seni iki tane if den kurtarıyor.
Şayet Okunan 511 den büyük ise ve sende 511-ADC dersen eksi sayılar bulman gerekir ama Pic basic bunu 65536-ADC olarak verir ve pozitif bir sayıdır. Bunu önlemek için ABS (Absolute değer) kulanmak zorundasın.
PBP da ** (çift çarpı) 32 bit çarpım yapar. Sonucu sana göstermez ama ara (tampon) bişr hafızada tutar ve hemen ardından bu tutlan değeri kullanma imkanı sağlar. Benzer şekilde */ işaretide solundaki sayı ile sağındakini çarpıp 256 ya bölünmüş halini verir.
Bunlar ondalıklı sayılarla çalışmanın püf noktalarıdır.
ADC ölçümünde voltaj ve akım hesapları 32 bit matematik gerektirir. Bu nedenle bende */ işlemcisini kullandım. Bana ADC değeri ile çarpacağım bir çarpan değeri gereklidir. Bunu hesaplarken işleme göre hesaplarım. ADC den 511 okuduğumda voltaj yada akım değerim sıfır olmalıdır. O halde bir defa okunan adc değerini 511 den çıkarmam (yada adc-511) yapmam lazım. Bu durumda benim 0- 2,5V luk aralık için okuyacağım ADC değerim 511-1023 aralığında veya 0-511 aralığında olacaktır.
Bunu teke indirmek için ADC=ABS(511-ADC) formülünü kullandık. Bu durumda okuyacağım değer 0-511 aralığında olacaktır.
O halde voltaj hesabında 2,5V hesap ederken bunu 25 olarak alıp ondalık bir hane kullanmaya imkan tanıyabilirim. 25V/511 işlemi bana çarpan hesabını verir. 0,0489236790606654 değeri ile okunan ADC değerini çarparsam bana o değere karşılık gelen volytajı verecektir.  Basit bir orantı ile bunu sağlayabilirsin. 511 ==> 25 e karşılık geliyor ise mesela 200 kaça denk gelir 200x(25/511) parantez içine aldığım işlem senin sabit çarpan değerindir.
Ondalıklı rakamla iş yapamayacağım için */ ile işlem yapabilmek için bu sayıyı 256 ile çarparm. Çünki */ işlemi çarpımdan sonra bana 256 ya bölünmüş halini verecektir. O halde öndceden 256 ile çarparak eşitliği bozmamış oluyorum.  Sonuç 12,52446 çıktı. Bunu 1253 olarak kullanarak sonucun 100 ile çarpılmış halini bulmu olacağım. Bu durumda */ işlemcisi ile kullanacağım sabit çarpanım 1253 olacak ama işlem sonucunda o sayıyı birde 100 e böleceğim ki eşitlik yine bozulmasın.
Bu kadar basit. Bu voltaj hesabı idi. Birde akım hesabı yapalım yeniden.
0-511 adc değeri bana 0-30A değeri verecek. Ondalık hesabı için 0-30 değil 0-300 olarak dikkate alalım bunu. O halde sabit çarpanım 300/511 =0,5870841487279843 dir bu sayıyı 256 ile çarpınca 150,29 gibi bir rakam buluruz. Bunuda 1503 şeklinde kullanıp sonucu 10 a böleriz olur biter.
Buda akım hesabındaki sabit çarpanın olacak.

Benden bu kadar. Sana kolay gelsin. Kafan neyi alıyor ise ona göre yaparsın artık.

Ete

aRci

hocam paylaştığınız kodları inceledim e bende şu şekilde ekran verdi.  hesaplamyı da yaptım ama eksik nedir bulamadım

not : sigorta ayarlarını derletmiyorum

ete


aRci


ete


Powered by EzPortal