Search code examples
pythonpyserialmodem

pySerial modem result codes


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.


Solution

  • 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)

    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.