Arduino Quick Start Guide ve Uygulama Örnekleri
Sümer Yamaner' Alıntı:
Zafer Bey'in son retract kodunu biraz anlamaya çalıştım. Aklıma şöyle bir şey geldi.
Şimdi akım sensörü için başlangıç değeri olarak 511 kullanılmış. Analog giriş çözünürlüğü 1024 adım mıdır Arduino'da? Yani sıfır Volt 0, besleme gerilimi yani 5V ise 1024 müdür? Doğru mu anlıyorum? Eğer böyle ise sorun yok çünkü sensör ile Arduino aynı kaynaktan besleniyorlar. Dolayısıyla mutlak gerilim değerlerinden çok göreceli değerler kullanıyor olmak işi kolaylaştırıyor. Ayrıca besleme gerilimindeki olası oynamalarda da sanki bir güvenlik sağlıyor gibi...
Şu an hem düşünüyor hem de yazıyorum. Yani yazılı düşünüyorum. Bağışlayın. Buraya nereden geldim. Sensör değeri olarak programda doğrudan değer atamak yerine motorlar kapalı haldeyken sensör çıkışını alıp sıfır Amper değeri olarak bunu kullanmayı düşünmüştüm. Ama yukarıda açıklamaya çalıştığım sebeplerle bu pek gerekli olmayacak anlaşılan.
Arduino Regüle edilmiş 5V(spesifik olarak USB portu voltajı ... ) ya da regüle edilmemiş 7V - 12V (9 Voltluk pil, 2S - 3S lipo pil...) kullanabilir. Regüle edilmemiş voltaj ile beslendiğinde, kartın üzerindeki regülatör devreye girerek, voltajı sabit bir 5 Volta düşürür.
ACS serisi akım ölçerlerin datasheet'ine baktığımızda ise şu şekilde bir durum var. ACS serisi akım ölçerler için filtrelenmiş 4.5V - 5.5V giriş voltajı gerekiyor. Dar bir aralıktaki giriş voltajı, ölçüm sonuçlarında, yanı çıkış değerlerinde pek bir fark yaratmıyor.
Ek bir not olarak, tüm sensörlerin, kartların (-) uçlarını birleştirdiğimiz için, "floating voltage" yani referans gerlimlerinin birbirinden faklı olması nedeni ile gerlimlerin yanlış ölçülmesi sorunu yaşamıyoruz.
Arduinonun analog uclarında 10 bitlik ADC kullanıldığında dolayı, sizin de farkettiğiniz üzere çözünürlük 1024.Ama uçlardan okunabilecek değer aralığı 0V - 5V ile sınırlı. Dijital değer skalası da 1 - 1024 değil, 0 - 1023. Direnç net'deki ACS712'ler -5A ve +5A arasındaki değerleri okuyorlar. ACS712'ler, çıkış voltajı olarak -5A için 0V , 0A için 2.5V, +5A için 5V üretiyor, tabii iki datasheet'e bakılarak kayma değerleri de hesaba katılmalı. Yazdığım kodda da (kayma değerlerini hesaba katmadım, datasheet'e bakarak bunlar da hesaba katılmalı)buna uygun olarak, L293D'nin verebileceği yaklaşık maksimum akım olan -1000mA ve +1000mA değerlerini zorlama değeri olarak kabul ederek, 0 - 1023 skalasında bu değerlere yaklaşık karşılık gelen değerleri, limit olarak tanımladım.
Sümer Yamaner' Alıntı:
Pratik olarak retractları üç değil iki konumlu butona atamayı tercih ediyorum. Yani açık ve kapalı konumları olsa yeterli. Stop konumuna gerek yok bence. Yani kodu biraz daha basitleştirmek mümkün olur sanıyorum.
3 pozisyonlu anahtardaki durdurma kodunu ise, kodda yanlışlık durumunda, sistemi yakmadan, retratları durdurabilmek amacı ile koydum. Nihai kodda bu olmayacak ama şu anda kod biraz ham olduğundan gözden kaçan bir şey olabilir. Ama genede sadelik amacı ile şimdilik koddan çıkardım
Sümer Yamaner' Alıntı:
Ve son bir ukalalık...
Sadece üç adet subroutine olsa:
Retract open
Retract close
Retract stop
Her biri kendi içinde iki retracta birden kumanda etse ve akım izlemesini yapsa. Her iki tarafın akımını kestikten sonra geri dönse.
İlk önce ben de o şekilde yapmıştım. Ama üzerinde biraz düşününce şu durumların ortaya çıkacağını farkettim.
- Malzemelerdeki ufak tefek farklılıklarda dolayı, asla iki retract aynı anda açılmayacak ve kapanmayacak.
- Düşme, çarpma ve tozlanma gibi yıpratıcı etkiler, bir retractın diğerinden farklı çalışmasına yol açacak.
- Arıza gibi durumlarda, arızalı ve sağlam tarafa aynı muammeleyi yapmak, sağlam tarafında düzgün çalışmamasına yol açacak.
Dolayısı ile her retract'ı bağımsız olarak değerlendirmenin, nihai üründe en sağlıklı sonucu ortaya çıkaracağı sonucuna vardım. Tabi birbirinden bağımsız çalıştırılacak iki ayrı retract'tı, tek "Thread"a sahip arduino üzerinde yapabilmek için kodu "non-blocking" olarak yazmak gerekiyor. Bu da işi karışık hale getiriyor. Ben de kodun anlaşılır kalmasını sağlamak için şimdilik kodda tek yarıyı yazıyorum.
Sümer Yamaner' Alıntı:
İlk aşamada timer konusuna hiç girmeden devam etsek benim gibi acemilerin kodu çözebilmelerini kolaylaştırır gibime geliyor ne dersiniz?
Timer'lara da güle güle
. Onlar olmayınca kod da bayağı rahatladı.
Kod:
/* Retract Project for RCKolik
by Zafer SAHIN
License of this example code is TEA-WARE.
modified 11/01/2015 by Zafer SAHIN
Version 0.23.4h - Codename "Half of the apple"
*/
int motor_left[] = {3, 11}; // Arduino pins for controlling left retract motor
int rxPin = 12; // Arduino pin for receiver pin
int curentSensorLeft = 2; // Arduino analog pin for left motor current sensor
int curretValLeft = 512; // Analog reading for 0A current reading from ACS712 sensor
// These values are purely dependent on the current sensor and the load. Tweaked for ACS712 bidirectional current sensor
// and L293D motor drives. Further tweak might be necessary.
int currentLimitLOW = 409; // Current values bigger than 1000mA to the negative direction.
int currentLimitHIGH = 614; // Current values bigger than 1000mA to the positive direction.
int retractLeftState = 0 ; // Variable to hold left retract position, open = 1, closed = -1
unsigned long rxPWMduration; // Variable for reading receiver
void setup() {
pinMode(motor_left[0], OUTPUT);
pinMode(motor_left[1], OUTPUT);
retractLeftStop();
delay(5000);
rxPWMduration = pulseIn(rxPin, HIGH);
while (rxPWMduration < 800) {
delay(1000);
rxPWMduration = pulseIn(rxPin, HIGH);
}
delay(1000);
if (rxPWMduration > 1500) {
retractLeftState = 1;
} else {
retractLeftState = -1;
}
}
void loop() {
rxPWMduration = pulseIn(rxPin, HIGH);
curretValLeft = analogRead(curentSensorLeft);
// This switch position is for opening the retracts
if (rxPWMduration > 1500) {
// Left Retract Operations
if (retractLeftState == 1) { // If we are already in retractState = 1, do NOTHING, stop retract motor.
retractLeftStop();
} else { // If we are not in retractState = 1, because we are switched from another state just yet, open retracts, and sense current to stop.
retractLeftOpen();
if ((curretValLeft < currentLimitLOW) || (curretValLeft > currentLimitHIGH)) {
retractLeftState = 1;
}
}
// This switch position is for closing the retracts
} else {
// Left Retract Operations
if (retractLeftState == -1) { // If we are already in retractState = -1, do NOTHING, stop retract motor.
retractLeftStop();
} else { // If we are not in retractState = -1, because we are switched from another state just yet, open retracts, and sense current to stop.
retractLeftClose();
if ((curretValLeft < currentLimitLOW) || (curretValLeft > currentLimitHIGH)) {
retractLeftState = -1;
}
}
}
}
void retractLeftOpen(){ // Function for opening Left Retract
digitalWrite(motor_left[0], HIGH);
digitalWrite(motor_left[1], LOW);
}
void retractLeftClose(){ // Function for closing Left Retract
digitalWrite(motor_left[0], LOW);
digitalWrite(motor_left[1], HIGH);
}
void retractLeftStop(){ // Function for stopping Left Retract
digitalWrite(motor_left[0], LOW);
digitalWrite(motor_left[1], LOW);
}
Düzenleme : Servolar da gitti...