備忘録

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
  1. --/--/--(--) --:--:--|
  2. スポンサー広告

RaspberryPiでSPI通信

Raspberry PiでのSPI通信を動作確認します。
今までの流れは↓です

Raspberry PiでSPI通信
http://nanicananica.blog.fc2.com/blog-entry-19.html
Raspberry PiでSPI通信(とりあえず実動作)
http://nanicananica.blog.fc2.com/blog-entry-23.html
RaspberryPi SPI通信(シェルから動作確認?)
http://nanicananica.blog.fc2.com/blog-entry-24.html


1.回路図
 とりあえずデバイスを変更しました。
 3軸ジャイロの代わりは、SRAMメモリです
 www.microfan.jp/shop/77_104.html

 回路図は以下
 raspi_spi_memory.png

 メモリの動作ですが、決まったフォーマットのコマンドを送って読み書きをします。
 
 [CMD] + [Address_Hibyte] + [Address_LoByte] + [data]
     ※ [  ] で1Byteづつです
 CMDは 0x02で書込み、0x03で読み込みです
 "0x02 0x00 0x00 0x01" は、アドレス0x0000に 0x01を書き込むという意味で、
 "0x03 0x00 0x03 0x00" は、アドレス0x0003を読み込むという意味です。

2.動作確認
 起動しましたら、spinclを使って動作確認をします。
 spinclのインストールと使い方は、↓でした
 RaspberryPi SPI通信(シェルから動作確認?)
 http://nanicananica.blog.fc2.com/blog-entry-24.html

 まずは、gpioにspiをロードします
  $ sudo gpio load spi

  実際にspiを使って、SRAMメモリに値を書き込んでいきます。
 コマンドを順に打ち込んでいきます。

- - - - - - -  - - - - SRAMへ書込み - - - - - - - - - - - - - - - - - -
$ sudo ./spincl -m2 -c4 -s0 -p0 4 0x02 0x00 0x00 0x01 
>0xfe 0xff 0xff 0xff
$ sudo ./spincl -m2 -c4 -s0 -p0 4 0x02 0x00 0x01 0x23
>0x00 0x00 0x00 0x00
$ sudo ./spincl -m2 -c4 -s0 -p0 4 0x02 0x00 0x02 0x45
>0x00 0x00 0x00 0x00
$ sudo ./spincl -m2 -c4 -s0 -p0 4 0x02 0x00 0x03 0x67
>0x02 0x00 0x03 0x67


- - - - - - -  - - - - SRAMへ読み込み - - - - - - - - - - - - - - - - - -
$ sudo ./spincl -m2 -c4 -s0 -p0 4 0x03 0x00 0x00 0x00
>0x00 0x00 0x00 0x01
$ sudo ./spincl -m2 -c4 -s0 -p0 4 0x03 0x00 0x01 0x00
>0x00 0x00 0x00 0x23
$ sudo ./spincl -m2 -c4 -s0 -p0 4 0x03 0x00 0x02 0x00
>0x00 0x00 0x00 0x45
$ sudo ./spincl -m2 -c4 -s0 -p0 4 0x03 0x00 0x03 0x00
>0xff 0xff 0xff 0x67

それぞれ書き込んだ値が、読み出せているのが確認できました。
スポンサーサイト

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2013/05/23(木) 00:00:01|
  2. Raspberry Pi
  3. | トラックバック:0
  4. | コメント:0

RaspberryPiでArduino温度センサをリモート確認

ここまでで、RaspberryPiに以下の機能が実装されました
・WiringPiライブラリにて、RaspberryPiのGPIO、UARTの制御が可能
・DRCファームのArduinoをUARTにて制御が可能
・Apache&PHPにて、Webによる情報公開が可能

ここから、
『RaspberryPiからUARTで接続されたArduinoの温度センサ値を読み取って、Webで公開する』
という感じにつなげてみます。

1.前準備
 ArduinoにDRCファームを書き込む
 DRCファームは以下の場所で、ダウンロードしてArduinoに書き込みます
 projects.drogon.net/drogon-remote-control/drc-downloads/
 このときDRCファームは、"a0”でADC0-A0ピンの値を出すように修正しときます
 詳しくは↓
 nanicananica.blog.fc2.com/blog-entry-26.html

2.回路を組む
 前々回の回路をそのまま利用します
 raspi_Arduino_temp.png

3.RasberryPiのプログラム作成 (Arduino-温度センサの値を読み取る)
 DRCファームの書かれたArduinoは、RaspberryPiからのコマンドで制御できます。
 ArduinoのA0ピンに接続された温度センサの値を読み取るようなプログラムを組みます。
 
- - - - - - - - - - - DRC_analogRead - - - - - - - - - -
#include <stdio.h>
#include <string.h>
#include <time.h>

#include <wiringPi.h>
#include <wiringSerial.h>

int main(){
    FILE *fp;
    int Tdata;
    int ret;
   
    /* シリアルポート オープン*/
    int fd = serialOpen("/dev/ttyAMA0",115200);
    if(fd<0){
        printf("can not open serialport");
    }
   
    while(1){
        /* 受信処理 */
        while(serialDataAvail(fd)){
            /* データの取得時間を取得~ファイル書き出し */
            ret = f_fileout_time();
           
            /* センサの値を取得~ファイル書き出し */
            Tdata = ( (serialGetchar(fd)&0xFF) << 8);
            Tdata += serialGetchar(fd);
            printf("%04x\n" , Tdata );
            ret = f_fileout(Tdata);
            fflush(stdout);
        }
       
        /* 送信処理 */
        serialPuts(fd,"a0");
       
        delay(1000);
    }
   
    return;
}

/* センサから取得した値を書き込む(改行付き) */
int f_fileout(int argc){
    FILE *fp;
    if((fp = fopen("/var/tmp/temperture.txt","a")) == NULL){
        return(-2);
    }
   
    fprintf(fp,"%04x\n",argc);
    fclose(fp);
   
    return 0;
}

/* 現在の時刻を書き込む(改行抜き) */
int f_fileout_time(void){
    time_t pv_time;
    struct tm *tm_data;
    char *str_time;
   
    time(&pv_time);
    tm_data = localtime(&pv_time);
    str_time = asctime(tm_data);
    int i = (int)strlen(str_time);
    str_time[i-1] = '\t';
    str_time[i] = '\0';
   
    FILE *fp;
    if((fp = fopen("/var/www/temperture.txt","a")) == NULL){
        return(-3);
    }
    printf("%s",str_time);
    fprintf(fp,"%s", str_time );
    fclose(fp);
   
    return 0;
}
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

$ sudo gcc -o DRC_analogRead_003 DRC_analogRead_003.c -I/usr/local/include -L/usr/local/lib -lwiringPi
ちなみに/var/www/に温度取得ログを吐き出すので、このディレクトリも
$ sudo chmod 777 /var/www/ などで、書込み可能としておきます

4.温度センサーログを取得して、Webで公開するためのPHPプログラム
 下のPHPコードを書いて、Webサーバのドキュメントルートにおきます
- - - - - - - - - temp.php - - - - - - - - - - - - - - -
<?php
    print("温度情報を読み込みます<br>");
   
    $last_lines = file("./temperture.txt",FILE_IGNORE_NEW_LINES|FILE_SKIP_EMPTY_LINES);
    print( array_pop($last_lines)."<br>" );
    $temp = strstr( array_pop($last_lines) , "\t" );
    print( $temp );
    $num16 = intval($temp,16);
   
    print("今の部屋の温度は、". $num16 . "(16)です<br>");
    $num10 = intval($num16);
   
    $temp_int = (($num10 * 4.9)-424)/6.25;
    print("今の部屋の温度は、". $temp_int . "です");
?>

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# きたねぇ・・・いつか書き直す

5.動作確認
センサー値取得のコードを実行
$ ./DRC_anarogRead_003
# 今後これをサービス化したいです

この後に、RaspberryPiにブラウザでアクセスすると・・・
http://192.168.0.***/temp.php

- - - - - - - - - - 結果 - - - - - - - - - - - - - -
温度情報を読み込みます
Tue May 21 18:28:30 2013 0074
0074今の部屋の温度は、116(16)です
今の部屋の温度は、23.104です
- - - - - - - - - - - - - - - - - - - - - - - - - - - -

ということで、温度センサーをWebから取得できるようになりました。
今後は、温度センサー値取得処理のサービス化や
温度のグラフ化をやっていきたいですね

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2013/05/22(水) 00:00:01|
  2. Raspberry Pi
  3. | トラックバック:0
  4. | コメント:0

RaspberryPiにPHPをインストール

Webサーバーのインストールは↓で既にやっていますが、
PHPもインストールしておきます

Raspberry PiでWebサーバー(Apache2)
http://nanicananica.blog.fc2.com/blog-entry-16.html

PHPをインストールと言ってもやることは、大してないです

$ sudo apt-get install php5
$ sudo /etc/init.d/apache2 restart


これだけです。

動作確認として、以下のコードを書いたファイルを
Webサーバーのドキュメントルートにおきます。
# 私の今回の場合は /var/www/

- - - - - - - testphp.php - - - - - - - - - -

<?php phpinfo(); ?>

- - - - - - - - - - - - - - - - - - - - - - - - - - -

これでRaspberry PiのWebサーバーに、ブラウザからアクセスしてみます。
http://192.168.0.***/testphp.php

# RaspberryPiからアクセスするならhttp://localhost/test.phpでもOK

PHPのバージョンや環境がずらずらと出れば、
インストール成功です

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2013/05/21(火) 22:34:32|
  2. Raspberry Pi
  3. | トラックバック:0
  4. | コメント:0

RaspberryPiから、Arudinoを制御 Doragon Remote Control版 その2

前回までのは↓
RaspberryPiから、Arudinoを制御 Doragon Remote Control版
http://nanicananica.blog.fc2.com/blog-entry-20.html

実際にArduinoにDRC(Doragon Remote Control)を入れて
動かしてみるのだけれど、コマンド'@'のpingは通るけど、
Arduino A0ピン読み出し(コマンドa0)が上手くいかない

なんでかなと思ったら、
PCからminicomで、コマンド"a0"送信すると、当たり前だけれども
アスキーコードにして"0x40 0x30"が飛ぶわけです。

DRCファームは、アスキーコード"0x30"をコマンド"0"としてみてくれないため
A0を読む処理まで行ってなかったです
DRCファームには、"0x40 0x01"を送信しなければいけなかったわけです。

阿呆なミスでした・・・

ただ、これですといろいろと面倒なので、DRCファームを修正しました。
修正したものが↓
https://docs.google.com/file/d/0B3Shzpx27ZKgZUs2WjdTR0YtMjg/edit?usp=sharing

int myGetchar ()
{
int x ;
while ((x = Serial.read ()) == -1)
;
if(x>=48 && x<=57)
x = x-48;

return x ;
}

なんのことはない、0~9のアスキーコード(0x30~0x38)を受信したら、
0x0~0x9に変更するというだけです。

確認のため、温度計をつけたArduinoと、RaspberryPiを接続しました。
接続回路は↓
raspi_Arduino_temp.png
# 見づらくてすみません
Arduinoは5V系なので、RasPiとの接続は、↓のレベルコンバータを挟んでいます
https://strawberry-linux.com/catalog/items?code=18187
LM60は温度計でArduinoのA0に接続しています

RaspberryPiでテスト用に利用したコードは、↓です

- - - - - DRC_DRC_analogRead_002 - - - - - -
#include <stdio.h>
#include <string.h>

#include <wiringPi.h>
#include <wiringSerial.h>

int main(){

/* シリアルポートオープン */
int fd = serialOpen("/dev/ttyAMA0",115200);
if(fd<0){
printf("can not open serialport");
}

while(1){
/* 受信処理 */
while(serialDataAvail(fd)){
printf("%02x\n" , serialGetchar(fd) );
fflush(stdout);
}

/* 送信処理 */
serialPuts(fd,"a0");

delay(1000);
}

return;
}

- - - - - - - - - - - - - -

実行結果は。。。。
00
77

Arduino A0ピンのセンサー値を取得しました。
# 上位バイト、下位バイトの順で出力されます

上記の値は、ArduinoがAD変換した生の値なので、実際の値は。。。
0077h -> 119d
4.9mV*119 = 583.1mV がA0ピンで取得した電圧値

温度センサLM60BIZのデータシートを見ると、出力電圧と、
温度の関係が以下の式で表されています。
Vo = (+6.25[mV/℃] * T[℃])+424[mV]
このため
T = (Vo-424)6.25
 = 25.44[℃]

大体あってそうですね

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2013/05/19(日) 18:54:50|
  2. Arduino
  3. | トラックバック:0
  4. | コメント:0

今更ですが、

wiringPiがアップデートされております
http://projects.drogon.net/wiringpi-v2-released/

暇ができたら、今までのプログラムの互換性を確認します

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2013/05/16(木) 14:48:50|
  2. Raspberry Pi
  3. | トラックバック:0
  4. | コメント:0

RaspberryPi SPI通信(シェルから動作確認?)

Raspberry PiでSPI通信
http://nanicananica.blog.fc2.com/blog-entry-19.html
Raspberry PiでSPI通信(とりあえず実動作)
http://nanicananica.blog.fc2.com/blog-entry-23.html
の続きです。

SPI通信なのですが、苦戦しています。
SPI通信はセンサと通っているみたいですが、データが流れてこない
初回以外、0x0しか戻ってこないです。

まぁここの調査は継続して続けていくのですが、
手軽にSPI通信の動作を確認するためのツール"spincl"を記録しておきます。

1.bcm2835ライブラリのダウンロード&インストール
 spinclは、bcm2835ライブラリというものを利用しています。
 このため、まずは事前にそっちをダウンロード&インストールします。
 手順は、通常と変わらないので、さくさくと書きます

 http://www.airspayce.com/mikem/bcm2835/このページの
 http://www.airspayce.com/mikem/bcm2835/bcm2835-1.25.tar.gz
 をダウンロードしてきて、いつもの流れです。

$ tar zxvf bcm2835-1.xx.tar.gz
$ cd bcm2835-1.xx
$ ./configure
$ make
$ sudo make check
$ sudo make install


2.spinclのダウンロード&インストール
 http://ipsolutionscorp.com/raspberry-pi-spi-utility/
 このページの下部よりspincl.tar.gzをダウンロードしてきます。

 こちらも、いつもの手順でビルドします。必要ならインストールしてください。
$ tar zxvf spincl.tar.gz
$ cd spincl
$ make


3.spinclの使い方
まぁヘルプなり、ホームページにでかでかと書いてありますが…
 Usage:
  spincl [options] len [xmit bytes]
 
 [option]には以下を指定します。
-i* : SPI開始時には -ib (biginのb)、通信停止時には、-ie (endのe)と指定します
   -m* : SPIモードの設定です。各種センサなどのデータシートを読んでください
      モード番号をそのままつけて -m0,-m1,-m2,-m3なんて形で指定します
   -c* : SPIの同期クロックのスピードを指定します。
      詳しくは、/usr/local/include/bcm2835.h の530行目くらいに記述がありますが、
      0~15の設定範囲で、125MHz~3.81KHzまでで可変できます。
      通信相手のスペックを見て指定してください
   -s* :SS信号を、RaspberryPiのCE0、CE1のどちらでやるかの指定です
      -s0:CE0、-s1:CE1、-s2:CE0&CE1、-s3:指定なし
   -p* :-p0で、Lowアクティブ、-p1でHighアクティブになります

 …ビットオーダーは今のところ、MSBFIRST固定のようです

 len [xmit bytes] は、Read/WriteのByte指定です。
 lenは最大32まで指定できて32ByteまでRead/Writeできます。

やたらとオプションをつけてやらないと動かないのは面倒ですが、
コマンドラインから手軽に呼び出せそうです。

ホームページの例ををのまま使うとすると
SPI通信開始、SPI設定はモード2、クロック15.625MHz、SSはCE0使用、CEはLowアクティブとで
3Byte読出しが以下です
$ sudo ./spincl -ib -m2 -c4 -s0 -p0 3
 >0x** 0x** 0x** <- 3byte分の受信データが戻されてきます

同様に2Byte送信は、送信Byte数を指定したあとに、送るデータを2Byte分直に書いてあげます
↓の例だと、2Byte 0xFF、0xFEを送信して、0xAB、0xCDを受信したという形です
$ sudo ./spincl -ib -m2 -c4 -s0 -p0 2 0xFF 0xFE
>0xAB 0xCD

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2013/05/14(火) 17:50:15|
  2. Raspberry Pi
  3. | トラックバック:0
  4. | コメント:0

Raspberry PiでSPI通信(とりあえず実動作)

SPI通信に関しても続いて、動作確認を行いました

Raspberry PiでSPI通信
http://nanicananica.blog.fc2.com/blog-entry-19.html
の続きです。

1.Raspberry PiのI2C通信を有効にする
 こちらも初期設定では使えないので、使えるようにします。
 $ sudo nano /etc/modules
 
 最後に以下を追加します
 spidev

 また、/etc/modprobe.d/raspi-blacklist.conf を修正します
 $ sudo nano /etc/modprobe.d/raspi-blacklist.conf

 以下のように、コメントアウトします
 #blacklist spi-bcm2708

 リブートします
 $ sudo reboot

 再起動が完了したら、ちゃんと利用できることを確認します
 $ ls -al /dev/spi*
 >crw------T 1 root root 153, 0 Jan 1 1970 /dev/spidev0.0
 >crw------T 1 root root 153, 1 Jan 1 1970 /dev/spidev0.1

2.センサを接続
 センサを取り付けます。I2Cでも利用した3軸ジャイロセンサを利用します。
raspi_SPI.png

 SPIは、おれ自身もよくわからず勉強中です。
 解説は許してください
 センサ自体の動作は、I2Cのときと同じで以下です。
  a.センサの内部レジスタ0x0Fを読み出す → 0xD4を確認
  b.センサの内部レジスタ0x20に、0x0Fを書き込む → センサ稼動開始
  c.センサの内部レジスタ0x28~0x2Dにセンサの読み取った値が入っているためそれを読む

3.なんか動作確認(とりあえず動いていることだけ)
 ↓のコードをとりあえずダウンロードしてます
 http://gist.github.com/chrismeyersfsu/3317805#file-spidev_test-c-L25
 $ gcc spidev_test.c -o spidev_test

 コンパイルした後に、実際に動作させてみます。
 $ sudo ./spidev_test -D /dev/spidev0.0

- - - ↓みたいのが返ってきました - - - - -
spi mode: 0
bits per word: 8
max speed: 500000 Hz (500 KHz)

00 00 A6 5E A9 FC
02 50 21 F0 45 FB
FD C0 48 CF 00 D4
1F 1F 07 60 A2 B6
49 46 0C 3F 10 09
01 03 03 01 07 00
00 00
- - - - - - - - - - - - - - - - - - - - - -
とりあえず0x00とか0xFFで埋まっていなければ良いらしいです・・・
明日は、ちゃんと動いているかを確認します。

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2013/05/13(月) 00:27:26|
  2. Raspberry Pi
  3. | トラックバック:0
  4. | コメント:0

Rasppbbery Pi でI2C通信(C言語で実動作 by wiringPi)

昨日に続き、I2C通信をします。

今までのをまとめます
Rasppbbery Pi でI2C通信(シェルで実動作)
http://nanicananica.blog.fc2.com/blog-entry-21.html
RaspberryPi I2C通信
http://nanicananica.blog.fc2.com/blog-entry-17.html

今回はwiringPiライブラリを利用します。
回路の構成は、前回とおりで、引き続き3軸ジャイロセンサを動かします

ドキュメントにあったとおりに進めていきます
1.libi2c-devをインストール
$ sudo apt-get install libi2c-dev

2.カーネルにi2cをロード
$ sudo gpio i2c


3.wiringPiのリビルド
 自分の場合必要なかったので、
 動かなかったらやってみる感じでよいのではないかと思います。

 ちなみに、このリビルド作業は、バッチが公開されているみたいです。↓
 http://github.com/WiringPi/WiringPi/blob/master/build
 
 wiringPi-98bcb20/wiringPi ディレクトリに下りて
 $ make clean
 $ sudo make uninstall
 wiringPi-98bcb20/gpio ディレクトリに行き
$ meke clean
 $ sudo make uninstall

 再びwiringPi-98bcb20/wiringPi ディレクトリに行き
$ meke i2c
$ make
 $ sudo make install

 wiringPi-98bcb20/gpio ディレクトリに行き
$ make
$ make
$ sudo make install

 wiringPi-98bcb20/へ行き
 ./build

4. コーディング

↓のソースコードを作りました
 # I2Cのバスアドレスは、個々に違うので確認して変更してください
 # 私の場合は、13行目の ID = 0x6b; で指定しています
- - - - - - - test_i2c.c - - - - - - -
#include <stdio.h>
#include <string.h>
#include <errno.h>

#include <wiringPi.h>
#include <wiringPiI2C.h>

int main()
{
int fd,ret;
int ID;

ID = 0x6b;

/* WHO AM I */
fd = wiringPiI2CSetup(ID);
printf("setup return : %d\n",fd);

/* start senser */
if((wiringPiI2CWriteReg8(fd,0x20,0x0F))<0){
printf("write error register 0x20");
}
printf("write register:0x20 = 0x0F\n");

/* read OUT_X_L */
ret = wiringPiI2CReadReg8(fd,0x28);
printf("OUT_X_L : %d\n",ret);

/* read OUT_X_H */
ret = wiringPiI2CReadReg8(fd,0x29);
printf("OUT_X_H : %d\n",ret);

/* read OUT_Y_L */
ret = wiringPiI2CReadReg8(fd,0x2A);
printf("OUT_Y_L : %d\n",ret);

/* read OUT_Y_H */
ret = wiringPiI2CReadReg8(fd,0x2B);
printf("OUT_Y_H : %d\n",ret);

/* read OUT_Z_L */
ret = wiringPiI2CReadReg8(fd,0x2C);
printf("OUT_Z_L : %d\n",ret);

/* read OUT_Z_H */
ret = wiringPiI2CReadReg8(fd,0x2D);
printf("OUT_Z_H : %d\n",ret);

return;
}
- - - - - - - - - - - - - - - - - - - - -

まぁwiringPiのドキュメントのまんまですね

#include <wiringPiI2C.h>
をインクルードしてあげて
wiringPiI2CSetup(ID)にて、I2Cの初期化処理を行います。

次に、wiringPiI2CReadReg8 にてデバイスレジスタ0x0Fを読み、
正しく通信ができていたときのデバイスのレジスタ値0xD4を確認します。

次に、wiringPiI2CWriteReg8にてデバイスレジスタ0x20に0x0Fの値を書いてあげて
センサをスタートさせます

その後は、レジスタ0x28~0x29にx軸,y軸,z軸の値が入っているので、
wiringPiI2CWriteReg8で順々に読み込んでいきます。

実行結果は↓のようになりました
- - - - - - - - - - - - -
setup return : 3
write register:0x20 = 0x0F
OUT_X_L : 82
OUT_X_H : 255
OUT_Y_L : 41
OUT_Y_H : 0
OUT_Z_L : 50
OUT_Z_H : 0
- - - - - - - - - - - - -
問題なく使えそうですね

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2013/05/12(日) 04:47:05|
  2. Raspberry Pi
  3. | トラックバック:0
  4. | コメント:0

Rasppbbery Pi でI2C通信(シェルで実動作)

実際の動作確認が遅くなっておりましたが、
パーツが届いたので、I2C通信を試してみます。

1.Raspberry PiでI2Cを使えるようにする
 I2C通信は初期設定で使えないので、使えるようにします
 $ sudo nano /etc/modules

ファイルが開きましたら、次の1行を追記します

 i2c-dev

 次に、
 $ sudo nano /etc/modprobe.d/raspi-blacklist.conf

 blacklist i2c-bcm2708
 と記載されている行をコメントアウトします
 #blacklist i2c-bcm2708

 ここで再起動一度
$ sudo reboot

2.動作確認用のツールをインストール
 $ sudo apt-get install i2c-tools

3.回路を組む
 以下のジャイロセンサ(L3GD20)を利用しました。
 http://strawberry-linux.com/catalog/items?code=12120
 test_i2c.png

 ジャイロセンサの内部レジスタ0x0F(WHO_AM_I)を読み取り、
 レジスタ0x20(CTRL_REG1)に0x0Fを書き込むと、
 レジスタ0x28~0x2Dから、それぞれセンサのx軸、y軸、z軸の値が読み取れます

4.シェルから動作確認
 4-1.Raspberry PiのI2C-BUSを確認
  下の二つのコマンドを打ってみます
  $ sudo i2cdetect 0
  $ sudo i2cdetect 1

  自分の場合だと、"i2cdetect 1"の時に、下のような表示が出ます
   0 1  2  3 4  5 6  7  8 9 a  b  c d  e  f
00:        -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- 6b -- -- -- --
70: -- -- -- -- -- -- -- --
  ここから、0x6BがI2Cのバスであることが確認できます。
  また、コマンドic2detectの後ろの値"0""1"の、
  値の載っている、表示があるほうを今後使っていきます。
  wiringPiのページを読む限り、Raspberry PiのRev.1だと"0"が、Rev.2だと"1"が使われるらしいです

 4-2.I2Cをシェルから
  センサの内部レジスタ0x0Fを読み出します
  i2cget [I2Cバス] [センサの内部アドレス]という感じでコマンドします
  $ sudo i2cget -y 1 0x6b 0x0f
  > 0x4d

  正しく通信ができている時は、0x4Dが戻されるとのことです(データシートから)

  センサの内部レジスタ0x20に0x0Fを書き込みます
  i2cset [I2Cバス] [センサの内部アドレス] [書き込む値]という感じでコマンドします
  $ sudo i2cset -y 1 0x6b 0x20 0x0f

  これで、センサが動き出します。

 4-3.センサ値の取得
  今回の3軸ジャイロセンサでは、
  それぞれ内部レジスタ 0x28~0x2Dに x軸、y軸、z軸の値を取得することができます
  $ sudo i2get -y 0x6b 0x** (**は28~2D)
  でセンサからの値を取得できます。

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2013/05/11(土) 23:23:25|
  2. Raspberry Pi
  3. | トラックバック:0
  4. | コメント:0

RaspberryPiから、Arudinoを制御 Doragon Remote Control版

ものをいじる時間がない・・・
wiringPiの本家Gordons Projectsを見ていたら、Doragon Remote Control(DRC)という
Arduinoをシリアル通信でつないで、コマンドをつかった会話で操作するようなものがあるみたい
http://projects.drogon.net/drogon-remote-control/drc-protocol-arduino/


同じようなものにFirmataというものがあります
http://firmata.org/wiki/Main_Page

折角なので、このDRC protocolに関しても
確認しておこうと思います。
ちなみに、DRCの実物は、↓にあります
http://projects.drogon.net/drogon-remote-control/drc-downloads/

DRC Protocol – Arduino

Arduino DueやUnoと会話をする時のシリアル通信プロトコルのドキュメントです。
また似たような、シリアル通信(USBホストを通して接続された)でつながるデバイスの為のドキュメントです。

シリアル通信は、ボーレート115200 ,data 8bit, 1stop bit,no parityの設定します。

次からのコマンドには、バイナリにてピン番号を示します。
そのため、もしminicomを通してコマンドを送るのなら、ピン番号3をコマンドを、文字"C"として入力します。
すべてのコマンドコードは、小文字です。

・Set pin mode:

デジタルピンには3つのモードがあります。
'o'(0x6F) を設定すると出力
'i'(0x69) を設定すると入力
'p'(0x71) を設定するとPWM出力 となります。
この後に、ピン番号が続きます。このため、3pinを出力に設定するためには、"0x6F 0x03"と2Byteを送ります。
コマンドのACK(応答)はありません

・DigitalWrite:
文字'0'(0x30)と'1'(0x31)はそれぞれロジックのLOWとHIGHを示し、これのあとにpin番号と続きます。
そのため、5pinをHIGHにしたい場合は、"0x31 0x05"と2Byteを送ります
13pinをLOWに設定したい場合は、"0x30 0x0D"とします

・PwmWrite

# 英文にはないですがPWM出力ピンの設定です
文字'v'(0x76)+pin番号と入れて、さらに3番目に0~255を表す値を示します。
9pinにディーティーサイクル50%を設定する場合は、"0x76 0x09 0x80"を送信します

・DigitalRead
文字'r'(0x72)+pin番号と入れて送信↓場合、そのピンの状態を読み取ることができます
pinのロジックレベルが、1Byteの'0'、'1'のどちらかで返されます
12pinを読みたい時は、"0x72 0x0C"と送信し、
ロジックれbるを示す'0'(0x30)か'1'(0x31)のどちらかが返信されてくることを期待できます

・AnalogRead:
文字'a'(0x61)+pin番号を送信することで、でアナログ値を読み取ることができます
アナログ値、2Byteが返信されてきますが、そのうち1番目のByteが上位バイトになります
例えば、4pinのアナログ値を読む場合、"0x61 0x04"を送信し、2Byteを返信されてきます。
もしデバイス側から0x10、0x5Cの順番で返信がきたら、"0x015C"で10進数384を示す値になります

・Ping:

基本的な命令テストとして、pingコマンドを送信することができます。
'@'か"0x40"にて、それを行うことができます。
リモートデバイスは、1Byteの'@'(0x40)を返信してきます。
シリアル通信の入力バッファをflushを必要なときは、デバイスとの接続確立のために何回か送信する

minicomなどのターミナルからテストをしたとき、2つの追加コマンドがあります。
'A':スペースキーが押されるまで、アナログポートの読み込みと表示を行います。
'X':スペースキーが押されるまで、デジタル入力の読み込みと表示を行います。
これらのコマンドは、ホストからプログラムをによる接続をしなくても、
ターゲットデバイスのテストに利用でき
機能をテストを可能にします。 続きを読む

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2013/05/10(金) 23:55:40|
  2. Arduino
  3. | トラックバック:0
  4. | コメント:0

Raspberry PiでSPI通信

I2Cの動作確認をしたいけど、I2C通信用のデバイスが一切ないことに気づく・・・
週末に買うことにして、今日はI2Cを飛ばしてSPI通信へ

いつもとおりのインチキ翻訳です。
http://projects.drogon.net/raspberry-pi/wiringpi/spi-library/

SPI Library


wiringPiは、ラズベリーパイのオンボードSPIインタフェースをより簡単に使えるようにするライブラリを含んでいます。

最初に、gpioユーティリティにてSPIドライバをカーネルにロードする必要があります

gpio load spi

もし4KBより大きいバッファが必要なときは、コマンドラインで設定してください。サイズはKBで指定

gpio load spi 100

この場合100KBのバッファがあてがわれます
(規定値は殆どアプリケーションでは十分なバッファサイズですが、スルーすべきでないです)

SPIライブラリを使用するには、プログラムに以下が必要です

#include <wiringPiSPI.h>


使える関数


・int wiringPiSPISetup (int channel, int speed) ;
これはチャンネルを初期化するためのものです。(Piは0と1の2チャンネルを持っています)
speedパラメータは、INT型で500,000~32,000,000の範囲をとり、SPIのクロックスピード(単位はHz)を表します。

戻り値は、Linuxのデバイスのための、ファイル ディスクリプタです。
-1はエラーです。
エラーが起きたら、グローバル変数の標準errnoを見て分析して下さい

・int wiringPiSPIDataRW (int channel, unsigned char *data, int len) ;
これらより、選択されたSPIを通じて、Readとwriteが同時に実行されます。
バッファ内にあったデータは、SPIバスから戻ってくるデータによって上書きされます。

プログラムはいつものように、-lwiringPi でリンクされる必要があります

ヘルパーライブラリの中にすべてがあります。
systemコールのread(),write()によっても、SPIを使用した単純な読み書きができます。
シフトレジスタに連続したデータを送るときは、標準write()を使ったほうが良いかもしれません。
また、RGBの3つセットのデータでLED表示をさせる場合も、標準のwrite()を使ったほうが良いでしょう。
AD変換やDA変換のような処理は、読み書きを平行して行う必要があります。

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2013/05/09(木) 21:57:46|
  2. Raspberry Pi
  3. | トラックバック:0
  4. | コメント:0

ツールなどなど

平日は、なかなかに時間を割けず、
ドキュメントを読んだりという形になってしまいます…

今日は、ツールの備忘録です。

・winscp
http://winscp.net/eng/docs/
大体Windows上から、コンソールでRaspberry Piをいじりますが、
コンソールからのファイルの操作が激しく面倒で、これを利用していたりします。

ファイルのアップロードや、ダウンロード、ソースコードやRaspberry Pi各種設定ファイルを
Windows上から直接操作できて、非常に有難いです。

ただし、以下の点は注意したほうが良いです。
# 特にこのツールを使うための注意というわけではないですが
・ログインユーザーの権限
 ログインするときのユーザー権限で、せっかく修正しても保存できなかったりすることがあります
・改行コード・文字コード
 Windowsからファイルを修正したり、コピーしたり修正すると狂ったりします。
 問題の起きないエディタなどと合わせて利用したほうが良いです

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2013/05/08(水) 20:38:27|
  2. Raspberry Pi
  3. | トラックバック:0
  4. | コメント:0

RaspberryPi I2C通信

Raspberry PiでI2Cできるようにします。
まずはドキュメント読み
ここにあるのは下の記述のインチキ翻訳でしかないです
http://projects.drogon.net/raspberry-pi/wiringpi/i2c-library/

I2C Library


wirinPiはRaspberry PiのオンボードI2C通信をより簡単に使うライブラリを含んでいます
すべてのシステムがI2C開発ライブラリとヘッダーピンを持っているわけではありません
wiringPiをビルドするとき、ビルド時は検出していない。
もしそれらのヘルプ関数やリンクエラーを使う場合、wiringPiI2Cヘルプファンクションがインストールされていないことを意味する
I2C開発ライブラリをインストール、リビルドする必要がある

Under Raspbian
sudo apt-get install libi2c-dev
その後、wiringPiをリビルドします

I2Cを使えるようになる以前、カーネルモジュールをロードする必要がある。
そして、gpioユーディリティを使うために、カーネルにI2Cドライバをロードする必要があります

gpio load i2c

もし規定値100Kbps以外のバンドレートを必要とするとき、
コマンドラインから以下を打ってください

gpio load spi 1000

バンドレート1000Kbpsを設定する場合は
L2Cライブラリを使うために、プログラムに下をいれます

#include <wiringPiI2C.h>

プログラムは、いつものように-lwiringPiをリンクする必要があります
I2Cデバイスを確認するために、通常のシステムコマンドを使います

Raspberry pi Rev1ではdeviece 0、Rev2ではdevice1 でることを覚えています

i2cdetect -y 0 # rev1
i2cdetect -y 1 # rev2

Funstions available

・int wiringPiI2CSetup(int devld);
引数で与えられた識別子の、I2Cシステムを初期化します
引数のdevIDはI2Cのデバイスナンバーで、i2cdetectから確認できます
なぞ文
//Raspberry Piで、wiringPiL2CSetup()は、/devに適して持ったり開いたり

戻り値は、標準的なLinuxファイルハンドルです。-1や他の値の場合は、
いつも通りerrnoで調べることが可能です

MCP23017GPIOエクスパンダは、通常デバイス0x20です。
だから、この値が戻ってくればOKです

戻り値が負の場合はエラーが起きています。errnoみて調査してね

・int wiringPiI2CRead(int fd);
単純なデバイス読み込みです。いくるかのデバイスは、レジスタ変換をしなくても、
送られてくるデータを読めます

・int wiringPiI2CWrite(int fd,int data);
単純なデバイス書込みです。いくつかのデバイスでは、内部レジスタにアクセスする必要なくデータを受けられます

・int wiringPiL2CWriteReg8(int fd,int reg);
・int wiringPiI2CWriteReg16(int fd,int reg ,int data);
デバイスのレジスタに、8/16bitの値を書き込みます

・int wiringPiI2CReadReg8(int fd,int reg);
・int wiringPiI2CReadReg16(int fd,int reg);
デバイスのレジスタから、8/16bitの値を読み取ります
続きを読む

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2013/05/07(火) 14:55:30|
  2. Raspberry Pi
  3. | トラックバック:0
  4. | コメント:0

Raspberry PiでWebサーバー(Apache2)

昨日までで、GPIOの制御ができるようになりました。
今日はWebサーバーのインストールをします。

GPIOからの信号をWebに表示させたり、
Webからの操作で、GPIOを制御したりと、そういうのに使おうと思います。


1.Webサーバー(Apache2)のインストール

$ sudo apt-get update
$ sudo apt-get install apache2

ここで、PHPやperlなんかを一緒に入れてしまう人も多いようです。



2.Webサーバーの動作確認

この時点で、Webサーバーが動きます。
http://192.168.0.***
にブラウザアクセスすれば、
It works! まで表示可能


エラーが出て動かないときは、
$ sudo groupadd www-data
$ sudo usermod -g www-data www-data
などでユーザーを追加してみましょう

これは、Apache2の動作権限でエラーが出る場合が多いらしいです

Apache2の設定は、/etc/apache2/に入るわけですが、
その /etc/apache2/apache2.conf 内に記述されています

User ${APACHE_RUN_USER}
Group ${APACHE_RUN_GROUP}
※ ${APACHE_RUN_USER}、${APACHE_RUN_GROUP} の実際の値は、
  envvarsファイル内に "export APACHE_RUN_USER=www-data"なんて形で記載されています

このため、このユーザーを追加してやれば、動作できるようになるということらしいです。
まぁ設定の方を変えちゃっても良いんだとは思いますが・・・

3.設定の確認

ルートドキュメントや、cgiディレクトリの確認しときます
/etc/apache2/sites-availableを開きます
> DocumentRoot /var/www
>
Webサーバーのルートがここになります

> ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
>
> AllowOverride None
> Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
> Order allow,deny
> Allow from all
>

スクリプトcgiの設定です。
/usr/lib/cgi-bi/nのスクリプトが、Web上の ../cgi-bin/として動作するとのことです
まぁつまりスクリプトファイルやcgiは、/usr/lib/cgi-bi/hogehoe.cgiとおくと
これは、Web上からは、http://192.168.0.***/cgi-bin/hogehoe.cgi としてアクセスできるということらしいです

まぁ設定を変更する必要はなかったです。

4.テスト用ファイル、cgiの作成、動作確認

4-1.シェルの呼び出し

以下の内容で、/usr/lib/cgi-bin/test.cgiを作成します。

- - - - - test.cgi- - - - - - - - - - -
#!/bin/sh
echo "Hello apache!\n" > testapache.txt
- - - - - - - - - - - - - - - - - - - -

セキュリティ的なところは置いておいて、
/usr/lib/cgi-bin/ ディレクトリのパーミッションを変更します
$ sudo chmod 755 /usr/lib/cgi-bin/

test.cgiも実行ができるように、実行権限を追加しておきます
$ sudo chmod 755 /usr/lib/cgi-bin/test.cgi

この上で、ブラウザから以下へアクセスします。
http://192.168.0.***/cgi-bin/test.cgi
503なんかのエラーが出ますが、
/usr/lib/cgi-bin/のディレクトリを見ると、testapache.txtが作成されています。
こんな感じで、ユーザーからのインタフェースになります。


4-2.Pythsonの呼び出し
まぁPerlでもRubyでも好きなものでいいと思いますが、
Pythsonが、Raspbianにはじめから入っているものですから・・・


- - - - - test2.cgi- - - - - - - - - - -
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
import cgi

def main():
print "Content-type: text/html\n"
form = cgi.FieldStorage()
print "<h1>Test Pythson</h1>"
main()
- - - - - - - - - - - - - - - - - - - -

同様にこれも、/usr/lib/cgi-bin/test2.cgiとしておいてあげて
実行権限を付け加えておいてやります

http://192.168.0.***/cgi-bin/test2.cgi
へアクセスすると、Test Pythsonと表示されました。


後は、補足になりますが、
何も設定を変えていないと、
Webサーバーのアクセスログの場所は、
/var/log/apache2
になります。

あと、Webサーバーの再起動は、以下のコマンドで可能です
$sudo /etc/init.d/apache2 restart

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2013/05/06(月) 00:09:26|
  2. Raspberry Pi
  3. | トラックバック:0
  4. | コメント:0

Raspberry PiでUART、シリアル通信 (実動作)

昨日に引き続き、wiringPiライブラリを使用したシリアル通信です。
今日は、実際のプログラムを作成しました。
事前に、PCとRaspberry Piを接続してターミナルを開いておいてください。

- - - - - - - - - - - - - - -
#include <stdio.h>
#include <string.h>

#include <wiringPi.h>
#include <wiringSerial.h>

int main(){

/* シリアルポートオープン */
int fd = serialOpen("/dev/ttyAMA0",115200);
if(fd<0){
printf("can not open serialport");
}

while(1){
/* 受信処理 */
while(serialDataAvail(fd)){
printf("recive : %c" , serialGetchar(fd) );
fflush(stdout);
}

/* 送信処理 */
serialPuts(fd,"hello world\n");

delay(1000);
}

return;
}

- - - - - - - - - - - - - - -
そしてコンパイル
$ gcc -o serialtest serialtest.c -I/usr/local/include -L/usr/local/lib -lwiringPi

エラーなく完了したら実行します。
$ sudo ./serialtest

1秒ごとに、Raspberry PiからPCへ"hello world"が、
PCターミナルから文字を入力すると、raspberry Piに送信されます。



・・・・といったところで、
wiringPiのexampleディレクトリの中に、使用例がありました。
serialRead.c ,serialTest.cというソースコードがありますので
コンパイルして、動作させてみても良いですね

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2013/05/05(日) 16:45:36|
  2. Raspberry Pi
  3. | トラックバック:0
  4. | コメント:0

Raspberry PiでUART、シリアル通信

シリアル通信の確認です。

1.Raspberry PiのUARTに設定する
Raspberry PiのUARTは、規定値ではシリアルコンソールに使われています。
これを解除しないと、普通のUARTとして利用できないです。
以下の手順で、普通のUARTとして利用できるようにします。
参考にしたのは↓のところ
http://www.irrational.net/2012/04/19/using-the-raspberry-pis-serial-port/

1-1./boot/cmdline.txtの修正
 念のため、バックアップを取りました
 $ sudo cp /boot/cmdline.txt /boot/cmdline_backup.txt
その後に、実際に修正します。
 $ sudo nano /boot/cmdline.txt

  dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 rootwait
  ↓
  dwc_otg.lpm_enable=0 rpitestmode=1 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 rootwait

  削除 : console=ttyAMA0,115200 kgdboc=ttyAMA0,115200
  追加 : rpitestmode=1

1-2.再起動
  $ sudo reboot

1-3./etc/inittabを編集
 こちらも念のため、バックアップを取りました
 $ sudo cp /etc/inittab /etc/inittab_backup.txt
その後に、実際に修正します。
 $ sudo nano /etc/inittab

 一番最後の行のttyAMA0の行をコメントアウトします
  T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100
  ↓
  #T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100

1-4.再起動
 もう一度再起動して完了

1-5.とりあえずここまでで動作確認
 PCと、Raspberry Piを物理的に接続します。

 Rassberry Pi
  6pin : GND → PCのシリアル通信のGNDと接続
  8pin : TXD → PCのシリアル通信のRXDと接続
  10pin : RXD → PCのシリアル通信のTXDと接続
 
 Raspberry Pi系の電圧は3.3Vで、PCのシリアルとはそのままでは接続できません。
 今回は、↓のFT232RLを使ったUSBドライバチップで接続してます。
 http://akizukidenshi.com/catalog/g/gK-01977/

 PC側からteratermを立ち上げて、ボーレート115200、データ8bit、パリティなし、ストップビットは1bit、フロー制御なしに設定。
 # 通信ポートは、FT232への通信ポートを設定

 Raspberry Pi側の設定として、minicomを入れました
 $ sudo apt-get install minicom
 $ minicom -b 115200 -o -D /dev/ttyAMA0

 これで、PC→RasPi 、 RasPi→PC の通信が正しく行われていることを確認できます。
 ちなみにminicomは、CTRL+A押す → Z を押す。などで操作できます。
 データの受信も、minicomで受信に設定しないと、PCから来るデータを表示しないです。
 初めて使ったので、ちょっと使い方が判らなくてあせりました。

なかなか進んでいませんが、wiringPiのシリアルライブラリの実プログラムは明日へ

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2013/05/04(土) 02:20:54|
  2. Raspberry Pi
  3. | トラックバック:0
  4. | コメント:1

WiringPi Serial Library

次はシリアル通信です。
本家は↓
https://projects.drogon.net/raspberry-pi/wiringpi/serial-library/

ちなみに実例は明日やります。

Serial Library


wiringPiは、シリアルポートを操作するライブラリを含んでいます。
オンボードのシリアルポートとして利用でき、他のUSBデバイスと特別な区別ありません。
初期のOpen関数で、デバイス名を名づけます。

使うために、プログラムに以下のファイルがインクルードされていることを確認してください

#include <wiringSerial.h>

その後、以下の関数で利用できます。


・int serialOpen (char *device, int baud) ;

 Open関数は、シリアルデバイスの初期化と、バンドレート(転送レート)を設定します。
 シリアルポートは、デコードなしで文字を取り込むrawモードに設定され、
 読み込みから10秒でタイムアウトするように設定されます。
 戻り値が-1のときはエラーが起きています。errornoと対応しています

・void serialClose (int fd) ;
引数にて与えられたデバイスを閉じます

・void serialPutchar (int fd, unsigned char c) ;
引数で与えられたデバイスに、1byteだけ送信します。

・void serialPuts (int fd, char *s) ;
シリアルデバイスにNULLで終わる文字列を送信します

・void serialPrintf (int fd, char *message, …) ;

printfをシリアルデバイスにエミュレートします

・int serialDataAvail (int fd) ;
読み込み可能な文字の数を返します。
-1のときは、エラーが出てます。

・int serialGetchar (int fd) ;

シリアルデバイスから次の文字を返します。
データがないときは-1を返し、最大10秒間コールをブロックされます

・void serialFlush (int fd) ;
受信したすべてのデータを破棄し、downが送信されるのを待ちます。
# "waiting to be send down the given device."ってどういう意味?

Note:記述子fdはLinux標準の記述子を戻します。
 標準のread()、write()関数や、システムコールにも使えます。
 E.g.大きなバイナリブロックを書き込もうとするとき、
   serialPutchar()やserialPuts()を使うのは適切でないかもしれません。
   その場合、write()関数を利用できます。

Advanced Serial Port Control
wiringSerialライブラリはシンプルな制御を意図されています。
もし高度な制御が必要であれば、それにあったアプリケーションを利用できる。
例えば、パリティ制御、モデム制御は、PiのオンボードUARTにはない機能です。
昔ながらの方法を実行する必要があります

例えば、シリアル7bit+even、パリティを追加するモードでは、
以下のようにします

#include <termios.h>

struct termios options;

tcgetattr (fd, &options) ; // Read current options
options.c_cflag &= ~CSIZE ; // Mask out size
options.c_cflag |= CS7 ; // Or in 7-bits
options.c_cflag |= PARENB ; // Enable Parity - even by default
tcsetattr (fd, &options) ; // Set new options


上記の変数'fd'は、serialOpenが返される記述子です。
設定できるオプションは、tcpgetattrをmanコマンドで見てください

man tcgetattr
  1. 2013/05/03(金) 18:21:58|
  2. Raspberry Pi
  3. | トラックバック:0
  4. | コメント:0

C言語でシェルを呼ぶ

何か連続するシステムを作るとき
手軽にシェルから処理できるところは、シェルでやっちゃいたいと思い
メモ書き


Cのプログラムからシェルを呼び出して使う

■書式
#include <stdlib.h>

int system(const char *command);

■備考
 "/bin/sh -c"としてコールされ、シェルを利用できます。
 シェルが動作して、動作完了まで次の行には行きません。
 正常に完了したら0が、異常終了の場合は-1が戻って来ます。

■例
#include <stdlib.h>

int ret = system("echo \"hello shell\" > temporary");

- - - - - - - - もう一例 - - - - -

#include <stdio.h>

main(void){
printf("hello world\n");
}

とあれば、

#include <stdio.h>
#include <stdlib.h>

int main(void){
printf("hello world\n");
int ret = system("echo \"hello world\n\");
}

と修正すると Hello worldが2回表示されるます。

  1. 2013/05/03(金) 00:54:46|
  2. Linux
  3. | トラックバック:0
  4. | コメント:0

GPIO Utility

次はGPIOの設定なり、簡単なsyるコマンドでの操作
本家は↓のところ
https://projects.drogon.net/raspberry-pi/wiringpi/the-gpio-utility/



The GPIO utility

wiringPiGPIO管理を補助するために、別のプログラムが付いています
このプログラムgpio(と呼ばれる)は、GPIOをスクリプトを扱うことができます
GPIOの入力を読み取ったり、出力に設定できます

シェルスクリプトのgpioコマンドからでさえ、書くことができます
効率的ではありません

もう一つの方法はSystem() をC言語やC++から呼ぶことです。
また同等のほかの言語からでもです

gpioコマンドはsudoコマンドや、rootでログインしなくても
setuidプログラムとしてインストールされ、
通常ユーザーから呼び出されるように設計されています

GPIOを制御するためのGPIOユーティリティとして以下に、
次のことができます

・/sys/class/gpio インタフェースを通じてピンをエクスポート/アンエクスポート
 rootログインやsudoコマンドを使用しなくてもプログラムで使える

・/sys/class/gpioを通じてエッジトリガ割り込みピンをエクスポートできます

・PiFaceペリフェラルデバイスを制御できます

・SPIやI2Cもモジュールをロードして、/dev/に
 ユーザープログラムからgpioの読み書きができる権限
 を取得できる

・SPIバッファサイズ、I2Cボーレートの設定

・Gertboard DACの出力

・Fertboard ADC入力の読み込み

・ラズベリーパイのハードウェアリビジョンの設定

gpioプログラムは、manコマンドですべての機能を確認できます

man gpio

- - - - - - - - - - - - - - - - -

使い方
 コマンドラインから入力してね

gpio -v
 バージョンを表示します

gpio -g
 オプション-gは、BCM_GPIOとして解釈させます。
 (wiringPiピンではなく)
 


Standard input and output commands

gpio [-g] mode in/out/pwm/up/down/tri
 gpioのモード/入力/出力/PWM出力/を設定します。
 付け加えて、プルアップ、プルダウン、なしの設定もできます

gpio [-g] write 0/1
出力ピンのHigh(1)、Low(0)を設定する

gpio [-g] pwm
 PWM値(0-1024)を設定する

gpio [-g] read
 入力ピンの値を読み取る。Low(0)、High(1)

gpio readall
 アクセス可能なピンを表にして表示します。
 

Module Load Commands
gpio load spi [buffer size in KB]


gpio load i2c [baud rate in Kb/sec]



/sys/class/gpio mode commands

gpio export in/out
 BCM-GPIOをユーザープログラムで入力/出力として設定します

gpio unexport
 ピンの設定を解除します

gpio unexportall
 すべてのピン設定を解除します

gpio exports
 /sys/class/gpioを通じて設定されているピンを出力表示します。

gpio edge rising/falling/both/none
 エッジ割り込みの設定ピンとして設定し、
 その引数で、立ち上がりか、立下りか、両方か、なしかのトリガを設定します

Example
 入力ピンに設定したピンを下のように設定できます


gpio mode 0 up # 内部抵抗のプルアップ、プルダウン
gpio mode 0 down # 内部抵抗のプルアップ、プルダウン
gpio mode 0 tri # なし


  1. 2013/05/02(木) 00:06:07|
  2. Raspberry Pi
  3. | トラックバック:0
  4. | コメント:0

wiringPi API

wiringPiに関してドキュメントを一通り読みました。
翻訳した内容を、メモとして残します。

まずは、wiringPi APIに関して
本家のざっと読みでしかないです。
https://projects.drogon.net/raspberry-pi/wiringpi/functions/


■Setup Functions
 int wiringPiSetup(void)
int wiringPiSetupGpio(void)
int wiringPiSetupSys(void)


Setup Functionsの一つは、プログラムの最初に呼ばなければいけません。
 もし、GPIOの初期化処理に失敗して戻り値-1が返された場合は、エラーナンバーより相談してください。

 ・int wiringPiSetup(void)
  これはwiringPi systemの初期化で、wiringPiピンナンバーを利用することを前提とします。
  実際のBroadcom GPIOピン番号を基礎とした、0~16の仮想ピンをマッピングしたものです
ピンページを確認してwiringPiピン配置と、Broadcom GPIOの物理位置を見て下さい

wiringPiSetupGpio(void)
 これも上の関数と同じです。しかし、こちらはプログラムがBroadcom GPIOのピン番号を直接呼び出すのを許します。

wiringPiSetupSys(void)

 これあ、wiringPiシステムを初期化しますが、 /sys/class/gpioインタフェースを使います。 むしろハードウェアの直接ダイレクトよりも
 これはrootでなくてもCallすることができます
 このモードのピン番号は、native Broadcom GPIO番号です
 
 Note:このモードでは、/sys/calss/gpioにてエクスポートされたピンだけを利用することができます
 ピンをプログラムで呼び出す前に、事前にエクスポートしてください
 シェルスクリプトで利用することができます
 system()関数を使用しても使うことができます
 
 また以下の関数のいくつかは、root権限でないと動きません。
 
General wiring functions
 ・void piMode(int pin,int mode)
  ピンのINPUT、OUTPUT、PWM_OUTPUTを設定します。
  Note: wiringPi pin 1(BCM_GPIO 18)は、PWM出力をサポートしています。
  ピン番号は、ピンテーブルから取得される値です。
 
 ・void digitalWrite(int pin,int value)
  引数pinのピンにHIGHかLOW(1か0)を設定します
 
 ・void digitalWriteByte(int value)
  8つのGPIOに、8bitで設定した値を設定します
  これは、8bitすべてを一回で制御するもっとも早い方法です
  twiってなに?
 
  ・void pwmWrite(int pin , int value)
  PWMレジスタに値を書き込みます。0~1024の間をとります。
  もう一度書きますが、PWMをサポートしているのは、pin1(BCM_GPIO18)だけです
 
  ・int digitalRead(int pin)
  引数で与えられたpinの値を戻り値とし返します。
  HighまたはLowのロジックレベルで戻します
 
  ・void pullUpDnControl(int pin,int pud)
  これは、引数のピンのプルアップ、プルダウンを設定します。
  事前に該当のピンをINPUTに設定しておかないといけません
  Arduinoとは違って、BCM2835は、プルアップ、プルダウン内部抵抗を両方持っています。
  パラメータPDU_OFF(プルアップ/ダウンなし)、PUD_DOWN(グランド接地)、PUD_UP(3.3Vに釣る)
  の値をとりえます
 
  この関数は、Sys modeだと効果がありません。
  プルアップ/プルダウンををアクティブにしたいのであれば、
  プログラムを起動させる前に、スクリプトなどでGPIO設定を行ってください
 
 PWM Control
  Sys mode時は、PWMコントロールはできません
  
 ・pwmSetMode(int mode)
  PWMは、"balanced"と、"mark:space"の2種類のモードがあります。
  "mark:space"は、伝統的なモードですが、既定値は"balanced"です。
  "PWM_MODE_BAL"と、"PWM_MODE_MS"を引数として与えることで、切り替えることができます
  
 ・pwmSetRange(unsigned int range)
  PWMジェネレータ内の範囲レジスタを設定します。
  既定値は1024です。
  # よくわからない
  
 ・pwmSetClock(int divisor)
  PWMクロックの除数を設定します。
 
 Timing functions

 ・unsigned int millis(void)
  wiringPiSetup関数(のどれか)を呼んでからミリ秒を示す数値を返します。
  49日毎に、32bit符号なしの値を返します
 
 ・void delay(unsigned int howLong)
  引数howLongで与えられた数値のミリ秒分、処理をポーズします。
  Linuxのマルチタスクの性質上、指定した値より長くなる可能性があります。
  最大ディレイは、符号なし32bit整数の最大値から約49日です
 
 ・void delayMicroseconds(unsigned int howLong)
  引数howLongで与えられた数値のマイクロ秒分、処理をポーズします。
  Linuxのマルチタスクの性質上、指定した値より長くなる可能性があります。
  最大ディレイは、符号なし32bit整数の最大値から約71分です
  
 Program/Thread Priority
 ・int piHiPri(int priority)
  より優先度の高いプログラムをリアルタイムで動作させられるように、優先度をシフトできます。
  優先度パラメータは、0(初期値)~99(最大)の間で設定できます
  これは、プログラム自体を早くするものではないですが、タイムスライスで割り当てられる時間を多くします
  優先度パラメータは相対的なものなので、他のプログラムの営業を受けます
  
  戻り値が0の時は成功です。1はエラー
  エラーナンバーが返されたら、慣例に従ってグローバル変数 errnoと相談してください
  
  root権限にて動作している時だけ優先度を変更できます。
  もしrootでないときに、この関数を呼ばれても何も起きません
  
 Interrupt
  GPIO割り込みhandingパッチを当てられたカーネルで、プログラムに割り込み待ち処理が可能になります
  割り込みを待つ間、プロセッサ―の処理を解放します。
  GPIOの立ち上がり割り込み、立下りの両方で割り込みを設定することができます。
  
  waitForInterrupt()関数は廃止されます。
  より簡単で新しい、wiringPiLSR()関数を使ってください
  
  ・int waitForInterrupt(int pin,int timeOut)
   関数が呼ばれると、割り込みイベントが起きるまで待ち、プログラムが停止状態になります。
   timeOutパラメータのミリ秒分を設定することができます。また-1を設定することで、
   永久に割り込みを待つこともできます
  
   エラーが起きた場合は、-1が戻されます。errnoも適切に設定されます。
   タイムアウトの時は0が返されます。割り込み成功した時は1が返されます。
   
   waitForInterruptの関数を呼ぶ前に、GPIOの初期化を行ってください。
   このgpioプログラムを行うための唯一の方法は、それぞれスクリプトか、System()関数です
   
   GPIO 0の立下り割り込みを待ちたいのであれば、下のように設定してください
    gpio edge 0 falling
   プログラムを実行する前に
   
   ・int wiringPiISR(int pin,int edgeType,void (*function)(void))
    この関数は、指定されたピンの割り込みを待ちます。
    edgeTypeのパラメータは、INT_EDGE_FALLING,
    INT_EDGE_RISING,
    INT_EDGE_BOTH,
    INT_EDGE_SETUP
    ???
   
    ピンの番号は、共通モード( native wiringPi , BCM_GPIO, Sys )で供給されます。
    ルートで動作させる必要も、動作モードをヘラ部必要はありません。
   
    割り込みが入ると、この関数が呼ばれます。
    多重割り込みの記述があるが、どういう意味かわからん
   
    この関数は、高い優先度で動作し、メインプログラムと同時に実行されます。
    グローバル変数や、オープンファイルハンドルのフルアクセスを持っています
   
    詳細な使い方は、isr.cの例を見てください
   
 Concurrent Processing(multi-threading)
  wiringPiは、Linux implementtation of Posix threadsへの簡単なインタフェースだけでなく、
  mutexへのアクセスも実装しています。
  
  これらの機能は、メインプログラム内の一つの処理として作成することができ、
  これらの機能を使用して、安全に変数へ渡すことができます。
  
  ・int piThreadCreate(name)
   
 
 Misc.Functions
 ・piBoardRev(void)
  RaspberryPiのボードリビジョンを返す。1or2
 
 ・wpiPinToGpin(int wPiPin)
  wiringPiから割り当てられているBCM_GPIOピンの番号を戻す
  ボードのリビジョンも考慮に入っています
 
 ・setPadDrive(int group,int value)
  特定グループのピンのために、pad driverの強度を設定することができる。
  3グループのピンと、ドライブ強度を0~7があります
  詳細を知っているのでなければ、これを触らないでください
 
  
 
  1. 2013/05/01(水) 15:11:24|
  2. Raspberry Pi
  3. | トラックバック:0
  4. | コメント:0
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。