Dijital Ay Çiçeği: Güneşe Dik

Bkz 1. Bölüm:  Dijital Ay Çiçeği #1 // 8000$ Değerinde post


Önceki bölümde, olayın genel mantığından bahsetmiş ve kodlarda kullanacağımız değişkenleri tanımlamıştık.

Ardından, sadece ilk seferinde çalışacak olan setup kodlarımızı yazmıştık.

Son duruma toplu halde bakalım:

#include
Servo xMotor;
const byte ldrSag=A1;
const byte ldrSol=A3;
byte aci=90;
int gunesSag, gunesSol;
void setup() { Serial.begin(9600);
// servo için PWM pinleri 3-5-6-9-10-11 olabilir
xMotor.attach(6); // Tek motor için
xMotor.write(aci);
}

Burada void Setup içinde, Serial.begin ile seri portu ekranda görme işlemini başlatmış oluyoruz.

Isim.attach(6) ile de 2. satırdaki xMotor adıyla oluşturduğumuz Servo nesnesine PİN numarasını bildiriyoruz.

Yani fiziksel olarak Servo Motor’u bağlayacak olduğumuz pin 6 nolu dijital pin. 6 yerine yukarıda PWM olarak belirtilen diğer pinler de olabilir.

İşin icraat kısmında ise İLK eylem olarak yaptığımız şey, Servo Motor’a SIFIR açısına gitmesini söylemek:

Ancak görüleceği üzere xMotor.write(0) yazmak yerine xMotor.write(aci) yazdık.. Neden?
Çünkü ilk bölümdeki tanımlamalar kısmında aci=0 değerini vermiştik.

x, y, aci ve benzeri değişken kullanmak bize “aci+15” örneğinde,
60+15 gibi sabit bir sonuç vermek yerine “daima mevcut açının 15 fazlası” şeklinde esneklik sunacak.


:)) ünlü düşürler


Sürekli dönecek olacak loop() fonksiyonumuzu yazalım:

Temel amacımız: Güneşe Dik olmak.

O halde şöyle bir kurgu yapabiliriz;
Bir elim pencereye bir elim odanın içine doğru olacak şekilde iki kolumu açsam.. Camdan taraftaki elime daha çok ışık düşecektir. Kollarımı bozmadan yüzümü pencereye doğru dönsem.. iki elimi birleştiren eksen, pencerenin olduğu duvar ile paralel konuma geldiğinde.. İki elime düşen ışık miktarı eşit olacaktır.

O halde, güneşe dik olmak demek, İki elime de düşen ışık miktarının eşit olması demek.

Peki ışık miktarını nasıl ölçeceğiz?

LDR: Işığa duyarlı direnç ile.

Aslında en temelde ilköğretim gördüğümüz Direnç ölçümü yapacağız. Sadece elimizdeki direnç, üzeri renkli çizgilerle kaplı olan direnç olmayacak da, üzerine düşen ışığa göre direnç (ohm) değeri değişen bir direnç olacak.

Hani karanlıkta yanan küçük gece lambalarının yanmasını sağlayan minik şey.


roboturka

Teoriden pratiğe gelirsek; Güneş panelimizin ön yüzünde, karşılıklı iki ayrı kenara birer tane LDR koyacağız.

Bunlara düşen ışık miktarını okuyacağız ve bunların eşit olmasını sağlamak için Servo Motor’un dönmesini (paneli döndürmesini) tetikleyeceğiz 😉


Görsel

Dijital Ay Çiçeği #1 // 8000$ Değerinde post :)

İtiraf: Güneş takip sistemini tarif etmek için Digital Ay Çiçeği tabiri çok hoşuma gidiyor. Yazının kapak resmi olması için bununla ilgili bir şeyler ararken, karşıma görseldeki Robotic Sunflower Umbrella diye bir şey çıktı. Ve değeri 8000$ mış. Ben de başlığa bunu ilave ettim 

Biz güneş panellerini daha verimli kullanmak için, güneşi takip ettireceğiz. Onlar da güneşi takip ettirmiş ancak şemsiye yön vermek amacıyla. Bu da çok güzel fikirmiş! Alkışlıyorum.

Malumunuz Dünya, Güneşin etrafında dönerken “mükemmel çember” yerine Elips bir yörüngede dolanıyor.


wikipedia 0

Ve bu yüzden küçükken kışların; dünyanın güneşe uzak olduğu zamanlar,
yazların ise dünyanın güneşe yakın olduğu zamanlar gerçekleştiğini sanırdım.

Yukarıda görselde de görüleceği üzere: Asıl etkili mesele bu değil. En uzak olduğundaki aylardan biri Temmuz, en yakın olduğu tarih ise 3 Ocak.

— Ee? O zaman -40°C ile +40°C gibi 80 dereceye varan farklar nasıl oluşuyor?

— AÇI.

Güneş’in açısı ne kadar DİK AÇI ile gelirse o kadar sıcak oluyor.

Özetle;
27 derecelik açı, 5 milyon kilometre mesafeden daha etkili.

[Bu arada “dünya güneşe 10 cm daha uzak/yakın olsa, hayat olmazdı” sözünün ne kadar Hurafe olduğu aşikar.]

Bu durumda, öylesine güneye bakan güneş panelleri yerine, gün içinde güneşle birlikte hareket ederek daima dik açıyı yakalamaya çalışmak, yazla kış farkı kadar önemli.

Let’s do it

NŞA’da paneller çift eksende hareket etmeli. Ama karışık olmaması için tek motorla gidelim..

Burada sadece xMotor kullanacağız.

Benzer şekilde daha iyi anlaşılması için aşağı yukarı eksenlerini şimdilik pas geçeceğiz ama mantığın aynı olduğunu sanırım söylememe gerek yok. Sağdan sola doğru dönen, elimize alıp motoru çevirdiğimizi düşünün. Bu kez de yukarıdan aşağıya yahut çapraz dönecektir.

Sadeleşmiş halleri şöyle;

#include <Servo.h>
Servo xMotor;
const byte ldrSag=A1;
const byte ldrSol=A3;

#include Servo.h kısmı, Servo motorun sürücüsünü içeri çağırdığımız kısım.

ldrSag, Güneş Panelimizin sağ tarafına yerleştireceğimiz Işık Sönsörü (LDR) ‘yi bağlayacağımız Analog Pin

ldrSol da diğer taraftaki için.

Şimdi de panelin Dönüş Açısı ve bunu hesaplamak için kullanacağımız değişken tanımlarını ilave edelim.

Ok.
Cihazımıza ilk elektrik geldiğinde BİR sefer çalışacak olacak, Setup() fonksiyonumuzu yazalım.

Sade bir kullanım isteyenler dikey-yatay eksen kodlarını kullanmayabilir. Yani sadece tek eksen için şunlar yeterli:

void setup() { Serial.begin(9600);
// servo için PWM pinleri 3-5-6-9-10-11 olabilir
xMotor.attach(6); // Tek motor için
xMotor.write(aci);
}

Burada dikkat edilmesi gereken bir nüans var: Servo motorun bağlanacağı pinler, PWM özelliğine sahip pinler olmalı. Kullandığınız karta göre göre bu değişebilir. Bizim örneğimizde yukarıda açıklama kısmında geçen pinler kullanılabildiği için bunlardan bi tanesini (6 nolu pini) seçtik.

Hazırlıklarımız hazır.

Devam eden yazıda,
Ay Çiçeği mantığının nasıl işlediğini buna benzer bir algoritmayı bizim nasıl kurgulayabileceğimize bakacağız ve bakmakla kalmayıp panelimizi ay çiçeği gibi güneşe döndürecek kodlarımızı da yazacağız.

 

void loop() ve analogRead açıklaması

Bkz: Önceki konular;
26 Satırda İsrafı Önleme
26 Satır Bahanesiyle, Ucundan Bit-Byte, MBit/s Meali


Kaldığımız yerden devam edelim..

// Sürekli çalışan fonksiyonumuz.
// Başlarda biraz kafa karıştırıcı olabilir.
// Zira normalde bir program akışı içinde, yazdığınız akış sona geldiğinde
// programın durmasını bekleriz.
// Ancak burada bazı dillerdeki _main_ fonksiyonları gibi,
// loop fonksiyonu sürekli çalışmaktadır.
// bu da bize “program sonu” olarak adlandıranbileceğimiz bir yer olmadığını gösterir.

// bi yerlerde başlayıp, bi yerlerde bitmesi, zihimizin çalışma mantığına daha uygun olduğu için
// şöyle denilebilir.. şu oluyor, bu oluyor.. sonra şu çalışıyor, bunu tektilliyor vs..
// en SON olarak buradaki WHILE döngüsü çalışıyor denilebilir.
// ki bu SON WHILE’ın çalışma şekli şekli şöyledir:
// while (elektrikler_var_mi) {}

 


// Cihazların üzerindeki A0, A1, A2.. şeklindeki pinlere gelen değerleri okumak için
// analogRead kullanıyoruz.
// hatırlayalım; Dijital demek 0-1 demekti.
// eğer alacağımız değerler 0-1 değilde 3 86 156 325 874 sadece var-yok sıfır-bir olmaktan
// öte değerler ifade ediyorsa lazım olan şey Analog işlemdir.
// bir ortamdaki “ışığın şiddeti” dediğimizde de böyle bir durumdan bahsediyoruz.
// sabah öğle akşam üstü gece yarısı sürekli değişecektir.
// ya da şu ayaklı, ışığı ayarlanabilir lamlarını düşünün.
// böyle bir ortamda ışık şiddetini 0-1’in ötesinde geniş bir sıkalada ifade edilecektir.

// LDR sensörü ise, ışığa duyarlı bir dirençtir. Üzerine düşen ışık değiştiğinde
// ldr’den okduğumuz direnç değerleri de değişir.

// O halde, LDR’yi dijital pinlere değil, analog pinlere bağlamak daha sağlıklı olacaktır
// ayrıca gelecek olan değer geniş bir aralıkta olduğu için biz de
// 0-300 arasındaysa şunu yap, 301 – 600 arasında bunu, 601-900 arasında şunu yap
// gibi farklı işlemler yapabileceğimiz gibi

// gelecek olan ışık şiddetini, bir servo motorun açısına eşitlemek gibi
// ışık şiddetinin az ya da çok değişimine dağlı olarak
// motorun açısını da orantılı ve anlık şekilde değiştirebiliriz.

// bu projede sabah olduğunda, sokak lambalarının sönmesi için, ışık şiddettine bağlı olarak
// çalışacak aşağıdaki kodları yazacağız.

// aşağıdaki linkten murattatar.xyz üzerinde daha okunur ve renkli olarak görebilirsiniz.

void loop() { 
  x = analogRead(A0);  
  if (x > 200) {
    while (1) {
      digitalWrite(3, LOW);
      x = analogRead(A0);
      if (x < 200) {
        break;
      }
    }
  }



  x = analogRead(A0);
  if (x < 200) {
    digitalWrite(3, HIGH);
    while (1) {
      x = analogRead(A0);
      if (x > 200) {
        break;
      }
    }
  }


}



Devam açıklamalar gelecek..
Görsel: shutterstock