[RepRap] My interactive RepRap control and G-Code parsing program

This is version 0.1 of my reprap controller. I don’t have much time to work on in so I’ll publish it in a non-finished state (then again, what is ‘finished’?). It still needs an open minicom session with the appropriate settings. I can make stty do this, but it works for me right now…

[edit] This work is now documented Here, at the RepRap Builders Wiki[/edit]

#!/usr/bin/php -q
<?php
/* ------------------------------------------------------------
// dotG 2 GCode
// By Erik de Bruijn, september 2008
//
// this script parses cam.py's .g files and pre-processes them 
// for .gcode files that run on RepRap Generation 2 electro-
// nics with the GCode firmware.
//
// Depends on php5-cli (ubuntu/debian: apt-get install php5-cli)
// Licence: GPLv3
//          See http://www.gnu.org/licenses/gpl.txt
// When distributing it, please include a copy of the licence.
   ----------------------------------------------------------*/
// todo: add ; in front of lines than can be skipped.

if(!isset($argv[2])) die("dotG2Gcode v0.1 - by Erik de Bruijn

Usage:
1. Make a .g file with MIT's cam.py

Process a file:
$argv[0] convert inputfile.g outputfile.gcode

Control the machine interactively line-by-line:
$argv[0] i[nteractive] [inputfile.g]

");

$fdata file($argv[2]);
foreach(
$fdata as $line)
{
  if(
trim($line)=='%') continue; // start & end notice... don't send
  
if(!strlen(trim($line))) continue; // remove blank lines
  
if(trim($line)=='O1234') continue;
  if(
$line{0}=='%') continue;

  if(ereg("G([0-9]+)[^0-9]",$line,$gcode))
  {
//echo "G code: ".$gcode[1];
    
switch($gcode[1])
    {
//       case 90: continue; break;
    
}
  }
  if(
$line{0}=='G'$out[]=trim($line)."\n";
  if(
$line{0}=='M'$out[]=trim($line)."\n";
  if(
$line{0}=='X'$out[]="G1".trim($line)."\n";
}

if(($argv[1]=='convert') || ($argv[1]{0}=='c'))
{
  
$fileout implode('',$out);
  
file_put_contents($argv[3],$fileout);
}

$commands = array(
'Quit'=>array('do'=>'quit','desc'=>'Exit the program.','aliasses'=>'Exit'),
'Help'=>array('do'=>'help','desc'=>'Show this help.'),
'Speed'=>array('do'=>'speed','desc'=>'Change G1 movement speeds'),
'History'=>array('do'=>'history','desc'=>'Show the history of commands'),
'Home'=>array('do'=>'home','desc'=>'Go to home position (G1X0Y0Z0)'),
'helpg'=>array('do'=>'helpg','desc'=>'Explanation of G codes'),
'absolute'=>array('do'=>'absolute','desc'=>'Absolute positioning (G90)'),
'relative'=>array('do'=>'relative','desc'=>'Relative positioning (G91)'),
'newhome'=>array('do'=>'newhome','desc'=>'Make this the new home (G92)'),
'fan_on'=>array('do'=>'fan_on','desc'=>'Turn on the cooler fan (M106)'),
'fan_off'=>array('do'=>'fan_off','desc'=>'Turn on the cooler fan (M107)'),
'spindle_on'=>array('do'=>'fan_on','desc'=>'Turn on the spindle (M106)'),
'spindle_off'=>array('do'=>'fan_off','desc'=>'Turn on the spindle (M107)'),
'unit_mm'=>array('do'=>'unit_mm','desc'=>'Make the milimeter the basic unit (G21)'),
'unit_inch'=>array('do'=>'unit_mm','desc'=>'Make the milimeter the basic unit (G20)'),
);

foreach($commands as $myac=>$bla)
{
  
$myAutoComplete[]='/'.strtolower($myac);
}
// $myAutoComplete[]='';
readline_completion_function('autoComplete');

if(($argv[1]=='interactive') || ($argv[1]{0}=='i'))
{
echo 
"     _       _    ____
  __| | ___ | |_ / ___|
 / _` |/ _ \| __| |  _
| (_| | (_) | |_| |_| |
 \__,_|\___/ \__|\____|\n"
;
echo 
"----INTERACTIVE MODE----\nCommands start with '/'. /h is help! Tab to autocomplete\n";
$dev "/dev/ttyUSB0";

$reprap= new RepRap($dev);
$reprap->gcode("G21\n"); 
$unit 'mm';
$linenr 0;
$fp fopen($dev,'r');
// stty ispeed 19200 ospeed 19200 cs8 raw -echo -parenb -cstopb onlcr < $port
// if(!is_writable($dev)) echo "Warning: Device $dev is not writable.\n";
$G='';
  while(!
$abort)
  {
    
$prompt ".G$G: ";
    
$cmd readline($prompt);
    if((
$cmd!='n')&&($cmd!='r')&&($cmd!='p'))
      
readline_add_history($cmd);
    list(
$do,$args) = parseCmd($cmd);
    if(
$cmd=='n')
    {
      if(
$linenr==count($out)) echo "This was the last line.\n";
      else {
        
$linenr++;
        
$line $out[$linenr-1];
        echo 
"Line $linenr: $line";
        
readline_add_history($line);
      }
    }
    if(
$cmd=='p')
    {
      if(
$linenr==1) echo "This is the first line.\n";
      else {
        
$linenr--;
        
$line $out[$linenr-1];
        echo 
"Line $linenr: $line";
        
readline_add_history($line);
      }
    }
    if(
$cmd=='r')
    {
        
$args $out[$linenr-1];
      if(
$linenr==count($out)) echo "This was the last line.\n";
      else {
        
$linenr++;
        
$line $out[$linenr-1];
        echo 
"Next $linenr: $line";
      }
    }
    switch (
$do)
    {
      case 
"quit":
        
fclose($fp);
        exit(
0);
      case 
"help":
        foreach(
$commands as $aKey => $aCommand)
          echo 
"  $aKey\t$aCommand[desc]\n";
      break;
      case 
"helpg":
        foreach(
$commands as $aKey => $aCommand)
          echo 
"  $aKey\t$aCommand[desc]\n";
      break;
      case 
"gcode":
        if(
ereg("G([0-9]+)[^0-9]?.*$",$args,$regs))
          
$G=$regs[1];
        echo 
"GCode: ".$args."\n";
        
$reprap->gcode($args);
      break;
      case 
"absolute"$reprap->gcode("G90\n"); break;
      case 
"relative"$reprap->gcode("G91\n"); break;
      case 
"newhome"$reprap->gcode("G92\n"); break;
      case 
"fan_on"$reprap->gcode("M106\n"); break;
      case 
"fan_off"$reprap->gcode("M107\n"); break;
      case 
"unit_inch"$reprap->gcode("G20\n"); $unit 'inch'; break;
      case 
"unit_mm"$reprap->gcode("G21\n"); $unit 'mm'; break;
      case 
"home":
        
$args='G1X0Y0Z0';
        echo 
"GCode: ".$args."\n";
        
$reprap->gcode($args);
      break;
      case 
"speed":
        if(
$unit == 'mm')
          
$speed 10.0*doubleval(readline("XY Speed (2.5-80 cm/s): "));//25 - 800 mm/s
        
else
          
$speed doubleval(readline("XY Speed (1-30): "));
        
$reprap->setG1speedXY($speed);
        if(
$unit == 'mm')
          
$speed 10.0*doubleval(readline("Z Speed (0.25-1.5 mm/s): "));
        else
          
$speed doubleval(readline("Z Speed (0.01-0.50): "));
        
$reprap->setG1speedZ($speed);
//         echo "Result: ".fgets($fp)."\n";
      
break;
    }
  }
}

function parseCmd($theCommand)
{
  global 
$commands;
  if(
ereg("^/(([a-z])[a-z]*) (.*)$",strtolower($theCommand).' ',$regs))
  {
    
$firstChar $regs[2];
    
$cmd $regs[1];
    
$args trim($regs[3]);
    foreach(
$commands as $aCommand=>$cmd_props)
    {
      
$aCommand=strtolower($aCommand);
      if(
$cmd==$aCommand)
      {
        
$do=$cmd_props['do'];
        break;
      }
      if((
strlen($cmd)==1) && ($aCommand{0}==$cmd))
      {
        
$do=$cmd_props['do'];
        break;
      }
    }
    if(!isset(
$do))
      echo 
"Command '$cmd' not recognized.\n";
    return array(
$do,$args);
  }
  return array(
'gcode',$theCommand);
}
function 
autoComplete($partial)
{
  global 
$myAutoComplete;
  return 
$myAutoComplete;
}
class 
RepRap {

  function RepRap($dev)
  {
    
$this->changeDev($dev);
//     $this->g1speedZ
//     var $this->g1speedXY = null;
  
}

  function changeDev($dev)
  {
    if(
file_exists($dev))
      
$this->dev=$dev;
    if(
file_exists("/dev/".$dev))
      
$this->dev="/dev/".$dev;
  }

  function setG1speedXY($speed)
  {
    
$this->g1speedXY $speed;
  }
  function 
setG1speedZ($speed)
  {
    
$this->g1speedZ $speed;
  }

  function gcode($str)
  {
    if((
substr($str,0,2) == 'G1') && (!strpos($str,"F")))
    {
      if(
strpos($str,'Z'))
        
$str trim($str).'F'.$this->g1speedZ."\n";
      else
        
$str trim($str).'F'.$this->g1speedXY."\n";
    }
    
$safe_args escapeshellarg($str);
    
$dev escapeshellarg($this->dev);
    `
echo $safe_args >> $dev`;
  }
}
?>


Dit vind je misschien ook leuk...