in reply to Perl/Tk vs Win32::SerialPort

Thank you, eventually i managed to set up the 'serial' thread and i can share its '@values' with Tk but the problem is that it's still in an infinite while loop.

$mw->repeat(1000,sub{ print "@values"."\n"; });

But is it possible to run a thread when i want it to run not just in a while(1) loop all the time?

I tried to pass another variable to my serial thread which determines the running state

share @values; share $opened_port;

Where $opened_port is set when i click on the Open button

sub opening_port { require Win32::SerialPort; $serial=Win32::SerialPort->new("COM6"); $serial->baudrate(9600) || die "Bad baudrate"; $serial->parity('none') || die "Bad parity"; $serial->databits(8) || die "Bad databits"; $serial->stopbits(1) || die "Bad stopbits"; #$serial->buffers(4096,4096) || die "Buffer error"; $serial->handshake("none") || die "Bad handshake method"; $serial->write_settings; while(1) { print $opened_port; if($opened_port) { my @array; my $string; my $i=0; do { $string=$serial->read(1); #Beolvass egy karakter +et a sorosportról if((ord($string) >= 0x09 && ord($string) <=0x7A) || $string eq '\t' + || $string eq '\n') #megvizsgálja, hogy a beolvasott karakter megfel +el-e az ASCII kritériumoknak { $array[$i]=$string; #elmenti a tömbbe i.-ik helyére az adott karakt +ert $i++; #növeli az index értékét } }while($string ne "\n" ); #addig fut a program amíg nem \n a beolva +sott karakter $i=0; $string = join('' , @array ) ; #ezután egy skalárba összef&#369;z +i a tömb elemeit, egymás után - nincs szeparátor chomp($string); # leszedi a \r és \n karaktereket a string végér&#337; +l @values = split('\t',$string); #majd felbontja a skalárt a tabul +árotok mentén # az 1-es index tartalmazza a a h&#337;mérsékleti adatokat, a 3-as ind +ex az id&#337;t } } }

Of course i get an error which says that $opened_port is uninitialized, so i guess that shareing variable is a child to parent thing and it won't work in the other way. But what could be the proper way to read the serial port on button press and close it on another button event?

Replies are listed 'Best First'.
Re^2: Perl/Tk vs Win32::SerialPort
by Shaoboy (Initiate) on Dec 10, 2013 at 17:50 UTC

    Okay I was a noob and shared a wrong variable with the serial thread...Now everything works like a charm!! Thank you Anonymous Monk and zentara for helping me!

      One more question :) Is there a way to share my $serial object with the serialport thread?

      I want to share this:

      $serial=(Win32::SerialPort->new($ports[$portname])

      So my serial worker thread could read from this. The only need for that is cause i select COMx ports from a listbox and i don't know how to tell the thread to read from the specific port

      my $serial :shared = shared_clone({}); bless($serial, 'Serial');

      When i share my serial object i get an error at $serial->read(1); line saying "Thread 1 terminated abnormally: Can't call method "read" on an undefined value"

        Put it on the queue? As data to create a new serialport object, not the serialport object itself?

        So setup

        sub Main { my $qin = Thread::Queue->new(); my $qout = Thread::Queue->new(); my $guithread = threads->create( \&tkgui, $qin, $qout ); ## don't wait for background downloading service / mechtitles threads->create( \&mechtitles, $qin, $qout ); $guithread->join; ## wait for gui to finish return; } ## end sub Main

        Then from tkgui somewhere (a button), you tell "mechtitles" to create a newserialport with a message

        my $message = { newserialport => [qw/ COM6 baudrate 11 ... /] } ; $qin->push( $message );

        Then back in mechtitles, you have a dispatch table, and you use the message from $qin to invoke a callback to create a new serialport (and replace existing serialport)

        sub mechtitles { my( $qin, $qout ) = @_; threads->detach(); ## can't join me :) my %dispatch = ( newserialport => \&newserialport, pollserialport => \&pollserialport, ); my %stash; ## STATE require Time::HiRes; while( 1 ) { #~ if( defined( my $url = $qin->popnow ) ) { if( defined( my $action = $qin->pop ) ) { my( $callbackname, $callbackargs ) = %$action; if( my $callback = $dispatch{$callbackname} ){ $callback->(\%stash, $qout, @$callbackargs ); } } Time::HiRes::usleep( 33 * 1000 ); ## microseconds versus milis +econds? grrdoh } } ## end sub mechtitles sub newserialport { my( $stash, $qout, @args ) = @_; my $serialport = Win32::SerialPort->new( ... @args ... ); ... ### THERE IS A NEW STASH IN TOWN $stash->{serialport} = $serialport; } ## end sub newserialport sub pollserialport { my( $stash, $qout, @args ) = @_; ... my $data = $stash->{serialport}->read(1); ## %stash!!!! ... $qout->push( { frobnicatetextdisplay => [ ... $data ... ] ); }