Thursday 21 March 2013

PySerial, Python, Raspberry Pi and issuing AT commands to a Mobile Dongle

For anyone who saw my last post, they will know that I've been working on a number of projects - the current one is to do with the RP and texting.

I couldn't find any modules out there that I liked to talk to the dongle, so I decided to make my own functions to do the job. It's not perfect, but it's doing the job for me and will be expanded on over time.

See below:

You'll need PySerial for this to work, and also create a serial object called 'dongle'
example: dongle = serial.Serial(port="/dev/ttyUSB0",baudrate=115200,timeout=2,rtscts=0,xonxoff=0)

# write a command to the dongle, check the line out buffer for the correct response and return it
# cmd is the command we issue
# success is what we're looking for in the buffer if it was successful
# fail is what we're looking for if it fails
# AT is whether we put the "AT+" in front of the command
# if we pass "pass" as the cmd, then we don't write anything - useful if we're looking for 2 outputs from a command (such as +CMGS and OK when we send a message)

def WriteBuffer(cmd, Success, Fail, AT):
if (cmd == "pass"):
pass
elif (AT == "Y"):
dongle.write('AT'+cmd+'\r')
elif (AT == "N"):
dongle.write(cmd+'\r')
Found = "False"
BufferCounter = 0
while (Found == "False"):
Buffer = dongle.readline()
if Buffer.find(Fail) > -1:
return Fail
if Buffer.find(Success) > -1:
if (Success == "+CMGW:"):
SuccessValue = Buffer.split(": ")
Success = SuccessValue[1]
if (Success == "+CMGR:"):
Next = dongle.readline()
SuccessValue = str(Buffer)+","+str(Next)
Success = SuccessValue
Next = dongle.readline()
Next = dongle.readline()
if (Success == "+CSQ:"):
SuccessValue = Buffer.split(": ")
Success = SuccessValue[1]
Next = dongle.readline()
Next = dongle.readline()
if (Success == "+CBC:"):
SuccessValue = Buffer.split(": ")
Success = SuccessValue[1]
Next = dongle.readline()
Next = dongle.readline()
if (Success == "+CPAS:"):
SuccessValue = Buffer.split(": ")
Success = SuccessValue[1]
Next = dongle.readline()
Next = dongle.readline()
return Success
if BufferCounter > 5:
return "timeout"
BufferCounter = BufferCounter + 1

Function to send a text below - you can add captures for errors that are thrown back:

# sendnumber = mobile, message = the message we want to send

def SendText(SendNumber, SendMessage):
WriteBuffer(('+CMGS="%s"') % SendNumber, ">", "Error", "Y")
WriteBuffer(SendMessage, ">", "Error", "N")
WriteBuffer(chr(26), "+CMGS:", "Error", "N")
WriteBuffer("pass", "OK", "Error", "N")

As I said, it's not perfect, but it does allow you to issues commands and get back the output quite easily.



E160G and Raspberry Pi

I thought i'd share a few of my findings on trying to use an E160G mobile dongle with my Raspberry Pi. I have a project where the Pi is sending text messages, and to do this i'm using Python and PySerial.

Everything has been working fine with it, got the modem connected and tested out the AT commands using minicom. Everything was pretty happy until we got down to sending.

Everything seems to work fine on the surface, you enter send string:

AT+CMGS="mobilenumberhere"

and then it returns the expected > for the message, so I enter the message and then end the message (char26 or ctrl+z)

Message sends, I see it arrive on my phone.. but then the dongle doesn't respond with a message ID number as expected (+CMGS), nor does it respond ok. It just crashes and sits there doing nothing.

I went through various things, my original htought was a power issue as it only happened when sending - tried 3 different powered USB hubs all to no avail. I thought I was going mad.

Eventually, I tried a different dongle (an E173) and it worked perfectly. Therefore at this moment in time, I believe there to be some kind of incompatibility between the E160G and the Pi - or at least MY E160G and the Pi.

I've wasted far to much time on this, so thought I would share my thoughts.

For anyone interested, I've written a some functions to work with Python and the dongles for sending adn collecting messages - see my next blog post.

Later