このページについて
部品単体での動作確認など電子工作を行うために実施した実験についてまとめる。
入力アンプに関する実験
この章では、簡易的なオシロスコープを作るために実施した入力アンプに関する実験を紹介する。
マイコンで出力した波形を手軽に見るツールがほしいので、自作の簡易オシロスコープを作ろうと考えた。
専用のオシロスコープほど精密に測定できなくてもよいが、手軽に使えるものにしたい。
プローブの接続方向などをあまり意識したくないのでマイナス側も計れるようにする。入力インピーダンスも意識したくない。
というわけで、-10V〜+10Vを0〜5Vに変換するアンプを作ることにした。
マイコンで出力した波形を手軽に見るツールがほしいので、自作の簡易オシロスコープを作ろうと考えた。
専用のオシロスコープほど精密に測定できなくてもよいが、手軽に使えるものにしたい。
プローブの接続方向などをあまり意識したくないのでマイナス側も計れるようにする。入力インピーダンスも意識したくない。
というわけで、-10V〜+10Vを0〜5Vに変換するアンプを作ることにした。
加算回路を利用したアンプ
下の回路図のIC5G$1のアンプが、CH1の入力を4分の1の電圧にして2.5Vに加算する加算回路になっている。
加算回路の出力はマイナス側に反転するので、IC5G$2の1倍の反転増幅回路を通してAN0の入力にした。
入力電圧は4分の1されて2.5Vに足されるため、-10Vを入力すると0V、+10Vを入力すると5VがAN0に入力される。
電源はIC1(MAX232)のVS+とVS-端子からとった。VS+は+9.8V,VS-8.9V程度を出力していた。
使ったオペアンプはフルスイングしないLM358なので、±6V程度しか計れないがやむなしとした。
実験結果のグラフは、入力がCH2(5V/Div)、出力CH1(500mV/Div)だ。
出力の3.69V(X),2.91V(0)は、理論的には下記の式にしたがってそれぞれ1.64V,4.76Vのはずである。
入力(V)=(出力(V)-2.5)×4
実際には、2.19V,5.31Vであるから、0.55V低い値になっている。
0.1375V(=0.55V/4)の誤差がどのような要因で生じたかについては考察していないが、下記の式を用いるとADコンバータの出力から正確な電圧を求めることができるとわかった。
入力(V)=(出力(V)-2.3625)×4
※ 2.3625V=2.5V-0.55V÷4
加算回路の出力はマイナス側に反転するので、IC5G$2の1倍の反転増幅回路を通してAN0の入力にした。
入力電圧は4分の1されて2.5Vに足されるため、-10Vを入力すると0V、+10Vを入力すると5VがAN0に入力される。
電源はIC1(MAX232)のVS+とVS-端子からとった。VS+は+9.8V,VS-8.9V程度を出力していた。
使ったオペアンプはフルスイングしないLM358なので、±6V程度しか計れないがやむなしとした。
実験結果のグラフは、入力がCH2(5V/Div)、出力CH1(500mV/Div)だ。
出力の3.69V(X),2.91V(0)は、理論的には下記の式にしたがってそれぞれ1.64V,4.76Vのはずである。
入力(V)=(出力(V)-2.5)×4
実際には、2.19V,5.31Vであるから、0.55V低い値になっている。
0.1375V(=0.55V/4)の誤差がどのような要因で生じたかについては考察していないが、下記の式を用いるとADコンバータの出力から正確な電圧を求めることができるとわかった。
入力(V)=(出力(V)-2.3625)×4
※ 2.3625V=2.5V-0.55V÷4
回路図
実験結果
実験装置
差動増幅器を利用したアンプ
下の回路図のIC2のアンプが、CH1の入力を4分の1の電圧にして2.5Vに加算する
入力電圧は4分の1して2.5Vに足すため、-10Vを入力すると0V、+10Vを入力すると5VがAN0に入力される。
NJU7092は、電源電圧まで出力できるので、-10Vから10Vまでほぼ全域を使える。
実験結果のグラフは、入力がCH1(1V/Div)、出力CH2(500mV/Div)だ。
出力の3.75V(X),2.94V(0)は、理論的には下記の式にしたがってそれぞれ5V,1.76Vのはずだ。
入力(V)=(出力(V)-2.5)×4
実際には、5V,1.87Vなので、それぞれ0V,0.11Vの誤差となった。
同様にマイナス側は、1.34V(X),2.03V(0)は、理論的には下記の式にしたがってそれぞれ-4.64V,-1.88Vのはずだ。
実際には、-4.94V,-1.81Vなので、それぞれ-0.3V,-0.07Vの誤差となった。
念のため入力電圧とアンプの出力電圧から決定した値の相関についても調べてみた。誤差の平均は0.034Vだった。
入力インピーダンスが小さめだが、回路がシンプルでノイズが小さいのでこの回路を採用することにした。
入力電圧は4分の1して2.5Vに足すため、-10Vを入力すると0V、+10Vを入力すると5VがAN0に入力される。
NJU7092は、電源電圧まで出力できるので、-10Vから10Vまでほぼ全域を使える。
実験結果のグラフは、入力がCH1(1V/Div)、出力CH2(500mV/Div)だ。
出力の3.75V(X),2.94V(0)は、理論的には下記の式にしたがってそれぞれ5V,1.76Vのはずだ。
入力(V)=(出力(V)-2.5)×4
実際には、5V,1.87Vなので、それぞれ0V,0.11Vの誤差となった。
同様にマイナス側は、1.34V(X),2.03V(0)は、理論的には下記の式にしたがってそれぞれ-4.64V,-1.88Vのはずだ。
実際には、-4.94V,-1.81Vなので、それぞれ-0.3V,-0.07Vの誤差となった。
念のため入力電圧とアンプの出力電圧から決定した値の相関についても調べてみた。誤差の平均は0.034Vだった。
入力インピーダンスが小さめだが、回路がシンプルでノイズが小さいのでこの回路を採用することにした。
回路図
実験結果
全域の相関
このページの最初に移動表示装置に関する実験
この章では、マイコンの表示装置に関する実験を紹介する。
Nokia 5110 LCD
仕様
- 解像度・・・・48×84ドット
- 表示色・・・・白黒
- バックライト・・・・LED(青)x4
- インターフェイス・・・・シリアルSPI
- 電源・・・・2.7〜3.3V
1:RESET、2:CE、3:D/~C、4:DIN、5:CLK、6:Vcc、7:LIGHT、8:GND
ハードウエア
H8S/2128マイコンに接続してみた。
データシートに書いてある信号そのままなので、扱いに迷うのはLIGHTぐらいだ。調べてたところ、バックライトのカソード側に接続されており、GND直結でよさそうだ。
マイコンから5Vを取り出し、レギュレータで3.3Vを作ってLCDの電源にした。
LCDの入力信号は5Vトレラントでないので、TC74LCX541を使ってレベルを合わせた。
データシートに書いてある信号そのままなので、扱いに迷うのはLIGHTぐらいだ。調べてたところ、バックライトのカソード側に接続されており、GND直結でよさそうだ。
マイコンから5Vを取り出し、レギュレータで3.3Vを作ってLCDの電源にした。
LCDの入力信号は5Vトレラントでないので、TC74LCX541を使ってレベルを合わせた。
【写真】
【実体配線図】
ソフトウエア
ソフトウエアについては、以下のサンプルを参照いただきたい。
サンプルソース
サンプルソース
表示速度について
動的なサンプルプログラムを作ってみた。
SCIは使わずにI/OポートをソフトウエアでON・OFFして通信しているが、下の動画のようにそこそこのスピードが出た。
普通に使う分には、これでも十分と思われる。
アプリケーションを組んだときに速度が不十分になったら、SCIを使って高速化しようと思う。
SPI(2.5M bps)を使って高速化してみた。
SCIは使わずにI/OポートをソフトウエアでON・OFFして通信しているが、下の動画のようにそこそこのスピードが出た。
普通に使う分には、これでも十分と思われる。
アプリケーションを組んだときに速度が不十分になったら、SCIを使って高速化しようと思う。
SPI(2.5M bps)を使って高速化してみた。
NTSC出力
H8S/2128マイコンを使って、CRTにモノクロ168×200の画面をビデオ出力する実験を行った。増設した64KBの一部をVRAMに使用し、ソフトウエアで表示した。
下の画像は、解像度を224×184に改善したものだ。
ハードウエアは、CPUに抵抗とロジックIC1個(74HC00)を追加した。
V_SYNC信号は8ビットタイマー0と1をカスケード接続してタイマーのPWM出力機能を使って生成しており、V_SYNC信号をP64(TMO0)から出力している。
画像データの出力には、ソフトウエアで処理する上で最上位ビットが使いやすいためP67を使った。
画像データを出力する処理をする時に、P64の出力を保持したまま、P67に画像データを出力する必要があるが、その処理をソフトウエアで行うと1ドットあたり50nsを消費してしまうため、横方向の解像度は168ドット程度が限界になる。
外付けにラッチ回路を付けて対処して、P64の出力をハードウエアで保持し、224ドットの解像度を実現した。
下の画像は、解像度を224×184に改善したものだ。
ハードウエアは、CPUに抵抗とロジックIC1個(74HC00)を追加した。
V_SYNC信号は8ビットタイマー0と1をカスケード接続してタイマーのPWM出力機能を使って生成しており、V_SYNC信号をP64(TMO0)から出力している。
画像データの出力には、ソフトウエアで処理する上で最上位ビットが使いやすいためP67を使った。
画像データを出力する処理をする時に、P64の出力を保持したまま、P67に画像データを出力する必要があるが、その処理をソフトウエアで行うと1ドットあたり50nsを消費してしまうため、横方向の解像度は168ドット程度が限界になる。
外付けにラッチ回路を付けて対処して、P64の出力をハードウエアで保持し、224ドットの解像度を実現した。
電源に関する実験
この章では、電源に関する実験を紹介する。
HT7750A昇圧実験
【電圧】
NCP1402昇圧実験
HT7750Aと同じ機能を持つNCP1402というICを見つけたので使ってみた。
データシートでは、コイルは47uFを推奨していたが、今回は手持ちの33uFを使った。120mA程度は問題なく出力できることがわかった。
今回は100mAを超えるあたりから5Vを下回ったが、コイルやダイオードを変更すれば200mAを出すことができるものと思われる。
このICは動作時に発熱が大きいようなので、使用時にはケースを作るなどして、接触しないよう工夫したほうがよさそうだ。
HT7750Aより安価に手に入るので、今後活用を検討したい。
データシートでは、コイルは47uFを推奨していたが、今回は手持ちの33uFを使った。120mA程度は問題なく出力できることがわかった。
今回は100mAを超えるあたりから5Vを下回ったが、コイルやダイオードを変更すれば200mAを出すことができるものと思われる。
このICは動作時に発熱が大きいようなので、使用時にはケースを作るなどして、接触しないよう工夫したほうがよさそうだ。
HT7750Aより安価に手に入るので、今後活用を検討したい。
【回路図】
H8S/2128を使った実験
この章では、H8S/2128マイコンの周辺機能を利用した実験を紹介する。
Simple DataLogger
電子工作をしていると、時系列に電圧の変化を確かめたいことがよくある。今回は、フリーソフト(DataDisplay)を活用させていただいて、8Bitタイマー1を使って出力した200μs周期Duty比50%の信号を可視化してみた。
このソフトは、マイコンからPCに16進の文字列にした数値データをCRLFをデリミッタにして送ると、グラフにしてくれる便利なツールだ。横軸は25データが1メモリにプロットされる。今回は8μsごとにサンプリングしたので、オシロスコープの200μs/divのような表示になる。
右のグラフを見ると、横軸の1メモリが1周期になっており、PWMは200μsの周期で出力されていることが分かる。
【回路図】
【プログラム】 SimpleDataLogger.mot
このソフトは、マイコンからPCに16進の文字列にした数値データをCRLFをデリミッタにして送ると、グラフにしてくれる便利なツールだ。横軸は25データが1メモリにプロットされる。今回は8μsごとにサンプリングしたので、オシロスコープの200μs/divのような表示になる。
右のグラフを見ると、横軸の1メモリが1周期になっており、PWMは200μsの周期で出力されていることが分かる。
【回路図】
【プログラム】 SimpleDataLogger.mot
【実行例】
ビープ音による演奏
ビープ音でルパンの主題歌を演奏してみた。
ビープ音にしては、それらしく聞こえると思う。
回路図もプログラムも簡単だ。
【回路図】
【動画】
【プログラム】 SimpleSound.mot
【ソースコード】
ビープ音にしては、それらしく聞こえると思う。
回路図もプログラムも簡単だ。
【回路図】
【動画】
【プログラム】 SimpleSound.mot
【実体配線図】
DCモーターの回転数の測定
DCモーターの回転数を測定してみた。
フォトインタラプタの出力信号の立下り時に割り込みを発生させて、回転数をカウントした。
【回路図】
【動画】
【プログラム】 RotationalSpeedCounter.mot
フォトインタラプタの出力信号の立下り時に割り込みを発生させて、回転数をカウントした。
【回路図】
【動画】
【プログラム】 RotationalSpeedCounter.mot
Simple ADC
ADコンバータで取り込んだ値をPCに表示してみた。
ボリュームの角度に従って、数値が0〜1023の間で変化する。
【回路図】
【プログラム】 SimpleADC.mot
ボリュームの角度に従って、数値が0〜1023の間で変化する。
【回路図】
【プログラム】 SimpleADC.mot
Simple DC Motor Control
DCモーターを制御してみた。
【回路図】
【動画】
【プログラム】 SimpleDCMotor.mot
【回路図】
【動画】
【プログラム】 SimpleDCMotor.mot
LED Loop
PWM出力を使って、LED_Loopを作ってみた。
先頭のLEDは100%、次は50%、最後は25%の出力のように制御した。
【回路図】
【動画】
【プログラム】 LED_LOOP.mot
先頭のLEDは100%、次は50%、最後は25%の出力のように制御した。
【回路図】
【動画】
【プログラム】 LED_LOOP.mot
ソフトウエアに関する考察
この章では、ソフトウエアに関する実験や考察を紹介する。
組込みでのオブジェクト指向
オブジェクト指向でLチカを組んだ。プログラムサイズは大きくなるが、部品化ができることと、忘れたころにソースを見たときに仕様を実現している部位の特定が早いことに魅力を感じる。今後、このスタイルでソフトウエアを資産化していこうと思う。
LEDを点滅させるプログラム
マイコンのHello WorldともいえるLEDを点滅させるプログラムをC++で作ってみた。
EE_Type_LTマイコンのLEDは、IOポート6の5ビット目をLowにすると点灯し、Highにすると消灯する。 今回は、(LEDにではなく)IOポートに着目してモデル化した。
ここでは、ソースコードの中のSystemFactoryというクラスのstartupメソッドがCでいうmainと同じで最初に実行される関数と考えていただきたい。
startupメソッドでは、シーケンス図に示すようにIOPinクラスのsetメソッドを使ってIOpinの出力をHighとLow交互に切り替えている。
IOPinクラスでは、H8SCPUのレジスタにアクセスして、IOPinの出力を切り替える処理を行っている。H8SのCPUのレジスタの機能については、CPUのハードウエアマニュアルに解説されている。ハードウエアマニュアルは、Renesasのホームページでキーワードに2398を指定して検索したページからダウンロードできる。
EE_Type_LTマイコンのLEDは、IOポート6の5ビット目をLowにすると点灯し、Highにすると消灯する。 今回は、(LEDにではなく)IOポートに着目してモデル化した。
ここでは、ソースコードの中のSystemFactoryというクラスのstartupメソッドがCでいうmainと同じで最初に実行される関数と考えていただきたい。
startupメソッドでは、シーケンス図に示すようにIOPinクラスのsetメソッドを使ってIOpinの出力をHighとLow交互に切り替えている。
IOPinクラスでは、H8SCPUのレジスタにアクセスして、IOPinの出力を切り替える処理を行っている。H8SのCPUのレジスタの機能については、CPUのハードウエアマニュアルに解説されている。ハードウエアマニュアルは、Renesasのホームページでキーワードに2398を指定して検索したページからダウンロードできる。
プログラムサイズは、ROM 10KByte RAM 100Byteだった。
アセンブラやCでプログラムすれば、100ByteのROMで実現できる。このあたりがC++は冗長だといわれる所以だろうか。(SystemFactoryクラスとIOPinクラスのサイズは1200Byteだった。Cでもすべてのポートをサポートするように部品化したら100Byteでは収まらないだろうし、他の約9KBはC++のライブラリのサイズなので、プログラムの規模が大きくなるとサイズの差は今回ほど極端ではなくなると思われる。)
利点としては、部品化する習慣が付くことのように感じる。 ソースコードを見ていただくと分かるとおり、IOPinクラスはH8S 2398が持つすべてのポートをサポートしており、次にIOポートを使うプログラムを作るときには、IOポートのアドレスなどは気にせずにポート番号とビットの位置、入力/出力を指定するだけでIOポートを使える。namespaceやアクセス指定子(private,public)など言語が部品化をサポートする機能を持っていることも気に入っている。趣味で電子工作をしていると、似たようなプログラムを何回も作るので、再利用性の高いプログラムが組めることは魅力だ。
【シーケンス図】 【ソースコード】
※ 説明のためソースコードを簡略化しsetDirectionでDDRの読み出しをおこなっていますが、H8で使う場合にはDDRの読み出しはできないのでDDRの値をレジスタとは別にクラス内に持つなどの工夫が必要です。
利点としては、部品化する習慣が付くことのように感じる。 ソースコードを見ていただくと分かるとおり、IOPinクラスはH8S 2398が持つすべてのポートをサポートしており、次にIOポートを使うプログラムを作るときには、IOポートのアドレスなどは気にせずにポート番号とビットの位置、入力/出力を指定するだけでIOポートを使える。namespaceやアクセス指定子(private,public)など言語が部品化をサポートする機能を持っていることも気に入っている。趣味で電子工作をしていると、似たようなプログラムを何回も作るので、再利用性の高いプログラムが組めることは魅力だ。
【シーケンス図】 【ソースコード】
※ 説明のためソースコードを簡略化しsetDirectionでDDRの読み出しをおこなっていますが、H8で使う場合にはDDRの読み出しはできないのでDDRの値をレジスタとは別にクラス内に持つなどの工夫が必要です。
今度は、タスクの概念を取り入れて、1秒周期でLEDを点滅するプログラムを作ってみた。
下記の2つのステップでアプリケーションは完成だ。
1、1秒周期に起動するTaskを定義する。(ソースコード中のSystemFactory参照)
2、指定した周期で呼び出されるperformメソッドの中にLEDを点滅させるコードを書く。(ソースコード中のLED_TASK参照)
プログラムサイズは、ROM 24KByte RAM 100Byte程度だった。
OSTimerには、起動周期の異なる複数のTaskを登録できる。
ノンプリエンプション型の擬似マルチタスクなので、OSTimerの周期以内に登録したすべてのタスクの実行が終わることが前提※ではあるが、処理の実行タイミングと処理内容を別々に考えられるのは魅力的だ。
※ 他のタイマを使えば、正確な周期で実行する処理を実現できる。
【シーケンス図】 【ソースコード】
このページの最初に移動 下記の2つのステップでアプリケーションは完成だ。
1、1秒周期に起動するTaskを定義する。(ソースコード中のSystemFactory参照)
2、指定した周期で呼び出されるperformメソッドの中にLEDを点滅させるコードを書く。(ソースコード中のLED_TASK参照)
プログラムサイズは、ROM 24KByte RAM 100Byte程度だった。
OSTimerには、起動周期の異なる複数のTaskを登録できる。
ノンプリエンプション型の擬似マルチタスクなので、OSTimerの周期以内に登録したすべてのタスクの実行が終わることが前提※ではあるが、処理の実行タイミングと処理内容を別々に考えられるのは魅力的だ。
※ 他のタイマを使えば、正確な周期で実行する処理を実現できる。
【シーケンス図】 【ソースコード】