ESP32 (13) – Sending SMS

by luca

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.


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.

I’ll try to explain in details how to read the documentation and implement API calls not to force you to use the SMS Gateway I used for this tutorial but to be able to choose the one you prefer.

BulkSMS publishes all the API documentation in a development portal (; in particular the service used to send SMS (send_sms) is described at the following link:


If you want to send a message – after having created your account – you have to send a POST request to the server 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:



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;

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",

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);


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:

[youtube id=”0SKfoPLa-bU” width=”600″ height=”350″]

Related Posts


Michele Wednesday March 29th, 2017 - 04:19 PM

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:

Michele Wednesday March 29th, 2017 - 05:19 PM

Risolto, il cavo usb un pochino lungo 2m , quando si attivava la wifi creava una caduta di tensione sul filo . Alimentato esternamente funzion benissimo!!

Michele Wednesday March 29th, 2017 - 05:23 PM

PS: Ma ESP32 assorbe moltissimo in wifi, circa 100mA forse anche qualcosina di più in tx wifi


Leave a Comment

5 × one =