pySerial modem result codes
Question: I'm using pySerial and python 2.7 on a Debian box. I'm writing python code to
control a USRobotics USB USR5637 modem. I want to check the responses from the
modem for issues/errors but I'm getting anomalous results from my code. I've
written some basic code for testing. I do have the phone line disconnected so
I can see a result code of "NO CARRIER." If anyone has access to pySerial and
a modem I would appreciate any help that can be provided.

I created the following code for testing:

    
    
    import serial
    ser = serial.Serial('/dev/ttyACM0', 9600, timeout=5)
    ser.write("ATE0\r")  # Attention - Echo disable
    response =  ser.read(4)
    print "ATE0 %s" % response
    ser.write("ATX0\r")  # Attention - Echo disable
    response2 =  ser.read(8)
    print "ATX0 %s" % response2
    ser.write("ATDT411\r")  # Attention - Dail - Tone - 411
    response3 =  ser.read(32)
    print "ATDT %s" % response3
    ser.write("ATH\r")  # Attention - Hang up line
    response4 =  ser.read(16)
    print "ATH %s" % response4
    ser.write("ATZ\r")  # Reset
    response5 =  ser.read(16)
    print "ATZ %s" % response5
    print "================================================="
    print "%s %s %s %s %s" % (response, response2, response3, response4, response5)
    ser.close()
    

The response I get is:

    
    
    ATE0 
    OK
    ATX0 
    
    OK
    
    ATDT 
    ATH 
    NO CARRIER
    
    ATZ 
    OK
    
    =================================================
    
    OK 
    
    OK
    
    NO CARRIER
    
    OK
    

My questions are:

  1. What is the number in ser.read(4) or ser.read(8). Is it a timeout?
  2. I don't seem to get the "NO CARRIER" until after the ATH section of the code. I would expect to get it directly after the ATDT section.
  3. Why do I end up with only four results?
  4. Why the anomalous spacing in the printed results?

Any help would be greatly appreciated. Thanks.


Answer: `ser.read(4)` means to read 4 bytes from the serial port. You have configured
a 5 second timeout with your constructor call:

    
    
    serial.Serial('/dev/ttyACM0', 9600, timeout=5)
    

so `ser.read(4)` may return less than 4 characters. Use `timeout=None` for a
blocking read in which case it won't return until exactly 4 characters have
been received.

You are getting the weird spacing because each response sent by the modem ends
in a CR character (and it may be be a CR/LF pair.)

You might find it easier to interact with the modem using this `getline()`
function:

    
    
    def getline(ser):
      buf = ""
      while True:
        ch = ser.read(1)
        if ch == '\r':    # or perhaps '\n'
          break
        buf += ch
      return buf
    

As for #2, I believe you are getting "NO CARRIER" due to the ATH command you
sent.

See the "Making a call" section in this MS Support Note
[(link)](http://support.microsoft.com/kb/164659)

According to the note sending a hangup command will result in a NO CARRIER
response. The modem is probably still trying to establish a connection when
you send the ATH.

