Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed SerialInputReactionHandler AMPulseTrain SwArr16MOSFET StrCommandHandler KajiLabES
subroutines.cpp
- Committer:
- aktk
- Date:
- 2020-01-06
- Revision:
- 3:ef730909a664
- Parent:
- 2:5cb68cc8ecaa
- Child:
- 4:8d73aaba879f
File content as of revision 3:ef730909a664:
#include "subroutines.h"
#include "KajiLabES.h"
#include "SwArr16MOSFET.h"
#include "StrCommandHandler.h"
#include "SerialInputReactionHandler.h"
#include "AMPulseTrain.h"
Serial pc(USBTX, USBRX, 921600); // tx, rx
Ticker ticker;
KajiLabES stimulator;
static int const nofch = 8;
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)
);
StrCommandHandler command_handler;
SerialInputReactionHandler reactor;
static const int g_sample_size_imp = 100;
uint16_t g_retval[g_sample_size_imp];
/// 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;
g_retval[itr_sample] = stimulator.DAAD(
arg_ampt->Signal->getAMSinalValue() * arg_pulsestate
);
swBrd.setTwin(ch + 1, ((ch + nofch/2) % nofch) + 1);
//swBrd.setTwin(ch + 1, ((ch + nofch/2 - 1) % nofch) + 1);
ch = (ch + 3) % nofch;
if (ch+1 == 2) ch = 3 -1;
//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;
if(arg_pulsestate == 1) {
itr_sample = (itr_sample + 1) % g_sample_size_imp;
}
}
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::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("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 = 10.0 * ampt.Signal->getAmplitude_uf();
// read values
if (scanValue(arg_digits, &lampl));//max 10mA
// set values
if( lampl < 0.0 || 10.0 < lampl) lampl = 10.0 * ampt.Signal->getAmplitude_uf();
ampt.Signal->setAmplitude((float)(lampl / 10.0));
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 + 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)
{
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: %3.3f "
"Carrier Frequency: %06d \n"
"Z(min, mean, max)=(%d, %d, %d)\n"
, 10.0 * ampt.Signal->getAmplitude_uf(), ampt.Carrier->getFrequency()
, l_min, l_mean, l_max);
return NULL;
}