Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

(jcwren) Re: Kludging the serial port

by jcwren (Prior)
on Oct 08, 2001 at 19:43 UTC ( #117479=note: print w/ replies, xml ) Need Help??


in reply to Kludging the serial port

RD cannot be controlled in software. It is a receive only input into the serial shift register. RD does not normally have a range of only 0 to -5V, unless it is disfunctional. To be RS232C compliant, pins must be no greater than +/- 30V, and no less than +/- 3V. Many level converters will treat 0V as if it were a negative voltage, but that is not RS232C compliant, nor is it *any* guarantee that it will work from system to system.

Real RS232 drivers are tolerant of being shorted together indefinitely, and the recievers being driven at +30V or -30V indefinitely. Most decent ones have 15KV human-body-model ESD protection. Proper RS232 is capable of sourcing/sinking up to 10 milliamps per pin, so shorting a driver at +5V to a driver at -5V won't damage the system (nor will it do anything useful). Inputs typically have pullups or pulldowns to the voltage rails to hold them in their idle condition. This prevents an unplugged cable from looking like DTR, etc is still asserted. This is most likely why you see a negative voltage on the input.

I'd like to see the schematic for this interface, because what you describe makes no sense (not what you typed, but what the product is expecting).

--Chris

e-mail jcwren


Comment on (jcwren) Re: Kludging the serial port
Re: Re: Kludging the serial port
by Aighearach on Oct 08, 2001 at 20:36 UTC
    Thank you, I am less worried about my sollution's safety now. The interface is (sortof) described at CashCode's website. PDF only. There are 4 manuals, each manages to describe part of the protocol. Some of them claim that the device supports 600 baud, others that it senses 1200 or 9600. My unit only works at 600. I don't have any specs on the "serial" to RS232 converter, as that would require spending an extra $500 on a "developers kit" from Happ Controls. I used the timings described in CashCode's MAN-CCS.pdf. Basically, they have a line labelled SEND, which they want me to play with when they throw their INTERUPT line. The interupt is tied to one of the handshake lines, but is irrelevant to me, as if SEND is in the correct state for the bill validator to be active and send a message, then I can just read the incoming data, and know by that when to respond, even if I turn off handshaking in my software. I used an RS232 breakout box to toggle lines until I found the SEND. I might not have found it correctly; I found I could also toggle one of the handshake lines from the validator side, and it would partially respond, but only with RD could I get it to give me the full documented behavior. And I couldn't think of another way to toggle it in software than tying it to RTS. (the other potential source, DTR, is the ACCEPT ENABLE line from the docs)

    I agree it makes no sense, but with the following code the whole thing works. (without the hardware hack, you put a bill in and it just stays in ESCROW position)

    use strict; require 5.006; use warnings; use Device::SerialPort; use Time::HiRes qw/ usleep /; my $port = shift @ARGV; $port ||= '/dev/validator' if -e '/dev/validator'; $port ||= '/dev/ttyS1' if -e '/dev/ttyS1'; $port ||= '/dev/ttyS0' if -e '/dev/ttyS0'; # validator commands my ( %v_bills, %v_status ); $v_status{pack('H*','89')} = 'VEND'; $v_status{pack('H*','8a')} = 'RETURNED'; $v_status{pack('H*','8b')} = 'REJECT'; $v_status{pack('H*','8c')} = 'FAILURE'; $v_status{pack('H*','8d')} = 'STACKER FULL'; $v_status{pack('H*','8e')} = 'LRC REMOVED'; $v_status{pack('H*','8f')} = 'LRC ATTACHED'; $v_bills{pack('H*','81')} = 1; # $1 inserted $v_bills{pack('H*','82')} = 2; $v_bills{pack('H*','83')} = 5; $v_bills{pack('H*','84')} = 10; $v_bills{pack('H*','85')} = 20; # what about model 1100, when it gets a $50 or $100? Not in the chart +:( $PortObj->baudrate( $baud ); $PortObj->parity("none"); $PortObj->databits(8); $PortObj->stopbits(1); $PortObj->datatype('raw'); $PortObj->write_settings(); print STDERR "$0 ($$) started at ",scalar localtime(), "\n"; # always send an ack to start, in case there is an event in the valida +tor's queue, or a half processed event ack(); my $last = time; while (1) { my ($count, $data) = $PortObj->read( 1024 ); if ( $count and defined $data ) { foreach my $byte ( split //, $data ) { if ( exists $v_bills{$byte} ) { printf "saw a \$%s dollar bill\n", $v_bills{$byte}; if ( $enabled ) { accept_bill(); } else { reject_bill(); } } elsif ( exists $v_status{$byte} ) { printf "saw status event %s\n", $v_status{$byte}; ack(); } else { my $hex = unpack "H*", $byte; my $bin = unpack( "B*", $byte ); $bin =~ s/(.{8})/$1 /g; # seperate the bytes please printf "UNKNOWN: hex: %s bin: %s\n", $hex, $bin; } } } else { pause( 50_000 ); # because the $PortObj->read is nonblocking, we d +on't want to loop too tight. so pause 50ms if a read fails. } } sub ack { $PortObj->rts_active( 0 ); pause( $rts_timing ); $PortObj->rts_active( 1 ); } sub accept_bill { ack(); } sub reject_bill { $PortObj->rts_active( 0 ); $PortObj->dtr_active( 0 ); pause( $rts_timing ); ack(); } sub pause { my $time = shift || 500_000; # micro seconds usleep( $time ); return 1; }
    Of course, the useful version does more than just print to the screen that money was inserted ;)
    --
    Snazzy tagline here

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://117479]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (8)
As of 2014-12-27 16:17 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (177 votes), past polls