Interference current stimulation program with kaji-lab ES device.
Dependencies: mbed SerialInputReactionHandler AMPulseTrain SwArr16MOSFET StrCommandHandler KajiLabES
Diff: subroutines.cpp
- 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; +} +