2014年11月29日土曜日

iModela+eagleでプリント基板作成(2/2)

前回の続き

ガーバーデータの出力は、いろいろなところで紹介されているので、
キーワードだけ。
gerb274x.cam → パターンデータ
excellon.cam   → ドリルデータ

らしい

生成したガーバーデータを「WINSTAR PCB for iModela」にて読み込む。
切削に使うエンドミルが一覧に無いので、「詳細設定」を選ぶ。
このあたりは、トライアンドエラーで行き着いた値なので、正しくは無いかもしれない。。。
でも大丈夫そうだから、まぁいいか。

「了解」を押すと「切削設定」が表示される
パターン:0.3mm
ドリル穴、カット:0.5mm
剥離面:0.5mm
芯ブレ補正値:0.04mm






「V」をクリック「Vカッター計算」というのが開く

このあたりの数値もトライアンドエラー、でも動くからこれでいいやOrz

もろもろ確認して、OKであれば切削を開始する。
 また「Vカッター計算」
切削速度は10mm/s程度までなら大丈夫みたい。



うりゃー
ガーガーうるせーーー
パターンの切り出しに20分くらい
穴あけに15分くらい

 ところどころ削りきれていないものがあるので、
カッターで微修正。
 今日はここまで。
久しぶりにやったので、一日がかりだ。やれやれ。
でも達成感があるね。

iModela+eagleでプリント基板作成(1/2)

ユニバーサル基板では大変だけど、基板を発注するほど大量には作らない時、
自分でプリント基板を作りたい衝動に駆られた。

感光基板をエッチング液でうんたらかんたらは、
綺麗に作れるのだけど、廃液の処理とか感光時間の 調整とか
ドリルで穴あけとか、ちょっと心が折れたので、
もう少し楽ができないかなと思った。
(もう1年以上前の話だけど。。)

その時に衝動買いしたのが、iModelaである。
http://icreate.rolanddg.com/iModela/DGJ/Japanese/index.html/

iModelaは非金属の加工ができる個人向けの切削加工マシーンなのだけど、
エンドミルをつければ、プリント基板を加工できるのだ。
http://www.pcbmilling.biz/

なかなか値が張るのだけど、いろいろできそうと心が踊り、
衝動買いしたのはもうかなり前。

しばらく厳重に保管しすぎてホコリがかぶっていたが、
これではいけないと思い、再び始めたのである。

前に作ったときは、FT232RLのSSOPのピッチまで作れたので、
今回のデザインルールもコレと同じでクリアランス0.35mmとした。

eagleでデザインルールを指定
チェックすると大量のNG項目がでて、作り直し。。。


その後、
太さを変えるのを忘れていた。
電源は16mil、信号線は12milとした。
直角曲がりは気持ち悪いので、変更した。
GNDのベタパターンを作成し、最終的にはこうなった。

まずはここまで。

2014年11月24日月曜日

Canon MG6330をLinuxで使用する(2/2)

前回は、同一セグメントからの利用だったので、
今回は異なるセグメントからの利用に挑戦する。

ルーターとしてdd-wrt化したあいつがいるので、
なんとか工夫したら使えないかぁ・・・。


  1. 調査
一体、このプリンターはどんなプロトコルで通信しているのか。
そして、install.shで勝手にプリンターを探してくれるけど
何をやっているのか?

まぁググったら一撃なんだけれども、それじゃあつまらないので、

先ほどインストールに成功したノートPCで再度install.shを動かしてみて、パケットキャプチャしてみた。

ARP投げまくってる。
プリンターの電源入れ忘れてた。。
電源を入れて再度キャプチャー

おぉとれた!
Canon BJNPというポート8611のやつですな!
このキーワードをもとにググって(やっぱり)みると
tcpudp8611を使用するみたい。
また、スキャナーの場合には、8612を使うとか使わないとか。


  1. ルーターの設定
    仕組みがわかれば、それに対応してルーターの設定を変更する。
# 192.168.4.1:8611に届いたパケットを192.168.2.6:8611に転送
iptables -t nat -A PREROUTING -m tcp -p tcp --dst 192.168.4.1 --dport 8611 -j DNAT --to-destination 192.168.2.6:8611
iptables -t nat -A PREROUTING -m udp -p udp --dst 192.168.4.1 --dport 8611 -j DNAT --to-destination 192.168.2.6:8611

# 192.168.2.6:8611宛のパケットの送信元は192.168.2.5にする
iptables -t nat -A POSTROUTING -m tcp -p tcp --dst 192.168.2.6 --dport 8611 -j SNAT --to-source 192.168.2.5
iptables -t nat -A POSTROUTING -m udp -p udp --dst 192.168.2.6 --dport 8611 -j SNAT --to-source 192.168.2.5

# 戻りのパケットは許可
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

上記設定にて動きました!!
あとは、設定の永続化をしないといけないのだけど、それはまた今度。。
今はプリンターが使えた喜びに浸りたい・・・。

Canon MG6330をLinuxで使用する(1/2)

Canon MG6330Linuxで使用する(1/2)


  1. はじまり
我が家のプリンターはCanon MG6330というやつで、
ネットワークプリント対応しており、
WindowsPCやスマホから印刷していた。

そういえば、Linuxから印刷したことがなかったので、今回チャレンジしてみた。
というのも、たまたまLinux向けのドライバーが公開されているのを知ったからだ。


  1. ネットワーク構成
我が家のネットワーク構成は以下のような感じで、
Wimaxルーターに無線LAN機能のついたものを使用している。
この無線LANにスマホやらWindowsPCやらがぶら下がっている。



そして、ルーター代わりにdd-wrt化したルーターをかませてセグメントを分けている。
同じセグメントのノートPCから先述のドライバーを使うのは何も困ることはなかったが、
違うセグメント(192.168.4.0/24系)からプリンターを利用するのがどうにもハマってしまった。



  1. 同一セグメントのノートPCにて
まずは、同一セグメントのノートPCからプリンターを使う場合
先述のリンクからドライバーをダウンロードする。
  
PIXUS MG6330 IJ Printer Driver Ver. 3.80 for Linux
cnijfilter-mg6300series-3.80-1-rpm.tar.gz

rootになって./install.shを実行してみる。
==================================================

Canon Inkjet Printer Driver
Version 3.80
Copyright CANON INC. 2001-2012
All Rights Reserved.

==================================================
実行コマンド = rpm -Uvh ./packages/cnijfilter-common-3.80-1.i386.rpm
エラー: 依存性の欠如:
cups cnijfilter-common-3.80-1.i386 に必要とされています

怒られた。そうだよね。
cupsのインストールして、再度チャレンジ!

==================================================

Canon Inkjet Printer Driver
Version 3.80
Copyright CANON INC. 2001-2012
All Rights Reserved.

==================================================
実行コマンド = rpm -Uvh ./packages/cnijfilter-common-3.80-1.i386.rpm
準備しています... ################################# [100%]
更新中 / インストール中...
1:cnijfilter-common-3.80-1 ################################# [100%]
実行コマンド = rpm -Uvh ./packages/cnijfilter-mg6300series-3.80-1.i386.rpm
エラー: 依存性の欠如:
libpangox-1.0.so.0 cnijfilter-mg6300series-3.80-1.i386 に必要とされています
libpng12.so.0 cnijfilter-mg6300series-3.80-1.i386 に必要とされています
libtiff.so.3 cnijfilter-mg6300series-3.80-1.i386 に必要とされています
実行コマンド = rpm -e cnijfilter-common
警告: ファイル /usr/lib64/cups/filter/pstocanonij: 削除に失敗しました: そのようなファイルやディレクトリはありません
警告: ファイル /usr/lib64/cups/backend/cnijusb: 削除に失敗しました: そのようなファイルやディレクトリはありません
警告: ファイル /usr/lib64/cups/backend/cnijnet: 削除に失敗しました: そのようなファイルやディレクトリはありません

また怒られた。怒られた内容に従い以下の追加インストール。
libpangox-devel
libpangox1.0_0
libpng12-devel
libpng12_0
libtiff-devel

すると[libtiff.so.3 cnijfilter-mg6300series-3.80-1.i386 に必要とされています]とまたまた怒られてしまった。

ググるとlibtiff.so.3が必要な場合には、libtiff.so.4などからシンボリックリンクを張っちゃうのが常套手段らしいので、やってみたが、まだ怒られる。

ムキー!!
心が折れたので、libtiff.so.3をネットから拾ってきた。。

==================================================

Canon Inkjet Printer Driver
Version 3.80
Copyright CANON INC. 2001-2012
All Rights Reserved.

==================================================
実行コマンド = rpm --test -U ./packages/cnijfilter-common-3.80-1.i386.rpm
パッケージ cnijfilter-common-3.80-1.i386 は既にインストールされています。
実行コマンド = rpm --test -U ./packages/cnijfilter-mg6300series-3.80-1.i386.rpm
パッケージ cnijfilter-mg6300series-3.80-1.i386 は既にインストールされています。

#=========================================================#
# プリンターの登録
#=========================================================#
続いて、プリンターの登録を行います。
プリンターを接続して、電源を入れてください。
ネットワーク接続で使用する場合は、プリンターをネットワークに接続してください。
準備が整ったら、Enterキーを押してください。
>

きたー!!
このまま指示に従っていくと無事にプリンターが使えるようになりました!

次は異なるセグメントから使えるようにするぞ!

2014年11月22日土曜日

Mageia4(64bit)+MPLABXでハマる・・・。

久しぶりにeagleで回路図を作成した。
片面+ジャンパー構成を考えていたので、
狙ったサイズに入らなくて苦戦すること4時間。
熱中してしまったので、後に引けなくなったのか・・・。



そして久しぶりにPICマイコンを使った。
今まではWindows環境でMPLABを使用していたが、
Windows環境は仮想化したので、今回はLinux環境にMPLABXをインストールした。
環境:Mageia 4 x86_64

MicrochipのサイトからIDEとXC8をダウンロード

MPLAB® X IDE v2.26
http://www.microchip.com/pagehandler/en-us/family/mplabx/

MPLAB® XC8 Compiler v1.33B
http://www.microchip.com/pagehandler/en-us/devtools/mplabxc/home.html

と、インストールなどは上記リンク先に丁寧に書いてあるのだけど、
困ったことに、遅い。
起動からプロジェクトが開くまでも1分くらいかかるし、
プロジェクトのビルドにも1〜2分かかる。

正直ちょっと待てない。

試しに、Windows7にインストールしてみると超速!
ならばと、32bit版のMageiaで試したら、そっちも超速だった・・・Orz
64bitの所為なのかーーー。

この問題も2.25で対策されていたので関係無かった。
http://microchip.wikidot.com/install:mplabx-lin64

javaのバージョンが古いかと思い、アップデート。
変わんねー。

まてよ・・・。こいつJavaアンインストールしても動いてる!!
ググると、独自で持ってるらしい。
/opt/microchip/mplabx/mplab_ide/etc/mplab_ide.conf

jdkhome="/opt/microchip/mplabx/sys/java/jre1.7.0_67/"

jdkhome="/usr/java/jre1.8.0_25/"
に書き換えてみた。
起動しない。。

ちなみにアンインストールの方法は
http://denethor.wlu.ca/cp316/software/Readme_for_MPLABX_IDE.htm#_Toc324949034
/opt/microchip/mplabx/Uninstall\ MPLAB\ X\ IDE にあるらしい。

うーん。 困った。。。

2014年11月15日土曜日

Buffalo WZR-600DHP2のdd-wrt化 その3

WZR-600DHP2を触る機会があったので、dd-wrtを導入してみた(のつづき)

定番プログラムを実行させてみた。

1.準備

ncursesの入手
生成
CC=arm-none-linux-gnueabi-gcc ./configure --prefix=/home/[自分の作業場所]/usr --host=arm-none-linux-gnueabi --with-shared

そしてmake, make install
usr内のbinと libをコピー

そして、定番プログラム・・・slの入手!
http://www.tkl.iis.u-tokyo.ac.jp/~toyoda/
https://github.com/mtoyoda/sl
すごいよねこれ。

CC=arm-none-linux-gnueabi-gcc
CFLAGS=-O -I/home/[自分の作業場所]/usr/include/ncurses -I/home/[自分の作業場所]/usr/include -L/home/[自分の作業場所]/usr/lib

これでmakeするとslが生成される。
slもbinにコピー

2.いざ実行!


sshからログインすると、環境変数が読み込まれない?ようなので、
手動で・・・(なんか良い方法ないかな)
export TERMINFO=/lib/terminfo

するとこんな感じに実行できる!




Buffalo WZR-600DHP2のdd-wrt化 その2

WZR-600DHP2を触る機会があったので、dd-wrtを導入してみた(のつづき)

前回はdd-wrtのインストールまでを行った。
今回は、簡単なプログラムを実行させてみた。

クロスコンパイルをやってみる。

1.準備

ツールチェーンを入手
http://www.mentor.com/embedded-software/sourcery-tools/sourcery-codebench/editions/lite-edition/

ツールチェーンはいろいろ種類があるみたいだけど、
 有名どころを使った。まずは動くことが大事。

2.スタティックリンクで生成してみる

いきなり難しいことはできないので、
スタティックリンクでやってみる
hello.c

#include <stdio.h>
int main(void)
{
 printf("Hello Wold\n");
 return 0;
}

いざコンパイル!!
arm-none-linux-gnueabi-gcc hello.c -static -o hello.exe

出来上がったhello.exeを600DHP2に転送して試してみる。

できた!

3.ダイナミックリンクで生成してみる

スタティックだけではつまらないので、ダイナミックリンクでもやってみる。
 
そのためには、ライブラリを保存できる環境が欲しい。
前回、SDカードが/jffsに自動マウントされるようにしたので、その領域を使う。

共有ライブラリの 保存先libを自由に変更できるようにするために、
SDカードに一式を保存して、それをメイン(/lib)として利用するようにする。

まずは、
/jffs内にclone/libを作成して、現在のlibの中身を全部コピー!!
ついでにclone/bin も作成して、全部コピー!!

そして、ツールチェーンの共有ライブラリもコピーする
CodeSourcery/Sourcery_CodeBench_Lite_for_ARM_GNU_Linux/arm-none-linux-gnueabi/libc/armv4t/lib
これで、下ごしらえはできた。

dd-wrtの「管理」から 「コマンド実行」を選択し、
起動スクリプトを作成する。
内容としては、
#!/bin/sh
sleep 20
if [ -f /jffs/optware.enable ]; then
mount -o bind /jffs/clone/lib /lib
mount -o bind /jffs/clone/bin /bin
else
exit
fi

があれば大丈夫。
20秒待つのはおまじない。。
 マウントしたSDカードが意図しているものかの簡易的なチェックのために、
/jffs/にoptware.enableをという空のファイルを作っておく。
このファイルがある場合にSDカードのlibとbinを使用するしくみ。

 一度再起動して、下準備完了。

 早速、ダイナミックリンクで生成してみる。

arm-none-linux-gnueabi-gcc hello.c -o hello_d.exe

どや!

次は定番プログラムの実行に挑戦

Buffalo WZR-600DHP2のdd-wrt化 その1

WZR-600DHP2を触る機会があったので、dd-wrtを導入してみた。


どうやらdd-wrt化は実績があるみたいだ。 
USBポートにext3フォーマットのSDをつなげて、そこに各種アプリをインストールしてみる。

※以下自己責任+無線出力はOFFにすること。

1.dd-wrtの入手



動作確認したのは以下のバージョン
Path: Downloads › betas › 2014 › 11-11-2014-r25309 › buffalo_wzr-600dhp2 
公式版ではなくbetaなのか。。

2.インストール


<デバッグ画面からファームアップを行う>
詳細は以下のリンク先が詳しい

インストール後、192.168.1.1にアクセス
ここまではとても簡単にできる!



3.SDを外部ストレージ化


SDカードはext3にてフォーマットした。
600dhp2に刺してみると、自動でマウントされる。
されない場合は「ネットワーク」→「USB」にある
「自動ドライブマウント」を確認する。
表示を「日本語」にしていると、レイアウトが崩れるみたいたので、
「英語」と切り替えながら確認すると良さそう。
自動マウントされたSDカードが/dev/sda1として認識された。
このUUIDを「自動ドライブマウント」の下にある
Mount this Partition to /jffsにコピペする。
これでこのSDカードが常に/jffsにマウントされるようになる。


まずはここまで

2014年11月10日月曜日

ラズベリーパイがICカードの残高をしゃべるよ

ICカードの残高を喋ってくれたら面白いと思ったので、早速やってみた。

ICカードのリーダーにはパソリPaSoRi(RC-S320)を使用した。

1.下準備
 a)libusb-devの インストール
apt-get install libusb-dev

 b)libpafeの インストール
wget http://homepage3.nifty.com/slokar/pasori/libpafe-0.0.8.tar.gz
tar xzvf libpafe-0.0.8.tar.gz
cd libpafe-0.0.8/
./configure
make
make install

 c)環境設定
 このままではrootでしか使えないので
/lib/udev/rules.d/60-libpafe.rulesを作成する

ACTION!="add", GOTO="pasori_rules_end"
SUBSYSTEM=="usb_device", GOTO="pasori_rules_start"
SUBSYSTEM!="usb", GOTO="pasori_rules_end"
LABEL="pasori_rules_start"

ATTRS{idVendor}=="054c", ATTRS{idProduct}=="006c", MODE="0664", GROUP="plugdev"
ATTRS{idVendor}=="054c", ATTRS{idProduct}=="01bb", MODE="0664", GROUP="plugdev"
ATTRS{idVendor}=="054c", ATTRS{idProduct}=="02e1", MODE="0664", GROUP="plugdev"

LABEL="pasori_rules_end"


そして、
udevadm control --reload-rules
これで、下準備はおしまい。

2.自作プログラムの実行
 動作確認として/libpafe-0.0.8/tests/内にsuica_zandaka.cを作成。

#include 
#include 
#include "libpafe.h"

int main(void){
 /*スイカの残高を表示する*/
 pasori* p;
 felica* f;
 int i;
 int m;
 int wk, wk2;
 uint8 b[16];
 uint8 idm[16];
 
 felica_block_info fbi;
 fbi.service = 0x090f;
 fbi.mode = 0;
 fbi.block = 0;
 
 printf("ICカードの残高は、");
 p = pasori_open();
 if(!p){
  fprintf(stderr,"error\n");
  exit(-1);
 }
 pasori_init(p);
 f = felica_polling(p,FELICA_POLLING_ANY,0,0);
 //printf("read test\n");

 felica_get_idm(f, idm);
  
        // IDm文字列を作成stdlib
 //printf("IDm = %02x%02x%02x%02x%02x%02x%02x%02x\n", idm[0], idm[1], idm[2], idm[3], idm[4], idm[5], idm[6], idm[7]);

 for(i=0;i!=32;i++){
  if(!felica_read(f,&i,&fbi,b)){
   /*printf("[%02d] : ",i);
                 printf("%02X ",b[0]);
   printf("%02X ",b[1]);
                 printf("%02X",b[2]);
                 printf("%02X",b[3]);
                 printf("%02X",b[4]);
                 printf("%02X ",b[5]);
                 printf("%02X-%02X -> ",b[6],b[7]);
                 printf("%02X-%02X      ",b[8],b[9]);
                 printf("%02X%02X - % 5d Yen        ",b[10],b[11],b[11]*256+b[10]);
                 printf("%02X%02X%02X%02X\n",b[12],b[13],b[14],b[15]);*/
   //printf("[%02d] : ",i);
   //printf("%d ",b[0]);
   if(((int)b[1] > 0) || ((int)b[2] > 0)){
     /*printf("%02X ",b[0]);
     printf("%02X ",b[1]);
     printf("%02X",b[2]);
     printf("%02X ",b[3]);
     wk=b[4]>>1;
     wk=wk&0x7F;
     printf("%02d/",wk);
     wk=b[4]&0x01;
     wk=wk<<3 data-blogger-escaped-wk2="b[5]">>5;
     wk2=wk2&0x07;
     wk=wk+wk2;
     printf("%02d/",wk);
     wk=b[5]&0x1F;
     printf("%02d ",wk);
     printf("%02X-%02X -> ",b[6],b[7]);
     printf("%02X-%02X      ",b[8],b[9]);*/
     printf("%6d円です。\n",b[11]*256+b[10]);
     pasori_close(p);
     return 0;
     //printf("%02X%02X%02X%02X\n",b[12],b[13],b[14],b[15]);
   }
  }
 }
 printf("読み取れませんでした。\n");
 pasori_close(p);
 return 0;
}



実行ファイルの作成はこんな感じ
gcc -DHAVE_CONFIG_H -I. -I..    -I../src -I../ -g -O2 -MT suica_zandaka-suica_zandaka.o -MD -MP -MF .deps/suica_zandaka-suica_zandaka.Tpo -c -o suica_zandaka-suica_zandaka.o `test -f 'suica_zandaka.c' || echo './'`suica_zandaka.c
mv -f .deps/suica_zandaka-suica_zandaka.Tpo .deps/suica_zandaka-suica_zandaka.Po
/bin/bash ../libtool --tag=CC   --mode=link gcc -I../src -I../ -g -O2   -o suica_zandaka suica_zandaka-suica_zandaka.o ../src/libpafe.la


プログラムの出力をAquesTalkPiにしゃべってもらう

./suica_zandaka | ../../aquestalkpi/AquesTalkPi  -v f1 -f - | aplay

こんな感じ


参考

2014年11月3日月曜日

ラズベリーパイが天気を教えてくれるよ

天気予報を喋ってくれたら面白いと思ったので、早速やってみた。

ヤフーの天気予報をローカルに保存して、
内容を解析し予報部分を音声合成してもらうというもの。

 tenki.shはこんな感じ

#!/bin/bash
wget -q -O - http://weather.yahoo.co.jp/weather/jp/13/4410.html > tenki.html
php tenki.php
tenki.phpはこんな感じ
<?php

$fp = fopen("tenki.html", "r");

$timezone_array = array();
$tenki_array    = array();
$kion_array     = array();
$situdo_array   = array();
$today_string   = "";
$find_mode=0;   //0:今日の天気 1:日付 2-3:時間 4:天気 5:気温 6:湿度

if ($fp){
    if (flock($fp, LOCK_SH)){
        while (!feof($fp)) {
            $buffer = fgets($fp);

                        if($find_mode == 0){
                                if(stristr($buffer,'<div id="yjw_pinpoint_today">')){
                                        $find_mode = 1;
                                    //print("■発見".$buffer);
                                        //echo "\n";
                                }
                        }else if($find_mode == 1){
                                if(stristr($buffer,'<span class="yjSt">')){
                                        $find_mode = 2;
                                    // <span class="yjSt"> - 6月30日(月)</span></h3>
                                        $b1 = str_replace('<span class="yjSt"> -', "", $buffer);
                                        $b2 = str_replace('</span></h3>', "", $b1);
         
                                        $b3 = str_replace('(', " ", $b2);
                                        $b4 = str_replace(')', "曜日", $b3);
                                        $today_string= trim($b4);
                                        //print("■日付".$today_string);
                                        //echo "\n";
                                }
                        }else if($find_mode == 2){
                                //<small>時間</small>を探す
                                if(ereg('<small>時間</small>', $buffer)){
                                        $find_mode = 3;
                                }
                        }else if($find_mode == 3){
                                if(ereg('<small><font color="#999999">.*時</font></small></td>', $buffer)){
                                        //print("■過去".$buffer);
                                        //echo "\n";
                                }else if(ereg("^<small>.*時</small></td>", $buffer)){
                                        $b1 = str_replace('<small>', "", $buffer);
                                        $b2 = str_replace('</small></td>', "", $b1);
                                        //print("■時間 ".trim($b2));
                                        //echo "\n";
                                        $timezone_array[] = trim($b2);
                                }
                                if(ereg('<small>天気</small>', $buffer)){
                                        //時間帯の探索は終わり
                                        $find_mode = 4;
                                }

                        }else if($find_mode == 4){
                                //<small><font color="#999999">曇り</font></small></td>
                                //<small>曇り</small></td>
                                if(ereg('<small><font color="#999999">.*</font></small></td>', $buffer)){
                                        //print("■過去".$buffer);
                                        //echo "\n";
                                }else if(ereg("^<small>.*</small></td>", $buffer)){
                                        $b1 = str_replace('<small>', "", $buffer);
                                        $b2 = str_replace('</small></td>', "", $b1);
                                        //print("■天気 ".trim($b2));
                                        //echo "\n";
                                        $tenki_array[] = trim($b2);

                                }
                                if(ereg('<small>気温(℃)</small>', $buffer)){
                                        //天気帯の探索は終わり
                                        $find_mode = 5;
                                }

                        }else if($find_mode == 5){
                                //<td><small><font color="#999999">98</font></small></td>
                                //<td><small>64</small></td>
                                if(ereg('<small><font color="#999999">.*</font></small></td>', $buffer)){
                                        //print("■過去".$buffer);
                                        //echo "\n";
                                }else if(ereg("^<td><small>.*</small></td>", $buffer)){
                                        $b1 = str_replace('<td><small>', "", $buffer);
                                        $b2 = str_replace('</small></td>', "", $b1);
                                        //print("■気温 ".trim($b2)."(℃)");
                                        //echo "\n";
                                        $kion_array[] = trim($b2);
                                }
                                if(ereg('<small>湿度(%)</small>', $buffer)){
                                        //天気帯の探索は終わり
                                        $find_mode = 6;
                                }

                        }else if($find_mode == 6){
                                if(ereg('<small><font color="#999999">.*</font></small></td>', $buffer)){
                                        //print("■過去".$buffer);
                                        //echo "\n";
                                }else if(ereg("^<td><small>.*</small></td>", $buffer)){
                                        $b1 = str_replace('<td><small>', "", $buffer);
                                        $b2 = str_replace('</small></td>', "", $b1);
                                        //print("■湿度 ".trim($b2)."(%)");
                                        //echo "\n";
                                        $situdo_array[] = trim($b2);
                                }
                                if(ereg('<small>降水量(mm/h)</small>', $buffer)){
                                        //天気帯の探索は終わり
                                        $find_mode = 7;
                                }

                        }

        }
                $result_array = array($timezone_array, $tenki_array,$kion_array,$situdo_array);
        //print_r($result_array);

                print($today_string."の天気をお伝えします。");
                //echo "\n";
                for($i=0;$i<count($result_array[0]);$i++){
                        print($result_array[0][$i]."は".$result_array[1][$i]."。 ".$result_array[2][$i]."度 ".$result_array[3][$i]."%です。");
                        //echo "\n";
                }

        flock($fp, LOCK_UN);
    }else{
        print('ファイルロックに失敗しました');
                echo "";
    }
}

$flag = fclose($fp);

if ($flag){
    print('おしまい。');
        echo "\n";
}else{
    print('クローズに失敗しました');
        echo "\n";
}

?>

実行はこんな感じで
./tenki.sh | ./AquesTalkPi  -v f1 -f - | aplay

すると天気予報をしてくれる!

ラズベリーパイが喋るよ

これがメインではなく、準備として
適当な文字列をラズベリーパイに喋ってもらうというもの。

AquesTalk Pi ↓を使わせてもらいました。
http://www.a-quest.com/products/aquestalkpi.html

インストール方法は上記が詳しいので省略。
動かし方としては、以下のような感じ。

echo "ラズベリーパイがしゃべるよ!" | aquestalkpi/AquesTalkPi  -v f1 -f - | aplay

こんな感じ。

どんなものかと…

いつまでもぼんやりしていられないので、
やってみた事を記録しておく。
1つ1つは些細だけど、いつか役に立つ時がくると信じて。