Interference current stimulation program with kaji-lab ES device.
Dependencies: mbed SerialInputReactionHandler AMPulseTrain SwArr16MOSFET StrCommandHandler KajiLabES
subroutines.cpp
- Committer:
- aktk
- Date:
- 2019-11-27
- Revision:
- 2:5cb68cc8ecaa
- Child:
- 3:ef730909a664
File content as of revision 2:5cb68cc8ecaa:
#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; }