add web-interface

This commit is contained in:
eddyem 2019-10-23 17:49:32 +03:00
parent cbec6c1f63
commit d348acd7f9
7 changed files with 322 additions and 8 deletions

View File

@ -55,6 +55,9 @@
// minimal & maximal focus positions (should be >min+dF0 & <max-dF0) // minimal & maximal focus positions (should be >min+dF0 & <max-dF0)
#define FOCMIN 200 #define FOCMIN 200
#define FOCMAX 320000 #define FOCMAX 320000
// focus raw positions @ endswitches (< or >)
#define FOCPOS_CW_ESW 5000
#define FOCPOS_CCW_ESW 315000
// the same in mm // the same in mm
#define FOCMIN_MM 0.1 #define FOCMIN_MM 0.1
#define FOCMAX_MM 76.0 #define FOCMAX_MM 76.0

View File

@ -35,11 +35,30 @@ static unsigned long motor_id = 0, motor_p_id = 0;//, bcast_id = 1;
static unsigned long curposition = 0; static unsigned long curposition = 0;
// encoder's node number // encoder's node number
static int encnodenum = 0; 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_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 canstatus can_read_par(uint8_t subidx, uint16_t idx, uint32_t *parval);
static int move(unsigned long targposition, int16_t rawspeed); 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 * @brief init_encoder - encoder's interface initialisation
* @param encnode - encoder's node number * @param encnode - encoder's node number
@ -107,6 +126,7 @@ int init_encoder(int encnode, int reset){
else for(i=0;i<n;i++) else for(i=0;i<n;i++)
verbose("Node%d PDO%d %08lx (%ld)\n",node[i],pdo_n[i],pdo_v[i],pdo_v[n]); verbose("Node%d PDO%d %08lx (%ld)\n",node[i],pdo_n[i],pdo_v[i],pdo_v[n]);
}while(0); }while(0);
curstatus = STAT_OK;
return 0; return 0;
} }
@ -132,12 +152,15 @@ int go_out_from_ESW(){
} }
if(e == ESW_BOTH_ACTIVE){ // error situation! if(e == ESW_BOTH_ACTIVE){ // error situation!
WARNX("Error: both end-switches are active!"); WARNX("Error: both end-switches are active!");
curstatus = STAT_BOTHESW;
return 1; return 1;
} }
if(e == ESW_INACTIVE){ if(e == ESW_INACTIVE){
DBG("Esw inactive"); DBG("Esw inactive");
curstatus = STAT_OK;
return 0; return 0;
} }
curstatus = STAT_GOFROMESW;
// try to move from esw // try to move from esw
parval = DI_NOFUNC; parval = DI_NOFUNC;
uint16_t idx = (e == ESW_CW_ACTIVE) ? PAR_CW_IDX : PAR_CCW_IDX; uint16_t idx = (e == ESW_CW_ACTIVE) ? PAR_CW_IDX : PAR_CCW_IDX;
@ -147,7 +170,6 @@ int go_out_from_ESW(){
getPos(NULL); getPos(NULL);
DBG("try %d, pos: %lu, E=%d", i, curposition, e); DBG("try %d, pos: %lu, E=%d", i, curposition, e);
unsigned long targ = (e == ESW_CW_ACTIVE) ? curposition - (double)FOCSCALE_MM*0.2 : curposition + (double)FOCSCALE_MM*0.2; unsigned long targ = (e == ESW_CW_ACTIVE) ? curposition - (double)FOCSCALE_MM*0.2 : curposition + (double)FOCSCALE_MM*0.2;
if(move(targ, speed)) continue; if(move(targ, speed)) continue;
get_endswitches(&e); get_endswitches(&e);
if(e == ESW_INACTIVE) break; if(e == ESW_INACTIVE) break;
@ -158,11 +180,14 @@ int go_out_from_ESW(){
if(CAN_NOERR != can_write_par(PAR_DI_SUBIDX, PAR_CCW_IDX, &parval)) goto bad; if(CAN_NOERR != can_write_par(PAR_DI_SUBIDX, PAR_CCW_IDX, &parval)) goto bad;
if(e != ESW_INACTIVE){ if(e != ESW_INACTIVE){
WARNX("Can't move out of end-switch"); WARNX("Can't move out of end-switch");
curstatus = STAT_ERROR;
return 1; return 1;
} }
curstatus = STAT_OK;
return 0; return 0;
bad: bad:
WARNX("Can't get/set esw parameters"); WARNX("Can't get/set esw parameters");
curstatus = STAT_ERROR;
return 1; return 1;
} }
@ -193,6 +218,26 @@ int init_motor_ids(int addr){
int getPos(double *pos){ int getPos(double *pos){
int r = !(getLong(encnodenum, DS406_POSITION_VAL, 0, &curposition)); int r = !(getLong(encnodenum, DS406_POSITION_VAL, 0, &curposition));
if(pos) *pos = FOC_RAW2MM(curposition); if(pos) *pos = FOC_RAW2MM(curposition);
eswstate e;
if(CAN_NOERR != get_endswitches(&e)){
WARNX("Can't read end-switches state");
curstatus = STAT_ERROR;
}else switch(e){
case ESW_BOTH_ACTIVE:
curstatus = STAT_BOTHESW;
break;
case ESW_CCW_ACTIVE:
if(curposition > 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; return r;
} }
@ -433,6 +478,7 @@ int stop(){
* @return 0 if all OK * @return 0 if all OK
*/ */
int movewconstspeed(int spd){ int movewconstspeed(int spd){
if(chk_eswstates()) return 1;
int16_t targspd = RAWSPEED(spd); int16_t targspd = RAWSPEED(spd);
unsigned char buf[8] = {0,}; unsigned char buf[8] = {0,};
buf[1] = CW_ENABLE; buf[1] = CW_ENABLE;
@ -457,6 +503,7 @@ static int move(unsigned long targposition, int16_t rawspeed){
verbose("Already at position\n"); verbose("Already at position\n");
return 0; return 0;
} }
if(chk_eswstates()) return 1;
unsigned char buf[6] = {0,}; unsigned char buf[6] = {0,};
DBG("Start moving with speed %d", rawspeed); DBG("Start moving with speed %d", rawspeed);
buf[1] = CW_ENABLE; buf[1] = CW_ENABLE;
@ -481,25 +528,35 @@ static int move(unsigned long targposition, int16_t rawspeed){
can_dsleep(0.01); can_dsleep(0.01);
//uint16_t motstat; //uint16_t motstat;
double speed; double speed;
eswstate esw;
if(emerg_stop){ // emergency stop activated if(emerg_stop){ // emergency stop activated
WARNX("Activated stop while moving"); WARNX("Activated stop while moving");
stop(); stop();
curstatus = STAT_OK;
return 1; return 1;
} }
if(get_motor_speed(&speed) != CAN_NOERR){ // WTF? if(get_motor_speed(&speed) != CAN_NOERR){ // WTF?
WARNX("Unknown situation: can't get speed of moving motor"); WARNX("Unknown situation: can't get speed of moving motor");
stop(); stop();
curstatus = STAT_ERROR;
return 1; 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){ if(get_endswitches(&esw) != CAN_NOERR){
WARNX("Can't get endswitches state, stopping"); WARNX("Can't get endswitches state, stopping");
stop(); stop();
curstatus = STAT_ERROR;
return 1; return 1;
} }
if(esw != ESW_INACTIVE){ // OOps, something wrong if(esw != ESW_INACTIVE){ // OOps, something wrong
if(esw == ESW_BOTH_ACTIVE){ // error! if(esw == ESW_BOTH_ACTIVE){ // error!
WARNX("Check end-switches, both active!"); WARNX("Check end-switches, both active!");
curstatus = STAT_BOTHESW;
stop(); stop();
return 1; 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(rawspeed > 0){ // moving CW, don't care for CCW esw state
if(esw == ESW_CW_ACTIVE){ if(esw == ESW_CW_ACTIVE){
WARNX("CW mowing: end-switch!"); WARNX("CW mowing: end-switch!");
curstatus = STAT_ESW;
stop(); stop();
return 1; return 1;
} }
}else{ // movig CCW }else{ // movig CCW
if(esw == ESW_CCW_ACTIVE){ if(esw == ESW_CCW_ACTIVE){
WARNX("CCW mowing: end-switch!"); WARNX("CCW mowing: end-switch!");
curstatus = STAT_ESW;
stop(); stop();
return 1; 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(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){ if(++zerctr == 10){
WARNX("Motor stopped while moving!"); WARNX("Motor stopped while moving!");
curstatus = STAT_ERROR;
stop(); stop();
return 1; return 1;
} }
@ -538,6 +598,7 @@ static int move(unsigned long targposition, int16_t rawspeed){
if(i == MOVING_TIMEOUT){ if(i == MOVING_TIMEOUT){
WARNX("Error: timeout, but motor still not @ position! STOP!"); WARNX("Error: timeout, but motor still not @ position! STOP!");
stop(); stop();
curstatus = STAT_ERROR;
return 1; return 1;
} }
DBG("end-> curpos: %ld, difference: %ld, tm=%g\n", curposition, targposition - curposition, can_dtime()-t0); 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) if(abs(targposition - curposition) > RAWPOS_TOLERANCE)
verbose("Current (%ld) position is too far from target (%ld)\n", curposition, targposition); 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); DBG("stop-> curpos: %ld, difference: %ld, tm=%g\n", curposition, targposition - curposition, can_dtime()-t0);
curstatus = STAT_OK;
return r; return r;
} }
@ -714,3 +776,7 @@ void movewithmon(double spd){
} }
#undef PRINT #undef PRINT
} }
sysstatus get_status(){
return curstatus;
}

View File

@ -37,6 +37,18 @@ typedef enum{
ESW_BOTH_ACTIVE = 3 ESW_BOTH_ACTIVE = 3
} eswstate; } 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); int init_encoder(int encnode, int reset);
void returnPreOper(); void returnPreOper();
int getPos(double *pos); int getPos(double *pos);
@ -49,5 +61,6 @@ int move2pos(double target);
int stop(); int stop();
int movewconstspeed(int spd); int movewconstspeed(int spd);
int go_out_from_ESW(); int go_out_from_ESW();
sysstatus get_status();
#endif // CAN_ENCODER_H__ #endif // CAN_ENCODER_H__

View File

@ -0,0 +1,49 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<style type="text/css">
body{text-align:center;}
.shadow{
position:absolute;
text-align:center;
vertical-align: center;
top:0;
display: none;
left:0;
width:100%;
height:100%;
background-color: lightGrey;
opacity: 0.5;
}
.B{font-weight: bold;}
.big{font-size: 200%;}
.M{margin-bottom: 5px;}
.C{text-align:center; padding: 10px;}
.btm{margin-top: 15px; color: red; position: fixed; bottom: 10px;
width: 50%; left: 25%; font-size: 200%;}
</style>
<script src="focus.js" type="text/javascript" language="javascript"></script>
<title>Zeiss-1000 focusing</title>
</head>
<body onload="Foc.Run();">
<noscript><h1>Turn ON JavaScript!!!</h1></noscript>
<div class="C" id="container">
<div class="C M big" onclick="Foc.upd();">
Current F=<span id="curFval"></span>
</div>
<div class="C M big">
<label for="speed">Speed: </label>
<input style="width: 50px" id="speed" type="number" value="1" min="1" max="4" onchange="Foc.chSpd(this.value);">
<button class="B" id="F-" onmousedown="Foc.Move(-1);" onmouseup="Foc.Stop();">-</button>
<!--<input style="width: 300px" id="focSlider" type="range" min="0" max="100" step="1" value="50" readonly>-->
<button class="B" id="F+" onmousedown="Foc.Move(1);" onmouseup="Foc.Stop();">+</button>&nbsp;&nbsp;
</div>
<div class="C big">
<button class="B" id="Fstop" onclick="Foc.Stop();">Stop</button>
<input style="width: 130px" id="focSet" type="number" lang="en-150" value="2" min="0.1" max="65" step="0.01"> <!-- onchange="Foc.Ch(this.value);"-->
<button class="B" id="Fset" onclick="Foc.SetFocus();">Set</button>
</div>
</div>
<div class="shadow" id="shadow">
</body>
</html>

143
Z1000_focus/html/focus.js Normal file
View File

@ -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", "<br>");
}
// 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", "<br>");
$("_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,
}
}();

View File

@ -193,7 +193,7 @@ static void *handle_socket(void *asock){
// empty request == focus request // empty request == focus request
if(strlen(found) < 1 || getparam(S_CMD_FOCUS)){ if(strlen(found) < 1 || getparam(S_CMD_FOCUS)){
DBG("position request"); DBG("position request");
snprintf(buff, BUFLEN, "%.3f", curPos()); snprintf(buff, BUFLEN, "%.03f", curPos());
}else if(getparam(S_CMD_STOP)){ }else if(getparam(S_CMD_STOP)){
DBG("Stop request"); DBG("Stop request");
emerg_stop = TRUE; emerg_stop = TRUE;
@ -226,6 +226,29 @@ static void *handle_socket(void *asock){
DBG("Move to position %g request", pos); DBG("Move to position %g request", pos);
sprintf(buff, startmoving(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); }else sprintf(buff, S_ANS_ERR);
if(!send_data(sock, webquery, buff)){ if(!send_data(sock, webquery, buff)){
WARNX("can't send data, some error occured"); 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 usleep(500000); // sleep a little or thread's won't be able to lock mutex
// get current position // get current position
pthread_mutex_lock(&canbus_mutex); if(!pthread_mutex_trylock(&canbus_mutex)){
getPos(NULL); getPos(NULL);
pthread_mutex_unlock(&canbus_mutex); 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); }while(1);
putlog("daemon_(): UNREACHABLE CODE REACHED!"); putlog("daemon_(): UNREACHABLE CODE REACHED!");
} }

View File

@ -36,12 +36,22 @@
#define S_CMD_FOCUS "focus" #define S_CMD_FOCUS "focus"
#define S_CMD_TARGSPEED "targspeed" #define S_CMD_TARGSPEED "targspeed"
#define S_CMD_GOTO "goto" #define S_CMD_GOTO "goto"
#define S_CMD_STATUS "status"
// answers through the socket // answers through the socket
#define S_ANS_ERR "error" #define S_ANS_ERR "error"
#define S_ANS_OK "OK" #define S_ANS_OK "OK"
#define S_ANS_MOVING "moving" #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; bool emerg_stop;
void daemonize(const char *port); void daemonize(const char *port);