=begin comment Matrix.pm Brian Rudy (brudyNO@SPAMpraecogito.com) Handles communication interface with the Setsnest 20x20 AV matrix switch. v0.01 12/19/2002 First working version Use these mh.ini parameters to enable this code: Matrix_serial_port = /dev/ttyS3 Matrix_baudrate = 2400 in code use: ################################### #Category=Video $matrix = new Matrix; my @array = (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,1); $v_set_matrix=new Voice_Cmd('Set matrix'); if ($state = said $v_set_matrix) { $matrix->setmatrix('binary',@array); } $v_scan_video=new Voice_Cmd('Scan video'); if ($state = said $v_scan_video) { $matrix->scanvid('binary',@array); } ####################################################3 =cut use strict; package Matrix; @Matrix::ISA = ('Serial_Item'); # pre-filling this hash may not be required... my %vidstat = (1 => 0, 2 => 0, 3 => 0, 4 => 0, 5 => 0, 6 => 0, 7 => 0, 8 => 0, 9 => 0, 10 => 0, 11 => 0, 12 => 0, 13 => 0, 14 => 0, 15 => 0, 16 => 0, 17 => 0, 18 => 0, 19 => 0, 20 => 0); # Look Up Table for input channels my @channelLUT = (0,120,121,122,123, 116,117,118,119, 108,109,110,111, 92,93,94,95, 60,61,62,63); my $serdata; my $scanning = 0; my $scanindex; sub serial_startup { &main::serial_port_create('Matrix', $main::config_parms{Matrix_serial_port}, $main::config_parms{Matrix_baudrate}, 'none', 'raw'); &::MainLoop_pre_add_hook( \&Matrix::check_for_data, 1 ); &::print_log("Matrix Serial Port Initialized"); } sub check_for_data { my ($self) = @_; &main::check_for_generic_serial_data('Matrix'); $serdata = $main::Serial_Ports{Matrix}{data}; $main::Serial_Ports{Matrix}{data} = ''; return unless $serdata; process_response($serdata); } sub process_response { my $data = shift; if ($scanning) { &scannext($data); } elsif ($data =~ m/Matrix ready:/) { # Just the prompt, ignore it. return; } else { print "Got \'$data\' from the Matrix.\n"; } } #sub set { # my ($self, $state) = @_; # return if &main::check_for_tied_filters($self, $state); # return &Generic_Item::set($self, $state); #} sub update_matrix { my ($self, $mode, @mtable) = @_; my $i; if ($mode eq "binary") { # send 'B' $main::Serial_Ports{Matrix}{object}->write('B'); select(undef, undef, undef, 0.010); for ($i = 21; $i > 0; $i--) { $main::Serial_Ports{Matrix}{object}->write(sprintf("%c", $channelLUT[$mtable[$i]])); select(undef, undef, undef, 0.040); #print "Sending=" . sprintf("%c", $channelLUT[$mtable[$i]]) . ".\n"; } #select(undef, undef, undef, 0.100); } elsif ($mode eq "character") { # send 'C' $main::Serial_Ports{Matrix}{object}->write('C'); select(undef, undef, undef, 0.010); for ($i = 21; $i >= 0; $i--) { $main::Serial_Ports{Matrix}{object}->write($channelLUT[$mtable[$i]] . "\n"); select(undef, undef, undef, 0.040); #print "Sending=" . $channelLUT[$mtable[$i]] . ".\n"; } } else { print "Error! Bogus argument to update_matrix!\n"; print "\$self=$self, \$mode=$mode.\n"; } } # Scan all inputs and update %vidstat hash # This function will take a while to execute sub scanvid { my ($self, $mode, @mtable) = @_; my $j; $scanning = 1; $scanindex = 1; &::print_log("Scanning video inputs..."); for $j (1 .. 20) { if ($j == 1) { $mtable[21] = $j; update_matrix($self,$mode,@mtable); &::run_after_delay(1, sub { $main::Serial_Ports{Matrix}{object}->write('V'); $scanindex = $j; }); } else { &::run_after_delay($j*3, sub { $mtable[21] = $j; &update_matrix($self,$mode,@mtable); }); &::run_after_delay(($j*3)+1, sub { $main::Serial_Ports{Matrix}{object}->write('V'); $scanindex = $j; }); if ($j == 20) { &::run_after_delay(($j*3)+3, sub { $scanning = 0; &Generic_Item::set($self,'scanned'); &::print_log("Done scanning."); }); } } } } sub getvidhash { my ($self) = @_; return %vidstat; } sub scannext { my ($data) = @_; # Do something with the reply if ($data =~ m/1/) { $vidstat{$scanindex} = 1; print "Video detected on channel $scanindex.\n"; } elsif ($data =~ m/0/) { $vidstat{$scanindex} = 0; print "No video on channel $scanindex.\n"; } elsif ($data =~ m/Matrix ready:/) { # Just the prompt, ignore it. return; } else { &::print_log("No match found for \'$data\'"); } } 1;