TOPPERS/R2CA
本田 晋也
名古屋大学 大学院情報科学研究科
honda@ertl.jp
TOPPERS活用アイデア・アプリケーション開発コンテスト 2015年7月2日概要
ArduinoボードでArduinoライブラリとTOPPERS/ASPカーネルを用い
たプログラミングが可能なTOPPERS/R2CAについて紹介
•
アジェンダ
−
Arduino
•
TOPPERS と Maker Movement
−
TOPPERS/R2CA
−
R2CAの使用方法
•
サンプルの実行
•
マルチタスク
−
サンプルプロジェクト詳細
−
まとめ
Maker Movement
• 技術発展によりものづくりが容易になり,スタートアップ企業や個人が アイデアを具体化する流れが活発化している −これらの人々がコミュニティを形成して交流 • 要因 −インターネットの発達 • オープンソースハードウエア,ソフトウェア • 特定の趣味を持つ人が繋がり安くなった −安価なハードウェア • 数千円のマイコンボード −容易に使用可能な開発環境 • インストーラによるインストール,Webコンパイラ −工作機器の発達と利用可能箇所の増大Arduino
• Makerの作品で広く使われているマイコンボードとIDEをセットにした環境 − 安価で容易に使える − 書籍等の情報が豊富 • Arduinoボード − 各種マイコンを用いたボード(数十種類存在) − Arduino Uno : 最も一般的なArduinoボード• Atmel ATmega328P, Flash 32KB, RAM 2KB − オープンハードウェアなためクローンのボードも存在 • ArduinoIDE − マルチプラットホームの開発環境 − インストーラによりコンパイラ(GCC)やArduinoライブラリ がインストールされる − ボタンを押すだけでコンパイルとボードへの書き込みが可能 − デバッグ機能はない(printfデバッグ)
Arduino
• Arduinoプログラミングモデル − setup()/loop()による容易なモデル − C++ベースの独自言語 • プロトタイプ等は必要なし − Arduino IDEがC++に変換してコンパイル • Arduinoライブラリ − コアライブラリ• IO操作(GPIO, AD, SPI, I2C),時間,文字列操作 − Arduino準拠ライブラリ • コアライブラリの上で実現されたライブラリ • Arduino IDEに含まれるライブラリ SD,LCD,USB,Audio等のライブラリ • その他,センサーやシールドに含まれるライブラリ void setup() { pinMode(13, OUTPUT); } void loop() { digitalWrite(13, HIGH); delay(1000); digitalWrite(13, LOW); delay(1000); }
Arduino
• シールド −拡張ピンに接続することによりハードウェア機能を拡張するボード • 物理的には拡張ボードにおけるディファクトとなっている −電気的互換性がない場合があるので注意(5V or 3.3V) −Wifi, LCD, SD,ロボット,センサーArduinoに対する拡張
•
マルチタスク(RTOS)を使用したい
−
複数の処置を平行に実行したい
−
処理毎にコードを分けたい
−
例)アクチュエータを制御しながらIoTサーバーと通信したい
•
デバッガを使用したい
−
変数の状態を確認したい
−
デバイスドライバの開発のためにデバイスレジスタの値を見たい
コンソール タスク LED タスク センサー タスク Webサーバ タスク Processing TFT/SD Ar dui no ライブラリ Ar dui no ライブラリASPカーネルとArduinoライブラリを組み合わせた環境
•
マルチタスク環境でArduinoライブラリを使用可能
•
GUIベースのデバッガを使用可能
•
TOPPERSの問題点の解決
−開発環境の導入や使用の敷居が高い • Arduino IDEをインストールするだけでビルド可能 • バッチファイルによるビルドが可能 • 安価で入手性の良いArduinoボードで実行可能 • マクロの定義によるタスクの生成 −ライブラリ・ミドルウェアが少ない ArduinoコアライブラリTOPPERS/R2CA
(RTE/RTOS compatible with Arduino libraries)ASPカーネル
Task1 Task2 Task3
R2CAの使用方法
インストール・ビルド・実行・デバッグ・プログラミングモデルについて説明 • Qiitaにもチュートリアル記事がある(R2CAで検索すると出てくる) −基本的な使い方 • インストールとサンプルの実行,マルチタスク,優先度・スケジュー リング,デバッグ −通信 • Wifi通信,Wifi通信(マルチタスク),CAN通信 −IoT • Milkcocoaへの接続,ThingSpeakへの接続 −Shield• Zumo,NCES IoT Base Shield −MacOSXでの使用方法
必要な機材
• ホストPC −Windows or Mac OS −本チュートリアルではWindowsで説明 −Linuxでも動作するはず • Arduino M0 Pro −6000円程度−秋月,Amazon, Switch Science,マルツパーツ等で購入可能 −Cortex-M0+ 48MHz/ROM 256KB/RAM 32KB
−デバッガ機能あり(EDBG(Atmel’s Embedded Debugger))
• デバッガ機能なしのArduino M0 もあるが推奨しない
Arduino UNOとの互換性が低いためプログラムの書き換えが必要
ツールのインストール
• Arduino IDE −Arduino.org(http://www.arduino.org/downloads)からダウンロード • 動作確認済みバージョン : 1.7.10 −!!Arduino.ccではないため注意!! −インストーラによりインストール • GCC/Make/GDB/OpenOCDがインストールされる • ターミナルエミュレータ −Teraterm等をインストール • 以下のツールはオプション −Cygwin • コマンドラインからのビルド −Atmal Studio • GUIによるデバッグR2CAパッケージのダウンロード
• TOPPERSのContributed Softwareから公開 − trac • http://dev.toppers.jp/trac_user/contrib/wiki/rtos_arduino • http://dev.toppers.jp/trac_user/contrib/browser/rtos_arduino/trunk tracのZIPダウンロード機能は使用出来ないため注意 − svn • http://dev.toppers.jp/svn_user/contrib/rtos_arduino/trunk • ダウンロード方法 − SVNクライアントをインストールしてチェックアウト • TortoiseSVN, CygwinのSVNクライアント • パッケージの更新頻度が高いのでこの方法を推奨 • ZIPファイルをダウンロード • http://dev.toppers.jp/trac_user/contrib/attachment/wiki/rtos_arduino/r 2ca_20160521.zipフォルダ構成
• パッケージのフォルダ一覧
−./arduino_lib : Arduinoライブラリ • hardware : コアライブラリ
• libraries : Arduino準拠ライブラリ
−./asp_1.9.2 : Arduino M0 依存部を含む ASP 1.9.2ソースコード −./examples : サンプルプロジェクト −./lib : R2CAライブラリ • Arduinoライブラリについて −Arduino IDEに付属のライブラリがベース −バグフィックスやマルチタスク対応のための排他制御を入れている −ライセンスはGPLやMIT −librariesにはArduino IDE付属以外のライブラリも含まれている
セットアップ
• Arduino IDE のインストールパスの設定
− 以下のファイルの”C:¥Program Files (x86)¥Arduino”の箇所を書き換える • example/do_path.bat
SET ARDUINO_DIR=C:¥Program Files (x86)¥Arduino • asp_1.9.1/target/arduino_m0_gcc/Makefile.target
ARDUINO_BASE_DIR_WIN = C:¥Program Files (x86)¥Arduino • ボードの接続
− M0のPROGRAMMINGポートとPCをUSBケーブルで接続
− ドライバがインストールされ,COMポートとEDBGが認識される − COMポートの番号を確認して,Teraterm等で115200bpsで接続
サンプルの実行
ボード上のLEDを点滅させるサンプルをビルド&実行する • フォルダ : ¥examples¥Basic • ユーザープログラム等 − Makefile : ライブラリやファイルの指定 − rca_app.h : ユーザープログラムヘッダーファイル − rca_app.cpp : ユーザープログラムプログラムファイル − rca_app.cfg : コンフィギュレーションファイル(静的APIを記述) − pitches.h : プログラムで使用するヘッダファイル • バッチファイル − do_make.bat : ビルド − do_run.bat : ビルド&書き込み&実行 − do_clean.bat : ファイルのクリーン − do_debug.bat : ビルド&書き込み&デバッグ • AtmelStudio用ファイル − rca.atsln,rca.componentinfo.xml,rca.cprojサンプルの実行 : プログラムの選択
• ¥examples¥Basic¥rca_app.cpp には,Arduino IDE に含まれているサン プルを複数含む.マクロで実行するプログラムを選択可能
• #define BLINK : LED点滅 サンプル
• #define toneMelody : ブザーサンプル
• #define USBUART : USB-UARTサンプル
• #define SERIALUSB : UARTサンプル(EDBGポート経由)
• #define SERIAL5 : UARTサンプル(TX/RXポート経由)
• #define ATTACHINTERRUPT : 割込みサンプル • #define ANALOGWRITE : PWMサンプル • #define ANALOGREAD : ADサンプル
• #define RTC_ALARM : RTCアラームサンプル
サンプルの実行 : プログラムの内容
• setup() : 起動時に一度だけ実行される関数 • loop() : 繰り返し実行される関数
• Atrduinoのサンプルからの変更点はR2CA用ヘッダのincludeのみ
#include "rca.h“
// the setup function runs once when you press reset or power the board void setup() {
// initialize digital pin 13 as an output. pinMode(13, OUTPUT);
Serial.begin(115200); }
// the loop function runs over and over again forever void loop() {
digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level) Serial.println("HIGH");
delay(1000); // wait for a second
digitalWrite(13, LOW); // turn the LED off by making the voltage LOW Serial.println("LOW");
サンプルの実行 : ビルド
•
do_make.bat をダブルクリックするとビルドが開始される
•
ASPカーネル&Arduinoライブラリ&ユーザープログラムがビルドされ
てダウンロードファイルが生成される
•
check completeが出ればビルドは成功
−
rca.elfが出来ている
サンプルの実行 : 実行
•
do_run.bat をダブルクリックすると書き込みが行われる
−
OpenOCDによる書き込み
•
書き込み後に実行される
サンプルの実行 : デバッグ
Atmel Studioによるデバッグ方法を説明 • Atmel Studioをインストール
サンプルの実行 : デバッグ
• メニューの“Build”から“Build Solution”を選択するとビルドが開始される
• メニューの"Debug"から"Start Debugging and Break"を選択するとデバッグが開始 • スタートボタンを押すと実行が開始されてブレークポイントを置いた箇所で止まる
マルチタスク : サンプルの実行
マルチタスクの使用方法をマルチタスクのサンプルを例に説明 • マルチタスクのサンプル : examples/MultiTask
• ビルドして実行
マルチタスク : サンプルの解説
• タスク毎にtaskX_setup()/taskX_loop()を記述 • setup()/loop()を実行するタスクをメインタスクと呼ぶ • ASPカーネルのAPIを発行可能 /* * For MAINTASK */ void setup() { Serial.begin(115200); Serial.println("setup() : running"); delay(1); } int loop_cnt = 0; void loop() { Serial.print("loop() : running"); Serial.print(loop_cnt++); Serial.println(" ."); /* * For TASK1 */ void task1_setup() { pinMode(13, OUTPUT); Serial.println("task1_setup() : running"); } void task1_loop() { digitalWrite(13, HIGH); delay(1000); digitalWrite(13, LOW); delay(1000); }マルチタスク : プログラミングモデル
• タスク数の設定(rca_app.hで定義)
• タスク毎の設定(マクロはrca_app.hで定義)
−マクロで定義しない場合は初期値(5)となる
タスク名 関数 タスクID setup()優先度 loop()優先度
メインタ
スク setup/loop RCA_MAINTASK RCA_MAINTASK_SETUP_PRI RCA_MAINTASK_LOOP_PRI
タスク1 task1_setup/task2_loop RCA_TASK1 RCA_TASK1_SETUP_PRI RCA_TASK1_LOOP_PRI
タスク2 task2_setup/task2_loop RCA_TASK2 RCA_TASK2_SETUP_PRI RCA_TASK2_LOOP_PRI
タスク3 task3_setup/task3_loop RCA_TASK3 RCA_TASK3_SETUP_PRI RCA_TASK3_LOOP_PRI
タスク4 task4_setup/task4_loop RCA_TASK4 RCA_TASK4_SETUP_PRI RCA_TASK4_LOOP_PRI
タスク5 task5_setup/ RCA_TASK5 RCA_TASK5_SETUP_P RCA_TASK5_LOOP_PRI
マルチタスク : スケジューリング
• ASPカーネルによるスケジューリング −優先度ベースのプリエンプティブスケジューリング −同一優先度はFCFSでスケジューリング −Arduino 向けのプログラムの移植時は,loop()内でdelay(xx)を入れて他 のタスクに実行権を与えること • ラウンドロビン −マクロを定義することにより同一優先度内で有効となる • RCA_RR_SCHEDULE ビット0(LSB)が優先度1に対応しており,1とした優先度をラウン ドロビンスケジューリングとする • RCA_RR_SCHEDULE_CYCLE ms周期で周期を設定,設定しない場合は1m周期 −例)全ての優先度で10ms周期でラウンドロビンスケジューリングサンプルプロジェクト
•
基本サンプル
•
CompositeExampleの構成
サンプルフォルダ名 概要 Basic 各種Arduinoのサンプル MultiTask マルチタスク機能のサンプル Profiling プロファイリング機能のサンプル RRScheduling ラウンドロビンスケジューリングのサンプル CompositeExample 複合機能のサンプル コンソール タスク LED タスク センサー タスク Webサーバ タスク Processing TFT/SD Ar dui no ライブラリ Ar dui no ライブラリサンプルプロジェクト
•
通信機能サンプル
•
IoTサンプル
サンプルフォルダ名 概要 WifiEcho WifiモジュールによるWifi通信のサンプル NCESCan NCESCANシールドによるCAN通信のサンプル NCESIoT NCESIoTシールドによるサンプル サンプルフォルダ名 概要 BlueMix_basic BlueMixへの接続サンプル Milkcocoa_basic Milkcocoaへの接続サンプル Milkcocoa_NCESIoT NCESIoTシールドによるMilkcocoaへの接続サンプル ThingSpeak_basic ThingSpeakへの接続サンプルサンプルプロジェクト
•
各種シールド向けのサンプル
サンプルフォルダ名 概要 NAxesMotion 9軸センサーシールドのサンプル Zumo Zumoロボット(タンク型ロボット)のサンプル PIXY PIXY(色認識カメラ)のサンプルPIXY_Wifi PIXY + Wifiを組み合わせたサンプル PIXY_Zumo PIXY + Zumo を組み合わせたサンプル
WifiEcho
WifiモジュールによりWifi通信を行うサンプル • 出来ること −シングルタスクによるエコーサーバー −マルチタスクによるエコーサーバー • 必要なハードウェアとセットアップ −ESP8266を使用したモジュール −Arduinoの0,1番ピン経由でUARTで接続 • 設定 −¥examples¥examples_gdef.h にSSIDとPASSWORDを設定 • 他のサンプルとの共有設定 −シングルタスク版とする • ¥examples¥WifiEcho¥rca_app.h のマクロをコメントアウト define STA_SSID "" #define STA_PASSWORD ""WifiEcho : ビルド&実行
• アクセスポイントに接続して,IPアドレスをDHCPから取得 • 取得したアドレスはコンソールに出力される • PCから上記のIPのポート80に接続して適当な文字を入力してエンターを押す と入力した文字がそのまま送られて来る −Ctrl-Q入力してエンターで終了WifiEcho : プログラム
• Wifiライブラリ −ESP8266用のライブラリをR2CA用にカスタマイズ • setup() −アクセスポイントに接続(ステーションモードにも変更可能) • loop() −接続を待ち,接続されたらデータを受信して受信したデータを送信する void loop() { delay(1); if(!Wifi.getMuxCStatus(&mux_id_ptn)) { Serial.println("getMuxCStatus(&mux_id_ptn) : Error!"); } ...if((len = WiFi.recv(mux_id, buffer, sizeof(buffer))) == 0) { return;
} ...
if(!WiFi.send(mux_id, buffer, len)) {
WifiEcho : プログラム(マルチタスク)
• 2タスクでエコーサーバーを実行 • Wifiモジュールの仕様上5個までコネクションを作成可能 • ¥examples¥WifiEcho¥rca_app.h のマクロを有効に • Task1でも同様にエコーサーバーを実行 −フラグを使いtask1_setup()でsetup()の終了を待つbool setup_done = false; void setup() { ...<skip>... setup_done = true; } ...<skip>... void task1_setup() { while(!setup_done) { delay(1); #define MULTI_ECHO_SERVER void loop() { delay(1); エコーサーバー処理 } void task1_loop() { delay(1); エコーサーバー処理 }
NCESIoT
NCESIoTシールドによりGROVEモジュールを使用するサンプル • NCESIoTシールド −R2CA用に開発したシールド −ESP8266によるWifi機能(UART接続) −MicroSDスロット(SPI接続) −Grove Systemと互換のコネクタ(3.3V↔5V変換) −Groveのコネクタを実装しない場合はブレッドボードを置けるNCESIoT : SD/Wifi/Grove System
• SD − Chip Selectをピン10とすることで使用することができる • Wifi − ESP8266を使用しているのでWifiを使用するサンプルを動作させることが可能 • Grove System − 各種センサやアクチュエータを簡単に着脱可能なモジュール − 100種類以上のモジュールがリリースされている − 各GroveモジュールにはWikiページとArduinoライブラリが用意されているNCESIoT : Grove Systemの使用例
• Ultrasonic Ranger を例に使用方法の流れを説明
• ハードウェアセットアップ
−M0にNCES IoT Base Shield を取り付け −Ultrasonic Rangerを接続
NCESIoT : Grove Systemの使用例
• ソフトウェアセットアップ −Ultrasonic RangerのWikiをチェック −ライブラリがGitHubからダウンロード可能 −GitHubにアクセスしてライブラリをダウンロード • GitHubのページの右側にあるDownload ZIPのリンクをクリックして zipファイルをダウンロードNCESIoT : Grove Systemの使用例
• 展開するとフォルダ名に“-master”が入っているため取って,フォルダ Grove_Ultrasonic_Rangerをrca_app.cpp等があるフォルダにコピー • サンプルの内容をエディタ等で開いてrca_app.cppにコピー − フォルダ examples 以下にある • rca_app.hのインクルードを追加 − D3に接続したので,Ultrasonicの定義時に’3’を指定 #include "rca.h" Ultrasonic ultrasonic(3); void setup() { Serial.begin(115200); } void loop() { long RangeInCentimeters; RangeInCentimeters = ultrasonic.MeasureInCentimeters(); Serial.print(RangeInCentimeters);//0~400cm Serial.println(" cm"); delay(250);NCESIoT : Grove Systemの使用例
• Makefileの編集 −APPL_DIR : ビルド対象のファイルがあるフォルダを追加 −APPL_CXXOBJS : ビルド対象のCPPファイルを追加 −APPL_COBJS : ビルド対象のCファイルを追加 • ビルド&実行 −do_make.bat/do_run.batでビルドと実行が行える APPL_DIR += ./Grove_Ultrasonic_Ranger APPL_CXXOBJS += Ultrasonic.o APPL_COBJS +=IoTサーバーとの通信
• Wifiモジュールを用いたIoTサーバーとの通信のライブラリとサンプルを用意 −Bluemix • IBMのサービス,様々な機能があるが使いこなすのは困難 −Milkcocoa • MQTTによるPUB/SUB通信が可能 − ThingSpeak • HTTPによるデータのUPと可視化と解析が可能 • Milkcocoaを例に説明 −IoT向けのリアルタイムなデータのやりとりやデータのストア及び可視化を サポートするクラウドサービス −PublishするとSubscribeしている機器にデータがブロードキャストされる −Pub/Subの対象は,app_idとdatasoreで指定 −データはkeyとvalueで構成されているMilkcocoa_basic
• サーバー側の設定 −アカウントの作成,作成後app_idが表示される • プログラム側の設定 −./example/examples_gdef.h にapp_idとデータストアを設定 • ビルドして実行 −データ受信のみが有効になる −Milkcocoa Testerを使い,プッシュしたデータを 受信することを確認 #define MILKCOCOA_APP_ID "" #define MILKCOCOA_DATASTORE ""Milkcocoa_basic
• setup() − Wifiを有効にしてアクセスポイントに接続 − データ受信時に実行するフック関数を指定 • loop() − サーバーからのデータをチェックしデータが来ていればフック関数を呼び出す • onpush()milkcocoa.on(MILKCOCOA_DATASTORE, "push", onpush)
milkcocoa.loop(1)
void onpush(DataElement *pelem) { char *data;
if(!pelem->getString("LED", &data)) {
Serial.print("onpush : key LED is not found."); return;
};
Serial.print("onpush : {LED, "); Serial.write(data);
Milkcocoa_basic
• pushのサンプルを実行する −マクロの定義を変更する • loop() −DateElemntにKEYとVALUEをセットしてpush()する #define MILKCOCOA_PUSH //#define MILKCOCOA_ON void loop(){DataElement elem = DataElement(); if(req_led_on) { elem.setValue("LED", "ON"); }else { elem.setValue("LED", "OFF"); } do {
Zumo
• タンク型のロボット − ライントレース,相撲,迷路探索等が可能 • Arduino UNO のシールドとして開発されておりライブラリが用意されている − LED,ブザー,左右モータ,フォトリフレクタアレイ − 三軸加速度センサ,三軸磁場センサ • Arduino M0 用にライブラリを整備し直した − 一部ライブラリはUNO(AVR)を前提としていたため • 簡単にロボット制御を体験できる − プログラム未経験の学部一年生でも理解して作成 できているZumo
•
サンプルの一覧
−
Basicと同様にマクロでどれかを有効にする
サンプル名 説明 BUTTON_BASIC ボタンのサンプル MOTOR_BASIC モーターのサンプル BUZZER_BASIC ブザーのサンプル GYRO_BASIC ジャイロによって起動時の方向からの差分を出力するサンプル REFLECTANCE_BASIC フォトリフレクタアレイの値を出力するサンプル COMPASS_BASIC 電子コンパスによって向いている方角の角度を表示.キャリブレーション値は固定値 RELECTORNCE_STOP 黒い線を見つけると止まるサンプル ROTATIONRESIST ジャイロを使って常に同じ方向を向くサンプル FORCEUPHILL 加速度センサを使って坂の上を見るサンプル LINEFOLLOWER ライントレースのサンプル BORDERDETECT 相撲リングから出ないように走るサンプルPIXY + Zumo
• PIXY −色認識が可能なカメラモジュール −Arduinoに対して認識した物体の番号(事前に登録する)とサイズと場所を SPI経由で送信する −SPI経由で2軸のサーボを制御可能 • PIXY + Zumo −色付きのボールを認識して追いかけ るロボット −PIXYの認識結果からPIXYのサーボ とZumoのモータを制御 −Wifiモジュールを組み合わせること により,IoTサービスとの連携も可能NCESCan
NECSCANシールドによりCAN通信を行うサンプル • 出来ること −CANによるデータの送受信 • 必要なハードウェアとセットアップ −Microchip社 MCP2515 を使用したArduino用シールド • NCESCANシールド,SparkFun CAN-BUSシールド • NCESCANシールド −MCP2515とxbee互換コネクタを持つボード −xbee互換のESP8266モジュールも開発 −松浦商事から購入可能NCESCan
•
受信用メールボックス : 2個
−
それぞれ2個と4個フィルターを設定可能
−
受信割込みを設定可能
•
送信用メールボックス : 3個
#include <SPI.h> #include "mcp_can.h" const int SPI_CS_PIN = 9; #define CAN_INT_PIN 3MCP_CAN CAN(SPI_CS_PIN); // Set CS pin void setup() { CAN.begin(CAN_500KBPS) //受信用メールボックス設定 CAN.init_Mask(MCP_RXM0, 0x0f); CAN.init_Filter(MCP_RXF0, 0x01); CAN.init_Filter(MCP_RXF1, 0x02); void loop() { //受信チェック if(CAN.checkReceive(0) != CAN_NOMSG) { CAN.readMsg(0, &id, &len, buf);
} //送信
CAN.sendMsg(0, ID, LEN, DATA); }
Arduinoライブラリの移植
• 紹介したサンプルで使用しているライブラリは既存のArduinoライブラリを ベースにR2CA用またはM0用に変更している • 変更点の例 −UNO(AVR)用の記述の変更 • AVRのタイマ等を直接使用している場合がある −Arduinoの機種毎のifdefへの追加 • M0は新しいArduinoなため対応していない場合がある −共有リソースの使用をセマフォ等で排他制御を追加 • SPI・I2Cはすでにサポートしている −割込み禁止許可をASPのAPIに変更 • コアライブラリは置き換えているTOPPERS活用アイデア・アプリケーション開発コンテスト・
貸し出し機材 : NCES IoT Package
•
機材
−
Arduino M0
−
NCS IoT ボード
−
Grove Digital Light Sensor
−
Grove OLED Display 0.96
−
Grove - Touch Sensor
−
Grove - Chainable RGB LED
−
Grove – LED
NCES IoT Package : サンプルの実行
• R2CAにNCES IoT Package用のサンプルを用意 − example¥NCESIoT_RTOS
• Qiitaに記事をup済み
− Arduino M0 Pro でマルチタスクプログラミング : NCES IoT Base Shield : GROVE・RTOS機能
機能 • 機能1
− LEDを1秒周期で点滅する • 機能2
− 周期的にDigital Light センサーの値を読み込んで,値をOLED Display に表示す る.
• 機能3
− Touch Sensorを押している間は,Light センサーの値の表示の更新を停止して, OLED Displayの表示を反転させる.
NCES IoT Package : ハードウェアセットアップ
•
Grove Digital Light
−
I2Cポートに接続
•
Grove OLED Display
−
I2Cポートに接続
•
Touch Sensor
−
D3に接続
•
LED
−
D4に接続
•
Chainable RGB LED
−
D8に接続
NCES IoT Package : プログラム
• 割込みを使用するかマクロで変更可能 −//#define USE_INTERRUPT −本資料は割込みを使わない例で説明 • タスクの生成 −各機能を1個のタスクで実現するため合計4個のタスクを使用する • ヘッダのインクルード −使用するセンサーのライブラリをコピーして,ヘッダファイルをインク ルードする ./example/NCESIoT_RTOS/rca_app.h #define RCA_NUM_TASK 3 ./example/NCESIoT_RTOS/rca_app.cpp #include "rca.h" #include <Wire.h> #include <Digital_Light_TSL2561.h>NCES IoT Package : 機能1の実現
• LEDを1秒周期で点滅する • LEDを接続しているポートを指定して出力値を変更 #define LED_PIN 4 void setup() { Serial.begin(115200); pinMode(LED_PIN, OUTPUT); } void loop() {digitalWrite(LED_PIN, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(LED_PIN, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
NCES IoT Package : 機能2の実現
• 周期的にDigital Light センサーの値を読み込んで値をOLED Display に表示する. • 機能3の実現のため − is_update_oledが1の時のみ表示を更新 : 共有メモリによる通信 − OLEDの更新は排他制御を行う : セマフォによる排他制御 int is_update_oled; void task1_setup() { Wire.begin(); TSL2561.init(); SeeedOled.init(); SeeedOled.deactivateScroll(); void task1_loop() {
Serial.print("The Light value is: ");
Serial.println(TSL2561.readVisibleLux()); if (is_update_oled == 1) { wai_sem(OLED_SEM); SeeedOled.clearDisplay(); SeeedOled.putNumber(TSL2561.readVisibleLux()); sig_sem(OLED_SEM); }
NCES IoT Package : 機能3の実現
• Touch Sensorを押している間はLight センサーの値の表示の更新を停止して,OLED Displayの表示を反転させる. • OLEDを操作する際にはセマフォを取得 • delay()を入れる void task2_setup() { pinMode(TOUCH_PIN, INPUT_PULLUP); } void task2_loop() { delay(1);
int TouchSensorValue = digitalRead(TOUCH_PIN); if(TouchSensorValue==1) { is_update_oled = 0; wai_sem(OLED_SEM); SeeedOled.setInverseDisplay(); sig_sem(OLED_SEM); }else{ is_update_oled = 1; wai_sem(OLED_SEM); SeeedOled.setNormalDisplay(); sig_sem(OLED_SEM); }
NCES IoT Package : 機能4の実現
• Chainable LEDを周期的に色を変更する • サンプル通りの動作
#define NUM_LEDS 1
ChainableLED leds(8, 9, NUM_LEDS); void task3_setup() { leds.init(); } float hue = 0.0; boolean up = true; int count = 0; void task3_loop() {
for (byte i=0; i<NUM_LEDS; i++) leds.setColorHSB(i, hue, 1.0, 0.5); delay(50); if (up) hue+= 0.025; else hue-= 0.025;
if (hue>=1.0 && up) up = false;