linuxでbeep音を鳴らす

加速度センサを監視しているDebianマシンで加速度が大きいときにアラームをならしたいのでどうしたらbeep音がなるか調べてみました。
beep音を鳴らすにはパッケージの導入が必要なようで、

# aptitude install beep

として、パッケージを導入します。さらに、/etc/group の audio グループにユーザが入っている必要があるようですが、自分のところでは初めから入っていました。
この状態でコマンドラインから、

$ beep -f 262 -l 500 -n -f 294 -l 500 -n -f 330 -l 500 -n -f 349 -l 500 -n -f 392 -l 500 -n -f 440 -l 500 -n -f 494 -l 500 -n -f 523 -l 500

と入力すると、「ドレミファソラシド」の音階を聞くことができました。
ただ、プログラムから鳴らす方法を調べなければなりません。
( system() でコマンドを呼ぶと、鳴り終わるまで動作がブロックされそうです・・・)

sshfsを試してみた

いろいろ実験していると、ホスト(サーバ)が乱立してきます。

そうなってくるとそのマシン上のファイル編集をどうしようかというのが段々面倒になってきます。高速なマシンであれば、FreeNXという手もあるのですが、データ収集用のマシンは古いノートPCなので性能的にも厳しいです。

で、ググっていたら、sshfsというものがあることがわかりました。これはホスト側でSSH Serverさえ動いていれば、ホスト側のファイルをローカルシステム側にユーザー権限でマウントできるというもので、非常に簡単・便利です。

以下、クライアント側(手元にある側)の設定方法です。

まず、Synapticパッケージマネージャでsshfsを検索すると、そのものずばりの「sshfs」パッケージがあるので、これをインストールします。

あとは、ホームディレクトリ内にマウントポイント(空のディレクトリ)を作ります。

準備ができたら、

% sshfs [-p ポート番号] [サーバ側のアカウント@]<サーバのホスト名>:[ディレクトリ] <マウントポイント>

でマウントできます。
同じユーザ名の場合、サーバ側のホームディレクトリを ~/mnt にマウントする場合は、

% sshfs [-p ポート番号] <サーバのホスト名>: <マウントポイント>

でOKです。アンマウント時は、

% fusermount -u <マウントポイント>

です。

これで手元のマシンのgeditなどでファイル編集ができるので楽ちんになります。

USB加速度計(KXM52版)

結局、KXP84は突然のノイズ(?)が入って使い物にならなかったので、KXM52-1050で改めてUSB接続のArduinoベースの加速度計を作りました。

今回はLCDがないのでより小さな基板とケースに入れています。ATMEGA328Pと加速度センサの電源はUSBシリアル変換モジュールからの3.3V出力を使っています。

写真に写っている一部の抵抗を除いて抵抗・コンデンサ・LEDはチップ部品を使って実装しています。ケースは100円ショップで売っていたポリプロピレンのカードケースを加工して納めました。

・・・が、このケースを固定する場所がなかったりします。どうしようかな・・。

KXP84+SCP1000

KXP84-2050は一応動くようになったのですが、稀におかしなデータを吐くので困っています。

連続でXYZの各データを読みつづけると、静止状態にも関わらず突然X方向に大きくずれた値を出力します。しかもYZは何事もなかったかの様に動作しつづけますし、その後X方向も元の値に戻ってしまいます。SPIでのデータ転送時のビット抜けかとも思いましたが、YZには影響がなかったり、ビット抜けパターンには合致しなかったりするので、ビット抜けではないようです。パスコンは写真の通り秋月モジュールなので0.1uFと4.7uFのセラミックコンデンサ(目視ではわかりませんけど)がついていますので、そうそう問題ではないはずです。

時々誤動作する加速度センサでは困りますので、KXM52-1050の方に切り替えようかと思っています。

一方、SCP1000の方ですが、こちらは上手くいっています。

5/1の深夜から5/2の午前中にかけての室内の温度変化です。窓を少し開けて寝ましたので、明け方に温度が下がっているのがわかります。

同様に気圧の変化です。約2サンプル/秒のものを強引にgnuplotでグラフ化しましたが、適切にサンプリングするようにすれば面白そうです。

SCP1000とKXP84を同時に動かす

タイトルの通りです。

CSを別々にして両方のデバイスをSPIにぶら下げただけです。

ただ、加速度計の方は周期的にデータを取りたいので一捻りしています。Arduinoで無理やりタイマ割り込みを設定し、割り込み処理ルーチン内でSPIにアクセスにいった上に浮動小数点演算までやるという無茶なことをしています。当然、SCP1000のSPIアクセスや非割り込み処理部分での浮動小数点演算と干渉しますので、SCP1000にアクセスに行くときや浮動小数点演算を行う箇所では割り込みを禁止しています。

以下に主要部分を記載します。

#include <avr/interrupt.h>
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

volatile unsigned long timer1_count = 0;
//////////////////////////////////////////////
// Timer1 Interrupt
SIGNAL(TIMER1_COMPA_vect)  // See voctor list sec.11-4
{
   timer1_count++;
   IntAccProc(); <--割り込み処理で呼びたい関数
}

// Initialize Timer1 as Interval Timer
void InitTimer1(unsigned long int cycle_in_ns){
  double t;
  TCCR1A = 0;
  TCCR1B = 0;
  // set timer 1 prescale factor to 64
  sbi(TCCR1B, CS11);
  sbi(TCCR1B, CS10);
  // Change mode 8bit-pwm to 16bit
  sbi(TCCR1B,WGM12); 
  // Set Cycle (10000000ns / 125ns) 
#if F_CPU >= 16000000L
  t = cycle_in_ns/62.5;
#else
  t = cycle_in_ns/125.0; // 
#endif
  OCR1A = (unsigned int)(t/64.0);
  // Enable Timer0 OCIE1A interrupt
  sbi(TIMSK1,OCIE1A);
}

反則技だと思いますが、やっぱり割り込みは使いたいですからね。
そうそう、干渉しそうな場所は cli()で割り込みを禁止し、必要がなくなったら sei()で割り込みを許可してやる必要があります。

A/D内蔵KXP84-2050を試す

SCP1000のExampleをベースにSPIの動作確認ができたところで、A/D内蔵の加速度センサKXP84-2050を接続してみました。KXP84-2050は3.3V動作ですので、接続するArduinoも3.3Vタイプでなければなりません。3.3Vタイプは液晶モジュールとの共存が難しいので頭が痛いところですが・・・。

それはさておき、Arduinoとの端子接続は以下の通りです。

  • モジュールの1ピン(VDD):ArduinoのVcc(3.3V)
  • モジュールの2ピン(GND):ArduinoのGND
  • モジュールの3ピン(MOT):オープン
  • モジュールの4ピン(FF):オープン
  • モジュールの5ピン(SCL/SCLK):Arduinoの13ピン
  • モジュールの6ピン(IO_VDD):ArduinoのVcc(3.3V)
  • モジュールの7ピン(SDA/SDO):Arduinoの12ピン
  • モジュールの8ピン(RESET):ArduinoのRESET
  • モジュールの9ピン(ADDR0/SDI):Arduinoの11ピン
  • モジュールの10ピン(CS):Arduinoの7ピン

で、SCP1000のExampleをベースにスケッチを作成したところ、あっさり動作しました。

参考になるかわかりませんがアップロードしておきます。→KXP84_2050.zip

気圧センサSCP1000を試す

秋月で売っている気圧センサモジュールのSCP1000モジュールを試してみました。

センサ単体では扱いにくいのですが、モジュールでは8pinDIPにまとめられています。これを3.3V版のArduinoにつないでみました。

Arduino 0022 にはExampleの「SPI」のグループの中に「BarometricPressureSensor」としてSCP1000を制御するサンプルが含まれています。そのソースの始めの方にSCP1000の端子との接続方法が記載されていますので、その通りにつなぎます。ただし、ここに記載されているのはSCP1000のピン番号ですから、モジュールと接続するときは注意が必要です。モジュールの各端子と、Arduinoの接続方法は以下の通りです。

  1. TRIG信号。無接続。
  2. DRDY信号。ArduinoのDigital Pin 6に接続する。
  3. SCK信号。ArduinoのDigital Pin 13に接続する。
  4. GND。
  5. MOSI信号。ArduinoのDigital Pin 11に接続する。
  6. MISO信号。ArduinoのDigital Pin 12に接続する。
  7. CSB信号。ArduinoのDigital Pin 7に接続する。
  8. VCC。ArduinoのVCCに接続する。このセンサは3.3Vまでしか印加できないので、要注意!

これで、サンプル「BarometricPressureSensor」をコンパイル・ダウンロードし、シリアルモニタでモニタすれば表示されるはずですが・・・・このサンプルはバグがあります。

自分が修正した箇所(loop()の中です)を示します。

//combine the two parts into one 19-bit number:
long pressure = (((long)pressure_data_high << 16) | pressure_data_low)/4;
float hPa = (float)pressure/100.0;

// display the temperature:
Serial.print(“\tPressure [hPa]=”);
Serial.println(hPa);

サンプルでは上記の箇所の2行目で(long)のキャストが抜けているために、正しく表示してくれません。ここを修正すれば、パスカル(Pa)単位で値が表示されます。(他に、SPIのレジスタアクセス部分にデバッグ用の表示があるので、それをコメントアウトしないと表示が鬱陶しいです)
さらに自分はヘクトパスカルで表示したかったので、計算後にfloatの変数を定義して値を100で割って、それを表示するように変更しています。

天気の変化に合わせて気圧が変化するのが目に見えるようになるのは面白いです。

gnuplotの使い方

データを効率よく(人手をかけずに)グラフ化する方法について考えています。人手をかけてやるなら、ExcelやOpenOffice.orgのSpreadSheetがいいと思うのですが、バッチファイル処理は難しいでしょう。

ということで、gnuplotについて調べています。

1.インストール

本家本元はgnuplot.infoです。 しかし、Ubuntuの場合にはSynapticパッケージマネージャからインストールできますので、直接お世話になることはなさそうです。

2.GUIフロントエンド・・・はあきらめました

gnuplotはコマンドラインインタフェースなのがとっつきにくい要因の一つになっています。最終的にはバッチ処理したいのでコマンドラインインタフェースは必要なのですが、とっつきにくい・・・ということで、いくつかGUIインタフェースを付加する試みはなされているようです。

その一つがcueplotで、比較的情報がありそうな感じ・・・・だったのですが、sourceforgeの方をみるとバージョンが0.08と進んでいないことと、どうもコンパイル済みバイナリ配布が基本のようなのでやめました。

3.その他の情報源

その他、使っていく上で参考になりそうな情報源を探してみました。

  • 日本語マニュアル
    新潟工科大学竹野研究室の方が日本語訳を公開しています。→こちら
    PDF化された物などもあり、参考になりそうです。(PDFファイルはGoogle Chromeの内蔵PDFビューアでは文字が表示できませんが、 Ubuntuのドキュメントビューアではしっかり見えました)
  • gnuplotの初歩 →こちら
    もちろん全部を網羅しているわけではないが、やりたいこと別に非常にとっつきやすく整理されています。こちらをみれば、まずはGUIフロントエンドがなくてもとっつけるような気がします。

またなにか見つかったら追加するつもりです。

 

脈拍検出をPSoCで再現

一昨日のOPAMP(LMC662A)による回路をそのままPSoCで再現してみました。

使用デバイスはまず制約の少ない条件で楽にインプリメントしたかったので、CY8C29466-24PXIを使っています。センサはGP2S05のままです。

PSoCらしくローパスフィルタ/ハイパスフィルタ部分もPSoC内に入れたかったのですが、周波数が低すぎて単純に実装するのではうまく取りこめないようです。そのため、CRのフィルタはそのままにしてあります。そして、最後のゲインを稼ぐ部分のみ48倍設定としてあります。

増幅した後の信号を端子に出力して、その波形を観測してみました。

動作としては検出はできています。ただ、フォトリフレクタへの指の当て方でだいぶ変わってしまいます。また、インバータ式蛍光灯や外部ノイズに弱いようで、なんらかの対策は必要な感じです。

宅内無線LANのトラブル

自宅内では秋葉原で買ったP社製(Web画面に中国語があるので中国メーカーのOEMでしょう)の格安802.11nの無線LANアクセスポイント(ルータ機能は内蔵されているが使っていない)をサブのネットワークに使っています。ちなみに、家族の写真や年賀状、その他諸々のデータを保管しているNASがつながっているメインのネットワークでは無線接続は設定ミスによるセキュリティリスクを考え、やめてしまいました。

で、このP社のアクセスポイントが突然つながらなくなってしまいました。そもそも電波が出ていないような感じです。以前も同じようなことがあって、電源を入れなおして復旧したのですが、今回は復旧しません。ルータ機能がハングアップして、電源を入れなおせば復旧する、なんて事象はいままで購入したほとんどのルータで経験していますので珍しい話ではないのですが、電源を入れなおしても復旧しないというのはいままでありません。

あれやこれややってもうまく行かず四苦八苦していたのですが、工場出荷時設定にWeb設定画面経由で戻したら、なんとみえるようになりました。(背面のリセットボタン長押しでも復旧しなかったのですが・・・!?)
しかし、以前設定した際に保存しておいた設定ファイルのバックアップを書き戻すと電波が出なくなってしまいます(表示ランプではできているように表示しているのに・・・)。

結局、再度工場出荷時設定に戻して、全部設定しなおしたら動くようになりました。一体なんだったんでしょうね。
こういう現象があるから格安なんでしょうか・・・???
なんにせよ、復旧するのになんだかんだで4時間以上格闘してしまいました。