Question

I have a embedded linux box with perl 5.10 and a GSM modem attached. I have written a simple perl script to read/write AT commands through the modems device file (/dev/ttyACM0).

If i write a simle command like "ATZ\r" to the modem and wait for a response I receive very odd data like "\n\n\nATZ\n\n0\n\nOK\n\n\n\n\nATZ\n\n\n\n..." and the data keeps coming in. It almost seems like the response is garbled up with other data.

I would expect something like "ATZ\nOK\n" (if echo is enabled).

If i send the "ATZ" command manually with e.g. minicom everything works as expected.

This leads me to think it might be some kind of perl buffering issue, but that's only guessing.

I open the device in perl like this (I do not have Device::Serialport on my embedded linux perl installation):



    open(FH, "+<", "/dev/ttyACM0") or die "Failed to open com port $comport";

and read the response one byte at a time with:



    while(1) {
        my $response;
        read(FH, $response, 1);
        printf("hex response '0x%02X'\n", ord $response);
    }

Am I missing some initialization or something else to get this right?

Regards Klaus

Was it helpful?

Solution 3

Thanks for your answer. Although not the explicit answer to my question it certainly brought me on the right track.

As noted by mti2935 this was indeed not a perl problem, but a mere tty configuration problem.

Using the "stty" command with the following parameters set my serial port in the "expected" mode:

  • -opost: Disable all output postprocessing
  • -crnl: Do not translate CR to NL
  • -onlcr: Do not translate NL to CR NL
  • -echo: Do not echo input (having this echo enabled and echo on the modem itself gave me double echoes resulting in odd behaviour in my script)

It is also possible to use the combination setting "raw" to set all these parameters the correct way.

-

OTHER TIPS

I don't think you need the while loop. This code should send the ATZ command, wait for the response, then print the response:

 open(FH, "+>", "/dev/ttyACM0") or die "Failed to open com port $comport";
 print FH ("ATZ\n");
 $R = <FH>;
 print $R;
 close(FH);

It may be something to do with truncation. Try changing "+>" into "+<".

Or it may be something to do with buffering, try unbuffering output after your open():

select((select(FH), $| = 1)[0]);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top