SPIによるADC(Analog-Digital Converter)の接続

コメントをどうぞ


ラズベリーパイによるディジタル入出力について,

こじ研さんのページ(Raspberry Pi応用編)

が非常に参考になった。例題を順々に実行することで,勉強になった。

ただ,「SPIによるADCの接続」について,SPI通信がうまくいかなかった。カーネルのバージョンの問題なのか原因は不明。
他に,BCM2835 libraryを用いる方法も試みたが,やはりうまくいかない。

cat /proc/version
Linux version 4.1.13-v7+ (dc4@dc4-XPS13-9333) (gcc version 4.8.3 20140303 (prerelease)

いろいろ試みた結果,PythonからSPIデバイスを操作するためのpy-spidevを用いた方法でうまくいった。

参考にしたページ

  • Qiita 「Raspberry PiのPythonからTMP36のアナログ温度センサとMCP3008のADコンバータを使う」
  • Analogue Sensors On The Raspberry Pi Using An MCP3008

接続の構成

  • Raspberry Pi 2 model B
  • MCP3208(12 bit ADC)
  • LM35DZ(温度センサ)

配線は,以下のようにした。

上記の参考ページのプログラムは,10bitのADCであるため,12bitに変更したプログラムを以下のように作成した。

import spidev
import time
import os

spi = spidev.SpiDev()
spi.open(0,0)

def ReadChannel(channel):

adc = spi.xfer2([(0x07 if (channel & 0x04) else 0x06), (channel & 0x03) << 6, 0])
data = ((adc[1] & 0x0f) << 8 ) | adc[2]
return data

def ConvertVolts(data,places):

volts = (data * 3.3) / float(4095)
volts = round(volts,places)
return volts

def ConvertTemp(data,places):

temp = ((data * 3.3)/float(4095)*100)
temp = round(temp,places)
return temp

temp_channel = 0

delay = 5

while True:

temp_level = ReadChannel(temp_channel)
temp_volts = ConvertVolts(temp_level,3)
temp = ConvertTemp(temp_level,2)
print “——————————-”
print(“Temp : {} ({}V) {}degC “.format(temp_level,temp_volts,temp))

time.sleep(delay)

spi.xfer2では,3バイトの信号を送信する。こじ研さんのページが詳しかった。

000001,SD,D2, D1,D0,000000,  00000000

SDはシングルエンド・差動の選択,D2D1D0はチャネルの選択。

本プログラムを実行した結果は,以下のようになった。

MCP3208,LM35DZの出力結果

MCP3208,LM35DZの出力結果

広告

ラズベリーパイにSSHでリモート接続

コメントをどうぞ


Raspberry pi 2 model Bを購入。
ディスプレイやキーボードを接続して使用するのは面倒なのでWindowsから,SSHでリモート接続する設定を行った。
「うしこlog」さんのページ(ラズベリーパイにSSHでリモート接続)の通りに作業を進めれば,うまくできた。
備忘録として,概要を記す。


ルーターで固定IPを割り当て

ラズベリーパイのMACアドレスとサブネットマスクを調べる。
ラズベリーパイのTerminalで,
 ifconfig
と入力。
Windowsを使って,ルータから固定IPアドレスをラズベリーパイに割り当てる。
ブラウザを立ち上げて,「192.168.10.1」にアクセス(このアドレスはルータによって変わる)。

DHCP固定割当

図1  固定IPアドレスを割り当て

図のように,詳細設定から「DHCP固定割当設定」に入り,先ほど調べたラズベリーパイのMACアドレスを登録し,IPアドレスを設定する。ここでは,「192.168.10.8」とした。

 


ラズベリーパイでネットワーク設定

ラズベリーパイのTerminalで,
sudo nano /etc/network/interfaces
と入力し,

manual -> static
address 192.168.10.8 (図1で設定したIP)
netmask 255.255.255.0
gateway 192.168.10.1

と変更および追記する。そして,
sudo reboot
で再起動。


SSHでリモート操作

フリーソフトであるTeraTermを用いる。ラズベリーパイに割り当てたIPアドレスにSSHでアクセスする。
ユーザー名とパスワードを入力すると,無事,リモートログインできる。

teraterm_capture

図2  TeraTermの接続画面


ラズベリーパイにGUIでリモート接続する方法

  1. Windowsに,VNC-Viewerをインストールする(ダウンロードしたexeファイルを都度実行する)。
  2. ラズベリーパイに,tightVNCをインストールする。
    sudo apt-get update
    sudo apt-get upgrade
    sudo apt-get install tightvcnserver
  3. tightVNCを実行する。
    Terminalで「tightvncserver」または「vncserver」と入力。初回は通信のためのパスワードを設定する。そして,「New ‘X’ desktop is raspberrypi: 」の後の番号を確認する。
  4. VNC-Viewerを起動する。
    IPアドレスと,tightVNCでの番号を指定する。
VNCserver_capture

図3  TeraTermとVNC-Viewerの設定画面

練習問題3.1-1 ガウスレーザビームのパラメータ

コメントをどうぞ


1mWのHe-Neレーザが,波長λ=633nmとスポットサイズ2W0 = 0.1mmのガウスビームを作っている。

(a)ビームの角度発散と焦点深度,およびz=3.5×105 km(ほぼ月までの距離)でのビーム直径を求めよ

(b)z=0,z=z0,z=2z0における波面の曲率半径はいくらか

(c)ビーム中心(z=0,ρ=0)とz=z0の軸上の点での光強度(単位W/cm2)はいくらか。これを,z=0に位置する小さくて等方的な光放射源によって生成される100Wの球面波のz=z0における強度と比較せよ。


(a)

角度発散θ0

焦点深度2z0

ビーム直径2W(z)

これはθ0とzとの積に相当
(b)
曲率半径R

z=0のとき
R=∞
z=z0のとき
R=2z0
z=2z0のとき
R=1.25z0

(c)
パワーP

パワーはピーク強度にビーム面積を掛けたものの半分。

ビーム軸上(ρ=0)において,強度は


z=0では,
I(0,0)=I0
z=z0では,
I(0,z0)=0.5I0

z=z0における球面波の強度は,

移動平均と標準偏差の算出 ~株価チャート:シグマバンド(ボリンジャーバンド)の作成~

コメントをどうぞ


「Igor:waveの読み込み3」で扱ったデータを元に,株価チャートの一つであるシグマバンド(ボリンジャーバンド)を作成する。

シグマバンドとは,株価の移動平均に対して,移動平均算出区間内での標準偏差σの線を引いて,株価の異常値を見つけるチャートである。

株価の変動について正規分布を仮定すると,平均値±σの範囲には68%±2σの範囲には95.5%±3σの範囲には99.7%の確率で株価は収まることになる。

 

移動平均を表すwave,+2σおよび-2σを表すwaveを作成する。
「Igor:waveの読み込み3」で読み込んだデータ数は250であったので,「Make」コマンドで,

Make /O /N=250 ‘wave_mean’ ‘wave_mean_2stdp’ ‘wave_mean_2stdm’;
AppendToTable wave_mean wave_mean_2stdm wave_mean_2stdp

とする。

移動平均算出のために,以下のマクロ「calc_mean(input_w, output_w)」を作成した。
input_wの移動平均値がoutput_wに代入される。
input_wとして株価の終値であるclosing_priceを代入し,wave_meanにその移動平均値が代入されるように使用する。

平均を算出する関数「 mean(waveName, [x1, x2]) 」を利用した。
waveNameのx1~x2の区間の平均値を算出してくれる関数である。

waveのデータ数が250であり,移動平均算出区間は20データ(定数spanとした)であるため,for文の区間は230とすべきである。例えばi=240の場合,mean(input_w, 240, 260)となり,waveデータが存在しないところを参照してしまう。
ただし,Igorはこのような場合,自動的にmean(input_w, 240, 249)として出力してくれるようである。

標準偏差を算出するために,以下のマクロ「calc_std(input_w, output_w1, output_w2, mean_w)」を作成した。
input_wの標準偏差σの2倍を移動平均値にプラスしたoutput_w1,マイナスしたoutput_w2を算出する。

標準偏差σを算出にあたり,分散σ2を算出する「 Variance(waveName, [x1,x2]) 」を利用した。
waveNameのx1~x2の区間の分散を算出してくれる関数である。

分散の平方根をとることで(sqrt関数),標準偏差を算出した。

移動平均と標準偏差

移動平均と標準偏差

 

以下のように,マクロを実効

calc_mean(closing_price,wave_mean)
calc_std(closing_price,wave_mean_2stdp,wave_mean_2stdm,wave_mean)

メニューバーの[Window]->[New Graph]よりグラフを作成。
XWave:[Day],YWave:closing_price, mean_wave, mean_2stdp, mean_2stdm
を選択。

見栄えは,軸をダブルクリックしていろいろと変更,ラインをダブルクリックしていろいろと変更。
メニューバーの[Graph]->[Add Anotation]から凡例を設定。

これらどのように設定したかは,以下のコマンドラインを参照のこと。

シグマバンドのできあがり

シグマバンドのできあがり

Igor : waveの読み込み3

コメントをどうぞ


Igorでwaveの読み込み方法について記す。前2回も参照のこと。

今回は,ヘッダ部をスキップして読み込むことと,日付データの読み込みを行う。

例として,株価データの読み込みを行う。以下のサイトから個別銘柄の株価データをダウンロードできる。
http://k-db.com/stocks/

直近250日分の日足をcsvファイル形式でダウンロード。

日足データのcsvファイル

日足データ

このcsvファイルは,最初の2行がヘッダ情報になっており,3行目からが日足データの本体。
1行目がタイトル行であり,2行目が各列の列名。

読み込みには,「LoadWave」を用い,

LoadWave /J /E=2 /L={1,2,0,0,0} /R={English,2,2,2,1,”Year-Month-DayOfMonth”,40}

とする。

/Jと/Eフラグは前回も用いたが,ASCIIデータであることと既存のテーブルに追加することを明示している。

/Lでヘッダをスキップすることを明示している。
/L={nameLine, firstLine, numlines, firstColumn, numColumns}という形式で指定する。
日本語でざっくり書くと,
/L={名前行は何行目か, データを何行目から読み込むか, データの行数, データを何列目から読み込むか, データの列数}
となる。

ここで,「0」とするとAutoとなる。numlines(行数)など,指定せずファイルにあるだけ読み込みたいときは0にすればよい。

/L={1,2,0,0,0}としているので,名前行は1行目(0からスタート)。ただしこのファイルは日本語データであり,うまく読み込めないので,0としてもよい。

 

/Rは日付形式を指定する。このcsvデータ(1列目)はIgorでの標準の日付形式でないため,指定してあげる必要がある。
/R={languageName, yearFormat, monthFormat, dayOfMonthFormat, dayOfWeekFormat, layoutStr, pivotYear}という形式で指定する。
今回は,/R={English,2,2,2,1,”Year-Month-DayOfMonth”,40}と指定した。

yearFormat: 1:数字2つで表記,2:数字4つで表記  14 or 2014
monthFormat: 1:数字(0省略),2:数字(0省略なし),3:アルファベット(省略表記,Janなど),4:アルファベット(省略なし,Januaryなど)
dayOfMonthFormat: 1:数字(0省略),2:数字(0省略なし)
dayOfWeekFormat: 1:アルファベット(省略表記,Monなど), 2:アルファベット(省略なし,Mondayなど)
layoutStr: レイアウト例を明示(図参照)
pivotYear: この数字(yyとする)以下ならば,20yy年。以上ならば19yy年。yyは4位上

Rフラグの説明

Rフラグの使い方

Rフラグの例

Rフラグの例

CSV読み込み後のIgor画面は下図。wave0~wave6まで自動で名前付けされた。

CSV読み込み後

CSV読み込み後

読み込み時のダイアログでもwave名は編集できるが,以下のようにRenameコマンドで名称変更してもよい。

Rename wave0,Day; Rename wave1,Opening_price; Rename wave2, high_p; Rename wave3, low_p;Rename wave4,closing_price; Rename wave5,trading_volume; Rename wave6 trading_value;

Igorでバイナリファイルの読み込み

コメントをどうぞ


Igorでバイナリファルを読み込む。

ファイル名はabc.binでファイルの中身はdouble型が50個格納されている。double型は8バイトなので合計400バイトとなる。

メニューで
Data/Load Waves/Load General Binary File
をクリック。

Load General Binary Data

型:Double float
Byte order:Low byte first (intel系の場合)
File:読み込むファイルを指定(今回はabc.bin)

実行後(Do it)
AppendToTable コマンドでテーブルに追加。以下のように読み込めた。

Output of Load Binary Data

補足1:

データが行列のように1次元でない場合,その列毎にwaveを分けたかったりする。
その場合には,以下のようにプロシージャを作成すれば良い。
GBLoadWaveコマンドを,読み込むオフセットを設定し,for文で繰り返し実行している。

Function test()
String file_name=”C:test:abc.bin”
Variable i, offset_i
offset_i = 0
for (i=0;i<5;i+=1)
GBLoadWave /B /T={4,4} /N=$(“wave”+num2str(i)) /S=(offset_i) /W=1 /U=10 file_name
offset_i += 50
endfor
end

補足2:

今回は,C言語でバイナリファイルを作成した。ファイルの中身は,double型で10行5列に乱数を代入している。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#pragma warning(disable:4996)

int main(void)
{
int i,j;
double abc[10][5];

FILE *file;

for(i=0;i<10;i++){
for(j=0;j<5;j++){
abc[i][j]=rand();
printf(“%lf\n”,abc[i][j]);
}
}

file = fopen(“abc.bin”,”wb”);
fwrite(abc,sizeof(abc),1,file);
fclose(file);

return 0;
}

Igorで行列計算(ジョーンズ行列で偏光状態を計算)

コメントをどうぞ


前稿で,Igorで行列計算をする方法について述べた。
本稿では,その例題として,ジョーンズ行列を用いた,波長板による偏光の計算を行う。
ジョーンズ行列は,光学系の偏光状態を計算するのに用いられる。

直線偏光を表すジョーンズベクトルは,

左円偏光を表すジョーンズベクトルは,

右円偏光を表すジョーンズベクトルは,

のように表される。

偏光状態を変化させる光学素子として,波長板がある。波長板は,速軸(Fast axis)と遅延軸(Slow axis)を有する素子である。波長板は,それを透過した光の遅延軸成分が速軸に対して,位相がΓ遅れる性質を持っている。
この波長板のジョーンズマトリックスTは,

で表される。

Γ=π/2のとき,1/4波長板と呼ばれる。
直線偏光J1 (1;1)を左円偏光J2 (1;-j)に転換し,右円偏光J3 (1;j)を直線偏光J1 (1;1)に転換する。

Γ=πのとき,1/2波長板と呼ばれる。
直線偏光J1 (1;1)を直線偏光J4 (1;-1)に転換し,右円偏光J3 (1;j)を左円偏光J2 (1;-j)に転換する。

1/4波長板と1/2波長板の例

1/4波長板と1/2波長板の例

1/4波長板と1/2波長板の計算をIgorで行ってみた。

1/4波長板のジョーンズ行列をT1,1/2波長板のジョーンズ行列をT2とすると,それぞれ,

となる。

1/4波長板に直線偏光J1を入射すると,左円偏光J2になる。

1/2波長板に右円偏光J3を入射すると,左円偏光J2になる。

以上をIgorで計算すると,以下のようになる。

//ジョーンズ行列

Make /N=(2,2) /C T1,T2
Make /N=2 /C J1,J3
variable theta1=pi/2 //1/4波長板
variable theta2=pi //1/2波長板
J1={1,1}
J3={1,cmplx(0,1)}
T1[][0]={1,0}
T1[][1]={0,cmplx(cos(theta1),-sin(theta1))}
T2[][0]={1,0}
T2[][1]={0,cmplx(cos(theta2),-sin(theta2))}
MatrixOp /O J2=T1 x J1
MatrixOp /O J2_=T2 x J3
appendtotable T1,T2,J2,J2_

実行例は下図。

Igorでジョーンズ行列計算

Igorでジョーンズ行列計算

Older Entries