realtime process control with RTOS

Fork of mbed-os-example-mbed5-blinky by mbed-os-examples

Revision:
20:13fcc82f4cab
Parent:
19:9381d775bfc5
Child:
21:967504024346
--- a/main.cpp	Fri Nov 25 17:37:31 2016 +0000
+++ b/main.cpp	Tue Oct 02 03:04:57 2018 +0000
@@ -1,42 +1,102 @@
+//  mbed-os-io-control
+//  I/O制御プログラム(機械工学実験1)
 //
-//  mbed-os-control-ex1
-//  正確な時間管理をするプログラムの例
-//
-//  20161027 ... v1.0 ... written by Y.Kuroda
-//
+//  20161027 ... v1.0 ... originally written by Y.Kuroda for Mechatronics
+//  20180917 ... v2.0 ... customised for Jikken1(mbed LPC1768専用)
 //
 #include "mbed.h"
-#include "rtos.h"
+
+const int DELTA_T = 1;    // mainスレッドの時間間隔の設定[ms](デフォルトは1ms)
+int delta_t = DELTA_T;
+int qbits = 6;            // 量子化シフト値
+const int SIG_MYT = 0x1;  // signal番号
+DigitalOut led1(LED1);
+DigitalOut led2(LED2);
+DigitalOut led3(LED3);
+DigitalOut led4(LED4);
+
+// p11,12 サンプリング周期設定ピン(デフォルトは0)
+// p11上位ビット,p12下位ビット.0:1kHz, 1: 100Hz, 2: 10Hz, 3: 1Hz 
+InterruptIn samplingtime_MSB(p11);
+InterruptIn samplingtime_LSB(p12);
 
-const int DELTA_T = 100;    // mainスレッドの時間間隔の設定 [ms]
-const int SIG_MYT = 0x1;    // signal番号
-DigitalOut led1(LED1);
+// p13,14 量子化粒度設定ピン(デフォルトは0)
+// p13上位ビット,p14下位ビット.0:10bit, 1:8bit, 2:6bit, 3:4bit
+InterruptIn quantization_MSB(p13);
+InterruptIn quantization_LSB(p14);
+
+// アナログ入出力ピン(入出力共に0 - 3.3V)
+AnalogOut aout(p18);
+AnalogIn  ain(p20);
 
-void robot_control(void const* arg) {   // ロボットの制御をするスレッド
+// デジタル入力ピン(割り込みにより実現)
+InterruptIn din1(p21);
+InterruptIn din2(p22);
+
+// 方形波,パルス波出力ピン
+PwmOut squarewave(p23);
+PwmOut pulsewave(p24);
+
+// サンプリング処理をするスレッド(時間管理された処理)
+void sampling_thread(const void* arg) {
     while(true){
         Thread::signal_wait(SIG_MYT);   // シグナルを待つ
-
-        // ここに自分のプログラムを書きます.
-        //
-        //
-        //
-        Thread::wait(10);   //これは時間稼ぎのダミー.消して良い.
-        //
-        //
-        //
-
-        led1 = 0;   // ループの最後でLEDを消す.処理が重くなると明るくなる
+        unsigned short a_data  = ain.read_u16(); // AD入力(ADは12ビット)
+        aout.write_u16((a_data>>qbits)<<qbits);// DA出力(量子化粒度はピンにより設定)
     }
 }
 
+// 量子化粒度設定ハンドラ
+void qsize_handler(void) {
+    // 量子化設定ピン(p13,14)の設定を読んで量子化粒度を決定する
+    // 設定ピンの状態を読み取り,2ビット値に変換
+    int quantization = (quantization_MSB<<1)&0x2|quantization_LSB&0x1;
+    qbits = 6+quantization*4;   // 量子化サイズの決定
+    // (デジタル出力時の量子化サイズは 0:1024, 1:256, 2:64, 3:16 steps)
+}    
+
+//  サンプリングタイム設定割り込みハンドラ...時間設定ピンの状態が変化した時に呼び出される
+void pinstate_handler(void) {
+    // ピンの状態を読み取り,2ビット値に変換
+    int samplingtime = (samplingtime_MSB<<1)&0x2|samplingtime_LSB&0x1;
+    // 制御周期を10^nとする(n=0:1s, n=1:0.1s, n=2:0.01s, n=3:0.001s) 
+    delta_t = (int)pow(10.0,(double)samplingtime);
+    squarewave.period_ms(delta_t);  // 方形波の周期の設定
+    pulsewave.period_ms(delta_t);   // パルス波の周期の設定
+    squarewave.write(0.5F);         // duty比
+    pulsewave.write(0.1F);          // duty比
+}
+
+//  デジタル入力割り込みハンドラ...デジタル入力信号の状態が変化した時に呼び出される
+void din_handler(void) {
+    led1 = din1;    // ピンの状態をそのままLEDの点灯状態にする
+    led2 = din2;
+}    
 
 int main() {
-    Thread mythread(robot_control, (void*)0);   // ロボット制御スレッドを起動
+    squarewave.period_ms(delta_t);  // 初期周期の設定
+    pulsewave.period_ms(delta_t);   // 初期周期の設定
+    squarewave.write(0.5F);         // 初期duty比(方形波=50%)
+    pulsewave.write(0.1F);          // 初期duty比(パルス波=10%)
+
+    samplingtime_MSB.rise(pinstate_handler);// 周期設定ハンドラの設定.
+    samplingtime_MSB.fall(pinstate_handler);// 設定ピンの状態変化で
+    samplingtime_LSB.rise(pinstate_handler);// ハンドラが呼び出される
+    samplingtime_LSB.fall(pinstate_handler);// ようにする
+    quantization_MSB.rise(qsize_handler);   // 量子化粒度設定ハンドラの設定
+    quantization_MSB.fall(qsize_handler);
+    quantization_LSB.rise(qsize_handler);
+    quantization_LSB.fall(qsize_handler);
+    din1.rise(&din_handler);            // デジタル入力ハンドラの設定
+    din1.fall(&din_handler);            // din1,2の状態変化でハンドラ
+    din2.rise(&din_handler);            // が呼ばれる
+    din2.fall(&din_handler);
+
+    Thread thread_dt(sampling_thread);  // サンプリング処理スレッドを起動
 
     while(true){
-        Thread::wait(DELTA_T);          // mainスレッドの時間間隔の設定 [ms]
-        led1 = 1;                       // 処理の先頭でLEDをを点灯
-        mythread.signal_set(SIG_MYT);   // スレッドへ再開シグナルを送る
+        Thread::wait(delta_t);          // mainスレッドの時間間隔の設定[ms]
+        thread_dt.signal_set(SIG_MYT);  // スレッドへ再開シグナルを送る
+        led4 = !led4;                   // 処理の先頭でLEDをを点滅
     }
-}
-
+}
\ No newline at end of file