semih_s
Hobici
- Katılım
- 16 Aralık 2020
- Mesajlar
- 1,968
Merhabalar.
Ömrümü yiyen projeyi tamamladım. Umduğumdan daha zahmetli oldu. Yeterli zaman olmaması ve üzerinde seyrek çalışmak kod yazmayı güçleştiriyor. Bir de kod yazmadan evvel iş akışını modellemek lazım. Birbiriyle girdi-çıktı alışverişi olan fonksiyonlarla çalışırken bodoslama kodlama girmek işi çok zorlaştırdı ve hata ayıklamayı da zorlaştırdı.
3 kere kontrol kartını değiştirmem gerekti. 2 tane Step sürücü yaktım, step sürücü koruma kartı ekledim sonra projeye.
Aslında bir kapının iki nokta arasında açılıp kapanmasını sağlamak çok da zor değil. Benim kalkıştığım şey parametrik bir yapı ile çalışmaktı. Yapı parametreleri belli bir uygulamayı, seri monitörden hız, limit, hızlanma, yavaşlama, kapı açıklığı vb. kontrol parametrelerini düzenleyerek kodlama yapmadan uygulanabilir olmalı. Neyse ki bugün tamamladım.
Bunun bir de aküsü var, henüz gelmedi. 7Ah bir kuru aküyle 5 saat çalışmasını bekliyorum. Kapı kapalı durağa geldikten 1 saniye kadar sonra stepper akımını kesiyorum.
Şöyle bir arayüzü var:
Github'a kılavuz şeklinde de ekleyeceğim nasip olursa düzenleyip.
Enkoder 5GT kayış dişlisi iki parça. Asetonla birleştiriliyor. stl ve fusion360 dosyaları ekledim. Diğer Yazıcıda yazdırılmış parçalar aşağıda. F360 dosyalarını eklledim.
Benim için zahmetli tarafı kodlama oldu. Dağınık çalışmanın çok zararı oldu. Kod tek dosyada.
Ömrümü yiyen projeyi tamamladım. Umduğumdan daha zahmetli oldu. Yeterli zaman olmaması ve üzerinde seyrek çalışmak kod yazmayı güçleştiriyor. Bir de kod yazmadan evvel iş akışını modellemek lazım. Birbiriyle girdi-çıktı alışverişi olan fonksiyonlarla çalışırken bodoslama kodlama girmek işi çok zorlaştırdı ve hata ayıklamayı da zorlaştırdı.
3 kere kontrol kartını değiştirmem gerekti. 2 tane Step sürücü yaktım, step sürücü koruma kartı ekledim sonra projeye.
Aslında bir kapının iki nokta arasında açılıp kapanmasını sağlamak çok da zor değil. Benim kalkıştığım şey parametrik bir yapı ile çalışmaktı. Yapı parametreleri belli bir uygulamayı, seri monitörden hız, limit, hızlanma, yavaşlama, kapı açıklığı vb. kontrol parametrelerini düzenleyerek kodlama yapmadan uygulanabilir olmalı. Neyse ki bugün tamamladım.
Bunun bir de aküsü var, henüz gelmedi. 7Ah bir kuru aküyle 5 saat çalışmasını bekliyorum. Kapı kapalı durağa geldikten 1 saniye kadar sonra stepper akımını kesiyorum.
Şöyle bir arayüzü var:
Github'a kılavuz şeklinde de ekleyeceğim nasip olursa düzenleyip.
Enkoder 5GT kayış dişlisi iki parça. Asetonla birleştiriliyor. stl ve fusion360 dosyaları ekledim. Diğer Yazıcıda yazdırılmış parçalar aşağıda. F360 dosyalarını eklledim.
Benim için zahmetli tarafı kodlama oldu. Dağınık çalışmanın çok zararı oldu. Kod tek dosyada.
Kod:
/*
* V2.0
*
* hızlanma ve yavaşlamada hedef konuma belli bir mesafede
* minimum hıza düşülmesi için çalışılacak.
*
*/
#include <Arduino.h>
#include <EEPROM.h>
//durumlar
#define KAPALI 0
#define ACIK 1
#define ACILIYOR 2
#define KAPANIYOR 3
#define BASLANGIC 4
//Parametreler
// timer prscl
// timer1 stepper motor kontrolü için.
// timer2 ultrason okuma ve süre sinyali için.
// timer0 arduino default kütüphane ve fonksiyonlarında kullanılıyor
#define PRSCL1 0b10 // prscl>> 0b10:8 0b11:64 0b100:256 0b101:1024
#define PRSCL2 0b111 // prscl: 0b10:8 0b11:32 0b100:64 0b101:128 0b110:256 0b111:1024
#define YON_AC -1 //1 veya -1 encoder defaultu için.
#define StepperAdimTur 200
#define StepperTurMm 75 // stepper 1 turda yürünen km
#define MicroStep 32
#define GuvenliHiz 75 // mm/sn
// Hizlanma için stepper frekansının saniyede kaç kez güncelleneceği
#define Ivme_Time_Base 20 // ivmeli hareket sırasın hızın saniyede kaç kez güncelleneceği
// stepper kontrol timer'i için saniyedeki tik sayısı,
uint32_t fTimer;
// prescaler göre böleni
uint16_t bolen;
// >>> 1mm/sn için gerekli frekans <<<, hızlanma ve hız değerlerinin frekans cinsinden yazılması için katsayı
// fAnlik=fCarpani* HIZ (mm/sn) veya fHizlanma=fCarpani * HIZLANMA (mm / time_base^2) ... gibi
uint32_t fCarpani;//=StepperAdimTur*MicroStep/StepperTurMm;
/*Parametrelerden kullanılabilir sabitler üretmeli
// açılma ivmesiyle kapanma ivmesi farklı olmalı, ya da maks hızları farklı olmalı
*/
#define ultra1 9
#define ultra1_OKU ((PINB>>1)&1)
/*
#define ultra2 10
#define ultra2_OKU ((PINB>>2)&1)
*/
#define ultra3 11
#define ultra3_OKU ((PINB>>3)&1)
#define echo 12
#define echo_OKU ((PINB>>4)&1)
//step sürücü enable girişine bağlı io
#define enablePin 8
#define enablePin_OKU (PINB&1)
#define enablePin_HIGH (PORTB|=1<<0)
#define enablePin_LOW (PORTB&=~(1<<0))
//step sürücü dir (yön) girişine bağlı io
#define dirPin 7
#define dirPin_OKU ((PIND>>7)&1)
#define dirPin_HIGH (PORTD|=1<<7)
#define dirPin_LOW (PORTD&=~(1<<7))
//step sürücü step pulse girişine bağlı io
#define stepPin 10
// açlık konum limit sensörünün bağlı olduğu io
#define acikPin 4
#define acikPin_OKU ((PIND>>4)&1)
// kapalı konum limit sensörünün bağlı olduğu io
#define kapaliPin 6
#define kapaliPin_OKU ((PIND>>6)&1)
// yedek-rezerve giriş veya çıkış için io
#define yedekPin A5
// enkoder sinyal bacaklarının bağlı olduğu io
// external interrupt fonksiyonu olan io
#define encA 3
#define encB 2
// Besleme gerilimini ölçen io analog giriş
#define V_SENSE A0
#define KORUMA A3
// yedek-rezerve giriş veya çıkış için io
#define DEBUGPIN A4 // debug jumper kısa devreyse (logic low) debug modda çalışacak
#define BUZZER A2 // buzzer bağlı io
#define vStep A1 // step sürücüye güç veren röleye bağlı io
#define surePin A6 // kapı açık süresini belirleyen trimpota bağlı analog giriş
// temel fonksiyonlar
void encoder (void); // encoder okuma konum takibi
void ultrason(void); // ultrason sensörünü okur ve sinyal çıkışı verir
void kapi(void); // kapiyi yönetir sensör fonksiyonunun
void hareket(void); // stepper motoru yönetir konum değişkenini sadece bu fonksiyon değiştirir
void saniye20(void) ; // ultrason yerine başka bir sensör kullanıldığında zaman yönetimi için
// yardımcı fonksiyonlar
void stepStart(byte onoff); // stepperi başlatma veya dururma
int yonOku(void); // stepper yon durumunu okur
void setYon(int8_t acKapa); // stepper yönü ayarla
int sureOku(void); // kapı açık kalma süresini okur
void hizlan(void); // step motor hız arttır, step periyodunu azaltır
void yavasla(void); // step motor hız düşür, step periyodunu arttırır
void timerInit(void); // timerları yapılandır
void timer1Ac(byte onoff); // timer1 kontrolü
void timer2Ac(byte onoff); // timer2 kontrolü
// Menu fonksiyonları
void anaMenu (void); // Ana menu
int seriOku (void); // seri port inputunu okur
void girilenDeger(int deger); // seriporttan okunan değeri teyit için yazdırır.
void ayarMenu (int8_t onoff);
void hareketMenu (int8_t onoff);
// Parametreler güvenli başlangıç ayarları
uint16_t hizlanma=500;
uint16_t fHizlanma,fYavaslama,fAniYavaslama;
uint16_t yavaslama=600;
uint16_t aniYavaslama=1000;
uint16_t acmaHizi=1000;
uint16_t kapanmaHizi;
uint16_t guvenliHiz=GuvenliHiz;
uint16_t minHiz=50;
uint32_t fKapa,fAc,fAnlik,fMin,fGuvenli;
uint16_t ocrMin=150;
uint16_t ocrMax;
int16_t limAcikToKapali=375;
int16_t limAcikToAcik=40;
int16_t limKapaliToKapali=40;
uint16_t yavasMesafesi=100;
uint16_t mesafeEsik=30;
int8_t enc,enc1,hedefYon,acikSure;
int16_t konum,hedef,seriOkunan,farkKonum,hedef0;
uint8_t durum,menuBuff,menu,durumBayrak,debugMode,ofv2,limAcik,limKapali,snUp=1,hedefUp;
long konumS; // atılan adımları takip eder, enkoderle karşılaştırıp adımkaçırmayı test eder.
uint32_t t0,t1;
uint8_t asama,u,sn20,sn20up,sn4,sn4up,acikSayaci,stepGucKesSayaci,sinyal,adimUp,u0Bayrak,u1Bayrak;
uint8_t indis0,indis1;
unsigned long mesafe[2] = {300,300};
uint8_t ultra[2] = {ultra1, ultra3};
int buffint;
uint16_t buffUint1,hizTampon;
ISR(TIMER2_OVF_vect)
{
ofv2++;
}
ISR(TIMER1_COMPB_vect) // stepper adımı
{
konumS++;
}
void setup()
{
Serial.begin(115200);
// stepper kontrol io
pinMode(stepPin, OUTPUT);
pinMode(dirPin, OUTPUT);
pinMode(enablePin, OUTPUT);
// kontrol io
pinMode(KORUMA, OUTPUT);
pinMode(vStep,OUTPUT);
pinMode(BUZZER,OUTPUT);
// sensör io
pinMode(ultra1, OUTPUT);
pinMode(ultra3, OUTPUT);
pinMode(echo, INPUT); //pull up yok devrede pulldown direnç var
pinMode(acikPin, INPUT_PULLUP);
pinMode(kapaliPin, INPUT_PULLUP);
pinMode(encA, INPUT_PULLUP);
pinMode(encB, INPUT_PULLUP);
pinMode(V_SENSE,INPUT);
pinMode(surePin, INPUT);
pinMode(LED_BUILTIN, OUTPUT);
pinMode(DEBUGPIN,INPUT_PULLUP);
//başlangıç değer atamaları
uint16_t bolen;
switch(PRSCL1)
{
case 0b1: bolen = 1;break;
case 0b10: bolen = 8;break;
case 0b11: bolen = 64;break;
case 0b100: bolen = 256;break;
case 0b101: bolen = 1024; break;
default: bolen = 65000; break;
}
enc = digitalRead(encB) + (digitalRead(encA) << 1);
enc1=enc;
konum=0;
hedefYon=0;
// Stepper etkinleştirme;
delay(100);
digitalWrite(KORUMA, LOW);
digitalWrite(vStep,LOW);
Serial.println(F("Stepper gucu kapali"));
delay(500);
digitalWrite(enablePin,HIGH);
Serial.println(F("surucu cikislari kapali"));
digitalWrite(vStep,HIGH);
Serial.println(F("Stepper gücü acik"));
delay(500);
digitalWrite(KORUMA, HIGH);
Serial.println(F("step motor bagli"));
delay(500);
digitalWrite(enablePin,LOW);
Serial.println(F("surucu cikislari acik"));
delay(100);
EEPROM.get(0,hizlanma);
EEPROM.get(2,yavaslama);
EEPROM.get(4,acmaHizi);
EEPROM.get(6,kapanmaHizi);
EEPROM.get(8,minHiz);
EEPROM.get(10,limAcikToKapali);
EEPROM.get(12,limAcikToAcik);
EEPROM.get(14,limKapaliToKapali);
EEPROM.get(16,yavasMesafesi);
EEPROM.get(18,mesafeEsik);
EEPROM.get(20,aniYavaslama);
// gerekli frekansı timer periyoduna çevirmek için gerekli parametre
// timer periyodu(timer tik cinsinden)= fTimer/ gerekli frekans
fTimer=F_CPU/bolen;
// Paramereleri kalibre et
fCarpani=StepperAdimTur*MicroStep/StepperTurMm;
fHizlanma=fCarpani*hizlanma/Ivme_Time_Base;
fYavaslama=fCarpani*yavaslama/Ivme_Time_Base;
fAc=fCarpani*acmaHizi;
fKapa=fCarpani*kapanmaHizi;
fMin=fCarpani*minHiz;
fGuvenli=fCarpani*guvenliHiz;
ocrMax=fTimer/fMin;
timerInit();
stepStart(0);
// vvvvvvvvvvvv başlangıç ayarlarından sonra tanımla vvvvvvvvvvvv
attachInterrupt(digitalPinToInterrupt(encA), encoder, CHANGE);
attachInterrupt(digitalPinToInterrupt(encB), encoder, CHANGE);
// debug pini oku ve sonrasında parametrelerin debugMode uygun değerlerini ata
debugMode=!digitalRead(DEBUGPIN);
if(debugMode)
{
Serial.println(F("DEBUG MODE AÇIK"));
menu=1; // debug modda doğrudan ayarlara girer kontrolsüz çalışmaz
}
/*else
{
Serial.println(F("DEBUG MODE KAPALI"));
Serial.print(F("Ayarlar icin '1'e bas"));
Serial.println();
menuBuff=4;// ayar menusune girmek için geri sayım değişkeni
while(menuBuff>0)
{
seriOku();
if((millis()-t0)>1000)
{
t0=millis();
Serial.println(menuBuff); //menuye giriş için kalan süreyi yazdır.
Serial.println();
menuBuff--;
}
if(Serial.available() > 0)
{
seriOkunan= Serial.parseInt(); // serial oku
if(seriOkunan==1)
{
menu=1;
menuBuff=0; // while dongusunu bitir
}
}
}
}*/
ayarMenu(menu);
// gerekli frekansı timer periyoduna çevirmek için gerekli parametre
// timer periyodu(timer tik cinsinden)= fTimer/ gerekli frekans
fTimer=F_CPU/bolen;
// Paramereleri kalibre et
fCarpani=StepperAdimTur*MicroStep/StepperTurMm;
fHizlanma=fCarpani*hizlanma/Ivme_Time_Base;
fYavaslama=fCarpani*yavaslama/Ivme_Time_Base;
fAc=fCarpani*acmaHizi;
fKapa=fCarpani*kapanmaHizi;
fMin=fCarpani*minHiz;
fGuvenli=fCarpani*guvenliHiz;
ocrMax=fTimer/fMin;
timerInit();
stepStart(0);
if(acikPin_OKU)
{
durum=ACIK;
konum=limAcikToAcik+limAcikToKapali;
hedef=-limKapaliToKapali;
}
else if(kapaliPin_OKU)
{
durum=KAPALI;
konum=-limKapaliToKapali;
hedef=limAcikToKapali+limAcikToAcik;
}
else
{
hedef=konum+2000;
hizTampon=fAc;
fAc=fGuvenli;
while(hedef>konum)
{
hareket();
saniye20();
if(acikPin_OKU)hedef=konum; //açık switch aktif şartı
}
fAc=hizTampon;
stepStart(0);
konum=limAcikToKapali;
hedef=limAcikToKapali+limAcikToAcik;
durum=ACIK;
}
Serial.print(F("Rutin"));
// while(1);
}
void loop()
{
kapi();
ultrason();
hareket(); // encoder, limitswitch ve tork switch. okuma
// put your main code here, to run repeatedly:
}
void encoder (void)
{
//enc = digitalRead(encB) + (digitalRead(encA) << 1);
enc = (PIND>>2)&0b11; // PORTD2 ve PORTD3'e bağlı encoder bacaklarını okur
if (enc1 != enc) //encoder değişmişse işlem yap
{
switch (enc1)
{
case 0b00: switch (enc)
{
case 0b01: konum+= YON_AC; break;
case 0b10: konum-= YON_AC;; break;
default: break;
}
break;
case 0b01: switch (enc)
{
case 0b11: konum+= YON_AC; break;
case 0b00: konum-= YON_AC; break;
default: break;
}
break;
case 0b11: switch (enc)
{
case 0b10: konum+= YON_AC; break;
case 0b01: konum-= YON_AC; break;
default: break;
}
break;
case 0b10: switch (enc)
{
case 0b00: konum+= YON_AC; break;
case 0b11: konum-= YON_AC; break;
default: break;
}
break;
default: enc1 = enc; break;
}
enc1 = enc;
if(konum==hedef)
{
stepStart(0);
}
}
}
void ultrason(void)
{
switch (asama) //
{
case 0: //ultrasona sinyal verme
//Serial.println("asama0");
timer2Ac(1);
digitalWrite(ultra[u], HIGH);
asama = 1;
break;
case 1:
if (TCNT2 > 2) // 10us'den uzun ultrason trigger pulse
{
digitalWrite(ultra[u], LOW);
}
// eğer echo pin HIGH ise
if(echo_OKU||(ofv2>0))
{
buffint=ofv2*256+TCNT2+1;
asama=2;
}
break;
case 2:
// echo pin low ise veya uzun süre beklendiyse çalışır
// sensörde hata varsa veya sinyal emildiyse gereksiz yere beklememek için
// ölçümü sonlandırır, süreci devam ettirir
if ((echo_OKU == 0)||(ofv2>2))
{
mesafe[u] = ofv2*256+TCNT2-buffint;
mesafe[u] *= 9;
mesafe[u] >>= 3; // "/8" mesafe hesaplandı
asama = 3;
}
break;
case 3:
// TCNT2 3 kez overflow olunca çalışır (saniyede 20 kez)
if (ofv2 > 2)
{
timer2Ac(0);
sn20++; //zaman sayacı saniyede 10 kez artar
sn20up=1; // 1/20 saniye bayrağı
u++; // sonraki sensöre geçiş
if (u > 1)u = 0; // iki sensör arasında çevrim
asama=0; // yeni ölçüm başlatmak için aşamayı sıfırlar.
if(sn20>4) // saniyede 4 kere çalışır
{
sn20=0;
sn4++; // 250ms sayacı
sn4up++; // 250ms bayrağı
}
if(sn4>3) // her saniye çalışır
{
sn4=0;
if(durum==ACIK)
{
acikSayaci++; // açık süresi değişkeni
}
else
acikSayaci=0;
// Kapı açık veya kapalıyken stepper etkinse stepGucKesSayaciı arttır yoksa 0'la
if((durum==ACIK)||(durum==KAPALI))
{
if(enablePin_OKU==0)
{
stepGucKesSayaci++; // stepperı kapama geri sayım değişkeni
}
else stepGucKesSayaci=0;
}
if(debugMode){
switch (durum)
{
case ACIK:Serial.println(F("ACIK"));break;
case KAPALI:Serial.println(F("KAPALI"));break;
case BASLANGIC:Serial.println(F("BASLANGIC"));break;
case ACILIYOR:Serial.println(F("ACILIYOR"));break;
case KAPANIYOR:Serial.println(F("KAPANIYOR"));break;
default: Serial.println(F("NULL"));break;
}
Serial.print(F("konum="));Serial.println(konum);
Serial.print(F("hedef="));Serial.println(hedef);
}
}
// eğer sensörlerden biri eşik mesafesinden düşükse sinyal üretir
if(mesafe[0]<mesafeEsik)
{
if(u0Bayrak)
{
sinyal=1;
}
u0Bayrak=1;
}
else u0Bayrak=0;
if((mesafe[1]<mesafeEsik))
{
if(u1Bayrak)
{
sinyal=1;
}
u1Bayrak=1;
}
else u1Bayrak=0;
}
break;
}
}
void kapi(void)
{
if(durum==ACIK)
{
if(debugMode)
{
if(durumBayrak!=ACIK){
Serial.println(F("Acik"));
durumBayrak=ACIK;
}
}
acikSure=sureOku();
if(sinyal>0)
{
sinyal=0;
acikSayaci=0;
}
else
{
if(acikSure<acikSayaci)
{
// kapalı konum limswitch "0" lim switch ten sonra tam kapanma konumu -limkapalitokapali
//burada sadece hedef konum belirleniyor,
//durum değişikliği hareket fonksiyonunda tayin ve kontrol ediliyor
hedef=-limKapaliToKapali;
if(debugMode)
{
Serial.print(F("A>K Hedef="));
Serial.println(hedef);
}
}
}
}
else if(durum==KAPANIYOR)
{
if(debugMode)
{
if(durumBayrak!=KAPANIYOR){
Serial.println(F("kapaniyor"));
durumBayrak=KAPANIYOR;
}
}
// kapanırken açık limit switch falling edge interrupt
if ((limAcik != acikPin_OKU)&&limAcik)
{
konum = limAcikToKapali;
}
// encoder hatası ihtimalini göz önünde bulundurarak kapalı limit switch konumunu güncelleme
// rising edge interrupt
if ((limKapali != kapaliPin_OKU)&&(limKapali==0))
{
konum=0;
}
if(konum<=-limKapaliToKapali)
{
durum=KAPALI;
}
if(sinyal>0)
{
hedef=limAcikToKapali+limAcikToAcik;
sinyal=0;
if(debugMode){
Serial.print(F("KyS"));
Serial.println(hedef);
}
}
if(acikPin_OKU)
{
if(yonOku()==0) durum=ACIK;
}
}
else if(durum==ACILIYOR)
{
if(debugMode){
if(durumBayrak!=ACILIYOR){
Serial.println(F("aciliyor"));
durumBayrak=ACILIYOR;
}
}
// açik limit switch için rising edge software interrupt
//if ((limAcik != digitalRead(acikPin))&&(limAcik==0))
if ((limAcik != acikPin_OKU )&&(limAcik==0))
{
konum=limAcikToKapali;
}
// falling edge interrupt kapıyı açarken kapali switch için düşen kenar kritik
//if ((limKapali != digitalRead(kapaliPin))&&(limKapali))
if ((limKapali != kapaliPin_OKU )&&(limKapali))
{
konum=0;
}
if(konum>=limAcikToKapali+limAcikToAcik)
{
durum=ACIK;
}
if(kapaliPin_OKU)
{
if(yonOku()==0)durum=KAPALI;
}
}
else if(durum==KAPALI)
{
if(debugMode){
if(durumBayrak!=KAPALI){
Serial.println(F("kapali"));
durumBayrak=KAPALI;
}
}
if(sinyal>0)
{
if(debugMode){
Serial.println(F("K>A S"));
}
hedef=limAcikToKapali+limAcikToAcik;
sinyal=0;
}
}
// kapı hareketsiz kaldığında stepper akımını kes
if ((durum == ACIK) || (durum == KAPALI))
{
if (stepGucKesSayaci > 2) // 2saniye sonunda stepper akımını kes
{
digitalWrite(enablePin, HIGH);
}
}
//Software PC interrupt için limit switch durumlarını kaydetme
limAcik=acikPin_OKU;
limKapali=kapaliPin_OKU;
}
void hareket(void)
{
/* sadece konum ve hedefle ilgilenir ve kapıya gerekli hareketi verir*/
if(hedef0!=hedef) // hedef değişmişse parametreleri baştan hesapla
{
hedef0=hedef;// şimdi parametreleri hesapla
}
farkKonum=hedef-konum;
if(farkKonum>0) hedefYon=1;
else if(farkKonum<0) hedefYon=-1;
else hedefYon=0;
if(sn20up) // motor hızlanma, yavaşlama, durma, yön değiştirme, etkinleştirme saniyede 20 kere
{
int8_t yonG = yonOku();
adimUp=0;
sn20up=0;
if(abs(farkKonum)>0)
{
if((hedefYon!=yonG)||(abs(farkKonum)<yavasMesafesi))// hedef yon mevcuttan farklıysa veya durağa yaklaşıldıysa
{
if(OCR1A>=ocrMax) // yeterince yavasladıysa
{
if((hedefYon!=yonG))// yon, hedefyonden farklıysa
{
if(hedefYon==1)//açılma yönüne yon değiştir
{
setYon(1);
durum=ACILIYOR;
}
else if(hedefYon==-1)//kapanma yönüne yön değiştir
{
setYon(-1);
durum=KAPANIYOR;
}
}
}
yavasla();
}
else if ((hedefYon==yonG)&&(abs(farkKonum)>yavasMesafesi))
{
hizlan();
}
}
else stepStart(0); //hedef=konum ise abs(farkkonum)=0 ise
}
}
void stepStart(byte onoff)
{
switch (onoff)
{
case 1: //stepper saatini 0'la ve aç, stepper akımını aç
OCR1A=ocrMax;
fAnlik=fMin;
enablePin_LOW;
TCNT1 = 0;
TCCR1B |= PRSCL1; // prescaleri aç
break;
case 0: //stepper saatini durdur
OCR1A=ocrMax;
fAnlik=fMin;
TCCR1B &= ~0b111;// prescaleri 0'la
TCNT1 = 0;
break;
}
}
int sureOku(void)
{
// acik kalma süresi minimum 1 saniye ile max 5 saniye arasında değişmeli
int16_t sureAcik;
sureAcik=analogRead(surePin);
sureAcik=analogRead(surePin);
sureAcik/=250;
sureAcik+=1; // max 1024/250+1=5sn, min 1sn
return sureAcik;
}
int yonOku(void)
{
int8_t yon;
if(!(TCCR1B&PRSCL1)) yon=0; // timer 2 kapalıysa
else if( dirPin_OKU ==1){yon=1;}
else if( dirPin_OKU ==0){yon=-1;}
return yon;
}
void setYon(int8_t acKapa)
{
stepGucKesSayaci=0;
if(acKapa==1) {dirPin_HIGH;stepStart(1);}//digitalWrite(dirPin,HIGH);
else if(acKapa==-1) {digitalWrite(dirPin,LOW);/*dirPin_LOW;*/stepStart(1);}// digitalWrite(dirPin,LOW);
else if(acKapa==0) stepStart(0);
}
void timerInit(void)
{
// Stepper kontrolü için değişken frekanslı pwm olarak kullanılır
// Hızlanma-yavaşlama ve max-min hız kontrolleri
TCCR1A = 0;// eğer varsa arduino presetlerini silmek için registerler sıfırlanır
TCCR1B = 0;
TIMSK1 = 0;
TIMSK1|= 1<<OCIE1B; // her adımlamada interrupt gerçekleştir
TCCR1A |= 1<<COM1B1 | 1<<WGM11 | 1<< WGM10;
TCCR1B |= 1<<WGM12 | 1<<WGM13 ;
OCR1A = ocrMax;
OCR1B = 15;
// timer2 ultrason sensörlerini hesaplamak için kullanılacak
// Arduino default değerlerini iptal etmek için sıfırlama
TCCR2A=0;
TCCR2B=0;
TIMSK2= 0;
}
void timer1Ac(byte onoff) // sadece debugging için kullanılıyor
{
if (onoff == 0)
{
TCCR1B &= ~0b111;
TCNT1 = 0;
}
else
{
TCNT1=0;
TCCR1B |= PRSCL1;
}
}
void timer2Ac(byte onoff)
{
if (onoff == 0)
{
TCCR2B &= ~0b111;
TIMSK2&=~(1<<TOIE2);
TCNT2 = 0;
ofv2=0;
}
else
{
TCCR2B |= PRSCL2;
TIMSK2 |= 1<<TOIE2;
TCNT2=0;
ofv2=0;
}
}
void hizlan(void)
{
if(durum==ACILIYOR)
{
if(fAnlik<fAc)
{
fAnlik+=fHizlanma; //hizlnamaya karsilik gelen frekans artisi yapıldı
if(fAnlik>fAc) fAnlik=fAc; //
OCR1A=fTimer/fAnlik; //hesaplanan hiz icin OCR1A tayin edildi
}
}
else if(durum==KAPANIYOR)
{
if(fAnlik<fKapa)
{
fAnlik+=fHizlanma; //hizlnamaya karsilik gelen frekans artisi yapıldı
if(fAnlik>fKapa) fAnlik=fKapa; //
OCR1A=fTimer/fAnlik; //hesaplanan hiz icin OCR1A tayin edildi
}
}
}
void yavasla(void)
{
if(fAnlik>2*fMin)
{
//yavasla
fAnlik-=fYavaslama; //hizlnamaya karsilik gelen frekans artisi yapıldı
}
else fAnlik=fMin;
OCR1A=fTimer/fAnlik; //hesaplanan hiz icin OCR1A tayin edildi
}
int seriOku (void)
{
if(Serial.available() > 0)
{
seriOkunan= Serial.parseInt();
}
return seriOkunan;
}
void anaMenu (void)
{
Serial.println(F("----"));
Serial.println(F("> AYAR MENU < "));
Serial.println();
Serial.print(F("1-Hizlanmayi ayarla (10-1000) mm/sn^2, mevcut deger= "));
Serial.println(EEPROM.get(0 ,buffUint1));
Serial.print(F("2-Yavaslamayi ayarla (10-1000) mm/sn^2, mevcut deger= "));
Serial.println(EEPROM.get(2,buffUint1));
Serial.print(F("3-Acilma hizini ayarla (10-2000) mm/sn, mevcut deger= "));
Serial.println(EEPROM.get(4,buffUint1));
Serial.print(F("4-Kapanma hizini ayarla (100-2000) mm/sn, mevcut deger= "));
Serial.println(EEPROM.get(6,buffUint1));
Serial.print(F("5-Minimum hizi ayarla (10-1000) mm/sn, mevcut deger= "));
Serial.println(EEPROM.get(8,buffUint1));
Serial.print(F("6-Minimum hiz mesafesi ayarla mm. (10-200), mevcut deger= "));
Serial.println(EEPROM.get(16,buffUint1));
Serial.print(F("7-Sensor Esik Mesafesini Ayarla, mevcut deger= "));
Serial.println(EEPROM.get(18,buffUint1));
Serial.print(F("8-limAcikToAcik mesafesini Ayarla, mevcut deger= "));
Serial.println(EEPROM.get(12,buffUint1));
Serial.print(F("9-limKapaliToKapali mesafesini Ayarla, mevcut deger= "));
Serial.println(EEPROM.get(14,buffUint1));
Serial.print(F("10-limAcikToKapali mesafesini Ayarla, mevcut deger= "));
Serial.println(EEPROM.get(10,buffUint1));
Serial.println(F("11-Kontrollü Hareket"));
Serial.println(F("12-ultrason test"));
Serial.println(F("99- Meduden Cikis"));
Serial.println();
}
void girilenDeger(int deger)
{
Serial.println();
Serial.print(F("Girilen Deger= "));
Serial.println(deger);
Serial.println();
delay(1500);
}
void hareketMenu (int8_t onoff)
{
if(onoff){
Serial.println(F(">Kontrollü Hareket< "));
Serial.print(F("konum="));
Serial.println(konum);
Serial.println();
Serial.println(F("1-Acik limit switch'e git"));
Serial.println(F("2-Kapali limit swithce git"));
Serial.println(F("3-Kontrollu ilerleme"));
Serial.println(F("9-Cikis"));
Serial.println();
}
}
void ayarMenu (int8_t onoff)
{
anaMenu();
while (menu)
{
indis0=seriOku();
seriOkunan=0;
switch(indis0)
{
case 0: break;
case 1:
Serial.print(F("1-Hizlanma yeni deger gir mm/sn^2 (10-1000), geri icin '-1' gir, mevcut deger= "));
Serial.println(EEPROM.get(0 ,buffUint1));
while(seriOku()==0);
switch (seriOkunan)
{
case -1:
seriOkunan=0;
break;
default:
if ((seriOkunan>=10)&&(seriOkunan<=1000))
{
hizlanma=seriOkunan;
EEPROM.put(0,hizlanma);
girilenDeger(hizlanma);
fHizlanma=hizlanma*fCarpani/Ivme_Time_Base;
seriOkunan=-1;
}
else
{
Serial.print(seriOkunan);
Serial.println(F(">>gecersiz giris"));
}
break;
}
indis0=0;
seriOkunan=0;
anaMenu();
break;
case 2:
Serial.print(F("2-Yavaslama yeni deger gir mm/sn^2 (10-1000), geri icin '-1' gir, mevcut deger= "));
Serial.println(EEPROM.get(2,buffUint1));
while(seriOku()==0);
switch (seriOkunan)
{
case -1:
seriOkunan=0;
break;
default:
if ((seriOkunan>=10)&&(seriOkunan<=1000))
{
yavaslama=seriOkunan;
EEPROM.put(2,yavaslama);
girilenDeger(yavaslama);
fYavaslama=yavaslama*fCarpani/Ivme_Time_Base;
seriOkunan=-1;
}
else
{
Serial.print(seriOkunan);
Serial.println(F(">>gecersiz giris"));
}
break;
}
indis0=0;
seriOkunan=0;
anaMenu();
break;
case 3:
Serial.print(F("3-Acilma hizi yeni deger gir mm/sn (100-1000), geri icin -1 gir, mevcut deger= "));
Serial.println(EEPROM.get(4,buffUint1));
while(seriOku()==0);
switch (seriOkunan)
{
case -1:
seriOkunan=0;
break;
default:
if ((seriOkunan>=10)&&(seriOkunan<=1000))
{
acmaHizi=seriOkunan;
EEPROM.put(4,acmaHizi);
girilenDeger(acmaHizi);
fAc=acmaHizi*fCarpani;
seriOkunan=-1;
}
else
{
Serial.print(seriOkunan);
Serial.println(F(">>gecersiz giris"));
}
break;
}
indis0=0;
seriOkunan=0;
anaMenu();
break;
case 4:
Serial.print(F("4-Kapanma hizi yeni deger gir mm/sn (100-1000), geri için -1 gir, mevcut deger= "));
Serial.println(EEPROM.get(6,buffUint1));
while(seriOku()==0);
switch (seriOkunan)
{
case -1:
seriOkunan=0;
break;
default:
if ((seriOkunan>=100)&&(seriOkunan<=1000))
{
kapanmaHizi=seriOkunan;
EEPROM.put(6,kapanmaHizi);
girilenDeger(kapanmaHizi);
fKapa=kapanmaHizi*fCarpani;
seriOkunan=-1;
}
else
{
Serial.print(seriOkunan);
Serial.println(F(">>gecersiz giris"));
}
break;
}
indis0=0;
seriOkunan=0;
anaMenu();
break;
case 5:
Serial.print(F("5-Minimum hizi Ayarla mm/sn (10-1000), geri için -1 gir, mevcut deger= "));
Serial.println(EEPROM.get(8,buffUint1));
while(seriOku()==0);
switch (seriOkunan)
{
case -1:
seriOkunan=0;
break;
default:
if ((seriOkunan>=10)&&(seriOkunan<=1000))
{
minHiz=seriOkunan;
fMin=seriOkunan*fCarpani;
EEPROM.put(8,minHiz);
girilenDeger(minHiz);
seriOkunan=-1;
}
else
{
Serial.print(seriOkunan);
Serial.println(F(">>gecersiz giris"));
}
break;
}
indis0=0;
seriOkunan=0;
anaMenu();
break;
case 6:
Serial.print(F("6-Minimum hiz mesafesi yeni deger gir mm. (10-200), geri için -1 gir, mevcut deger= "));
Serial.println(EEPROM.get(16,buffUint1));
while(seriOku()==0);
switch (seriOkunan)
{
case -1:
seriOkunan=0;
break;
default:
if ((seriOkunan>=10)&&(seriOkunan<=200))
{
yavasMesafesi=seriOkunan;
EEPROM.put(16,yavasMesafesi);
girilenDeger(yavasMesafesi);
seriOkunan=-1;
}
else
{
Serial.print(seriOkunan);
Serial.println(F(">>gecersiz giris"));
}
break;
}
indis0=0;
seriOkunan=0;
anaMenu();
break;
case 7:
Serial.print(F("7-Sensor Esik Mesafesini yeni deger gir cm. (10-500), geri için -1 gir, mevcut deger= "));
Serial.println(EEPROM.get(18,buffUint1));
while(seriOku()==0);
switch (seriOkunan)
{
case -1:
seriOkunan=0;
break;
default:
if ((seriOkunan>=10)&&(seriOkunan<=500))
{
mesafeEsik=seriOkunan;
EEPROM.put(18,mesafeEsik);
girilenDeger(mesafeEsik);
seriOkunan=-1;
}
else
{
Serial.print(seriOkunan);
Serial.println(F(">>gecersiz giris"));
}
break;
}
indis0=0;
seriOkunan=0;
anaMenu();
break;
case 8:
Serial.print(F("8-limAcikToAcik mesafesi yeni deger gir (enc), geri için -1 gir, mevcut deger= "));
Serial.println(EEPROM.get(12,buffUint1));
while(seriOku()==0);
switch (seriOkunan)
{
case -1:
seriOkunan=0;
break;
default:
if ((seriOkunan>0)&&(seriOkunan<10000))
{
limAcikToAcik=seriOkunan;
EEPROM.put(12,limAcikToAcik);
girilenDeger(limAcikToAcik);
seriOkunan=-1;
}
else
{
Serial.print(seriOkunan);
Serial.println(F(">>gecersiz giris"));
}
break;
}
indis0=0;
seriOkunan=0;
anaMenu();
break;
case 9:
Serial.print(F("9-limKapaliToKapali mesafesi yeni deger gir (enc), geri için -1 gir, mevcut deger= "));
Serial.println(EEPROM.get(14,buffUint1));
while(seriOku()==0);
switch (seriOkunan)
{
case -1:
seriOkunan=0;
break;
default:
if ((seriOkunan>0)&&(seriOkunan<10000))
{
limKapaliToKapali=seriOkunan;
EEPROM.put(14,limKapaliToKapali);
girilenDeger(limKapaliToKapali);
seriOkunan=-1;
}
else
{
Serial.print(seriOkunan);
Serial.println(F(">>gecersiz giris"));
}
break;
}
indis0=0;
seriOkunan=0;
anaMenu();
break;
case 10:
Serial.print(F("8-limAcikToKapali mesafesi yeni deger gir (enc), geri için -1 gir, mevcut deger= "));
Serial.println(EEPROM.get(10,buffUint1));
while(seriOku()==0);
switch (seriOkunan)
{
case -1:
seriOkunan=0;
break;
default:
if ((seriOkunan>0)&&(seriOkunan<10000))
{
limAcikToKapali=seriOkunan;
EEPROM.put(10,limAcikToKapali);
girilenDeger(limAcikToKapali);
seriOkunan=-1;
}
else
{
Serial.print(seriOkunan);
Serial.println(F(">>gecersiz giris"));
}
break;
}
indis0=0;
seriOkunan=0;
anaMenu();
break;
case 11:
hareketMenu(1);
Serial.println();
Serial.print(F("acik lim= "));
Serial.println(digitalRead(acikPin));
Serial.print(F("kapali lim= "));
Serial.println(digitalRead(kapaliPin));
Serial.println();
while (indis0==11)
{
indis1=seriOku();
seriOkunan=0;
switch (indis1)
{
case 1: // açık switche git
Serial.println(F("açık switche gidiyor."));
if(acikPin_OKU)
{
Serial.println(F("zaten açık switchte"));
}
else
{
hedef=konum+2000;
Serial.print(F("hedef= "));Serial.println(hedef);
hizTampon=fAc;
fAc=fGuvenli;
Serial.print(F("Freq= "));Serial.println(fAc);
while(hedef>konum)
{
hareket();
saniye20();
if(acikPin_OKU)hedef=konum; //açık switch aktif şartı
}
stepStart(0);
fAc=hizTampon;
Serial.print(F("Acık Switch konumu="));
Serial.println(konum);
Serial.println();
}
seriOkunan=0;
indis1=0;
hareketMenu(1);
break;
case 2: // Kapalı switche git
if(kapaliPin_OKU)
{
Serial.println(F("zaten kapalı switchte"));
}
else
{
Serial.println(F("Kapalı switche gidiyor."));
hedef=konum-2000;
Serial.print(F("hedef= "));Serial.println(hedef);
hizTampon=fKapa;
fKapa=fGuvenli;
Serial.print(F("Freq= "));Serial.println(fKapa);
while(hedef<konum)
{
hareket();
saniye20();
if(kapaliPin_OKU) hedef=konum; //kapalı switch aktif şartı
}
stepStart(0);
fKapa=hizTampon;
Serial.print(F("Kapalı Switch konumu="));
konum=0;
hedef=0;
Serial.println(konum);
Serial.println();
}
seriOkunan=0;
indis1=0;
hareketMenu(1);
break;
case 3:
Serial.println(F("Adim gir(enkoder) Acma pozitif, kapatma negatif, önceki menu:999"));
Serial.print(F("Konum="));
Serial.println(konum);
Serial.println();
seriOkunan=0;
while(indis1==3)
{
while(seriOku()==0);
girilenDeger(seriOkunan);
if(seriOkunan>=999)
{
indis0=11;
indis1=0;
hareketMenu(1);
}
else
{
hedef=konum+seriOkunan;
Serial.print(F("konum="));
Serial.print(konum);
Serial.print(F(" hedef="));
Serial.println(hedef);
Serial.println();
/*
if(hedef>konum)
{
dirPin_HIGH;
Serial.print(F("dirpinHigh="));
Serial.println(digitalRead(dirPin));
}
else if(hedef<konum)
{
dirPin_LOW;
Serial.print(F("dirpinLow="));
Serial.println(digitalRead(dirPin));
}
*/
while(hedef!=konum)
{
hareket();
saniye20();
/*
for(uint16_t i=0;i<65000;i++)
{
digitalWrite(stepPin,HIGH);
delayMicroseconds(100);
digitalWrite(stepPin,LOW);
delayMicroseconds(100);
encoder();
if(hedef==konum)
{
Serial.println(i);
i=65000;
}
}*/
}
Serial.print(F("konum="));
Serial.print(konum);
Serial.println();
Serial.println(F("Adim gir(enkoder) Acma pozitif, kapatma negatif, önceki menu:999"));
Serial.println();
stepStart(0);
}
seriOkunan=0;
}
break;
case 9:
indis0=0;
indis1=0;
seriOkunan=0;
anaMenu();
break;
default: break;
}
}
break;
case 12:
// ultrason çıktısını okuma
Serial.print(F("Cıkıs icin 1'e bas"));
seriOkunan=0;
while(seriOkunan!=1)
{
ultrason();
if(sn4up>0)
{
sn4up=0;
Serial.print(F("1.sensor= "));
Serial.println(mesafe[0]);
Serial.print(F("2.sensor= "));
Serial.println(mesafe[1]);
}
seriOku();
}
indis0=0;
seriOkunan=0;
anaMenu();
break;
case 99:
menu=0;
seriOkunan=0;
break;
default :
seriOkunan=0;
hareketMenu(1);
break;
}
indis0=0;
}
}
//ultrason yerine başka bir sensör kullanıldığında veya sadece zaman yönetimi için
void saniye20(void)
{
switch (asama) //
{
case 0:
timer2Ac(1);
asama=1;
break;
case 1:
if(ofv2>2)
{
sn20++; //zaman sayacı saniyede 10 kez artar
sn20up=1; // 1/20 saniye bayrağı
if(sn20>4) // saniyede 4 kere çalışır
{
sn20=0;
sn4++; // 250ms sayacı
sn4up++; // 250ms bayrağı
}
if(sn4>3) // her saniye çalışır
{
sn4=0;
snUp=1;
if(durum==ACIK)
{
acikSayaci++; // açık süresi değişkeni
}
else
acikSayaci=0;
}
asama=0;
}
break;
default:
asama = 0;
break;
}
}
Ekler
-
demo küçük.mp44.7 MB
-
15kanal_Hedef ölçülerde.stl84.8 KB · Görüntüleme: 185
-
encoder Tutar.stl121.7 KB · Görüntüleme: 174
-
encoder_buffer.v1.pdsprj22.1 KB · Görüntüleme: 135
-
5GT15x13,5.stl471.3 KB · Görüntüleme: 153
-
otomatik kapı v5_enc interrupt.pdsprj49.3 KB · Görüntüleme: 192
-
baskı alt bakır.pdf69.6 KB · Görüntüleme: 221
-
baskı üst bakır.pdf60.4 KB · Görüntüleme: 210
-
baskı üst silk.pdf20.4 KB · Görüntüleme: 205