#!/usr/bin/perl -w print "initializing...\n"; require POSIX; use strict; use Fcntl; use Term::ReadKey; use Term::Cap; my @ledpat; # General terminal line I/O my $termios = new POSIX::Termios; $termios->getattr; # The baud at which your terminal is set. my $speed=$termios->getospeed; # Extract the entry of the terminal type my $term = Term::Cap->Tgetent({OSPEED=>$speed}); defineLEDPats(); my $exec = 'stdinlpt'; open(PPOUT, "|$exec") or die "cannot open pipe to $exec:$!"; # make the pipe unbuffered select(PPOUT);$| = 1; select \*STDOUT; # constants my $delay = 0.000001; # initial values. nothing here should be changed my $byout = 0; # output byte my $cstep = 0; # stepper motor counter my $lcstep = 0; # stepper motor counter difference check my $DLstep = 0; # led counter my $ledout = 0; # led output var my %stat; $stat{'bspeed'} = 5; # disco ball speed $stat{'ledrandom'} = 1; # randomly change the led blink pattern/speed $stat{'stopped'} = 0; $stat{'direction'} = 1; $stat{'ledrmax'} = 75; $stat{'leds'} = 0; # led manual status byte $stat{'lspeed'} = 5; $stat{'blinktype'} = 0; $stat{'blinkdir'} = 1; # led blink direction $stat{'blinkauto'} = 1; # automaticly change blink type $stat{'manualstep'}= -1; # allow user to step with "6, 7, 8, 9" keys ReadMode 4; DrawStatus(); my( $scount, $lcount) = (0,0); my $in; my $flash; do{ $in = ReadKey -1; handleKeys($in); # don't go toooo fast... # select(undef, undef, undef, $delay); #if($ledrandom){$interval = log(rand(1000)) if int rand 500 == 1} $scount++; $lcount++; if($stat{'bspeed'} <= $scount){ $scount = 0; $cstep = step($cstep, $stat{'direction'}) unless $stat{'stopped'}; } $ledout = $stat{'leds'} unless $stat{'ledrandom'}; $cstep = $stat{'manualstep'} if ($stat{'stopped'} && $stat{'manualstep'} != -1); # if($stat{'ledrandom'}){ $stat{'leds'} = int(rand(15)) if int(rand($stat{'ledrmax'})) == 0} if($stat{'ledrandom'}){ if($lcount >= $stat{'lspeed'}){ $lcount = 0; $ledout = DanceLED($stat{'blinktype'}, $stat{'blinkdir'}); } if($stat{'blinkauto'}){ $stat{'blinktype'} = int(rand(scalar @ledpat)) if int(rand($stat{'ledrmax'})) == 0; $stat{'blinkdir'} = (int(rand(2)) * 2 - 1) if int(rand($stat{'ledrmax'})) == 0; } } if($flash){ $ledout = 15; $flash = 0 } # construct byte $byout = 0; $byout |= (2 ** $cstep) if $cstep != $lcstep; $ledout = 0 unless defined $ledout; $byout |= $ledout<<4; print PPOUT "$byout\n"; # don't go toooo fast... select(undef, undef, undef, 0.0001); print PPOUT "0\n"; $lcstep = $cstep; }until(defined $in && $in eq 'q'); # reset things print PPOUT "0\n"; ReadMode 0; sub step{ # step, direction my $steps = 4; my ($step, $dir) = @_; if ($dir >= 1){ $step++; $step = 0 if $step >= $steps; }elsif($dir <= -1){ $step = $steps if $step <= 0; $step--; } # else leave it alone, since it's 0 return $step; } sub DrawStatus{ # status hash my %status = %_; # clear $term->Tputs('cl', 1, \*STDOUT); print "Direction:\t\t$stat{'direction'}\n"; print "Ball speed:\t\t$stat{'bspeed'}\n"; print "Stopped:\t\t$stat{'stopped'}\n"; print "LEDs:\t\t\t$stat{'leds'}\n"; print "LED random:\t\t$stat{'ledrandom'}\n"; print "LED blink change:\t$stat{'ledrmax'}\n"; print "LED blink speed:\t$stat{'lspeed'}\n"; print "LED blink type:\t\t$stat{'blinktype'}\n"; print "LED blink dir:\t\t$stat{'blinkdir'}\n"; print "LED blink auto:\t\t$stat{'blinkauto'}\n"; show_keys(); } sub DanceLED{ # type, direction my ($type, $dir) = @_; my @steps; $DLstep = 0 unless defined $DLstep; return 1 if $type >= scalar @ledpat; @steps = split(/\s/, $ledpat[$type]); if($dir >= 1){ $DLstep++; }elsif($dir <= -1){ $DLstep--; } if($DLstep >= scalar @steps){ $DLstep = 0; }elsif($DLstep < 0){ $DLstep = (scalar @steps - 1) if $DLstep < 0; } print "$type:$DLstep\n" unless defined $steps[$DLstep]; return $steps[$DLstep]; } sub defineLEDPats{ $ledpat[0] = "1 2 4 8"; $ledpat[1] = "1 0 1 0 2 0 2 0 4 0 4 0 8 0 8 0"; $ledpat[2] = "1 0 1 0 1 0 1 0 1 0 2 0 2 0 2 0 2 0 2 0"; $ledpat[3] = "1 1 1 1 1 1 1 1 2 2 2 2 2 2 2"; $ledpat[4] = "1 4 1 8 1 2 8 4"; } sub handleKeys{ # key my($in) = @_; if(defined $in){ if($in eq 'f') { $flash = 1 } if($in eq 'r') { $stat{'ledrandom'} = !$stat{'ledrandom'} } if($in eq 'd') { $stat{'direction'} = $stat{'direction'} - ($stat{'direction'} * 2) } if($in eq 's') { $stat{'stopped'} = !$stat{'stopped'} } if($in eq ',') { $stat{'bspeed'}--; $stat{'bspeed'} = 0 if $stat{'bspeed'} < 0 } if($in eq '.') { $stat{'bspeed'}++; $stat{'bspeed'} = 80 if $stat{'bspeed'} > 80 } if($in eq '[') { $stat{'lspeed'}--; $stat{'lspeed'} = 0 if $stat{'lspeed'} < 0 } if($in eq ']') { $stat{'lspeed'}++; $stat{'lspeed'} = 80 if $stat{'lspeed'} > 80 } if($in eq '/') { if($stat{'ledrmax'}> 20){$stat{'ledrmax'} -= 5} else{$stat{'ledrmax'}--} $stat{'ledrmax'} = 0 if $stat{'ledrmax'} < 0; } if($in eq '\''){if($stat{'ledrmax'}>= 20){$stat{'ledrmax'} += 5} else{$stat{'ledrmax'}++} $stat{'ledrmax'} = 1000 if $stat{'ledrmax'} > 1000; } if($in eq '0') { $stat{'leds'} = 0 } if($in eq '1') { $stat{'leds'} = $stat{'leds'} ^ 1 } if($in eq '2') { $stat{'leds'} = $stat{'leds'} ^ 2 } if($in eq '3') { $stat{'leds'} = $stat{'leds'} ^ 4 } if($in eq '4') { $stat{'leds'} = $stat{'leds'} ^ 8 } $stat{'manualstep'} = "-1"; if($in eq '6') { $stat{'manualstep'} = 0 } if($in eq '7') { $stat{'manualstep'} = 1 } if($in eq '8') { $stat{'manualstep'} = 2 } if($in eq '9') { $stat{'manualstep'} = 3 } if($in eq 'z') { $stat{'blinktype'} = 0 } if($in eq 'x') { $stat{'blinktype'} = 1 } if($in eq 'c') { $stat{'blinktype'} = 2 } if($in eq 'v') { $stat{'blinktype'} = 3 } if($in eq 'b') { $stat{'blinktype'} = 4 } if($in eq 'n') { $stat{'blinktype'} = 5 } if($in eq 'm') { $stat{'blinktype'} = 6 } if($in eq 't') { $stat{'blinkauto'} = ! $stat{'blinkauto'} } DrawStatus(%stat); } } sub show_keys{ print <