Interference current stimulation program with kaji-lab ES device.

Dependencies:   mbed SerialInputReactionHandler AMPulseTrain SwArr16MOSFET StrCommandHandler KajiLabES

Files at this revision

API Documentation at this revision

Comitter:
aktk
Date:
Wed Nov 27 23:41:55 2019 +0000
Parent:
1:b97639dad576
Child:
3:ef730909a664
Commit message:
nov 27th 2019 digital sin works

Changed in this revision

DSinGenerator.lib Show annotated file Show diff for this revision Revisions of this file
PMRC16ch.lib Show diff for this revision Revisions of this file
SerialCom/CommandHandler.h Show diff for this revision Revisions of this file
SerialCom/sigbind.cpp Show diff for this revision Revisions of this file
SerialCom/sigbind.h Show diff for this revision Revisions of this file
SerialInputReactionHandler.lib Show annotated file Show diff for this revision Revisions of this file
StrCommandHandler.lib Show annotated file Show diff for this revision Revisions of this file
SwArr16MOSFET.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
subroutines.cpp Show annotated file Show diff for this revision Revisions of this file
subroutines.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DSinGenerator.lib	Wed Nov 27 23:41:55 2019 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/aktk/code/DSinGenerator/#6400e338266f
--- a/PMRC16ch.lib	Wed Oct 23 20:08:31 2019 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-https://os.mbed.com/users/aktk/code/PMRC16ch/#03e875137433
--- a/SerialCom/CommandHandler.h	Wed Oct 23 20:08:31 2019 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-#ifndef COMMAND_HANDLER_H
-#define COMMAND_HANDLER_H
-#include "mbed.h"
-#include <string>
-#include <unsorted_map>
-
-class CommandAnalyzer
-{
-public:
-    CommandAnalyzer(
-        int     num_of_command = 10,
-        char    response_mode = 0
-    );
-    int analyzeCommand(
-        const char* const   command
-    );
-    int mapCommand(
-        const char* const   command
-        int (*fanction)(void)
-    );
-private:
-    char (*m_command_name)[20];
-    int (**m_function)(void);
-}
-#endif
\ No newline at end of file
--- a/SerialCom/sigbind.cpp	Wed Oct 23 20:08:31 2019 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,288 +0,0 @@
-#include "sigbind.h"
-namespace aktk_sigbind
-{
-//  To avoid pressing key too much
-enum Lock {UNLOCK, LOCK};
-Lock aktk_keylock = UNLOCK;
-
-//private functions
-template<typename T>
-int scanValue(T* arg_val);
-void waitUnpress();
-void setPulseParam();
-void ArrowKeyBind(const char arg_c);
-//void printStimType();
-void printStatus(void);
-void keyBind()
-{
-    //stimulator.DAAD(0);
-    char sig = pc.getc();
-    if (aktk_keylock == UNLOCK) {
-        aktk_keylock = LOCK;
-        switch(sig) {
-            case 'w':
-                spacing = WIDE_CONDITION;
-                pc.printf("Wide condition\n");
-                waitUnpress();
-                break;
-            case 'n':
-                spacing = NARROW_CONDITION;
-                pc.printf("Narrow condition\n");
-                waitUnpress();
-                break;
-            case 'm':
-                switch(pc.getc()) {
-                    case 'b':
-                        smode = BIPOLAR;
-                        pc.printf("BIPOLAR Stimulation\n");
-                        break;
-                    case 'a':
-                        smode = ANODIC;
-                        pc.printf("ANODIC Stimulation\n");
-                        break;
-                    case 'c':
-                        smode = CATHODIC;
-                        pc.printf("CATHODIC Stimulation\n");
-                        break;
-                }
-                waitUnpress();
-                break;
-            case 'p':
-                printStatus();
-                waitUnpress();
-                break;
-            case 'v':
-                setPulseParam();
-                waitUnpress();
-                break;
-            case 'a':   //switch mbed-pc communication on/off
-                if (pstate == MAIN_ROUTINE) {
-                    pstate = WAIT_A_CERTAIN_KEY;
-                    pc.printf("stop\n");
-                } else if (pstate == WAIT_A_CERTAIN_KEY) {
-                    pstate = MAIN_ROUTINE;
-                    //printStimType();
-                    pc.printf("start\n");
-                }
-                waitUnpress();
-                break;
-            case 'E':
-                pstate = TERMINATED;
-                pc.printf("TERMINATED");
-                waitUnpress();
-                break;
-            case 'S':// start
-                if (pstate == WAIT_A_CERTAIN_KEY) {
-                    pstate = MAIN_ROUTINE;
-                    //printStimType();
-                    pc.printf("start\n");
-                }
-                waitUnpress();
-                break;
-            case 'P':// pause
-                pstate = WAIT_A_CERTAIN_KEY;
-                pc.printf("stop\n");
-                waitUnpress();
-                break;
-            case 0x1b:
-                if(pc.getc() == 0x5b) {
-                    ArrowKeyBind(pc.getc());
-                    pc.printf("Hight:%d\n",ph);//sc.getPH());
-                }
-                waitUnpress();
-                break;
-            default:
-                printKBManual();
-                pc.printf("Sent data was: %d(%c)\n", sig, sig);
-                waitUnpress();
-                break;
-        }
-        //aktk_keylock = UNLOCK;
-    } else if (sig == 0x1B) //esc
-        aktk_keylock = UNLOCK;
-}
-
-void waitUnpress()
-{
-    while (1) {
-        if(! pc.readable()) {
-            aktk_keylock = UNLOCK;
-            break;
-        }
-    }
-}
-
-template<typename T>
-int scanValue(T* arg_val)
-{
-    char c = 0;
-    char c_prevent = 0;
-    double tmp = 0.0;
-    double fig = 1.0;
-    bool dot_flag = false;
-    bool no_modified = true;
-
-    T arg_last_val = *arg_val;
-
-    do {
-        c = pc.getc();
-
-        if ('0' <= c && c <= '9') {
-            no_modified = false;
-            pc.putc(c);
-            if(! dot_flag) {
-                tmp *= 10.0;
-                tmp += (double)(c - '0');
-            } else {
-                fig *= 10.0;
-                tmp += (double)(c - '0') / fig;
-            }
-        } else if (c == '.') {
-            if(dot_flag == 0)pc.printf(".");
-            dot_flag = true;
-        } else if (c == 'k' || c == 'K') {
-            pc.printf("(keep present value)\n");
-            tmp = (double) arg_last_val;
-            break;
-        } else if (c == 0x10 || c == 0x08) {
-            pc.putc(0x08);
-            pc.putc(0x20);
-            pc.putc(0x08);
-            if(! dot_flag) {
-                c_prevent = (double)(((int)tmp) % 10);
-                tmp -= (double)(c_prevent);
-                tmp /= 10;
-            } else {
-                if(fig == 1.0)
-                    dot_flag = false;
-                else {
-                    c_prevent = (double)((int)(tmp * fig) % 10);
-                    tmp -= (double)(c_prevent) / fig;
-                    fig /= 10;
-                }
-            }
-            if(tmp == 0) no_modified = true;
-        } else if (c == 0x1b) {
-            pc.printf("CANSELED\n");
-            return -1;
-        } else if (c == 0x0A || c == 0x0D) {
-            pc.printf("\n");
-            break;
-        }
-    } while(1);
-
-    waitUnpress();
-
-    if(no_modified) *arg_val = arg_last_val;
-    else *arg_val = static_cast<T>(tmp);
-    pc.printf("tmp:%f\n",tmp);
-
-    return 0;
-}
-//int scanValue<int>(int*);
-//int scanValue<double>(double*);
-//int scanValue<unsigned short>(unsigned short*);
-
-void setPulseParam()
-{
-    int lph, lpp, lpw;
-
-    lph = ph;//sc.getPH();
-    lpp = pp;//sc.getPP();
-    lpw = pw;//sc.getPW();
-
-    //  read values
-    pc.printf("set pulse Height:");
-    if( scanValue<int>(&lph) ) goto BreakV;
-    pc.printf("set pulse period:");
-    if( scanValue<int>(&lpp) ) goto BreakV;
-    pc.printf("set pulse width :");
-    if( scanValue<int>(&lpw) ) goto BreakV;
-
-    //  set values
-    ph = lph;
-    pp = lpp;
-    pw = lpw;
-BreakV:
-    waitUnpress();
-}
-
-void ArrowKeyBind(const char arg_c)
-{
-    switch(arg_c) {
-        case 0x41 : {
-            if(ph <= 4090) //if(sc.getPH()<4000)
-                ph = ph + 5;//sc.setWaveParam(sc.getPH() + 5, sc.getPP(),sc.getPW());
-            else
-                ph = 4095;
-            pc.printf("up\n");
-            break;
-        }
-        case 0x42 : {
-            if(5 <= ph) //if(5<sc.getPH())
-                ph = ph - 5;//sc.setWaveParam(sc.getPH() - 5, sc.getPP(),sc.getPW());
-            else
-                ph = 0;//sc.setWaveParam(0, sc.getPP(),sc.getPW());
-            pc.printf("down\n");
-            break;
-        }
-        case 0x43 : {
-            if(ph <= 4045)//if(sc.getPH()<4000)
-                ph = ph + 50;//sc.setWaveParam(sc.getPH() + 50, sc.getPP(),sc.getPW());
-            else
-                ph  = 4095;
-            pc.printf("shift up\n");
-            break;
-        }
-        case 0x44 : {
-            if(50 <= ph)//if(50<sc.getPH())
-                ph = ph - 50;//sc.setWaveParam(sc.getPH() - 50, sc.getPP(),sc.getPW());
-            else
-                ph = 0;//sc.setWaveParam(0, sc.getPP(),sc.getPW());
-            pc.printf("shift down\n");
-            break;
-        }
-        default: {
-            //pc.printf("default\n");
-            break;
-        }
-    }
-}
-
-void printKBManual(void)
-{
-    pc.printf( "\n"
-               "keybind are following:\n"
-               "    ---\n"
-               "    v: set all paramater by arbitrary value\n"
-               "    ---\n"
-               "    UP:     pulse hight + 5\n"
-               "    Down:   pulse hight - 5\n"
-               "    right:  pulse hight +50\n"
-               "    left:   pulse hight -50\n"
-               "    ---\n"
-               "    w:  Wide condition\n"
-               "    n:  Narrow condition\n"
-               "    ---\n"
-               "    mb: Bipolar stimulation\n"
-               "    ma: Anodic Stimulation\n"
-               "    mc: Cathodic Stimulation\n"
-               "    ---\n"
-               "    p:  print wave parameter\n"
-               "    ---\n"
-               "    a:  Start or Pause main loop\n"
-               "    S:  Start or Resume Stimulation\n"
-               "    P:  Pause Stimulation\n"
-               "    E(shift+a): terminate the loop\n"
-               "\n");
-}
-void printStatus(void)
-{
-    pc.printf(
-        "PHeight:%05d   "
-        "PPeriod:%05d   "
-        "PWidth :%05d\n"
-        //,(int)sc.getPH(), (int)sc.getPP(), (int)sc.getPW()
-        ,ph,pp,pw);
-}
-}//end of name space
\ No newline at end of file
--- a/SerialCom/sigbind.h	Wed Oct 23 20:08:31 2019 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-#ifndef SIG_BIND_H
-#define SIG_BIND_H
-#include "mbed.h"
-
-
-namespace aktk_sigbind
-{
-//  prototype
-void keyBind();
-void printKBManual(void);
-}
-
-extern uint32_t pw, pp, ph;
-
-//  Mbed Specails
-extern Serial pc; // tx, rx
-
-//  -   For Procedure state
-enum ProcessState {WAIT_A_CERTAIN_KEY, MAIN_ROUTINE, TERMINATED};
-extern ProcessState   pstate;
-
-enum ElectrodeSpacing {WIDE_CONDITION, NARROW_CONDITION};
-extern ElectrodeSpacing spacing;
-
-enum StimulationMode {BIPOLAR, ANODIC, CATHODIC};
-extern StimulationMode smode;
-
-#include "KajiLabES.h"
-extern KajiLabES   stimulator;
-#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SerialInputReactionHandler.lib	Wed Nov 27 23:41:55 2019 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/aktk/code/SerialInputReactionHandler/#599073f82114
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/StrCommandHandler.lib	Wed Nov 27 23:41:55 2019 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/aktk/code/StrCommandHandler/#049a5f083f32
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SwArr16MOSFET.lib	Wed Nov 27 23:41:55 2019 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/aktk/code/SwArr16MOSFET/#8af1b775e1dc
--- a/main.cpp	Wed Oct 23 20:08:31 2019 +0000
+++ b/main.cpp	Wed Nov 27 23:41:55 2019 +0000
@@ -1,81 +1,32 @@
 #include "mbed.h"
-#include "KajiLabES.h"
-#include "PMRC16ch.h"
-#include "sigbind.h"
-#include <iostream>
-#include <bitset>
-ProcessState   pstate = WAIT_A_CERTAIN_KEY;
-ElectrodeSpacing spacing = WIDE_CONDITION;
-StimulationMode smode = BIPOLAR;
-Serial pc(USBTX, USBRX); // tx, rx
+#include "subroutines.h"
 
 DigitalOut  myled1(LED1);
 DigitalOut  myled2(LED2);
 DigitalOut  myled3(LED3);
 DigitalOut  myled4(LED4);
-KajiLabES   stimulator;
-PMRC16ch    pmrc(16);
-uint32_t pw;//pulse width
-uint32_t pp;//pulse period
-uint32_t ph;//pulse hight
+ProcessState   pstate = WAIT_A_CERTAIN_KEY;
 
 int main()
 {
-    stimulator.init();
-    myled1 = 1;
-    pmrc.allHiZ();
-    myled2 = 1;
-    {
-        using namespace aktk_sigbind;
-        pc.baud(921600);
-        pc.attach(&keyBind);
-        pw = 100;
-        pp = 5000;
-        ph = 0;
-        printKBManual();
-        wait(.5);
+    printf("SystemCoreClock = %d Hz\n", SystemCoreClock);
+    myled1 = myled2 = myled3 = myled4 = 0;
+    init();
+
+PRELOOP_POINT:
+    while (pstate == WAIT_A_CERTAIN_KEY) {
+        wait(0.5);
+        myled3  = (!myled3);
     }
-    while(1) {
-        while (pstate == WAIT_A_CERTAIN_KEY) {
-            myled3  = (!myled3);
-            wait(0.5);
-        }
-        myled3 = 1;
-        pmrc.setPol(PMRC16ch::Cathodic);
-        while (pstate == MAIN_ROUTINE) {
-            
-            for (int i = 0; i < 2; i++) {
-                switch(smode){
-                    case BIPOLAR:   pmrc.setPol((PMRC16ch::Polarity)i); break;
-                    case CATHODIC:  pmrc.setPol(PMRC16ch::Cathodic);    break;
-                    case ANODIC:    pmrc.setPol(PMRC16ch::Anodic);      break;
-                }
-                if(spacing == WIDE_CONDITION)
-                    //pmrc.setTrio(3,1,5);
-                    pmrc.setTwin(1, 2);
-                else
-                    //pmrc.setTrio(3,2,4);
-                    pmrc.setTwin(1, 3);
-                wait_us(pp-pw);
-                stimulator.DAAD(ph);
-                wait_us(pw);
-                stimulator.DAAD(0);
-            }
-            /*
-            for(int i = 0; i < 2; i++) {
-                pmrc.setTwin(i+1, (i+1)%8+1);
-                //pmrc.setTwin(i+1, (i+1)%8+1);
-                //pmrc.setTwin(i+1, (i+1)%8+1);
-                //pmrc.setOvsO(i+1);
-                wait_us(pp-pw);
-                stimulator.DAAD(ph);
-                wait_us(pw);
-                stimulator.DAAD(0);
-                //pmrc.allHiZ();
-                //wait_us(pw);
-            }
-             */
-            if (pstate == TERMINATED) break;
-        }
+    
+    
+    myled3 = 1;
+    while(pstate == MAIN_ROUTINE) {
+        wait(.1);
+        myled3  = (!myled3);
     }
-}
+    
+    
+    myled3 = 0;
+    goto PRELOOP_POINT;
+}
\ No newline at end of file
--- a/mbed.bld	Wed Oct 23 20:08:31 2019 +0000
+++ b/mbed.bld	Wed Nov 27 23:41:55 2019 +0000
@@ -1,1 +1,1 @@
-https://os.mbed.com/users/mbed_official/code/mbed/builds/5aab5a7997ee
\ No newline at end of file
+https://os.mbed.com/users/mbed_official/code/mbed/builds/65be27845400
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/subroutines.cpp	Wed Nov 27 23:41:55 2019 +0000
@@ -0,0 +1,344 @@
+#include "subroutines.h"
+
+#include "KajiLabES.h"
+
+#include "SwArr16MOSFET.h"
+
+#include "DSinGenerator.h"
+#include "StrCommandHandler.h"
+#include "SerialInputReactionHandler.h"
+
+Serial pc(USBTX, USBRX, 921600); // tx, rx
+Ticker ticker;
+KajiLabES   stimulator;
+SwArr16MOSFET swBrd(4, p11, p12, p13, p14, p10);
+DSinGenerator singen ( 
+    /*Initial Amplitude*/ 0,
+    /*Initial Frequency*/ 4000,
+    /*Discret.-fineness*/ 16
+);
+StrCommandHandler command_handler;
+SerialInputReactionHandler reactor; //todo: implement function replace sigbind.cpp/h
+
+
+void init (void)
+{
+    //void init_Hardware(void)
+    {
+        stimulator.init();
+        swBrd.allHiZ();
+        swBrd.setPol(SwArr16MOSFET::Cathodic);
+        swBrd.setTwin(1,2);
+    }
+    myled1 = 1;
+
+    NVIC_SetPriority(TIMER3_IRQn, 1);
+
+    //void init_commands(void)
+    {
+        command_handler.map("a",    &switchState);
+        command_handler.map("E",    &terminateLoop);
+        command_handler.map("S",    &startLoop);
+        command_handler.map("P",    &pauseLoop);
+        command_handler.map("v",    &beginParamsSetting);
+        command_handler.map("p",    &printStatus);
+        command_handler.map(StrCommandHandler::ARROW_UP,    &increaseCurrent);
+        command_handler.map(StrCommandHandler::ARROW_DOWN,  &decreaseCurrent);
+        command_handler.map(StrCommandHandler::ARROW_RIGHT, &increaseFrequency);
+        command_handler.map(StrCommandHandler::ARROW_LEFT,  &decreaseFrequency);
+        reactor.attach(callback(&command_handler, &StrCommandHandler::exe));
+        reactor.attach_PostProc(&calleddefault);
+        reactor.startReception(&pc, SerialInputReactionHandler::KB_SINGLE_INPUT);
+    }
+    printKBManual();
+    printDSinSamples();
+    wait(.1);
+    myled2 = 1;
+}
+
+
+
+void loop()
+{
+    static int ph = 0;
+    static int ph_sign = 0;
+
+    myled4 = 1;
+
+    ph = singen.getValue_p16m16();
+    if(ph > 0) {
+        ph_sign = 1;
+    }
+    //  when ph is negaive, make it positive
+    else if (ph < 0) {
+        ph = -ph;
+        ph_sign = -1;
+    }
+    stimulator.DAAD(ph);
+
+    if(ph == 0) {
+        if (ph_sign > 0)
+            swBrd.setTwin(1, 4);
+
+        else if (ph_sign < 0)
+            swBrd.setTwin(4, 1);
+        else;
+        ph_sign = 0;
+    }
+
+    myled4 = 0;
+}
+
+
+
+void calleddefault(char const * const arg_command, void * arg_errorcode)
+{
+    int errorcode = *(int*)arg_errorcode;
+    if (errorcode != 0xFFFFFFFC) return;
+    printKBManual();
+    pc.printf("Sent data was: %d(%c)(%s)\n", arg_command[0], arg_command[0], arg_command);
+}
+
+
+void * switchState()
+{
+    if (pstate == MAIN_ROUTINE)
+        pauseLoop();
+    else if (pstate == WAIT_A_CERTAIN_KEY) {
+        startLoop();
+
+    }
+    return NULL;
+}
+
+
+void * startLoop(void)
+{
+    if (pstate != WAIT_A_CERTAIN_KEY) return NULL;
+
+    ticker.attach_us(loop, singen.getPulseWidth());
+    pstate = MAIN_ROUTINE;
+    pc.printf("start\n");
+    return NULL;
+}
+
+
+
+void * pauseLoop(void)
+{
+    if (pstate != MAIN_ROUTINE) return NULL;
+
+    stimulator.DAAD(0);
+    ticker.detach();
+    pstate = WAIT_A_CERTAIN_KEY;
+    pc.printf("stop\n");
+    return NULL;
+}
+
+
+
+void * terminateLoop(void)
+{
+    stimulator.DAAD(0);
+    ticker.detach();
+    pstate = TERMINATED;
+    pc.puts("TERMINATED");
+    return NULL;
+}
+
+
+
+void * increaseCurrent(void)
+{
+    float lampl = singen.getAmplitude();
+    if(lampl < singen.ampl_max - 0.5)
+        lampl += 0.5;
+    else
+        lampl = singen.ampl_max;
+    singen.setAmplitude(lampl);
+    printStatus();
+    return NULL;
+}
+
+
+
+void * decreaseCurrent(void)
+{
+    float lampl = singen.getAmplitude();
+    if(1 <= lampl )
+        lampl -= 0.5;
+    else
+        lampl = 0;
+    singen.setAmplitude(lampl);
+    printStatus();
+    return NULL;
+}
+
+
+
+void * increaseFrequency(void)
+{
+    uint16_t lfreq = singen.getFrequency();
+    if(lfreq < singen.freq_max - 10)
+        lfreq += 10;
+    else
+        lfreq  = 5000;
+    singen.setFrequency(lfreq);
+    ticker.attach_us(loop, singen.getPulseWidth());
+    printStatus();
+    return NULL;
+}
+
+
+
+void * decreaseFrequency(void)
+{
+    uint16_t lfreq = singen.getFrequency();
+    if(20 <= lfreq )
+        lfreq -= 10;
+    else
+        lfreq = 10;
+    singen.setFrequency(lfreq);
+    ticker.attach_us(loop, singen.getPulseWidth());
+    printStatus();
+    return NULL;
+}
+
+
+
+template <typename T>
+bool scanValue(char const * const arg_digits, T * const arg_dest)
+{
+    int l_len = 0;
+    int l_digit = 0;
+    int l_value = 0;
+    bool l_isfloat = false;
+
+    while (arg_digits[l_len] != '\0') {
+
+        if (l_len > 50) {
+            pc.puts("\nerror: too long number of digits\n");
+            return false;
+        }
+
+        if ('0' <= arg_digits[l_len] && arg_digits[l_len] <= '9')
+            l_digit = arg_digits[l_len] - '0';
+        else if(arg_digits[l_len] != '.')
+            if(l_isfloat)
+                return false;
+            else
+                l_isfloat = true;
+        else return false;
+
+        if(l_isfloat) l_digit /= 10;
+        else l_value *= 10;
+
+        l_value += l_digit;
+        l_len++;
+    }
+
+    *arg_dest = static_cast<T>(l_value);
+    return true;
+}
+
+
+
+
+void * beginParamsSetting(void)
+{
+    pauseLoop();
+    reactor.changeMode(SerialInputReactionHandler::KB_TILL_ENTER);
+
+    pc.puts("---\n");
+    pc.printf("set amplitude:");
+    reactor.attach(SetAmplitude);
+    return NULL;
+}
+
+void * SetAmplitude(char const * const arg_digits)
+{
+    float lampl = singen.getAmplitude();
+
+    //  read values
+    if (scanValue(arg_digits, &lampl));
+
+    //  set values
+    if( lampl <   0 || singen.ampl_max < lampl) lampl = singen.getAmplitude();
+    singen.setAmplitude(lampl);
+
+    pc.puts("===\n");
+    pc.printf("set frequency:");
+    reactor.attach(SetFrequency);
+    return NULL;
+}
+
+void * SetFrequency(char const * const arg_digits)
+{
+    uint16_t lfreq = singen.getFrequency();
+
+    if (scanValue(arg_digits, &lfreq));
+
+    if( lfreq < 500 || singen.freq_max < lfreq) lfreq = singen.getFrequency();
+    singen.setFrequency(lfreq);
+
+    pc.puts("...\n");
+    printStatus();
+    endParamsSetting();
+    return NULL;
+}
+
+void * endParamsSetting(void)
+{
+    reactor.changeMode(SerialInputReactionHandler::KB_SINGLE_INPUT);
+    reactor.attach(callback(&command_handler, &StrCommandHandler::exe));
+    startLoop();
+    return NULL;
+}
+
+
+
+void * printKBManual(void)
+{
+    pc.puts(
+        "\n"
+        "keybind are following:\n"
+        "    ---\n"
+        "    v: set all paramater by arbitrary value\n"
+        "    ---\n"
+        "    UP:     Amplitude + 1(mA)\n"
+        "    Down:   Amplitude - 1(mA)\n"
+        "    Right:  Frequency +10(Hz)\n"
+        "    Left:   Frequency -10(Hz)\n"
+        "    ---\n"
+        "    p:  print wave parameter\n"
+        "    ---\n"
+        "    a:  Start or Pause main loop\n"
+        "    S:  Start or Resume Stimulation\n"
+        "    P:  Pause Stimulation\n"
+        "    E(shift+a): terminate the loop\n"
+        "\n");
+    return NULL;
+}
+
+void * printStatus(void)
+{
+    pc.printf(
+        "Amplitude:  %2.3f  "
+        "Frequency:  %05d  "
+        "Pulse Width:%05d\n"
+        , singen.getAmplitude(), singen.getFrequency(), singen.getPulseWidth());
+    return NULL;
+}
+
+void * printDSinSamples(void)
+{
+    pc.printf("resolution of sin: %d\n", singen.resolution_ofsin);
+
+    float dsin[singen.resolution_ofsin];
+    singen.getValueofSamplePoints(dsin);
+    for ( int i = 0; i < singen.resolution_ofsin; i++ )
+        pc.printf("sin[%02d]: %2.2f\n", i, dsin[i]);
+
+    return NULL;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/subroutines.h	Wed Nov 27 23:41:55 2019 +0000
@@ -0,0 +1,43 @@
+#ifndef SUBROUTINES_H
+#define SUBROUTINES_H
+
+#include "mbed.h"
+
+extern DigitalOut  myled1;
+extern DigitalOut  myled2;
+extern DigitalOut  myled3;
+extern DigitalOut  myled4;
+
+enum ProcessState {WAIT_A_CERTAIN_KEY, MAIN_ROUTINE, TERMINATED};
+extern ProcessState   pstate;
+
+//  prototype
+
+/// Called in main 
+void init(void);
+
+/// Called when it attached to ticker
+void loop(void);
+
+
+void * printKBManual(void);
+void * printStatus(void);
+void * printDSinSamples(void);
+
+void * increaseCurrent(void);
+void * decreaseCurrent(void);
+void * increaseFrequency(void);
+void * decreaseFrequency(void);
+
+void * beginParamsSetting(void);
+void * SetAmplitude(char const * const);
+void * SetFrequency(char const * const);
+void * endParamsSetting(void);
+
+void * switchState();
+void * startLoop(void);
+void * pauseLoop(void);
+void * terminateLoop(void);
+
+void calleddefault(char const * const, void *);
+#endif
\ No newline at end of file