diff --git a/LocCorr_new.old.tgz b/LocCorr_new.old.tgz new file mode 100644 index 0000000..47ac934 Binary files /dev/null and b/LocCorr_new.old.tgz differ diff --git a/LocCorr_new/CANSERVER_pusirobo b/LocCorr_new/CANSERVER_pusirobo deleted file mode 100644 index a7cf164..0000000 --- a/LocCorr_new/CANSERVER_pusirobo +++ /dev/null @@ -1,9 +0,0 @@ -MULTIPLY steps & speed by microsteps!!! - -register U 0x581 stepper -> OK\nU maxspeed=OK -mesg U maxspeed 12800 -> OK\nU maxspeed=OK -register V 0x582 stepper -> OK\nV maxspeed=OK -mesg V maxspeed 12800 -> OK\nV maxspeed=OK -mesg U relmove 1600 -> OK\nU rotdir=OK\nU relsteps=OK -mesg U setzero -> OK\nU curpos=OK -mesg V setzero -> OK\nV curpos=OK diff --git a/LocCorr_new/CMakeLists.txt b/LocCorr_new/CMakeLists.txt index eff40e0..9450ac8 100644 --- a/LocCorr_new/CMakeLists.txt +++ b/LocCorr_new/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.20) set(PROJ loccorr) -set(MINOR_VERSION "1") -set(MID_VERSION "0") +set(MINOR_VERSION "0") +set(MID_VERSION "1") set(MAJOR_VERSION "0") set(VERSION "${MAJOR_VERSION}.${MID_VERSION}.${MINOR_VERSION}") @@ -40,7 +40,7 @@ message("Build type: ${CMAKE_BUILD_TYPE}") ###### pkgconfig ###### # pkg-config modules (for pkg-check-modules) -set(MODULES usefull_macros cfitsio improc) +set(MODULES usefull_macros>=0.3.2 cfitsio improc) # find packages: SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}) diff --git a/LocCorr_new/Changelog b/LocCorr_new/Changelog new file mode 100644 index 0000000..9dfcdcc --- /dev/null +++ b/LocCorr_new/Changelog @@ -0,0 +1,3 @@ +Mon Apr 28 13:05:48 MSK 2025 +Move to libusefull_macros v0.3.2. +Fixed some troubles with `inotifying` log files. \ No newline at end of file diff --git a/LocCorr_new/basler.c b/LocCorr_new/basler.c index 0b52f12..1589171 100644 --- a/LocCorr_new/basler.c +++ b/LocCorr_new/basler.c @@ -63,7 +63,7 @@ static char* describeError(GENAPIC_RESULT reserr){ #define PYLONFN(fn, ...) do{register GENAPIC_RESULT reserr; if(GENAPI_E_OK != (reserr=fn(__VA_ARGS__))){ \ WARNX(#fn "(): %s", describeError(reserr)); return FALSE;}}while(0) -static void disconnect(){ +static void cam_disconnect(){ FNAME(); if(!isopened) return; FREE(imgBuf); @@ -180,13 +180,13 @@ static void disableauto(){ } static void GENAPIC_CC removalCallbackFunction(_U_ PYLON_DEVICE_HANDLE hDevice){ - disconnect(); + cam_disconnect(); } -static int connect(){ +static int cam_connect(){ FNAME(); size_t numDevices; - disconnect(); + cam_disconnect(); PylonInitialize(); PYLONFN(PylonEnumerateDevices, &numDevices); if(!numDevices){ @@ -223,7 +223,7 @@ static Image *capture(){ static double t0 = 0.; if(!getFloat("DeviceTemperature", &f)) WARNX("Can't get temperature"); else{ - double t = dtime(); + double t = sl_dtime(); if(t - t0 >= 30.){ // log T each 30 seconds LOGMSG("Basler temperature: %.1f", f.val); t0 = t; @@ -327,8 +327,8 @@ static float gainmax(){ // exported object camera Basler = { - .disconnect = disconnect, - .connect = connect, + .disconnect = cam_disconnect, + .connect = cam_connect, .capture = capture, .setbrightness = setbrightness, .setexp = setexp, diff --git a/LocCorr_new/cameracapture.c b/LocCorr_new/cameracapture.c index 289c9d2..6bff645 100644 --- a/LocCorr_new/cameracapture.c +++ b/LocCorr_new/cameracapture.c @@ -228,13 +228,13 @@ static void *procthread(void* v){ typedef void (*procfn_t)(Image*); void (*process)(Image*) = (procfn_t)v; #ifdef EBUG - double t0 = dtime(); + double t0 = sl_dtime(); #endif while(!stopwork){ while(iCaptured < 0) usleep(1000); pthread_mutex_lock(&capt_mutex); if(Icap[iCaptured]){ - DBG("---- got image #%d @ %g", iCaptured, dtime() - t0); + DBG("---- got image #%d @ %g", iCaptured, sl_dtime() - t0); Image *oIma = Icap[iCaptured]; // take image here and free buffer Icap[iCaptured] = NULL; pthread_mutex_unlock(&capt_mutex); @@ -263,7 +263,7 @@ static void *procthread(void* v){ } FREE(oIma->data); FREE(oIma); - DBG("---- cleared image data @ %g", dtime() - t0); + DBG("---- cleared image data @ %g", sl_dtime() - t0); }else pthread_mutex_unlock(&capt_mutex); usleep(1000); } diff --git a/LocCorr_new/cmdlnopts.c b/LocCorr_new/cmdlnopts.c index 057a53b..323d032 100644 --- a/LocCorr_new/cmdlnopts.c +++ b/LocCorr_new/cmdlnopts.c @@ -61,7 +61,7 @@ static glob_pars G = { * Define command line options by filling structure: * name has_arg flag val type argptr help */ -static myoption cmdlnopts[] = { +static sl_option_t cmdlnopts[] = { // common options {"maxexp", NEED_ARG, NULL, 0, arg_double, APTR(&G.maxexp), _("maximal exposition time (ms), default: 500")}, {"minexp", NEED_ARG, NULL, 0, arg_double, APTR(&G.minexp), _("minimal exposition time (ms), default: 0.001")}, @@ -106,13 +106,13 @@ glob_pars *parse_args(int argc, char **argv){ char helpstring[1024], *hptr = helpstring; snprintf(hptr, hlen, "Usage: %%s [args]\n\n\tWhere args are:\n"); // format of help: "Usage: progname [args]\n" - change_helpstring(helpstring); + sl_helpstring(helpstring); // parse arguments - parseargs(&argc, &argv, cmdlnopts); - if(help) showhelp(-1, cmdlnopts); + sl_parseargs(&argc, &argv, cmdlnopts); + if(help) sl_showhelp(-1, cmdlnopts); if(argc > 0){ WARNX("Extra parameters!"); - showhelp(-1, cmdlnopts); + sl_showhelp(-1, cmdlnopts); } return &G; } diff --git a/LocCorr_new/config.c b/LocCorr_new/config.c index 1566900..75ba0c8 100644 --- a/LocCorr_new/config.c +++ b/LocCorr_new/config.c @@ -290,7 +290,7 @@ confparam *chk_keyval(const char *key, const char *val, key_value *result){ break; case PAR_DOUBLE: //DBG("DOUBLE"); - if(!str2double(&result->val.dblval, val)){ + if(!sl_str2d(&result->val.dblval, val)){ WARNX("Wrong double value '%s' of parameter '%s'", val, key); return NULL; } diff --git a/LocCorr_new/debug.c b/LocCorr_new/debug.c index 6e813f1..4759d66 100644 --- a/LocCorr_new/debug.c +++ b/LocCorr_new/debug.c @@ -18,6 +18,7 @@ #ifdef EBUG +#include #include #include @@ -25,10 +26,11 @@ #define DEBUGLOG "DEBUG.log" -sl_log *debuglog = NULL; +sl_log_t *debuglog = NULL; void makedebuglog(){ unlink(DEBUGLOG); + DBG("Create debug log file: " DEBUGLOG); debuglog = sl_createlog(DEBUGLOG, LOGLEVEL_ANY, 0); } diff --git a/LocCorr_new/debug.h b/LocCorr_new/debug.h index 00c41f5..a3709b4 100644 --- a/LocCorr_new/debug.h +++ b/LocCorr_new/debug.h @@ -27,7 +27,7 @@ #ifdef EBUG -extern sl_log *debuglog; +extern sl_log_t *debuglog; void makedebuglog(); void *my_malloc(size_t N, size_t S); void my_free(void *ptr); @@ -36,6 +36,7 @@ void my_free(void *ptr); #undef ALLOC #undef MALLOC #undef FREE +#undef DBGLOG #define _LOG(...) do{if(!debuglog) makedebuglog(); sl_putlogt(1, debuglog, LOGLEVEL_ERR, __VA_ARGS__);}while(0) #define DBGLOG(...) do{_LOG("%s (%s, line %d)", __func__, __FILE__, __LINE__); \ sl_putlogt(0, debuglog, LOGLEVEL_ERR, __VA_ARGS__);}while(0) diff --git a/LocCorr_new/grasshopper.c b/LocCorr_new/grasshopper.c index c9aac7a..64d8884 100644 --- a/LocCorr_new/grasshopper.c +++ b/LocCorr_new/grasshopper.c @@ -20,6 +20,7 @@ #include #include // FLT_EPSILON #include +#include #include #include @@ -39,7 +40,7 @@ static fc2Error err = FC2_ERROR_OK; #define FC2FN(fn, ...) do{err = FC2_ERROR_OK; if(FC2_ERROR_OK != (err=fn(context __VA_OPT__(,) __VA_ARGS__))){ \ WARNX(Stringify(fn) "(): %s", fc2ErrorToDescription(err)); return FALSE;}}while(0) -static void disconnect(){ +static void cam_disconnect(){ fc2DestroyContext(context); } @@ -178,7 +179,7 @@ static int changeformat(frameformat *fmt){ return TRUE; } -static int connect(){ +static int cam_connect(){ FNAME(); unsigned int numCameras = 0; if(FC2_ERROR_OK != (err = fc2CreateContext(&context))){ @@ -263,8 +264,8 @@ static float maxgain(){ // exported object camera GrassHopper = { - .disconnect = disconnect, - .connect = connect, + .disconnect = cam_disconnect, + .connect = cam_connect, .capture = capture, .setbrightness = setbrightness, .setexp = setexp, diff --git a/LocCorr_new/hikrobot.c b/LocCorr_new/hikrobot.c index 3e23ab5..4f2a740 100644 --- a/LocCorr_new/hikrobot.c +++ b/LocCorr_new/hikrobot.c @@ -235,7 +235,7 @@ static int cam_findCCD(){ return TRUE; } -static int connect(){ +static int cam_connect(){ if(!cam_findCCD()) return FALSE; cam_closecam(); lastecode = MV_CC_CreateHandleWithoutLog(&handle, stDeviceList.pDeviceInfo[0]); @@ -374,10 +374,10 @@ static int cam_startexp(){ static Image* capture(){ if(!cam_startexp()) return NULL; MV_FRAME_OUT_INFO_EX stImageInfo = {0}; // last image info - double starttime = dtime(); + double starttime = sl_dtime(); do{ usleep(100); - double diff = exptime - (dtime() - starttime); + double diff = exptime - (sl_dtime() - starttime); if(diff > 0.) continue; // wait until exposure ends DBG("diff = %g", diff); if(diff < -5.0){ // wait much longer than exp lasts @@ -393,7 +393,7 @@ static Image* capture(){ camera Hikrobot = { .disconnect = cam_closecam, - .connect = connect, + .connect = cam_connect, .capture = capture, .setbrightness = cam_setbright, .setexp = setexp, diff --git a/LocCorr_new/improc.c b/LocCorr_new/improc.c index 3d8db63..f6a4f2c 100644 --- a/LocCorr_new/improc.c +++ b/LocCorr_new/improc.c @@ -107,7 +107,7 @@ static void getDeviation(object *curobj){ Xc[counter] = curobj->xc; Yc[counter] = curobj->yc; if(fXYlog){ // make log record fprintf(fXYlog, "%-14.2f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t", - dtime() - tstart, curobj->xc, curobj->yc, + sl_dtime() - tstart, curobj->xc, curobj->yc, curobj->xsigma, curobj->ysigma, curobj->WdivH); } //DBG("counter = %d", counter); @@ -209,8 +209,8 @@ void process_file(Image *I){ il_ConnComps *cc = NULL; size_t *S = NULL; #ifdef EBUG - double t0 = dtime(), tlast = t0; -#define DELTA(p) do{double t = dtime(); DBG("---> %s @ %gms (delta: %gms)", p, (t-t0)*1e3, (t-tlast)*1e3); tlast = t;}while(0) + double t0 = sl_dtime(), tlast = t0; +#define DELTA(p) do{double t = sl_dtime(); DBG("---> %s @ %gms (delta: %gms)", p, (t-t0)*1e3, (t-tlast)*1e3); tlast = t;}while(0) #else #define DELTA(x) #endif @@ -324,7 +324,7 @@ void process_file(Image *I){ qsort(Objects, objctr, sizeof(object), compDist); } SKIP_FULL_PROCESS: - DBGLOG("T%.2f, N=%d\n", dtime(), objctr); + DBGLOG("T%.2f, N=%d\n", sl_dtime(), objctr); DELTA("Calculate deviations"); if(objctr){ #ifdef EBUG @@ -386,8 +386,8 @@ SKIP_FULL_PROCESS: } }else Image_write_jpg(I, GP->outputjpg, theconf.equalize); ++ImNumber; - if(lastTproc > 1.) FPS = 1. / (dtime() - lastTproc); - lastTproc = dtime(); + if(lastTproc > 1.) FPS = 1. / (sl_dtime() - lastTproc); + lastTproc = sl_dtime(); DELTA("End"); } @@ -408,7 +408,7 @@ static char *watchfl(const char *messageid, char *buf, int buflen){ } int process_input(InputType tp, char *name){ - DBG("process_input(%d, %s)", tp, name); + LOGDBG("process_input(%d, %s)", tp, name); if(tp == T_DIRECTORY){ imagedata = watchdr; return watch_directory(name, process_file); @@ -460,7 +460,7 @@ void openXYlog(const char *name){ fprintf(fXYlog, "# Start at: %s", ctime(&t)); fprintf(fXYlog, "# time\t\tXc\tYc\tSx\tSy\tW/H\taverX\taverY\tSX\tSY\n"); fflush(fXYlog); - tstart = dtime(); + tstart = sl_dtime(); } void closeXYlog(){ if(!fXYlog) return; diff --git a/LocCorr_new/inotify.c b/LocCorr_new/inotify.c index 6d46ed9..20d601d 100644 --- a/LocCorr_new/inotify.c +++ b/LocCorr_new/inotify.c @@ -43,16 +43,25 @@ static int changed(const char *name, int fd, uint32_t mask){ WARN("inotify read()"); return -1; } + DBG("got: %zd", len); if(len < 1) return 0; // not ready uint32_t bm = buf[0].mask; buf[0].mask = 0; - for(int i = 0; i < 10; ++i) - DBG("CHANGED: %s (%d)\n", buf[i].name, bm); + int i = 9; + for(; i > -1; --i){ // find last changed file + DBG("%d: mask=%04x; len=%u", i, buf[i].mask, buf[i].len); + if(buf[i].mask & IN_IGNORED || buf[i].len < 1) continue; + DBG("%d: name=%s", i, buf[i].name); + } + if(i == -1){ + DBG("NO names found"); + return -1; + } if(bm & mask){ if(name){ - snprintf(filenm, FILENAME_MAX, "%s/%s", name, buf[0].name); // full path + snprintf(filenm, FILENAME_MAX, "%s/%s", name, buf[i].name); // full path }else{ - snprintf(filenm, FILENAME_MAX, "%s", buf[0].name); // file name + snprintf(filenm, FILENAME_MAX, "%s", buf[i].name); // file name } return 1; } @@ -98,6 +107,10 @@ static int watch_any(const char *name, void (*process)(Image*), uint32_t mask){ if(ch == 1){ // changed if(process){ Image *I = Image_read(filenm); + if(!I && (mask & IN_ISDIR)){ // changed file isn't an image + DBG("Changed file isn't an image"); + continue; + } process(I); } } @@ -109,7 +122,7 @@ static int watch_any(const char *name, void (*process)(Image*), uint32_t mask){ int watch_file(const char *name, void (*process)(Image*)){ - FNAME(); + DBG("try to watch file %s", name); if(!name){ WARNX("Need filename"); return 1; @@ -118,7 +131,7 @@ int watch_file(const char *name, void (*process)(Image*)){ } int watch_directory(char *name, void (*process)(Image*)){ - FNAME(); + DBG("try to watch directory %s", name); if(!name){ WARNX("Need directory name"); return 1; diff --git a/LocCorr_new/main.c b/LocCorr_new/main.c index 0e3329a..53c3932 100644 --- a/LocCorr_new/main.c +++ b/LocCorr_new/main.c @@ -66,14 +66,15 @@ void iffound_default(pid_t pid){ } static void *procinp_thread(_U_ void* arg){ + LOGDBG("procinp_thread(%s)", GP->inputname); int p = process_input(tp, GP->inputname); - LOGDBG("process_input=%d", p); + LOGERR("procinp_thread(%s)=%d", GP->inputname, p); return NULL; } static InputType chk_inp(const char *name){ if(!name) ERRX("Point file or directory name to monitor"); - InputType itp = chkinput(GP->inputname); + InputType itp = chkinput(name); if(T_WRONG == itp) return T_WRONG; green("\n%s is a ", name); switch(itp){ @@ -116,7 +117,7 @@ static InputType chk_inp(const char *name){ } int main(int argc, char *argv[]){ - initial_setup(); + sl_init(); char *self = strdup(argv[0]); GP = parse_args(argc, argv); if(!chkconfig(GP->configname)){ @@ -142,11 +143,8 @@ int main(int argc, char *argv[]){ fclose(f); } if(GP->logfile){ - sl_loglevel lvl = LOGLEVEL_ERR; // default log level - errors - int v = GP->verb; - while(v--){ // increase loglevel for each "-v" - if(++lvl == LOGLEVEL_ANY) break; - } + sl_loglevel_e lvl = LOGLEVEL_ERR + GP->verb; // default log level - errors + if(lvl > LOGLEVEL_ANY) lvl = LOGLEVEL_ANY; OPENLOG(GP->logfile, lvl, 1); DBG("Opened log file @ level %d", lvl); } @@ -194,7 +192,7 @@ int main(int argc, char *argv[]){ theconf.stpserverport = GP->steppersport; } } - check4running(self, GP->pidfile); + sl_check4running(self, GP->pidfile); DBG("%s started, snippets library version is %s\n", self, sl_libversion()); free(self); self = NULL; signal(SIGTERM, signals); // kill (-15) - quit @@ -202,6 +200,7 @@ int main(int argc, char *argv[]){ signal(SIGINT, signals); // ctrl+C - quit signal(SIGQUIT, signals); // ctrl+\ - quit signal(SIGTSTP, SIG_IGN); // ignore ctrl+Z + DBGLOG("\n\n\nStarted; capt: %s", GP->inputname); while(1){ // guard for dead processes childpid = fork(); if(childpid){ // father @@ -216,6 +215,7 @@ int main(int argc, char *argv[]){ break; // go out to normal functional } } + DBGLOG("start thread; capt: %s", GP->inputname); if(!(theSteppers = steppers_connect())){ LOGERR("Steppers server unavailable, can't run"); WARNX("Steppers server unavailable, can't run"); diff --git a/LocCorr_new/median.c b/LocCorr_new/median.c index 503eab7..b0c4ff9 100644 --- a/LocCorr_new/median.c +++ b/LocCorr_new/median.c @@ -361,7 +361,7 @@ Image *get_median(const Image *img, int seed){ size_t blksz = seed * 2 + 1, fullsz = blksz * blksz; #ifdef EBUG - double t0 = dtime(); + double t0 = sl_dtime(); #endif OMP_FOR(shared(inputima, med)) for(size_t x = seed; x < w - seed; ++x){ @@ -385,7 +385,7 @@ Image *get_median(const Image *img, int seed){ } Image_minmax(out); DBG("time for median filtering %zdx%zd of image %zdx%zd: %gs", blksz, blksz, w, h, - dtime() - t0); + sl_dtime() - t0); return out; } @@ -401,7 +401,7 @@ int get_stat(const Image *in, int seed, Image **mean, Image **std){ if(!in) return FALSE; if(seed < 1 || seed > (in->width - 1)/2 || seed > (in->height - 1)/2) return FALSE; #ifdef EBUG - double t0 = dtime(); + double t0 = sl_dtime(); #endif Image *M = NULL, *S = NULL; if(mean) M = Image_sim(in); @@ -441,6 +441,6 @@ int get_stat(const Image *in, int seed, Image **mean, Image **std){ Image_minmax(S); *std = S; } - DBG("time for mean/sigma computation: %gs", dtime() - t0); + DBG("time for mean/sigma computation: %gs", sl_dtime() - t0); return TRUE; } diff --git a/LocCorr_new/steppers.c b/LocCorr_new/steppers.c index 838cdba..2e1effc 100644 --- a/LocCorr_new/steppers.c +++ b/LocCorr_new/steppers.c @@ -266,10 +266,10 @@ static ssize_t read_message(char *msg, size_t msglen){ LOGWARN("read_message(): pthread_mutex_lock() err"); return 0; } - double t0 = dtime(); + double t0 = sl_dtime(); size_t gotbytes = 0; --msglen; // for trailing zero - while(dtime() - t0 < WAITANSTIME && gotbytes < msglen && sockfd > 0){ + while(sl_dtime() - t0 < WAITANSTIME && gotbytes < msglen && sockfd > 0){ if(!canread()) continue; int n = recv(sockfd, msg+gotbytes, msglen, 0); if(n <= 0){ // disconnect or error @@ -280,7 +280,7 @@ static ssize_t read_message(char *msg, size_t msglen){ gotbytes += n; msglen -= n; if(msg[gotbytes-1] == '\n') break; - t0 = dtime(); + t0 = sl_dtime(); } //DBG("Dt=%g, gotbytes=%zd, sockfd=%d, msg='%s'", dtime()-t0,gotbytes,sockfd,msg); pthread_mutex_unlock(&mesg_mutex); @@ -343,8 +343,8 @@ static errcodes getecode(const char *msg){ */ static errcodes read_and_parse(steppercmd idx){ char value[128], msg[1024]; - double t0 = dtime(); - while(dtime() - t0 < WAITANSTIME*10.){ + double t0 = sl_dtime(); + while(sl_dtime() - t0 < WAITANSTIME*10.){ ssize_t got = read_message(msg, 1024); if(got < 1) continue; //LOGDBG("GOT from stepper server:\n%s\n", msg); @@ -760,7 +760,7 @@ static int try2correct(double dX, double dY){ pidU.Kp = theconf.PIDU_P; pidU.Ki = theconf.PIDU_I; pidU.Kd = theconf.PIDU_D; pidV.Kp = theconf.PIDV_P; pidV.Ki = theconf.PIDV_I; pidV.Kd = theconf.PIDV_D; double dU, dV; - double current_time = dtime(); + double current_time = sl_dtime(); if( current_time - pidU.prev_time > MAX_PID_TIME || current_time - pidV.prev_time > MAX_PID_TIME){ LOGWARN("Too old PID time: have dt=%gs", current_time - pidU.prev_time); @@ -803,7 +803,7 @@ static int try2correct(double dX, double dY){ * This function called from improc.c each time the corrections calculated (ONLY IF Xtarget/Ytarget > -1) */ static void stp_process_corrections(double X, double Y){ - static bool coordstrusted = TRUE; + static int coordstrusted = TRUE; if(!relaxed(Ustepper) || !relaxed(Vstepper)){ // don't process coordinates when moving coordstrusted = FALSE; coordsRdy = FALSE; @@ -958,7 +958,7 @@ static char *set_stpstatus(const char *newstatus, char *buf, int buflen){ // MAIN THREAD static void *stp_process_states(_U_ void *arg){ // FNAME(); - static bool first = TRUE; // flag for logging when can't reconnect + static int first = TRUE; // flag for logging when can't reconnect while(!stopwork){ usleep(10000); // check for disconnection flag @@ -989,10 +989,10 @@ static void *stp_process_states(_U_ void *arg){ if(nth_motor_setter(CMD_RELPOS, Vstepper, dVmove)) dVmove = 0; } static double t0 = -1.; - if(t0 < 0.) t0 = dtime(); + if(t0 < 0.) t0 = sl_dtime(); if(state != STP_DISCONN){ - if(dtime() - t0 >= 0.1){ // each 0.1s check state if steppers aren't disconnected - t0 = dtime(); + if(sl_dtime() - t0 >= 0.1){ // each 0.1s check state if steppers aren't disconnected + t0 = sl_dtime(); chkall(); } if(!relaxed(Ustepper) && !relaxed(Vstepper)) continue;