I am trying to send SMS messages through software serial ports on a Sony Ericsson Z500a phone. (I bought this particular one because it was unlocked, for a great price, and it had the serial port!) I made a quick sketch to interpret the data and to have it eco the user input and the phone's output in one Serial monitor. Everything works great, but I can't get the darn phone to send SMS messages. It works if I send it "AT" - it replies with "OK". Also, I can use "ATD##########" and "ATH" to make and hang up on calls. I really thought that this would use the Text mode sms, but when I use "AT+CMGF=?", I only get "+CMGF: (0)" meaning I had to use PDU.
I found some sketches (and even tried the libraries from they playground), but I can't get my phone to send SMS. (Ugh!)
Here is what I get when I try to send a SMS message through PDU:
The connections have been established
AT
OK
AT+CMGF=0
+CMGF=0
OK
AT+CMGS=23
+CMGS=23
> 0011000B916407281553F80000AA0AE8329BFD4697D9EC37
0011000B916407281553F80000AA0AE8329BFD4697D9EC37
26
26
I sent it 26 at the end because that should be "control + z" to tell the phone that the code is done. However, it just keeps echoing everything until I reset everything. Also, I can't read SMS either, but that's a different story.
Here is the code for the interperating sketch if you're interested:
//Used to talk to Sony Ericsson Phones over AT commands
//Made by Mitch Duncan on Feb. 20 2013
//Feel free to modify
#include <SoftwareSerial.h>;
String inputString;
SoftwareSerial phone(10,11); // Sets up the software serial
// between the phone and the arduino
void setup()
{
phone.begin(9600); //starts the virtual serial at 9600 baud
delay(100); //waits for good measure
Serial.begin(4800); //begins real serial (for serial monitor) at 4800 baud
delay(100); // waits again for good measure
Serial.println("The connections have been established"); //used to know that the program has started
}
void loop()
{
if (phone.available() > 0) // if the Serial phone is available (Putting something in serial)
{
delay(10); //wait for a split second (for good measure again)
Serial.print((char) phone.read()); //print out the phone's message (one char at a time)
}
while (Serial.available() > 0) { //when the user enters something into the Arduino's serial
delay(10); //wait for good measure
char letter = Serial.read(); //read back what it was so the console can echo it
inputString += letter; // add that to a string to print
}
if (inputString.length() > 0) //if there is something in the string (something was printed from the user)
{
phone.println(inputString); //send it to the phone
Serial.println(inputString); //send it back (for echoing purposes)
inputString = ""; //clear the string
}
}
Anyways, If anyone has any idea, I would greatly appreciate the help!
-Mitch
I'm afraid you'll have to review the format and encoding to be used for PDU mode. By format I mean there should be a header and other information before the message, by encoding I mean IA5. The reason why the phone echoes what you type is that the protocol says it must do so, until you send the ctrl-z as a single byte (not 26, two bytes). I don't know whether pressing ctrl-z in the serial monitor would give you what you want, I doubt it, but you can easily do that in code.
I'm sorry this is stuff I did in the past and I have no pointers to give you, but I think you you'll find no difficulties in finding examples and perhaps reusable scripts.
dan007:
"AT+CMGF=?", is what you use to query the state I believe, and as start up it will be in PDU mode hence "AT+CMGF=0", on your response.
If you use "AT+CMGF=1", instead of "AT+CMGF=?", this will set into text mode by settining it high.
Hope this helps if you.
Hi Dan, there's a subtle difference between AT+CMGF? and AT+CMGF=?. The first returns the modem's state, the second the modem's capabilities. The answer +CMGF: (0) tells that only PDU mode is supported.
I figured out how to send control-z as a command to the phone. Now every time I try to send a SMS message I get "+CMS ERROR: 304" . If anyone could help me, that'd be great. I really wish I could find a cheap alternative to the SMS shield or another unlocked phone that supports text mode for this project.... I've tried numerous examples of PDU codes I found online, but I always get "+CMS ERROR: 304".
(The error states that there is something wrong with the syntax)
I was just able to get the phone to SEND SMS through PDUspy, but I haven't figured out how to read incoming messages yet. When I try to transfer the pdu messages from PDUspy to hyperterminal to send the message, I still get error 304...
When I try to transfer the pdu messages from PDUspy to hyperterminal to send the message, I still get error 304
I think you have to understand the difference between a byte and a character on the terminal. Sometimes they are the same, but as you already know a byte such as ctrl-z is not printable, so you cannot copy and paste it. The same applies to the header of the PDU message, containing the length of the message itself. If the message is, say, ten characters long, you will not be able to copy and paste the corresponding character from PDUspy to the terminal. You need to do that in code where you can set the value of the byte as an integer, e.g.
spatula:
Sometimes they are the same, but as you already know a byte such as ctrl-z is not printable, so you cannot copy and paste it. The same applies to the header of the PDU message, containing the length of the message itself. If the message is, say, ten characters long, you will not be able to copy and paste the corresponding character from PDUspy to the terminal. You need to do that in code where you can set the value of the byte as an integer, e.g.
So you're saying that I need to take every octet from my PDU message and make that into a byte and then print each byte?
Or do I need to take the "AT+CMGS=23" and just print the "23" as a byte? If so, how do I send a string literal and a byte in one line of code without returning?
Both options work, but I prefer the second. You can copy the bytes into an array then send the array.
First declare an array that can contain all your content:
byte sms_content[200] = {0}; // initialize to 0, should be long enough to contain phone no and message
Then when you transform your message in pdu format you can put the bytes into the array. Better define an index to insert the bytes sequentially:
int sms_ctr = 0;
sms_content[sms_ctr++] = header_byte; // might be more than one byte, any zeroes must be sent as well
sms_content[sms_ctr++] = cr_byte; // carriage return
// then, multiple times,
sms_content[sms_ctr++] = converted_byte;
// and finally
sms_content[sms_ctr++] = ctrlz_byte;
Note that sms_ctr also works as a counter of the number of bytes in your content.
phone.print("AT+CMGS="); // do not use println here
phone.write(sms_content, sms_ctr);
I chose to distinguish print and write just for readability (one is text, the other binary), but you can use write for both.