2017年2月
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28        

Amazonウィジェット

  • miniPC
  • 最近買った本
  • Raspberry Pi
  • クアッドコプター
  • 書籍ランキング

AdSense

  • 広告
無料ブログはココログ

AVRマイコン

2015年4月28日 (火)

Arduino CuHead Wifi Shield for Arduino V2.0 (LinkSprite)の使い方

ArduinoのWifiシールドをAmazonで買って動かしてみた。
ドキュメントは英語ながら比較的わかりやすかったが、色々引っ掛かったのでシェアします。

環境
・ルーターのネットワークに接続元のPCがある場合を想定。
 接続はルーターに接続しているスマホでも可能。
・ArduinoUNOを使用(3.3V)
・ArduinoIDE1.0.6

参考資料
公式解説ページ
サンプルソースの有りかとインストールの仕方。図が一杯でよくわかる。
マニュアル 使い方編

CuHeadの使い方
このURLのマニュアルに沿って、サンプルコードをコンパイルして書き込むまでの手順をしらべた。

1.サンプルプログラムをダウンロード・解凍し
  librariesのフォルダに入れる。

  ただし、落としたままの長いファイル名ではIDEが認識できないので、
  フォルダの名前をCuHeadに変更する。

2.IDEを起動し、スケッチ⇒スケッチの例からCuHeadのWebServerを選ぶ。

3.そのままコンパイルを押す。
  マニュアルには「コンパイルできませんでも焦らないで」とある。。。
  先ほどのCuHeadフォルダのapps-conf.hを開き、
  APP_WISERVER
  をコメントアウトし、
  APP_WEBSERVER
  のコメントアウトを外し有効化。

4.するとコンパイルが通るようになる。
  しかし、このあとWifiネットワーク設定が必要。

次はこのマニュアルを参考にする。

1.マニュアルの13ページ目にIPやルータアドレスの設定をせよとある。

こんな風に設定した。

local_ip = 192.168.0.10 //Wifiシールドに設定する固定IPアドレス
gateway_ip = 192.168.0.1  //ルータのIPアドレス
subnet_mask = 255.255.255.0
ssid = AirPortxxxxx //ルータのSSID

2.セキュリティタイプの設定

 security_type = 3

 とすると、WPA2が選択される。

3.セキュリティパスフレーズの設定

セキュリティがWPA/WPA2を選んだ場合は
xxxにパスフレーズを入力。WEPの場合はその下のwep_keysにキーを入れる。

// WPA/WPA2 passphrase
const prog_char security_passphrase[] PROGMEM = {"xxxxxxx"};     // max 64 characters

4.wireless_modeの設定。今の場合、WIRELESS_MODE_INFRAのままでよい。

とりあえずのサンプルソース.ino
「ExampleWebServer.ino」をダウンロード

これを大きめのドローン(ARDroneやPhantom)に載せて飛べば、
ほしいデータを自由にワイヤレスで取得できる。
APIが公開されていない、改造が難しいタイプのドローンに役立ちそうだ。

2014年5月 1日 (木)

AVR デバッグのときだけdelay関数を無効化するフレーズ

タイミングがそれほど重要でないようなプログラムは、winavrライブラリのdelay関数をよく使うが、デバッグのときは非常に邪魔になる。そこで、デバッグのときだけマクロで弾くようにした。

ソースの冒頭部分にこれを置く。

#define _debug
#ifndef _debug #define F_CPU 8000000UL  // 8 MHz #include
  <util/delay.h> #else void _delay_ms(int n){} #endif

defineで_debugというラベルを定義すると、上記#elseのところにある偽者の_delay_ms関数が呼ばれるようになる。(※普通のマクロの使い方と何も変わらない。)ちょっと便利だと思ったのでメモしておいた。

2013年12月23日 (月)

AVRでプレステのコントローラを使えるようにする。SPIの使い方

AVRでPSパッドを動かす。

タンスやテレビ台の奥に眠っているSONYプレイステーションのコントローラ(以下PSパッドと記述)を、ロボットやオリジナル機器のコントロールに役立てようという企画。
実は過去にPICアセンブラでロボ用に作ったことがあるが、そのAVR版リメイク。
参考資料はこちら:”プレイステーション・PAD/メモリ・インターフェースの解析”より。

<<AVR動作環境>>
・Vcc=3.3V。 ☆PSパッドは3V動作。電源3.3Vで動かせばレベルシフタは不要。
・PSパッドから出るACK信号は使わず簡単に動かす。
・内蔵8MHzで動作。
・用意したPSパッドはPS1のもので、”HORIパッド”というやつ。

その他詳細
使ったチップはATmega328P。SPIもUARTも内蔵されている。8MHz内蔵クロックで簡単動作。コンパイラはWinAVR-20100110。開発環境はAVRstudio4(AVRSPImk2の付属CDのもの。)


まずパッドの標準仕様では、SPIクロックを250kHzに設定する。
SPIクロックの設定は、SPIの章のRegister Descriptionを参照。
内蔵8MHzだからfosc/32を選択する。パッドの信号を読むだけなら周波数が落ちる分には問題ない。手持ちのオシロが遅いやつなので、125kHzに設定した。
125kHzは内蔵8MHzをクロックを128分周すればよい。

SPR0、1はSPCRにあるが、SPI2XだけSPSRにあるので注意。コンパイラは設定レジスタにないビット名が間違って入っていてもエラーを出してくれない。

とりあえず規定のSPIのバイトを送ってみて、返答が来るか見た。ところがデータラインがギザギザしているし、GNDの浮いたプローブのようにいつまでもフラフラしている。

Ws000084
赤がAVRの出しているCLK信号。黄色がPSパッドから返ってくるはずのDATA信号。プラスマイナスに振れて、ちっとも振幅が出ていない。

資料をよく見ると、DATAはオープンドレインポートらしい。DATAにはプルアップ抵抗が必要だ。周波数が250kHzなので、大きな抵抗値にすると波形がなまってビットが読めなくなるので注意。5.1kΩあたりの小さい値にするのが無難。

データはLSBファースト。だからAVRデフォルトの設定ではパッド側で正しく認識されない。ビットオーダーを設定するのは、SPCRのDORD。

ビットオーダーを修正すると、データがパッドから返ってくるようになった。4,5バイト目にボタン情報が入る。何も押さなければ全てハイ。ボタンを押すと、対応するビットがローになる。全てのボタンを押してみると、L2ボタンだけが認識されていない様子。ボタンが利きにくいのかとも思ったが、L2ボタンはバイトの先頭のビットに出てくることから、クロックの位相が問題と判断した。参考資料ではCLKが出ていないときはハイとなっているためだ。

Ws000085
四角ボタンを押したときの波形。プルアップ抵抗は4.7kΩ。

Ws000086_2
これがプルアップ10kΩにした時の波形。ほとんど変わらないので、使えないこともないかなというレベル。部品がないときの参考になれば。

次に、
AVRが出すCLKはこのような条件を満たさなければならない。

・CLKが出ていないときはHi
・CLKの立ち上がりでデータ書き込み。

このクロックとサンプルタイミングの規定は最も大事なところ。これを正しく設定しなければバイトの端っこのビットが着実に拾えなくなってしまう。
When this is written to one, SCK is high when idle.から、CPOLを1にすればSCKアイドル状態でハイになることがわかる。

仕様書の中で、ちょっと見かけない単語を見つけた。
このあたりを誤解すると時間かかるので、図を見るのが一番早い。
"SPI transfer format"のFigure19-3と19-4

Ws000089

図の緑の矢印がLeading Edge。赤がTrailing Edge。黄色が読み取りタイミング。
Leading Edge:パルスの開始端
Trailing Edge:パルスの終端

のような感じだろうかと理解した前提で、CPOLが1ならクロックの開始はFalling。CPOLが0ならクロックの開始はRisingとなる。

CPHAは、ビットのサンプルをどのタイミングでやるかを規定する。資料から、クロックの立ち上がりでビットをサンプルしたい。
CPHAFunctionalityの表から、Leading Edgeのときにsetup。Trailing Edgeのときにsampleとなるほうを選ぶ。つまりCPHAは1。

Ws000087
全てのボタンが読めた時の波形。この波形はL2ボタンを押したところ。5バイト目のビット0が確かにローになっているのが確認できる。


次のステップ>>

USBシリアルでボタンのデータを読み出し、シリアル端末上に表示させる。

注意
USBシリアルケーブルの電源ラインをうかつにつないではいけない。3.3Vならば大丈夫だが、5Vラインが出ているとパッドを破壊してしまう。

AVR専用シリアル通信のライブラリを準備した。

デフォルトのボーレートは9600bps。

<<完成版>>
「PSpadReader.zip」をダウンロード
「SPItame.hex」をダウンロード

パッドのボタン情報が入った4、5バイト目のデータをそのままシリアル(9600bps)で取り出すことができるプログラム。ノータッチで0xFF。ボタンを押すと、押したボタンに対応したビットが0になる。

注意事項:
AVRstudioの最適化レベルによってwinavrのライブラリにあるdelay関数が誤作動することがある。変な動作をする場合はまずこれを疑い、どうしても変だったら最適化をレベル0にし、適当なウエイトを挿入できる関数を作って置き換える。

同じソースをコンパイルしてもdelay関数がバグると、ウェイトが短くなったり極端に長くなったりする。
☆コンパイルしなおした時に動かなかったときはこのHEXを試してください。

2013年10月 9日 (水)

ATmega328でADコンバータを使う。+距離測定センサを動かす。

ADコンバータを動かして、GP2D12の距離測定センサーの値を読み取る。

まずはソース
「ADconv.c」をダウンロード

PC0の23pinに、センサーの出力をつなぐ。
PB0から7に、センサーの値をそのままパラレルでポートに出力しているので、好きな桁にLEDをつなぐ。

電源を入れるとPORTBにつないだLEDが点滅し、そのあとセンサーの値にしたがってLEDの状態が変化する。

センサーに手をかざすとビットが変化する様子が見られる。


さらに、このソースを使えばUARTを使ってPCで値をよむこともできる。
「ADconv_withSci.c」をダウンロード

少し内容を解説
ADの結果は1バイトの16進数なので、これを10進数に変換する関数を用意している。

void bcd_conv(int digit){
    ad100 = digit / 100;
    ad10 = (digit % 100) / 10;
    ad1 = (digit % 10);
}


この関数で、百の桁はad100。十の桁はad10。にそれぞれ格納される。
0x30を足してUART送信することで、ASCIIコードの数字に変換する。

usart_tx(0x30 | ad100);

これでシリアル端末に3桁の数字が表示される。

2013年8月20日 (火)

AVRからI2CタイプのEEPROMを読む。

せっかくI2Cのプログラムが動いたので、実用的なサンプルを掲載。

I2C式のEEPROMを書き込み・読み込み。
まずはソース

「eeprom.zip」をダウンロード

解凍すると3つのソースファイルが入っているので、ローカルでプロジェクトを作成し、コンパイルされたし。

EEPROMtameshi.cが本体で、main関数が入っている。
動作確認用のLEDが点滅したあと、I2C動作を始める。

書き込み回数にも限りがあるので、1Byteずつライトする操作はコメントアウトされている。最初に動作を見る場合はコメントアウトを解除のうえ、RUNされたし。

そのあとは1Byteずつリード操作。
シリアルで受信したデータを読み取る。

I2Cについては過去の記事を参照されたし。
I2Cマスターの設定方法


2013年7月28日 (日)

AVRのI2C マルチバイト 連続送受信のやり方

I2Cでは、スレーブアドレスの後のリード・ライトを指定するビットで送受信を切り替えることができる。また、ACK応答かNOACK応答かをマスター側から指定することで、何バイト受信するかを指定することができる。

エレキジャック さんのページにあるI2C用プログラムをベースにマスター受信のプログラムを組み、これにUART送信機能を追記して受信データが見られるようにした。

<まずは1バイトの場合の動作>
I2Cのクロックは1バイトで9発出ている。最後の1発はACK・NACKの受信のために出ている。この例では1バイトだけマスター受信している。 1バイト目でスレーブアドレス+リードビットの0x41を送信し、2バイト目でスレーブからの0x30と、最後のクロックでビット1=NOACKがでている。






<マルチバイトの場合>

AVRでこんな使用のプログラムを組んだときの動作の様子。

マスター側
・マスター受信モード
・20バイトを連続受信する。
・受信バッファのデータを全てUARTで送信

スレーブ側
・20バイトをバッファに用意する。
・マスターに送信。パケットごとにバッファのアドレスをインクリメント





先頭はスレーブアドレスとWriteビット=0。続けてデータが0x30,0x31。。
それぞれのデータの後にACKがスレーブから返されて0が来ている。

ちなみにエレキジャックさんのサンプルプログラムを使ってマスター受信をするときは、I2CRead関数の引数に0を入れるとACK応答の受信。1を入れるとNOACK応答になる。



ここで注意

スレーブアドレスの設定に注意。 エレキジャックのサンプルソースのスレーブ側では、 I2CSIInit(BYTE adrs)で、adrs<<=1の操作をしている。 adrsで引数渡ししたものを左シフトした0x40が最終的なスレーブアドレスとして入力される。 マスター側では0x40を送る必要がある。 スレーブアドレスの設定に注意。

アドレスが間違っている場合は、1バイト目送信のときに9clk目でNACK=1が出るので直ぐにわかるはず。

ちなみにNACKが返ってきたときはこんな波形になってしまう。

I2c_erroravrmr_lpcst_1

クロックがLowのままになり、そこからハングアップする。







2013年7月17日 (水)

AVRでI2C(TWI)を使う 第三弾 マスター受信とスレーブ送信ペア

引き続き、マスター受信とスレーブ送信のプログラムをペアで製作した。
いままでで一番てこずってしまった。

まずはサンプル。
「i2c-masterReceiver_8MHz.c」をダウンロード
「i2c_slaveTransmitter_8MHz.c」をダウンロード


この記事に直接お越しの方は”第一弾のAVRでI2Cを使う マスター送信”からご参照ください。この記事は、最初の記事で作成したプログラムの改造の過程をメモしたものであり、ところどころ説明をはしょっている部分があります。


いくつかのつまずきポイントを下記にまとめた。

<マスター受信側>
・少し紛らわしいが、受信側といってもスレーブにスレーブアドレスを送信してからでないと、受信ができない。

・スタートコンディション、ストップコンディションを送る。

・データ受信の際に、ACK有りかNO ACKかで、受信を継続するのか終了するのかを分岐できる。これを意識して送信開始をセットしないと受信側で正しく受け取れない。特にTWSRを使ってチェックをしている場合はなおさら。

<スレーブ送信側>
・スレーブアドレスをセットし、スレーブモードで開始しておく。

・ACKかNO ACKかで、TWSRステータスコードが異なるので注意。



一通りやってみて最後まで上手くいかなかったのはマスターの受信側だった。
最初に書いたとき、ACKあり・なしの意味を考えずにやっていたら、返されるであろうステータスコードが違っていることに気づかず、間違った値をIf文に入れてしまった。このために、コードがあっているはずなのになぜ次の工程に進まないのかと悶々とした。
とりあえずTWSRのステータスコードのチェックを省いてみても良かったと思う。

ステータスコードの判定をなくしてしまえばACKあり・なしに関わらず受信動作を続けるので、リピート受信のためのコードを別に用意する必要がなくなって好都合。あまり厳密にエラーチェックをやってもすべきことはなかったのだから、最初から省略すべきだった。


スレーブ側ではステータスコードを読むことで次にすべき処理がわかるので、これを使って分岐処理を作れば見渡しやすいソースを書くことができる。

・TWCRにビットを立てて通信開始
・TWINTがセットされるのをポーリング
・ステータスコードを読む

この3ステップの処理単位を意識してコードを書いていけば良かった。



本稿のプログラム作成に当たって、ここのサイトが非常に役に立った。
エレキジャック”AVRのI2C”


実はWinAVRのマニュアルにもExampleソースコードが載っている。
MicrochipのEEPROMをコントロールできるようになっている。

Library ReferenceのDemo projectsにある、
Example using the two-wire interface (TWI)


2013年7月13日 (土)

AVRでI2C(TWI)を使う。 スレーブ受信プログラム

AVRでI2Cを使うシリーズ第二弾。スレーブ受信プログラムの作成。


まずはサンプルプログラム。
「i2c_slave_8MHz.c」をダウンロード



I2Cは手順が複雑なので、I2Cを使うのが始めての方は”第一弾:I2C マスター送信”を読んで基礎知識を蓄えてから読むことをおすすめします。

処理手順はマスター側とほとんど同じなので、違うところだけ設定や処理を変えてやれば受信側が完成する。

マスターと違うところは、
・スレーブアドレスの設定が必要
・スタート/ストップコンディションの送信および確認はスレーブにはない。
・スレーブアドレス+Read/Writeビットの、アドレスパケットを受け取りに成功したとき。データパケットの受信をした時。それぞれの工程で得られるTWSRの値は、マスター送信の場合と全く違う。

--- ---

まずはスレーブアドレスの設定から。

 

TWARにアドレスを設定する。これは自由に決められる。ただしLSBはTWGCEという 特殊なビットで、これが1にセットされているとスレーブアドレス0x00のジェネラルコール。つまりパソコンの世界でいうブロードキャストが送信されたと きに応答する設定になる。ジェネラルコールされたときの処理を書いていないとハングアップする危険があるので、LSBは0に設定しておこう。

--- ---

処理の流れ。

全て順調にいけば、図の赤丸に示す数値が工程実行の度にTWSRに返ってくる。

Avr_i2c__3


アドレスパケットを受信すると、TWSRには0x60が返される。そしてデータを受信すると0x80が返される。最後のストップコンディション受信で0xA0。




2013年7月 7日 (日)

AVRでI2Cを使う。 マスター送信側プログラム

I2Cを使うのがはじめての場合は、まずI2Cの通信規約について一通り読んだほうが良い。2本の通信ラインを複数デバイスで共有できるという特徴を持っているために、一対一の通信よりも複雑になっている。

AVRのI2Cについては国内外問わず、多数のHPでサンプルプログラムが公開されている。なかでも 「始める電子工作」さんにて公開されているサンプルが最もわかりやすかったので、まずはこちらのプログラムを使わせてもらって感じを掴むことにした。

サンプルプログラムを使わせてもらう際の注意。クロックの設定が違うと動かない。
このプログラムはAVR出荷時のFUSEデフォルト値で使うことが前提になっている。
書き込み時にFUSEを内蔵8MHzで1/8divを有効にする。

また、プルアップ抵抗をSCL、SCKのポートにつけることを忘れないこと。内蔵プルアップの設定はしていない。

↓の画面のように設定。

Ws000056

スレーブ・マスターを書き込んで数秒待つと 受信データは0xC0だからスレーブ側のPD6,7が点灯する。他のPDピンは全てLow。

動かしたときの動作。(動画をYouTubeで見る)

電源を入れて暫くするとマスターのLEDが1秒程度点灯し、消灯すると同時にスレーブ側が点灯して終了する。通信は一回しか行われない。

おかげさまで無事に動作することが確認できました!

--- --- ---

しかしながら、8MHz / 8 = 1MHzでは応用範囲が限られてしまうので、この記事で8MHzで動かせるように手直しをすることに。

仕様書を見ると、I2Cのビットレートは下記の式によって決まる。

Ws000055

たとえば、 20MHzで100kHzのビットレートを設定したければ、TWBRは23で、プリスケーラは4を入れる。
8MHzで100kHzなら、 TWBRは2で、プリスケーラは16を設定する。


サンプルプログラムの、

    TWBR = 0xFF;

を、下記のように書き換えることで、内蔵クロック8MHzで動かしたときに100kHzビットレートで通信することができるようになる。

    TWBR = 2;
    TWSR = 0x02;
    TWCR = 1<< TWEN;

以上でビットレートの設定は完了。

---

I2Cはたくさんのスレーブが接続されることが想定されているので、データ本体を送る前に送信先デバイスの指定。つまりスレーブアドレスを指定してやらねばならない。

そして、スレーブアドレスにつづく1ビットが重要。スレーブに対して次のパケットで送信したいのか受信したいのかを知らせるビットになっている。

本稿ではマスター送信プログラムなので、0をセットする。
そしてスレーブアドレスはb'1000000とする。

Avr_i2c__2

---

ここから先は手順が複雑になる。TWCRというI2C(TWI)のコントロールレジスタのビットの組み合わせで、I2Cポートの出力を工程に合わせて操作しなければならない。そしてその操作が成功してスレーブ側に届いたことをビットを読んで確認しなければならない。


これらの工程については、22.6 Using the TWI の図に載っている。そして詳細が英文でツメツメと書かれている。この辺りの字の細かい奴にいきなり取り掛かるより、その次のTable2にあるCコードを打ち込んでみたほうが速く理解できると思う。

途中STARTやらMT_DATA_ACKなどの謎の定数が出てくるが、これはさらに先のページにある、Table 22-2. Status codes for Master Transmitter Mode の数値である。

最初に読み込むのにお勧めなのは22.7.1 Master Transmitter Mode の部分。ここに略記号などの定義が書いてある。まずこれがわからないと本文を読んでも意味不明。

22.7.1項では、マスター送信モードの処理をどのような手順で進行するかが簡潔に書かれている。すごく複雑そうに見えるが基本的な手順は同じで、

・工程ごとに示された表にある値をTWCRレジスタに値を書き込む。
・その工程に対応した値がTWSRと同じかどうかでエラー処理に飛ぶか次の工程に進むか分岐する。

の処理が繰り返されているような感じである。


色々いじくりまわして完成したのがこのソース。
結局AVRの仕様書を元に一から作り直してしまった。
あとから見てもやってる内容が追えるように、コメント文、名前宣言、処理の流れ、ステップ番号は全て仕様書の表にある物に合わせている。

「i2c-master_8MHz.c」をダウンロード

・内蔵8MHzクロック(1/8 divはFUSEを外すこと)。
・実行確認デバイスはATmega328P。28ピンシリーズならば多分使えると思う。
・プルアップをSCL、SCKのポートにつけること。10kΩ。

念のためFUSEの設定画面を載せておきます。

Ws000057

PD6,7にLEDをつなぐと送信しようとしているデータが見られる。ソースでは0xC0だが、データを変えてみると動作が実感できる。データの送信はこの関数が行っている。この引数を変えてみればよい。

twi_send(0xC0);

PORTDの6,7ビット目がLEDに表示されるので、たとえば0x80とか0x40とかならばLEDの変化が楽しめる。

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

パーツ屋さんに足を運んでみたら、Raspberry Piの前に人だかりが!!
この本が一番見やすく、すぐ実践できるように書かれていました。
基板自体は3500円くらいから。

Raspberry Piで遊ぼう!

        林 和孝 ラトルズ 2013-05-20
        売り上げランキング : 9431
by ヨメレバ

2013年7月 3日 (水)

AVR書き込み器 AVRISPmk2 デバイス書き込み時の接続方法

書き込み器が幾ら純正で安心でも、コネクタからの配線を間違うとちっとも動いてはくれない。意外とつまずきやすいので写真つきで確実に再現できるようメモ。

書き込み器AVRISPmk2から出ているコネクタを、6ピンのピンヘッダなどに接続する場合に、どちら側から見たピン配置なのかに注意しなければならない。もし間違っても純正書き込み器はLEDが赤に点灯するだけで、ピン配を間違ったからといって潰れることはなかった。

28ピンデバイスは、このように接続する。

Avr_todevice

一列ピンヘッダに書き込み器からの配線を半田付けしておくと、ブレッドボードに挿して使う場合にとても便利。ピンヘッダの位置に合わせてデバイスを刺すだけで確実に書き込みができる。

Avr__2

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

レジスタをちょこちょこいじって設定するのが面倒になったらArduino。
簡単なAPIでサクッと試せる。

そしてこの本はお気に入り。
解説が丁寧で、オリジナル作品を作る際への応用が利く作例が多い。

ボクのArduino工作ノート

        鈴木哲哉 ラトルズ 2013-03-26
        売り上げランキング : 42028
by ヨメレバ

より以前の記事一覧