3

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 simple 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?

phuclv
  • 37,963
  • 15
  • 156
  • 475

3 Answers3

3

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);
mti2935
  • 11,465
  • 3
  • 29
  • 33
  • Tried reading on line at a time with , but that unfortunately didn't change the data received. – Klaus Holst Jacobsen Nov 20 '13 at 12:29
  • Can you try connecting to the device using a terminal emulator (such as screen, see http://www.cyberciti.biz/faq/unix-linux-apple-osx-bsd-screen-set-baud-rate/), and executing the ATZ command, and seeing what the response is? I suspect that this may not be a perl problem, but rather the output from the device may be different than what you expect. Or, perhaps the wrong comm settings (baud rate, parity, stop bits, etc) are being used. This test will help to isolate the problem. – mti2935 Nov 20 '13 at 12:36
3

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]);
Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
1

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.

phuclv
  • 37,963
  • 15
  • 156
  • 475