View previous topic :: View next topic |
Author |
Message |
PrinceNai
Joined: 31 Oct 2016 Posts: 463 Location: Montenegro
|
send SMS to multiple phone numbers |
Posted: Mon Oct 31, 2016 8:50 am |
|
|
Hi,
I have a project that receives and sends SMS messages. With one fixed phone number stored in program memory everything works fine. What I'd like to do is send that SMS to multiple numbers at once.I should also be able to add and delete phone numbers via SMS with something like "add +xxxxxxxxx" command, but that is step two :-). If I'm thinking correctly, my numbers should be stored in EEPROM, than at boot time loaded to RAM and when the time comes, get the first number, send an SMS, get the second, send and so on. Since I'm new to C, I have no idea how exactly to do that. Questions:
-best way to store numbers (each number is 12 characters long)
-how to delimit numbers
-how to incorporate them into AT command (strcat is my guess)
-how to indicate that I went through all the numbers
Any help would be welcome.
Regards |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19367
|
|
Posted: Mon Oct 31, 2016 9:17 am |
|
|
Normally numbers will be up to 15 characters long. Many cellular providers require SMS numbers to be in the E164 format, which is +[country code] [full subscriber code]. Some providers will not accept SMS's unless this format is followed. You therefore need to allow for 15 character numbers.
So 'KISS', and allow 16 characters per number including null terminator. Just have the numbers at 16 character steps in the ROM, and terminate each with a null. Then if there is a null as the first character at the 16 character boundary, you have finished.
Since each number is then null terminated, standard string functions can be used with them.
Sequence becomes:
1) Load character at start of block.
Is is a null?. Yes: finish. No: send SMS to this number. Move to next *16 address, and loop back to '1'.
All you then need to do, is when the character is not NULL, read the characters from the EEPROM, into a RAM array until you reach the NULL at the end of the number. If this array is called 'telno', then once this is done, you can send a text mode SMS (assuming the modem is on a serial port with stream name 'GSM'), with:
fprintf(GSM,"AT+CMGS=\"%s\"\r",telno);
You then have to wait for the modem to reply with '>', and can then send your text, followed by the '`x1A' character. |
|
![](templates/subSilver/images/spacer.gif) |
PrinceNai
Joined: 31 Oct 2016 Posts: 463 Location: Montenegro
|
|
Posted: Mon Oct 31, 2016 9:35 am |
|
|
Great, thank you. Just one more, probably very basic question and I should be able to start tinkering. How do I assign those 16 byte blocks?
Regards |
|
![](templates/subSilver/images/spacer.gif) |
PrinceNai
Joined: 31 Oct 2016 Posts: 463 Location: Montenegro
|
|
Posted: Mon Oct 31, 2016 9:42 am |
|
|
16x10 or 10x16 (for 10 numbers) array and then increment pointer to 15, then 31 and so on when one number is done? |
|
![](templates/subSilver/images/spacer.gif) |
PrinceNai
Joined: 31 Oct 2016 Posts: 463 Location: Montenegro
|
|
Posted: Mon Oct 31, 2016 9:43 am |
|
|
16 and 32 |
|
![](templates/subSilver/images/spacer.gif) |
Gabriel
Joined: 03 Aug 2009 Posts: 1067 Location: Panama
|
|
Posted: Tue Nov 01, 2016 5:50 am |
|
|
In my experience, there is no way to address multiple recipients.
I might be wrong, but I've never seen such AT command.
You have to loop and repeat the send sms operation for every recipient.
G. _________________ CCS PCM 5.078 & CCS PCH 5.093 |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19367
|
|
Posted: Tue Nov 01, 2016 6:03 am |
|
|
You have to send multiple SMS's.
A directory of numbers, and send them one after the other, using the same SMS text. |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9174 Location: Greensville,Ontario
|
|
Posted: Tue Nov 01, 2016 11:22 am |
|
|
One thing to be aware of...depending on the provider, sending multiple SMSes may look like 'spamming' and they cut you off ! I found out that the hard way. Their server said I sent too many msgs, too fast........it didn't matter that I was sending them to MY devices NOT JQPublic...
Jay |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19367
|
|
Posted: Tue Nov 01, 2016 2:33 pm |
|
|
Yes. Also the rate of repeat is often limited. Some accounts allow high rates like one SMS per second, but others have limits like five an hour. This is why there are services like IntelliSMS. It might well be better to be using a service like this to forward the SMS to a list of recipients, rather than trying to send a lot directly from the device. |
|
![](templates/subSilver/images/spacer.gif) |
benoitstjean
Joined: 30 Oct 2007 Posts: 553 Location: Ottawa, Ontario, Canada
|
|
Posted: Tue Nov 01, 2016 8:01 pm |
|
|
If I may add my two cents since this is something I am currently doing, depending on the modem, there might be different methods of sending an SMS:
1) Using something like AT+CMGS and pass the 'TO' number as parameter then sumbit the command. The modem will then wait for the text until it receives a CTRL+Z character to terminate the text. Then, you might get something like an 'OK' but this just means the command is sent. You need to wait (such as in my case) for a +CMGS response and that can take from a few seconds to a few minutes. This is the equivalent of the progress bar on an iPhone when you send a text and when you hear the "foooip!" sound, then the text is officially sent.
2) Using a command like AT+CMGSO (note the 'O') and that is the equivalent of 'Send SMS now' and you pass the number as parameter followed by the text to send followed by \x0D\x0A.
The same principle as #1: get OK then wait for the +CMGSO response.
The thing to be aware of is that if you send another text while the +CMGS/O response is not received, then you will most likely run into issues.
Also, you have to be aware that AT commands can also return errors. And you also might have to configure "SMS message mode" and "SMS character set" and "SMS Receive mode" etc.
It is not that simple to get the thing to work right.
The most important is to have a message queue that will contain all messages to send. The queue is constantly checked for new messages to process but a flag also needs to be set which indicates if an SMS is currently being sent (or not) and that flag is reset only when the +CMGS confirmation is received. This means that if you have like 15 SMS queued, they will all be sent one after the other but only when the flag is reset.
Not sure if this is all clear.
I didn't notice the type of device you are using nor the type of modem.
Here in Canada using Rogers, I can send as many SMS's as I want in a row without a problem. |
|
![](templates/subSilver/images/spacer.gif) |
PrinceNai
Joined: 31 Oct 2016 Posts: 463 Location: Montenegro
|
|
Posted: Wed Nov 02, 2016 3:14 am |
|
|
Hi,
Thank you all for your replies. It is a project for an alarm. It monitors a pellet stove for the level of pellets and it will not be used to send mass SMS-es. Maybe one every three or four days on 5 or so phone numbers. I never heard of any limitation regarding the number or speed, but then again, I never tried to send many messages at once.
The project uses SIM900 modem and 18f252.
Sending and receiving already works for one fixed number.
I tried Ttelmah's method and it works like magic :-) :
-copy number from EEPROM to buffer
-use fprintf to send the number to modem
I still need to add a loop there that will check the first character of a 16 byte block in EEPROM for '+' and get the number to the buffer if it finds one, else check the next block. Since there is space for max. 16 numbers all rows in EEPROM are going to be checked every time. The reason for that is my plan to add the option to add and delete phone numbers via SMS. Adding a number will simply find the first 16 byte block that doesn't start with '+' and write it there, while deleting a number will write NULLS to that row. This way I don't need to sort the numbers or write them to EEPROM in any specific order.
Regards |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19367
|
|
Posted: Wed Nov 02, 2016 3:29 am |
|
|
Very sensible.
Remember that you only need to overwrite the single character at the start of the line. Saves time, and lives on the later characters.
So:
Code: |
\0something...\0
something...\0
\0more...\0
|
says that line '1' has a 'in use' number and the others are not to be sent. No need to overwrite the rest of the 'line'.
Personally I wouldn't store the '+'. The numbers have to have it, so 'why save it'. You can just append it when you send the number. One less character to store. ![Smile](images/smiles/icon_smile.gif) |
|
![](templates/subSilver/images/spacer.gif) |
benoitstjean
Joined: 30 Oct 2007 Posts: 553 Location: Ottawa, Ontario, Canada
|
|
Posted: Wed Nov 02, 2016 4:52 am |
|
|
I use the SIMCOM modems as well. I'll tell you right away, they can be a pain to work with. The commands and responses are very peculiar and the documentation is terrible because it is written by someone who's main language is not english so descriptions are very vague and difficult to understand.... but once you get them working, they are very nice and reliable.
Depending on if this is a personal project or a company project (therefore depends on your budget), I strongly suggest you get yourself a Saleae logic analyzer for about 180$ (Canadian) to troubleshoot data between the modem and the PIC. The reason is that some responses have the 'OK' embedded in them and others the 'OK arrives later, in some other cases you get 'OK' followed by another response. So there is no consistency between messages and it can get confusing.
I looked at the AT command guide and this modem does not appear to support AT+CMGSO so you will have to use AT+CMGS.
Also, you will have to use 'AT+CMGF' e.g. AT+CMGF=1 to set it in 'text' mode rather than 'PDU' mode and also 'AT+CNMI' e.g. AT+CNMI=1,2,0,0,0 to set the receive mode.
Good luck.
Benoit |
|
![](templates/subSilver/images/spacer.gif) |
Gabriel
Joined: 03 Aug 2009 Posts: 1067 Location: Panama
|
|
Posted: Wed Nov 02, 2016 8:33 am |
|
|
Just loop this function and change the number accordingly...
Code: | //_________________________________________________________
//
// SEND SMS
void SEND_SMS()
{
counter_read=0;
printf("AT+CMGS=\"########\"\r"); // send command and cel #
delay_ms(1000); // Delay long enough for modem response
printf("LORD JESUS ITS A FIRE!!!\n\r"); // Text to reply
putchar(0x1A); // send Ctrl-z
delay_ms(20000); // Delay long enough for modem response
} |
Ive made this with fixed delays... there are clever ways to shorten this delays.... but thats your work.
G. _________________ CCS PCM 5.078 & CCS PCH 5.093 |
|
![](templates/subSilver/images/spacer.gif) |
benoitstjean
Joined: 30 Oct 2007 Posts: 553 Location: Ottawa, Ontario, Canada
|
|
Posted: Wed Nov 02, 2016 8:59 am |
|
|
If I may comment on the above reply, I wouldn't do it in a loop.
If you read my previous posts, sending an SMS is a multi-step process. I've been doing development on SIMCom modems for the last 4 years. Sending an SMS requires the modem to return the +CMGSO response before another SMS can be sent. I've seen SMS reponses arrive within 5 seconds just like I've seen SMS responses arrive in more than 5 mintues.
The +CMGSO response is somewhat the network confirmation that the message was sent.
Anyhow, do it how you wish, I'm just providing my comments since I am in it as I type this.
Ben |
|
![](templates/subSilver/images/spacer.gif) |
|