Interference current stimulation program with kaji-lab ES device.

Dependencies:   mbed SerialInputReactionHandler AMPulseTrain SwArr16MOSFET StrCommandHandler KajiLabES

Revision:
2:5cb68cc8ecaa
Child:
3:ef730909a664
--- /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;
+}
+