C言語でボタン状態の取得

C言語でボタン状態の取得

WiringPi のC言語ライブラリにある
digitalRead() を使うことで
指定したGPIOポートの値を取得できる

vim button.c

でファイルを作成

ソースは

#include<stdio.h>
#include<wiringPi.h>

#define BTN_PORT 25

int main(void){
        int data, i;

        //初期化
        if(wiringPiSetupGpio() == -1) return 1;

        //GPIO mode in
        pinMode(BTN_PORT,INPUT);

        //読み込み
        for(i=0; i<10;i++){
                //GPIO の値読み込み
                data = digitalRead(BTN_PORT);


                printf("GPIO%d = %d\n",BTN_PORT,data);
                
                //1秒まつ
                sleep(1);
        }
        return 0;
}

最初に
#include
でライブラリなどを読み込む

#define は定数の定義

wiringPiSetupGpio() は
wiringPi の初期化

pinMode(GPIOポート番号 , 入力モード)
でポートのモードを設定
今回なら in モードなので INPUT

pinMode(BTN_PORT,INPUT);

digitalRead(GPIOポート番号)
でポートの値を取得
今回は

data = digitalRead(BTN_PORT);

として結果を変数data に格納している

これで

cc -o button button.c -lwiringPi

でコンパイル

構文は

cc -o 任意の名前 Cソースファイル名 -lwiringPi

これで実行するけど
権利者権限で実行しないとエラーになるので

sudo ./button 

これでボタンをおすと1
ボタンを押していないと0
が10回まで表示される

結果は

GPIO25 = 0
GPIO25 = 0
GPIO25 = 0
GPIO25 = 1
GPIO25 = 1
GPIO25 = 0
GPIO25 = 1
GPIO25 = 0
GPIO25 = 1
GPIO25 = 0

となった

raspbery Pi でボタンからの入力を検知

raspbery Pi でボタンからの入力を検知

GPIOポートが out モードのときなら
値が0なら 0V
値が1なら 3.3V
の電圧が出力される

これに対して
inモード、つまり入力のときには
GPIOポートの電圧に応じた値を読み込める

電圧 0V なら 0
3.3V なら 1
となる

GPIOポートはデジタル入力のため
値が 0 と 1 しかない

例えば
3.3V の半分の1.65V の電圧を加えても 0.5 にはならず
0と1のどっちかという不安定な値になってしまう

このため Raspberry Pi のGPIOポートに入力する電圧は値を正しく検知できるように
3.3V

0V
にする

今回はボタンをおすと 3.3 V の電圧が加わるようにする

使うパーツは
10KΩの抵抗
タクトスイッチ
ジャンパーケーブル3本
ブレッドボード
そして Raspberry Pi 本体

部品に関しては Amazon で購入

電子部品についてはセットであったのでこれを購入

抵抗に関しては少し分かりにくいため
カラー抵抗値の写真早読み表!

を参考に
一番左が茶色のものが 10KΩということで使用

部品に関してはこれでOK

GPIOのヘッダピンになる Pin1
これは一番左上のピン

これは 3.3 V が出力されているので
ボタンが押されたら、この 3.3V が
GPIO25 の Pin22 に加わるようにする
この位置は右上3番めにある

そしてGNDとの間には
10KΩの抵抗を入れる

これがプルダウン抵抗
これがないと
ボタンをおすと GPIO25に 3.3 V が加わるけど
押していないと何もつながっていない状態になる
しかし
電圧は 0V にならずに不安定な状態になっている

これを防ぐために
高い抵抗値をもつ抵抗をいれることで
GND側に電圧を引っ張る

ちなみに
GND側に抵抗をいれることをプルダウンと呼ぶ

注意点として4本足のボタンを使うので
ボタンを押したときににどのピンとつながるのかを調べておく必要がある

これで準備できたので、まずはコマンドでボタンの状態を取得

LEDを光らせるのと同じ手順になるけど
今回は入力になるので
モードが in になる

まずはGPIO25を inモードで使用開始宣言

echo 25 > /sys/class/gpio/export 

で使用するポートを宣言

echo in > /sys/class/gpio/gpio25/direction 

でモードを in に指定

次に cat コマンドで値を読み込む

cat /sys/class/gpio/gpio25/value 

まずはボタンを押していない状態で実行すると

になる

ボタンを押しながら

cat /sys/class/gpio/gpio25/value 

を実行すると

になる

このように、信号の入出力もファイルを読み書きする感覚でGPIOポートを扱うことができる

そして、GPIOポートの使用が終了したら
unexport で終了宣言をする

echo 25 > /sys/class/gpio/unexport 

ちなみに、WiringPi を使えばもっと簡単に操作できる

gpio mode コマンドで in モードに設定して
gpio read コマンドで値を読み出せる

まずはポートの設定
構文は

gpio -g mode 使用するGPIOポート番号 in

今回なら GPIO25 なので

gpio -g mode 25 in

次に gpio read コマンドで値を読み込む

構文は

gpio -g read GPIOポート番号

今回は GPIO25 なので

gpio -g read 25

これでボタンを入れながら実行すると

と表示され、入れずに実行すると

となる

C言語でLED操作

C言語でLED操作

WiringPi のC言語用ライブラリを使えば
C言語でGPIOポートを制御するプログラムをかける

C言語の基礎は
ドットインストールを参考にするとわかりやすい

http://dotinstall.com/lessons/basic_c
で基礎の動画みれます

基本文法はこれでいいけど
Wiring Pi の関数も覚える必要があるので
https://projects.drogon.net/raspberry-pi/wiringpi/functions/
を参考に
(英語のサイトになります)

この中で使うのとしては

wiringPiSetupGpio()
これで WiringPi の初期化
gpio -g を使ったのと同じようにGPIOポートで指定するために宣言する

pinMode(GPIOポート番号, モード)
指定したGPIOポートのモードを設定
出力なら OUTPUT になる

pinMode(4,OUTPUT);

というように書く
ほとんどの場合はポート番号は定数にする

digitalWrite(GPIOポート番号, 値)
指定したGPIOポート番号に値を出力する
値は


のどちらかになる

digitalWrite(4,1);

これらを元にC言語ファイルを作成

vim led.c

内容は

#include<wiringPi.h>

#define LED_PORT 4

int main(void){
        int i;

        //初期化
        if(wiringPiSetupGpio() == -1) return 1;
        pinMode(LED_PORT,OUTPUT);

        for(i=0;i<10;i++){
                //LED ON
                digitalWrite(LED_PORT,1);
                delay(500);

                digitalWrite(LED_PORT,0);
                delay(500);
        }
        return 0;
}

がソースになる

なお定数の宣言で ; を最後につけるとエラーになる
#define LED_PORT 4
に注意

次にコンパイル

cc -o led led.c -lwiringPi

構文は

cc -o 好きな名前 ソースファイル名 -lwiringPi

となる

実行するには

sudo ./led 

とする

管理者権限が必要なので sudo をつける必要がある

これをつけないと

wiringPiSetup: Must be root. (Did you forget sudo?)

と言うエラーがでてくるので注意

実行するとLEDの点灯と消灯を10回繰り返す

WiringPi でLEDの制御

WiringPi でLEDの制御

仮想ファイルにアクセスすればGPIOを制御できるけど
手順が複雑になる

このため WiringPi に付属している gpio ユーティリティを使うことで簡単に操作できる

まず gpio mode コマンドで
GPIOポートのモード

つまり入出力の方向を設定する

引数の mode の後に設定したいGPIOのポート番号と
in out などのモードを設定する

信号を出力してLEDを光らせるのなら
モードは out になる

また、オプションの -g をつけることで
GPIOポート番号で指定できる

-g オプションをつけないと
WieingPi の独自の番号になる

つまり、モードの構文は

gpio -g mode GPIOポート番号  モード

となる

今回はLEDを光らせるので

gpio -g mode 4 out

となる

これでモードの指定はできたので
gpio write コマンドで出力する

引数の write の後に
GPIOのポート番号

出力する値
を設定する

構文は

gpio -g write GPIOポート番号 値

となる

今回なら

gpio -g write 4 1

これを実行するとLEDが点灯する

また
gpio export コマンド
gpio unexport コマンド
を使うことで
GPIOポートの仮想ファイルの読み書きができる

これらは -g オプションをつけずに実行する

構文は

gpio export GPIOポート番号 モード
[/shell
と

gpio unexport GPIOポート番号 

となる

今回なら

gpio export 4 out
[/shel]
と

 gpio unexport 4 

となる

AndroidでCookieの利用

AndroidでCookieの利用

Cookieは、Webサイト側がブラウザを利用している端末に一時的にデータを保存する仕組み

端末へcookieを設定すれば
設定した端末のブラウザからWebサイトへアクセスしたときに
自動的にCookieの値を送信する

これは、ログイン情報の保持に使われる

AndroidのWebViewでもCookieが使えるので
これを使って自動ログインの仕組みの実装
アプリ内ブラウザか、それともそれ以外のブラウザかをサーバーで判定できる

Cookieを使うには
アプリの開始直後に
CookieSyncManagerクラスの
createInstance()を呼び出す

そして、
onResumeハンドラ
onPauseハンドラ

startSync()
stopSync()
を記述する

そして、CookieManagerクラスの
setAcceptCookie()を呼び出せば
Cookieの利用ができる

まず、メンバ変数の宣言

private WebView mWebView;

次に、onCreate()の中へCookieを使うための設定

CookieSyncManager.createInstance(getApplicationContext());

CookieManager cm = CookieManager.getInstance();

//Cookie利用開始
cm.setAcceptCookie(true);

//期限切れのCookie削除
cm.removeExpiredCookie();

setCookie();

途中に書いた resumeExpiredCookie()は
期限切れのCookieを削除するメソッド

次に、onResume()へ
startSync()を追加

@Override
protected void onResume(){
super.onResume();
CookieSyncManager.getInstance().startSync();
}

onPause()には、stopSync()を追加

@Override
protected void onPause(){
super.onPause();
CookieSyncManager.getInstance().stopSync();
}

次に、Cookieの設定
独自のCookieを設定するには
CookieManagerクラスのsetCookie()を使う

setCookie()の第1引数にはURL
第2引数には、Cookieとして設定する文字列を指定する

まずは、setCookie()の実装

private void setCookie(){

CookieManager cm = CookieManager.getInstance();
BasicClientCookie cookie = getSampleCookie();
cm.setCookie(cookie.getDomain(), toHeaderCookie(cookie));
CookieSyncManager.getInstance().Sync();
}

サンプルのCookieのURLを作成

private BasicClientCookie getSampleCookie(){

BasicClientCookie cookie = new BasicClientCookie("CookieSampleKey", "CookieSampleValue");
cookie.setDomain("サーバーのドメイン");
cookie.setPath("/");
return cookie;
}

そして、Cookieの値の作成

private String toHeaderCookie(BasicClientCookiec){

StringBuilder sb = new StringBuilder();
sb.append(c.getName()).append("=").append(c.getValue()).append(";");

sb.append("domain").append("=").append(c.getDomain()).append(";");

sb.append("path").append("=").append(c.getPath()).append(";");

return sb.toString();
}

GPIOポートからLED制御

GPIOポートからLED制御

Raspberry pi のGPIOポートは
値が0なら 0V
値が1なら 3.3V
の電圧が出力される

値が1のときにLEDが光るようにすれば
GPIOポートの信号が正しく出力されているかわかる

今回も270Ωの抵抗とLEDを使用

今回は
GPIO 04 を+
GND をーにする

ジャンパケーブルをさすのは
+が左上から4番め
ーは前回と同じく右から3番め

これで配線準備は完了
電源をいれても、今回は最初からLEDは点灯しない

次に、コマンドからLEDを制御する

現在動かしているOS Raspbianは
/sys/class/gpio/
の中にある仮想ファイルにアクセスすることで
GPIOポートを制御できる

GPIOポートを使う手順は
使用開始を宣言
入出力設定
値の入出力
使用終了の宣言
となる

これにアクセスするには root 権限を得るか
pi ユーザが gpioグループに所属していることが条件

 id -Gn pi

で所属しているグループをみることができる

pi adm dialout cdrom sudo audio video plugdev games users netdev input spi gpio

というように結果の中に gpio があればOK

これが確認できたら、操作開始

まずはGPIOの使用するポートを宣言
今回はGPIO 04 を使うので

echo 4 > /sys/class/gpio/export 

構文は
echo ポート番号 /sys/class/gpio/export
となる

これを実行すると
/sys/class/gpio/

の下に gpio4 という仮想ディレクトリができる

GPIO 04 の制御はここで行うことになる

次に、出力方向の指定
今回は信号を出力してLEDを光らせたいので
out を使う

出力方向の設定は

echo out > /sys/class/gpio/gpio4/direction 

構文は
echo out > /sys/class/gpio/使用するGPIOポート番号/direction
[/shell]

ここまででGPIO 04 の制御の準備ができたので
/sys/class/gpio/使用するGPIOポート番号/value
に値を書き込むと操作できる
点灯なら1
消灯なら0

今回は点灯なので

echo 1 > /sys/class/gpio/gpio4/value 

で点灯する

消したいのなら

echo 0 > /sys/class/gpio/gpio4/value 

とりあえずこれで操作は終了となるので
使用収量を宣言する必要がある

使用終了は

echo 4 > /sys/class/gpio/unexport 

というように

echo 終わりたいポート > /sys/class/gpio/unexport
とする

位置情報を利用したページの表示

位置情報を利用したページの表示

位置情報を利用したページは
アプリ利用者の位置情報を必要とするページのこと

JavascriptにGeolocation APIがあるので
これを使えるようにする

まずは、AndroidManifest.xmlへ権限を追加する

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

次に、JavaでGeoLocation APIの有効化
まずは、位置情報の取得の有効化
これで、Webページが位置情報をリクエストしてきたときに
アプリ側でリクエストを許可するかを決めることができる

まず、メンバ変数の定義

private WebView mWebView;

次に、onCreate()へWebView関連の処理追加

mWebView = new WebView(this);
setContentView(mWebView);

//Javascript有効化
mWebView.getSettings().setJavascriptEnabled(true);

setupGeoLocation(mWebView);
mWebView.setWebViewClient(new WebViewClient());

setupGeoLocation()は、ユーザー関数
つまり自作でつくる関数なので
これを追加する

private void setupGeoLocation(WebView webview){

WebSettings ws = webview.getSettings();

//位置情報取得の有効化
ws.setGeoLocationEnabled(true);

//DB保存場所の指定
File databaseDir = getDir("databases", Context.MODE_PRIVATE);

//保存場所がないなら新規作成
if(!databaseDir.exists()){
databaseDir.mkdirs();
}
ws.setGeoLocationDatabasePath(databaseDir.getPath());
}

次に、位置情報取得許可を表示するためのダイアログ作成

Webページが位置情報のリクエストをすると
WebChromeClientクラスの
onGeoLocationPermissionShowPrompt()
が呼ばれる

このタイミングでダイアログを表示して
ユーザーに位置情報取得許可を促す

これで、許可されたら
GeoLocationPermissions.Callbackインスタンスの
invoke()を呼ぶことで
Webページは位置情報を取得できるようになる

このダイアログ作成処理をonCreate()へ追加する

mWebView.setWebChromeClient(new WebChromeClient(){

@Override
public void onGeoLocationPermissionsShowPrompt(String origin, Callback callback){
GeoLocationPermissionDialog.newInstance(callback, origin).show(getFragmentManager(), GeoLocationPermissionDialog.FRG_TAG);
}

@Override
public void onGeoLocationPermissionsHidePrompt(){
FragmentManager fm = new FragmentManager();
Fragment f = fm.findFragmentByTag(GeoLocationPermissionDialog.FRG_TAG);

if(f != null){
GeoLocationPermissionDialog d = (GeoLocationPermissionDialog)f ;
d.dismissAllowingStateLoss();
}
}
});

mWebView.loadUrl("http://位置情報取得許可するページのURL");

次に、ダイアログフラグメントの作成

public static class GeoLocationPermissionDialog extends DialogFragment{

public static final String FRG_TAG = GeoLocationPermissionDialog.class.getSimpleName();

public static final String EXTRA_ORIGIN = "extra.ORIGIN";

private GeoLocationPermissionDialog newInstance(GeoLocationPermissions.Callback callback, String origin){
GeoLocationPermissionDialog f = new GeoLocationPermissionDialog();
f.mCallback = callback;
Bundle args = new Bundle();
args.putString(EXTRA_ORIGIN,origin);
f.setArguments(args);
return f;
}

次に、ダイアログの設定
はい、いいえボタンの動作を定義

@Override
public Dialog onCreateDialog(Bundle savedInstanceState){

AlertDialog.Builder = new AlertDialog.Builder(getActivity());

builder.setTitle("位置情報の要求");
builder.setMessage(String.format("このページはあなたの位置情報を求めてます¥n許可しますか?", getArguments().getString(EXTRA_ORIGIN)));

builder.setPositiveButton("はい",
new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which){
if(mCallback != null){
mCallback.invoke(
getArguments().getString(EXTRA_ORIGIN),true, false);
}
mCallback = null;
}
});

builder.setNegativeButton("キャンセル", null);

return builder.create();
}
}
@Override
public void onDismiss(DialogInterface dialog){

super.onDismiss(dialog);

if(mCallback != null){
mCallback.invoke(getArguments().getString(EXTRA_ORIGIN), false, false);

mCallback = null;
}
}

このクラスのinvoke()の引数は3つ

1つは、オリジン
オリジンとは、URLのうちの
スキーム
ホスト
ポートの組み合わせ
JavascriptやPHPやっているとわかりやすい

オリジンには
onGeoLocationPermissionsShowPromptハンドラの引数 origin を指定する

2つめの引数は、位置情報提供の許可、
拒否を表す真偽値
つまり許可ならtrue
拒否ならfalse

そして、3つめの引数が
今後も位置情報提供を記憶するかどうかの真偽値
つまり記憶するならtrue
記憶しないならfalse
となる

Raspberry Pi に WiringPi のインストール

Raspberry Pi に WiringPi のインストール

WiringPi は Raspberry Pi 用GPIOライブラリで
GPIOを利用するプログラムをC言語で作成するときに使える

またC言語だけでなく
Python
PHP
Ruby
Perl
などでも使えるラッパーがあるのでC言語以外でも使える

WiringPi にはC言語ライブラリ以外に
gpioユーティリティが付属している

これを使うことで
コマンドでGPIOの制御ができる

まずは準備
WiringPi を使うには
lib2c-dev という I2C の開発ライブラリが必要

 sudo apt-get install libi2c-dev

次に WiringPi のインストールだけど
apt-get でインストールはできない

ソースファイルのダウンロード
コンパイル
インストールという手順になる

まずはパッケージ管理ソフトで
ソースファイルを入手するために
git をインストールする

sudo apt-get install git-core 

次にソースファイルのダウンロード

git clone git://git.drogon.net/wiringPi

これで wiringPi ディレクトリが作成され
この中にファイルが展開される

次にコンパイル

 cd wiringPi/
./build 

コンパイルが完了すると
ライブラリやgpioユーティリティがインストールされる

念のためバージョンも確認

gpio -v


確認できる

結果は

gpio version: 2.20
Copyright (c) 2012-2014 Gordon Henderson
This is free software with ABSOLUTELY NO WARRANTY.
For details type: gpio -warranty

Raspberry Pi Details:
  Type: Model B, Revision: 2, Memory: 512MB, Maker: Sony 

これで、WiringPi はインストールできたけど
注意点としては
GPIOポートの指定方法が2つあること

1つはGPIOのポート番号を使う方法

もう1つは
WiringPi が独自に決めた番号で設定する方法

GPIOポートの場合だと
順番にならんでいないし番号もとびとび

WiringPi のほうだと0から順番に指定できるけど
配線作業のときに置き換える必要があるので面倒

というようにどちらがいいとは言えない

ある意味好みなのと
ソースを読むときに、この種類の違いを覚えておくと
動かない理由を探ることができる

Raspberry Pi とGPIOポート

Raspberry Pi とGPIOポート

raspberry pi のGPIOポートに
LED
スイッチ
モーターを制御するICなど様々な電子部品を接続することができる

なおGPIOポートは
デジタル出力なので
0か1のデジタル信号になる

各端子に出力する電圧が0Vなら0
3.3Vなら1になる

電圧の高低でデジタル情報を表すので
0ならL、つまり Low
1ならH つまりHigh
となる

Raspberry Pi には複数のGPIOポートがあるけど
ピン番号とGPIOポートの番号は一致していないので注意

GPIOポートについては
http://elinux.org/RPi_Low-level_peripherals#GPIO_hardware_hacking
にまとめられてるので参考に

そして
私の場合、ハンダ付けができないため
ブレッドボードを使用

ブレッドボードはユニバーサル基盤みたいにたくさん穴があるけど
さすだけで使えるのでこれを使う

基本的にはんだができないので
はんだを使わないものから実践

なお、秋葉原にハンダ付けカフェというものがあり
そこでも使えるみたい

営業日については
https://www.google.com/calendar/hosted/switch-science.com/embed?src=switch-science.com_adlqek3ketk3pl2sqjufv1fcos@group.calendar.google.com&ctz=Asia/Tokyo
を参考に

ブレッドボードは、ハンダ付けはいらない代わりに
ジャンパーワイヤーを使うことになる

書籍には
秋葉原とかで買えますって書いてあるけど
基本的に私の場合オンラインで購入したい

これは、引越しとかもあるし
東京在住でない人も実践できるから

あと、抵抗を買うときにはΩだけではダメで
何に使うかによっていろいろ変わるらしい

まずはLEDを光らせる通称Lチカに挑戦

一番迷うのが抵抗

これは
カラー抵抗値の写真早読み表!

を参考にさせてもらいました

抵抗については
150~330Ω程度
となっているので
ハック ラズベリーパイ Raspberry Pi 電子工作入門キット。

を購入し、その中から
赤のLED
ジャンパワイヤーのメスオスx2本
ブレッドボード
270Ωの抵抗

を使いました

抵抗は色で判断するしかないので
http://part.freelab.jp/s_regi_list.html
を参考に

見分けの方法ですが
金色の線をを右側にして
左側から3番めの線が橙色なのが 10KΩです

入っている部品は
10KΩ が4本
270Ω が4本
となっているので消去法で270Ωをみつけました

さらに、LEDにも極性
つまり+と-があります

LEDは足の長いほうが+で
アノードと呼ばれ
足の短いほうがーで
カノードと呼ばれます

ちなみに、抵抗には極性がないらしいです

これでブレッドボードを実践します

Raspberry Pi の 
Pin1 左上のところへ+の抵抗とつけたジャンパケーブルをさして

Pin 6 右上から3番めがGNDになるので
ここへLEDの-部分にさしたジャンパケーブルをさします

これで Raspberry Pi の電源を入れると
LEDが点灯します

次回は WiringPi を入れてLEDの操作をしていこうと思います

なお書籍で部品まで詳しく掲載されているものとして
Raspberry Piクックブック (Make:PROJECTS)

がありました

機会をみてショップのリンクなどを書いていこうと思います

AndroidでHTML5 のWebStorageの利用

AndroidでHTML5 のWebStorageの利用

HTML5からは、WebStorageAPIがあり
Javascriptを使うことでページを更新してもデータを永続化できるのがメリット

AndroidのWebViewの中でWebStorageを使うには
WebSettingsクラスの
setDatabaseEnabled()
setDomStorageEnabled()
を使う

これらにtrueをセットすることで
WebStorageの有効化ができる

さらに
setDatabasePath()へ保存先を指定すれば
データの保存も可能になる

private void setupWebStorage(WebView webview){

WebSettings ws = WebView.getSettings();

//DB有効化
ws.setDatabaseEnabled(true);
ws.setDomStorageEnabled(true);

//DB保存場所の指定
if(Build.VERSION_CODES.JELLY_BEANS_MR2 <= Build.VERSION_SDK_INT){
File databaseDir = getDir("databases", Context.MODE_PRIVATE);

保存場所がないなら新規作成
if(!databaseDir.exists()){
databaseDir.mkdirs();
}
ws.setDatabasePath(databaseDir.getPath());
}
}