Arduino

5$’a Evinizin Elektrik Tüketimini Takip Etmek!


Lisans bitirme tezim olan bu konuda bir yazı hazırlamak istedim. Bitirme tezimin konusu, ev tipi kullancıların elektrik tüketimlerini(aktif tüketim) online olarak izleyebilmesi üzerineydi. Kendi isteğimle belirlemiş olduğum bu konu hakkında tez almama olanak sağladığı için Doktor Öğretim Üyesi Murat Mustafa Savrun hocama teşekkürlerimi iletirim.

Yazıyı bazı parçalara ayırmamız gerekiyor, öncelikle işin fiziksel sayaç kısmına değineceğim. Hadi başlayalım!

Sayaç üzerinden veri okumamıza olanak sağlayan protokolün adı IEC62056-21 eski adıyla IEC1107 protokolü. Sayaç üzerinden veriyi iki farklı kanaldan okuyabilirsiniz. İlk seçenek sayacın RS-485 portu üzerinden (sayaca göre portun konumu değişebilir) diğer bir seçenek ise sayaç üzerinde bulunan optik göz aracılığıyla okuma yapabilirsiniz. Protokol katmanı aynı olduğu için fiziksel katmanda RS485 kullanıyorsanız ona göre yazılımınızda değişiklik yapmanız gerekir haliyle.

Ben optik göz üzerinden bir okuma yapmayı tercih ettim. Sayacın üzerinde bulunan optik göz içerisinde bir adet IR led, bir adette FotoTransistör mevcut. Bu optik göz üzerinden okuma yapabilmeniz için bir adet optik probe’a gebe kalmanız gerekiyor. Ben ilk başlarda bir firmanın optik probe’unu kullandım ancak genel sistemim için kısıtlamalar yaratıyordu. Çünkü 6v besleme istiyorlardı, kısacası kendi OSOS modemleri için tasarlamışlardı. Ve temel bir osos modem yapmaya çalışan ben için çok alternatif bir seçim değildi. Madem öyle iş başa düştü diyerek optik probe hazırlamaya koyuldum. Bu optik probe süreci ile ilgili oldukça detaylı bir videoyu şurada hazırlamıştım. Sözlü anlatım benim için her zaman yazmaktan kolay olmuştur, şuraya videoyu bırakayım.

Sistemi ilk olarak Arduino Mega ile kurmuştum, birden fazla donanımsal UART imkanı sunduğu için tercih etmiştim. Fakat iş dataları internete çıkarmaya geldiği noktada ekstra bir donanıma gebe kalmayı istemediğim ve kurcalamak istediğim bir donanım olan https://onion.io/ kartı ile devam ettim. Kendisini ilk olarak kickstarter üzerinden temin etmişti bir arkadaşımız ve bizlere de hediye olarak almıştı.

Şöyle ufak bir setup kurmuştum.

Daha sonrasında tekrar bir donanım değişikliği yaparak olabildiğince düşük maliyetlere indirgemek istedim sistemi ve NodeMcu olarak bilinen üzerinde ESP8266 wifi modülü barındıran bir karta geçiş yaptım. Ve sistemi kendi probelarım ile tekrar kurguladım.

Gelin şimdi haberleşme protokolü üzerine biraz konuşalım. Bu konuda internet üzerinde bulabileceğiniz en kalite içerik şu olsa gerek [buradan]. Eğer başka bildiğiniz var ise yeşillendiririz sonrasında.

Haberleşme başlangıcında ayarlarımız 300 baud, Even Parity, 7 Data Bit şeklinde olması gerekmekte. “Günaydın” manasında göndereceğimiz data paketimiz

----> /?1!

Bu mesaj sonrasında sayacımız “Günaydınlar Efendim” şeklinde

<---- /SAT6EM72000656621

datasını dönmekte.

Bundan sonrasında OBİS bazlı bir sorgulamamı yoksa READOUT mu çekmek istediğinizi sisteminizi kurgularken düşünmeniz gerekmekte. OBİS, READOUT ne diyenler için bir açıklama yapalım. Sayaç içerisinde bir çok farklı parametrenin datası tutulmakta, faz akımlarından aktif enerji datalarına, aktif enerji datalarından cihaz içerisinde bulunan yazılım versiyonuna gibi bir çok parametre var. Yani siz cihazdan READOUT istediğiniz vakit size içinde ne var ise kusmakta. Örnek bir READOUT dosyasını bırakıyorum.

0.0.0(EM72000656621)
0.9.1(172751)
0.9.2(100209)
1.8.0(343642.9*kWh)
2.8.0(1958.9*kWh)
3.8.0(120.7*kvarh)
4.8.0(7068.5*kvarh)
1.6.0(18014*kW)(10-02-01 00:15)
2.6.0(0*kW)(10-02-01 00:15)
3.6.0(186*kvar)(10-02-01 00:15)
4.6.0(366*kvar)(10-02-01 00:15)
1.2.0(275663*kW)
2.2.0(2158*kW)
3.2.0(54*kvar)
4.2.0(5683*kvar)
1.8.1(150967.3*kWh)
1.8.2(104673.3*kWh)
1.8.3(88002.3*kWh)
2.8.1(1958.9*kWh)
2.8.2(0.0*kWh)
2.8.3(0.0*kWh)
3.8.1(55.1*kvarh)
3.8.2(2.8*kvarh)
3.8.3(62.8*kvarh)
4.8.1(3125.7*kvarh)
4.8.2(2140.7*kvarh)
4.8.3(1802.1*kvarh)
1.6.1(0*kW)(10-02-01 00:00)
1.6.2(0*kW)(10-02-01 00:00)
1.6.3(18014*kW)(10-02-01 00:15)
2.6.1(0*kW)(10-02-01 00:00)
2.6.2(0*kW)(10-02-01 00:00)
2.6.3(0*kW)(10-02-01 00:15)
3.6.1(0*kvar)(10-02-01 00:00)
3.6.2(0*kvar)(10-02-01 00:00)
3.6.3(186*kvar)(10-02-01 00:15)
4.6.1(0*kvar)(10-02-01 00:00) 
4.6.2(0*kvar)(10-02-01 00:00)
4.6.3(366*kvar)(10-02-01 00:15)
1.2.1(275663*kW)
1.2.2(0*kW)
1.2.3(0*kW)
2.2.1(2158*kW)
2.2.2(0*kW)
2.2.3(0*kW)
3.2.1(54*kvar)
3.2.2(0*kvar)
3.2.3(0*kvar)
4.2.1(5683*kvar)
4.2.2(0*kvar)
4.2.3(0*kvar)
0.1.2*01(10-02-01 00:00)
1.8.0*01(320695.7*kWh)
2.8.0*01(1958.9*kWh)
3.8.0*01(49.4*kvarh)
4.8.0*01(6599.6*kvarh)
1.6.0*01(275663*kW)(10-01-03 19:15)
2.6.0*01(2158*kW)(10-01-03 19:15)
3.6.0*01(54*kvar)(10-01-03 19:15)
4.6.0*01(5683*kvar)(10-01-03 19:15)
1.2.0*01(0*kW)
2.2.0*01(0*kW)
3.2.0*01(0*kvar)
4.2.0*01(0*kvar)
1.8.1*01(141503.7*kWh)
1.8.2*01(97883.8*kWh)
1.8.3*01(81308.2*kWh)
2.8.1*01(1958.9*kWh)
2.8.2*01(0.0*kWh)
2.8.3*01(0.0*kWh)
3.8.1*01(46.6*kvarh)
3.8.2*01(2.8*kvarh)
3.8.3*01(0.0*kvarh)
4.8.1*01(2932.0*kvarh)
4.8.2*01(2002.2*kvarh)
4.8.3*01(1665.4*kvarh)
1.6.1*01(275663*kW)(10-01-03 19:15)
1.6.2*01(0*kW)(10-01-01 00:00)
1.6.3*01(0*kW)(10-01-01 00:00)
2.6.1*01(2158*kW)(10-01-03 19:15)
2.6.2*01(0*kW)(10-01-01 00:00)
2.6.3*01(0*kW)(10-01-01 00:00)
3.6.1*01(54*kvar)(10-01-03 19:15)
3.6.2*01(0*kvar)(10-01-01 00:00)
3.6.3*01(0*kvar)(10-01-01 00:00)
4.6.1*01(5683*kvar)(10-01-03 19:15)
4.6.2*01(0*kvar)(10-01-01 00:00)
4.6.3*01(0*kvar)(10-01-01 00:00)
1.2.1*01(0*kW)
1.2.2*01(0*kW)
1.2.3*01(0*kW)
2.2.1*01(0*kW)
2.2.2*01(0*kW)
2.2.3*01(0*kW)
3.2.1*01(0*kvar)
3.2.2*01(0*kvar)
3.2.3*01(0*kvar)
4.2.1*01(0*kvar)
4.2.2*01(0*kvar)
4.2.3*01(0*kvar)
0.1.2*02(10-01-01 00:00)
1.8.0*02(230481.9*kWh)
2.8.0*02(1958.9*kWh)
3.8.0*02(46.0*kvarh)
4.8.0*02(4728.0*kvarh)
1.6.0*02(0*kW)(09-12-01 00:00) 
2.6.0*02(0*kW)(09-12-01 00:00)
3.6.0*02(0*kvar)(09-12-01 00:00)
4.6.0*02(0*kvar)(09-12-01 00:00)
1.2.0*02(0*kW)
2.2.0*02(0*kW)
3.2.0*02(0*kvar)
4.2.0*02(0*kvar)
1.8.1*02(105851.0*kWh)
1.8.2*02(68334.5*kWh)
1.8.3*02(56296.4*kWh)
2.8.1*02(1958.9*kWh)
2.8.2*02(0.0*kWh)
2.8.3*02(0.0*kWh)
3.8.1*02(46.0*kvarh)
3.8.2*02(0.0*kvarh)
3.8.3*02(0.0*kvarh)
4.8.1*02(2179.5*kvarh)
4.8.2*02(1396.7*kvarh)
4.8.3*02(1151.8*kvarh)
1.6.1*02(0*kW)(09-12-01 00:00)
1.6.2*02(0*kW)(09-12-01 00:00)
1.6.3*02(0*kW)(09-12-01 00:00)
2.6.1*02(0*kW)(09-12-01 00:00)
2.6.2*02(0*kW)(09-12-01 00:00)
2.6.3*02(0*kW)(09-12-01 00:00)
3.6.1*02(0*kvar)(09-12-01 00:00)
3.6.2*02(0*kvar)(09-12-01 00:00)
3.6.3*02(0*kvar)(09-12-01 00:00)
4.6.1*02(0*kvar)(09-12-01 00:00)
4.6.2*02(0*kvar)(09-12-01 00:00)
4.6.3*02(0*kvar)(09-12-01 00:00)
1.2.1*02(0*kW)
1.2.2*02(0*kW)
1.2.3*02(0*kW)
2.2.1*02(0*kW)
2.2.2*02(0*kW)
2.2.3*02(0*kW)
3.2.1*02(0*kvar)
3.2.2*02(0*kvar)
3.2.3*02(0*kvar)
4.2.1*02(0*kvar)
4.2.2*02(0*kvar)
4.2.3*02(0*kvar)
0.1.2*03(09-12-01 00:00)
1.8.0*03(160737.9*kWh)
2.8.0*03(1958.9*kWh)
3.8.0*03(46.0*kvarh)
4.8.0*03(3299.5*kvarh)
1.6.0*03(0*kW)(09-11-01 00:00)
2.6.0*03(0*kW)(09-11-01 00:00)
3.6.0*03(0*kvar)(09-11-01 00:00)
4.6.0*03(0*kvar)(09-11-01 00:00)
1.2.0*03(0*kW)
2.2.0*03(0*kW)
3.2.0*03(0*kvar)
4.2.0*03(0*kvar)
1.8.1*03(78592.2*kWh)
1.8.2*03(43985.4*kWh)
1.8.3*03(38160.3*kWh)
2.8.1*03(1958.9*kWh)
2.8.2*03(0.0*kWh)
2.8.3*03(0.0*kWh)
3.8.1*03(46.0*kvarh)
3.8.2*03(0.0*kvarh)
3.8.3*03(0.0*kvarh)
4.8.1*03(1621.3*kvarh)
4.8.2*03(898.1*kvarh)
4.8.3*03(780.1*kvarh)
1.6.1*03(0*kW)(09-11-01 00:00) 
1.6.2*03(0*kW)(09-11-01 00:00)
1.6.3*03(0*kW)(09-11-01 00:00)
2.6.1*03(0*kW)(09-11-01 00:00)
2.6.2*03(0*kW)(09-11-01 00:00)
2.6.3*03(0*kW)(09-11-01 00:00)
3.6.1*03(0*kvar)(09-11-01 00:00)
3.6.2*03(0*kvar)(09-11-01 00:00)
3.6.3*03(0*kvar)(09-11-01 00:00)
4.6.1*03(0*kvar)(09-11-01 00:00)
4.6.2*03(0*kvar)(09-11-01 00:00)
4.6.3*03(0*kvar)(09-11-01 00:00)
1.2.1*03(0*kW)
1.2.2*03(0*kW)
1.2.3*03(0*kW)
2.2.1*03(0*kW)
2.2.2*03(0*kW)
2.2.3*03(0*kW)
3.2.1*03(0*kvar)
3.2.2*03(0*kvar)
3.2.3*03(0*kvar)
4.2.1*03(0*kvar)
4.2.2*03(0*kvar)
4.2.3*03(0*kvar)
!
ETX
v 

Yukarıda görmüş olduğunuz her satır aslında bir obis kodu, yani siz obis bazlı bir sorgu yapıyor iseniz sadece sorgusunu yaptığınız obis kodunun verisi alıyorsunuz.

Readout paketinin sonuna bakar iseniz ‘!’, [ETX], ‘v’ karakterlerini görürsünüz. Burada ! işareti ve [ETX] (End of Text) gelen data paketinde sabittir. ‘v’ karakteri ise, tüm pakette ki dataların XOR’lanması ile elde edilir. Daha iyi anlaşılması için şöyle bir örnek verelim. Sayacımıza “sign off” komutunu yollayalım.

<SOH>B0<ETX><BCC>
01 42 30 03 71

#include <stdio.h>
#include <string.h>

const char readout[4]  = {0x01, 0x42, 0x30, 0x03};
char BCC = 0x01;
int main()
{
   for(int i = 0; i < sizeof(readout); i++)
   {
       BCC ^= readout[i];
   }

    printf("BCC = %c", BCC);
    
    return 0;
}

Kodumuzun çıktısı : BCC = q

Ascii tablosunda bakarsanız, ‘q’ karakteri hex karşılı olarak 71 olarak görebilirsiniz.

Volkan, READOUT sorgusunu nasıl yapıyoruz ?

Sayaçtan READOUT sorgusu için paket gönderirken dikkat etmeniz gereken bir nokta var. Sayacın timeouta düşmediğinden emin olun. Günaydın mesajını gönderdikten bir süre sonra readout mesajını göndermeniz gerekmekte. Aksi halde kendisini tekrar kapatıyor port ve tekrar günaydın mesajını yollamanız gerekiyor. Bu timeout süresi sayaçlara göre değişiklik gösterebiliyor.

----> 050

Yukarda ki sorgu paketinin parametrelerinden şu an için önemli olan ‘5’ parametresi. Bu parametre ile baud geçişini ayarlıyorsunuz. Burası ‘0’ olsa idi, 300bd. ‘1’ olsa 600bd şeklinde gitmekte. 5 olduğu için 9600baud ile verileri çekeceğimizi söylüyoruz. Şöyle söyleyim, Köhler cihazlarda bazı modeller yaklaşık olarak 17Kb veri göndermekte readout cevabı olarak. Bu çok ciddi bir boyut çalıştığımız alan için. Bunu bir şekilde eritmeniz gerekiyor. Ama asıl önemli olan bu veriyi 300baud gibi hızlar ile alırsanız gözle görülür şekilde 9600 ile veri çekmeye göre bir zaman farkı olacaktır.

Son parametre olan kısmın ‘0’ ya da ‘1’ olması yük profili ya da obis bazlı sorgularda kullanıyor. Ancak bu yazıda buna değinmeyeceğim.

Yukarda bahsettiğim tüm işlemleri RS485 to usb bir dönüştürücü ile nasıl deneyebileceğiniz konusunda şurada bir video paylaştım.

Bu “Günaydın” mesajı hakkında bir kaç not düşmek istiyorum. Bazı sayaçların “GÜNAYDIN” mesaj paketi değişiklik gösterebiliyor. Örnek vermek gerekirse MAKEL sayaçlar /?MSY!\r\n şeklinde bir sorgu gönderilmesini istiyor.

RS485 katmanı üzerine IEC1107 protokolünü giydiriyor ve hattınızda birden fazla sayaç var ise, sorgu paketine hangi sayıcı sorgulamak istediğinizi belirtmeniz gerekiyor. Her sayacın üzerinde 8 haneli bir seri numarası mevcut. Yani şöyle;

----->/?69205929!\r\n

Bu konuştuklarımızı mikrodenetleyici seviyesinde gerçekleştirmeden önce biz elimizde bulunan bu dataları networke açıldıktan sonra kullancıya hangi platform üzerinden göstereceğiz ?

Custom bir servis elbette oluşturabilir ancak buna bilgim ve zamanım olmadığı için halihazırda servis sunan uygulamalara yöneldim. Öğrencilik zamanlarımda Thingspeak adresini projelerimde sıklıkla kullanıyordum. Ancak artık ücretli olmuş ve para ödemek istemedim. Gerçi kullancıya sunmuş oldukları ile para ödenebilir bir platform bence. Neyse ben kullanımı oldukça kolay https://iotguru.live/ sitesini kullanacağım. Thingspeak kadar iyi bir servis değil baştan belirtmek isterim.

Şimdi gelelim işin donanım yazılımı tarafına;

NODEMCU üzerinde 2 adet UART bulunmakta. Ancak bunlardan bir tanesi sadece TX hattı(D4). Ben bu hattı basic bir şekilde serial üzerinden DEBUG yapmak için kullandım. Kendi hazırladığım probe ile bağlantısını soracak olursanız. Yazının başlarında belirttiğim optik probe hazırlıyoruz videosunu henüz izlememişsinizdir. Böyle olmaz!

Esp8266’yı programlamak için Arduino IDE’sini kullandım. Bu süreçte espressif firmasının yayınlamış olduğu NONOS SDK‘sı ile flashladım öncesinde çipi. Öncelikle DEBUG için bir makro oluşturalım.

#define DEBUG 

#ifdef DEBUG
#define PROTOCOL_PRINT(...)\
do {\
  Serial1.println(__VA_ARGS__);\
}while(0);
#else
#define PROTOCOL_PRINT(...) do{ }while(0);
#endif 

Biraz sistem kurgum üzerinden bahsedip, kafanızda fikir uyandırmak istiyorum. Benim sistem kurgum READOUT mantığına dayanmakta. Belirlenen periyotlar doğrultusunda cihaz “Günaydın” mesajını ve bu mesaja cevap alımı tamamlandıktan sonra READOUT mesajı gönderiliyor. Arka planda yazılımsal bir timer ile kurulan UART kesmesi ve durum makinesi mevcut. READOUT sırasında gelen veriler ‘\n’ karakteri ile gelmekte, yukarda bahsettiğim READOUT dosyasından görebileceğiniz gibi. Her gelen veri paketinde aşağıda bulunan parser fonksiyonuna girerek, istenilen obis kodunu parçalamalayı hedefler.

void vParseOsosProcess(String buffer)
{
  //char *SampleObis = "1.8.0(000000.012*kWh)\r\n1.8.0*1(000000.000*kWh)\r\n";
  char ObisCode[40];
  char *p =  NULL;
  
  buffer.toCharArray(ObisCode, sizeof(ObisCode));
  
  p = strstr(ObisCode, "32.7.0");
  
  if(p)
  {
    PROTOCOL_PRINT("Parse Process");
    p = strstr(p, "(");
    if(p)
    {
      char buf[20];
      int i = 0;
      
      while(*p++ != '*')
      {
        buf[i] = *p;
        i++;
      }
      
      buf[i-1] = '\0';
      osos_handle.fvalue = atof(buf);
      PROTOCOL_PRINT(osos_handle.fvalue, 5);
    }
  }
  
  osos_handle.sBuffer = "";
}

Yukarda belirtilen fonksiyon üretim kodunuz için çok uygun bir fonksiyon olmayabilir.

“Günaydın” ve READOUT mesajı göndereceğimiz için

void vSendStartMessage(void)
{ 
  #if defined(LUNA) || defined(KOHLER)
    const uint8_t  ucStartMessage[] = { 0x2F, 0x3F, 0x21, 0x0D, 0x0A };
  #elif  defined(MAKEL)
    const uint8_t *ucStartMessage = "/?MSY!\r\n");
  #endif
  osos_handle.hs-> write(ucStartMessage, strlen((const char*)ucStartMessage));

  delay(1000);
  
  PROTOCOL_PRINT("WAKEUP REQUEST");
  START_MESSAGE = START_MESSAGE_SEND;
}

void vSendReadOutMessage(void)
{
  const uint8_t  ucReadoutMessage[] = { 0x06, 0x30, 0x30, 0x30, 0x0D, 0x0A };
  osos_handle.hs-> write(ucReadoutMessage, strlen((const char*)ucReadoutMessage));
  
  delay(700);
  
  PROTOCOL_PRINT("READOUT REQUEST");
  OBIS_MESSAGE = OBIS_MESSAGE_SEND;
}

şeklinde fonksiyonlar tanımlayabiliriz. Göndereceğimiz mesajlarda bizim kurgumuz için BCC karakter eklemediğimiz için yapımızda olmasına gerek yok.

Monitoring hizmeti için kullanacağımız sitenin kendi github hesabında bir kütüphane var, data basmak için direkt olarak onu kullandım. Ve neticede şu şekilde bir loop elde etmiş olduk.

void loop()
{
  if(bGotIpFlag)
  {
    bGotIp();
  }
  
  if(!bGotIpFlag) iotGuru.check();
  if(bFirstKickMillis) CurrentMillis = millis();
  
  if(CurrentMillis - PreviousMillis >= interval && START_MESSAGE == START_MESSAGE_IDLE)
  {
    if(!bFirstKickMillis) CurrentMillis = 0;
    bFirstKickMillis = true;
    PreviousMillis = CurrentMillis;
    vSendStartMessage();
  }
  
  if(START_MESSAGE == START_MESSAGE_RECEIVED && OBIS_MESSAGE == OBIS_MESSAGE_IDLE)
  {
    vSendReadOutMessage();
  }
  
  if(bSendValueToCloud)
  {
    iotGuru.sendHttpValue(nodeKey, fieldName, osos_handle.fvalue);
    bSendValueToCloud = false;
  }
}

Yukarda bahsetmiş olduğum monitoring hizmeti veren servis 0.003 gibi dataları 0 olarak gösterdiğinden dolayı, 32.7.0 obis kodunu yani L1 fazının gerilim değerini basıyorum.

Sanırım blogumda bulunan en uzun yazı oldu, son olarak eklemek istiyorum ki evet farkındayım tüm projeyi açık kaynak olarak paylaşmış değilim çünkü bu projeyi ticari amaçları doğrultusunda benden habersiz kullanarak emeklerimin, proje üzerinde harcadığım glikozun sömürülmesini istemiyorum. Olabildiğince tüm know how’ımı vermeye çalıştım diyebilirim bütün kalbimle.

NOT : Ben evimin elektrik sayacına bağlı bir cihaz ile değil, harici bir cihaz temin ederek çalışmalar yürüttüm. Bu konuda ki yasal prosedür hakkında bilgi sahibi değilim.

NOT 2 : Elektrik sayacının optik gözünden veri okuyabilmeniz için sayacınız enerjili olmasına gerek yoktur. Ancak veri okumaya başlamadan önce üzerinde bulunan “ÇAĞRI” butonuna basmanız gerekmekte. Eğer cihaz enerjisi yok ise belli bir okuma sınırınız var. Enerji yokken RS485 portundan okuma yapamazsınız.

Lütfen bu yazıyı okuduktan sonra youtube kanalıma gelen bir yorum gibi düşüncelere kapılmayın.

Bu süreçte desteklerinden dolayı Yunus Öztekin ve Engin Çelik’e teşekkür ederim.

Kırsalda ki Çocukları Teknoloji ile Tanıştırmak/Askıda Arduino


Herkese selamlar , bu yazım teknik bir yazı değil bir destek çağrısında bulunmak olacak.Geçtiğimiz günlerde bir proje başlattık adı “Askıda Arduino” amacımız kırsal da ki çocukları da kodlama ile tanıştırmak.Peki bunu nasıl yapıyoruza gelirsek , arduino modelleri ile uyumlu bir shield tasarladık üzerinde 12 farklı sensör , modül barındırıyor.

Amacımız hem kablolamadan doğacak hataları sıfıra indirmek hem de burada harcayacağı zamanı kodlama becerisini geliştirmesi için kullanmasını sağlamak.

Şu anda kitlesel fonlamaya açıldık ve çırpınıyoruz 🙂

Projemizi şuradan inceleyebilir ve destek olabilirsiniz.Bağış olarak destek olamasanız dahi sosyal medya hesaplarınızda paylaşarak bizi çok mutlu edersiniz 🙂

https://www.gofundme.com/askidaarduino

 

 

Makers Türkiye : http://makersturkiye.com/askida-arduino/

Ceotudent : https://ceotudent.com/newtoysforkids-askida-ardunio/

 

Basic Voltage Oscilloscope


Bu yazımda processing ile oluşturduğum voltaj osiloskobu üzerine konuşacağım.Görsel bir şey yapmak istiyordum , yanımda sadece bir adet arduino olmasından kaynaklı analog çıkış voltajlarını kontrol etmek istedim sonucunda da böyle bir şey ortaya çıktı diyebilirim.

Dataları serial port üzerinden bilgisayara aktarma işleminden sonra processing de port nesnesi ile dataları alıp işleme tabi tutuyorum.

void setup() {
Serial.begin(9600);}

void loop() {
int val = analogRead(A0);
Serial.write( 0xff );
Serial.write( (val >> 8) & 0xff );
Serial.write( val & 0xff );}

 

Burada bence çok önemli bir kısım var oda öteleme işlemi , dikkat etmek gereken bir şey var ki ADC çözünürlüğümüz 10bit , yani Serial.write((val>>8)& 0xff); ifadesi en fazla 3  değerini alır , 0b0000000011 olarak.Burada ilk parti veriyi gönderiyoruz , ardından 0xff yani 0b11111111 yani 8bitlik bir paket oluşturarak 2.partiyi gönderiyoruz.Gönderdiğimiz kısım kadar alıcı kısmıda önemli.

Burayı daha iyi anlamak için okuduğunuz değeri herhangi işleme tabi tutmadan ekrana print ediniz , daha sonra Serial ekranına yazarken BIN parametresi ile yazın anlamanız daha iyi olacaktır.Farkettiğim bir şey var ki örneğin 10bitlik bir veri de  8 değerini ekrana yazdırırken direkt olarak 1000 olarak yazıyor zaten solunda ki sıfırların bir önemi de olmayacaktır.

Processing de , serial port kütüphanesinin yanında controlP5 ile buton gibi şeyleri kolayca oluşturabildim ve bunları kontrol ettim.İlerleyen versiyonları olursa şayet , daha efektif bir osiloskop yapabilirim 🙂 iyi çalışmalar.

capture

capture

 

Github link : https://github.com/volkanunal/voltageosci

 

Ayarlanan Saat Süresince Çıkış Alma


Herkese selam , bir çok arkadaş menü tarzında bir şey olsun ve onun üzerinden ayarlanan zaman aralıklarında röle çektirmek , sulama motoru gibi gibi bir proje istiyor.Kısaca belirlenen zaman aralıklarında çıkış almak istiyor.Bunun için rotary encoder ,arduino nano , nokia5110 ekranı ve ds1302 zaman entegresi kullanarak sizler için bir şeyler hazırladım.

Öncelikle rotary encoder nedir ? Şurada ki amca gayet keyifli bir şekilde açıklamış
https://www.youtube.com/watch?v=CpwGXZX-5Ug şimdi onun üzerinden biraz geçeyim.

Rotary encoderların mekaniksel olanlarında 5 ayrı bacak bulunuyor ,

capture

Kırmızı ile gösterdiğim yer RC filter devresi buna daha sonra değineceğiz.

Mavi ile gösterdiğim yer ise , pull up direnç bağlama şekli.Eğer modül halinde alırsanız dirençler üzerinde takılı geliyor , ancak kapasitörleri yine sizin takmanız gerekiyor.

Diğer 2 bacak ise birisi buton için diğerini de gnd ye çekerek devreyi tamamlıyorsunuz.Buton için herhangi harici bir devre elemanı eklemeye gerek yok.

A ve B phaselerımız rotary encoderı çevirme yönümüze göre bize bir çıkış veriyor.Videoyu izlerseniz şayet 4 farklı alanımız var bunun sebebi 2 çıkışınız varsa 2^2 den 4 farklı alanda işlem yapıyor olmanız.(Logic circuit dersinden). Bu alanlarda bir doğruluk tablosu oluşturuyorsunuz kısaca.Yukarıda ki video da bunları daha net görebilirsiniz.

Peki neden RC filtreleme yapıyoruz ?

RC filtreleme adı üzerinde Resistor ve Capacitor yani bir direnç ve kapasitörden meydana geliyor.

rc-low-pass-filter-example

Temel artan frekans nedeniyle gösterilen kapasitenin tepkisi azalmaya başlar , az sonra circuit theory ders kitabından çekmiş olduğum hesapları da sizi anlatmaya çalışacağım.Direncin frekansla herhangi bir değişimi olmayacağı için zaman uzayına taşıdığımızda da değeri aynı kalacaktır.

Kapasitörü zaman uzayına taşıdığınızda  1/jwc olacaktır , W açısal frekansı barındırıyor ,j ise zaten zaman uzayına taşdığımız için complex olarak geliyor.C ise sığa değerimiz.

Giriş ile çıkış arasında ki bağıntıyı yazmak çok zor olmasa gerek , gerilim bölücü bir devre gibi düşünürsek , Kapasitör üzerinde ki gerilim V çıkışımıza eşit olacaktır.

Buda Vçıkış=Vgiriş x [(1/jwc)/((1/jwc)+R)] olacaktır.Burada devam eden bir dizi işlem var , ancak hepsini yapmayacağım şu an için.RC filtreleme yardımıyla devremizde encoder’ın sinyalini formunu düzenlemiş olduk ve daha kararlı çalışması sağladık.Tepe de ki bahsettiğim resimde dirençler pull-up şeklinde bağlanmış.Benim elimde çıplak halde modül olduğu için herhangi pull-up bağlantısı yapmadım sadece RC filter devresi kurdum.

Kapasitör değerim =100n , mercimek kondansatörler üzerinde 104 yazar bu 100nf anlamına gelmektedir ,hesaplanışı ise , ilk iki hanesi x 10^sonhane.

104 =10×10^4=10^5 yapar bu pikofarad değeridir, 10^-3 ile çarparsanız nf değerini bulursunuz.

Devrenin bir diğer elemanı ds1302 şunu kullandım.

Sistem de ekran üzerinden çıkış almak istediğiniz saati giriyorsunuz örneğin.

22:10 ile 23:10 bu saatler arasında pin çıkış veriyor, ister röle bağla , ister su motoru vb.

Tabi röle ya da su motoru gibi arduinodan alamayacağımız miktarda amper çeken elemanlar için transistör ,mosfet şemalarını incelemeniz fayda var.

Kodlara şuradan erişebilirsiniz.

Çalışma videosu:

 

 

 

 

 

 

 

Seni Anan PID’i Algoritması İçin Doğurmuş


Dürüst davranayım ki şu an yazıyı yazarken  , oynatma listemde şu şarkı çalıyor. Nedeni belli kafam yandı , Karate Kid izliyordum oradan bu şarkıyı açtım.Neyse şimdi gelelim mevzuya PID diye bir şey var , tatlı ama azcık zahmetli.Kendime bir haftalık challenge yaptım , öküz gibi pid kasıp burada aktarmak için.Kasma kısmı bitti anlatma kısmı başladı.En temelden başlayacağım..Nedir bu PID ? Diyelim bir sisteminiz var ve bunu sürekli kontrol etmeniz gerek ? , iyi de mübarek if falan yemez bu sistem , ne yer ?PID yer.Endüstri de kullanım alanının oldukça yaygın olduğu ortada.

“Bir PID denetleyici çıkıştan geri besleme (feedback) ile gelen sinyali giriş (referans) sinyali ile karşılaştırır ve farkından bir hata oluşur. Bu oluşan hataya göre PID denetleyici hatayı en aza indirgemeye çalışarak bir etki yapar ve çıkışa gönderir. Bu şekilde hata en aza indirilene kadar çıkıştan girişe sürekli geri besleme ile hatalar belirlenir ve denetleyici etkisini çıkışa göndererek hata azaltılır.”

Dayayım mı integrali   ?

pid_resim

Bu formülü gelin koda dökelim , e = error yani hatamız.Hatayı sevmem ben ankaralıyım çünkü.Hazır Kütüphaneden de pek hazetmem , kütüphaneyi yazıcıdan çıkartır incelerim tuvalette falan. (ciddiyim)

uint32_t son_sure;
float giris,cikis,set_noktasi,
tplm_hata,onck_hata,p,i,d;
void pid_set(float kp,float ki,double kd)
{
p=kp;
i=ki;
d=kd;
}
void hesapla(void)
{
unsingned long anlik_zaman=millis();
float zaman_degisimi=(float)(anlik_zaman-son_sure);
float e=set_noktasi-giris;
tplm_hata += (float)(e*zaman_degisimi)
float Dhata=(e-onck_hata)/zaman_degisimi;
cikis=p * e + i * tplm_hata + d * Dhata;
onck_hata=e;
son_sure=anlik_zaman;
}

Temel olarak yukarda ki integrali koda dökmüş bulunduk , henüz hiç bir şey yapmadık 🙂

Pid kütüphanelerinin temel aldığı yapı bu aslında , burayı hemen hemen her akşam 5 gün boyunca güncelleyeceğim.En sonunda süpriz bir uygulamam var.

14729131_320814384959043_4755391138855258940_n.jpg