Category Archives: PERSONAL COMPUTER - Page 4

Linux ファイル・ディレクトリ作成時のデフォルトパーミッションを一般ユーザ権限で設定する

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

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

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

Bashでインタプリタ(Brainf*ck)を書いてみる

ワケありましてBrainf*ckを書くことになりBashでこんなものを書く人は少ないかもなと思いながら実装してみました。
とりあえずWikipediaで公開されている”Hello, world!”は実行出来ます。
色んなところで公開されている”FizzBuzz”も試した限りでは動作しているようです。

#!/bin/bash
############################################################################
#
# メモ
#
# このソースコードは私のサーバにて一般公開しております
# 公開先: https://www.orsx.net/archives/4469
#
# Bashは明確にローカル変数であることを宣言しなければ
# 全てグローバル変数となるが・・・・
# とりあえず初期化する関数を定義すれば追いやすくなるかもしれないとかと
# べ、別にこんなもの無くても問題ない。。。
#
# 言語によっては最後に標準出力した値を返り値として返す物があったりするため
# 癖で関数の最後には必ず明的にreturnしてあるが・・・
# べ、別にこんなもの無くても問題ない。。。
#
# ちなみに、変数は下記のようになっている
# ・グローバル変数は大文字
# ・ローカル変数は小文字
#
############################################################################

# 使用するグローバル変数を明的に初期化する
function initialize() {
  # 変数
  TEXT_SRC=""
  CODE_LEN=0
  CODE_PTR=0
  BUFF_PTR=0
  BUFF_LEN=0

  # 配列
  CODE=()
  BUFF=()

  return
}

# EOF(CTRL+D)が来るまで読み続け改行は無視する
# グローバル変数SRCにソースコードを格納する
function readstring() {
  local line
  while read line
  do
    # 文字列連結 連結演算子は存在しない
    TEXT_SRC=$TEXT_SRC$line
  done

  # returnは数字しか返せない
  return
}

# 標準入力で1文字だけ受け取る
function readchar() {
  local line
  read line
  # 文字を数字に変換
  BUFF[${BUFF_PTR}]=$(printf "%d" "'${line:0:1}")

  return
}

# ASCIIコードからアルファベットを表示する
function echochar() {
  echo ${BUFF[${BUFF_PTR}]} | awk '{ printf("%c", $0); }'

  return
}

# 初期化されていない配列の要素を使おうとする前に初期化して拡張する
# これによりバッファーの長さを制限しなくて良くなる
function expansion() {
  if [ ${BUFF_PTR} -gt ${BUFF_LEN} ]
  then
    BUFF_LEN=$((BUFF_LEN+1))
    BUFF[${BUFF_LEN}]=0
  fi

  return
}

# ソースコードをグローバル配列CODEに一文字ずつ格納する
function tokenizer() {
  # トークンを格納する配列の添字を数える
  CODE_LEN=$((${#TEXT_SRC}-1))

  # 文字列から一文字ずつトークンを取り出し配列に追加していく
  local i
  for i in $(seq 0 ${CODE_LEN})
  do
    CODE[${i}]=${TEXT_SRC:${i}:1}
  done

  return
}

# BUFF_PTRがな0ら対応する']'まで直後までジャンプする
function left_jumper() {
  if [ ${BUFF[${BUFF_PTR}]} -eq 0 ]
  then
    local loop_ptr=1
    while [ ${loop_ptr} -ne 0 ]
    do
      CODE_PTR=$((CODE_PTR+1))
      case ${CODE[${CODE_PTR}]} in
      '[')
        loop_ptr=$((loop_ptr+1));;
      ']')
        loop_ptr=$((loop_ptr-1));;
      esac
    done
  fi

  return
}

# BUFF_PTRがな0ら対応する'['の直後までジャンプする
function rite_jumper() {
  if [ ${BUFF[${BUFF_PTR}]} -ne 0 ]
  then
    local loop_ptr=1
    while [ ${loop_ptr} -ne 0 ]
    do
      CODE_PTR=$((CODE_PTR-1))
      case ${CODE[${CODE_PTR}]} in
      ']')
        loop_ptr=$((loop_ptr+1));;
      '[')
        loop_ptr=$((loop_ptr-1));;
      esac
    done
  fi

  return
}

# 意味解析を行い実行する
function execute() {
  while [ ${CODE_PTR} -le ${CODE_LEN} ]
  do
    case ${CODE[${CODE_PTR}]} in
    '>')
      BUFF_PTR=$((BUFF_PTR+1));;
    '<')
      BUFF_PTR=$((BUFF_PTR-1));;
    '+')
      BUFF[${BUFF_PTR}]=$((BUFF[${BUFF_PTR}]+1));;
    '-')
      BUFF[${BUFF_PTR}]=$((BUFF[${BUFF_PTR}]-1));;
    '.')
      echochar;;
    ',')
      readchar;;
    '[')
      left_jumper;;
    ']')
      rite_jumper;;
     * )
      local message="Unknown Token! : ";
      echo $message${CODE[${CODE_PTR}]};
      break;;
    esac

    expansion
    CODE_PTR=$((CODE_PTR+1))
  done

  echo "";

  return
}

initialize   # 初期化
readstring   # 入力受付・プリプロセッサ
tokenizer    # 構文解析
execute      # 意味解析・実行

実行方法
直接標準入力で渡すかもしくは
適当なファイル例えば”script.bf”のようなファイルにソースコードを書き込み下記のように実行することができます。
# cat script.bf | brainfuck.sh

2013/05/07 追記
Bashでは”文字”に対して足し算を行えないようなので
文字入力時に整数型に変換するように”,”の処理を修正しました。

Perl IPアドレスを10進数の整数型に変換し戻す

データベースにIPアドレスを格納する時は整数型にしたほうがブロックで検索出来たりと後々取り扱いが楽だったりするので変換する変換方法を書いてみる

#!/usr/bin/perl
use utf8;
use strict;
use warnings;

my $addr_i = &addr_s_to_i("192.168.1.1");
my $addr_s = &addr_i_to_s($addr_i);
print "INTEGER:" . $addr_i . "\n";
print "STRING :" . $addr_s . "\n";

# IPアドレスを文字列型から整数型に変換
sub addr_s_to_i {
    my $addr = shift;

    # "."ごとに8bitずつ区切りそれを2進数に変換し配列に入れる
    my @addrs;
    foreach my $addr_split (split('\.', $addr)){
        push(@addrs, sprintf("%08b", $addr_split));
    }

    # 区切った2進数を連結する
    my $bin = join('', @addrs);
    # 2進数を10進数に変換
    my $result = oct('0b' . $bin);

    return $result;
}

# IPアドレスを整数型から文字列型に変換
sub addr_i_to_s {
    my $addr = shift;

    # 10進数を32bitの2進数に変換
    my $bin = sprintf("%032b", $addr);

    # 2進数を8bitごとに区切り10進数に変換し配列に入れる
    my @addrs;
    foreach my $addr_split ($bin =~ m/.{8}/g){
        push(@addrs, oct('0b' . $addr_split));
    }

    # "."ごとに区切り連結する
    my $result = join('.', @addrs);

    return $result;
}

実行結果
INTEGER:3232235777
STRING :192.168.1.1

Perlに変数の型は無いが変数の型を意識しないプログラムは書いてはいけない

Perlには変数の型は無いですが最近変数の容量を見なければならない機会があり調べていたところPerlの変数には型は存在しないが型を意識したプログラムを書かなければならない事が分かったためメモしておく。

#!/sur/bin/perl
use utf8;
use strict;
use warnings;

use Devel::Size qw(size total_size);

my $DATA = 1000;
my $INIT = "";

# 直接操作した場合
{
    print "[variable]\n";

    my $data = $DATA;
    my $init = $INIT;

    my $res = $init;
    for(my $i = 0; $i < $data; $i++){
        $res .= "*";
    }

    print "Before initialization :". size($res) . "\n";

    $res = $INIT;

    print "After initialization  :". size($res) . "\n";
}

# 関数の場合
{
    print "[function]\n";

    my $res = &routine($DATA, $INIT);

    print "Before initialization :". size($res) . "\n";

    $res = &routine(0, $INIT);

    print "After initialization  :". size($res) . "\n";

    sub routine {
        my $data = shift;
        my $init = shift;

        my $result = $init;
        if($data){
            for(my $i = 0; $i < $data; $i++){
                $result .= "*";
            }
        }
        return $result;
    }
}

# メソッドの場合
{
    print "[ method ]\n";

    my $mt = MemTester->new();

    my $res = $mt->routine($DATA, $INIT);

    print "Before initialization :". size($res) . "\n";

    $res = $mt->routine(0, $INIT);

    print "After initialization  :". size($res) . "\n";


    package MemTester;

    sub new {
        my ($class, @args) = @_;
        my %args = ref $args[0] eq 'HASH' ? %{$args[0]} : @args;
        my $self = {%args};

        return bless $self , $class;
    }

    sub routine {
        my $self = shift;
        my $data = shift;
        my $init = shift;

        my $result = $init;
        if($data){
            for(my $i = 0; $i < $data; $i++){
                $result .= "*";
            }
        }
        return $result;
    }
}

最初の値を整数(“$INIT = 0”)で初期化した場合の実行結果
[variable]
Before initialization :1056
After initialization :1056
[function]
Before initialization :1056
After initialization :1056
[ method ]
Before initialization :1056
After initialization :1056

最初の値を文字(“$INIT = ””)で初期化した場合の実行結果
[variable]
Before initialization :1048
After initialization :1048
[function]
Before initialization :1048
After initialization :48
[ method ]
Before initialization :1048
After initialization :48

このように、文字列と数値を混同して使用した変数は多くメモリを消費することが分かる。
さらに、返り値としてデータを受け取った場合、その分受け取った変数もメモリを無駄に使用するためさらに効率は低下する。

Webページを取得するなど文字列を大量に格納し返すようなプログラムを書く場合は取得に失敗した場合は0を返すのではなく””を返すべきである。

数字(例:0)より文字列(例:”0″)の方がメモリを多く使用することは当然のことであるが、変に気取って返り値を混同するような関数やメソッドは書いてはならない事が分かった。

Perl cpanでインストールしたIP::Countryのデータベースを更新する 更新スクリプトの作成 CentOS

IP::Countryには”whois_filenames”と呼ばれるDB更新用のスクリプトが同封されているがインストールされないためcpanでインストール後は非常に困る。その上、更新用スクリプトを単純にコピーして実行しても正しく動作しないため、今回アップデート用のスクリプトを改良しインストール後でも使用出来るようにしておく。

なお、更新用スクリプトはメモリを非常に使うためマシン側では物理的に4GB以上のメモリを搭載している必要があるかもしれない。

“dbmScripts”ディレクトリの存在確認
# ls ~/.cpan/build/IP-Country-2.27/dbmScripts/

“IP::Country”のインストール場所の確認
# ls /usr/lib/perl5/site_perl/5.8.8/IP/

“dbmScripts”ディレクトリのコピー
# cp -R ~/.cpan/build/IP-Country-2.27/dbmScripts/ /usr/lib/perl5/site_perl/5.8.8/IP/

“dbmScripts”ディレクトリへ移動
# cd /usr/lib/perl5/site_perl/5.8.8/IP/dbmScripts/

アップデート用スクリプトをbashにて作成
# vi whois_filenames

#!/bin/bash

wget ftp://ftp.ripe.net/ripe/dbase/split/ripe.db.inetnum.gz && gunzip ripe.db.inetnum.gz
wget ftp://ftp.ripe.net/pub/stats/afrinic/delegated-afrinic-extended-latest
wget ftp://ftp.ripe.net/pub/stats/apnic/delegated-apnic-extended-latest
wget ftp://ftp.ripe.net/pub/stats/arin/delegated-arin-extended-latest
wget ftp://ftp.ripe.net/pub/stats/lacnic/delegated-lacnic-extended-latest

perl ipcc_loader.pl && perl ipcc_maker.pl && perl ipauth_loader.pl && perl ipauth_maker.pl

rm -f *extended-latest* ripe.db.inetnum* sorted_*.txt*

読み込むファイル名が異なるため修正

# vi ipauth_loader.pl

69行目付近

read_reg('delegated-afrinic-extended-latest'); # 修正
read_reg('delegated-lacnic-extended-latest');  # 修正
read_reg('delegated-apnic-extended-latest');   # 修正
read_ripe();
read_reg('delegated-arin-extended-latest');    # 修正

join_neighbours();
punch_holes();
optimize();
output();

# vi ipcc_loader.pl

69行目付近

read_reg('delegated-afrinic-extended-latest'); # 修正
read_reg('delegated-lacnic-extended-latest');  # 修正
read_reg('delegated-apnic-extended-latest');   # 修正
read_ripe();
read_reg('delegated-arin-extended-latest');    # 修正

join_neighbours();
punch_holes();
optimize();
output();

DBのパスが違うため”ipauth_maker.pl”と”ipcc_maker.pl”のパスを修正

# vi ipauth_maker.pl

32行目付近

print "Saving ultralite IP registry to disk\n";
my $ip = new IO::File "> ../Authority/ipauth.gif"; # 修正
if (defined $ip) {
    binmode $ip;
    print $ip pack("N",time()); # returned by $obj->db_time()
    $tree->printTree($ip);
    $ip->close();
} else {
    die "couldn't write IP registry:$!\n";
}

44 行目付近

print "Saving ultralite country database to disk\n";

open (CC, "> ../Authority/auth.gif") # 修正
    or die ("couldn't create authority database: $!");
binmode CC;
foreach my $country (sort $tree->get_countries()){
    print CC substr(pack('N',$tree->get_cc_as_num($country)),3,1).$country;
}

# vi ipcc_maker.pl

33行目付近

print "Saving ultralite IP registry to disk\n";
my $ip = new IO::File "> ../Country/Fast/ip.gif"; # 修正
if (defined $ip) {
    binmode $ip;
    print $ip pack("N",time()); # returned by $obj->db_time()
    $tree->printTree($ip);
    $ip->close();
} else {
    die "couldn't write IP registry:$!\n";
}

45行目付近

print "Saving ultralite country database to disk\n";

open (CC, "> ../Country/Fast/cc.gif") # 修正
    or die ("couldn't create country database: $!");
binmode CC;
foreach my $country (sort $tree->get_countries()){
    print CC substr(pack('N',$tree->get_cc_as_num($country)),3,1).$country;
}

作成した”db_update”に実行権を与える
# chmod 755 whois_filenames

アップデート実行
# sh whois_filenames

__追記__
2016/06/16 delegated-arin-latestなどがextended-latest形式に変更となっていたため記事の一部を更新しました

ぴくぴくダウンローダ for Java(仮) Ver 6.10

修正された項目

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

Windows7 での実行の様子
WS000000

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

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

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

ダウンロード

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

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

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

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

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

1万円で放射線量を計測して自動でTwitterに投稿する装置を作ろう!

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

利用するパーツ

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を日本語環境で動かそう!

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でスクリーンショットを撮る

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

$ sudo apt-get install ksnapshot

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

snapshot2

Raspberry PiでC言語を使い2つのスレッドを200ミリ秒と2秒ごとに処理させる

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