From d348acd7f9efff12e4aecfba7f23b69e98a4d676 Mon Sep 17 00:00:00 2001 From: eddyem Date: Wed, 23 Oct 2019 17:49:32 +0300 Subject: [PATCH] add web-interface --- Z1000_focus/HW_dependent.h | 3 + Z1000_focus/can_encoder.c | 74 ++++++++++++++++++- Z1000_focus/can_encoder.h | 13 ++++ Z1000_focus/html/focus.html | 49 ++++++++++++ Z1000_focus/html/focus.js | 143 ++++++++++++++++++++++++++++++++++++ Z1000_focus/socket.c | 38 +++++++++- Z1000_focus/socket.h | 10 +++ 7 files changed, 322 insertions(+), 8 deletions(-) create mode 100644 Z1000_focus/html/focus.html create mode 100644 Z1000_focus/html/focus.js diff --git a/Z1000_focus/HW_dependent.h b/Z1000_focus/HW_dependent.h index 62b1503..e8b24b8 100644 --- a/Z1000_focus/HW_dependent.h +++ b/Z1000_focus/HW_dependent.h @@ -55,6 +55,9 @@ // minimal & maximal focus positions (should be >min+dF0 & ) +#define FOCPOS_CW_ESW 5000 +#define FOCPOS_CCW_ESW 315000 // the same in mm #define FOCMIN_MM 0.1 #define FOCMAX_MM 76.0 diff --git a/Z1000_focus/can_encoder.c b/Z1000_focus/can_encoder.c index e33d379..88efb2f 100644 --- a/Z1000_focus/can_encoder.c +++ b/Z1000_focus/can_encoder.c @@ -35,11 +35,30 @@ static unsigned long motor_id = 0, motor_p_id = 0;//, bcast_id = 1; static unsigned long curposition = 0; // encoder's node number static int encnodenum = 0; - +// system status +static sysstatus curstatus = STAT_OK; static canstatus can_write_par(uint8_t subidx, uint16_t idx, uint32_t *parval); static canstatus can_read_par(uint8_t subidx, uint16_t idx, uint32_t *parval); static int move(unsigned long targposition, int16_t rawspeed); +// return 0 if all OK +static int chk_eswstates(){ + uint32_t cw, ccw; + if(CAN_NOERR != can_read_par(PAR_DI_SUBIDX, PAR_CW_IDX, &cw)) goto verybad; + if(CAN_NOERR != can_read_par(PAR_DI_SUBIDX, PAR_CCW_IDX, &ccw)) goto verybad; + uint32_t parval = DI_ENSTOP; + if(cw != DI_ENSTOP || ccw != DI_ENSTOP){ // activate enable/stop + WARNX("\n\nThe end-switches state wasn't default!"); + if(CAN_NOERR != can_write_par(PAR_DI_SUBIDX, PAR_CW_IDX, &parval)) goto verybad; + if(CAN_NOERR != can_write_par(PAR_DI_SUBIDX, PAR_CCW_IDX, &parval)) goto verybad; + } + return 0; +verybad: + WARNX("Can't return esw to default state"); + curstatus = STAT_ERROR; + return 1; +} + /** * @brief init_encoder - encoder's interface initialisation * @param encnode - encoder's node number @@ -107,6 +126,7 @@ int init_encoder(int encnode, int reset){ else for(i=0;i FOCPOS_CCW_ESW) curstatus = STAT_BADESW; + else curstatus = STAT_ESW; + break; + case ESW_CW_ACTIVE: + if(curposition < FOCPOS_CW_ESW) curstatus = STAT_BADESW; + else curstatus = STAT_ESW; + break; + case ESW_INACTIVE: + default: + curstatus = STAT_OK; + } return r; } @@ -433,6 +478,7 @@ int stop(){ * @return 0 if all OK */ int movewconstspeed(int spd){ + if(chk_eswstates()) return 1; int16_t targspd = RAWSPEED(spd); unsigned char buf[8] = {0,}; buf[1] = CW_ENABLE; @@ -457,6 +503,7 @@ static int move(unsigned long targposition, int16_t rawspeed){ verbose("Already at position\n"); return 0; } + if(chk_eswstates()) return 1; unsigned char buf[6] = {0,}; DBG("Start moving with speed %d", rawspeed); buf[1] = CW_ENABLE; @@ -481,25 +528,35 @@ static int move(unsigned long targposition, int16_t rawspeed){ can_dsleep(0.01); //uint16_t motstat; double speed; - eswstate esw; if(emerg_stop){ // emergency stop activated WARNX("Activated stop while moving"); stop(); + curstatus = STAT_OK; return 1; } if(get_motor_speed(&speed) != CAN_NOERR){ // WTF? WARNX("Unknown situation: can't get speed of moving motor"); stop(); + curstatus = STAT_ERROR; return 1; } + getPos(NULL); + if(curstatus != STAT_OK){ + WARNX("Something bad with end-switches"); + stop(); + return 1; + } + /* eswstate esw; if(get_endswitches(&esw) != CAN_NOERR){ WARNX("Can't get endswitches state, stopping"); stop(); + curstatus = STAT_ERROR; return 1; } if(esw != ESW_INACTIVE){ // OOps, something wrong if(esw == ESW_BOTH_ACTIVE){ // error! WARNX("Check end-switches, both active!"); + curstatus = STAT_BOTHESW; stop(); return 1; } @@ -507,20 +564,23 @@ static int move(unsigned long targposition, int16_t rawspeed){ if(rawspeed > 0){ // moving CW, don't care for CCW esw state if(esw == ESW_CW_ACTIVE){ WARNX("CW mowing: end-switch!"); + curstatus = STAT_ESW; stop(); return 1; } }else{ // movig CCW if(esw == ESW_CCW_ACTIVE){ WARNX("CCW mowing: end-switch!"); + curstatus = STAT_ESW; stop(); return 1; } } - } + }*/ if(fabs(speed) < 0.1){ // || (motstat & (SW_B_UNBLOCK|SW_B_READY|SW_B_POUNBLOCK)) != (SW_B_UNBLOCK|SW_B_READY|SW_B_POUNBLOCK)){ if(++zerctr == 10){ WARNX("Motor stopped while moving!"); + curstatus = STAT_ERROR; stop(); return 1; } @@ -538,6 +598,7 @@ static int move(unsigned long targposition, int16_t rawspeed){ if(i == MOVING_TIMEOUT){ WARNX("Error: timeout, but motor still not @ position! STOP!"); stop(); + curstatus = STAT_ERROR; return 1; } DBG("end-> curpos: %ld, difference: %ld, tm=%g\n", curposition, targposition - curposition, can_dtime()-t0); @@ -553,6 +614,7 @@ static int move(unsigned long targposition, int16_t rawspeed){ if(abs(targposition - curposition) > RAWPOS_TOLERANCE) verbose("Current (%ld) position is too far from target (%ld)\n", curposition, targposition); DBG("stop-> curpos: %ld, difference: %ld, tm=%g\n", curposition, targposition - curposition, can_dtime()-t0); + curstatus = STAT_OK; return r; } @@ -714,3 +776,7 @@ void movewithmon(double spd){ } #undef PRINT } + +sysstatus get_status(){ + return curstatus; +} diff --git a/Z1000_focus/can_encoder.h b/Z1000_focus/can_encoder.h index e545695..a16dbf1 100644 --- a/Z1000_focus/can_encoder.h +++ b/Z1000_focus/can_encoder.h @@ -37,6 +37,18 @@ typedef enum{ ESW_BOTH_ACTIVE = 3 } eswstate; +// system state +typedef enum{ + // non-blocking statuses: + STAT_OK, // all OK + // blocking statuses: + STAT_ESW, // end-switch active + STAT_BADESW, // wrong end-switch active + STAT_BOTHESW, // both end-switches active + STAT_GOFROMESW, // mowing from end-switch + STAT_ERROR // uncoverable error +} sysstatus; + int init_encoder(int encnode, int reset); void returnPreOper(); int getPos(double *pos); @@ -49,5 +61,6 @@ int move2pos(double target); int stop(); int movewconstspeed(int spd); int go_out_from_ESW(); +sysstatus get_status(); #endif // CAN_ENCODER_H__ diff --git a/Z1000_focus/html/focus.html b/Z1000_focus/html/focus.html new file mode 100644 index 0000000..a49c8f0 --- /dev/null +++ b/Z1000_focus/html/focus.html @@ -0,0 +1,49 @@ + + + + + +Zeiss-1000 focusing + + + +
+
+ Current F= +
+
+ + + + +    +
+
+ + + +
+
+
+ + diff --git a/Z1000_focus/html/focus.js b/Z1000_focus/html/focus.js new file mode 100644 index 0000000..62a71e3 --- /dev/null +++ b/Z1000_focus/html/focus.js @@ -0,0 +1,143 @@ +Foc = function(){ +// const REQ_PATH=window.location.hostname+":4444/"; +const REQ_PATH="http://dasha.sao.ru:4444/"; +var minVal=0.01, maxVal=76.5, curVal = 3.0, curSpeed = 1; +var timeout_upd, timeout_msg; +// ID +function $(id){ return document.getElementById(id); } +// Request: req_SRT - request string, _onOK - function to run if all OK +function sendrequest(req_STR, _onOK){ + var request = new XMLHttpRequest(), timeout_id; + request.open("POST", REQ_PATH + req_STR, true); + request.onreadystatechange=function(){ + if (request.readyState == 4){ + if (request.status == 200){ + clearTimeout(timeout_id); + if(_onOK) _onOK(request); + } + else{ + clearTimeout(timeout_id); + blockMsg("Request Error"); + } + } + } + request.send(req_STR); + timeout_id = setTimeout(function(){blockMsg("Request timeout");}, 3000); +} +// show message blocking all +function blockMsg(txt, bgcolor){ + $("shadow").style.display = "block"; + if(!bgcolor) bgcolor = "red"; + $("shadow").innerHTML = txt.replace("\n", "
"); +} +// parse answer for status request +function chkStatus(req){ + var msg = req.responseText; + console.log("Get status message: " + msg); + if(msg == "OK"){ + $("shadow").innerHTML = ""; + $("shadow").style.display = "none"; + }else blockMsg(msg); +}; +// parse answer for command requests +function chkCmd(req){ + var msg = req.responseText; + console.log("Get cmd answer: " + msg); + if(msg != "OK") alert(msg); +} + /* +function ch_status(txt, bgcolor){ + function rmmsg(){clearTimeout(timeout_msg);document.body.removeChild($("_msg_div"));} + clearTimeout(timeout_msg); + if(!bgcolor) bgcolor = "red"; + if(!$("_msg_div")){ // добавляем блок для вывода сообщений + var div = document.createElement('div'), s = div.style; + div.id = "_msg_div"; + div.class = "btm"; + document.body.appendChild(div); + }; + $("_msg_div").style.backgroundColor = bgcolor; + $("_msg_div").innerHTML = txt.replace("\n", "
"); + $("_msg_div").addEventListener("click", rmmsg, true) + timeout_msg = setTimeout(rmmsg, 5000); +}*/ +var first = true; +function chF(req){ + console.log(req.responseText); + curVal = Number(req.responseText); + if(first){ + $('focSet').value = curVal; + first = false; + } + $('curFval').innerHTML = curVal; + //$('focSlider').value = curVal; +} +function getdata(){ + clearTimeout(timeout_upd); + sendrequest("focus", chF); + sendrequest("status", chkStatus); + timeout_upd = setTimeout(getdata, 1000); +} + +// init all things +function FirstRun(){ + blockMsg("init", "black"); + // first we should get all params + chSpd($('speed').value); + var F = $('focSet'); + F.value = curVal; + F.min = minVal; + F.max = maxVal; + getdata(); +} +// send new focus value +function SetFocus(){ + var set = $('focSet').value; + if(set < minVal || set > maxVal){ + alert("Wrong focus value"); + return; + } + console.log("Set focus: " + set); + sendrequest("goto="+set, chkCmd); +} +function Move(dir){ + console.log("Move to " + ((dir > 0) ? "+" : "-") + " with speed " + curSpeed); + var targspeeds = [ 130, 400, 800, 1200 ]; + var cmd = "targspeed=" + ((dir > 0) ? "" : "-") + targspeeds[curSpeed-1]; + sendrequest(cmd, chkCmd); + console.log("send request " + cmd); +} +function Stop(){ + sendrequest("stop", chkCmd); + console.log("Stop"); +} +// slider or input field changed +function change(val){ + if(val < minVal) val = minVal; + else if(val > maxVal) val = maxVal; + //$('focSlider').value = val; + $('focSet').value = val; + console.log("Chfocval: " + val); +} +function chSpd(val){ + if(val < 1) val = 1; + else if(val > 4) val = 4; + $('speed').value = val; + curSpeed = val; + console.log("Chspd: " + val); +} +// update value in input field by current +function update(){ + $('focSet').value = curVal; +} + +return{ + Run: FirstRun, + SetFocus: SetFocus, + Move: Move, + Stop: Stop, + Ch: change, + chSpd: chSpd, + upd: update, + } +}(); diff --git a/Z1000_focus/socket.c b/Z1000_focus/socket.c index 3334991..3e903a7 100644 --- a/Z1000_focus/socket.c +++ b/Z1000_focus/socket.c @@ -193,7 +193,7 @@ static void *handle_socket(void *asock){ // empty request == focus request if(strlen(found) < 1 || getparam(S_CMD_FOCUS)){ DBG("position request"); - snprintf(buff, BUFLEN, "%.3f", curPos()); + snprintf(buff, BUFLEN, "%.03f", curPos()); }else if(getparam(S_CMD_STOP)){ DBG("Stop request"); emerg_stop = TRUE; @@ -226,6 +226,29 @@ static void *handle_socket(void *asock){ DBG("Move to position %g request", pos); sprintf(buff, startmoving(pos)); } + }else if(getparam(S_CMD_STATUS)){ + const char *msg = S_STATUS_ERROR; + switch(get_status()){ + case STAT_OK: + msg = S_STATUS_OK; + break; + case STAT_BADESW: + msg = S_STATUS_BADESW; + break; + case STAT_BOTHESW: + msg = S_STATUS_BOTHESW; + break; + case STAT_ERROR: + msg = S_STATUS_ERROR; + break; + case STAT_ESW: + msg = S_STATUS_ESW; + break; + case STAT_GOFROMESW: + msg = S_STATUS_GOFROMESW; + break; + } + sprintf(buff, msg); }else sprintf(buff, S_ANS_ERR); if(!send_data(sock, webquery, buff)){ WARNX("can't send data, some error occured"); @@ -297,9 +320,16 @@ static void daemon_(int sock){ } usleep(500000); // sleep a little or thread's won't be able to lock mutex // get current position - pthread_mutex_lock(&canbus_mutex); - getPos(NULL); - pthread_mutex_unlock(&canbus_mutex); + if(!pthread_mutex_trylock(&canbus_mutex)){ + getPos(NULL); + if(get_status() != STAT_OK){ + if(!pthread_mutex_trylock(&moving_mutex)){ + go_out_from_ESW(); + pthread_mutex_unlock(&moving_mutex); + } + } + pthread_mutex_unlock(&canbus_mutex); + } }while(1); putlog("daemon_(): UNREACHABLE CODE REACHED!"); } diff --git a/Z1000_focus/socket.h b/Z1000_focus/socket.h index c1ee33a..76e366e 100644 --- a/Z1000_focus/socket.h +++ b/Z1000_focus/socket.h @@ -36,12 +36,22 @@ #define S_CMD_FOCUS "focus" #define S_CMD_TARGSPEED "targspeed" #define S_CMD_GOTO "goto" +#define S_CMD_STATUS "status" // answers through the socket #define S_ANS_ERR "error" #define S_ANS_OK "OK" #define S_ANS_MOVING "moving" +// statuses +#define S_STATUS_OK "OK" +#define S_STATUS_ESW "End-switch active" +#define S_STATUS_ERROR "Uncoverable error" +#define S_STATUS_BOTHESW "Both end-switches active" +#define S_STATUS_BADESW "Wrong end-switch active" +#define S_STATUS_ESW "End-switch active" +#define S_STATUS_GOFROMESW "Moving from end-switch" + bool emerg_stop; void daemonize(const char *port);