한국어 English Chinese Russian

모터 제어기

모터 제어기는 펌웨어가 내장된 프로그래머블 유선랜 IoT 보드와 모터제어 기능을 제공하기 위해 하드웨어 인터페이스가 있는 스마트 확장보드가 결합된 드라이버 일체형 제어기입니다.

//task0.php
<?php
include_once "/lib/sd_spc.php";

spc_reset(); // reset all smart slaves stacked on P4S-34X
spc_sync_baud(115200); // synchronize master to slave baud-rate

spc_request_dev(1, "set vref stop 4");   // set stop current to 4/15
spc_request_dev(1, "set vref drive 15"); // set drive current to 15/15
spc_request_dev(1, "set mode 32");       // set micro-step to 1/32

while(1)
{
  for($i = 0; $i < 4; $i++)
  {
    spc_request_dev(1, "move 16000 128000 1280000");
    while((int)spc_request_dev(1, "get state"))
      usleep(1);
    usleep(200000);
  }

  $pos = -(int)spc_request_dev(1, "get pos");

  spc_request_dev(1, "move $pos"); // return to initial position
  
  while((int)spc_request_dev(1, "get state"))
    usleep(1);
  usleep(200000);
}
?>


//task0.php
<?php
include_once "/lib/sd_spc.php";

spc_reset(); // reset all smart slaves stacked on P4S-34X
spc_sync_baud(115200); // synchronize master to slave baud-rate

spc_request_dev(1, "set vref stop 4");   // set stop current to 4/15
spc_request_dev(1, "set vref drive 15"); // set drive current to 15/15
spc_request_dev(1, "set mode 32");       // set micro-step to 1/32

spc_request_dev(2, "set vref stop 4");   // set stop current to 4/15
spc_request_dev(2, "set vref drive 15"); // set drive current to 15/15
spc_request_dev(2, "set mode 32");       // set micro-step to 1/32

while(1)
{
  for($i = 0; $i < 4; $i++)
  {
    spc_request_dev(1, "move +16000 128000 1280000");
    spc_request_dev(2, "move -16000 128000 1280000");
	
    while((int)spc_request_dev(1, "get state"))
      usleep(1);
    usleep(200000);
  }

  $pos1 = -(int)spc_request_dev(1, "get pos");
  $pos2 = -(int)spc_request_dev(2, "get pos");

  spc_request_dev(1, "move $pos1"); // return to initial position
  spc_request_dev(2, "move $pos2"); // return to initial position
  
  while((int)spc_request_dev(1, "get state"))
    usleep(1);
  usleep(200000);
}
?>


//task0.php
<?php
include_once "/lib/sd_340.php";
include_once "/lib/sd_spc.php";
include_once "/lib/sn_tcp_ws.php";

define("PWM_PERIOD", 20000); // (20ms)
define("WIDTH_MIN", 600);
define("WIDTH_MAX", 2450);

define("SID_X",      13);
define("SID_Y",      14);

define("MAX_X",      1710);
define("MAX_Y",      2140);
define("TOUCH_OFFSET",  100);

define("PEN_UP",     0);
define("PEN_DOWN",   1);

define("CMD_PEN_UP",   0);
define("CMD_PEN_DOWN", 1);
define("CMD_MOVE",     2);

define("SPEED_X_COEF",    20);
define("SPEED_Y_COEF",    20);
define("SPEED_X_OFFSET",  50);
define("SPEED_Y_OFFSET",  50);
define("SPEED_X_MAX",     5000);
define("SPEED_Y_MAX",     5000);

define("ACCEL_X_COEF",    1500);
define("ACCEL_Y_COEF",    1000);
define("ACCEL_X_OFFSET",  0);
define("ACCEL_Y_OFFSET",  0);
define("ACCEL_X_MAX",     20000);
define("ACCEL_Y_MAX",     20000);

define("STATE_X_LOCK",  1);
define("STATE_X_RUN",   2);
define("STATE_Y_LOCK",  4);
define("STATE_Y_RUN",   8);


function step_cmd($sid, $cmd)
{
  $resp = spc_request($sid, 4, $cmd);

  if($resp)
  {
    $resp = explode(",", $resp);

    if((int)$resp[0] != 200)
    {
      echo "step_cmd : '$cmd' request error ", $resp[0], "\r\n";
      return false;
    }

    if(count($resp) > 1)
      return $resp[1];
    else
      return "";
  }
  else
    return false;
}

function spc_check_did($sid, $did)
{
  $resp = spc_request_csv($sid, 0, "get did");

  if($resp === false)
  {
    echo "spc_check_did: sid$sid - device not found\r\n";
    return false;
  }

  if($resp[1] != "40002405")
  {
    echo "spc_check_did: unknown device ", $resp[2], "\r\n";
    return false;
  }

  return true;
}

function pen_up()
{
  $angle = 110;

  $width = WIDTH_MIN + (int)round((WIDTH_MAX - WIDTH_MIN) * $angle / 180.0);

  if(($width >= WIDTH_MIN) && ($width <= WIDTH_MAX))
    ht_pwm_width(2, $width, PWM_PERIOD);
}

function pen_down()
{
  $angle = 180;

  $width = WIDTH_MIN + (int)round((WIDTH_MAX - WIDTH_MIN) * $angle / 180.0);

  if(($width >= WIDTH_MIN) && ($width <= WIDTH_MAX))
    ht_pwm_width(2, $width, PWM_PERIOD);
}

function xy_goto($x, $y)
{
  global $mode;
  
  if($x < TOUCH_OFFSET)
    $x = TOUCH_OFFSET;
  if($x > (MAX_X - TOUCH_OFFSET))
    $x = MAX_X - TOUCH_OFFSET;
  
  if($y < TOUCH_OFFSET)
    $y = TOUCH_OFFSET;
  if($y > (MAX_Y - TOUCH_OFFSET))
    $y = MAX_Y - TOUCH_OFFSET;
  
  $x0 = (int)step_cmd(SID_X, "get pos") / $mode;
  $y0 = (int)step_cmd(SID_Y, "get pos") / $mode;
  
  $delta_x = $x - $x0; 
  $delta_y = $y - $y0;
  
  if($delta_x == 0 && $delta_y == 0)
    return;
  
  $speed_x = SPEED_X_COEF * abs($delta_x) + SPEED_X_OFFSET;
  $speed_y = SPEED_Y_COEF * abs($delta_y) + SPEED_Y_OFFSET;
  
  $x *= $mode; 
  $y *= $mode;
  $speed_x *= $mode;
  $speed_y *= $mode;
  
  if($speed_x > SPEED_X_MAX * $mode)
    $speed_x = SPEED_X_MAX * $mode;
  
  if($speed_y > SPEED_Y_MAX * $mode)
    $speed_y = SPEED_Y_MAX * $mode;
  
  $accel_x = ACCEL_X_COEF * $speed_x + ACCEL_X_OFFSET;
  $accel_y = ACCEL_Y_COEF * $speed_y + ACCEL_Y_OFFSET;
  
  if($accel_x > ACCEL_X_MAX * $mode)
    $accel_x = ACCEL_X_MAX * $mode;
  
  if($accel_y > ACCEL_Y_MAX * $mode)
    $accel_y = ACCEL_Y_MAX * $mode;
  
  if($delta_x == 0)
  {
    step_cmd(SID_Y, "goto $y $speed_y $accel_y");
  }
  else if($delta_y == 0)
  {
    step_cmd(SID_X, "goto $x $speed_x $accel_x");
  }
  else
  {
    step_cmd(SID_X, "goto $x $speed_x $accel_x");
    step_cmd(SID_Y, "goto $y $speed_y $accel_y");
  }
  //echo "state: ", step_cmd(SID_Y, "get state"), "\r\n";
  //echo SID_X, ", goto $x $speed_x $accel_x\r\n";
  //echo SID_Y, ", goto $y $speed_y $accel_y\r\n";
}

function xy_state()
{
  $ret_val = 0;
  
  $x_state = (int)step_cmd(SID_X, "get state");
  $y_state = (int)step_cmd(SID_Y, "get state");
  
  if($x_state == 1) // motor is locked
    $ret_val |= STATE_X_LOCK;
  else if($x_state > 1) // motor is running
    $ret_val |= STATE_X_RUN;
    
  if($y_state == 1) // motor is locked
    $ret_val |= STATE_Y_LOCK;
  else if($y_state > 1) // motor is running
    $ret_val |= STATE_Y_RUN;
    
  return $ret_val;
}

function xy_wait()
{
  while(xy_state() & (STATE_X_RUN | STATE_Y_RUN))
    usleep(1);
}

function xy_init()
{
  global $mode;
  
  $width = WIDTH_MIN + (int)round((WIDTH_MAX - WIDTH_MIN) * 110 / 180.0);
  ht_pwm_setup(2, $width, PWM_PERIOD);
  pen_up();
  
  spc_reset();
  spc_sync_baud(460800);

  if(!spc_check_did(SID_X, "40002405"))
    return;
  if(!spc_check_did(SID_Y, "40002405"))
    return;

  step_cmd(SID_X, "set vref stop 4");
  step_cmd(SID_X, "set vref drive 15");
  step_cmd(SID_X, "set mode $mode");
  step_cmd(SID_X, "set rsnc 120 250");
  
  step_cmd(SID_Y, "set vref stop 4");
  step_cmd(SID_Y, "set vref drive 15");
  step_cmd(SID_Y, "set mode $mode");
  step_cmd(SID_Y, "set rsnc 120 250");
  
  // move pen to (0, 0)
  $v = 800 * $mode;
  $a = 10000 * $mode;
  step_cmd(SID_X, "goto -sw1 $v $a");
  step_cmd(SID_Y, "goto -sw1 $v $a");
  xy_wait();
  step_cmd(SID_X, "reset");
  step_cmd(SID_Y, "reset");
  /*
  $time_stemp = st_free_get_count(0);
  step_cmd(SID_X, "goto 100 $v $a");
  step_cmd(SID_Y, "goto 100 $v $a");
  xy_wait();
  $time_stemp = st_free_get_count(0) - $time_stemp;
  
  echo $time_stemp;
  
  step_cmd(SID_X, "reset");
  step_cmd(SID_Y, "reset");
  */
  xy_goto(TOUCH_OFFSET, TOUCH_OFFSET);
  xy_wait();
  
  // uncomment this block for the first run and change the value in line 45 of index.php
  /*
  // check max steps
  step_cmd(SID_X, "goto +sw0 1600 20000");
  step_cmd(SID_Y, "goto +sw0 1600 20000");
  
  xy_wait();
  // change this value in line 45 of index.php: var MAX_X * $mode = 3421, MAX_Y * $mode = 4296;
  echo "Max X:", step_cmd(SID_X, "get pos"), "\r\n";
  echo "Max Y:", step_cmd(SID_Y, "get pos"), "\r\n";
  */
}

function send_position($pen_state)
{
  global $mode;
  
  $x = (int)step_cmd(SID_X, "get pos") / $mode;
  $y = (int)step_cmd(SID_Y, "get pos") / $mode;
  $wbuf = "[$x, $y, $pen_state]";
  ws_write(0, $wbuf);
}

$mode = 32;

ws_setup(0, "xy_plotter", "csv.phpoc");
xy_init();

$pre_x = 0;
$pre_y = 0;
$cur_x = 0;
$cur_y = 0;
$rbuf = "";
$pen_state = CMD_PEN_UP;
$x_is_unlock = false;
$y_is_unlock = false;

while(1)
{
  if(ws_state(0) == TCP_CONNECTED)
  {
    $rlen = ws_read_line(0, $rbuf);
    
    if($rlen)
    {
      $data = explode(" ", $rbuf);
      $cmd = (int)$data[0];
      
      switch($cmd)
      {
        case CMD_PEN_DOWN:
          $x = (int)$data[1];
          $y = (int)$data[2];
          xy_goto($x, $y);
          xy_wait();
          
          pen_down();
          $pen_state = PEN_DOWN;
          
          send_position($pen_state);
          
          break;
        case CMD_PEN_UP:
          pen_up();
          $pen_state = PEN_UP;
          
          send_position($pen_state);
          
          break;
        case CMD_MOVE:
          $x = (int)$data[1];
          $y = (int)$data[2];
          xy_goto($x, $y);
          //xy_wait();
          
          break;
      }
    }
  }
  
  $cur_x = (int)step_cmd(SID_X, "get pos") / $mode;
  $cur_y = (int)step_cmd(SID_Y, "get pos") / $mode;
  
  if(abs($pre_x - $cur_x) > 10 || abs($pre_y - $cur_y) > 10)
  {
    $pre_x = $cur_x;
    $pre_y = $cur_y;
    send_position($pen_state);
  }
  
  $xy_state = xy_state();
  
  if(($xy_state & STATE_X_LOCK) && ($x_is_unlock == false))
  {
    step_cmd(SID_X, "unlock");
    $x_is_unlock = true;
  }
  else if(($xy_state & STATE_X_RUN))
  {
    step_cmd(SID_X, "eio set 0 mode lock");
    step_cmd(SID_X, "eio set 1 mode lock");
    $x_is_unlock = false;
  }
  
  if(($xy_state & STATE_Y_LOCK) && ($y_is_unlock == false))
  {
    step_cmd(SID_Y, "unlock");
    $y_is_unlock = true;
  }
  else if(($xy_state & STATE_Y_RUN))
  {
    step_cmd(SID_Y, "eio set 0 mode lock");
    step_cmd(SID_Y, "eio set 1 mode lock");
    $y_is_unlock = false;
  }
}
?>