Ses ile Raspberry Pi 2 üzerinde LED kontrol

Bu yazıda Raspberry Pi 2'ye bağladığımız bir LED'i Windows Phone'dan internet aracılığı ile kontrol edeceğiz. Bu kontrolü ses (ingilizce) veya buton yardımıyla yapacağız.

  Raspberry Windows Phone  

Nasıl çalışacak?

  1. Windows Phone üzerinden ses ile komut vereceğiz. (Şuan için on/off) Sadece ses ile değil buton aracılığı ilede bu işlemi yapabilmeliyiz.
  2. Windows Phone veriyi SignalR ile azure'da bulunan bir web sitesine gönderecek. Bu web siteside yine signalR ile bağlı olan Raspberry Pi'a gönderilecek. (birden çok raspberry pi bağlamak mümkün.)
  3. Raspberry Pi bu komutu signalR aracılığı ile alacak ve gelen veriye göre pin'e gerekli değerleri gönderecek.

   

Kullanacağımız Teknolojiler

Tüm kodlarımızı C# ile yazacağız.

  • Raspberry Pi 2 üzerinde mono kullanacağız. Mono nasıl yüklenir?
  • SignalR (bunun için bir tane asp.net projesi oluşturacağız ve azure websites'ta yayınlayacağız).
  • Windows Phone'da çalışacak uygulamamızı C# ve XAML ile yazacağız.

       

Raspberry Client Uygulaması

Visual Studio'yu açalım ve bir tane C# console uygulaması yaratalım. Aşağıdaki kodları projemize yazalım.

Kodlarda gördüğünüz gibi WiringPi namespace'ine ihtiyacınız olacak. Gereken kodları https://github.com/LocalJoost/SunfounderTest1/tree/master/WiringPi adresinden bulabilirsiniz.

   

Bu kodları build ettikten sonra Raspberry Pi'a yüykleyebiliriz. Ancak Raspberry Pi üzerinde wiringPi ve mono yüklü olamlı. (Mono Nasıl yüklenir?, WiringPi nasıl yüklenir?)

   

SignalR Service

Visual Studio da bir tane Web Application açıyoruz ve Package Manager Console'a

  • Install-Package Microsoft.AspNet.SignalR
  • Update-Package

Komutlarını yazarak SignalR kütüphanelerini projemize ekliyoruz ve gerekli paketleri güncelliyoruz.

Daha sonra MessageHub adında bir class yaratıyoruz ve aşağıdaki kodları yazıyoruz.

   

Daha sonra signalR içeren web projesini Azure Web Sites'a deploy ediyoruz. (Azure yerine .net host edebileceğiniz başka bir server'da olabilir)

   

   

Windows Phone Client Uygulaması

Visual Studio üzerinde yeni bir Windows Phone 8.1 uygulaması yaratıyoruz ve MainPage.xaml içine aşağıdaki kodları yazıyoruz.

   

   

Daha sonra MainPage.xaml.cs dosyasına geçerek aşağıdaki kodu yazıyoruz.

   

   

Daha sonra Package.appxmanifest dosyası içerisinde Capabilities tabı içerisinde Microphone'a check atıyoruz. Böylece uygulamamızın mikrofone erişim yetkisi olacak.

   

Artık Windows Phone uygulamamız hazır. Uygulama üzerinde bulunan textBox'a yazdığın pin numarası ve toogleSwitch ile ayarladığınız on/off değeri gönder butonuna bastığınızda SignalR server'a gönderilecektir. Ve Raspberry Client uygulamamız bu veriyi alacaktır. Komutu ses ile de vermeniz mümkün bunun içinde Speech To Text butonuna basarak Turn off the light veya Turn on the light demeniz yeterli. Bu özellikte pin numarası eklemediğimi şimdi fark ediyorum bunuda siz ekleyebilirsiniz. "Turn on the first light" derseniz 0 numaralı pin'in çalışması gibi bir mantık izleyebilirsiniz.

   

Fiziksel Bağlantı

Raspberry Pi 2 üzerindeki 11 numaralı pin'e LED'in kısa bacağını, 6 numaralı pin'e ise LED'in uzun bacağını bağlamanız(arada 270k resistor kullanmanızı öneririm) gerekmekte. Pin numaralarını aşağıdaki şemada bulabilirsiniz.

   

Uygulamayı çalıştırma zamanı

İlk olarak raspberry pi üzerinde client uygulamasını çalıştıralım ve Started yazmasını bekleylim. Console'a started yazdığında herşey tamam ve bizden komut bekliyor demektir. Şimdi Windows Phone uygulamasını acarak ve "Turn on the light" demeniz yeterli. Veya textBox'a 0 yazarak On konumunda butona basabilirsiniz.

   

Kodlar için: https://github.com/altinokdarici/RPiSignalR

   

Demo

Mobile Services JS Backend - Data - Kayıt Ekleme (Insert)

Mobile Services tablo nasıl oluşturulur yazısına yukarıda bulunan linkten gidebilirsiniz.

   

Proje Oluşturalım

Şimdi bir tane Univerall App projesi açıyoruz ve bu tablodan veri okuyup yazma işlemlerinin nasıl olduğuna bakiyoruz.

Install-Package WindowsAzure.MobileServices

Komutu ile nuget package yüklüyoruz, bu işlemi hem Windows Phone hem Windows projesi için ayrı ayrı yapmanız gerekmektedir.

Projelerimizdeki tüm MainPage.xaml dosyalarını siliyoruz ve .Shared projesi içerisine bir tane MainPage.xaml isminde dosya oluşturuyoruz. Bu dosya hem Windows Phone hem Windows projesinde çalışacaktır.

   

MainPage.xaml içine aşağıdaki kodları yazıyoruz.

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

<Grid.RowDefinitions>

            <RowDefinition Height="230"/>

            <RowDefinition Height="*"/>

</Grid.RowDefinitions>

<StackPanel Grid.Row="0">

            <TextBox Header="Adi" x:Name="TextBoxName"/>

            <TextBox Header="Soyadi" x:Name="TextBoxSurname"/>

            <Button Content="Gönder" x:Name="ButtonKaydet" Click="ButtonKaydet_Click"/>

</StackPanel>

<ListView x:Name="ListViewPersons" Grid.Row="1">

                <ListView.ItemTemplate>

                    <DataTemplate>

                        <TextBlock>

                            <Run Text="{Binding Adi}"/>

                            <LineBreak/>

                            <Run Text="{Binding Soyadi}"/>

                        </TextBlock>

                    </DataTemplate>

                </ListView.ItemTemplate>

            </ListView>  

</Grid>

 <Page.BottomAppBar>

<CommandBar>

          <AppBarButton Label="Refresh" Icon="Refresh" Click="AppBarButton_Click"/>

</CommandBar>   

</Page.BottomAppBar>

Yukarıdaki kodu yazarak aşağıdaki ekran görüntüsünü elde edeceksiniz.

   

MainPage.xaml Design

   

Gördüğünüz gibi iki textbox, bir buton ve birde göremediğimiz bir listview var. Kullanıcı textbox'lara bilgileri girecek ve Gönder butonuna basacak böylece bilgiler hem aşağıdaki ListViewda gösterilecek hemde Azure'da bulunan mobile services table'ina kayıt edilecek. Aşağıdaki refresh butonuna basıldığında ise tüm tablodaki bilgiler listview'a tekrar yüklenecek. Aynı şekilde sayfa ilk açıldığında tüm bilgiler tablodan listview'a yüklenecek.

   

Insert

Tablomuz ve görsel olarak projemiz hazır şimdi MainPage.xaml.cs dosyasına giderek aşağıdaki kodu yazalım ve URL, APPKEY bölümlerini kendi azure hesabınızın bilgileri ile değiştirin.

  

public class Kisiler

{

public string Id { get; set; }//mecburi

public string Adi { get; set; }

public string Soyadi { get; set; }

}

public sealed partial class MainPage : Page

{

private IMobileServiceClient client = new MobileServiceClient("URL", "APPKEY");

private ObservableCollection kisiler = new ObservableCollection();

private IMobileServiceTable tableClient;

public MainPage()

{

this.InitializeComponent();

tableClient = client.GetTable();

} 

private async void ButtonKaydet_Click(object sender, RoutedEventArgs e)

{

var kisi = new Kisiler()

{

Adi = TextBoxName.Text,

Soyadi = TextBoxSurname.Text

};

await tableClient.InsertAsync(kisi);//Azure'a gonder

kisiler.Add(kisi);//UI guncelle 

}
}

Yukarıdaki kodu biraz inceleyecek olursak. İlk önce Mobile Service'ta yaratmış olduğumuz tablo ile aynı isimde "Kisiler" bir class yarattık bu bizim data class'imiz olacak. Bu class içerisine string türünde Id isimli bir property yazdım. Bu Id property'si mecburen olmak zorunda. Daha sonra string tipinde Adi ve Soyadi olarak 2 property daha ekledim. Bu class'tan yaratılan her nesne mobile service table'daki bir satıra karşılık geliyor olarak düşünebilirsiniz.

   

Mobile Services ile bağlantı kurabilmek için IMobileServiceClient türünden client adında bir değişken yarattık, daha sonra tabloya ulaşabilmek için IMobileServiceTable<Kisiler> tableClient olarak bir değişken yarattık ve constructor'da bu tableClienta değer atadık bu aşamada client.GetTable<Kisiler> diyerek tabloya ulaşabildik. Burada dikkat edilmesi gereken konu Tablo ismi ile class isminin aynı olması. Eğer isimler farklı ise client.GetTable<ClassAdi>("TabloAdi") şeklinde kullanabilirsiniz.

   

Daha sonra kaydet butonuna basıldığında çalışması için yeni bir Kisiler nesnesi yarattık ve kisi olarak isimlendirdik. tableClient.InsertAsync(kisi) kodu ile oluşturduğumuz kişi nesnesini azure'a gönderdik. Ardından kisiler isimli ObservableCollection'imiza kişiyi ekledik ve ListViewda görünmesini sağladık.

   

Azure tarafına bakacak olursak;

Management Portal üzerinden tablonun içine giriyoruz ve Browse segmesinden tablo içeriğini görüyoruz.

   

   

Table Content

   

   

Gördüğünüz gibi Adi, Soyadi ismindeki kolonlar otomatik olarak yaratıldı, Id otomatik olarak atandı ve __ ile başlayan bir kaç kolon daha yaratıldı bu kolonlar mobile services tarafından tutarlılığı sağlamak amacıyla otomatik olarak ekleniyor.


Dinamik Şema

Şimdi Kisiler Class'ina bir property daha ekleyelim ve tekrar bakalm. UI'a bir textbox daha ekliyorum ve class'a bir property daha ekliyorum.

public class Kisiler
{

public string Id { get; set; }//mecburi

public string Adi { get; set; }

public string Soyadi { get; set; }

public int Yas { get; set; }

}

private async void ButtonKaydet_Click(object sender, RoutedEventArgs e)
{

var kisi = new Kisiler()
{

Adi = TextBoxName.Text,

Soyadi = TextBoxSurname.Text,

Yas = int.Parse(TextBoxAge.Text)

};
await tableClient.InsertAsync(kisi);//Azure'a gonder

kisiler.Add(kisi);//UI guncelle
}

Yeni görsel ve class'i yukarıdaki gibi değiştirdim. Tekrar çalışıtırıyorum ve bir kayıt daha ekliyorum. Tekrar Mobile Services table'a bakalım.

   

Table Content - 2

   

Gördüğünüz gibi Yas otomatik olarak server tarafına eklendi. Bunun ne kadar hızlı developmenta izin veren birşey olduğunu umarım. Bu sayede sadece client tarafındaki modeli değiştirerek bu değişikliğin database'I etkilimesini sağlamış oluyoruz.

Dikkat!! Tabiki bu özelliğin production esnasında açık bırakılması kötü niyetli kişiler tarafından kötü şekilde kullanılabilir. (Zor ama olabilir) Bu sebepten bu özelliği Mobile Services Configure tabından kapatmanızı öneririm (development bittiğinde).

Dynamic Schema

   

   

Server Tarafında Script

Insert isteğiniz server'a gittiğinde bir takım kodların çalışmasını isteyebilirsiniz. Örneğin giden insert isteğinin server tarafında kontrol edilmesini istedik ve eğer yas 20den büyük ise Status kolonuna 20 üstü yazsın eğer 20 altında ise 20 alti yazsın. Status adında bir kolonun daha önce olmadığını hatırlatmak isterim ve bu kolonu uygulama içerisindeki class'a eklemedim.

   

Server Script

   

Yeni bir insert requesti yaptım ve yaşı 50 olarak girdim, server tarafında yazdığım kod çalıştı ve server tarafına Status diye bir kolon eklendi.

Table Content - 3

   

Tabiki bu işlemi yapabilmeniz için Dynamic Scheme özelliğinin açık olması gerekmekte. Server Script esnasında insert, update, delete, read gibi operation'larin arasına girerek kod yazmanız mümkün. Sadece bu tip kontrol değil notification atmaktan tutun direkt olarak sql'e bağlanmaya kadar herşeyi yapmak çok kolay ve mümkün. Örneklerini ilerleyen yazılarda yapacağım.

   

   

Aşağıdaki linkten kodlara ulaşabilirsiniz.

https://github.com/altinokdarici/AzureEgitimSerisi/tree/master/MobileServices/JavascriptBackend/Data