2013年1月24日木曜日

トラ技(2012-10)付録 LPC1114を試しました。

 遅ればせながら、CQ出版 トランジスタ技術 2012年10月号 付録の NXP LPC1114を試しました。

 昨年 同誌をとりあえず購入、3か月余り書棚にしまいこんだままでした。しまいこんだ割には、その付録が気になっていました。付録は他の雑誌付録と違ってLPC1114単体、「一体どうやって使うのだろう?」 4KバイトのRAM、32KバイトのフラッシュROM、記事の通り「チョコット試す」にはもったいないようなスペック。
 今日、改めて記事を眺めてみました。すると、LPC1114を試すには、USB シリアル(RS232C、UART)のIFドライバIC、電源レギュレータ―等諸々、が必要であることが分かりました。
  入手できそうなIFドライバはFT231X(ICパッケージはSSOP-20)、電源レギュレータは手持ちかあるが結構手間取ることになりそう。
 ふと、傍らのTIのLaunchPad パッケージに目が止まりました。LunchPadを使えば、「USB-UART(Rx Tx)変換が簡単に利用出来そう!」「Vddの出力もある!」「USBドライバーのインストール不要!」 早速LPC1114のプログラミングに挑戦。以下にその顛末を述べます。    
 
まず、開発環境の整備
 
1.MDK-ARMのインストール(不要)
Interface誌付属 FM3基板を試したときインストールしたKeil uVision4の機能を確かめる。
 新規プロジェクト作成で対応CPUをみると
LPC1114/201  ~ LPC1114/323 が対応していました。
そこで LPC1114/102 用にデバイスデータベースをインストールしました。
 1)付録CDで立ち上がるIE HTMLページでMDK-ARM_NXP_LPCxxxx.exeを実行
 2)Keil uVision4を再度立ち上げ新規プロジェクト作成
   Select a CPU Data Base Fileで「NXP LPC Family Device Database」が選択可能になり そこに登録されているLPC1114/102でプロジェクト作成が可能になりました。
2.MyARM_sampleのインストール
   サンプルプログラムを入手するためインストールしました。
3.Flash Magicのインストール
サンプルプログラムによる、プログラム開発の実施
  
  
  
  
4.LPC1114の周辺回路の構築
   ・電源 Vdd、Vss    必須
   ・UART Rx、Tx    必須
   ・スイッチ SW1 (PIO0_1)  SW2(Reset) 必須(ブートローダでISPを起動させるため・・・後述)
   ・LED  LED1(PIO0_7) LED2(PIO1_5)  適宜
5.サンプルプログラムMDK-sampleをビルド/プログラム書き込み/実行
 

メモ
●Flash Magicでのプログラム書き込み。
  FlashMagic側) Baud Rateを115200に指定 InterfaceをNone(ISP)に
  PC側) デバイスマネージャでCOMポート ボーレートを1152000 に設定
●書き込み失敗時
  SW1(PIO0_1) SW2(RESET)同時 Push後 再度書き込む。
   (CPUリセット時 PIO0_1がLowの場合 ISPが起動、UARTによるプログラムの書き込みが可能になります。)

●トラ技2012-10号 P62 の図1の回路図でRXD/TXDの配線間違いがあるので注意
(Flash Magicで、てこずった原因)

2013年1月15日火曜日

NHD-C12864でチャート表示を試しました。

  TI Stellaris LaunchPadで作成した電子温度計の表示をSUNLIKE社SG12864aの他、Newhaven Display NHD-C12864でも試しました。
 SG12864のデータインターフェースはパラレル、一方NHD-C12864はシリアル、当初、SG12864の方が、表示能力に勝ると思われたのですが、最小限の表示プログラム改造でNHD-C12864を稼働させると、遜色ない結果になりました。逆に、SG12864で起こる表示の乱れがNHD-C12864で起こらない満足いく結果になりました。
 
 
NHD-C12864による温度チャート表示

SG12864による温度チャート表示
SG12864では頻繁に表示の乱れが起こり、各信号のタイミング調整でなんとか、対応しようとしています。











  NHD-C12864は、マイコンとのIFは5本(GPIO4本 /RES1本)、さらに、LCDドライバICが1つで、これがSG12864に較べ扱いやすいLCDとなっていると思われます。



 





グラフィックLCD NHD-C12864A1Zを試しました。

Newhaven Display International社 グラフィックLCD NHD-C12864A1Z-FSB-FBWを試しました。
 これまではTI Stellaris LaunchPadでSUNLIKE社グラフィックLED SG12864 を使用していました。SG12864ではGPIOピンを13本占有するので、開発アプリケーションが自ずと制限されます。
 そこで、データインターフェースがシリアルのLCDを探したところ、DigiKeyでNHD-C12864A1Zを見つけ、早速に入手しました。

NHD-C12864A1Zは、
 ・マイコンとのインターフェースはGPIOピン4本でOK
 ・0.1インチ(2.54mm)ピッチの12本のピン (6×2)
 ・3.3V駆動 (No.9ピン H+ ヒータ用の12Vの給電があるが、いまいち不明?)


最初、シリアルのデータインターフェースはSPI(SSI)やI2Cを使うと予想していたのですが、ドキュメントに記載された、初期化コードをみると、単純にGPIOのHi/Low出力でSCLとSI(SDA、Tx)を実現しているようで以下のコーディングを行いました。

  * シリアルによるデータ出力 1バイトの出力データ siout を シフトさせながら1ビットづつ出力

     for(i=0;i<8;i++)
     {
      lcd_SCL_low();          //SCL:Low
      if(siout & _10000000B)
      {
        GPIOPinWrite(LCD_PORT_BASE, LCD_PIN_SI, LCD_PIN_SI);  //SI:High
      }
      else
      {
        GPIOPinWrite(LCD_PORT_BASE, LCD_PIN_SI, 0);      //SI:Low
      }
      lcd_SCL_high();        //SCL:High
      siout = siout <<1;       //1ビットのシフト
     }


*感想 
  ・表示内容により、濃淡のムラがある。
  ・比較的簡単に表示が実現。
   (SG12864では、各信号の出力タイミングの調整が必要でしたが、今回は簡単に表示が確認出来ました。)

2013年1月12日土曜日

.Net (VC++) Chartクラスを使ってグラフを表示


先日作成した電子温度計(Stellaris LM4F120)とPCとの連携を行いたいと思い、測定データをPCに取り込み、データのグラフ表示を試しました。
以前VC++でグラフ表示を行った時 System::Drawing::Graphics等の Drawing配下のクラスを利用しましたが、今回は、Chartクラスを使ったグラフ表示を試しました。
 
===================================================================
1.概要
     電子温度計 [UART] ==(USB)== [COMポート]  PC
                      測定温度

  デザイン
   VC++でWindowsフォームアプリケーションでプロジェクトを作成する。
   Form1にChart、SerialPort オブジェクトを追加 設定する。

  初期処理
   Chart/Seriseに1024個のDataPointを値0で登録する。
  メイン処理  
   シリアルポート受信イベントで電子温度計が出力する温度データを取り込む。
   取り込んだ温度データを順次 Chart/Serise/DataPointオブジェクトに設定する。

===================================================================
2.VC++プロジェクト作成<<非時系列チャート>>
 1)Chart設定
   Form1にChartオブジェクト chart1 を作成
     プロパティ設定 Seriseコレクション(ChartType:Line)
 2)SerialPort設定
   Form1にSerialPortオブジェクト serialPort1を作成
     プロパティ設定 BaudRate と PortNameを設定
   
   
 3)コーディング コンストラクタ Form1(void)
   ①Charting/Seriesオブジェクト series1tをローカル宣言
     System::Windows::Forms::DataVisualization::Charting::Series^  series1t;
   ②chart1のSeries1を①で宣言したseries1tに読みだす。
     series1t = this->chart1->Series["Series1"];
   ③Charting/DataPointオブジェクトを初期値で作成。
     
     System::Windows:・・・:Charting::DataPoint^  tmppoint
      = (gcnew System::Windows::・・・::Charting::DataPoint(i,0));
   
   ④Charting/DataPointオブジェクトを①で宣言したseries1tに登録する。
     series1t->Points->Add(tmppoint);
   *③④を繰り返し1024のDataPointオブジェクトをseries1t(chart1/Series1)に登録する。

   ⑤シリアルポートをOpenする。
     this->serialPort1->Open();

 4)コーディング シリアルポート受信イベント処理 (serialPort1_DataReceived)
   ①Charting/Series、Pointsオブジェクト series1t、tmppoint をローカル宣言
   ②DateTime型で現在時刻を取得する。
     DateTime timesp =   System::DateTime::Now;
   ③シリアルポート受信データを取り込み、温度データを抽出する。
     strreceive = this->serialPort1->ReadLine();   [[strreceive:String]]
     strvalue = strreceive->Substring(7,6);  [[strvalue:String 温度データ位置:7]]
   ④取得した温度データでSeries1のDataPointを更新する。
     (インデックス指定で、一旦Series1のDataPointを削除して、取得した温度データでDataPointオブジェクトを作成し登録し直す。)
     series1t = this->chart1->Series["Series1"];
     tmppoint = series1t->Points[IntPointIndex];    [[IntPointIndex:DataPointインデックス]]
     series1t->Points->Remove(tmppoint);
     System::Windows:・・・:Charting::DataPoint^  tmppoint1
      = (gcnew System::Windows::Forms::DataVisualization::Charting::DataPoint(IntPointIndex,System::Convert::ToDouble(strvalue)));
     series1t->Points->Insert(IntPointIndex,tmppoint1);

  5)エラー対処
    このコーディングでプログラムを実行すると、不定期のタイミングで「InvalidOperationException ”コレクションが変更されました。実行されない可能性があります。” エラー」が発生します。
    ①原因の予想
      チャート表示処理中にチャート情報の更新が重なったため起きたエラーと思われます。
    ②対処
      Serise1/DataPointオブジェクトの削除、挿入処理はChartを一旦非表示にして実行する。
         this->chart1->Visible = false;       


===================================================================
3.VC++プロジェクト作成 <<時系列チャート>>

 1)Chart設定
     プロパティ設定 Seriseコレクション(ChartType:Line  XValueType:Time
 2)SerialPort設定
   
   
 3)コーディング コンストラクタ Form1(void)
   ①シリアルポートをOpenする。

 4)コーディング シリアルポート受信イベント処理 (serialPort1_DataReceived)
   ①Charting/Seriesオブジェクト series1tをローカル宣言
   ②DateTime型で現在時刻を取得する。
   ③シリアルポート受信データを取り込み、温度データを抽出する。
   ④取得した温度データでDataPointを作成し Series1に登録する。
         System::Windows:・・・:Charting::DataPoint^  tmppoint2
          = (gcnew System:・・・:Charting::DataPoint(timesp.ToOADate(),System::Convert::ToDouble(strvalue)));
      series1t->Points->Add(tmppoint2);
   ⑤Series1に登録されたDataPointオブジェクトが1024を超えた場合。先頭のDataPointオブジェクトを削除する。
      series1t->Points->RemoveAt(0);

===================================================================
※メモ
 ●DataPointの設定
 DateTime値をDataPointのX値に設定する場合 ToOADate()メソッドを使用する。
●チャートデータの更新処理の工夫
 データDataPointコレクションの更新時 Chatオブジェクトは非表示にする。 (前述)

※気になる点
●MicroSoftのmsdnオンラインドキュメントの不備
ChartクラスのSystem名前空間からの継承階層はSystem::Windows::Forms::DataVisualization::Charting::Chartですが、オンライドキュメントでSystem名前空間から繰るとSystem::Windows::Forms名前空間 止まりでした。また、DataVisualization名前空間配下の Series等のクラスではドキュメントの繰り方で、内容の無いページが現れます。
 とにかく、Chartクラスを使うのには情報が少ない。