in reply to Re: Win32::SerialPort, buffer overflow
in thread Win32::SerialPort, buffer overflow

It definitely looks like there's a discrepancy on output, but it doesn't appear you've shown how you call Serial_TrxRcv() or with what data. There's no way to know what the problem is without that information.

Replies are listed 'Best First'.
Re^3: Win32::SerialPort, buffer overflow
by jmClifford (Beadle) on Nov 12, 2024 at 07:01 UTC

    Hi. Thank you for your replys. I think I can be now more specific about my issue of the buffer overflow error. The routine I call for COM5 serial handshaking is Serial_TrxRcv( $commandForTransmission ). In my main routine I have a sub doing this which is below;

    sub ProcessPIDs { # print "Inside ProcessPIDs \n"; # Process the input arguments my ( $nickname, $ref_nicknametocommand ) = @_; my %InSubNickNameToCommand = %{$ref_nicknametocommand}; # De-ref +erence the reference to a hash my $ccmd; $ccmd = $InSubNickNameToCommand{ $nickname }; # ne +ed further ERROR checking here !!!!!! my $newcmd = '0101'; print "\$ccmd; $ccmd ".length($ccmd). " \$newcmd; $newcmd ".le +ngth($newcmd)."\n"; # my $newcmd = $ccmd; # not work my $response = Serial_TrxRcv($newcmd); my $result; ...etc...

    If I use Serial_TrxRcv in the manner as above, I do not have error. If I call the same but with the parameter $ccmd then I get the error. This $ccmd is initialised from a hash structure. The hash is to provide quick mapping from a nickname to the wanted command string. I provide a comparison between these 2 parameters with the just above programs and the console output below;

    TPA $ccmd; 0101 4 $newcmd; 0101 4 cmd; 0101 x x MonStatus Cmd; 0101 Length; 21 Response; 41 01 00 07 61 00 __>. $nickname MonStatus; 00 07 61 00 TPB

    The non-faulty and faulty parameters both appear the same and have the same lengths. So, do people have any further ideas about my problem ??

    Thanks. Regards JC.....

      Serial devices usually have a very small buffer, like 16 bytes or something. Could the problem be that the device isn't consuming data as fast as you write it? Is that module supposed to block your script until there is room in the buffer, or does it just throw that exception when the buffer is full?

      You might try a quick experiment to see what other cases can give you the same error. What if you write a 17-byte string once? What if you write two 9-byte strings back-to-back without waiting? What if you write 5000 bytes?

      There are also flow-control lines on the serial connection, so the device can indicate when it is ready to read or not. Do you have a breakout-box showing you those signals on LEDs? What happens if you write data on the line when the device isn't ClearToSend?

      Ah, and I just learned something. (from that StackOverflow post)

      RTS/CTS wasn't supposed to ever be a flow control mechanism, originally; it was for half-duplex modems to coordinate who was sending and who was receiving. RTS and CTS got misused for flow control so often that it became standard.
        There are also flow-control lines on the serial connection, so the device can indicate when it is ready to read or not.

        Not all RS232 devices implement hardware flow control. Some don't implement anything but the bare minimum (GND, RxD, TxD).

        Just last week, I've wired a new, major brand UPS to a small server. That UPS lacks USB for some unknown reason, but supports RS232. Of course, it does not use the usual PC pinout. That would be far too easy. And the official adapter cable just shorts the two main handshake pairs on the PC side (RTS to CTS and DCD to DTR). Only RxD, TxD and GND are connected to the UPS.

        That server, by the way, has one RS232 with a PC pinout on a DB9 connector, and a second serial port on an internal pinheader with CMOS 3.3V levels lacking the handshake lines. They are present at the UART, but not connected to the pinheader.

        From my experiance with modern ARM-based microcontrollers, RS232 works fine in home and office environments, even without handshake lines, and even at relatively high baud rates (115200 bit/s). The old 8-bit AVRs (and probably also the 8-bit PICs) can be problematic without handshake lines, they just can't get the data out of the UART receive buffer fast enough. If you connect a USB UART (e.g. FTDI FT232) close to the microcontroller board instead of using a long RS232 cable, ARM-based microcontrollers can even work at much higher speeds without handshake, up to the limits of the USB UART.

        In an industrial environment, I would use something with differential signals instead (RS485, RS422, CAN), or a current loop (e.g. 4-20 mA), because those systems are almost immune to noise.

        Do you have a breakout-box showing you those signals on LEDs?

        At 38400 Bit/s, a data byte encodes to at least 10 bits (start, 8x data, stop), so you end up with up to 3840 Bytes/s. That's almost 4 bytes per ms, or 4 kHz. You won't be able to see an LED flashing at that speed, if one of the two devices sets or clears a handshake signal for a few bytes. That's just a limit of your wetware. You can hear a 4 kHz signal, but visually, you are limited to about 25 Hz.

        At 300 Bit/s = 30 Bytes/s, you could clearly see the LEDs flickering. At 38400 Bit/s or more, you can just hope that the handshake lines change their level very often, so they effectively drive the LEDs with a PWM signal and make them change their apparant brightness.

        If you want to see short signal changes, with a duty cycle close to 0 % or close to 100 %, you need an oscilloscope. At RS232 speeds, any cheap one with at least 2 Megasamples per second / 1 MHz bandwith will do. (Note that some people sell cheap junk kits that can't even measure outside the audio range.)

        Alexander

        --
        Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
      when debugging, I prefer to see my values in quotes (or other markers), and possible control characters (or "extended" characters) "translated". Therefore I'd suggest instead of simply printing the values, perusing Data::Dumper (core module), or Data::Dump or somesuch.
      Although it probably isn't a case of homoglyphs, perhaps the different representation by Data::Dumper might help you spot something.