Raspberry Pi 自分の用途に合わせたディスクイメージを作成する Debian 最小構成
5月 14, 2013 — 11:23

RaspbianはRaspberry Piに適した素晴らしいLinuxですがGUIが不要な用途だったりすると
不要なパッケージがあまりにも多く含まれていると感じたり
ほかのデスクトップ環境のディスクイメージを作りたいと考える人もいるかと思います
そこで、自分の用途に合わせたディスクイメージの作り方をメモしておきます

必要な物
・Raspberry Pi
・Raspbianの入ったSDカード
・空のSDカード
・カードリーダライタ

Raspbianの入ったSDカードで起動し
空のSDカードにディスクイメージとなる環境を作ります

SDのパーティション削除とジオメトリの設定
$ sudo fdisk /dev/sda

Command (m for help): p

Disk /dev/sda: 1990 MB, 1990197248 bytes
241 heads, 63 sectors/track, 256 cylinders, total 3887104 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *          63     3886847     1943392+   b  W95 FAT32

Command (m for help): d
Selected partition 1

Command (m for help): x

Expert command (m for help): h
Number of heads (1-256, default 241): 255

Expert command (m for help): s
Number of sectors (1-63, default 63): 63

Expert command (m for help): c
Number of cylinders (1-1048576, default 256): 各自計算したシリンダ数

Expert command (m for help): r

Command (m for help): p

Disk /dev/sda: 1990 MB, 1990197248 bytes
255 heads, 63 sectors/track, 241 cylinders, total 3887104 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

   Device Boot      Start         End      Blocks   Id  System

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

シリンダ数の計算
SDカードの容量 / 255 / 63 / 512 = シリンダ数
例) 1990197248 / 255 / 63 / 512 = 241
割り切れない数値は切り捨てます

Windowsパーティション’/boot’の作成 (64MB)
$ sudo fdisk /dev/sda

Command (m for help): n
Partition type:
   p   primary (0 primary, 0 extended, 4 free)
   e   extended
Select (default p):
Using default response p
Partition number (1-4, default 1):
Using default value 1
First sector (2048-3887103, default 2048):
Using default value 2048
Last sector, +sectors or +size{K,M,G} (2048-3887103, default 3887103): +64M

Command (m for help): t
Selected partition 1
Hex code (type L to list codes): c
Changed system type of partition 1 to c (W95 FAT32 (LBA))

Command (m for help): a
Partition number (1-4): 1

Command (m for help): p

Disk /dev/sda: 1990 MB, 1990197248 bytes
62 heads, 62 sectors/track, 1011 cylinders, total 3887104 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *        2048      133119       65536    c  W95 FAT32 (LBA)

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.

WARNING: If you have created or modified any DOS 6.x
partitions, please see the fdisk manual page for additional
information.
Syncing disks.

Linuxパーティション”/”の作成 (残りの容量全部)
$ sudo fdisk /dev/sda

Command (m for help): n
Partition type:
   p   primary (1 primary, 0 extended, 3 free)
   e   extended
Select (default p):
Using default response p
Partition number (1-4, default 2):
Using default value 2
First sector (133120-3887103, default 133120):
Using default value 133120
Last sector, +sectors or +size{K,M,G} (133120-3887103, default 3887103):
Using default value 3887103

Command (m for help): p

Disk /dev/sda: 1990 MB, 1990197248 bytes
40 heads, 6 sectors/track, 16196 cylinders, total 3887104 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *        2048      133119       65536    c  W95 FAT32 (LBA)
/dev/sda2          133120     3887103     1876992   83  Linux

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

必要なパッケージのインストール
$ sudo apt-get install dosfstools debootstrap git-core ca-certificates

フォーマット
$ sudo mkfs -t vfat -v -c -F 32 /dev/sda1
$ sudo mke2fs -t ext4 /dev/sda2 -m 1

SDカードに作成したパーティション/を/mntにマウントしてdebootstrapを使いDebianをインストール
$ sudo mount -o defaults,noatime /dev/sda2 /mnt/
$ sudo debootstrap –exclude=ed,nano –foreign –arch armel wheezy /mnt http://ftp.jp.debian.org/debian

必要なファイルをコピー
$ sudo cp /etc/inittab /mnt/etc/inittab
$ sudo cp /etc/hosts /mnt/etc/hosts
$ sudo cp /etc/fstab /mnt/etc/fstab
$ sudo cp /etc/network/interfaces /mnt/etc/network/interfaces

rootユーザで/mntをchrootし疑似的にLinuxを触る
chrootするとsudoコマンドは使えないためrootユーザになっておく必要があります
作業中は一応、ヒストリーに履歴が残ってしまうようなので残らないようにしておきます
debootstrapを実行させるとマウントしていた/procがアンマウントされるようなので再度マウントします
$ sudo su –
# export HISTSIZE=0 HISTFILESIZE=0
# chroot /mnt
# mount -n /proc
# export PATH=/bin:/sbin:/usr/bin:/usr/sbin
# /debootstrap/debootstrap –second-stage –no-resolve-deps
# mount -n /proc

リポジトリの追加
これは標準のDevianのリポジトリを追加していますが面倒ならRaspbian側のファイルをコピーしても問題ありません
# vi /etc/apt/sources.list

# See sources.list(5) for more information, especialy
# Remember that you can only use http, ftp or file URIs
# CDROMs are managed through the apt-cdrom tool.
deb http://http.us.debian.org/debian stable main contrib non-free
deb http://non-us.debian.org/debian-non-US stable/non-US main contrib non-free
deb http://security.debian.org stable/updates main contrib non-free

# Uncomment if you want the apt-get source function to work
#deb-src http://http.us.debian.org/debian stable main contrib non-free
#deb-src http://non-us.debian.org/debian-non-US stable/non-US main contrib non-free

アップデートとアップグレードの実行とその他、各自必要なパッケージのインストール
ここで好きなパッケージをインストールしておくことで用途に合わせたディスクイメージを作成することができます
# apt-get update
# apt-get upgrade
# apt-get install console-common console-setup console-data console-tools \
keyboard-configuration locales ntpdate ntp lua5.1 vim ssh sudo syslog-ng usbutils

ユーザの作成とsudoグループへの追加
この時にpasswdコマンドを使用しrootユーザのパスワードを設定することもできます
# adduser pi
# gpasswd -a pi sudo

chrootでの作業とrootでの作業の終了
# exit
# exit

起動時にeth0を有効化させる設定
$ sudo vi /mnt/etc/network/interfaces

auto lo eth0

iface lo inet loopback
iface eth0 inet dhcp

allow-hotplug wlan0
iface wlan0 inet manual
wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf
iface default inet dhcp

/bootとモジュールのコピー
$ sudo mount /dev/sda1 /mnt/boot
$ sudo cp -rp /boot/* /mnt/boot
$ sudo cp -rp /lib/modules/* /mnt/lib/modules

カーネルとモジュールのアップデート
$ sudo wget http://goo.gl/1BOfJ -O /usr/bin/rpi-update
$ sudo chmod +x /usr/bin/rpi-update
$ sudo ROOT_PATH=/mnt BOOT_PATH=/mnt/boot rpi-update

SDカードをアンマウント
$ sudo umount -l /mnt

シャットダウン
$ sudo shutdown -h now

SDカードを引き抜き、SDカードのイメージを作成すればオリジナルディスクイメージの完成です。
イメージ作成はWin32 Disk Imagerなどを使用すると簡単かもしれません

最後に作成したSDカードをRaspberry Piに接続し電源を入れ、正常に起動するするかを確認してみてください。

参考URL
覚書的な何か » Blog Archive » Raspberry PiでまっさらなDebianのインストール
Debian Linux for Raspberry Pi – GreenLeaf
Raspberry piにDebian squeezeをインストールする – もぐてっく
fdiskでフォーマットする – Android on Beagle

Bashで文字と数字を足してみると・・・?
5月 7, 2013 — 17:18

Bashの文字の処理について気になり調べていたところ
Bashの面白い仕様を見つけたので投稿します。
# C=’A’
# echo $((${C}+1));
1
# echo ${C};
A
# echo $((1+1));
2
# C=1
# echo $((${C}+1));
2
#

変数Cに文字Aを代入する
変数Cに1を足し結果を標準出力を行うと1が返る
変数Cを標準出力するとAが返る
数字1に1を足し結果を標準出力を行うと2が返る
変数Cに数字1を代入する
変数Cに1を足し結果を標準出力を行うと2が返る

変数内の文字に対する足し算はエラーを出さず完全に無視するようです。

Perl LWP::UserAgentを使ったHTTPS接続
5月 7, 2013 — 14:47

PerlでLWP::UserAgentを使い、HTTPSサイトへ接続を行いコンテンツを取得してくるプログラムを書く必要が出てきて、色々調べて書いたのですが情報が錯綜していたりで結構ハマったのでソースコードを載せておきます。
今回わけあったりでコンストラクタ側でProxyの情報を保持していなかったりしますが、そこはお好きに改変してお使いください。

#########################################################
#
# LWP::UserAgentを使ったHTTPS接続
#
#########################################################
use utf8;
use strict;
use warnings;

{
    package ProxyWebGet;

    use LWP::UserAgent;

    # コンストラクタ
    sub new {
        my ($class, @args) = @_;
        my %args = ref $args[0] eq 'HASH' ? %{$args[0]} : @args;
        my $self = {%args};

        # オプション項目
        $self->{ac_timeout} ||= 10;    # プロキシ接続時のタイムアウト(秒)

        return bless $self , $class;
    }

    # ホストとポート番号に対してProxy接続を行う
    # 引数にホストとポート番号と接続先URLを指定する
    sub proxy_connect {
        my $self = shift;
        my $proxy_host = shift; # ホストを受け取る
        my $proxy_port = shift; # ポート番号を受け取る
        my $target_url = shift; # 接続先URL

        # ホストとポート番号をLWP::UserAgentで利用できる形式に整形する
        my $http_proxy = 'http://' . $proxy_host . ':' . $proxy_port;

        $ENV{PERL_NET_HTTPS_SSL_SOCKET_CLASS} = 'Net::SSL';
        $ENV{PERL_LWP_SSL_VERIFY_HOSTNAME}    = 0;
        $ENV{HTTPS_PROXY}   = $http_proxy;
        $ENV{HTTPS_VERSION} = 3;

        # LWP::UserAgentのインスタンスの生成
        my $ua = LWP::UserAgent->new(
            timeout => $self->{ac_timeout} # オプションにタイムアウト時間を指定
        );

        # ヘッダーにUTF-8を含む場合エラーが出るため解析しない
        $ua->parse_head(0);

        # 整形したProxyを指定
        $ua->proxy(['http'], $http_proxy);

        # 指定されたURLへ接続する
        # FTP等のプロトコルに接続を行った場合
        # コネクションが維持されるため強制的に破棄する
        my $res = "";
        eval{
            local $SIG{ALRM} = sub{die "timeout"};
            alarm($self->{ac_timeout});   # タイマー設定
            $res = $ua->get($target_url); # URLへ接続しコンテンツを取得
            alarm(0);                     # タイマー解除
        };

        # ステータスコードが正常である場合、コンテンツを返す
        my $result = $res->is_success() ? $res->content() : "";

        return $result;
    }
}

{
    # sub main
    my $pwg = ProxyWebGet->new();

    print $pwg->proxy_connect(
              '000.000.000.000',
              '0000',
              'https://ja.wikipedia.org/wiki/'
          );
}
Linux ファイル・ディレクトリ作成時のデフォルトパーミッションを一般ユーザ権限で設定する
5月 6, 2013 — 10:51

学校やレンタルサーバなどではセキュリティーを意識してかデフォルトパーミッションが600や700に設定されていたりする場合がある。非常に良い設定であると思うが、普段からサーバを触る機会の多い自分からすれば普通にファイルを作成すれば他のユーザから閲覧される可能性があるのは百も承知な訳で煩わしいだけである。そのためこちら側でデフォルトパーミッションを変更したいと思う。

変更自体は簡単で”~/.bash_profile”の中に”umask 022″を追記すればファイルは644・ディレクトリは755で作成される。

面倒な場合やコマンドが叩ける環境であるならば下記のコマンドを実行すればよい。
$ echo “umask 022” >> ~/.bash_profile

ぴくぴくダウンローダ for Java(仮) Ver 6.10
4月 1, 2013 — 13:12

修正された項目

・Pixivの仕様変更により作品のダウンロードができなくなっていたのを対応しました。

Windows7 での実行の様子
WS000000

MacOSX での実行の様子
スクリーンショット 2013-01-14 16.31.21

Linux での実行の様子
Screenshot-ぴくぴくダウンローダ for Java (仮)

コマンドモードでの実行の様子

ダウンロード

こちらのダウンロードページよりダウンロードをお願い致します。

質問・問い合わせについて

質問・問い合わせは下のコメント欄にお願いいたします。また、質問を行う前に下記を確認してください。手順に沿わない場合は返答できない場合がございます。

正常に動かない等の問題があり質問・問い合わせを行う場合、実行場所(一軒家や集合住宅や学校などこれらの場所ではネットワークの環境が異なるため)、OS、Javaのバージョン、収集対象(実行時に指定したパラメータ)、停止した場所のコンソールの内容をお書きください。書いて頂けない場合こちらで検証することができないので返答することができません。

追加して欲しい機能がある場合、特にPixivの機能に依存するものなどは実際のページまでのURLなど詳しい情報をお書きください。それらの情報を元に今後のアップデートで実装可能か検討させて頂きます。

1万円で放射線量を計測して自動でTwitterに投稿する装置を作ろう!
3月 24, 2013 — 21:05

一昔前はこういう装置を作成するのに結構な費用が必要となっておりましたが最近は非常に低価格かつ簡単に実現することができます。そして計測結果は高い精度を期待できます。
今回は難しいハンダ付けやプログラミングをほとんど行わなくても作成できる事を目標とします。

利用するパーツ

Linux組み込みボード Raspberry Pi 3,500円
組み込み用線量計 ポケットガイガー Type 5 6,450円
ジャンパーワイヤー ジャンパーワイヤ オス⇔メス(10本セット) 400円
ジャンパーワイヤー ジャンパーワイヤ オス⇔オス(70本セット) 400円
ブレッドボード ブレッドボード EIC-801 250円
プルアップ抵抗 【CF1/4-22kΩJ】1/4Wカーボン抵抗 22kΩ 赤赤橙金(100本入) 283円
ピンソケット ピンヘッダ(オスL型) 1×40 (40P) 50円
SDカード ADATA ASDH4GCL4-R SDHCカード Class4 4GB 452円
合計 11,785円

※ 状況によっては価格は変動します。
※ 上記の他に、Windows OSをインストールしたパソコン、モニタ、HDMIケーブル、キーボード、マウス、ネット環境、MicroUSBケーブル、半田ゴテ、ハンダ線、こて台、Twitterアカウントが必要となります。

Twitterのディベロッパー登録

こちらのサイトを元にアプリケーションの登録を済ませておいてください。
下記の内容が必要となります。メモしておいてください。
CONSUMER_KEY,CONSUMER_SECRET,ACCESS_TOKEN,ACCESS_TOKEN_SECRET
bot開発物語 その2―アプリケーション登録―
※ 必ずAPI側でRead and Writeの権限を与えておいてください。

Raspberry PiへのOSインストール

以前の記事を参考にしてください。
Raspberry PiでRaspbianを日本語環境で動かそう!

ピンヘッダのハンダ付け

ピンヘッダの列から5本分を折り取りポケットガイガー Type5に差し込んでハンダ付けします。
IMG_1589[1]

Raspberry Piとポケットガイガー Type5の接続

ブレッドボードとジャンパーワイヤーを使用しRaspberry Piとポケットガイガー Type5の接続を行います。

ワイヤーの色とピンの対応表

ジャンパーワイヤー ポケガ RasPi
赤色 VCC 3v3
黒色 GND GND
青色 SIG GPIO 17
黄色 NS GPIO 27

ポケットガイガー Type5とプルアップ用抵抗をブレッドボードに設置しジャンパーワイヤー(オス⇔オス)で接続します。

IMG_1620[1]

IMG_1621[1]

IMG_1622[1]

ブレッドボードとRaspberry Piをジャンパーワイヤー(オス⇔メス)で接続すます。

IMG_1623[1]

IMG_1625[1]

※ 私のRaspberry PiはP5の位置にピンヘッダがハンダ付けされておりますが気にする必要はありません。

Raspberry Piのピン配置はこのようになっております。
Raspberry_Pi_GPIO

全体的に見るとこういう感じになります。
IMG_1627[1]

Raspberry Piへのプログラムインストール

起動とログイン

Raspberry Piとポケットガイガー Type5を接続した状態でRaspberry Piを起動します。
ログイン後コンソールに下記のコマンドを入力してデスクトップを起動してください。
$ sudo startx
※ こうすることにより管理者権限でGUIな操作を行うことができるようになります。
※ Linux初心者向けにGUIで解説しますがコンソールのみで操作できる方はX Windowを起動する必要ありません。

ターミナルの起動

左下メニュー”アクセサリ”→”LXTerminal”を起動してください。
snapshot1

起動に成功すると真っ黒な画面が出てきます。
snapshot2

真っ黒な画面の中に必要なコマンドを入力していきます。
snapshot3

gitコマンドのインストール

“LXTerminal”内に下記のコマンドを1行ずつ実行してください。
※ #以降の文字列を入力してください。
※ 依存パッケージのインストールを求められる事があります。その場合は”Enter”を押してください。
※ 場合によっては非常に時間が掛かる事があります。気長にお待ちください。
# apt-get update
# apt-get upgrade
# apt-get install git

wiringPiライブラリのインストール

“LXTerminal”内に下記のコマンドを1行ずつ実行してください。
# git clone git://git.drogon.net/wiringPi
# cd wiringPi
# git pull origin
# ./build
# cd ../

Rasdiationのインストール

“LXTerminal”内に下記のコマンドを1行ずつ実行してください。
# git clone git://github.com/orsp/Pocket_Rasdiation_Counter.git
# cd Pocket_Rasdiation_Counter
# make
# make install
# cd ../

Rasdiationの動作テスト

“LXTerminal”内に下記のコマンドを実行してください。
# rasdiation -s 17 -n 27 -b -m

下記の様にCPMやuSv/hの値がカウントされた状態で表示されていれば接続とインストールに成功しています。
snapshot4

Raspberry Pi起動時に連動したRasdiationの自動実行の設定

タスクバー左側アイコンより”ファイルマネージャ”を起動します。
snapshot5

ディレクトリパスに”/etc”と指定しその中の”inittab”をダブルクリックします。
snapshot6

ファイルの最後に下記の行を追記し上書き保存します。
alog:2000:respawn:/usr/local/bin/rasdiation -s 17 -n 27 -o /var/lib/rasdiation/rasdiation.fifo
snapshot7

python-tweepyライブラリのインストール

“LXTerminal”を起動してください。
“LXTerminal”内に下記のコマンドを実行してください。
※ 依存パッケージのインストールを求められる事があります。その場合は”Enter”を押してください。
# apt-get install python-tweepy
# easy_install tweepy
※ apt-getのpython-tweepyは古いようなのでこちらから新しいバージョンのpython-tweepyをインストールします。

Twitter自動投稿スクリプトの設置

“LXTerminal”内に下記のコマンドを1行ずつ実行してください。
# mkdir -p /GEIGERCOUNTER/Twitter
# cp Pocket_Rasdiation_Counter/example/twitter_post.py /GEIGERCOUNTER/Twitter/
# chmod 755 /GEIGERCOUNTER/Twitter/twitter_post.py

Twitter自動投稿スクリプトの設定

タスクバー左側アイコンより”ファイルマネージャ”を起動します。
ディレクトリパスに”/GEIGERCOUNTER/Twitter”と指定します。
“twitter_post.py”をダブルクリックで開きます。
snapshot13

“Twitterのディベロッパー登録”で得たパラメータを記述し上書き保存します。
snapshot14

Twitter自動投稿スクリプトの動作テスト

“LXTerminal”を起動してください。
“LXTerminal”内に下記のコマンドを実行してください。
# python /GEIGERCOUNTER/Twitter/twitter_post.py

設定したTwitterアカウントで下記のような内容がツイートされている事を確認してください。
※ 実際の投稿内容の日付や数値は変化します。
2013年03月24日(日) 11時35分 現在の放射線量は CPM:2.964 uSv/h:0.05589(誤差 0.00833) でした。

Twitter自動投稿スクリプトの定期実行の設定

タスクバー左側アイコンより”ファイルマネージャ”を起動します。
ディレクトリパスに”/etc/cron.d”と指定します。
snapshot8

中に空ファイル”twitter_post”を新規作成します。
snapshot9

作成した”twitter_post”をダブルクリックします。
snapshot10

下記の行を記述し上書き保存します。
※ この設定は30分毎に”twitter_post.py”を実行するという意味です。必要に応じて変更してください。
*/30 * * * * root python /GEIGERCOUNTER/Twitter/twitter_post.py
snapshot15

最終動作確認

正常に30分毎に投稿されるかを確認できましたら放射線量自動投稿機の完成です。
正しく設定されていればRaspberry Piを再起動しても自動で放射線量を計測し投稿いたします。

今回、ブレッドボードを使用しましたがユニバーサル基板を使い回路を作成しても良いかもしれません。
必要があればPythonのスクリプトを改造し自分の好みの投稿内容にするのも楽しいでしょうね。

Raspberry PiでRaspbianを日本語環境で動かそう!
3月 24, 2013 — 13:56

Raspberry PiのOSインストール

こちらからRaspberry PiにインストールするDebian系Linux OS “Raspbian”をダウンロードしてきます。
こちらからRaspbianをSDカードにインストールするためのプログラム”Win32DiskImager”をダウンロードします。

ダウンロードした双方の圧縮ファイルを展開します。

SDカードをパソコンに接続し展開したフォルダーから”Win32DiskImager.exe”を起動します。
※ “Win32DiskImager”の使用は書き込み先を間違うとデータ損失の危険性があります。慎重に行なってください。

ダウンロードした”Raspbian”のイメージファイルを選択し、書き込み先のSDカードを選択します。
準備ができたら”Write”ボタンを押してください。
WS000003

警告ダイアログが出てきます。問題がなければ”Yes”を押してください。
WS000004

書き込みが完了すると下記のダイアログが出ます。”OK”を押し、”Win32DiskImager.exe”を終了してください。
WS000007

Raspberry Piの初回起動

Raspberry PiにOSの入ったSDカードを接続し、キーボード、マウス、モニタ、LANケーブルを接続します。
準備ができたことを確認し最後にMicroUSBケーブルを接続します。
※ Raspberry Piには電源ボタンがありません。MicroUSBケーブルを接続した瞬間起動し始めます。
IMG_1610

起動中に下記のような初回設定画面が表示されます。
WS000008
※ 画像ではインストール後、SSHによる遠隔操作にて再現を行なっております。
※ ここでは、最低限の設定を紹介いたします。各自、必要に応じて設定を行なってください。

SDカードの容量全部を使用するようにします。

“expand_rootfs”を選択しTabキーを押し”Select”を選択し”Enter”を押します。
※ 以降、カーソルの移動に仕方につては省略して解説します。
WS000009

そのまま”Ok”を押して設定項目が並んでいる画面に戻ってください。
WS000014

画面をフルスクリーンで表示する設定を行います。

“overscan”を選択します。
WS000011

“Enable”を選択し設定項目が並んでいる画面に戻ってください。
WS000012

キーボードレイアウトを設定します。

“configure_keyboard”を選択します。
WS000013

“Generic 105-key (Intl) PC”を選択します。
WS000015

“Other”を選択します。
WS000016

“Japanese”を選択します。
WS000017

“Japanese”を選択します。
WS000018

“The default for the keyboard layout”を選択します。
WS000019

“No compose key”を選択します。
WS000020

そのまま”No”を押して設定項目が並んでいる画面に戻ってください。
WS000021

ローケルを設定します。

“change_locale”を選択します。
WS000022

“ja_JP.UTF-8 UTF-8″にSpaceキーでチェックを入れ、”Ok”押してください。
WS000023

“ja_JP.UTF-8″を選択し設定項目が並んでいる画面に戻ってください。
WS000024

タイムゾーンを設定します

“change_timezone”を選択します。
WS000025

“Asia”を選択します。
WS000026

“Tokyo”を選択し設定項目が並んでいる画面に戻ってください。
WS000027

OSをアップデートします

“update”を選択します。
※ アップデートにはインターネット環境が必要です。
※ 結構時間がかかります。気長に待ってください。
WS000028

設定を終了します

“Finish”を選択してください。
WS000029

日本語環境をインストール

コンソール画面に切り替わりましたら下記のコマンドを入力してください。
※ インストールにはインターネット環境が必要です。
※ 結構時間がかかります。気長に待ってください。
$ sudo apt-get install task-japanese task-japanese-desktop
WS000031

依存関係にあるパッケージのインストール求められるので”Enter”を押します。
WS000033

Raspberry Piを再起動します

日本語環境のインストールが完了しましたら下記のコマンドを入力してください。
※ 今回は若干エラーを吐いているパッケージもありますが気にしないことにします。
※ どうしてもエラーが気になる場合は$ sudo apt-get -f installと実行してください。
$ sudo reboot
WS000034

Raspberry Piのログイン

正常に起動すると下記のような文字列が表示されます。
下記のようにアカウント情報を入力してください。

My IP address is ***.***.***.***

Debian GNU/Linux 7.0 raspberrypi tty1

raspberrypi login: pi       ← ユーザ名
Password: raspberry         ← パスワード(入力中の文字列は表示されません)

デスクトップの起動

ログインするとコンソールが表示されます。
下記の様にコマンドを入力してデスクトップを起動してください。

$ startx
snapshot1

以上でインストール完了となります。

Raspbianでスクリーンショットを撮る
3月 24, 2013 — 13:55

Raspbianでスクリーンショットを撮ろうと思ったらパッケージが入っていなかったようなのでインストールしてみました。

$ sudo apt-get install ksnapshot

左下メニューの”グラフィックス”→”KSnapshot”から起動出来ます。

snapshot2

Raspberry PiでC言語を使い2つのスレッドを200ミリ秒と2秒ごとに処理させる
3月 17, 2013 — 17:45

Arduinoだとタイマー割り込みを使って処理したいところですが残念ながら私の調べた限りRaspberry Piでは無さそうなのでC言語とスレッドを利用し近い処理をさせることにしました。

$ vi thread_test.c

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

void *thread_function1( void *ptr );
void *thread_function2( void *ptr );

int main(void){
     pthread_t thread1, thread2;
     useconds_t tick1 = 200000;
     useconds_t tick2 = 2000000;

     pthread_create( &thread1, NULL, thread_function1, (void *) &tick1);
     pthread_create( &thread2, NULL, thread_function2, (void *) &tick2);

     pthread_join( thread1, NULL);
     pthread_join( thread2, NULL);

     return 0;
}

void *thread_function1(void *ptr){
    useconds_t tick = *( int * )ptr;

    while(1){
        printf("function1\n");
        usleep(tick);
    }
}

void *thread_function2(void *ptr){
    useconds_t tick = *( int * )ptr;

    while(1){
        printf("function2\n");
        usleep(tick);
    }
}

コンパイルします
$ gcc thread_test.c -pthread

実行
$ ./a.out

しかし、これでは共有資源を利用したプログラムを書いた場合取り合いになり下手をするとデータが失われたりする場合があるため排他制御するようにします。

$ vi thread_test.c

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

void *thread_function1( void *ptr );
void *thread_function2( void *ptr );

pthread_mutex_t mutex;
pthread_cond_t cond;
int count = 0;

useconds_t tick1 = 200000;
useconds_t tick2 = 2000000;

int main(void){
     pthread_t thread1, thread2;

     pthread_mutex_init(&mutex, NULL);

     pthread_create( &thread1, NULL, thread_function1, (void *) &tick1);
     pthread_create( &thread2, NULL, thread_function2, (void *) &tick2);

     pthread_join( thread1, NULL);
     pthread_join( thread2, NULL);

     pthread_mutex_destroy(&mutex);

     return 0;
}

void *thread_function1(void *ptr){
    useconds_t tick = *( int * )ptr;

    while(1){
        pthread_mutex_lock(&mutex);

        printf("function1 %d\n",count++);
        pthread_mutex_unlock(&mutex);
        usleep(tick);
    }
}

void *thread_function2(void *ptr){
    useconds_t tick = *( int * )ptr;

    while(1){
        pthread_mutex_lock(&mutex);

        printf("function2 %d\n",count++);
        pthread_mutex_unlock(&mutex);
        usleep(tick);
    }
}

コンパイルします
$ gcc thread_test.c -pthread

実行
$ ./a.out
function2 0
function1 1
function1 2
function1 3
function1 4
function1 5
function1 6
function1 7
function1 8
function1 9
function1 10
function2 11
function1 12
function1 13
function1 14
function1 15
function1 16
function1 17
function1 18

Raspberry PiでAdafruit製LCD(カラーバックライト+ボタン付きシールド)を利用する
3月 16, 2013 — 20:30

Raspberry PiでAdafruit RGB Negative 16×2 LCD+Keypad Kit for Raspberry Pi – を使ったプログラムをAdafruitの公式ライブラリを使い書いてみました。

シールドの組立、ライブラリのインストールや使い方は公式の方をご覧ください。

下記のソースコードはRasbperry Piの時間とインターフェイス毎のIPアドレスをLCDに表示します。

インターフェイス毎のローカルIPアドレスを取得するために”netifaces”ライブラリを使用しております。
$ apt-get install python-netifaces

/LCDディレクトリを作成し公式ライブラリを入れておきます。
$ sudo mkdir /LCD

$ sudo vi /LCD/MENU_LCD.py

#!/usr/bin/env python
from netifaces import interfaces, ifaddresses, AF_INET

from time import sleep
from Adafruit_I2C import Adafruit_I2C
from Adafruit_MCP230xx import Adafruit_MCP230XX
from Adafruit_CharLCDPlate import Adafruit_CharLCDPlate

from IPaddr_LCD import IPaddr_LCD
from DateTime_LCD import DateTime_LCD

import smbus

lcd = Adafruit_CharLCDPlate(busnum = 1)

class MENU_LCD():
    def get_const_list(self):
        const_list   = []

        ip   = IPaddr_LCD()
        time = DateTime_LCD()

        const_list.append(ip)
        const_list.append(time)

        return const_list

    def print_progress(self, sleep_time, message):
        lcd.clear()
        lcd.message(message)
        sleep(sleep_time)
        self.print_lcd()

    def print_lcd(self):
        pointer_id = 0
        push_flag  = 0

        lcd.clear()
        lcd.message("Please Push\nRite/Left Button")

        const_list = self.get_const_list()
        const_list_size = len(const_list) - 1

        while 1:
            if (lcd.buttonPressed(lcd.RIGHT) or lcd.buttonPressed(lcd.LEFT)):
                if (lcd.buttonPressed(lcd.RIGHT)):
                    if (pointer_id < const_list_size):
                        pointer_id += 1
                    else:
                        pointer_id = 0

                if (lcd.buttonPressed(lcd.LEFT)):
                    if (pointer_id > 0):
                        pointer_id -= 1
                    else:
                        pointer_id = const_list_size

                push_flag  = 1
                const_list[pointer_id].title()

            if (push_flag > 0 and lcd.buttonPressed(lcd.SELECT)):
                const_list[pointer_id].print_lcd()
                break

            if (push_flag > 0 and lcd.buttonPressed(lcd.UP)):
                break

            if (push_flag > 0 and lcd.buttonPressed(lcd.DOWN)):
                break

            sleep(.2)
        return self.print_progress(1, "Reinitializeing\nPlease wate....")

if __name__ == '__main__':
    try:
        menu = MENU_LCD()
        menu.print_progress(3, "Initializeing\nPlease wate....")
        menu.print_lcd()
    except KeyboardInterrupt:
        print("Exit\n")

$ sudo vi /LCD/DateTime_LCD.py

#!/usr/bin/env python
import datetime
import locale

from time import sleep
from Adafruit_I2C import Adafruit_I2C
from Adafruit_MCP230xx import Adafruit_MCP230XX
from Adafruit_CharLCDPlate import Adafruit_CharLCDPlate

import smbus

lcd = Adafruit_CharLCDPlate(busnum = 1)

class DateTime_LCD():
    def title(self):
        lcd.clear()
        lcd.message("Raspberry Pi\nDate Time")
        return

    def print_lcd(self):

        while 1:
            d = datetime.datetime.today()
            time = d.strftime("Date %Y/%m/%d\nTime  %H:%M:%S")

            lcd.clear()
            lcd.message(time)

            if (lcd.buttonPressed(lcd.RIGHT)):
                break

            if (lcd.buttonPressed(lcd.LEFT)):
                break

            sleep(.2)
        return


if __name__ == '__main__':
    try:
        time = DateTime_LCD()
        time.print_lcd()
    except KeyboardInterrupt:
        print("Exit\n")

$ sudo vi /LCD/IPaddr_LCD.py

#!/usr/bin/env python
from netifaces import interfaces, ifaddresses, AF_INET

from time import sleep
from Adafruit_I2C import Adafruit_I2C
from Adafruit_MCP230xx import Adafruit_MCP230XX
from Adafruit_CharLCDPlate import Adafruit_CharLCDPlate

import smbus

lcd = Adafruit_CharLCDPlate(busnum = 1)

class IPaddr_LCD():
    def title(self):
        lcd.clear()
        lcd.message("Raspberry Pi\nIP Address")
        return

    def get_ip_list(self):
        ipaddr_list   = []
        for ifaceName in interfaces():
            nic_ip_list = []
            addresses = [i['addr'] for i in ifaddresses(ifaceName).setdefault(AF_INET, [{'addr':'No IP addr'}] )]
            nic = '%s' % (ifaceName)
            ip  = '%s' % (', '.join(addresses))
            nic_ip_list.append(nic)
            nic_ip_list.append(ip)
            ipaddr_list.append(nic_ip_list)
        return ipaddr_list

    def print_lcd(self):
        pointer_id = 0

        lcd.clear()
        lcd.message("Please Push\nUp/Down Button")

        while 1:
            if (lcd.buttonPressed(lcd.UP) or lcd.buttonPressed(lcd.DOWN)):
                ipaddr_list = self.get_ip_list()
                ipaddr_list_size = len(ipaddr_list) - 1

                if (lcd.buttonPressed(lcd.UP)):
                    if (pointer_id < ipaddr_list_size):
                        pointer_id += 1
                    else:
                        pointer_id = 0

                if (lcd.buttonPressed(lcd.DOWN)):
                    if (pointer_id > 0):
                        pointer_id -= 1
                    else:
                        pointer_id = ipaddr_list_size

                lcd.clear()
                lcd.message(ipaddr_list[pointer_id][0] + "\n" + ipaddr_list[pointer_id][1])

            if (lcd.buttonPressed(lcd.RIGHT)):
                break

            if (lcd.buttonPressed(lcd.LEFT)):
                break

            sleep(.2)
        return

if __name__ == '__main__':
    try:
        ip = IPaddr_LCD()
        ip.print_lcd()
    except KeyboardInterrupt:
        print("Exit\n")

コマンド用の実行ファイルを作成しておきます
$ sudo vi /LCD/LCD_PRINTER

#!/usr/bin/env python
from MENU_LCD import MENU_LCD

if __name__ == '__main__':
    try:
        menu = MENU_LCD()
        menu.print_progress(3, "Initializeing\nPlease wate....")
        menu.print_lcd()
    except KeyboardInterrupt:
        print("Exit\n")

実行権限を与えどこからでもパスが通るように”/usr/bin/”の中にシンボリックを貼っておきます。
$ sudo chmod 700 /LCD/LCD_PRINTER
$ sudo ln -s /LCD/LCD_PRINTER /usr/bin/LCD_PRINTER

せっかくなので起動スクリプトも書いてみました。
$ sudo mkdir /LCD/init.d/
$ sudo vi /LCD/init.d/lcd_printer

#!/bin/sh
### BEGIN INIT INFO
# Provides:          LCD_PRINTER
# chkconfig:         2345 91 91
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Description:       LCD_PRINTER daemon script.
### END INIT INFO

. /lib/lsb/init-functions

PATH=/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/bin/LCD_PRINTER
DAEMON_NAME=`basename $DAEMON`
PIDFILE="/var/run/lcd_printer.pid"

set -e

start() {
  log_daemon_msg "Starting $DAEMON_NAME"
  if ! start-stop-daemon --stop --quiet --pidfile ${PIDFILE} --signal 0; then
    start-stop-daemon --start --pidfile ${PIDFILE} --make-pidfile --quiet --background --exec ${DAEMON}
    log_end_msg $?
  else
    echo -n " already running."
    log_end_msg 1
  fi
}

stop() {
  log_daemon_msg "Stopping $DAEMON_NAME"
  start-stop-daemon --stop --pidfile ${PIDFILE}
  log_end_msg $?
}

case "$1" in
  start)
    start
    ;;
  stop)
    stop
    ;;
  restart)
    stop
    start
    ;;
  status)
    status_of_proc -p $PIDFILE $DAEMON $DAEMON_NAME && exit 0 || exit $?
    ;;
  *)
    echo $"Usage: $DAEMONNAME {start|stop|restart|status}" >&2
    exit 1
    ;;
esac
exit 0

実行権限を与え、起動スクリプトとして”/etc/init.d/”の中にシンボリックを貼っておきます。
$ sudo chmod 755 /LCD/init.d/lcd_printer
$ sudo ln -s /LCD/init.d/lcd_printer /etc/init.d/lcd_printer

起動するか確認してみます。
$ sudo service lcd_printer start

自動起動するように設定します。
$ sudo update-rc.d lcd_printer defaults

自動起動するか確認します。完全に電源を落とすためrebootではなくシャットダウンして電源を入れます。
$ sudo shutdown -h now

余談ですがRedHat系はchkconfigで設定するのですがDebian系は違うのですね・・・勉強になりました。