#include "liftlibio.h" #include "liftlibcontrol.h" /* Global variables */ int lift_levelPos[16]; int lift_one_level; /** Is the counter valid for level positioning? */ int lift_cntValid; /** Position absolute or relative<. */ int lift_cnt; /** Last stoped level (1..13) if position is absolute else 0. */ int lift_level; /** load position in level, 0 means we don't know */ int lift_loadLevel; /** we're going TOP or BOTTOM, but stop at load position. */ int lift_loadPending; /** we're waiting for the load sensor to go. */ int lift_loadSensor; /** cmd keeps the value of the command until the command is finished. It is only updated by the switches if it's current value is CMD_NONE. */ int lift_cmd; int lift_timMotor; int lift_timImp; /** Remember last direction for impuls count after motor off; */ int lift_directionUp; /** Last value of impuls sensor. */ int lift_lastImp; int lift_dbgCnt; /** stop value for the counter. */ int lift_endCnt; void lift_ctrl_init() { int i; lift_checksum = 0; lift_io_init(); lift_cntValid = 0; lift_cnt = 0; lift_cmd = lift_CMD_NONE; lift_timMotor = 0; lift_timImp = 0; lift_directionUp = 1; lift_lastImp = 0; lift_loadLevel = 0; lift_loadPending = 0; lift_loadSensor = 0; i = 0; lift_levelPos[i++] = 0; lift_levelPos[i++] = 58; lift_levelPos[i++] = 115; lift_levelPos[i++] = 173; lift_levelPos[i++] = 230; lift_levelPos[i++] = 288; lift_levelPos[i++] = 346; lift_levelPos[i++] = 403; lift_levelPos[i++] = 461; lift_levelPos[i++] = 518; lift_levelPos[i++] = 576; lift_levelPos[i++] = 634; lift_levelPos[i++] = 691; lift_levelPos[i++] = 749; lift_levelPos[i++] = 806; lift_levelPos[i++] = 864; lift_one_level = lift_levelPos[1]; } void lift_ctrl_loop() { if ( lift_cmd == lift_CMD_NONE ) lift_check_cmd(); else { lift_do_impulse( lift_ctrl_io_in[lift_SENS_IMPULS], lift_ctrl_io_out[lift_MOTOR_ON], lift_ctrl_io_in[lift_SENS_BOTTOM] ); lift_do_cmd(); } lift_check_level(); lift_ctrl_io_led[13] = ( lift_dbgCnt & 0x80 ) != 0; ++lift_dbgCnt; } void lift_check_level() { int i; int middle = lift_one_level >> 2; if ( lift_cntValid ) { _Pragma( "loopbound min 14 max 14" ) for ( lift_level = 1; lift_level < 14; ++lift_level ) { if ( lift_cnt < lift_levelPos[lift_level] - middle ) break; } } else lift_level = 0; _Pragma( "loopbound min 14 max 14" ) for ( i = 0; i < 14; ++i ) lift_ctrl_io_led[i] = ( i == lift_level - 1 ); } void lift_check_cmd() { if ( lift_loadPending ) { if ( lift_ctrl_io_in[lift_SENS_BOTTOM] ) lift_cmd = lift_CMD_TOP; } else if ( lift_ctrl_io_in[lift_GO_UP] ) { if ( !lift_ctrl_io_in[lift_SENS_TOP] && lift_level != 14 ) lift_cmd = lift_CMD_UP; } else if ( lift_ctrl_io_in[lift_GO_DOWN] ) { if ( !lift_ctrl_io_in[lift_SENS_BOTTOM] && lift_level != 1 ) lift_cmd = lift_CMD_DOWN; } else if ( lift_ctrl_io_in[lift_GO_LOAD] ) { if ( lift_loadLevel != 0 && lift_level < lift_loadLevel ) lift_cmd = lift_CMD_TOP; else lift_cmd = lift_CMD_BOTTOM; lift_loadPending = 1; lift_loadSensor = 0; } else if ( lift_ctrl_io_in[lift_GO_TOP] ) { if ( !lift_ctrl_io_in[lift_SENS_TOP] ) lift_cmd = lift_CMD_TOP; } else if ( lift_ctrl_io_in[lift_GO_BOTTOM] ) { if ( !lift_ctrl_io_in[lift_SENS_BOTTOM] ) lift_cmd = lift_CMD_BOTTOM; } if ( lift_cmd != lift_CMD_NONE ) lift_timMotor = 50; } void lift_do_impulse( int val, int motor, int reset ) { if ( val && !lift_lastImp ) { if ( motor || lift_timImp > 0 ) { if ( lift_directionUp ) ++lift_cnt; else --lift_cnt; } } if ( reset ) { lift_cnt = 0; lift_cntValid = 1; } lift_lastImp = val; if ( lift_timImp > 0 ) { --lift_timImp; if ( lift_timImp == 0 && lift_cmd != lift_CMD_NONE ) lift_cmd = lift_CMD_NONE; } } void lift_do_cmd() { int run = 0; if ( lift_timMotor > 0 ) lift_wait_for_motor_start(); else { run = lift_check_run(); if ( lift_ctrl_io_out[lift_MOTOR_ON] && !run ) { /* motor stopped: */ lift_cmd = 99; lift_timImp = 50; } lift_ctrl_io_out[lift_MOTOR_ON] = run; } } void lift_wait_for_motor_start() { int newLevel = 0; --lift_timMotor; lift_directionUp = ( lift_cmd == lift_CMD_UP || lift_cmd == lift_CMD_TOP ); lift_ctrl_io_out[lift_MOTOR_UP] = lift_directionUp; if ( !lift_cntValid ) { lift_cnt = 0; /* use relative counter */ if ( lift_cmd == lift_CMD_UP ) lift_endCnt = lift_one_level; else lift_endCnt = -lift_one_level; } else { lift_endCnt = lift_cnt; newLevel = -99; if ( lift_cmd == lift_CMD_UP ) newLevel = lift_level + 1; else if ( lift_cmd == lift_CMD_DOWN ) newLevel = lift_level - 1; --newLevel; /* lift_level is one based */ if ( newLevel >= 0 && newLevel < 14 ) lift_endCnt = lift_levelPos[newLevel]; } } int lift_check_run() { if ( lift_cmd == lift_CMD_UP ) { if ( lift_cnt < lift_endCnt - 1 && !lift_ctrl_io_in[lift_SENS_TOP] ) return 1; } else if ( lift_cmd == lift_CMD_DOWN ) { if ( lift_cnt > lift_endCnt + 1 && !lift_ctrl_io_in[lift_SENS_BOTTOM] ) return 1; } else if ( lift_cmd == lift_CMD_TOP ) { if ( lift_loadPending && lift_ctrl_io_in[lift_SENS_LOAD] ) { /* we are at lift_load position */ lift_loadLevel = lift_level; lift_loadPending = 0; return 0; } if ( !lift_ctrl_io_in[lift_SENS_TOP] ) return 1; /* safe fallback if lift_load sensor does not work */ lift_loadPending = 0; } else if ( lift_cmd == lift_CMD_BOTTOM ) { if ( lift_loadPending ) { if ( lift_loadSensor ) { if ( !lift_ctrl_io_in[lift_SENS_LOAD] ) { lift_loadSensor = 0; /* we are at lift_load position */ lift_loadPending = 0; lift_loadLevel = lift_level; return 0; } } lift_loadSensor = lift_ctrl_io_in[lift_SENS_LOAD]; } if ( !lift_ctrl_io_in[lift_SENS_BOTTOM] ) return 1; } return 0; }