When designing and developing an embedded application, you often need to implement a way to notify the user if a specific event or condition is reached. Let’s imagine for example an house alarm system that must inform the owner if the front door is open when he’s away…
In today’s tutorial I’ll show you how to send SMS using the esp32 chip.
SMS Gateway
SMS (Short Message Service) is a service offered by the mobile network to send short text messages to mobile phones. To use that service and to be able to send SMS messages, you need an interface to the GSM mobile network. On the market you can find boards and modules (for example this GPRS Shield for Arduino by SeeedStudio) that allows a direct connection to the mobile network; an alternative is to use service providers on the Internet, called SMS Gateways.
SMS Gateways offers a way to send (and also receive) SMS messages using standard Internet protocols (HTTP, SMTP…). It’s usually a pay service (it costs you for each SMS you send); some gateways offer few free messages when you register. In this tutorial I’m going to use one of these gateways, BulkSMS, to send messages from my esp32 development board.
BulkSMS API
To be able to use an SMS Gateway, you first need to learn how to interact with it. An application exposes its services through an API (Application Programming Interface) and the “language” that must be used to speak with that interface is normally documented on the website or in a programming manual.
BulkSMS publishes all the API documentation in a development portal (http://developer.bulksms.com); in particular the service used to send SMS (send_sms) is described at the following link:
http://developer.bulksms.com/eapi/submission/send_sms/
If you want to send a message – after having created your account – you have to send a POST request to the server bulksms.vsms.net specifying at least the following parameters:
- username of your BulkSMS account
- password of your BulkSMS account
- message, text of the message to be sent
- msisdn, recipient’s phone number
The parameters have to be included in the request body with the form parametername=value and concatenated with the symbol &. If for example you want to send the message “hello world” to number 39123456789, the request body is:
username=bulksmsUser&password=bulksmsPass&message=hello+world&msisdn=39123456789
Program
The complete source code of the program is available in my Github repository. It’s similar to the one described in a previous tutorial: also this example is an HTTP client that sends a request to BulkSMS server and receives its response with the result of the call.
The SMS message is sent when you press the BOOT button on the development board… I’ve already explained how to use interrupts to handle this event. In this example I decided to use event groups to communicate between tasks both the status of the wifi connection and the click on the button:
// Event group for inter-task communication static EventGroupHandle_t event_group; const int WIFI_CONNECTED_BIT = BIT0; const int BUTTON_PRESSED_BIT = BIT1; |
If indeed the interrupt is triggered, I use the xEventGroupSetBitsFromISR method to “set” the BUTTON_PRESSED bit:
// button ISR void IRAM_ATTR button_isr_handler(void* arg) { xEventGroupSetBitsFromISR(event_group, BUTTON_PRESSED_BIT, NULL); } |
The main task (main_task) waits for the event to call BulkSMS and send the message:
xEventGroupWaitBits(event_group, BUTTON_PRESSED_BIT, pdTRUE, pdTRUE, portMAX_DELAY); |
As I wrote, the communication with BulkSMS is performed using the POST method of the HTTP protocol. First, the program builds the request body with the format described above:
sprintf(request_body, "username=%s&password=%s&message=%s&msisdn=%s", CONFIG_BULKSMS_USER, CONFIG_BULKSMS_PASSWORD, CONFIG_SMS_TEXT, CONFIG_SMS_RECIPIENTS); |
Then it defines the whole request. One of the headers (Content-Length) must specify the length (in bytes) of the body and that’s the reason why this is built first:
sprintf(request, "POST %s HTTP/1.1\nHost: %s\nUser-Agent: ESP32\n Content-Type: application/x-www-form-urlencoded\nContent-Length: %d\n\n%s", WEB_URL, WEB_SERVER, strlen(request_body), request_body); |
The BulkSMS response has the form ReturnCode|ReturnMessage. In particular if ReturnCode=0 the message is successfully sent, otherwise there was an error:
char* ret_code_string = strtok(body, "|"); int return_code = atoi(ret_code_string); char *return_message = strtok(NULL, "|"); if(return_code == 0) printf("SMS sent successfully!"); else printf("SMS send failed, error code = %d - %s\n", return_code, return_message); |
Test
Before running the program, you have to configure some parameters (the ones related to the wifi network and your BulkSMS account), via menuconfig:
Once completed the configuration and executed the program, if you click the BOOT button the message is sent:
In case of failure, the program prints the return code and also the error description:
And now a short video about the program sending a message to my mobile phone:
Salve ho provato l’esempio 01_wifi_scanner , ma va in crash , scollega la seriale.
(Mentre gli esempi originali “esp-idf” ) la wifi funziona corretamente
Nel log ho questo:
https://s4.postimg.org/i5vwacub1/MWSnap097.jpg
Risolto, il cavo usb un pochino lungo 2m , quando si attivava la wifi creava una caduta di tensione sul filo . Alimentato esternamente funzion benissimo!!
PS: Ma ESP32 assorbe moltissimo in wifi, circa 100mA forse anche qualcosina di più in tx wifi