2015年1月9日金曜日

ADCを使ってみよう。

今回、ADCを使って高精度温度センサLM61のアナログ値を
キャラクターLCDに表示させます。
まず、必要な物
Vssa,Vddaが外に出ているPSoC5LPボード(今回はCQ出版のボード)
高精度IC温度センサーLM61BIZ 1個
セラミックコンデンサ1μF 1個

出来ればあると良いもの
抵抗330Ω 1個
コンデンサ0.1μF 1個

今回は必ず、PSoC Creater3.0の環境で行ってください。
3.1ではsprintf()のトラブルシューティングが出来ません。
3.1環境でもsprintf()を使うことが出来ます。

さて、PSoCのADCは通常のマイコンとはかけ離れた高級仕様となっています。
普段以上に濃いので、よく見ながら進めて行ってほしいとおもいます。
では、普段通り「空のプロジェクト」を立ち上げたら、以前に書いた

Sprintf()のトラブルシューティングの記事の手続き(別ウインドウ)を済ませます。


そうしたら、表示用のキャラクターLCDをドラッグアンドドロップで入れます。
次は「Analog」⇒「ADC」から「Delta Siguma ADC」を選んで、ドラッグアンドドロップします。

また、アナログの入力ピンも必要なので
「Ports and Pins」から「Analog Pin」を選んで入れます。

どう繋いだか忘れないように外につなぐ部品も「off Chip」から選んで入れておきましょう。入れ終わった段階でこんな感じ。半固定抵抗がセンサーの代わりです。

ピンに入れる前のつなぎ方はこんな感じです。

センサー側で使われる電源はアナログ側の電源のVdda,Vssaを使います。

1μFのコンデンサはADC側で使うのでまだ使いません。
それでは、ΔΣADCの設定をしていきましょう。
設定を開くとこんな感じです。

上から説明していくと

「Modes」では計測を連続、単発にするか、分解能やサンプルレートを設定します。
分解能はどれぐらい電圧を細かく見られるか、
サンプルレートは秒間何個計測できるかとなっています。
ADCでは1番目のキーとなるところで、
分解能が高くてもサンプルレートが正しくなければ誤った計測結果となります。



「Input options - ***」どれぐらいの幅の電圧を分解するかについてです。
シングルエンド入力、差動入力で異なりますし、基準電圧よっても異なります。
今の状態では差動入力となっています。差動入力とはある2線間において
の電圧を測る場合、交流な電圧を測る場合、また外からのノイズが強い場合において
使われます。

「Reference」ADCが使う基準電圧に付いての設定です。
内蔵の基準電圧を使うことも出来ますし、内蔵の基準電圧にコンデンサを追加することも出来ます。また外部の基準電圧を使うことも出来ます。

今回は差動入力の必要が無いので、先ず「Common」のタブを開いて

「Differetial」のラジオボタンを「Single ended」に切り替えて
シングルエンド入力にしましょう。

元のタブに戻ると「Input options」の所が「Single ended mode」となります。

それでは、詳細な設定を上からしていきたいと思います。
Modesの所では、
「Resolution(bits)」をプルダウンメニューの中から14を選び
「Conersion rate」に20000と入力します。

Input options-***では、
「Input range」のプルダウンメニューからVssa to 2.048Vを選びます。
LM61のセンサーは最大1.6VなのでVssa to Vddaまでは必要ありません。

Referenceでは、
「Referense」のプルダウンメニューから
Internal Bypassed on P3.2(P0.3でも大丈夫)を選びます。
高精度の基準電圧を持っていても、ノイズは避けられません。
よって基準電圧とGNDの間にコンデンサを追加してノイズ対策をします。

全ての設定が終わるとこんな感じになります。


設定が終わってOKをクリックしたら
ΔΣADCのコンポーネントがシングルエンド入力に変わっているはずです。

シングルエンド入力の側とアナログ入力側をつなぎましょう。

これで大まかな設定が終わりました。
次はPSoC5LP全体の設定をしていきましょう。
先ずはピンの設定をしていきましょう。
適当で良いです。
1μFのコンデンサはここで登場します。
繋げ方は下の図のように繋げます。



クロックもそのままでも大丈夫だと思いますが、
PLLは24MHzから48MHzにしておいた方がよいでしょう。

そして、今まで触れていないところに触れたいと思います。
「Pins」のタブと同じ列にある「System」のタブを開きます。

このSystemのタブではプログラムの書き込み、デバッグの方法、
どう言う電圧で稼働させているかについての設定が出来ます。

 Systemの画面をスクロールさせるとVdddやVssaについての設定が出ていきます。
スクロールした状態ではVdddからVddio3まで5.0Vとなっているはずです。

ボードによっても異なりますがCQ出版のボードは3.3Vで動かすため
VdddからVddio3までを3.3と入力します。

ここまで終わったら、1度コンパイルします。
今回は長いのでmain.cを書いておきます。

#include <project.h>
#include <stdio.h>//sprintf()を使うのでこれは追加する
int main()
{
    /* Place your initialization/startup code here (e.g. MyInst_Start()) */
    LCD_Char_1_Start();
    //確認用なのでここの部分はあっても無くてもいい。
    LCD_Char_1_Position(0,0);
    LCD_Char_1_PrintString("test");
    CyDelay(500);
    LCD_Char_1_ClearDisplay();
    //ここまではあっても無くてもいい
    ADC_DelSig_1_Start();//ΔΣ使うよ宣言
    int32_t get=0,mvout=0;//戻り値を入れる場所
    double temper=0;//電圧値温度変換用
    char outget[10];//文字変換した後に入れる場所
        CyGlobalIntEnable; /* Uncomment this line to enable global interrupts. */
    ADC_DelSig_1_StartConvert();//ΔΣ変換スタート
    for(;;)
    {
        /* Place your application code here. */
        ADC_DelSig_1_IsEndConversion(ADC_DelSig_1_WAIT_FOR_RESULT);//変換まで待つ
        get = ADC_DelSig_1_GetResult32();//変換数値を入れる
        LCD_Char_1_Position(0,0);
        LCD_Char_1_PrintU32Number(get);//uint32をそのまま出力
        mvout = ADC_DelSig_1_CountsTo_uVolts(get);//変換された数値をμVに変換する
        LCD_Char_1_Position(0,8);
        LCD_Char_1_PrintU32Number(mvout);
        LCD_Char_1_PrintString("uV");
        //電圧値を温度用に計算させる
        temper = mvout;
        temper = temper/1000;
        temper = temper-600.0;
        temper = temper/10.0;
        //計算おしまい
        sprintf(outget,"%.2f",temper);//数値を文字変換する。
        LCD_Char_1_Position(1,0);
        LCD_Char_1_PrintString(outget);
        //LCD_Char_1_PutChar(LCD_Char_1_CUSTOM_0);//LCDのカスタムモードで「」を作った場合
        LCD_Char_1_PrintString("C");//の代わり
       
    }
}

/* [] END OF FILE */


書けたらもう一度コンパイルをして、おしまい。

ピンへの接続が終わったら、書きこんでみましょう。
変換値、電圧値、温度が表記されていれば成功(/・ω・)/。


これでΔΣADCのおおよその全貌が見えてきました。
ADCはサンプルレートが上がる、もしくはビット数が上がれば
ノイズやエリアジングも気にしなければなりません。
今回はビックループでのサンプリングをしましたが
入力のピン数が増えれば、割り込みを使う場合や
サンプリングレートが高ければDMAも使わないと
CPUだけでは正しい計測が出来ません。

高級仕様なのでmb*dの様に簡単には行きませんが
真面目に計測をしたい場合ではこれ位必要でしょう。
また、差動入力も選べますからホイットストーンブリッジも大丈夫です。

私も勉強中ではありますが、これはまだ序の口でしょう…。

2015年1月6日火曜日

セグメントLCDを使ってみよう。

以前に書いた「7segLEDを使ってみよう」の記事にある
「4 Digit 7-segment LED Driver」PSoC4にはありません。

じゃあ、簡単に同じような事をしたい場合はどうしたら?
そう言う場合では、セグメントLCDを使いましょう!

セグメントLCDと言ってもピンと来ないでしょう。
簡単に言えば、キッチンタイマーで使われるような液晶です。
決まった形の表示が出来る液晶で、省電力に優れています。
消費電力の設計が厳しい場合において表示させるには非常に良いでしょう。

LCDと言うと秋月電子とかで見るようなキャラクターLCDの様な
モジュール化された物を想像するかもしれません。
しかし、必ずしもセグメントLCDの場合ではモジュール化されている訳ではありません。

PSoC4,5LPではどのようにべきか
PSoCにはLCDコントローラーが伝統的に(?)導入されています。
ただし、全てのPSoCに入っている訳では無いのではありません。
LCDコントローラーが入っているかどうかはデータシートの確認が必要です。

今回はPSoC4でセグメントLCDとaitendoで売っている
多機能表示器 [JY2941B]を動かしたいと思います。
もちろんPSoC5LPでも似た方法です。

コンポーネントの一覧の「Display」から「Segment LCD」

ドラッグアンドドロップで入れます。
PSoC4ではクロック供給をしてあげる必要があるので
1KHz~のクロックを作って接続します。(私は1MHzでしました。)


始めに設定を開くとこのように出てきます。


7segLEDの時と同じでコモンとセグメント数の設定があります。
ほかは、駆動方法、フレッシュレートフレームレート、ブライトネスコントラストの設定となっています。
フレッシュレートフレームレートを上げるとブライトネスコントラストの設定幅が広がります。
今回はセグメント数とコモンの設定はそのままにして
フレッシュレートフレームレートを120Hz、ブライトネスコントラストを50%にします。

設定が終わったら、「Display Helpers」のタブを開きます。 


この設定では、使う液晶のコモンとセグメントの関係を設定していきます。
今回はこの設定が非常に重要です。
この設定が出来ていないと、便利なAPIを使うことが出来ません。
左側の「Helpers」が設定の候補です。今回は7segなので
「7 Segment」をクリックしたら、緑の右矢印をクリックします。
そうすると次のように画面が変わります。



中段の7セグの表記の「Helpers function configuration」
と下段の「Pixel mapping table」が出てきます
7segのA,B,Cがコモンとセグメントのどれに対応するかを設定していきます。
操作の仕方は、たとえば7セグのAがCom0とseg0が対応しているとします。
まず、7セグのAをクリックして選択します。


選択したらそのまま、PIX0に向かってドラッグアンドドロップします。
出来るとこのようになります。


この作業は7segLCDのデータシートを見ながら設定していくと良いでしょう。
多機能表示器 [JY2941B]用に設定が終わるとこんな感じになります。 


(Helper_Bar_0が足されていますが、コンマ向けです。)
設定を閉じて、ピンの接続と設定をしていきましょう。
LCDの使うピンをPSoC4の適当なピンに接続していきます。
接続が終わったら、LCDのコモン側にはNameがCom[*]LCDのseg側にはSeg[*]に設定していきます。
設定が終わったら、一度コンパイル。
プログラムは2行でおしまい。

2行書いたら、もう一度コンパイルをして書き込みましょう。
7segLCDに「1234」が表記されていれば
成功(/・ω・)/


segmentLCDのAPIは7segLEDのAPIと似ていて、一番左側の桁が0番目となっています。
しかし、7segLCDのAPIは文字(A,B,C)の表記が出来ません。
7segLCDで文字を表記したい場合はピクセルごとにON,OFFが必要になります。
そう言う場合では、14,16segLCDを使う方がよいでしょう。

白黒液晶(TN液晶)は大抵のMCUでは表示させるだけで一苦労ものです。
こう言うタイプの液晶は交流電圧で動くことが出来ます。つまりLEDみたいに
GNDに単純につなげば動いてくれる訳ではありません。PSoCには面倒な事を引き受けて
自分のやりたい事を優先させてくれます。
mb*dで同じことが出来るんですかね??

2014年12月16日火曜日

プログラムをモニターせよ~デバッグを使おう~

mb○dやArdui●oを通常の使い方をした場合では
プログラムのどこのコードが動いているかが分かりません。
お手軽の場合な場合では、マイコンのシリアル通信を使って
シリアル通信のプログラムを反して「どこが動いていますよ」みたいな
事を人力でする感じ。

ですがPSoC Creatorでは「デバック」と言う機能を使って
プログラムのどこのコードが動いていますよ。
と言うのが隅々まで分かるようになります。
また、デバッグ用のプログラムを作る必要もありません。

この機能を使うには
まずPSoC5LPへの書き込み方法を確認しましょう。
「ブートローダ」を使っている場合では「デバッグ」を使うことが出来ません。

ブートローダを使っている場合では
miniProg3やCro_Progキットのような書き込み機を用意しましょう。
PSoC5LPと書き込み機を接続すれば大丈夫です。

freeSoCのような海外のボードやCQ出版のボード、CY8CKIT-050、CY8CKIT-042等は
デバック対応の書き込み機が入っています。

さて、デバッグを使ってみましょう。
難しいことはありません。

LEDドライバーを使って、カウンターコンポーネットの数値を取り出すプログラム
を例にデバッグを使っていきましょう。



カウンターのピリオドを4000としてプログラムをしました。
任意でリセットが出来るようにコントロールレジスタコンポーネット
を使っています。

プログラムを書き終わって、コンパイルが終わったら
虫マークのボタンをクリックしてみましょう。



そうすると画面が少し変わって
下側にメモリーやレジスター、ローカルのタブが付いた画面が出てきます。
これがデバッグ画面になります。



まずは、「StepOver」のボタンを押してみましょう。



クリックすると黄色い矢印と帯が下に進みます。



このようにして、自分のプログラムを進めていきます。
もう一度押すと、7セグLEDに「PSoc」と表示され
プログラムの処理が終わり、次のコードに進みます。
今度は、「Step Into」を押してみましょう。



今度は、別のページに飛びます。




これは「Write7SegDigitHex()」に関するプログラムが表示されています。
用事が無い場合、「Strp Out」を押して自分のプログラムに戻りましょう。



Step Overを押してコードを進めていくと、変数 iに差し掛かります。



そうするとLocalsのタブ上にNameの行の隣のValueの行の数値が変わりました。



この画面では自分できめた変数が表示されます。
また、プルダウンメニューから数値に対する表記方法も変更出来ます。



何度かループを回してみると、変数 i が不思議とif 関数で
リセットをかけたつもりが、かかっていません。
この事から、カウンターコンポーネットのピリオド値を
変えてあげる必要がありそうという事がわかりました。

デバッグを終了するには、「Stop Debugging」をクリックして終了します。



この様に、ビルドの時のミスとは別に
プログラムの良くない所がわかるようになります。

この方法はm●edやArdu●noでは純正環境が無ければ出来ません。
また、無料の時点ではビルドのデータ量に制約が付くため
上位モデルにおいてはビルドすら出来ません。

デバッグを使うことによって、プログラムの裏側で動いている場合でも
何が動いているのが明らかになり、ビルドから漏れたエラーも分かるようになります。
サンプルプログラムからより多くの事も分かるようになるので、
デバッグが使えることは、プログラムに慣れない人にはうれしいですね。

2014年12月7日日曜日

7セグメントLEDを使ってみよう!

ADCの記事が先なのは、十分わかっているのですが。
PSoCまつりで7セグメントLEDを使ったデモを持ってきたので
それの説明、と言うわけ。

さて、7セグメントLEDを通常のマイコンで使う場合
ダイナミック点灯と言う方法を使います。
ダイナミック点灯の簡単な説明をすると
マイコンの入出力ポートにLEDのカソードとアノードの両方を接続して
数字、もしくは文字のように表示させる方法。
ただし、制御がそれなりに面倒な部類で、
プログラムでは配列をつかって
セグメントのON,OFFを繰り返す形で表示させます。

PSoC5LPではどうなのかと言うと

配列云々を使ったりはしません!

では、どうするのかと言うと
LEDドライバーコンポーネットを使います。
「Display」のファイルの中のから「4 Digit 7-segment LED Driver」を選びます。
(これと近いコンポーネットがあると思うが、このタイプを使ってほしい。)



画面にドラックアンドドロップするとこんな形となります。



それでは、LEDドライバーの設定を開けてみましょう。


中の設定は、左側に「ナンバーオブセグメント」
「ナンバーオブコモン」と言う表示があって
右側に「タイミング」「ブライトネスコントロール」と言うのがあります。

「ナンバーオブ***」はセグメントの数と桁の数の設定で
アクティブLowとhigtは7セグメントがアノードコモンか、
カソードコモンなのかによって違います。

アノードコモンである場合はこのままで良いですが
カソードコモンである場合は2つとも逆にします。
また、トランジスタ等でドライブ回路を組む場合にも調整が要ります。

ブライトネスコントロールを使う場合では
タイミングの数値を下げる必要性がありますが
今回はカソードコモンの7セグを使って、
ブライトネスコントロールを使わないので、このまま。
「OK」をクリックして閉じましょう。

閉じたら、今度は配線をしましょう。
配線は少しヤヤコシイですが、カソードコモン4桁の場合を例にやってみます。
アノード側のピンをA~DPまでを抵抗をはさんで適当なピンにつなぎます。
抵抗はLEDに対して1mAになるように選びます。
(電源電圧-下がった電圧/0.001=抵抗値)
コモン側も同じように適当なピンにつなぎます。
この時に必ずつないだポート番号(ピン番号)と7セグの何番ピンを使ったか
のメモしてください。

繋げたらピンアサインの画面を開いて設定をします。
今回は「Name」の行を見ながら作業をしていきます。

NameにはそれぞれCom[0]Seg[0]と言うような事が書いてあります。
コレが重要な目印になってくれています。
図を見ていただきたいのですが、



7segAの所(11番め)につないだPSoC5LPのポート番号を
Nameの行がSeg[0]の所に設定をしてあげます。
7SegBの所(7番目)につないだPSoC5LPのポート番号を
Nameの行がSeg[1]の所に設定をしてあげます。
という形で7segAGseg[0]seg[7]に一致するように設定します。

コモン側の設定は4桁の左側が基準になるように設定をしていきます。
たとえば4桁の左側、一桁目のコモンの12番目につないだPSoC5LPのポート番号には
Nameの行がCom[0]の所に設定をしてあげます。

こう言う形だとちょっと面倒かもしれませんが
ポートごとでの設定と言うことも出来ます。今回は省略させていただきます。

設定が出来るとこんな感じ。



ここで一度、コンパイルをしましょう。
コンパイルが出来たら「main.c」を開いて

3行書きます。




LED_Driver_1_WriteStering7Seg()では「C」の文字がどうしても小文字で表記されるので
LED_Dreiver_1_Write7SegDigitHex()を使って16進数表記で「C」を表記しています。

もう一度コンパイルして書き込みましょう。
そうしたら7セグLEDに「PSoC」と表示されますね。
そうしたら成功(/・ω・)/

PSoC5LPではトランジスタ等が必要にはなりますが、16セグまで同じやり方で動きます。
16セグのLEDが手に入れば、表記の幅も広がって表現が豊かになりますね。

どうでしょう?arduinombedでは出来ない芸当です。
またカメラを通して見てみるとダイナミック点灯で起きるチラつきがありません。
CPUが最低限の事をしていませんから当然ですね。

~~~~ソース電流とシンク電流について~~~

今回、LEDをつなぐ際に
1mAになるように抵抗を選んでください」と書きました。
これはPSoC5LPに吸い込める電流値が「8mA」と決まっているためです。
吸い込める電流をシンク電流
出せる電流をソース電流
と言ってどのON,OFFするような回路にも出てきます。




PSoC5LPではシンク電流が8mA、ソース電流が4mA
決まっています。
SIOと言うデジタル専門のピンを使えばシンク電流を25mAまで拡張出来ます。