ACS712 RÖLE KONTROL

Başlatan muyat, 28 Ekim 2021, 09:57:42

muyat

MErhabalar.
1 adet 16f688 ,2 adet röle ,2 adet dc  motor ve 2 adet acs712 kullanarak motor kontrolü yapıyorum.Motorların zorlandıgı zaman durması gereken ortak akımı trimpotla ayarlıyorum. Programımın mantıgı şöyle:
-Butona basınca motorlar çalışacak.Fakat ilk kalkışta çekilen akımlar yüksek oldugundan,motorlar çalıştıktan sonra 750 ms bekleme süresi verdim.
-Sonrasında for next döngüsünde program çalışıp acs712leri kontrol ediyor.
-Diyelimki motorun biri zorlanma akımını gördü motor o an hemen stop etmicek, 500ms daha çalışacak.işte o an program tekrar o motorun acs712sini okumaya gidip geri döndügünde akım hala zorlanma akımında veya o akımın üstünde ise o motor o zaman duracak.'--------- kesikli  çizgilerle belirttim yazılımda.Böylelikle çok kısa süreli zorlanmalarda motor durmamış olacak.Şayet motorlar hiç zorlanmazsa 6-7 saniye sonra motorlar kendiliginden duracak.
Şİmdi soru şu:
Aşagıdaki kodlarda motorlar aynı anda zorlanıp zorlanma akımını gördügünde yazılım 2.motoru görene kadar 2.motor zorlanma akımında 500ms değil 1000ms kalmış oluyor.Aşagıdaki mantıkla ben 4 motor kullanırsam ve motorlar aynı anda zorlanma akımını görürse 4.motorun durmasına sıra gelene kadar 4.motor en az 2000ms zorlanma akımında kalmış olacak.Çünkü program for next döngüsü içinde zorlanma ile karşılaşılan yerlerde 500 ms bekliyor bu durumda
Bu problemi nasıl çözebiliriz.Sanırım en kesin çözüm her bir işlemci için farklı işlemci kullanmak ama bu problemi bir tek işlemciyle nasıl çözebilirim.

'****************************************************************
'*  Name    : UNTITLED.BAS                                      *
'*  Author  : [select VIEW...EDITOR OPTIONS]                    *
'*  Notice  : Copyright (c) 2021 [select VIEW...EDITOR OPTIONS] *
'*          : All Rights Reserved                               *
'*  Date    : 9.02.2021                                         *
'*  Version : 1.0                                               *
'*  Notes   :                                                   *
'*          :                                                   *
'****************************************************************

@ __config _INTRC_OSC_NOCLKOUT & _WDT_OFF & _MCLRE_OFF & _CP_OFF

CMCON0=7                               'komparatörler kapalı  16F688
DEFINE OSC 4 

DEFINE ADC_BITS 10 
DEFINE ADC_CLOCK 3
DEFINE ADC_SAMPLEUS 50 
ANSEL  = %00011111  ' AN6 ANALOG, DİĞERLERİ DİJİTAL, 
OPTION_REG.7=0
ADCON1=%10000000
ADCON0=%10000000 ' internal A/D module RC oscillator          
OSCCON=%01101110        'İNTERNAL OSİLATÖRÜ 4mhz' E AYARLA

TRISA=%00111111         '
TRISC=%00000001 

SYMBOL BEYAZ=PORTA.5           'BUTON BUTON

SYMBOL TRIMPOT=PORTA.4'                      AN3 POTTANS GİRİŞ


symbol ROLE3=PORTC.3
SYMBOL ACS3=PORTA.1  'ANALOG GİRİŞ       AN1

symbol ROLE4=PORTC.5
SYMBOL ACS4=PORTA.0  'ANALOG GİRİŞ         AN0



SAYIM VAR WORD
SAYAC VAR BYTE
OKUNAN1 VAR WORD
OKUNAN2 VAR WORD
OKUNAN3 VAR WORD
OKUNAN4 VAR WORD
HAMS VAR WORD
HAMS2 VAR WORD
HAM1 VAR WORD
HAM2 VAR WORD
HAM3 VAR WORD
HAM4 VAR WORD

SURE VAR WORD
TOPLAM VAR WORD
K VAR WORD
I VAR WORD


PORTC=0
PORTA=0
PAUSE 250
CLEAR

PAUSE 200

BASLA:

GOSUB TRIMPOTOKU 
HAMS2=(HAMS*/1279)/10 

IF BEYAZ=0 THEN
WHILE BEYAZ=0:WEND
PAUSE 50
GOSUB CALISTIR
ENDIF

GOTO BASLA


CALISTIR:

ROLE3=1
ROLE4=1
PAUSE 750    'ilk kalkış akımı yüksek oldugundan biraz beklesin


for K=0 to 650

GOSUB ACS3OKU
OKUNAN3=ABS(HAM3-511)

GOSUB ACS4OKU
OKUNAN4=ABS(HAM4-511)


IF ROLE3=1 AND OKUNAN3>HAMS2 THEN
PAUSE 500         '---------------------------------------------------
GOSUB ACS3OKU
OKUNAN3=ABS(HAM3-511)
IF OKUNAN3>HAMS2 THEN
ROLE3=0
ENDIF
ENDIF

IF ROLE4=1 AND OKUNAN4>HAMS2 THEN
PAUSE 500               '--------------------------------------
GOSUB ACS4OKU
OKUNAN4=ABS(HAM4-511)
IF OKUNAN4>HAMS2 THEN
ROLE4=0
ENDIF
ENDIF

PAUSE 1
NEXT

CIK:

ROLE3=0
PAUSE 1000
ROLE4=0
PAUSE 1000
RETURN


TRIMPOTOKU:
TOPLAM=0
        FOR I=0 TO 29
           ADCIN 3,HAMS
           TOPLAM=TOPLAM+HAMS
           PAUSEUS 10
        NEXT   
        HAMS=TOPLAM/30
        I=0
        TOPLAM=0
  RETURN
  

  
  
  
ACS3OKU:
TOPLAM=0
        FOR I=0 TO 29
           ADCIN 1,HAM3
           TOPLAM=TOPLAM+HAM3
           PAUSEUS 10
        NEXT   
        HAM3=TOPLAM/30
        I=0
        TOPLAM=0
  RETURN
  
ACS4OKU:
TOPLAM=0
        FOR I=0 TO 29
           ADCIN 0,HAM4
           TOPLAM=TOPLAM+HAM4
           PAUSEUS 10
        NEXT   
        HAM4=TOPLAM/30
        I=0
        TOPLAM=0
  RETURN  
  
  
END

Hattuşa

usta ben olsam 500ms veya 1sn lik  bir timer interrupt kurar bunun içinde akımı sürekli kontrol ederdim.
for döngüsü programı sürekli bir yerde oyalar

ete

Gecikmeleri pause ile yaratarak bu işi yapmak mümkün olamaz. Doğru mantık tmr1 sayacı ile 500 ms lik gecikme döngüleri yaratarak bu döngü sonunda akım kontrollerini yapmak. Kim kontrol edilecek ise ona ait bir bir değişkeni set etmek ve döngü sonunda hangi bit set ise ona ait akıma bakmak çözüm olabilir.
Ete

ete

Programa 3 adet değişken eklenecek. KES (Byte) , Say3 (Byte), Say4 (Byte)
sonra program aşağıdaki şekilde değiştirilecek,
BASLA:
      GOSUB TRIMPOTOKU 

      IF BEYAZ=0 THEN GOSUB CALISTIR
      GOTO BASLA

CALISTIR: 
        ROLE3=1
        ROLE4=1
        PAUSE 750    'ilk kalkış akımı yüksek oldugundan biraz beklesin
        WHILE BEYAZ=0:WEND
        PAUSE 50
ZAMAN:
      T1CON=%00110001:KES=14:SAY3=0:SAY4=0  'KES=14 DEĞER 7 SANİYE SÜREYE DENK GELİYOR HER BİR KESME 500 MS
ZAMAN_BIR:
          TMR1H=$0B:TMR1L=$DC:PIR1.0=0
          WHILE PIR1.0=0
            GOSUB ACS3OKU       
            GOSUB ACS4OKU
            IF ROLE3=1 AND AND SAY3=0 AND OKUNAN3>HAMS2 THEN SAY3=1
            IF ROLE4=1 AND SAY4=0 AND OKUNAN4>HAMS2 THEN THEN SAY4=1
          WEND
          IF SAY3=1 THEN 
              GOSUB ACS3OKU
              IF OKUNAN3>HAMS2 THEN
                  SAY3=0:ROLE3=0
              ENDIF
          ENDIF
           
          IF SAY4=1 THEN
             GOSUB SAY4OKU
             IF OKUNAN4>HAMS2 THEN
                SAY4=0:ROLE4=0
          ENDIF
                       
          KES=KES-1:IF KES>0 THEN ZAMAN_BIR
          ROLE3=0:ROLE4=0
          PAUSE 500
          RETURN     

TRIMPOTOKU:
TOPLAM=0
        FOR I=0 TO 29
           ADCIN 3,HAMS
           TOPLAM=TOPLAM+HAMS
           PAUSEUS 10
        NEXT   
        HAMS=TOPLAM/30
        I=0
        HAMS2=(HAMS*/1279)/10 
  RETURN
  
ACS3OKU:
        TOPLAM=0        
        FOR I=0 TO 29
           ADCIN 1,HAM3
           TOPLAM=TOPLAM+HAM3
           PAUSEUS 10
        NEXT   
        HAM3=TOPLAM/30
        I=0
        OKUNAN3=ABS(HAM3-511)
        RETURN
  
ACS4OKU:
        TOPLAM=0
        FOR I=0 TO 29
           ADCIN 0,HAM4
           TOPLAM=TOPLAM+HAM4
           PAUSEUS 10
        NEXT   
        HAM4=TOPLAM/30
        I=0
        OKUNAN4=ABS(HAM4-511)
  RETURN  
  
  
END
bu şekilde olması gerek. Mantık şöyle
Röle çektirilince her biri 500 ms lik peryotlar ile çalışan 14 peryotluk bir sayac çalıştırıyoruz.
Sayacın 500 ms lik dilimleri içinde çekilen akımları kontrol ediyoruz. Aşan var ise o röleye ait zaman sayacını set ediyoruz (Say3 veya Say4) aslında verdiğimiz 1 değeri 500 ms lik gecikmeye denk gelecek. 500 ms lik süre sonunda set edilmiş sayac var ise onun akımını kontrol edip aşma var ise röleyi kapatıyoruz zira set ile ikinci okuma arasında 500 ms lik zaman dilimi geçmiş oluyor zaten.
aşma hiç yok ise zaten sistem 7 sn sonra kendiliğinden kapanmış oluyor.
hepsi bu kadar.

Ete



muyat

Ete hocam teşekkürler.
Öncelikle tmr1 sayıcını şimdiye kadar hiç kullanmadıgım bilmedigim için okuyup anlamaya çalışıyorum 2 gündür yorum yazmadım.
Sadece anlamadıgım kısım şurası :
  WHILE PIR1.0=0
            GOSUB ACS3OKU       
            GOSUB ACS4OKU
            IF ROLE3=1 AND AND SAY3=0 AND OKUNAN3>HAMS2 THEN SAY3=1
            IF ROLE4=1 AND SAY4=0 AND OKUNAN4>HAMS2 THEN THEN SAY4=1
          WEND
Yukardaki kod ile  evet 500msnin dolmasını bekliyoruz.Demekki bu while wend döngüsünde program 0'dan 500e kadar sayıyor.Yani ben öyle oldugunu düşünüyorum.
Diyelimki o döngüde  bu sayım esnasında sayım 0,1,2,3.........500 diye devam ederken sayı tam 498 iken o sırada örnegin say3=1 olursa veya hem say3=1 hem de say4=1 olursa o zaman program 499,500 diye devam edip wend satırından çıkar çıkmaz acs'yi okuyup ilgili röle veya röleyi hemen 0 yapcak.
Yani yazdıgınız kodlardan ben şu an onu anladım..Ama benım istedigim o değil:İlgili röle veya röleler say3=1 veya say4=1 olursa veya her ikisi de 1 olursa röleler hemen sıfır olmamalı..İlgili röledeki yükün akımından oluşan deger en az 500ms boyunca hams2 degerinin üzerine çıkarsa ancak o zaman 0 olmalı.Yani motora yük en az 500ms binerse öyle durmalı motor.Motora yük 300ms binerse motor durmamalı..
Ona göre tekrar inceler misiniz?Ben mi yanlış yorumladım acaba?


ete

#5
Sistem senin düşündüğün gibi çalışmıyor.
TMR1 sayacına bir ön yükleme değeri veriyoruz. Bölme oranını ayarlıyoruz. Başla dediğimiz zaman yani T1CON registerinin 0 nolu bitini 1 yapınca sayac saymaya başlıyor. Nerden sayıyor her pic osilatiründen clk palsi alarak sayıyor. Değeri 65535 i aşar aşmaz PIR1.0 biti o anda 1 oluyor ve while - wend döngüsü sona eriyor. 0-500 arasında sayan bir şey yok anlayacağın. us bazında sayma var. Önyükleme değerimiz 3036 bundan başlıyor saymaya. sayarken her 8 adet clk palsinde sayac bir artıyor. Çünki bölme oranımız 1/8. Bu durumda 65536-3036=62500 adet sayma yapıyor her 8 clk palsinde bir saydığı için 8 x 62500 =500.000 us saymış oluyor. İşin temeli bu.
Bu açıklama üzerinden dediklerini yeniden düşün istersen.
While - wend döngüsü 0-500.000 arasında sayma yapıyor teorik olarak. Ancak değer daha sıfırlarda iken işin başında akımın aştığını yakalar diye umuyorum. Yok sürenin sonunda yakalar dersen SAY3=1 yerine SAY3=2 verirsin ve her kesme sonunda say3=say-1 dersin ve
       IF SAY3=1 THEN
              GOSUB ACS3OKU
              IF OKUNAN3>HAMS2 THEN
                  SAY3=0:ROLE3=0
              ENDIF
          ENDIF
satırlarını
       IF SAY3=0 THEN
              GOSUB ACS3OKU
              IF OKUNAN3>HAMS2 THEN
                  SAY3=0:ROLE3=0
              ENDIF
          ENDIF
şeklinde değiştirirsin. Bu şekilde garanti 500 ms geçirmiş olursun belkide biraz fazlasını. Bu işi başka türlü halletmek mümkün değil zaten.

ete

Powered by EzPortal