1Merhaba arkadaşlar uzun zamandan sonra Beaglebone Black yazılarıma devam etmekteyim. Bu projemizde Android ve NFC Reader üzerinden herhangi gerilimde çalışan (0-220V aralığındaki) bir kapıyı kontrol edeceğiz. Burada önemle vurgulamak isterim ; özellikle kapı olmak zorunda değildir. Bunun sebebi bir röle sürme üzerinde durmaktayız. Kendi sistemlerinizide bu platformlara dahil edebilirsiniz.

1      Giriş

 1

      

 

Tasarlanan sistem Android destekleyen telefon ya da NFC destekleyen bir kart üzerinden kapı kontrolü senaryosu üzerine kurulmuştur.
Sistemde kısaca ;

  • Android destekleyen telefon ( ya da destekleyen cihaz)
  • Beaglebone Black ( ya da Beaglebone )
  • Kapı kontrol kartı
  • PN-532 NFC Reader
  • Asus N-10 USB Wifi Dongle
  • Modem

kullanılmıştır.

Android telefon modeme WIFI üzerinden local networke bağlanmıştır. Beaglebone ise wifi dongle üzerinden modeme bağlanmıştır. Bu iki aygıt birbirleri ile TCP Socket üzerinden haberleşmektedirler.  NFC Reader I2C üzerinden Beaglebone ile haberleşmektedir. Kontrol kartı bir GPIO ile Beaglebone’a bağlıdır.
Beaglebone tarafında ana yapı dili olarak JAVA kullanılmıştır. NFC Reader veri okuma işlemlerinde arka planda I2C çalıştırması için hazır kütüphanesi için Python dili kullanılmıştır.

Ortam local networkte çalışmaktadır. Bunu external’a ( İnternete) çıkarabilmek için işlemler olası modemde PORT açma işlemleri ve end device’lara static IP’den haberdar etmek olacaktır.

2      Uygulama Yazılım Mimarisi , Diagramları ve İşlevleri

2

2.1    Android

Android kısmında manuel olarak yapılması gereken durum modeme wifi üzerinden bağlanmak. Kod kısmında yapılan pek bir karmaşıklık yoktur. Bir Socket tanımlanır ServerSocket’e yani Beaglebone’un IP’si ve belirlenen Portuna bağlanır. Bağlantı başarıyla sonuçlandığı takdirde hat üzerinden “1” verisi üretip basılır ve karşı taraf harekete geçirilir ve uygulama kapatılır. Bu uygulama işlem hızından dolayı arka planda yapılıyor gibi düşünülebilir.

2.2    BeagleBone Black

Beaglebone tarafında öncelikli olarak GPIO konfigürasyonu yapılmaktadır. Öncelikli olarak röleye giden pini konfigüre edilmektedir. Bu işlem için başlangıçta “export” edilir. Devamında direction’ı “out” yapılmaktadır. Böylelikle GPIO konfigürasyonu tamamlanmış bulunmaktadır. İşlem satırı devamında NFC konfigürasyonu yapılmaktadır. Burada yapılan işlem NFC board’ın I2C ile bağlantısının bağlı olup olmadığını kontrol etmektedir. Bu işlemler tamamlandıktan sonra

  1. NFCHandle
  2. SOCKETHandle

olmak üzere iki handle çalışmaktadır.  Ve

  1. runRole() Fonksiyonu

bu ortamdaki cihazı çalıştırmaya yarayan fonksiyon çalışmaktadır.

  1. NFCHandle :

NFC library’si Adafruit tarafından lisanslı python ile yazıldığından dolayı java kodumuza user’ın yerine python kodunu terminalde çalıştırmasını ve cevaplarını döndürmesini sağlamaktayız. Burada cevap okunan kart olacaktır. Bir if döngüsü ile sorguda doğru kartı bulmayı hedeflemekteyiz. Doğru kart geldiği anda runRole() fonksiyonu çalıştırılmaktadır.

  1. SOCKETHandle

Bu thread’da ServerSocket açılmaktadır. Port olarak 8000 kullanılmaktadır. Sonsuz döngü içerisinde Socket isteklerini kabul etmektedir ve her kabul edilen socket için okuyucu thread’ı oluşuturulmaktadır. Böylelikle aynı anda birden çok kişi kabul edilip işleme sokulabilir . Bu durum sisteme multi-threading yapısını katmaktadır. Okuyucu thread’ında basit olarak socketten gelen veri okunur ve runRole() fonksiyonu çalıştırılmaktadır.

  1. runRole() Fonksiyonu

Bu fonksiyon çalıştırıldığı anda röleyi kontrol eden GPIO pinine çıkış değerleri atanmaktadır. Başlangıç olarak 1 yapılır ve 1 saniye uykuya dalınır ve ardında 0 yapılır böylelikle GPIO High ve Low olur. Bu durum transistörün collectorunden emiterine yani rölenin uçları arasında potansiyel fark oluşturur. Böylelikle röle çalışmış olmaktadır.

3      Uygulama Şematikleri ve Fotoğrafları

3.1    Proteus Isis Çizimi

3

3.2    Proteus Ares Çizimi

4

4      Yazılım

Yazılım mimarisi temelde 2 yapıya ayrılmış olup aslında 3 yapıdan oluşmaktadır. NFC Reader kısmında Adafruit’in tarafından hazırlanan library kullanılmaktadır. Temel yapılar ;

  1. Beaglebone
  2. Android

4.1    Beaglebone

4.1.1   MainClass.java

import java.io.BufferedReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
 
public class MainClass {
	public static boolean PROJECT_DEBUG = true;
	public static boolean PROJECT_I2CDETECTED = false;
 
	public static void main(String[] args) {
 
		pinConfig();
		NFCConfig();
 
		 Thread NFCHandle = new Thread(new Runnable() {
 
			@Override
			public void run() {
				while(true){
					try {
						Process processNFC = Runtime.getRuntime().exec("sudo python3.3 /home/ubuntu/bbprojects/womp_door/nfcpy/nfc.py");
						processNFC.waitFor();
						BufferedReader bufci = new BufferedReader(
								new InputStreamReader( 
										processNFC.getInputStream()));
 
						String okunanDeger = bufci.readLine();
						if(okunanDeger.toString().equals("bytearray(b\'K\\x01\\x01\\x00\\x04\\x08\\x04\\xdb.S_\')") ){
							if(PROJECT_DEBUG == true)
								System.out.println("Role is run");
							runRole();
 
						}else{
							if(PROJECT_DEBUG == true)
								System.out.println("Wrong Card is readed (NFC) !");
						}
 
					} catch (IOException e) {
 
						if(PROJECT_DEBUG == true){
							System.out.println(e.toString());
							System.out.println("NFC IO Problem");
						}
					} catch (InterruptedException e) {
						if(PROJECT_DEBUG == true){
							System.out.println(e.toString());
							System.out.println("NFC InterruptedExeption Problem");
						}
					}
				}
 
			}
		});
 
		Thread SOCKETHandle = new Thread(new Runnable() {
 
			@Override
			public void run() {
				socketListener();
			}
		});
 
		NFCHandle.start();
		SOCKETHandle.start();
	}
 
	public static void pinConfig(){
		Process process1;
		Process process2;
		Process process3;
		try {
 
			FileWriter outFile1 = new FileWriter("/sys/class/gpio/export");
			PrintWriter out1 = new PrintWriter(outFile1);
			process1 =Runtime.getRuntime().exec("chmod 777 /sys/class/gpio/export");
			process1.waitFor(); 
			out1.println("60");
			out1.flush(); 
			out1.close(); 
 
			FileWriter outFile2 = new FileWriter("/sys/class/gpio/gpio60/direction");
			PrintWriter out2 = new PrintWriter(outFile2);
			process2 = Runtime.getRuntime().exec("chmod 777 /sys/class/gpio/gpio60/direction");
			process2.waitFor();
			out2.println("out");
			out2.flush();
			out2.close();
 
			if(PROJECT_DEBUG == true)
				System.out.println("Pin Configuration is OK!");
		} catch (IOException e) {
			if(PROJECT_DEBUG == true)
				System.out.println(e.toString());
		} catch (InterruptedException e) {
			if(PROJECT_DEBUG == true)
				System.out.println(e.toString());
		} 
 
	}
 
	public static void NFCConfig(){
 
		try {
			Process processI2C = Runtime.getRuntime().exec("i2cdetect -y -r 1");
			processI2C.waitFor();
			BufferedReader bufci = new BufferedReader(
					new InputStreamReader( 
					processI2C.getInputStream()));
			String readedI2C ="1";
			if((readedI2C = bufci.readLine()) != "Error: Read failed"){
				PROJECT_I2CDETECTED = true;
				if(PROJECT_DEBUG == true)
				System.out.println("I2C Detected..");
			}else{
				if(PROJECT_DEBUG == true)
				System.out.println("I2C Not Detected..");
			}
 
		} catch (IOException e) {
 
			System.out.println("NFC Config IO Exception Problem");
			System.out.println(e.toString());
		} catch (InterruptedException e) {
 
			System.out.println("NFC Config IntException Problem");
			System.out.println(e.toString());
		} 
	}
 
	public static void runRole(){
 
		Process process3;
		try {
			FileWriter outFile3 = new FileWriter("/sys/class/gpio/gpio60/value");
			PrintWriter out3 = new PrintWriter(outFile3);
			process3=Runtime.getRuntime().exec("chmod 777 /sys/class/gpio/gpio60/value");
			process3.waitFor();
			out3.println("1");
			out3.flush();
			Thread.sleep(1000);
			if(PROJECT_DEBUG == true)
				System.out.println("Pin On");
			out3.println("0");
			out3.flush();
			if(PROJECT_DEBUG == true)
				System.out.println("Pin Off");
			out3.close();
			if(PROJECT_DEBUG == true)
				System.out.println("Pin Output is OK!");
		} catch (IOException e) {
			if(PROJECT_DEBUG == true)
				System.out.println(e.toString());
 
			System.out.println("pin problem");
		} catch (InterruptedException e) {
 
			System.out.println("pin problem2");
			if(PROJECT_DEBUG == true)
				System.out.println(e.toString());
		} 
	}
 
	public static void socketListener() {
 
        ServerSocket sSocket = null;
		try {
			sSocket = new ServerSocket(8000);
		} catch (IOException e) {
			e.printStackTrace();
		}
	    System.out.println("server soket acildi");
 
	    while (true) {
	    	try {
	            final Socket socket = sSocket.accept();
	            System.out.println("socket accepted "+socket.toString());
 
	            if (socket.isConnected()) {
					System.out.println("socket connected. "+socket.toString());
				}
 
	            Thread th = new Thread(new Runnable() {
 
					@Override
					public void run() {
						BufferedReader buf;
						try {
							buf = new BufferedReader(new InputStreamReader(socket.getInputStream()));
 
							String veri = buf.readLine();
							if(veri.equals("1")){
								runRole();
								System.out.println("islem tamam");
							}
						} catch (IOException e) {
							e.printStackTrace();
						}
					}
				});
	            th.start();
	        } catch (IOException e1) {
				e1.printStackTrace();
			}
	    }
	}
}

4.2    Android

4.2.1      MainActivity.java

package com.gokhantarim.wompdoor;
 
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
 
import android.os.Bundle;
import android.os.StrictMode;
import android.app.Activity;
import android.view.Menu;
import android.widget.RemoteViews;
import android.widget.Toast;
 
public class MainActivity extends Activity {
 
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
 
		if (android.os.Build.VERSION.SDK_INT > 9) {
		    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
		    StrictMode.setThreadPolicy(policy);
		}
 
		try {
			Socket socket = new Socket("192.168.1.27", 8000);
			Toast.makeText(getApplicationContext(), "baglandı" , Toast.LENGTH_LONG).show();
			PrintWriter out = new PrintWriter(new OutputStreamWriter(
					socket.getOutputStream()), true);
			out.println(1);
			out.flush();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
 
		android.os.Process.killProcess(android.os.Process.myPid());
		System.exit(1);
	}
 
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}
 
}

4.2.2   AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.gokhantarim.wompdoor"
    android:versionCode="1"
    android:versionName="1.0" >
 
    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="18" />
	<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
	<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
 	<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
	<uses-permission android:name="android.permission.WAKE_LOCK"></uses-permission>
	<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
	<uses-permission android:name="android.permission.INTERNET"/>
 
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.gokhantarim.wompdoor.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
 
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
 
        <receiver android:name=".ExampleAppWidgetProvider" android:label="@string/app_name">
             <intent-filter >
                 <action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
             </intent-filter>
             <meta-data android:name="android.appwidget.provider"
                 android:resource="@xml/widget1_info" />
         </receiver>
 
    </application>
 
</manifest>

4.2.3   activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >
 
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />
 
</RelativeLayout>

5      Uygulama Çıktıları ve Fotoğrafları

5.1    Beaglebone Ekran Çıktıları

5 6

5.2    PCB ve NFC Reader Fotoğrafları

9 8 7

6      Sonuç

PCB çizim kısmında yaşadığım dikkatsizliklerden dolayı P8 slotunun son iki pinine bağlanmış olan kablolar aslında I2C’nin SCL ve SDA pinleridir. Doğru yerlerine kablo ile çekilmiştir.

Sistem sorunsuz şekilde çalışmaktadır. Burada ileriye dönük olarak her gerilimle ( 0-220V aralığındaki ) çalışan kontrol edilecek cihazların eklenmesi ile geliştiricinin hayal dünyasına kalmıştır.

Proje rapor pdf dosyasına buradan ulaşabilirsiniz : GTBBB_proje

___________

Gökhan TARIM
tarim.gokhan@gmail.com