nRF24L01+ 無線実験

Atmega328P-PUと無線ユニット

前回は失敗していまいましたが、こりずに挑戦です。今回もまたebayから仕入れた品物のお話です。

マイコン+無線といいますとxbeeが有名どころのようですが、今回、怪しいもの好きの私が見つけた品物はNordic Semiconductor社のnRF24L01+というチップを使った無線ユニットです。

「NRF24L01+ 2.4GHz Wireless Transceiver Module FOR Arduino」というタイトルで売っていました。最大の特徴はその安さです。私が購入した時は2個セットで約$6(送料込)でした。とても小型で、アンテナもユニットの基盤にプリントされています。

この製品の特徴は

  • 無線LAN等に使われている2.4GHzのISMバンドで通信を行う
  • 通信速度を250Kbs,1Mbps,2Mbpsから選ぶ事ができる
  • 1.9V-3.6Vで動作する。(※5Vをかけると壊れてしまう。注意が必要です)入力ピンは5Vトレントラント
  • 出力1mW (0dBm)
  • 低消費電力 送信1mw時11.3mA、受信2MBps時13.5mA

他にも超低電力消費モードがある事や、最大1台対5台の通信が出来ること(MultiCiever機能)がデータシートに記載されていました。周波数は2.400GHz~2.525GHz間で1MHz単位で変えることができます。

一定出力以下のISMバンドの通信機器は免許不要ということですが、日本国内で使用するためには認可が必要みたいですね。この製品はそのような認可はとってないでしょう。まぁ、個人的にちょっと実験するだけならば問題にはならないでしょう。残念ですが日本国の法律に抵触する可能性がありますね。善良な市民の皆さんは許可された国に行き実験しましょう。

ということで、まず初めにYour Duinoさんのwebを参考にさせていただきました。ぱっと見て気付きましたが、このページには私が購入したタイプとピン配置が違う製品が記載されています。よくわかりませんが、こちらの図のジグザグアンテナの方が良く電波が飛びそうに見えます。これは早くも失敗だったでしょうか?

気を取り直して、本文を良く読むと、Arduinoでこの無線ユニットを使うために2つのライブラリが作られている事がわかりました。1つはRF24ライブラリ、もう1つはMirfライブラリだそうです。

こちらのページにRF24ライブラリのダウンロード先が書いてありました。もうひとつのMirfライブラリはこちらのページに情報があります。残念なことにMirfライブラリはArduino 1.0環境では現時点で動作しませんでした。(0023環境では動きました)

ここから後の作業は、このブログタイトル通り試行錯誤でした。いかんせん初心者ですので誤りがあるかもしれません。もし記述に誤りがあった時には御指摘いただければ有難いです。NRF24L01+をより活用することができると書いてあったRF24ライブラリを使って通信を試みます。

  • こちらからRF24ライブラリをダウンロードします。 Download RF24 Library here (ZIP or GZ)
  • ダウンロードしたファイルを展開してできるフォルダ名(現時点ではmaiacbug-RF24-94635e8)をRF24にリネームする。
  • そのRF24フォルダごと Arduino-x.x\libraries\ 以下にコピーする

上記の手順でライブラリの登録ができました。

さてnRF24L01+ユニットとArduinoとの結線です。RF24ライブラリ作者であるmaniacbugさんのwebに載っていました。

【nFR24L01+とArduinoの結線】
nFR2401+ Arduino
GND GND
VCC 3.3V
CE 9
CSN 10
SCK 13
MOSI(MO) 11
MISO(MI) 12
IRQ 通常は未使用、チャレンジャーは2

Your Duinoさんのwebに書かれている結線とはCE,CSNの配線が異なっています。デフォルトでRF24ライブラリを使用するならば、上記が正解みたいです。)
--->1/19追記 CE,CSNのピンアサインは変えることができます。


最初ブレッドボードで実験しようとしたのですが、ピンの間隔は一般的な2.54mmなのですが列の間隔が足りなくてブレッドボードではうまくいきませんでした。(ちょっと考えれば分かりそうなものです。まだまだですね。)

というわけで今回は片側がオス反対側がメスのブレッドボード用のジャンパワイヤーで配線しました。また、実験には同じセットが2台必要になります。

さて準備ができました。Arduino 1.0の環境で実験開始です。Arduino IDEのメニューからサンプルスケッチを試します。 [File]-[Examples]-[RF24]-[GettingStarted]を、無線ユニットをつないだ2台のArduino双方にアップロードします。

シリアルモニタを表示させてボーレートを 57,600baud に合わせます。するとシリアルモニタには

RF24/examples/GettingStarted/

ROLE: Pong back

*** PRESS 'T' to begin transmitting to the other node

STATUS        = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0

RX_ADDR_P0-1  = 0xf0f0f0f0d2  0xf0f0f0f0e1

・・・ 以下略

このようなステータスが表示されます。現在双方のArduinoはPong backモードですので、’T’をタイプしてSendボタンを押します。

*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK

Now sending 428654...ok...Got response 428654, round-trip delay: 23

Now sending 429678...ok...Got response 429678, round-trip delay: 24

Now sending 430703...ok...Got response 430703, round-trip delay: 24

・・・ 以下略

このように表示されれば成功です。ミリセコンド単位でpingのディレイが表示されました。

出力が1mWということで、どのくらいの飛距離がでるか実験してみました。デフォルトの1MBpsで室内障害物無しの条件で約10mは全く問題無しでした。さらに、外に出て木造建物の壁1枚を隔て約15m程度はなれた所で限界が来ました。いろいろな環境条件によって変わると思いますので、これはごくおおざっぱな参考値です。データシートには256Kbpsにすると消費電力は増えるが受信感度が増すという内容の記述がありました。距離的にちょっと心もとない気もしますが、使う用途によっては十分実用になると思います。

以下の事柄は私の環境に限ったことかもしれません。ジャンパー線を外しプロトシールドにピンソケットを付けて実験してみました。φ0.26mmのジュンフロン線で配線をしたのですが、最初全てのパケットがタイムアウトになってしまいました。一瞬言葉を失いましたが、冷静に戻った後、モジュールにつながる電源の3.3VとGNDの配線を太いものにしてようやく動作しました。電源周りに気を付けた方がよさそうです。現在はさらにバイパスコンデンサを取り付け、他の信号線も太い配線にしました。

ebayでの買い物 2点

(1点目) 【Prototype Shield ProtoShield & MINI Bread Board FOR Arduino Duemilanove】
というタイトルで売り出されていたユニバーサル基盤のシールド+小さなブレッドボードです。ブレッドボードの裏には両面テープがついていて、基盤の上に張り付けることができます。キットかと思っていたのですが、完成品でした。(送料込 約$8.0)

両面スルーホール。リセット用のタクトスイッチとICSP用ピンヘッダ用のスルーホールがあって、それぞれ配線されています。基盤の短辺方向に延びるピンソケットは、それぞれ5V、GNDにつながっています。14PINの表面実装用のSOICを載せるスペースが1か所ありあます。

LED1、2は1KΩの抵抗を経由してカソード側がGNDにつながっていて、アノード側はランドで止まっています。LED2は1kΩ、タクトスイッチと直列につながり、両端はランドで止まっています。 タクトスイッチS1は片側がGND、反対側がランドで止まってます。

(2点目)【Arduino UNO (ATMEGA328P / ATMEGA8U2) + USB Cable WL
というタイトルで売り出されていた品物。(送料込 $18.5)

ずいぶん安いな、と思って買ったのですが、結局のところ非常に似ている非純正品でした。まぁ、良く考えればこの値段では当然です。でも、ebayで表示されていた写真は純正品みたいだったのですが….

もう一度webに戻り、その業者の商品説明を読み直しました。すると、最後の方の目立たない所に「写真は図解の意味だけのものである」などと書かれていました。また同時に「気に入らないことがあったら、フィードバックをする前に必ずメールをよこしてくれ」との注意書きがあります。少々グレーゾーンの業者ですね。

さて、この商品には続きの話があります。内容は互換品なので動きさえすれば良いと思い、動作確認をすることにしました。WindowPCにUNO用のデバイスドライバをインストールした後に、Arduino IDE からスケッチをアップロードしましたが、エラーが出てアップロードできません。リセットスイッチを押して読み込ませようとしてもだめでした。IDE内のTools-BoardでもちゃんとUNOを指定してあります。IDEのバージョンを変えたりもしてみました。

業者に連絡しようか否か迷いましたが、言葉の壁や手間を考えると非常におっくうです。金額は大したことは無いですが、輸入品の悪い面をまともに食らってしまいました。国内の業者であればこのような事はまずないでしょう。あったとしても簡単に連絡して話ができます。

幸いICSPピンから書き込みができましたので、ブートローダ、fuseビット等を上書きして通常動作できるようになりました。スケッチがアップロードできない原因はいろいろあると思いますが、もし私が最初に購入したArduinoがこれでしたらお手上げだったと思います。今回は非常に良い勉強になりました。次回からは注意します。

Ethernet shield メール受信…か?

キャンプに行く予定はないですが....

前回Ardunoからメールを打つことができましたので、今回はメールの受信です。通常のメールソフトみたいな物はとても作る技術がないので、いま何通メールが届いているかシリアルモニタに表示させてみましょう。

前回、Telnetを使いSMTPサーバにアクセスしました。今回も前回と同様にArduino君にやってもらう前に、手動でメール(POP3)サーバにアクセスして試してみます。なおPOP3コマンドはwww.atmarkit.co.jpさんのWebに詳しく書いてあります。

[POP3 サーバにtelnetで接続してメールを読み込む]

telnet POP3サーバアドレス 110  

Connected to mail.hogehoge.co.jp.
Escape character is '^]'.
+OK Hello there. <24680.1326193375@mail.hogehoge.co.jp>

USER ユーザー名 

+OK Password required.

PASS メールパスワード 

+OK logged in.

STAT                   ;メールの数とサイズを尋ねる。 

+OK 2 2632            ;2通あることがわかります。 

RETR n                 ;n番目のメールを表示する。 
 
+OK message follows 
 Return-Path: baz@foobar.co.jp
Received: from deredere006.hogehoge.co.jp (LHLO deredere006.hogehoge.co.jp)
 (118.23.178.10) by daradara001.hogehoge.co.jp with LMTP; Tue, 10 Jan 2012
 19:23:01 +0900 (JST)

        ・・・ 以下内容表示 ・・・
        
QUIT                   ;通信終了 

+OK Bye-bye.
Connection closed by foreign host.

私のプロバイダのPOP3サーバでは、このようなやり取りになりました。黒字はPOP3サーバが表示した文字ですが、POP3サーバの種類によって異なる場合があります。さてさて手動では問題なくつながりました。でも、これからどうしたものでしょう。今回も諸先輩の知恵をお借りしました。

そこで、ようやくみつけたのがこのMy Open Source Projects さんのArduino POP3 Email Checker  です。(Thx Mr. Torchris!!)

こちらの作品は、LEDを使ってメールの数を知らせていますね。さすがです。でも、私は当初の予定通りシリアルモニタに表示させるだけにして置きましょう。実を言うと、ここにたどり着くまでに精魂使い果たしてしまいました。もう、余力がありません。ほんとです。

こちらに書かれていたコードを見て、おぼろげながら分かってきました。POP3サーバから表示されるデータは全部POP3コマンドを送信してから取り込めばよいみたいです。この参考スケッチではQUIT(終了)まで指示を行った後にデータを取り込んでいます。

だいたい理解できました、この作者が参考にしたお手本を元にしてスケッチを作ります。ほぼそのまんまです。

/* 
  Simple POP3 Email Checker
  Arduino 1.0 version
 */
  
#include <Ethernet.h>
#include <SPI.h>
 

 byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
 byte ip[] = { 192, 168, xxx, xxx };     // Arduino EtherShield IP address
 byte gateway[] = { 192,168, xxx, xxx };  // Default Gateway IP address
 byte subnet[] = { 255, 255, 255, 0 };  // Subnet Mask
 
 byte server[] = { xxx,xxx,xxx,xxx };    // POP3 server address
 
 EthernetClient client;
 long updateTimer;
 boolean clientConnected = false;

void setup()
{
   Serial.begin(9600);
}
 
void loop()
{
  if ((millis() - updateTimer) > 10000)
  {
    Ethernet.begin(mac, ip ,subnet,gateway ); //Arduino 1.0 see http://arduino.cc/forum/index.php?topic=83800.0
    
    delay(1000);
 
    Serial.println("connecting...");
 
    if (client.connect(server, 110))        //POP3 port 110
    {
       Serial.println("connected");
       client.println("user  ユーザー名");
       client.println("pass  パスワード");
       client.println("stat");
       client.println("retr 1");
       client.println("QUIT"); 
       clientConnected = true;       
                                                   // **** (2) **** 
     } else {
       Serial.println("connection failed");
     }
     updateTimer = millis();
  }

  if (clientConnected)
  {
     if (client.available()) 
     {                    
       char c = client.read();                    // ***** (1) *****
       Serial.print(c);                           // ***** (1) *****
      }

      if (!client.connected())
      {
      Serial.println("disconnecting.");
      client.stop();
      clientConnected = false;
     }  
   } 
}
 

まず試しに、上記のスケッチでメールの数と、1番目のメールを表示させることができました。

これで、サーバから受け取ったすべての文字の表示をすることができました。さて、STATで表示されるメール数を取り出すにはどうすればよいでしょうか?

こちらもいろいろ検索してわかりました。find()関数parseInt()関数を使って取り出します。先程の例で、サーバから送られてくる文字列は以下の通りです


Connected to mail.hogehoge.co.jp.
Escape character is '^]'.
+OK Hello there. <24680.1326193375@mail.hogehoge.co.jp>
+OK Password required.
+OK logged in.
+OK 2 2632               ;この2をゲットしたい

・・・

ストリームクラスで使うfind()関数ですが、この場合ちょっとだけ工夫が必要です。4番目の”+OK”にヒットさせてparseInt()関数でメールの数を取り込みますが、今回は同じ文字列が複数あるので2段階にしなければなりません。


       if ( client.find("+OK logged in."))
       {
         client.find("+OK ");
         int count = client.parseInt(); 
         Serial.print(" Your mail = ");
         Serial.println(count);       
       }

(****** (1) ***** の場所を書き換えます)

これで良いはずだと思っていたのですが実際動かしてみると、うまくいきませんでした。結局のところ、理由不明ですがfind()関数を使う前にディレイを入れないと動かない事が分かりました。 苦労をしたので、この事を発見した時は少し涙が出てきてしまいました。この事象はArduino 1.0 に限った、特有の事かもしれません。

    delay(1000);       //この数値が適切か否かはわかりませんが、必要でした

(****** (2) ***** の場所に書き加えます)

ようやく完成しました。(・・・・と、喜んでいたのですが、しばらく動かしていると止まってしまいます。残念。原因が分かりません。前途多難です。)

Ethernet Shield メール送信

メール...です

思わぬ伏兵にやられそうになってしまいましたが、気を取り直して再び前進です。TCPを使ってwebサーバと通信ができましたので、今回はArduinoからメールを送信する実験です。

私たちがメールを送る時、その作業はメールソフトがやってくれるので、普段は気に留めることもありません。しかし、今回はArduino君にやってもらうので、その前に手動で試してみます。

プロバイダによっては流儀が違って、この方法ではメールを送れないかもしれません。私は自宅でメールサーバを運用しているので、そちらで試してみました。

[SMTP サーバにtelnetで接続してメールを送る]

telnet  SMTPサーバアドレス  25


HELO クライアントドメイン 
MAIL FROM:送信元メールアドレス 
RCPT TO: 送信先メールアドレス 

DATA
Subject:題名 
From: 送信元メールアドレス 
To:   送信先メールドレス 
本文 
.
QUIT

このような順番で通信です。さっそく自宅にあるDebian LinuxPCのターミナルから試してみましょう。

$ telnet mail.hogehoge.co.jp 25

Trying 123.xxx.789.101...
Connected to 123.xxx.789.101.
Escape character is '^]'.
220   mail.foobar.com ESMTP Postfix (Debian/GNU)
HELO foobar.co.jp
250 mail.foobar.co.jp
MAIL FROM:baz@foobar.co.jp
250 2.1.0 Ok
RCPT TO: hoge@hogehoge.co.jp
250 2.1.5 Ok
DATA
354 End data with <CR><LF>.<CR><LF>
Subject:test
From: baz@foobar.co.jp
To:   hoge@hogehoge.co.jp
Hello world.
.
250 2.0.0 Ok: queued as CE7AE57054D
QUIT
221 2.0.0 Bye
Connection closed by foreign host.

やりました、ちゃんと送信できました。さて、先日のEthernetClient()を元にしてスケッチを作ってみましょう。Arduino 1.0 の環境で動かします。

/* 
  Simple SMTP Email Sender
  Arduino 1.0 version
 */
#include <Ethernet.h>
#include <SPI.h>
 

 byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
 byte ip[] = { 192, 168, xxx, xxx };     // Arduino EtherShield IP address
 byte gateway[] = { 192,168, xxx, xxx };  // Default Gateway IP address
 byte subnet[] = { 255, 255, 255, 0 };  // Subnet Mask
 
 
 byte server[] = { xxx,xxx,xxx,xxx };    // SMTP server address
 
EthernetClient client;
 
void setup()
 {
   Ethernet.begin(mac, ip ,subnet,gateway  ); //Arduino 1.0 http://arduino.cc/forum/index.php?topic=83800.0
   Serial.begin(9600);
 
  delay(1000);
 
  Serial.println("connecting...");
 
  if (client.connect(server, 25)) {       //port 25
     Serial.println("connected");
     client.println("HELO foobar.co.jp");
     client.println("MAIL FROM: baz@foobar.co.jp");
     client.println("RCPT TO:  hoge@hogehoge.co.jp");
     client.println("DATA");
     client.println("Subject:test");
     client.println("From:  baz@foobar.co.jp");
     client.println("To:    hoge@hogehoge.co.jp");     
     client.println("Hello world.");
     client.println(".");          
     client.println("QUIT");          
     client.println();
   } else {
     Serial.println("connection failed");
   }
 }
 
void loop()
 {
   if (client.available()) {
     char c = client.read();
     Serial.print(c);
   }
 
  if (!client.connected()) {
     Serial.println();
     Serial.println("disconnecting.");
     client.stop();
     for(;;)
       ;
   }
 }
 

例によってMACアドレスがDE:AD:BE:EF:FE:ED (Dead Beef Feed 「死んだ牛のえさ?」)になっていますが家庭内LANに接続する分には問題ないでしょう。このまま続行です。IPアドレス、デフォルトゲートウエイ、サブネットマスクは適切な値にセットします。SMTPサーバのIPアドレスも調べてセットです。果たして実行結果は?

やりました。ちゃんと送信することができました。

Ethernet Shield Arduino 1.0 大はまり

Etherenet Shield from ebay

段々とArduinoの深みにはまって来た私です。さてさて、良い獲物を見つけてしましました。「Ethernetシールド!!」です。早速調達です。

純正品を購入するか否か迷ったのですが、結局ebayから互換品を注文することにしました。検討の結果「Ethernet Shield W5100 For Arduino 328 UNO Mega 2560」と表示されていた品物を「beauty.2011」という香港の業者に発注しました。金額は送料込みで$23.5でした。

今回発注したものはWiznet W5100 というチップが乗っていて、Arduinoのオフィシャルライブラリが使えるとWebに記述があります。同じ互換Ethernetシールドでも ENC28J60チップが乗っているものは少し安く買うことができます。しかし、使う事が出来るライブラリが異なるみたいでした。これを選んで正解だったと思います。

その時点で純正のEthernetシールドが$45でしたので、今回購入価格は純正品のだいたい半分の値段です。値が安いというのは非常に良い事ですが、その反面ちゃんと動くか否か一抹の不安があります。

さて、現物が到着してさっそく実験です。Arduino 1.0の環境でテストを行うことにしました。「File」-「Example」-「DnsWebClient」の順に選択して、スケッチをロードしました。このスケッチはグーグルのサーバにアクセスして “arduino”の検索結果をシリアルモニタに表示させるプログラムです。新規購入のEhternetシールドの動作確認にはもってこいですね。

スケッチ中の注釈を読むと、新型純正品のEthernet ShieldにはMACアドレスが書かれたステッカーが貼られていると書かれています。今回購入したEthernet shieldには残念がらMACアドレスはついていませんでした。きっと登録作業がされていないのでしょう。

まぁ、今回は特に何も影響が無いので例題のまま”00:AA:BB:CC:DE:02″を、使うことにします。でも仮に、もう一つのEthernet シールドを同一ネットワークで使用するときには、このMACアドレスに注意をしなければなりません。あまり関係はないですが、調べたところ上位3オクテットで表現される“00:AA:BB”のベンダーは登録されていませんでした。

驚くべき事に、スケッチの中身を見てみるとIPアドレスを設定する箇所がありません。Arduino自身のIPアドレスはDHCPから受け取って設定し、宛先のwebサーバ(www.google.com)のIPアドレスもDNSサーバから引いて来るようです。恐るべし!ですね。

早速スケッチをアップロードして、走らせてみます。シリアルモニタを開いてみると、ちゃんとwww.google.comにつながって、データを読んできました。良かったです、この購入したEthernetシールドは、ちゃんと使えるようです。

ここまでは順調だったのですが、ここからが大はまりでした。

続いて、本家のリファレンスにあるEthernetClient()を元にDHCPを使用しない設定を試してみました。レスポンスが早くなり、メモリも節約できるはずです。先ほどの例文とほとんど同じですが、今度はDHCP及びDNSを使わないで通信します。

まず、スケッチ中のグーグルwebサーバのIPアドレスが異なっていたので正しいアドレスに変更します。あと、IPアドレス等を、私の家の環境にあわせセットします。

byte server[] = { 74, 125, 235,176 }; // Google IPアドレス変更
 

 byte ip[]      = {192, 168, xxx, xxx };    ArduinoのIPアドレスに変更
 byte gateway[] = {192 ,168 ,xxx, xxx};     デフォルトゲートウエイを追加
 byte subnet[]  = {255,255,255,0};          サブネットマスクを追加
 
 Ethernet.begin(mac, ip );                  gatewayとsubnetを書き加える   
 

修正した後のスケッチ 

#include <Ethernet.h>
#include <SPI.h>
 

 byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

 byte ip[] = { 192, 168, xxx, xxx };
 byte gateway[] = {192,168,xxx,xxx};
 byte subnet[] = {255,255,255,0};
 
 
 byte server[] = { 74,125,235,176}; // www.google.com
 
EthernetClient client;
 
void setup()
 {
   
   Ethernet.begin(mac, ip, gateway, subnet);
   
   Serial.begin(9600);
 
  delay(1000);
 
  Serial.println("connecting...");
 
  if (client.connect(server, 80)) {
     Serial.println("connected");
     client.println("GET /search?q=arduino HTTP/1.0");
     client.println();
   } else {
     Serial.println("connection failed");
   }
 }
 
void loop()
 {
   if (client.available()) {
     char c = client.read();
     Serial.print(c);
   }
 
  if (!client.connected()) {
     Serial.println();
     Serial.println("disconnecting.");
     client.stop();
     for(;;)
       ;
   }
 }

さて、万全の自信を持ってスケッチを実行してみます。が、残念ながら期待通り動きません。

[シリアルウインドウ]

 
connecting...
connection failed

disconnecting.

何度やっても connection faild です。リセットをかけてもだめ、何をやっても全然だめです。いろいろやってみましたが外部のサーバを参照することができません。(ローカルは可)

ルータをいじって、デフォルトゲートウエイを変えてみたり、サブネットマスクの値を変えてみたりしましたがだめでした。どうやらgatewayとsubnetを指定するとだめみたいです。

散々時間がかかった後、ようやく答えを見つけました。

0022  Ethernet.begin(mac, ip, gateway, subnet); 
1.0   Ethernet.begin(mac, ip, subnet, gateway); 

リファレンスにも載っていないのですが、Arduino 1.0 ではgatewayとsubnetの記述する順番が逆になっている模様です。

続-ガイガカウンタ・簡易モニタリングポスト製作日記(5)

ヒューズビットの書き込みです

ヒューズビットの書き込みです

  • Program
  • さて、作成したプログラムが良さそうなので書き込みを行います。新品のATmega168PをArduinoボードにセット、ISPコネクタにAVRISP mkIIをつなぎ、双方を通電します。さて、肝心の出来あがったhexファイルはどこにあるのでしょうか。Windowsの「プログラムとファイルの検索」から検索すると

    …\AVRStudio\プロジェクト名\プロジェクト名\Debug\プロジェクト名.hex

    このようなPATHにて作成されていました。

    先日ArduinoのBootloaderを書き込んだ時のように「Tools」-「AVR Programming」の順に進みます。[Flash]の所に先ほど検索したファイルを指定してプログラムを書き込みます。

    「Program」のボタンを押すと、Feifying Flash …OKの表示が出ました。ちゃんと書き込みできた様です。

    さて次はFuseビットの書き込みです。はっきり言って良く分かりませんでしたが、ATmega168Pは新品の時は内蔵RC発信1MHzで動いているという情報は得ていました。

    今回、私は内蔵RC発信を使用して8MHzで動かす予定です。CKDIV8にチェックが入っていましたので。ここのチェックを外し、FusesビットをProgramしました。

    高圧電源モジュールは7.5cm×4.5cmのユニバーサル基盤上に、0.26mmのジュンフロン線で配線しました。私には細すぎです。ニッパで被覆を剥がずのが大変でした。

    ここだけの話ですが、慎重にに間違えなく配線しつもりだったのですが、1か所不手際があり、最初動作しませんでした。原因を探すのにかなり手間取ってしまいました。

    2回目の製作は総額で初回製作費の倍ほどかかってしまいましが、授業料ということであきらめましょう。

    ようやく完成しました

    ようやく完成しました

    続-ガイガカウンタ・簡易モニタリングポスト製作日記(4)

    良く分かりませんが、とりあえずプロジェクトを作成します

    良く分かりませんが、とりあえずプロジェクトを作成します

  • AVR Studio 5
  • プログラムを組みましたので、次の段階にはいります。使用方法も良く分かりませんが、AVR Studio5を起動します。最初に行わねばならない動作はきっとNew Projectを作る事でしょう。「File」-「New」-「Project」の順にすすみます。するとポップアップウインドウがでてきました。分からないことだらけですが、勘を働かせドンドンドンすすんでいきます。

    [Installed Templates] の項は “AVR GCC” ,”AVR Assembler”及び”AVR Studio Solutino”の選択肢がありますが、今回は”AVR Assembler”をクリックします。プロジェクトの名前欄に任意の名前を入力し[OK]をクリックます。続いて今回使用するマイクロコントローラの型番を入力しました。今回私は”ATmega168P”です。いよいよソースコードを打ち込む段取りになりました。間違えないように打ち込んでいきます。はい、打ち終わりました。

    さて、続いてどうすればよいのでしょうか?いろいろとメニューがあって迷ってしまいそうですね。画面上はカラフルなボタンがたくさんあって、結構にぎやかです。どうせ多少の事をやってもPCが壊れることはないでしょう。適当にボタンを押しまくりましょう。今ならちょうど誰も見ていませんし。

    とは言ったものの、「適当にボタンをクリックしていたら、いつの間にか出来あがっていた」では再現性が大きく欠けてしまいますね。危ない危ない。今回はぎりぎりのところで踏みとどまる事ができました。少し冷静になって作戦を立ててから先に進むことにしましょう。

    メニューの項目を見てみると左から「File」「Edit」「View」「VAssistX」「Project」「Build」「Debug」「Tools」「window」「Help」の順になっています。まぁ、次は「Build」「Debug」あたりが妥当な所でしょう。

    「Build」を見てみますとプルダウンメニューに[BuildSolution]という項目と[Buildプロジェクト名]という項目がありました。どちらを選べば良いか全くわかりません。でも、[BuildSolution]のほうはF7キーが割り当てられているので、きっとメインストリームでしょう。私は初心者ですから、無難なこちらを選びましょう。「寄らば大樹の陰」です。F7キーを押します。

    すると下の方の画面が変わり、Error Listが出てきてしまいました。良く見るとソースコードを打ち間違えていました。タイポでした。間違えた所を訂正して再びF7キーを押すと今度は、だらだらと表示が出て最後の行に

    Build succeeded.
    ========== Build: 1 succeeded or up-to-date, 0 failed, 0 skipped ==========

    やりました。succeedっては、いい響きですね。どうやら出来た様です。でも、出来あがった物がどこにあるか分かりません。どこかに16進数で記述されたATmega168Pネーティブの機械語ファイル(hex)があるはずです。まぁ、後ほど検索をかけて見つけることにしましょう。

    それよりも私はメニューの項目に「Debug」の文字があったことが気になりました。以前どこかでデバッガという言葉を聞いたことがあります、プログラム中にブレークポイントを設定したり、1ステートメントずつ実行させたりする代物でした。

    シュミレーションです

    シュミレーションです

    ちょっと試してみましょう。新たな発見があるかもしれません。「Debug」のプルダウンメニューから[Start Debugging and Break] (Alt+F5)を実行します。すると[Select Debug Tool]というタイトルのポップアップウインドウが出てきました。”下からtoolを選べ”と書いてあり、「AVR Simulator」のみ選択可能な状態です。どうやらこのAVR Studioはマイクロコントローラをシュミレートして動作確認ができるみたいです。

    その後、いろいろと探索をして次の事柄を発見しました。

  • debugのスタート、ストップ、コンテニュー、シングルステップ(2種類)がある
  • debugがスタートしていない状態の時に、各ステートメントの左端の部分をクリックするとブレークポイントを作成できる。
  • debugをスタート、又はコンテニュー、シングルステップ動作をしたときにIO view とProcessor viewを出すことができる
  • IO Viewではポートの状態を見ることができる
  • proseccor viewでは 動作スピード(Frequency)を変えることができる,Stop Watchで経過時間を測ることができる、さらにレジスタの値も見ることができる
  • CPUの状態、経過時間がわかります

    CPUの状態、経過時間がわかります

    他にも多数の機能があるみたいですが、今回はこれ位で十分です。目的とするパルスのタイミングがわかりそうです。助かりました。早速ブレークポイントを設定してシュミレートしてみましょう。設定する場所はRCALL T62uS、RCALL T938uSの2か所のステートメントで良いでしょう。

    debugをスタートすると、[Processor View]中の”Frequency(動作速度)”が1.000 MHzになっていますので、ここをクリックして8.000MHzに書き換えました。

    スタート直後は.csegの次の一番最初のステートメントで実行が止まってます。[Processor View]の”Program Counter”は0、”Stop Watch”も0.00μSを表示しています。”Registers”の前の+をクリックするとR16の状態を見ることができます。[IO View]では”PORTB”をクリックして選択しておきました。

    さて続いてF5を押すか画面上の緑右矢印ボタンを押してコンテニューさせます。最初のブレークポイントまで進んできました。このプレークポイントの命令、サブルーチンコールはまだ実行されていません。Stop Watchを見てみると0.88μSという表示です。初期設定におおむね0.88μ秒かかりました。

    同様にして時間を測り、パルスのON時間62.75μS、OFF時間939.37μSを得ました、合計で1002.12μSですから周波数に直すと0.998KHzです。出力PORTに設定したPB3もちゃんとON、OFFしています。目標とした時間からは多少誤差がありますが、ガイガー管の動作電圧範囲は広いのできっと大丈夫でしょう。

    続-ガイガカウンタ・簡易モニタリングポスト製作日記(3)

    この様な流れでしょうか


    ハードの方はめどがたちましたが、さて問題はソフトです。全ての処理を1つのマイクロコントローラに任せるプログラムを書くのは相当高度なテクニックが必要そうですが、今回は豪華に2つ使うことにしました。まるで大名のような贅沢ですね。いや、ひょっとするとそれ以上かもしれません。放射線のカウント、表示の処理は「ちびでぃ~の2」にまかせて、もう一つはパルス発生だけに専念します。これなら初心者の私でも何とかなりそうです。

    e-電子工房さんのサイトを見ると400Vの場合、1KHzの周期でパルス幅が大体62n秒であれば良いことがわかります。まったくもって貴重な情報を公開していただき本当にありがとうございます。今回はアッセンブラでプログラムを作り、秋月電子通商から仕入れた新品のATmega168Pへ書き込みます。

    当然のことながらAVRのアッセンブラも初めて触る私です。Nの電子講座・AVRマイコン編AVRマイコンで学ぶ コンピュータの仕組みのサイトに詳しく記述されていましたので勉強させていただきました。ありがとうございました。今回は特に小山さんが書かれた「AVRマイコンで学ぶ コンピュータの仕組み」から、ソフトウエアタイマー “blink.asm”の項を参考にプログラムを組ませていただきました。本当にお世話になりました。

    フローを考えると次のようになります

    スタート–>初期設定–>①–>1を出力する–>62μS待つ–>0を出力する–>938μS待つ–>①へジャンプ

    前述のBlink.asmを参考にコードを書いていきます。特に変える必要もなさそうなので、出力ポートも同じPB3にさせていただきました。

    GeigerClock.asm
    
     .include "m168Pdef.inc"
     .cseg
    	LDI	R16,0b00001000
    	OUT	DDRB,R16		;PB3は出力,他は入力
    
    	LDI	 R16,HIGH(RAMEND)	;RAM最終アドレス上位を取得
        	OUT	 SPH,R16		;スタック ポインタ上位を初期化
    	LDI	 R16,LOW(RAMEND)	;RAM最終アドレス下位を取得
        	OUT	 SPL,R16		;スタック ポインタ下位を初期化
    
    LOOP:
    	LDI	R16,0b00001000
    	OUT	PORTB,R16		;PB3は1, 他は0
    
    	RCALL	T62us			;62μ秒待つ
    
    	LDI	R16,0b00000000
    	OUT	PORTB,R16		;PB3は0, 他も0
    
    	RCALL	T938uS			;938μ秒待つ
    
    	RJMP	LOOP			;LOOPの箇所にジャンプ
    
    

    62μSと938μS待機するサブルーチンを作成します。ATMEGA168Pを8MHzのクロックで動作させて1クロックサイクル=0.125μSで計算します。62μSは50μs+12μSで、938μSは50μSを18回繰り返し、さらに+38μSとすれば大体良さそうです。コメントに書いてある数値、計算は参考にさせて頂いた「AVRマイコンで学ぶ コンピュータの仕組み」サイト中に丁寧な説明があります。

    
    ; timer subroutine
    T50US:			;((3)+1+5*78-1+4)*0.125=397*0.125=49.625μ秒
    	LDI	R20,78	;1 以下を78回繰り返す
    _TUS:
    	NOP		;1
    	NOP		;1
    	DEC	R20	;1 R20から1を減じ
    	BRNE	_TUS	;1/2 結果が0でなければ_TUSへ
    	RET		;4
    
    T62us:			;((3)+397+1+8*12-1+4)*0.125=500*0.125=62.5μ秒
    	RCALL	T50US	;397
    	LDI	R21,12	;1 以下を12回繰り返す
    _T12US:
    	NOP		;1
    	NOP		;1
    	NOP		;1
    	NOP		;1
    	NOP		;1
    	DEC	R21	;1 R21から1を減じ
    	BRNE	_T12US	;1/2 結果が0でなければ_T12USへ
    	RET		;4
    
    T938us:			;((3)+1+400*18-1+1+8*38-1+4)*0.125=7510*0.125=938.875μ秒
    	LDI	R21,18	;1 以下を18回繰り返す
    _T900US:
    	RCALL	T50US	;397
    	DEC R21		;1
    	BRNE	_T900US	;1/2 結果が0でなければ_T900USへ
    
    	LDI	R21,38	;1 以下を38回繰り返す
    _T38US:
    	NOP		;1
    	NOP		;1
    	NOP		;1
    	NOP		;1
    	NOP		;1
    	DEC	R21	;1 R21から1を減じ
    	BRNE	_T38US	;1/2 結果が0でなければ_T38USへ
    	RET		;4
    
    

    うまく動くでしょうか????

    AVRISP mkII とAVR StudioとArduinoIDE

    AVR Studio5を使って書き込みます


    Arduino初心者の私ですが、AVRISP mkIIを購入しましたので、早速、新品のATMEGA328P-PUにArduinoのブートローダーを書き込んでみました。

    まず、ATMEL社のWebよりAVR Studio5をダウンロード、そしてインストール。続いてAduinoボードから現在動作しているATMEGA328を、足を曲げないよう丁寧に取り外し、新規に購入したATMEGA328に装着し直します。AVRISP mkIIをISPコネクタにつなぎ、さらにUSBケーブルでPCに接続します。Arduinoボード本体も電源を入れます。

    AVR Studio5を起動して「Tools – AVRprograming」の順に進み [Tool]欄が”AVRISP mkII”, [Device]欄が”ATmega328P”,[Interface]欄が”ISP”になるようにセットして「Apply」ボタンをクリックします。その後表示された「Interface settings」メニューをクリックすると、書き込みスピードの設定画面になります。ここはデフォルトのまま125KHzにしておきました。

    さて次は”Arduino bootloader”の指定です。やはり左のメニューから「Memories」をクリックして、[Flash]欄に適正なHexファイルを指定します。最後に「Program」ボタンをクリックで書き込むことができます。その後メニューの 「Fuses」 をクリックしてヒューズビットを書き込みました。

    今回私は 
    arduino-1.0\hardware\arduino\bootloaderes\atmega\ATmegaBooT_168_atmega328.hex を書き込んでみました。

    書くと簡単ですが、私が上記の手順を発見するまで結構時間がかかってます。(….半日ほど)でも、実際の書き込み作業は数秒で終わり、まったくあっけないです。

    果たして生ATMEGA328はArduinoの動作をはじめました。もう、私は得意満面です。

    ところが、です。今度はAduinoIDEから同様に書き込もうとしましたが、何回やってもエラーが出てうまくいきません。原因を調べたところ。ここに回答が載っていました。

    AVR StudioとArduinoIDEは、同時にこの機能を使うことはできないみたいです。具体的にはAVR Studioが使うAVRISP mkII用のUSBドライバとArduinoIDEが使うAVRISP mkII用のUSBドライバが違う物で、共存できないとのことでした。

    そういえば、AVR Studio5をインストールするときに”USB なんたら jungo driver をインストールするか?”との表記があったような気がします。 「当然でしょう!」と悪態ついた事を思い出しました。

    ArduinoIDE用のAVRISP mkII用USBドライバは上記フォーラム中に書いてありますが、

    ..\arduino-XXXX\hardware\tools\avr\utils\libusb\bin 以下のディレクトリに入っていました。

    ArduinoIDEの1.0版では、Fileメニューに「Upload Using Programmer」の項目があります。試してみるとブートローダだけでなく、スケッチもAVRISP mkII経由で書き込みができました。すごいですね、Arduino!

    続-ガイガカウンタ・簡易モニタリングポスト製作日記(2)

    AVRIPmkII  (買ってしまった.....)

    AVRIPmkII  (買ってしまった…..)

  • お買い物
  • さて、もう1台ガイガーカウンタを製作するのですが回路をどうするか?です。一番簡単な方法は、先日の「ちっちゃいものくらぶ」さんが出しているガイガーカウンタキットの「ガイガー菅無し」のセットを購入することです。6500円と値段も手ごろですし、こちらは前回製作の実績もあります。問題が生じる余地がありません。

    しかし、私は丁度ガイガーカウンタの動作原理がわかって有頂天になっていた所でしたので「Arduino + 高電圧ユニット」という組み合わせで作る、イバラの道を選択しました。

    さっそく、これまた「ちっちゃいものくらぶ」さんのちびでぃ~の2というArduino互換キットを注文いたしました。このちびでぃ~の2は LCDまで付ているフルセット版が1500円、基本セットが1000円という低価格です。電源レギュレータICがないので7~12V電源は使えませんが、それにしてもすばらしい商品です。

    続いて、ガイガー管の高電圧ユニットですが、こちらはネットで検索してもなかなか良いものがみつかりませんでした。仕方なく部品を集めて組むことにします。検索するとタイマーICを使った回路図や特殊なトランスを使用した回路図が発表されています。しかし、いずれも電圧の調整が必要みたいです。情報では、内部抵抗の関係で、普通のテスタではガイガー管にかかる電圧を測る事ができないそうです。電圧がわからなければ、それを調整する手立てがありません。

    ものは試しに、手持ちのSBM-20の回路を測ってみることにしました。私の安物テスターの内部抵抗はわからないのですが、そんなことはかまわず実験です。測定してみるとやはり結果が変です。400V程度あるはずなのですが、一桁たりない数値です。

    WEBでは高い数値の抵抗で分圧して計測する方法もかかれていましたが、費用がかかりそうです。調整なしで400Vを発生できる方法を懸命に検索しました。その結果e電子工房さんの「ガイガーカウンタ用高電圧電源(CK1026,SBM20,J408γ用回路」に、ようやくたどりつくことができました。e-電子工房さん、大変ありがとうございます。感謝します。

    入手しやすい部品のみで構成されていて、パルス幅で電圧を制御するので、こちらに書かれている定数で部品を組み立てれば、きっと目的の電圧になるはずです。問題はパルスを発生するPICです。PICとはマイクロチップ・テクノロジー社が作っているマイクロコントローラです。秋月電子通商の広告では良く目にしますが、残念ながら私は現物を見たことがありません。PICを使って作るとなるとプログラムを焼くPIC用のプログラマをも購入せねばなりません。

    考えに考え抜いた結果、上記で使われているPICチップをAVRのATMEGA168に置き換えることにしました。2足のワラジをやめてAtmel AVR1本に絞ります。部品は秋月電子通商、千石電商、鈴商、以上3店ですべて揃いました。秋月電子では3000円という安い値段でしたので、「ATMEL AVRISPインシステム・プログラマー AVRISPmkII」 まで買ってしまいました。結局買うことになるんですね、プログラマは。

    通販で購入したのですが、いろいろと欲望がふくらんで、不必要なものまで買ってしまったようです。(勢いで秋月電子ATmega168/328マイコンボードキットまでも買ってしまった…)自宅のPC前に座っているはずなのに、なぜか気分的には鉄火場にいるように熱くなっています。あたかも何かに憑かれたようにクリックが止まりません。ショッピングカートの品物がどんどん増えていきます。知らないうちに購入金額は福沢諭吉先生一人では納まらなくなってしまいた…. もう、失敗はゆるされません。