ブログ

κυσο βλογ

Learning the Art of Electronics A Hands-On Lab Course がとうとう出るらしい

The art of electronics という本

artofelectronics.net

数学を衒学的に使って読者を威圧するような電子工学の本は腐るほどありますが、この本は主に(数学的には高度に洗練されている)物理の学生向けに、そういう虚仮威しの数学を極力排除して電子工学の本当に役立つ技だけを伝えようという方針で編まれたものです。第二版が1990年ごろ出て高い評価を得ていましたが、その第三版がようやく去年出版されて、これも高い評価を得ています。

A Hands-On Lab Course

The Art of Electronics 第二版では、The Art of Electronics Student Manualという副読本が出版されており、ハーバード大学の電子工学の実践講義のテキストとして広く利用されてきました。

www.amazon.co.jp

それの、第三版に対応するものとして、Learning the Art of Electronics: A Hands-On Lab Course という本がもうすぐ出ます。

Learning the Art of Electronics | by Thomas C. Hayes with Paul Horowitz

1200ページというボリュームで、Student Manualの約二倍です。The Art of Electronics 第三版を買った人は買って損はない内容だと思います。

Bookdepositoryがやっぱり安い

www.bookdepository.com

予約段階の現在ではやはりここが安いです。現時点でAmazonで7043円、Bookdepositoryで5740円です。本の輸送段階で若干の物理的ダメージはあるかもしれないけど、安くて確実に早く届くので私は今回もBookdepositoryで予約しました。円安で洋書が軒並み高額になっているので、こういう店は有り難いです。

 

正月によく落ちるXively

また落ちてますね。

f:id:XX-Prime:20160106212338p:plain

M2Xは健在

お隣の某民主主義人民共和国が水爆実験をやったとやらで大気中の放射性物質が気になる所ですが、私はXivelyとM2Xの両方に放射線センサの(同一)データを上げているのでM2Xでは確認することができました。

f:id:XX-Prime:20160106212923p:plain

UTCなので+9時間して見る必要がありますが、一日分見ても特に異常な変動は無いので安心して良いと思います。政治的には大変ですが。

Xivelyにだけデータを上げている方は複数クラウドの同時利用をお勧めします。

参考のために、raspberry piからXivelyとM2Xの両方に放射線データを上げるrubyスクリプトを以下に記します。
xively-m2x.rb

#!/usr/bin/ruby

require 'xively-rb'
require "time"
require "m2x"

APIKEY = "YOUR_XIVELY_API_KEY"
FEEDID = "YOUR_XIVELY_FEEDID"

M2X_API_KEY="YOUR_M2X_API_KEY"
M2X_DEVICE="YOUR_M2X_DEVICE"

FIFO_PATH = '/var/lib/rasdiation/rasdiation.fifo'

def put_data(client, feedid, channel, value)
  datapoint = Xively::Datapoint.new(:at => Time.now, :value => "#{value}")
  client.post("/v2/feeds/#{feedid}/datastreams/#{channel}/datapoints", :body => {:datapoints => [datapoint]}.to_json)
end

radiation = nil
radiation_error = nil
radiation_cpm = nil

# Read from rasdiation fifo
# UnixTime,1420256802,CPM,2.350000,uSv/h,0.044313,uSv/h_Error,0.006464 etc.
File.open FIFO_PATH do |file|
  l = file.read
  arr = l.split(",")
  radiation_cpm = arr[3].to_f
  radiation = arr[5].to_f
  radiation_error = arr[7].to_f
end

# try uploading to Xively
begin
  c = Xively::Client.new(APIKEY)
  p c
  unless radiation.nil? && radiation_error.nil?
    res1 = put_data(c, FEEDID, "z_radiation_cpm", radiation_cpm)
    res2 = put_data(c, FEEDID, "z_radiation", radiation)
    res3 = put_data(c, FEEDID, "z_radiation_error", radiation_error)
    # for debug
    #p res1
    #p res2
    #p res3
  end
rescue => ex
  p "Xively Error"
  p ex
end

# try uploading to m2x
begin
  m2x = M2X::Client.new(M2X_API_KEY)

  device = m2x.device(M2X_DEVICE)
  device.create_stream("radiation_uSv_per_hour")
  #device.create_stream("radiation_CPM")
  device.create_stream("radiation_Error_uSv_per_hour")

  now = Time.now.iso8601

  values = {
    radiation_uSv_per_hour: [ { value: radiation, timestamp: now } ],
    #radiation_CPM: [ { value: radiation_cpm, timestamp: now } ],
    radiation_Error_uSv_per_hour: [ { value: radiation_error, timestamp: now } ]
  }

  res = device.post_updates(values: values)
rescue => ex
  p "M2X Error"
  p ex
end

放射線センサの接続と使用は以下を参考にしてください。
xx-prime.hatenablog.com

まとめ

政治がらみの事をちょっと書こうなどと画策して恥ずかしくなって諦めた結果がこのありさまだよ。

UDOO Neo

UDOO Neoとは

Raspberry PiとArduinoの機能を併せ持ち、更に無線および有線LAN、Bluetooth4.0、加速度センサを搭載した名刺カードサイズのボードコンピュータです。

www.udoo.org

今年の4月ごろにKickstarterで投資したのがちゃんとモノになって送られてきました。素晴らしい。

 

外観

RpiとArduinoのハイブリッドそのものです。

f:id:XX-Prime:20151109193255j:plain

 

パッケージ

パッケージの紙箱の内部が解説図になっているという素敵仕様。

f:id:XX-Prime:20151109193843j:plain

図を見て分かる通り、右上のチップがBluetoothWi-Fiを同時に司るものです。で、実際のチップの表面を良く見ると・・・。

 

Blutooth/Wi-Fi チップ

f:id:XX-Prime:20151109193602j:plain

反射して見難いのですが、左の真ん中当たりにTELECの認証マークがあります。表面の型番を読み取ると、WL18 MODGBと書いてあります。下の方にはテキサスインスツルメンツのロゴもあります。写真で白飛びしてるあたり。

 

一応確認

www.tele.soumu.go.jp

上のページで型番WL18を検索してみると

f:id:XX-Prime:20151109200330p:plain

ありました。チップレベルで設計認証が取れているということは、チップを分解したりアンテナをつけたりしない限り日本国内で使用しても問題無いのではないかと思います。

 

まとめ

UDOO Neoを日本国内で使用しても、総務省に雇われた殺し屋に狙われる可能性は低そうです。

(ただし使用は自己責任でね。)

TIの新版Sensor Tagが技術基準適合証明を取得

技適取得機器の調べ方

www.tele.soumu.go.jp

上記ページで調べたいモノの情報の一部を入力すれば検索可能です。「氏名または名称」フォームに「テキサス」と入力して、下の方の送信ボタンを押すと以下のように新版のセンサタグ(CC2650STK)が登録されていることを確認できます。

f:id:XX-Prime:20150801155258p:plain

今年の4月16日にすでに取得されていたようですが、この検索ページに出てきたのは最近だと思います。

これで新版センサタグを日本国内で使用しても暗殺される危険性がなくなりました。

空中線電力の規定

新版センサタグはBLEとZigbeeの両方の通信方式に対応しています。それに応じて、空中線電力の規定も2つあって、

  • F1D 2402~2480MHz(2MHz間隔40波) 0.0012W
  • G1D 2405~2480MHz(5MHz間隔16波) 0.0007W/MHz

となっています。上がBLE、下がZigbee用の規定です。

新版センサタグは、Devpackという安価で小さな基板を使って簡単に自作プログラムをアップロードできますが、出力電波強度を変更する際に上の規定を守るにはどの定数を選べばよいか調べてみます。

出力電波強度の設定

センサタグはファームウェアソースコードIDE(クラウドコンパイラもある)が手に入るのでサルでも簡単に開発ができます。センサタグアプリのApplicationディレクトリにあるSensortag.cで出力電波強度の設定ができます。デフォルトでは以下のようにGAP_ADTYPE_POWER_LEVELで0dBmが指定されています。

// GAP - SCAN RSP data (max size = 31 bytes)
static uint8_t scanRspData[] =
{
// complete name
0x11, // length of this data
GAP_ADTYPE_LOCAL_NAME_COMPLETE,
'C', 'C', '2', '6', '5', '0', ' ', 'S', 'e', 'n', 's', 'o', 'r', 'T', 'a', 'g',

// connection interval range
0x05, // length of this data
GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE,
LO_UINT16( DEFAULT_DESIRED_MIN_CONN_INTERVAL ),
HI_UINT16( DEFAULT_DESIRED_MIN_CONN_INTERVAL ),
LO_UINT16( DEFAULT_DESIRED_MAX_CONN_INTERVAL ),
HI_UINT16( DEFAULT_DESIRED_MAX_CONN_INTERVAL ),

// Tx power level
0x02, // length of this data
GAP_ADTYPE_POWER_LEVEL,
0 // 0dBm
};

実はこれは実際の強度設定ではなく、BLEスキャンコマンドへの応答データの文字列を設定しているだけです。 

実際の強度設定は、

HCI_EXT_SetTxPowerCmd(HCI_EXT_TX_POWER_MINUS_21_DBM);

というように強度設定関数をSensortag.cのSensorTag_init(void)の中で書けばOKです。

参考:

c - How to modify the TI SensorTag Firmware to advertise indefinitely? - Stack Overflow

上のリンクの情報は旧版センサタグのもので、設定可能な値が異なりますが問題なく機能します。

新版で指定可能な値は、Includeディレクトリにあるhci.hで確認できます。

#if defined( CC26XX ) || defined( CC13XX )
#define HCI_EXT_TX_POWER_MINUS_21_DBM LL_EXT_TX_POWER_MINUS_21_DBM
#define HCI_EXT_TX_POWER_MINUS_18_DBM LL_EXT_TX_POWER_MINUS_18_DBM
#define HCI_EXT_TX_POWER_MINUS_15_DBM LL_EXT_TX_POWER_MINUS_15_DBM
#define HCI_EXT_TX_POWER_MINUS_12_DBM LL_EXT_TX_POWER_MINUS_12_DBM
#define HCI_EXT_TX_POWER_MINUS_9_DBM LL_EXT_TX_POWER_MINUS_9_DBM
#define HCI_EXT_TX_POWER_MINUS_6_DBM LL_EXT_TX_POWER_MINUS_6_DBM
#define HCI_EXT_TX_POWER_MINUS_3_DBM LL_EXT_TX_POWER_MINUS_3_DBM
#define HCI_EXT_TX_POWER_0_DBM LL_EXT_TX_POWER_0_DBM
#define HCI_EXT_TX_POWER_1_DBM LL_EXT_TX_POWER_1_DBM
#define HCI_EXT_TX_POWER_2_DBM LL_EXT_TX_POWER_2_DBM
#define HCI_EXT_TX_POWER_3_DBM LL_EXT_TX_POWER_3_DBM
#define HCI_EXT_TX_POWER_4_DBM LL_EXT_TX_POWER_4_DBM
#define HCI_EXT_TX_POWER_5_DBM LL_EXT_TX_POWER_5_DBM
#else // CC254x
#define HCI_EXT_TX_POWER_MINUS_23_DBM LL_EXT_TX_POWER_MINUS_23_DBM
#define HCI_EXT_TX_POWER_MINUS_6_DBM LL_EXT_TX_POWER_MINUS_6_DBM
#define HCI_EXT_TX_POWER_0_DBM LL_EXT_TX_POWER_0_DBM
#define HCI_EXT_TX_POWER_4_DBM LL_EXT_TX_POWER_4_DBM
#endif // CC26XX/CC13XX

新版では最強の+5dBmから最弱の-21dBmまで設定可能なようです。

上で見たとおり、TIが取得した技適では0.0012Wが上限なので、0.8dBmが上限ということになります。よって、日本国内で問題なく設定可能なのはHCI_EXT_TX_POWER_0_DBMが上限です。それより大きい値を設定すると逮捕・監禁・打首・獄門の憂き目にあうので注意しましょう。

まとめ

技適取得から検索ページに出てくるまでのタイムラグ(約3ヶ月?)をなんとかしてほしい。

mbed HRM1017の電池駆動

HRM1017とは

mbedでBLEペリフェラルデバイスの開発が簡単に行えるボードで、技適マークが付いているので使っていることを公表しても逮捕・監禁・拷問されることはありません。

www.switch-science.com

ただし、電波強度の設定によっては違法な強度の電波が出ることもある(かもしれない)ので、プログラムで電波強度パラメータを調整する際には注意が必要です。

電源電圧の取得方法

Measuring battery voltage with Nordic nRF51x devices | mbed

上記のリンク先の方法で電源電圧を取得できます。USB給電の場合は、レギュレート済みの3.2V程度の値が取得できます。

単三電池二本での駆動結果

取得した電圧の値をセントラル側に返すサービスを実装して、セントラル側から一分に一回電圧値を取得してXivelyに送信して電池電圧の降下状況を記録してみました。

使用した単3アルカリ乾電池はオーム電機のV-アルカリ乾電池です。これを選んだ理由は単純に安くてどこでも売ってるからです。

省電力のためのコード上の工夫を全くしていない状態で、駆動時間は9日と12時間でした。

f:id:XX-Prime:20150615101842p:plain

終端電圧は1680mVで、1789mVを下回ったあたりから通信の失敗が発生し始めるので、安全に使用可能な範囲は1800mV程度まででしょうか。それを考慮すると、寿命は9日と2時間程度です。

感想

ちょっとこのままの状態だと電池駆動は実用的でないと思います。一日に一回充電が必要なマヌケな腕時計にくらべればだいぶマシではありますが。

コードの工夫でどこまで消費電力を絞れるかが興味ある点です。しかし、ざっと調べてみた限り、寿命が1年に伸びるといったような劇的な改善はあまり期待できそうにありません。

まとめ

現時点ではちょっとがっかり。酒飲んでふて寝でもするか。

mbedにPocketGeiger Type5を接続する

mbed触りだしてみました

使いやすいですmbed。オンラインIDEで使いたいボードなりチップを選ぶとピン配置図が出て配線が簡単に確実にできます。とても賢い人達が作っているのがわかります。某マイコンボード陣営が内部分裂でグダグダやってる内に嫌気が差してmbedに移るユーザもいるのではないでしょうか。

触ってるのはこれ

www.switch-science.com

BTつきのモノとかいくつか買ってみたのですが、いま私が主に触ってるのはLPC1114FN28です。プログラムをアップロードした後は石だけ取り出して電源を与えるだけでも動き出すという素敵な構成で、石単体なら200円ちょっとで手に入ります。すごい。

PocketGeiger Type5をつないでみる

mbedに慣れる目的で、PocketGeiger Type5をLPC1114FN28につないで放射線センサデータを取れるかどうか試してみました。といっても、arduino用のコードがすでにRadiation-Watch.orgから入手できるので、移植は私程度のクズでも簡単にできるはずです。

f:id:XX-Prime:20150503174907p:plain

オンラインIDEでLPC1114FN28を選んでPinoutを見てみると、dp25とdp26が空いているのでこれらをデジタル入力として使うことに決めました。PocketGeiger Type5からは信号線として放射線検出信号とノイズ信号の二本がデジタル出力として出ており、これらを取り扱う必要があります。

arduinoからmbedへ移植

arduinoのソースはほぼプログラミング言語Cそのものですが、以下の三点がarduino独自の方言です。

  1. ピン設定
  2. シリアル通信
  3. タイマー

この方言をmbed用のCに翻訳するだけで移植は完了します。

1. ピン設定(と読み取り)

これは簡単です。

arduino

//設定

//信号検出ピンの設定
pinMode(signPin,INPUT);
digitalWrite(signPin,HIGH);
//ノイズ検出ピンの設定
pinMode(noisePin,INPUT);
digitalWrite(noisePin,HIGH);

//読み取り

// 信号のローデータ 通常:High 検出時:Low
int sign = digitalRead(signPin);

// ノイズのローデータ 通常:Low 検出時:High
int noise = digitalRead(noisePin);

をmbedでは

//設定

DigitalIn signPin(dp25);
DigitalIn noisePin(dp26);
signPin.mode(PullUp);
noisePin.mode(PullUp);

//読み取り

// Raw data of Radiation Pulse: Not-detected -> High, Detected -> Low
int sign = signPin;

// Raw data of Noise Pulse: Not-detected -> Low, Detected -> High
int noise = noisePin;

と書きます。mbedは関数すら呼ばずにピンの状態を変数に直接代入しているようにみせてます。すごい。

2. シリアル通信

これも簡単です。

arduinoでは

Serial.begin(9600);

//シリアルで送信
Serial.println(msg);

 などとしますが、mbedでは

Serial pc(USBTX, USBRX); // tx, rx

pc.puts(msg);
pc.puts("\r\n");

などとします。\rを付けずに\nだけ付加しているmbedプログラムをよく見かけますが、多くの環境(というかシリアル通信端末プログラム)で\rがないと改行後に左端にカーソルが移動せずに出力が乱れてしまいます。

3. タイマー

これも簡単。

arduinoでは

//現在の時刻を取得
currTime = millis();

ですが、mbedでは

Timer t;

    t.start();

    currTime = t.read_ms();

 とすれば一対一対応します。

動かしてみたが、止まる。

移植はすぐ終わったのですが、いざ動かしてみると短時間で動作を停止してしまうことがわかりました。どうやらノイズピンに信号があると動作停止するようです。移植元のarduinoソースコードを真面目に読んでみたところ、怪しげな部分を見つけました。

//10000回ループを回ったら、計測値を計算して、シリアルで出力する
if(index==10000) //Arduino Nano(ATmega328)で160-170ms程度
{

  //省略
  
  //ノイズが10000回のループの中でまったく検出されないとき
  //ノイズが検出されたときは、処理をしない
  if(noiseCount == 0)
  {
  
    //省略
  
    //シリアルで送信
    Serial.println(msg);
  
    index=0; // <-えっ???ここで?
  }
  
  // 省略
  
}
index++;

 つまり、ノイズがない時だけ、indexが正常に0に初期化されるロジックになっているので、ノイズがあるとindexが初期化されずに増加しすぎておかしな挙動につながる、と思われます。よって

  if(noiseCount == 0)
  {
  
    //省略
  
    //シリアルで送信
    Serial.println(msg);
  
    //index=0; // <-ここをやめて
  }

  index=0; // <- ここにする
  

 としました。これでmbedでも正常に動作し続けることを確認できました。

f:id:XX-Prime:20150503182752p:plain

なぜarduinoでは問題が起こらないのか?

起きてるような気もしますが、とりあえずわかりません。intのサイズの違いかなあ。

追記(2015/05/05)

Radiation-watch.orgの問い合わせフォームから、上記のコード部分について質問してみたところ、やはりバグであることが判明しました。現在ダウンロードできるarduinoコードは修正済みのものなので、もし現在古いコードを使っている方は新しいもので置き換えることをお勧めします。ノイズピンに信号があった場合の計測値の精度が若干向上します。

arduinoで問題が起こらなかった理由も、Radiation-watch.orgのご担当の方の説明で判明しました。arduinoのintが2バイトであるため、index変数の初期化に失敗しても短時間でオーバーフローして、ある意味で勝手に再初期化が行われるために明確なバグとして発覚していなかったというのが真相です。mbedはintが4バイトなので、オーバーフローまでarduinoの65535倍の時間がかかるために、動作が止まったことがハッキリと認識できたわけです。私がもし賢かったら、移植の際にintのサイズを合わせるためにmbedではshort intを使っていたはずで、その場合はバグが発覚することもなかったでしょう。バカで良かった。

コード

改変部分をあえてコメントとして残してある部分もあります。

 

まとめ

mbedすげー。

Arduino yunで放射線センサのデータをxivelyとM2Xにアップロードする

xivelyだけでは不安

xivelyはたまにサービスが止まるので、センサデータをxivelyだけに上げるのは良いアイディアとは言えません。M2Xにも同時に上げてデータロストに備えましょう。

yunのプログラムスペースはやはり小さい

複数クラウドへの同時データアップロードの例として、pocket geiger type5の測定データをarduino yunでxivelyとM2Xの両方に上げるプログラムを書いてみました。当初はxivelyと同様にarduino側のProcessクラス経由のcurlを利用してM2Xにもアップロードしようと試みましたが、パラメータの文字列を用意するためにメモリが足りなくなって断念し、結局linux側のシェルスクリプトにM2Xへのアップロード機能を移しました。また、放射線データ保存用の配列も、デフォルトでは200要素ありましたが、150まで減らしてやっとうまく動作しました。しかしここまで苦労するなら素直に全部linux側でやってしまったほうが良いような気もします。

つかいかた

スケッチの下の方でコメントになっているシェルスクリプトを、yunの/root/にm2x_up.shという名前で作成して実行権限を付与します。スクリプト内の

M2X_DEV_KEY='XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
M2X_API_KEY='XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
M2X_RADIATION='radiation' # radiation stream
M2X_RAD_ERROR='radiation_error' # radiation error stream

を自分用のM2Xの適切な文字列に変更します。

次にスケッチ内の

#define APIKEY "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
#define FEEDID "000000000"

を自分用のxivelyの適切な文字列に変更してyunにアップロードします。うまくいけば一分に一回の頻度でxivelyとM2Xの両方に放射線センサのデータが上がります。

データ例

以下の様な感じで、両方共アップロードがうまくいっているようです。

f:id:XX-Prime:20150426221329p:plain

f:id:XX-Prime:20150426221340p:plain

これでどちらか(というかxively)が止まっても安心です。

コード

まとめ

シェルスクリプトjsonデータの構築部分がどうしてもうまく行かず、3日くらい試行錯誤したことは人として恥ずべき過去です。