Interference current stimulation program with kaji-lab ES device.
Dependencies: mbed SerialInputReactionHandler AMPulseTrain SwArr16MOSFET StrCommandHandler KajiLabES
subroutines.cpp
- Committer:
- aktk
- Date:
- 2020-02-03
- Revision:
- 5:779d799b5c83
- Parent:
- 4:8d73aaba879f
File content as of revision 5:779d799b5c83:
#include "subroutines.h" #include "KajiLabES.h" #include "AMPulseTrain.h" #include "SwArr16MOSFET.h" #include "StrCommandHandler.h" #include "SerialInputReactionHandler.h" Serial pc(USBTX, USBRX, 921600); // tx, rx Ticker ticker; KajiLabES stimulator; static int const nofch = 5; SwArr16MOSFET swBrd(nofch, p14, p13, p12, p11, p10); void callback_PulseEdge(bool arg_pulsestate, PulseTrain*, AMSignal*); uint16_t callback_AMSignalExpression (PulseTrain*, AMSignal* arg_SignalModel); AMPulseTrain ampt ( new PulseTrain(20000, 1.0, 100000), new AMSignal(50, 200) ); static float const AMPLE_MAX_mA = 15.0; StrCommandHandler command_handler; SerialInputReactionHandler reactor; static const int g_sample_size_imp = 100; uint16_t g_retval[g_sample_size_imp]; static int g_ch = 1; void * setch1(){g_ch = 1; return NULL;} void * setch2(){g_ch = 2; return NULL;} void * setch3(){g_ch = 3; return NULL;} void * setch4(){g_ch = 4; return NULL;} int signalvalue = 0; int prevvalue = 0; /// Wrapper to be attached to PulseTrain's Callback as pulse rising void callback_PulseEdge(bool arg_pulsestate, AMPulseTrain* arg_ampt) { //static int ch = 0; static int itr_sample = 0; prevvalue = signalvalue; signalvalue = arg_ampt->Signal->getAMSinalValue(); if(prevvalue > 0&& signalvalue==0) pauseLoop(); g_retval[itr_sample] = stimulator.DAAD( signalvalue * arg_pulsestate ); if(signalvalue > 0) { swBrd.setTwin(g_ch, nofch); //swBrd.setTwin(ch + 1, ((ch + nofch/2) % nofch) + 1); //swBrd.setTwin(ch + 1, ((ch + nofch/2 - 1) % nofch) + 1); itr_sample = (itr_sample + 1) % g_sample_size_imp; } else { swBrd.allGround(); } #if 0 do { ch = (ch + 1) % nofch; } while ( //false ch + 1 >= 3 //&& //ch + 1 == 1 //|| //ch + 1 >= 3 ); #endif //if (ch+1 == 2) ch = 6 -1; //if (ch+1 == 6) ch = 2 -1; //if (ch+1 == 5) ch = 2 - 1; //if (ch+1 == 6) ch = 1 - 1; } uint16_t callback_AMSignalExpression (AMPulseTrain* arg_ampt) { static int itr = -1; uint16_t ph = (itr < arg_ampt->getPWidth_pPulse_Signal()) ? arg_ampt->Signal->getAmplitude_u16() : 0; itr = (itr + 1) % arg_ampt->getPeriod_pPulse_Signal(); return ph; } void init (void) { //void init_Hardware(void) { stimulator.init(); swBrd.allHiZ(); swBrd.setPol(SwArr16MOSFET::Anodic); //swBrd.setPol(SwArr16MOSFET::Cathodic); swBrd.setTwin(1,2); } myled1 = 1; NVIC_SetPriority(TIMER3_IRQn, 255); //void init_commands(void) { ampt.attachCallback_asPulseEdge(callback_PulseEdge); ampt.attachAMSignalExpression(callback_AMSignalExpression); command_handler.map("1", &setch1); command_handler.map("2", &setch2); command_handler.map("3", &setch3); command_handler.map("4", &setch4); 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(); wait(.1); myled2 = 1; } 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( callback(&t, &ulseTrain::incrementClock), ampt.getClockperiod_us() ); 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 = ampt.Signal->getAmplitude_uf(); if(lampl < 0.95) lampl += 0.05; else lampl = 1.0; ampt.Signal->setAmplitude(lampl); printStatus(); return NULL; } void * decreaseCurrent(void) { float lampl = ampt.Signal->getAmplitude_uf(); if(0.05 <= lampl ) lampl -= 0.05; else lampl = 0; ampt.Signal->setAmplitude(lampl); printStatus(); return NULL; } void * increaseFrequency(void) { uint32_t lfreq = ampt.Carrier->getFrequency(); if(lfreq < ampt.Carrier->FREQ_MAX - 100) lfreq += 100; else lfreq = ampt.Carrier->FREQ_MAX; ampt.setFrequency_Carrier(lfreq); printf("%d\n", ampt.getClockperiod_us()); if(pstate == MAIN_ROUTINE) ticker.attach_us( callback(&t, &ulseTrain::incrementClock), ampt.getClockperiod_us() ); printStatus(); return NULL; } void * decreaseFrequency(void) { uint32_t lfreq = ampt.Carrier->getFrequency(); if(200 <= lfreq ) lfreq -= 100; else lfreq = 100; ampt.setFrequency_Carrier(lfreq); if(pstate == MAIN_ROUTINE) ticker.attach_us( callback(&t, &ulseTrain::incrementClock), ampt.getClockperiod_us() ); 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 = AMPLE_MAX_mA * ampt.Signal->getAmplitude_uf(); // read values if (scanValue(arg_digits, &lampl));//max 10mA // set values if( lampl < 0.0 || AMPLE_MAX_mA < lampl) lampl = AMPLE_MAX_mA * ampt.Signal->getAmplitude_uf(); ampt.Signal->setAmplitude((float)(lampl / AMPLE_MAX_mA)); pc.puts("===\n"); pc.printf("set frequency:"); reactor.attach(SetFrequency); return NULL; } void * SetFrequency(char const * const arg_digits) { uint32_t lfreq = ampt.Carrier->getFrequency(); if (scanValue(arg_digits, &lfreq)); if( lfreq < 500 || ampt.Carrier->FREQ_MAX < lfreq) lfreq = ampt.Carrier->getFrequency(); ampt.Carrier->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:\n" " ---\n" " v: set all paramater by arbitrary value\n" " ---\n" " UP: Amplitude + 5% of Max I(mA)\n" " Down: Amplitude - 5% of Max I(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) { unsigned int l_max = 0, l_min = 0, l_mean = 0; for (int i = 0; i < g_sample_size_imp; i++) { l_mean += g_retval[i]; if (l_max < g_retval[i]) l_max = g_retval[i]; if (l_min > g_retval[i]) l_min = g_retval[i]; } l_mean /= g_sample_size_imp; pc.printf( "Signal Amplitude: %2.2f (MAX %2.2f)" "Carrier Frequency: %06d \n" "Z(min, mean, max)=(%d, %d, %d)\n" , AMPLE_MAX_mA * ampt.Signal->getAmplitude_uf() , AMPLE_MAX_mA , ampt.Carrier->getFrequency() , l_min, l_mean, l_max); return NULL; }