13

Can anyone help me to send and receive SMS using AT commands in Python?

In case it matters, I'm using Fedora 8.

Which phone will be better with Linux (Nokia, Sony Ericson, Samsung,.....)? Will all phones support sending and receiving SMS using AT commands?

sth
  • 222,467
  • 53
  • 283
  • 367
RSK
  • 17,210
  • 13
  • 54
  • 74

4 Answers4

10

Here's some example code that should get you started (in Python 3000):

import time
import serial

recipient = "+1234567890"
message = "Hello, World!"

phone = serial.Serial("/dev/ttyACM0",  460800, timeout=5)
try:
    time.sleep(0.5)
    phone.write(b'ATZ\r')
    time.sleep(0.5)
    phone.write(b'AT+CMGF=1\r')
    time.sleep(0.5)
    phone.write(b'AT+CMGS="' + recipient.encode() + b'"\r')
    time.sleep(0.5)
    phone.write(message.encode() + b"\r")
    time.sleep(0.5)
    phone.write(bytes([26]))
    time.sleep(0.5)
finally:
    phone.close()

You need to do two additional things:

  • Encode the message in the appropriate format (mostly GSM 03.38, there's a handy translation table at unicode.org). If you really don't care about any characters other than ASCII, you can just check if every character is in string.printable.

  • Check the length of the message (I'm not sure if it's to do with the encoding, but it's sometimes 140 characters, sometimes 160).

You can use phone.readall() to check for errors, but it's best to make sure your message is OK before you send it off to the phone. Note also that the sleeps seem to be necessary.

Most phones will understand this. In order to get my old Nokia C5 to open up the serial connection, I had to select "PC Suite" from the menu that pops up when you insert the USB cable. This should work equally well over Bluetooth.

The code uses the PySerial package, available for python 2 and 3.

See also:

Community
  • 1
  • 1
Stefano Palazzo
  • 4,212
  • 2
  • 29
  • 40
  • 7
    No, no, no! Please do not process AT commands in this way. You **MUST** wait for the final result code (e.g. OK, ERROR, ...) before sending the next command. And specifically for AT+CMGS you **MUST** wait for the modem to send "\n\r> " before you should start sending MyMessage. See this answer for more details, http://stackoverflow.com/a/15591673/23118. – hlovdal Mar 25 '13 at 10:31
  • Sleeping is no substitute for reading and parsing the response. It's as useful as kicking dogs that stand in your way in order to get them to move. Yes it might actually work some times, but at some point you will be sorry for taking that approach. – hlovdal Mar 25 '13 at 10:32
8

to see send sms using At command this will help.

    import serial
    import time

    class TextMessage:
        def __init__(self, recipient="+2348065777685", message="TextMessage.content not set."):
            self.recipient = recipient
            self.content = message

        def setRecipient(self, number):
            self.recipient = number

        def setContent(self, message):
            self.content = message

        def connectPhone(self):
            self.ser = serial.Serial('COM70', 460800, timeout=5, xonxoff = False, rtscts = False, bytesize = serial.EIGHTBITS, parity = serial.PARITY_NONE, stopbits = serial.STOPBITS_ONE)
            time.sleep(1)

        def sendMessage(self):
            self.ser.write('ATZ\r')
            time.sleep(1)
            self.ser.write('AT+CMGF=1\r')
            time.sleep(1)
            self.ser.write('''AT+CMGS="''' + self.recipient + '''"\r''')
            time.sleep(1)
            self.ser.write(self.content + "\r")
            time.sleep(1)
            self.ser.write(chr(26))
            time.sleep(1)

        def disconnectPhone(self):
            self.ser.close()

    sms = TextMessage("+2348063796720","Mummy i sent this message from my computer")
    sms.connectPhone()
    sms.sendMessage()
    sms.disconnectPhone()
    print "message sent successfully"

To recieve sms using At command this should help

    import serial
    import time
    import sys


    class HuaweiModem(object):

        def __init__(self):
            self.open()

        def open(self):
            self.ser = serial.Serial('COM70', 406800, timeout=5)
            self.SendCommand('ATZ\r')
            self.SendCommand('AT+CMGF=1\r')


        def SendCommand(self,command, getline=True):
            self.ser.write(command)
            data = ''
            if getline:
                data=self.ReadLine()
            return data 

        def ReadLine(self):
            data = self.ser.readline()
            print data
            return data 



        def GetAllSMS(self):
            self.ser.flushInput()
            self.ser.flushOutput()



            command = 'AT+CMGL="REC UNREAD"\r\n'#gets incoming sms that has not been read
            print self.SendCommand(command,getline=True)
            data = self.ser.readall()
            print data


    h = HuaweiModem()
    h.GetAllSMS()
Transformer
  • 3,642
  • 1
  • 22
  • 33
3

Talking to the phone is easy. You just need to open the appropriate /dev/ttyACM* device and talk to it. Which phone is trickier. Any phone that supports "tethering" and the full AT command set for SMS messages should be fine.

Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
2

I would suggest replace the time.sleep with condition loop waiting for the response from the modem "OK" before continue next state.

Vivz
  • 6,625
  • 2
  • 17
  • 33
Kelvin Koh
  • 21
  • 1
  • Am connecting my android phone with the USB cable and am not finding it under "ports" rather it is under "portable devices", because of this am not able to test the SMS feature. How can I enable COM port? – Ds Arjun Mar 30 '18 at 10:13