実 験           TOPページへもどる

1 プログラムライタによるSPI通信 05.06.19
2 tiny2313 USARTによる通信1 05.07.10 基本のみ.3つのコマンドに文字列を返す.
3 tiny2313 USARTによる通信2 05.07.14 2を MS Excel で通信する その1
4 tiny2313 USARTによる通信3 05.07.16 時刻の読み取りと設定 ハイパーターミナル
5 tiny2313 USARTによる通信4 05.07.17 時刻の読み取りと設定 Excel VBA
6 100円電卓のLCD 05.07.24 Tiny2313で表示する
7 DCモータを回してみる 05.08.30 
8 SSRによる電力制御 06.02.12 
9 SPI通信による7セグLEDアレイの表示 06.04.18 
10 時計モジュールを使ったRTC(tiny2313) 07.09.30 
11 実験用簡易可変電源 08.03.15 
12 J-FETによる定電流回路 08.03.16 
13 降圧型1.5V電源 08.05.04 
14 swによるLED制御 09.02.22 
15 hidmonによるデータ通信 10.03.12 
16 LCD用負電源装置 11.08.14 
---------------------------------------------------------------








16 LCD用負電源装置

5VLCDを3.3Vで表示するためには -1.5V 程度の負電源が必要です。
AVRポートの100kHz程度の矩形波出力からチャージポンプで負電圧を発生するモジュールを作りました。
1kΩの負荷で2.0Vが得られました。使えると思います。ダイオードをシリコンにすると-1.4V位になります。






15 hidmonによるデータ通信

HIDaspxをライタとしてターゲットに接続したときに、3本のポートがターゲットデバイスと繋がっています。この3本を使ってターゲットからPCにデータを転送する実験をしました。

HIDaspxはライタ/IOの切り換えスイッチがありますが、ライタ接続のままでもこのケースでは通信できます。
当然の事ながらバイトデータをシリアル展開して送ることになります。受信のタイミングをいろいろ考えたのですが、hidmonはエッジの検出ができない(少なくとも私にはわからない)のでハンドシェイクは無理と判断しました。

実際の回路ではターゲットのmega168で得た温度データ(バイトデータ)をPCへ送ろうとするものです。速度はせいぜい4データ毎秒位です。1データ毎秒でも支障はありません。
考えたあげく、また実験の結果から、3本のポートに クロック スタートビット データ を割り当てるようにしました。受信はdelphi6 personalですが、送信クロックに比べて十分速いループで3本のポートを読み取り、前回と同じデータを受信すると再読として捨てることにより必要なデータを受信するようにします。

受信したデータがスタートビットであればbitカウンタとデータ変数をクリアして、データビットがHならデータ変数に128を書きます。次のデータ受信でデータビットがHならデータ変数に64を加え、bitカウンタをインクリメントします。
bitカウンタが8になると1バイト受信終了ですからデータ変数からデータを取り出します。
もし、スタートがスタートビットでない(途中からの受信)だとbitカウンタが8になる前にスタートビットが来てデータ変数とbitカウンタがクリアされるので、間違ったデータが取り出されることはありません。

転送速度は受信側のDelphiの速さで決まると考えて、遅い速度でまず開発を行い、次第に速度を上げました。使用PCがペンティアム デュアルコア2.8MHzで最終的にクロックのHまたはLの幅が2msで通信できています。1データ転送の最小時間が20ms(リーダービットを含む)で転送できることを確認しました。

次にタイムテーブルを図示します。


使い方を工夫すれば適当なルーチンにバイトデータを埋め込んでデバグにも使えるのではないかと思います。
接続がライタだけで、また、スイッチの切り換えもなくPCに取り出せるところがミソではないかと思います。



ページのはじめへ戻る



14 swによるLED制御

折れ線グラフを動的に展示することを想定しています。8個以内の点を持つ折れ線グラフが2〜7本ある時に、手元のスイッチを押すと指定された折れ線グラフが順次点灯されるというものです。
MCUはTiny2313を使います。単純に考えると8個のLEDをコントロールするために8個のポートが必要で、このLEDアレイが7個あればアレイのドライブにポートが7個とスイッチ入力に7個のポートが必要になります。しかし、Tiny2313ではこれだけの数のポートがありません。
これを解決するために点灯の合間にポートを入力に切り換えてスイッチを読み込み、それが終わると点灯のための出力に切り換えることを考えました。

プログラムの表示ループのはじめにPORTBを入力に切り換え、プルアップします。いずれかのスイッチが押されるまでスイッチを読み続け、スイッチが押された=PORTBのいずれかのビットが0になるとPORTBを出力に変更してスイッチで指定された番号のPORTDビットを有効にして指定のLEDアレイにドライブ電流を2SA1015トランジスタを経由して流します。回路図は次のとおりです。


スイッチは入力動作が終わって出力に変わっても押し続けられることになりますから、スイッチでGNDに落とすとHになった出力PORTBが短絡して過大な電流が流れることになります。プルアップ抵抗に対して十分低い抵抗でGNDに落とせば入力はLと判断されますから1〜4.7kの抵抗で落とします。この程度であればスイッチが押されてもLEDからの流れだし電流は小さく点灯には至らないようです。10kでは大きすぎて安定した動作になりませんでした。LEDの感度とかねあいで決める必要があるようです。

LEDドライブの電流容量については、小電流高輝度LEDであればこのままで良いかと思いますが、全IOLの合計が60mA以内という制限を厳密に考えるとカソード側にもトランジスタなどによるドライバを付けねばならないかもしれません。
テストしたプログラムをここに置きます

テストには電流制限抵抗内蔵のLEDアレイを使いましたが、単独のLEDをアレイにするときには電流制限抵抗は共通にできます。




ページのはじめへ戻る



13 降圧型1.5V電源

 小型モーターの実験などに乾電池1個にあたる1.5V、1A程度の電源があれば便利かな、と思っていろいろ遊んでみました。このページのLM317レギュレータを用いた電源でも得られるのですが、熱ばかりを作るのも芸がないかと思ってスイッチング電源を考えてみました。
 まず最初に調べたのは AT90S2313 を使って出力端子の電圧をTL431の電圧と比較して、低ければ電源回路のPチャンネルFETをONにして出力コンデンサに電流を流すものです。小型のモーターを使って実験したところほぼ思い通りの結果が得られました。が、モーターの軸に負荷をかけて電流が増えると連続ONで暴走してしまいました。微妙なタイムラグが判断を狂わせるのかな、と思います。
 次に、コンパレータICを使って、これもTL431の電圧と比較してPチャンネルFETをON、OFFするものです。出力電圧はリップルを含むものの比較的安定していて、モーターを回す分には実用になりそうです。しかし、そのまま接続しますとFETがかなり発熱します。コンパレータ入力回路に 0.1μF*10kΩ の遅延を入れると発熱もそこそこで1A近い電流が取れそうです。出力段を 1000μFと180μHのπ型にするとリップルはかなり減少しました。
 そうこうする内に、チョッパ型レギュレータICを以前に秋月で購入していたのを思い出し、手持ちの部品で組み立てたのが次の電源です。(基板の大きさは47*35です)

PQ1CZ1はさすがに専用ICです。少ない部品でリップルもほとんど見られず安定しています。また、0.5A程を連続で流しても発熱はほとんどなく、ほのかに暖かい程度です。なお、放熱は大事をとって部品面全面の銅箔を使っています。
データによると1.5Aが最大で、それを超えるとリミターが働くようです。入出力電圧差は3V程度必要なのでしょうか。1.5Vに調整した回路に3.3V入力とすると電圧が出ませんでした。反対に、9V入力としても5V時と同じ出力が得られています。当然の事ながら入力を9Vにすると5Vの時に比べて入力電流は小さくなります。
12V〜15Vの電源を使うと、効率の良い電圧可変電源ができるかと思います。しかし、このICはいまは秋月では店頭にはあるようですが通販では見られなくなっています。


ページのはじめへ戻る



12 J-FETによる定電流回路

 なひたふさんのサイトに電子回路の丁寧な解説がありますが、その中にJ-FETで簡単に定電流回路が得られることが書かれています。ツェナーダイオードを使うときも定電流電源での駆動が望ましいとも聞きますが定電流ダイオードは使ったことがありません。その昔、LEDを購入したときに同梱されていた1個だけはあるのですが使ってはいません。
手元に 2SK30A GR がありましたので特性を調べてみました。回路を次に示します。


東芝のデータシートによると2SK30のIDSSにはいくつかのランクがあって、GRでは2.60〜6.50mAとなっています。今回の測定は手元の1個について調べたものですから傾向はわかりますが一般的なデータとはいえないでしょう。
ソースの抵抗を、無し、1kΩ、10kΩと変えて測定しました。なお、電圧はアナログテスタで測っているため多少違いがありますが、傾向をみるということで測定しています。
電圧1kΩ10kΩ
5.8v3.13mA0.84mA0.13mA
5.03.120.840.13
4.03.100.840.13
3.03.100.830.13
2.03.000.820.13
1.52.800.800.13
1.22.500.710.11
これをみるとソースに高い抵抗を入れる方が安定しているようです。10kの場合は9Vでも電流は変わりませんでした。概ね2V以上の電圧では定電流と考えて良いのではと思います。
ChaNさんの記事に、AD変換機能のないmcu(2313など)ではコンデンサを100μA程度の定電流源で充電してコンパレータの一致までの時間を測定するとアナログ電圧が測れると書いてあったと記憶しています。この実験の測定値から考えると、5Vで充電するときにはコンデンサの電圧が3Vまでは定電流で充電されていると考えれば良いのでしょうか。1.2V以下は電源が得られなかったので様子はわかりません。
もし大きな定電流回路が必要なときはこの電流をトランジスタで増幅すればできるのではないかと考えます。


ページのはじめへ戻る



11 実験用簡易可変電源

 電源電圧の変更による影響を調べるために、小型の簡易電源を考えてみました。卓上の電源は 9V、0.8A のスイッチング電源を元にして、LM317レギュレータの抵抗を切り換えて5Vと3.3Vを得ています。この9V出力から別のLM317の可変出力によって 1.25V〜6.5Vの範囲の電圧を作ってみました。

基板は例によってカッターで絶縁用の溝を切って作っていますが今回は表面のみの実装にしています。
はじめは分圧抵抗に240Ωを使って、可変抵抗は1kの小型のものにしたのですが、電流容量の不足のためVRが燃えだしてしまいました。10mAに耐えるVRとはどのようなものでしょうか。炭素皮膜ではもたないように思います。回路を変更して1kと10kVRで電圧を決めています。このレギュレータは出力電圧を2つの抵抗で分圧して、中点をAdj端子に接続すると、HOT側の抵抗による電圧が基準電圧(1.25V)になるように働きます。また、安定した動作のためには10mA以上の負荷電流が必要だとのことで、そのために基準電圧を作る抵抗に240Ωが選ばれているようです。

1kの抵抗では1mAしか流れませんから、最低の電圧でも10mAの負荷電流が流れるように140Ω(560Ω4本パラ)を付けています。最大電圧では電流が大きくなりますからぎりぎりにしています。電流容量の大きな抵抗がなかったのでパラ接続にしています。

入力を9Vとしますと、レギュレータの電圧降下1.5Vが最大で、最小は1.25Vとなりました。大きな電流は予定していませんのでヒートシンクは付けていません。400mA位流しますとかなり熱くなります。熱関係の保護回路は入っているとのことですからそれに期待します。
NチャネルJFETをつかった定電流回路を実験するためにこの電源を作りました。

(2008.03.16追記)分圧抵抗を1kから2.7kに変更しました。1kでは90°の回転で飽和してしまうため、回転角の調整が微妙になってしまったためです。結果的には飽和電圧まで上がらず1.25〜6.1Vとなりました。(上記の6.5Vは間違いで7.5Vでした)


ページのはじめへ戻る



10 時計モジュールを使ったRTC(tiny2313)

 \100アナログ時計のモジュールを使って1秒のクロックを作り、tiny2313で液晶に時刻表示する時計を実験しました。


このモジュールは1.5V電池で動作します。液晶表示の関係で電源は5Vとしたいので、5Vから抵抗分割で1.5Vを作ることにします。消費電流が小さいので、抵抗値は大きくても良いだろうと考えてシリーズに100kを繋いでみましたがまだ電圧が高そうです。もっと抵抗を大きくすると1.5Vにはなるのですが電源のインピーダンスが高くなりすぎて内部の消費による変動が大きくなってしまいます。カットアンドトライで47k+100kでおよそ1.5Vを作ることにしました。

出力端子は、秒針を動かすステッピングモータを駆動する関係でしょうか、1秒ごとに極性の変わるパルスが出てきます。電源のマイナス側(GND)を基準にすると、2秒に1回の割合で0Vのパルス(幅はおよそ20〜30ms)が交互に出てきます。合わせると1秒に1回のパルスになります。

ここで2つの問題が生じます。一つは振幅1.5VではAVRが駆動できないこと、もう一つは0Vのパルスの"OR"をとる必要があることです。1.5Vの(正の)パルスのORなら、NPNトランジスタを並列に並べるとどちらかがONになれば反転した0VのOR出力が得られますが、常時1.5Vで0Vのパルスが来るときは常にどちらかのTrがONになって、信号が得られません。
そこで、PNPトランジスタを使って、信号の基準を5Vに取ることにしました。モジュールのVccが5Vで、GNDが3.5Vになります。パルスがないときは電源電圧ですから5Vになり、パルスが来ると電源電圧-1.5Vになりますから、PNPTrがパルスが来たときには導通します。これでどちらかのTrにパルスが来るとコレクタに5V近い電圧が発生するので、毎秒1回の正パルスが得られることになります。

この形でAVRに読みとらせてみました。ところが、INT0端子入力が"low"レベルで割り込みをかけるととんでもない速い時計になってしまいました。考えてみるとlowは970msほどあるわけですから何回も割り込みが発生してしまいます。割り込みを立ち上がりエッジでかけると正しい時刻を刻みます。この状態でスリープをかけて見ましたが、エッジ検出では浅いスリープ(アイドリング動作)しかできません。消費電流を測ると約6mA流れます。(電池のバックアップを考えると少しでも減らしたい)。このうち液晶の消費は2mA程です。

パルスの位相を反転すると30ms程度のlowができますから、NPNトランジスタを追加して反転の実験をしてみました。コレクタ抵抗を10kとしますと単純に0.5mAですから辛抱できます。
とりあえず、割り込みをlowレベルとしてスリープを深い状態−−パワーダウン動作−−に設定しました。およそ30msのパルス幅がクロック起動時間と調和がとれたのか正しくカウントしました。予定した時刻を刻んでいます。

消費電流を調べると、液晶を外した状態でスリープ時は0.1mAくらいで、パルスの瞬間は5.3mA程流れているようです(電源に150Ωを入れてオシロスコープで電圧降下を見ました)。NPNの位相反転を付加した効果がありました。なお、液晶は約2mAを消費しています。


プログラム

今は時刻表示だけで、時刻設定機能もなく、日付の計算もしていません。将来的には、メインとなる装置がUSIを使ってI2Cで時刻データを利用する用途をイメージしています。そのときは液晶を外して消費電流を少なくすることができ電池によるバックアップも可能だと思います。長時間は無類としても、移動による短時間の電源断のために時刻を再設定する必要はないでしょう。

\100のクリスタルは精度の悪い物の救済措置?との話もありますが、安定して狂う?ならうるう秒補正で使えるかもしれません。余分なスイッチを載せていますが±30秒の補正を行うことも考えています(四捨五入で0秒に設定する方法)。とりあえず、様子を見ましょう。

自動温度測定器−−温度計にこの時計モジュールを付加して、データをSDカードに書けば長期間の自動測定が出きるかと...電源は用意しなくてはなりませんが1年間でも使えるでしょうか。それとも加速度センサーを用意して、いつ来るかわからない地震に備える?ことも...。



ページのはじめへ戻る



9 SPI通信による7セグLEDアレイの表示

ジャンク箱から20数年前に購入した9桁の7セグメントLEDアレイが出てきました。9桁の表示幅が45mmぐらいですから当時の電卓に使用されたものと思います。 やや暗いところでは液晶よりも見やすいので生き返らせようと頑張ってみました。
これだけの桁は周波数カウンタぐらいではないかと思い、実用的に8桁を考えました。
8桁を表示すると、小数点を含めたセグメントに8本、桁表示に8本と合計16本のポートが必要になり、mega8クラスではほとんど使えなくなります。重ねて、mega8 グループは他の機能を使うと8ビットまとめて使えるポートがありません。
Chanさんのページにはシフトレジスタを使ったスマートな回路がありますが、手元に部品がなく、またLEDアレイがカソードコモンですからそのままは使えません。 それ以上にシフトレジスタがまだ不勉強です。そこで、AVRを使って表示器を作り、SPI通信でデータを送ればポートが4本(MOSI,MISO,SCK、SS)ですみますから 周波数カウンタと連結できそうです。

mcuには手持ちのmega8を使いました。機能的にはもったいないと思いますが、日本橋への電車賃でいくつも買えます。

桁ドライバのトランジスタ2SC2458は50円基板から外したものでC1815より小さく、規格も一回り小さいようです。1815の代わりに使いました。電流制限抵抗は2000個 100円で買ったチップがありますので2個直列にしています。

SPI通信についてはmega8,mega48のデータシートを読んで調べました。


送信側として、mega48を使ってブレッドボード上にプログラムでセットした数値をSPIに送り出すだけのものを作りました。通信回線はプログラム書き込みのコネクタ の、Vccを使わず、resetをssに変更したものでよろしいから、書き込みと通信でresetとssを切替えればプログラム書き込みコネクタがそのまま使えるのですが、多分デバグ に回数がかかるだろうから別に通信コネクタを付けています。

関係するレジスタは、とりあえず最低必要なものをあげると
SPCR(SPI制御レジスタ):SPI割込許可 SPI動作イネーブル マスタ/スレーブ選択 SPIクロックの分周比設定
SPRS(SPIステータスレジスタ):SPI割込要求フラグ(転送完了フラグ)
SPDR(データレジスタ):マスタ/スレーブとも送り出しデータを書き、受信データを読むレジスタ
があります。

送信側のmega48では、
  DDRB=0b00101100;         /* B5:sck B3:mosi B2:SS の3ポートを出力設定*/
  SPCR=(1<<SPE)|(1<<MSTR)|(1<<SPR0);      /* SPI許可 マスタ動作 クロック16分周 */
と設定しておいて、
 PORTB&=0b11111011;     /* ssポートをLにして */
 SPDR=data;        /* レジスタに代入すると送信が開始される。dataは1バイト型変数 char型 uint8_t型 */
 while(!(SPSR & (1<<SPIF)));     /* 送信完了フラグが立つまで待つ */
 PORTB|=0b00000100;          /* 送出後はssをHにすると通信は終了する */
とすれば1バイトのデータが送出される。

他方、受信側のmega8では、
 DDRB|=0b00010000;     /* PB4:MISO出力 */
 SPCR=(1<<SPE)|(1<<SPIE);     /* SPI通信有効 割込み有効 */
と設定しておいて、
 for(;;){
  /*・・・・適当なループで割込みを待って処理をする */
 }
割込ルーチンは、
 ISR(SPI_STC_vect){       /* データが届いたとき=SPIFが立ったときの割込みルーチン */
  data_t=SPDR;      /* data_t変数(1バイト型)に1バイト取り込み。  グローバル変数*/
 }
となります。

通信バイトが1バイトだけの時は、フラグ(SPSR & (1<<SPIF)) を読んで、これが真(≠0)であれば通信が完了しているからデータレジスタを 読めばいいのですが、複数バイトの受信ではいろいろ試みたのですが割込みを使って初めて成功しました。(他に方法があるのかもしれません)
複数バイトの時は、送信完了フラグが立つのを待って、次のデータをデータレジスタSPDRに書けばよろしい。受信側では同じくフラグが立つのを待って、
 while(!(SPSR & (1<<SPIF)));
それから、SPDRを読めばよろしい。

今回は8桁ですから、取り扱う数値は32ビット型整数(uint32_t型)を考えました。10進8桁の適当な数値を設定して、256のn乗で割って、4つのバイト型に 分割し、順次送信した後受信側で4つのバイト型変数で受けて256のn乗倍したものを足しあわせて32ビット型に合成する事を考えましたが、どうしてもうまく 繋がりません。32768(符号付き2バイトの最大値+1)でおかしくなるようです。
それではと、10進2桁(100)で分割し、受信後合成しましたがまたまた失敗に終わりました。そこで、10進2桁を合成せずに2桁を分解×4回=8桁として 表示したところ成功しました。分解/合成の過程で符号無しのつもりが符号付きに変わっているような気がします(?)。
32ビットデータは連続した4バイトのメモリに納まっているはずですから、ポインタを使って1バイトずつ取り出して、受信後はポインタでメモリに納め、4バイト 数値として取り出す方法があると思うのですが不勉強で今はわかりません。
ただ、今の方法でもよたよたしながら4回の送信で10進8桁が送られますから、とりあえずよしとします。

プログラムの書き込みと実行では、どちらもライタを繋いだままではエラーが起こります。MOSI,MISO,SCKが繋がったままだからでしょうか。実験中の実際は1回毎に 通信コネクタの着脱とライタコネクタの着脱が必要で、なおかつ、送信側のプログラム変更と受信側のプログラム変更がありますから、ここで書くほどには簡単では ありませんでした。

現在、液晶で動いている周波数カウンタと連結するにはしばらく時間がかかりそうです。しかし、関係のポートはすべて空いているので変更は比較的簡単だと思います。

LED表示に専用のMCUを使うということですが、汎用のものが使えるということと、液晶表示器はもっと大規模なICが使われていることでしょうからmaga8が もったいないということもないかと思います。

LED表示器(受信側)の回路図プログラム、 送信側の回路図プログラム

2つのMCUを繋ぐことができました。マスタにもう1本のポート(第2のSSポート)を増やすと2個のスレーブと通信できます。 入力や出力をそれぞれのMCUに分担したマルチMCUの構成ができますし、また単純にIOの数を増やすことも可能だと思います。 私にとっておもしろい実験でした。
SPIについてのWebページは少ないようです。ご感想をお願いします。




ページのはじめへ戻る



8 SSRによる電力制御

タイトルが仰々しいのですが、ソリッドステートリレーSSRでAC100Vの電流をon,offして負荷に流れる電流を一定の割合で止めて、平均の電流を少なくする回路です。
手元に以前特売で購入したsharpのSSR S101D02がありましたので、これを使ってみようと考えたのがことの始まりです。Webで規格を調べますと 1.2A までコントロール できるとのことですから、半田ごての温度調整はできるだろうと考えました。位相制御をしたかったのですが、実験を始めてからこのSSRはゼロクロス型で位相制御は できないことがわかりました。
ゼロクロス型と非ゼロクロス型:トライアックはゲートをonにすると後はゲートをoffにしても電流は流れ続け、交流のサイクルで0Vになったところで電流 がoffにになります。非ゼロクロス型だと、電源の位相にあわせて短いパルスでonにすると次にくる0Vの時間まで電流が流れます。トリガの位相を半サイクルの立ち 上がり直後にすると100%近い時間電流が流れ、半サイクルの終わり近くでトリガすると0%に近い時間だけ電流が流れます。半サイクルごとに通電時間を決めることに なります。これを位相制御と言います。
ゼロクロス型は、トリガがかかってもすぐに導通せず、電源が0V近くになった時に通電します。急峻な立ち上がりがないのでノイズが少ない特長があります。 反面、半サイクルのはじめしかトリガが有効でないので、半サイクルを単位としてon,offをする事になります。位相制御型と比べて長時間周期の制御となります。
回路もプログラムも実に簡単です。交流100Vを使いますから電源はトランスで落としてダイオードで整流して(電流が少ないのでスイッチング用を流用しています)、平滑 の後、3端子レギュレータで5Vを得ています。トランスのレギュレーションが悪いので、低ドロップ型の3端子を使っています。
通電時間の調節は、バリオームの電圧をAD変換して、その値からonとoffの時間を作っています。適当な時間だけPORTをHにして220Ωを通じてSSRのトリガ信号としています。 バリオームの変化から10段階の値が取れれば十分と考え、8ビットの値(0〜254)を25で除して0〜10の値とし、制御周期0.48秒(0.5秒程度)を10%刻みでonに設定できる ようにしています。on,offの時間は単純にウエイトルーチンを使いました。目新しいことはなにもありません。
はんだごての場合は冷時と熱時で抵抗値の差が少なく、熱容量も大きいので0.48秒で十分だと思います。温度センサと組み合わせれば恒温槽にも使えるでしょう。
余談ですが、40Wの電球の抵抗値は冷時で18Ωでした。想像以上に小さいものですね。ラッシュは5A強です。
下の写真は実験中のものです。使うときにはアルミの箱に入れて、ヒューズやスイッチもつけます。

なお、SSRはすべてのピンを半田付けせよとあったので(放熱のためでしょう)、マジックインク手書きのエッチング基板を使いました。 プログラム




ページのはじめへ戻る



7 DCモータを回してみる

模型用の小型DCモータをHブリッジを使って正・逆転させる実験をしました。モータは無名の品で、300mA程で3枚羽根のファンを回します。ちなみにミニ四駆用の モータはもっと電流を流さないと回りません。
Hブリッジモータドライバは東芝の TA7288Pで、デジットで150円で購入したものです。このICは18Vで1Aの容量を持ち、同時には使えない2組のHブリッジを 持っています。バイポーラのパルスモータ駆動用に作られているようです。今回はDCモータですから1組だけを使いました。
回転制御のテストだけですから、ブレッドボードにTiny2313とともに配線し、モータ電源に5Vは高すぎるので5Ωの抵抗で制限しています。プログラムは 正逆転と停止の切り替えをひとつのタクトスイッチで切り替えることにしました。次に回路図とHブリッジのスイッチ関係を示します。

正逆転の切り替えだけですが、回っている最中に切り替えても安定した切り替えができないので、正転−停止−逆転−停止 と切り替えています。
ここにプログラムを置きます。

この種のバイポーラトランジスタによるHブリッジICではよくいわれることですが、ICの消費電力が大きいようです。上下のトランジスタで約2.2V消費されます。 この実験装置では、電源は実測4.8vですが、ブリッジに2.2v、抵抗に1.5vが消費され肝心のモータは1.1vで動いています。模型用の小型モータは1.5〜3v位のものが 多いようで、この場合にはかなりの部分がブリッジで消費されます。簡単な自動車型ロボットにこのタイプのHブリッジがよく使われるようですが、電池電源 の効率は悪いようです。
次にはPWMで回転数をコントロールする事を考えています。




ページのはじめへ戻る



6 100円電卓のLCD
 (Tiny2313で表示する)
100円電卓の中に、表示が大きく見やすいものがあります。この表示器がMCUで使えないか、実験してみることにしました。
電卓のLEDは27本の端子があります。この端子をコントロールするにはMCUのIOが不足するだけでなく、頭脳がついていきません。ここでは、邪道ですが 電卓の押しボタンをMCUに押させて、ボタンの数字を表示するだけの機能を使うことを考えました。
右の写真のように、トランジスタを11個と抵抗を22本追加して表示することに成功しました。が....
電卓の押しボタンにはチャタリング防止のためのディレイが十分取ってあるようです。一つのボタンを押して離して、かなりの時間が経たなければ次のボタン を受け付けません。4桁表示で1秒強、8桁表示で2秒強の時間をかけないと動作しませんから、表示替えがちらつくどころの話ではなく、1桁ずつ表示が 上がっていくのがゆっくりわかります。それだけの更新時間が辛抱できる時は使えるかもしれません。例えば、急激な変化がない室内用の温度計で30秒に一度 更新すれば良いような目的には可能性があります。

数字ボタンがマアトリックスになっていることは知っていました。ボタンの数から、5×5 か 5×6 であろうと考え、もし、行に信号を出して、それを列で受けて 判断するならMCUのIOで受け取り、結果をIOから出せば良いのではないか、とはじめは考えました。

分解すると導電塗料で印刷されたボタンスイッチ用パターンがあります。基板からは11本の端子が出ています。一方から番号を打ちました(1〜11)。パターンを 詳しく見て端子との関係を調べたのが次の表です。

端子に針を立てて、マトリックスどおりに短絡すると数字が表示されました。スキャンの波形があるかをオシロで見ましたが、それはありません。1,2と9,10,11番 端子は1V程の電圧が出ています。そこでこの1V側から0V側へダイオードで短絡すると文字が表示されました。さらに、NPNトランジスタのCを1V側端子に当て、Eを 0V側端子に繋ぎ、電源電池のマイナスをGNDとしてBに1.5Vを繋ぐと数字が表示されました。

端子に接着してあるパターンフィルムを剥がし、端子を補強するために小さな蛇の目基板を接着しました。トランジスタはジャンク基板から取り外した2SC143を 使っています。形状が小さいのでうまくおさまりました。場所を考えなければ2SC1815が使えると思います。MCUからはHでドライブする事にして、ベース抵抗を 4.7kとし、電卓の電源1.5Vを超える電圧をかけたくないので、ベース−GND間に2.2kを接続しています。
 
一つを除いて、すべてうまく行きました。価格・大きさ・字の大きさ・コントラストは合格です。2313のプログラムも簡単に書けます。でも表示速度がどうにもなりません。 もう1桁速ければ周波数カウンタにも使えると思うのですが、残念です。
"1234567"を表示するだけのプログラムです。

右の写真は電卓基板の表とトランジスタ・抵抗基板の表面です。




ページのはじめへ戻る



5 tiny2313 USARTによる通信4
 (時刻の読み取りと設定 Excel VBA)
このシリーズの一区切りの目標がMS VBAを使ってExcelにMCUからデータを読みとることでした。読みとるべきデータとして時計機能による時刻文字列をMCUで作り、 それをUARTで外部と通信できるように、先の4で用意しました。4のハードウエアとファームウエアは時刻文字列を生成し、外部に通信で送り出すことができるよう にしてありますから今回はVBAからコマンドを送ること、MCUから送られたデータ文字列をExcel VBAで受信してセルに書き込むことが目的になります。 したがって、ハードウエアとファームウエアは変更していません。

Excelには3つのコマンドボタンを配置しました。
第一のコマンドボタン"start"は表示位置を初期化するだけです。
第二のコマンドボタン"read time"はMCUに rコマンド を送って、秒更新後のhh:mm:ssデータをMCUから読み取り、セルに書き出します。
第三のコマンドボタン"set time"はMCUに sコマンド を送って、指定されたセルに書かれた hh,mm,ssデータを時計に設定するものです。

startボタンで、読み取った時刻データをE2セルから書き始めるように指示しています。
read timeボタンで、押す毎に秒更新された時刻をE2セルから下へ順に表示します。秒更新が終わるまで返答がないので、続けて押すとエラーになります。
set timeボタンは、先にhh,mm,ssを入力しておいてこのボタンを押すとLCDの時刻が変わりますが、通信のタイムラグを感じます。
VBAのプログラム

これでUARTによるExcel VBAとの通信実験は成功したと考えています。通信に時間がかかるようですが、これは現PC(セレロン500MHz、WinXP)のスペックによる ものかもしれません。今後実際にMCUからデータをExcelに取り込む装置を作ったときに細かいところを調べましょう。

(05.07.17) VBAプログラムを修正しました(1桁時刻の設定が働かなかった)。

ページのはじめへ戻る



4 tiny2313 USARTによる通信3
 (時刻の読み取りと設定 ハイパーターミナル)
3の回路に時計機能を付けました。時刻表示は2行のLCDで、hh:mm:ss としています。今回はハイパーターミナルを使って、 hh:mm:ss の読み出しと設定をしてみました。
ハイパーターミナルからは、'r'(read)と's'(set)のみが有効です。'r'を受け取ると秒更新を待って時刻を送出します(少し不細工)。's'fを受け取ると、引き続いて 送られてくるはずの hh:mm:ss を待ちます。完了時に時刻を設定します。おまけで1秒で点滅するLEDを付けました。(本当はデバグ用)

計時の考え方: 10時 1時 10分 1分 10秒 1秒 に8ビット符号無し変数を用意しました。9.216MHzを1024分周して9000カウントすると1秒が得られますので、 その1秒毎に割込をかけて処理しています。インクリメントは繰り上がりがあれば零に戻して上位をアップしています。関数itoa()より簡単かなと思います。一桁の 数値と数字文字は0x30の加減で変換できるのでわかりやすいかと思います。時刻の文字列には、文字列ポインタの1字毎に代入しています。文字列の扱いを理解して いないので良い扱い方でない可能性が大きいです。

ハードウエア:回路図は用意していませんが、Tiny2313 を 電源5V、クロック9.216MHzセラミックで動いています。内蔵RCの発振でしたかったのですが、 通信の安定性に問題があるようなので手持ちのセラミックに変更しました。
IO端子は次のとおりです。
PB0〜3 LCDデータ
PB4 LCDのRS
PB5 LCDのE
PA0,1 セラミック発振子
PD0,1 RXDとTXD(USART)
PD5 1秒点滅のLED(1kでVccに接続)
これらをブレッドボードに並べています。

ソフトウエア:urt02.cとlcd.clcd.hの3ファイルです。 例によって.hファイルが通りませんので.txt名で置きますから注意してください。(TABがそろっていないので不細工です。TAB=2で見やすくなります。)

単体で時刻設定を考えるとスイッチだけでも大変ですが、PCには多くのスイッチ(キー)があるので楽にできます。これで976バイト、2313のメモリの半分に なります。あと1kありますから機能はまだ追加できるでしょう。このデータをExcelで処理できるとこのシリーズの一区切りです。

ページのはじめへ戻る



3 tiny2313 USARTによる通信2
 (2を MS Excel で通信する その1)
最終的にはMCUのデータを通信によってExcelのセルに取り込みたいのですが、ここではまずExcelと通信できることの確認だけしました。

通信にはMSのVBAを使った公開されている通信ソフトEasyCommを利用させていただきました。
ダウンロードして解凍すると、インポートする2つのファイルとともにExcelで書かれたマニュアルが入っています。このマニュアルにしたがって使ってみました。
ハードウエアは2の通信1で使ったものをまったく変えていません。COMポートへの変換もFDTI232BMでTXDとRXDだけ使っています。番号はポート3です。

手順は次のとおりです。
@EasyCommをダウンロードして解凍し、わかりやすいようにフォルダに入れてマイドキュメントに置きます。
AExcel(2002)を起動しました。
BVisual Basic Editor(Alt+f11)を起動し、メニューバーの「ファイル」から「ファイルのインポート」を選択し、ec.basとecDef.basをインポートしました。 標準モジュールフォルダに2つのファイルがインポートされます。
C次に、同じ画面でメニュー「挿入」から「標準モジュール」を選び上の2つのファイルが入っているフォルダに「Module1」を作りました。
Dこの画面を終了してsheet1のExelの表に戻り、名前を付けて保存しました。test1.xlsとしてデスクトップに置きました。
E続いてテスト画面の製作です。コントロールツールボックスを開いて置いて、デザインモードに入ります。

Fコマンドボタンを選択して、セルのある画面に長方形のボタンを作ります。
Gデザインモードのまま、今作ったボタンをダブルクリックするとVBAのテキスト編集画面に変わります。
Hここの sub・・・・end sub の間に次の様にプログラムを書きます。(コメントは不要です)
  Private Sub CommandButton1_Click()
    ec.COMn = 3                    'ポートは3番
    ec.Setting = "38400,n,8,1"     'ボーレイト、パリティ、データビット、ストップビット
    ec.Delimiter = ec.DELIMs.Cr    'デリミタ
    ec.Ascii = "1"                 '1を送る 2,3に変えてみる
    A$ = ec.AsciiLine              'MCUから受け取り
    MsgBox A$                      'メッセージボックスに表示
    ec.COMn = -1
  End Sub
HVBA編集画面を終了してsheet1へ戻ります。
Iデザインモードを終了して、上書き保存しました。
Jコマンドボタンをクリックすると「one」がメッセージボックスに現れました。プログラムを"2"に変えれば「two」が返ってきます。

今回はここまでです。MCUとExcelが間違いなく通信していることが確認できました。あと、VBAを書けば、セルに指定した文字列(指令)をMCUに送り、 MCUから連続してデータを読み出し、セルに納めることができると思います。ただ・・・VBAがわからないのでその勉強にどれだけ時間がかかるか問題です。 そのような訳で、今日の記述も極めて怪しいもですが、とにかく動いたと自己満足しておきましょう。

  05.07.15追記 休憩して再起動するとうまく反応してくれません。シリアルコンバータを交換しても動いたり動かなかったりの不安定は変わりません。ハイパーターミナルを 使っても不安定でした。かなり悩んだのですが、クロック変動を疑って、9.22(9.216?)MHzのセラミック発振子に変えてみました。素直に安定した反応を見せました。 内蔵のRC発振は温度による変動が大きく使いにくいもののようです。「通信が不安定ならクロックを疑いましょうw」

ページのはじめへ戻る



2 tiny2313 USARTによる通信1
 (基本のみ.3つのコマンドに文字列を返す.)
Tiny2313を使って、PCのハイパーターミナルと通信する基本実験をしました。
ハードウエアはTXDとRXD以外には何も接続していません。クロックは内蔵RCの8MHzです。また、通信以外のソフトウエア機能も持ちません。 通信のための最小のプログラムです。PCとの通信は FTDIのチップからTXDとRXDを取り出し(RTSとCTSは短絡)クロスで2313と接続しています。

プログラムはここに置きます。通信のための記述はデータシートのものをアレンジしました。
@ボーレイトの設定はUBBR値を自動設定にする例がありましたのでそのまま使っています。ただ、誤差は計算されませんので確認しておく必要があると思います。 ここの値では0.2%になるようで、問題はありません。
A受信のための割込は、割込処理中にデータを読まないと、また割込がかかって不都合が生じます。割込処理時間を短くするために(必要?)割込処理では フラグを立てることと、グローバル変数にデータを読み込むことだけをしています。
B送信はデータシートのとおりバッファの空きを待って一文字ずつ送っています。文字列変数の扱いが分からない(=不勉強)ので時間がかかりました。使い方が 間違っているかもしれないけれど動いているからよしとしましょう。
C'1'を受け取れば'one'を返し、2ならtwo、3ならthree、それ以外ならselect1,2,3を返すようにしました。

ハイパーターミナルのポート番号(私の場合はCOM3)を設定し、38400bpsを指定して、(8ビット、ノンパリティ、1ストップビット)設定を合わせれば通信できました。 ハイパーターミナルを起動してもカーソルが見えるだけですが、1,2,3を入力すると文字が返ってきます。

これだけで310バイトでしたから、ROMの圧迫も少ないでしょう。これでPCから文字が送れること、mcuでそれを処理してデータを送り返せることが確認できましたので 次のステップへ進めます。


ページのはじめへ戻る



1 プログラムライタによるSPI通信

ChaNさんのプログラムライタ「COMポート制御ISPアダプタ」はSPIを使ってPCと通信することができます。 同じページにサンプルプログラムを提供していただいているので、これを試してみることにしました。
ページ最下欄にある「ISP通信サンプル、汎用AVRモニタ(GCC) 2005. 1. 30」をダウンロードして解凍します。
Makefile suart.h suart.S test1.c の4つのファイル が含まれています。
注意書きとして
 ・少なくともMISOはモニタ用として完全に空けておく。
 ・MISOを出力に、MOSIを入力に設定する。
 ・MISOとMOSIを使ってソフトウェアUARTでホストと通信する。
とありますので、これを満たすハードウエアをブレッドボードに組み立てました。MCUは 90S2313 を使いました。回路は簡単なものなので回路図は省略しますが、
 5Vの電源を用意し
 発振子に12MHzの水晶を繋ぎ、C=22p(手持ちの関係です)
 リセット端子を100kΩでプルアップ
しただけのものです。

サンプルのソフトウエアは次の点を修正しました。
 test1.cの #define SYSCLK 8000000 の8000000を12000000
 suart.Sの #define BPS 68 /* Bit delay. (see above) */ の68を102
 makefileの MCU_TARGET = at90s8515 # s2313 and s8535 also work without any change. の at90s8515をat90s2313に。
これらの変更の後、WinAVR(ave-gcc)でコンパイルしました。

PC側のソフトはハイパーターミナルを用意しました。ボーレートなどの設定は次のとおりです。


プログラムを書いて、ハイパーターミナルを立ち上げるとスターティングメッセージが出るようですが、毎回書き込むわけではないので一般的な立ち上げを考えると、 プログラムライタの書き込みスイッチをONにしておくとハイパーターミナルが立ち上がらない(または、動かない)ので、ライタのスイッチを0FFにして置いて ハイパーターミナル を起動しておき、書き込みスイッチをONにして、ターゲットをリセットすると確実に次のとおりのスターティングメッセージが現れました。


ここで t 1 2 3 と入力し、次の行に g を入力すると

このように時刻をカウントします。

ライタの接続を使ってターゲットとPCが通信できることを確認できました。しかし、usart.Sファイルの意味も理解できず、プログラムをどう書けば使えるのか、 勉強はこれからです。とりあえず、書かれているとおりの通信ができたことだけを報告します。なお、通信の確実性を考えて水晶を使いましたが、セラミック 12MHzでも動きました。また、ボーレートを115200にしても問題なく動きました。もちろん、usart.Sとハイパーターミナルのボーレートを一致させないと通信できま せんでした。

ページのはじめへ戻る
TOPページへもどる