Cannot set receiver phone number using AT+CMGS="XXXXXXXXX" returns error 325 - arduino

I am using SIM808 to send SMS to a perticuar number. But when trying to set the number using AT+CMGS=XXXXXXX returns +CMS ERROR:325. I have set the AT+CSCS to GSM but still no luck.The following is the code:
import serial
import os, time
# Enable Serial Communication
port = serial.Serial("/dev/ttyUSB0", baudrate=9600, timeout=1)
# Transmitting AT Commands to the Modem
# '\r\n' indicates the Enter key
port.write('AT'+'\r\n')
rcv = port.read(10)
print rcv
port.write('AT+CMGF=1\r\n')
time.sleep(10)
rcv = port.read(10)
print rcv
port.write('AT+CMGS=\'9912345678\'\r\n')
time.sleep(2)
port.write('test msg')
time.sleep(2)
port.write(chr(26))
rcv = port.read(10)
print rcv
port.flush()

SIM808 expects that AT+CMGS command should enclose the mobile/cell number in double quotes. You have provided escape sequence for single quote.
Your code should be :
port.write("AT+CMGS=\"9912345678\"\r\n")
instead of
port.write('AT+CMGS=\'9912345678\'\r\n')
Because you are providing single quotes escape sequence you get +CMS ERROR:325 error.
While providing mobile/cell number it is an good practice to include country code (in your case +91).

Related

RS232 Serial communication with PR4000 controller from MKS

I am trying to establish a serial connection via an RS232 port on the PR4000 controller from MKS. This controller is connected to a pressure gauge, and I try to read the pressure from my PC with the following script:
import time
import serial
import bitarray
ba = bitarray.bitarray()
# configure the serial connections (the parameters differs on the device you are connecting to)
ser = serial.Serial(
port='COM7',
baudrate=9600,
parity=serial.PARITY_ODD,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.SEVENBITS
)
#ser.isOpen()
print ('Enter your commands below.\r\nInsert "exit" to leave the application.')
data_in=0
while True :
data_in = input(">> ")
if data_in == 'exit':
ser.close()
break
else:
ser.write((data_in).encode('utf-8'))
out = ''
time.sleep(0.1)
while ser.inWaiting() > 0:
out = ser.read(ser.inWaiting()).decode('utf8')
if out != '':
print (out)
This code is inspired from this post :
Full examples of using pySerial package
you can find the doc of the controller here :
https://www.idealvac.com/files/manuals/PR4000_InstructionManual.pdf
The interface chapter start at page 43.
basically, the RS interface works with an requests and answers syntax.
example of answer :
RT,ON : set the remote on the controller.
?RT : ask for the state of the remote mode.
I managed to establish the connection with hyper terminal
But with python, I've tried to enter the commands and I can't have any answers, the serial buffer is empty.
Do you think the problem is in the format of the requests ?
Do you think the problem is in the format of the requests ?
A command to the device needs to be terminated with a carriage return character. Suggest you append a CR character (i.e. '\r') to data_in before it is sent.
Refer to the code that inspired your version for an example.

Write and read from a serial port

I am using the following python script to write AT+CSQ on serial port ttyUSB1.
But I cannot read anything.
However, when I fire AT+CSQ on minicom, I get the required results.
What may be the issue with this script?
Logs:
Manual Script
root#imx6slzbha:~# python se.py
Serial is open
Serial is open in try block also
write data: AT+CSQ
read data:
read data:
read data:
read data:
Logs:
Minicom console
1. ate
OK
2. at+csq
+CSQ: 20,99
3. at+csq=?
OKSQ: (0-31,99),(99)
How can I receive these results in the following python script?
import serial, time
#initialization and open the port
#possible timeout values:
# 1. None: wait forever, block call
# 2. 0: non-blocking mode, return immediately
# 3. x, x is bigger than 0, float allowed, timeout block call
ser = serial.Serial()
ser.port = "/dev/ttyUSB1"
ser.baudrate = 115200
ser.bytesize = serial.EIGHTBITS #number of bits per bytes
ser.parity = serial.PARITY_NONE #set parity check: no parity
ser.stopbits = serial.STOPBITS_ONE #number of stop bits
ser.timeout = None #block read
#ser.timeout = 0 #non-block read
ser.timeout = 3 #timeout block read
ser.xonxoff = False #disable software flow control
ser.rtscts = False #disable hardware (RTS/CTS) flow control
ser.dsrdtr = False #disable hardware (DSR/DTR) flow control
ser.writeTimeout = 2 #timeout for write
try:
ser.open()
print("Serial is open")
except Exception, e:
print "error open serial port: " + str(e)
exit()
if ser.isOpen():
try:
print("Serial is open in try block also")
ser.flushInput() #flush input buffer, discarding all its contents
ser.flushOutput()#flush output buffer, aborting current output
#and discard all that is in buffer
#write data
ser.write("AT+CSQ")
time.sleep(1)
# ser.write("AT+CSQ=?x0D")
print("write data: AT+CSQ")
# print("write data: AT+CSQ=?x0D")
time.sleep(2) #give the serial port sometime to receive the data
numOfLines = 1
while True:
response = ser.readline()
print("read data: " + response)
numOfLines = numOfLines + 1
if (numOfLines >= 5):
break
ser.close()
except Exception, e1:
print "error communicating...: " + str(e1)
else:
print "cannot open serial port "
You have two very fundamental flaws in your AT command handling:
time.sleep(1)
and
if (numOfLines >= 5):
How bad are they? Nothing will ever work until you fix those, and by that I mean completely change the way you send and receive command and responses.
Sending AT commands to a modem is a communication protocol like any other protocols, where certain parts and behaviours are required and not optional. Just like you would not write a HTTP client that completely ignores the responses it gets back from the HTTP server, you must never write a program that sends AT commands to a modem and completely ignores the responses the modem sends back.
AT commands are a link layer protocol, with with a window size of 1 - one. Therefore after sending a command line, the sender MUST wait until has received a response from the modem that it is finished with processing the command line, and that kind of response is called Final result code.
If the modem uses 70ms before it responds with a final result code you have to wait at least 70ms before continuing, if it uses 4 seconds you have to wait at least 4 seconds before continuing, if it uses several minutes (and yes, there exists AT commands that can take minutes to complete) you have to wait for several minutes. If the modem has not responded in an hour, your only options are 1) continue waiting, 2) just give up or 3) disconnect, reconnect and start all over again.
This is why sleep is such a horrible approach that in the very best case is a time wasting ticking bomb. It is 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...
And regarding numOfLines there is no way anyone in advance can know exactly how many lines a modem will respond with. What if your modem just responds with a single line with the ERROR final result code? The code will deadlock.
So this line number counting has to go completely away, and instead your code should be sending a command line and then wait for the final result code by reading and parsing the response lines from the modem.
But before diving too deep into that answer, start by reading the V.250 specification, at least all of chapter 5. This is the standard that defines the basics of AT command, and will for instance teach you the difference between a command and a command line. And how to correctly terminate a command line which you are not doing, so the modem will never start processing the commands you send.

ESP8266 String max size 247 Bytes?

I program an ESP8266 NodeMCU with Lua script. As I was debugging the problem that strings just were cut off at the beginning and extended further. I send from ESP8266 to an Android Phone.
I looked more in testing the esp via UART Interface, following problem:
the maximum String size when I declare a string container is 247 characters. After I exceed the 247th there is an error:
stdin:1: unexpected symbol near '='
The String is obviously too long but I need to send at least 2048 bytes per String for maximum efficiency. Is it possible to extend the input limit of a string variable?
(I build a 2048 bytes Packet and 86 bytes Overhead for the HTTP Get Response)
The TCP Tx Buffer of ESP8266 is 2920 bytes.
str_resp0 = "HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=UTF-8\r\n";
str_resp1 = "Connection: close\r\n\r\n";
send_buf = "";
uart.on("data", "$",
function(data)
t = {send_buf,data}
send_buf = table.concat(t);
if data=="quit$" then
uart.on("data") -- quit the function
end
end, 0)
srv=net.createServer(net.TCP)
srv:listen(80,function(conn)
conn:on("receive",function(conn,payload)
--print(payload)
conn:send(str_resp0)
conn:send(str_resp1)
conn:send(send_buf)
send_buf = "";
end)
conn:on("sent",function(conn) conn:close()
end)
end)
stdin:1: unexpected symbol near '='
sounds very much like a problem with your "IDE" (ESPlorer?).
Furthermore, you should send long payloads in batches. The SDK limits the packet size to some 1500 bytes which is the standard Ethernet MTU.
http://nodemcu.readthedocs.io/en/latest/en/modules/net/#netsocketsend has some explanations and a nice example.
srv = net.createServer(net.TCP)
srv:listen(80, function(conn)
conn:on("receive", function(sck, req)
local response = {}
-- if you're sending back HTML over HTTP you'll want something like this instead
-- local response = {"HTTP/1.0 200 OK\r\nServer: NodeMCU on ESP8266\r\nContent-Type: text/html\r\n\r\n"}
response[#response + 1] = "lots of data"
response[#response + 1] = "even more data"
response[#response + 1] = "e.g. content read from a file"
-- sends and removes the first element from the 'response' table
local function send(sk)
if #response > 0
then sk:send(table.remove(response, 1))
else
sk:close()
response = nil
end
end
-- triggers the send() function again once the first chunk of data was sent
sck:on("sent", send)
send(sck)
end)
end)
Update 2016-07-18
Results of some experimenting in ESPlorer. The test uses a single initialized variable:
buffer = "A very long string with more than 250 chars..."
Hitting 'Send to ESP' (sending char-by-char over UART) will fail with an error similar to the one reported here.
Saving this into a file works fine.
Hit 'Save', will save the line to a file on your file system e.g. paul.lua
Hit 'Save to ESP', will send paul.lua to the device.
If it's not done automatically as part of 'Save to ESP' you can send dofile("paul.lua") to the device. This will make the variable buffer available in the global space.
Sending print(buffer) will print the entire string to the terminal window.
The Problem is as it seems unavoidable. Referring to the espressif forums:
"the delay added by the lower level code is 20ms it is documented!"
so the event frame could'nt get handled faster than this. The only way to tweak this might be buffering the data in microcontroller and sending it at once every 20ms or installing the so called "FreeRTOS SDK for ESP8266", whose transfer speed is only limited by uart speed.

AT+CMGS returns ERROR

I am using SIM900 GSM module connect to my AVR Microcontroller.
I tested it with FT232 to see transmitting data.
First Micro sends AT it will response OK
AT OK
AT+CMGF=1 OK
AT+CMGS="+9893XXXXXX" returns ERROR and doesn't show ">"
Could anybody advise me what to do?
Command AT+CSCS? will answer You what type of sms-encoding is used. Properly answer is "GSM", and if not, You should set it by command AT+CSCS="GSM".
And remember about "Ctrl+Z" (not "Enter") as a finish of sms text, please.
You aren't passing all the parameters to the command.
The command format is:
AT+CMGS=<number><CR><message><CTRL-Z>
Where:
<CR> = ASCII character 13
<CTRL-Z> = ASCII character 26
You have passed only the number and without the <CR> you won't see the > note for the message.
Example:
AT+CMGS="+9893XXXXXX"
> This is the message.→
The response is:
+CMGS:<mr>
OK
Where <mr> is the message reference.
If AT+CSCS? command returns UCS2, then many arguments need to be encoded as hex string of UTF-16 encoding, so the phone number would become "002B0039003800390033...", and the SMS text would need to be encoded in the same way. If you don't need UCS2 encoding, then the easiest thing to do is to switch to GSM encoding (or another encoding from the available set as shown by AT+CSCS=? command)
Sometimes the issue is the text mode you are in. Enter AT+CMGF? and you should receive +CMGF: 1. If instead you receive +CMGF: 0, enter AT+CMGF=1. This changes the message format from PDU mode to Text mode. I'm not sure what either of those mean exactly, but this fixed my issue.
SIM 800 AT command manual

Controlling MDrive 23 with Python under Linux

MDrive 23 motor takes commands from a terminal, and I got it to work with screen program:
screen /dev/ttyUSB0
Is this is called a serial terminal? I'm unfamiliar with the details of the connection, but feel like I should be able to use PySerial to send the commands.
I tried:
import serial
ser = serial.Serial('/dev/ttyUSB0', 19200)
ser.isOpen() # Returns True
ser.write('ma 100000\r\n') # Does nothing...
ser.inWaiting() # Returns 0
ser.close()
I didn't know how to set the other init variables, like:
parity = serial.PARITY_ODD,
stopbits = serial.STOPBITS_TWO
bytesize = serial.SEVENBITS
I'm going to try guessing some values next... The documentation is lame, but it mentions MODBUS TCP and Mcode.
How do I set these and are there any syntax errors in my snippet?
I know how to send arguments to the Serial object, but I do not know what values are typical.
The other parameters to the Serial constructor are set in a similar way as port and baudrate:
ser = serial.Serial(port = '/dev/ttyUSB0', baudrate=19200, bytesize=serial.SEVENBITS, parity=serial.PARITY_ODD, stopbits=serial.STOPBITS_TWO)
ser.write('whatever')
ser.flush() # wait for data to be written
ser.close()
Edit: It seems the default settings are 9600 baud, 8 bits, no parity and 1 stop bit. In addition no flow-control is used. That would be equivalent to:
ser = serial.Serial(port = '/dev/ttyUSB0', baudrate=9600, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, xonxoff=False, rtscts=False, dsrdtr=False)
As all values, except port, are set to their defaults, you may use:
ser = serial.Serial(port = '/dev/ttyUSB0')
The last thing to worry about is which (read) timeout to set. This is measured/set in seconds (float allowed) and sets how long a read() command will block before returning what has been read.

Resources