3: 2014-06-30 (月) 01:40:06 なーお ソース 4: 2014-06-30 (月) 10:28:38 なーお ソース
Line 16: Line 16:
-- [[mbed LPC1114でLチカしてみた(2):http://www3.big.or.jp/~schaft/hardware/tips/LPC1114/page002.html]]:しなぷすのハード製作記 -- [[mbed LPC1114でLチカしてみた(2):http://www3.big.or.jp/~schaft/hardware/tips/LPC1114/page002.html]]:しなぷすのハード製作記
 LPC1114限定で「LPCISP」というソフトを公開しておられます。USB/serialコンバーター経由で一発書き込み、即座にリセットが働くので、楽ちんです。  LPC1114限定で「LPCISP」というソフトを公開しておられます。USB/serialコンバーター経由で一発書き込み、即座にリセットが働くので、楽ちんです。
 +|&ref(LPCISP_0.jpg,mw:360,mh:360);|
- ハード図 - ハード図
- ブレッドボードを使うとテストは楽にできるけど、ちゃんと図面を書いておかないと、一度バラしたら再現するのが面倒になっちゃいますんで、書くクセをつけたいですね。今回は資料への使いまわしがしやすいようにEXCELでこんな感じで書いてみました。 + ブレッドボードを使うとテストは楽にできるけど、一度バラしたら再現するのが面倒になっちゃいますんで、ちゃんと図面を書くクセをつけたいですね。今回は資料への使いまわしがしやすいようにEXCELでこんな感じで書いてみました。 
--- LPC1114のLED回路はソース出力(PNP)でプラスコモン、FT232RLのLEDモニタ回路は、シンク出力(NPN)マイナスでコモンになっているみたいで、ちょっと混乱します。+-- LPC1114のLED回路はソース出力(PNP)でプラスコモン、FT232RLのLEDモニタ回路は、シンク出力(NPN)でマイナスコモンになっているみたいで、ちょっと混乱します。 
 + 工業用制御部品に関していえば、日本国内やアジア圏ではシンク(NPN)でマイナスコモン、欧州ではソース出力(PNP)でプラスコモン が多いですが、欧州への輸出時にはCEマーク表示の関係で本質安全の考え方から必ずPNPにしないといけなくなるため、国内でもPNPへの変更が徐々に進んでいる・・ のかなあ? 
 + 組み込み部品での状況は全くわからずです。
|&ref(mbed_UART_SERVO.jpg,mw:480,mh:360);| |&ref(mbed_UART_SERVO.jpg,mw:480,mh:360);|
 +
 +|&ref(site://modules/dblog1/upimg/00215f18aa1dcaf25bbcdb400acb72dfcb.jpg,mw:360,mh:360);|
 +
 +*** プログラム [#n356f22a]
 + mbedはarduinoと違い、ほぼ素のC/C++で書けます。 オンラインコンパイラでビルドが通ったプロジェクトをエクスポートして、外部のIDEで編集・コンパイルできることからもそれを実感できます。
 +
 + とはいえまずはオンラインコンパイラで。
 +
 +|&ref(mbed_WorkSpace_0.jpg,mw:480,mh:360);|
 +
 +**** 使用ライブラリ [#tb797654]
 +- Servo
 + mbedのオンラインコンパイラ状の「Import」でキーワード「Servo」検索し、sford cstyles さんの [[mbed R/C Servo Library:http://mbed.org/users/simon/code/Servo/]]を試しに使ってみました。
 +- MySerial
 + [[自作ライラリ MySerial:http://mbed.org/users/naao/code/MySerial/]] です。mbed標準のRawSerialクラスを継承し、受信文字列のchar配列格納を簡単にできるようにしてみました。 現時点でのソースを貼っておきます。
 +-- GetString メソッドは、テンプレート化でオーバーロードしてあり、引数にポインタ変数指定でも char配列指定の参照でも使えるようにしました。
 +-- Wait時間の設定を追加してあります。
 + その他APIは、[[こちらを参照:http://mbed.org/users/naao/code/MySerial/docs/930d325f3d31/classMySerial.html]]。
 +
 +-- MySerial.h
 +#code(c,0-){{
 +/** mbed Serial Library extend RawSerial
 + * Copyright (c) 2014 Naoki Okino
 + *
 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 + * THE SOFTWARE.
 + */
 +#ifndef MBED_MYSERIAL_H
 +#define MBED_MYSERIAL_H
 +
 +#include "mbed.h"
 +
 +/** MySerial control class, based on a RawSerial
 + *
 + * Example:
 + * @code
 + * #include "mbed.h"
 + * #include "MySerial.h"
 + *
 + * MySerial pc(USBTX,USBRX);  //instance of MySerial Class
 + * char cWord[16]; //receive chars  or cWord[256], cWord[1024] etc..
 + *
 + * void readbuf()
 + * {
 + *  // int iRtn =  pc.GetString(6,&cWord);    //Serial received chars by pointer cWord
 + *    int iRtn =  pc.GetString(6,cWord); //Serial received chars byref of cWord
 + * }
 + * int main() {
 + *    pc.baud(9600);                  //set baud rate
 + *    pc.format(8, MySerial::None, 1);//set bits for a byte, parity bit, stop bit
 + *    pc.SetRxWait(0.01, 0.001);      //set wait getting chars after interrupted, each char
 + *    pc.attach( readbuf, MySerial::RxIrq );    //Set Interrupt by Serial receive
 + * }
 + * @endcode
 + */
 +class MySerial : public RawSerial{
 +
 +public:
 +   /** constructor to get chars received by serial
 +     *
 +     * @param PinName tx
 +     * @param PinName rx
 +     */
 +   MySerial(PinName tx, PinName rx);
 +
 +   /** set wait getting chars after interrupted
 +     *
 +     * @param float _fRxStartWait wait getting a 1st char after interrupted
 +     * @param float _fRxEachWait wait getting each char
 +   */
 +   void SetRxWait(float _fRxStartWait, float _fRxEachWait);
 +
 +   /** function to get chars after received chars by serial
 +     *
 +     * @param int size for get chars
 +     * @param *cWord returns got chars by pointer
 +     * @param returns success by 0
 +     */
 +   virtual int GetString(int size, char *cWord);
 +
 +   /** overload function to get chars after received chars by serial
 +     *
 +     * @param int size for get chars
 +     * @param cWord returns got chars by ref
 +     * @param returns success by 0
 +     */
 +   template <class X> int GetString(int size, X cWord)
 +   {
 +       return GetString(size, &cWord);
 +   }
 +
 +protected:
 +   float fRxStartWait;
 +   float fRxEachWait;
 +
 +};  /*  class MySerial  */
 +
 +#endif
 +}}
 +
 +-- MySerial.cpp
 +#code(c,0-){{
 +#include "MySerial.h"
 +
 +MySerial::MySerial(PinName tx,PinName rx):RawSerial(tx,rx)          //constructor
 +{
 +   fRxStartWait = 0.01;    //wait getting a 1st char after interrupted
 +   fRxEachWait = 0.001;    //wait getting each char
 +}
 +
 +void MySerial::SetRxWait(float _fRxStartWait, float _fRxEachWait)
 +{
 +   fRxStartWait = _fRxStartWait;  //wait getting a 1st char after interrupted
 +   fRxEachWait = _fRxEachWait;    //wait getting each char
 +}
 +
 +int MySerial::GetString(int size, char *cWord)            //by pointer
 +{
 +   int i=0;
 +   int ichar;
 +   memset(cWord, '\0', strlen(cWord));  //initialise chars
 +
 +   wait(fRxStartWait);
 +
 +   while(1) {
 +       if(!readable())    {
 +           break;
 +       }
 +       ichar = getc();
 +       if(i<size) {
 +           cWord[i] =ichar;
 +           //putc(ichar);
 +       }
 +       i++;
 +       wait(fRxEachWait);
 +   }
 +   return 0;
 +}
 +}}
 +
 +**** メイン [#w251f1f2]
 +- シリアルコマンド
 +ただの実験なので、<STX><ETX>などの制御コマンドは一切無しです。(汗)
 +-- 「start」で開始
 +-- 「pxxx」(xxxは角度)で位置決め
 +-- 「stop」で停止
 +です。
 +- 受信の割り込みと、50ms定時タイマ割り込みを受けてメインで動作及びLチカさせてみました。
 +-- 割り込みのIRQ変数名は、シリアルが「UART_IRQn」、定時タイマが「TIMER_16_0_IRQn」でしたので、割り込み優先度や割り込み禁止を個別に管理できます。 この辺の定義は、[[こちらに全部書いてあります:http://mbed.org/users/mbed_official/code/mbed-src/file/1b2bee05fe98/targets/cmsis/TARGET_NXP/TARGET_LPC11XX_11CXX/LPC11xx.h]]ね。
 +
 +- まだ試していませんが、フロー制御を入れないと9600bps以外では取りこぼしが発生します。
 +- ソース
 +volatile のつけ方などわかっていないので、まだ適当です。
 +-- main.cpp
 +#code(c,0-){{
 +#include "mbed.h"
 +#include "Servo.h"
 +#include "MySerial.h"
 +
 +Servo myservo(dp18);
 +MySerial pc(USBTX,USBRX);        //instance of MySerial Class
 +Ticker timer;
 +DigitalOut led2(LED2);            //alive check LED
 +
 +volatile int cntRx=0;
 +volatile int cntRx_old=0;
 +volatile int timeUp=0;
 +volatile int timeUp_old=0;
 +
 +char cWord[6]; //receive chars  or cWord[256], cWord[1024] etc..
 +char *pCword = cWord;    //pointer for cword
 +const char ccStart[6] = "start";
 +const char ccStop[5] = "stop";
 +const char ccMove_[2] = "p";
 +
 +int readSize = 5;
 +int doStatus;
 +int iDeg;
 +
 +void atRx()
 +{
 +   NVIC_DisableIRQ(UART_IRQn);
 +   cntRx++;
 +}
 +
 +void atTimer()
 +{
 +   //NVIC_DisableIRQ(TIMER_16_0_IRQn);
 +   timeUp++;
 +}
 +
 +void readbuf()
 +{
 +   pCword = cWord;    //pointer for cword
 +
 +   //int iRtn =  pc.GetString( readSize, &cWord[0] ); //Serial received chars by pointer of cWord
 +   int iRtn =  pc.GetString( readSize, cWord ); //Serial received chars byref of cWord
 +
 +   if(strcmp(cWord, ccStart)==0) {    // start
 +       doStatus=1;
 +       printf("started\n");
 +   } else if(strcmp(cWord, ccStop)==0) { // stop
 +       doStatus=0;
 +       printf("stopped\n");
 +   } else if(cWord[0]==ccMove_[0]) { // 1st char matches
 +       pCword++;                    // increment pointer to get after 2nd chars
 +       iDeg = atoi( pCword );
 +       printf("%d\n",iDeg);
 +   } else {                        //no action except for start/stop
 +       printf(" no match %s\n" , cWord);
 +   }
 +   if ((doStatus == 1) && (0 <= iDeg) && (iDeg <= 180)) {
 +       wait(0.01);                          // waits for the servo to get there
 +       myservo.position(iDeg - 83.0);
 +   }
 +}
 +
 +int main()
 +{
 +   pc.baud(9600);                  //set baud rate
 +   pc.format(8, MySerial::Odd, 1);//set bits for a byte, parity bit, stop bit
 +   //pc.format(8, MySerial::None, 1);//set bits for a byte, parity bit, stop bit
 +   //pc.set_flow_control(MySerial::RTSCTS,dp26,dp25);
 +   pc.SetRxWait(0.01, 0.001);      //set wait getting chars after interrupted, each char
 +
 +   wait(0.25);    //startup wait
 +
 +   pc.attach( &atRx, MySerial::RxIrq );    //Set Interrupt by Serial receive
 +   NVIC_SetPriority(UART_IRQn, 120);
 +   timer.attach( &atTimer, 0.05 );
 +   NVIC_SetPriority(TIMER_16_0_IRQn, 10);
 +
 +   myservo.calibrate(/* range */ 0.00099, /* angle +/- */ 90.0);
 +
 +   while(1) {
 +       wait(0.01);
 +
 +       if(cntRx != cntRx_old)
 +       {
 +           readbuf();
 +           cntRx_old = cntRx;
 +           NVIC_EnableIRQ(UART_IRQn);
 +       }
 +
 +       if(timeUp != timeUp_old)
 +       {
 +           if( 10 <= timeUp )
 +           {
 +               led2 = !led2;
 +               timeUp=0;
 +           }
 +             timeUp_old = timeUp;
 +           //NVIC_EnableIRQ(TIMER_16_0_IRQn);
 +       }
 +   }
 +}
 +}}
 +
 +** 実行結果 [#r5494d56]
 +
 +シリアルコンソールには、定番のTeraTermではなく、「[[RS232cTOOL:http://homepage2.nifty.com/nonnon/Download/Rs232cTool/]]」というフリーソフトを使ってみました。
 +
 +下図のように、コマンドを送ると帰ってきたアンサーが表示されます。
 +|&ref(Comm_0.jpg,mw:480,mh:360);|
 +
 +** 総括 [#uadc2152]
 +
 + mbed、おもしろいです。 C/C++の入門にもなるし、ハード回路の勉強にもなります。
 +
 + 次回は、オフラインでのコンパイルとデバグ環境にチャレンジしたいと思います。
[[inc/mbed]] [[inc/mbed]]


トップ   差分 バックアップ 複製 名前変更 リロード印刷に適した表示   ページ新規作成 全ページ一覧 単語検索 最新ページの一覧   ヘルプ   最新ページのRSS 1.0 最新ページのRSS 2.0 最新ページのRSS Atom Powered by xpWiki
Counter: 4247, today: 1, yesterday: 0