Classe permettant de controler le K8101 de chez Velleman via PHP
Traduit du perl depuis https://github.com/sebkirche/K8101
Dépendance : PHPCom
<? class K8101 { private $com=""; private $BOC = 0xAA; private $EOC = 0x55; private $cmds = array( "backlight" => 20, "beep" => 6, "clearall" => 2, "clearfg" => 3, "contrast" => 17, "line" => 18, "pixel" => 9, "aire" => 7, "eraseline" => 19, "erasepixel" => 16, "eraseaire" => 8, "invert" => 21, "bitmap" => 1, "smalltext" => 5, "bigtext" => 4, ); /** * Constructor for K8101 * * @param string $tty TTY device to handle */ public function __construct($tty) { $this->com=new PHPcom( $tty, 9600, 8, 1 ); $this->com->Setup( ); $this->com->Open( ); } /** * Destructor for K8101 */ public function __destruct() { $this->com->Close(); } /** * Send Command * * @param string $cmd command to send * @param mixed $args (optional) command's arguments. string, array or gd resource. * @return bool Success */ public function __call($cmd,$args="") { if (count($args)==1) $args=$args[0]; if (isset($this->cmds[$cmd])) { $data=$this->make_cmd($cmd,$args); return $this->com->Write($data); } else throw new Exception("Commande inconnue"); } /** * Command bytes chain maker * * @param string $cmd command to send * @param mixed $args (optional) command's arguments. string, array or gd resource. * @return string Binary Chain */ protected function make_cmd($cmd,$args='') { // Si la commande n'existe pas if (!isset($this->cmds[$cmd])) return false; // Plusieurs arguments (array), on concat�ne et packe if (is_array($args)) { $sor=""; foreach($args AS $arg) { $sor.=$this->packer($arg); }; $args=$sor; } elseif (is_int($args)) $args=$this->packer($args); // Entier, on packe // Functions sp�cifiques ? if (method_exists(__CLASS__,"build_".$cmd)) $data=call_user_func(array(__CLASS__,"build_".$cmd), $args); else $data=$args; // LSB / MSB list($lsb,$msb)=$this->get_data_size($data); // Corrections if (substr($cmd,-4)=="line" || substr($cmd,-4)=="aire") $lsb+=6; // wtf ?!! bug of PIC ? elseif ($cmd=="bitmap" || substr($cmd,-4)=="text") $data.=chr(0); // extra byte needed by �controller of k8101. off-by-one bug? // Checksum $chksum = $this->checksum($this->packer($lsb, $msb, $this->cmds[$cmd]).$data); if ($data!='') $c=$this->packer($this->BOC,$lsb, $msb, $this->cmds[$cmd]).$data.$this->packer($chksum, $this->EOC); else $c=$this->packer($this->BOC,$lsb, $msb, $this->cmds[$cmd], $chksum, $this->EOC); return $c; } /** * Get LSB/MSB from payload * * @param string $payload * @return array (lsb,msb) */ private function get_data_size($payload) { // a command is: AA, lsb(size), msb(size), cmd, [data,] chk, 55 // thus it is 6 bytes + data (if any) $size=strlen($payload)+6; $lsb=$size & 0xFF; $msb=($size >> 8) & 0xff; return array($lsb,$msb); } /** * Get ByteCode from gd resource (128 x 64 px) * * @param resource $img * @return string Binary Chain */ private function build_bitmap($img) { if (imagesx($img)!=128 || imagesy($img)!=64) { echo "Pas la bonne taille !"; return false; } $s=""; for ($y=0;$y<64;$y+=8) { for ($x=0;$x<128;$x++) { $b=0; for ($i=7;$i>=0;$i--) { $b+=(1-imagecolorat($img,$x,$y+$i))*pow(2,$i); } $s.=$this->packer((int)$b); } } return $s; } /** * Get checksum * * @param resource $img * @return string Binary Chain */ private function checksum($d) { $t=0; $s=unpack("C*",$d); $t=array_sum($s); return $t % 256; } /** * String Packer * * @param mixed $input * @param mixed $input * @param mixed $input * @param ... * @return string Binary Chain */ private function packer() { foreach (func_get_args() as $input) { if (!is_string($input)) $output.=pack("C*",$input); else $output.=$input; } return $output; } /** * Debug function : Print binary chain in human form * * @param binary $data */ public function print_d($data) { $s=unpack("C*",$data); foreach($s AS $v) { echo $v.' '; } echo "\n"; } /** * Advanced Functions : Draw Rectangle * * @param int $x1 X value of Top-Left * @param int $y1 Y value of Top-Left * @param int $x2 X value of Bottom-Right * @param int $y2 Y value of Bottom-Right */ public function rectangle($x1,$y1,$x2,$y2) { $this->line($x1,$y1,$x2,$y1); $this->line($x2,$y1,$x2,$y2); $this->line($x2,$y2,$x1,$y2); $this->line($x1,$y2,$x1,$y1); } /** * Advanced Functions : Draw Poly-line * * @param int $x X value of origin. * @param int $y Y value of origin. * @param int $x1 X value of first line * @param int $y1 Y value of first line * @param int $x2 .... * @param int $y2 .... */ public function polyline() { $nbargs=count(func_get_args()); if ($nbargs%2!=0) return false; foreach (func_get_args() as $i=>$param) { if ($i%2==0) $x=$param; else { $y=$param; if ($i>=3) $this->line($couple[0],$couple[1],$x,$y); $couple=array($x,$y); } } } /** * Advanced Functions : Draw Circle or Disk from center * * @param int $x X value of center * @param int $y Y value of center * @param int $r rayon * @param bool $plein false=circle, true=disk */ public function circle($x,$y,$r,$plein=false) { $px=0; $py=$r; $m=5-4*$r; do { if ($plein==false) { $this->pixel($x+$px,$y+$py); $this->pixel($x+$py,$y+$px); $this->pixel($x-$px,$y+$py); $this->pixel($x-$py,$y+$px); $this->pixel($x+$px,$y-$py); $this->pixel($x+$py,$y-$px); $this->pixel($x-$px,$y-$py); $this->pixel($x-$py,$y-$px); } else { $this->line($x+$px,$y+$py,$x+$px,$y-$py); $this->line($x+$py,$y+$px,$x+$py,$y-$px); $this->line($x-$px,$y+$py,$x-$px,$y-$py); $this->line($x-$py,$y+$px,$x-$py,$y-$px); } if ($m>0) { $py--; $m-=8*$py; } $px++; $m+=$px*8+4; } while ($px<=$py); } /** * Advanced Functions : Draw Circle or Disk in square * * @param int $x X value of top-left * @param int $y Y value of top-left * @param int $size size of square in pixels * @param bool $plein false=circle, true=disk */ public function circleinsquare($x,$y,$size,$plein=false) { $x=($x+$size)/2; $y=($y+$size)/2; $r=$size/2; $this->circle($x,$y,$r,$plein); } /** * Advanced Functions : Sprite (foreground) * * @param resource $img * @param int $x X value of top-left * @param int $y Y value of top-left * @param int $mask mask Type of drawing (cover, transparent) */ public function sprite($img,$x=0,$y=0,$mask="cover") { $width=imagesx($img); $height=imagesy($img); if ($x>128 || $y>64) { echo "Hors limites"; return false; } $width=min(128,$x+$width)-$x; $height=min(64,$y+$height)-$y; $s=""; for ($iy=0;$iy<$height;$iy++) { for ($ix=0;$ix<$width;$ix++) { $color=1-imagecolorat($img,$ix,$iy); if ($color==1) $s.=$this->pixel($x+$ix,$y+$iy); elseif ($color==0 && $mask=="cover") $s.=$this->erasepixel($x+$ix,$y+$iy); } } } } ?>