STM32 - GPRS
Здравствуйте.
Продолжение описания работы с GSM-модемом и stm32. В предыдущей статье рассматривалось взаимодействие с модемом как с телефоном (звонки, смс), а здесь рассказано как передавать/получать данные через GPRS.
HTTP пример
TCP пример
Как и в предыдущем примере (ознакомьтесь), здесь используются два USART'а, один таймер и выход для светодиода. То есть ничего нового за исключением одного — добавлен выход (PA0) для управления реле через которое запитан модуль…
Это нужно чтобы вместе с ресетом платы модуль обесточивался и сбрасывал все свои настройки.
Работает следующим образом:
При старте, автоматически устанавливается скорость USART'а — 57600, и начинают отсылаться команды настройки с помощью функции
Передавать/получать данные можно несколькими способами — TCP/UDP, HTTP, FTP. Я сделал два отдельных примера, первый для передачи по HTTP, а второй по TCP. Через HTTP
HTTP
Предварительная настройка производится в начале программы, в блоке…
/*------------------- БЛОК HTTP START --------------------*/
//////////////////// HTTP НАСТРОЙКА /////////////////////
set_comand(ATCGATT1); // включить GPRS сервис
...
Всё происходящее (и успешные команды, и ошибки) выводится в терминал.
В блоках обработки ошибок…
while(1) // мигаем 5 секунд и ресетим плату
{
count_err++;
HAL_GPIO_TogglePin(ER_LED_GPIO_Port, ER_LED_Pin);
HAL_Delay(100);
//if(count_err > 49) HAL_NVIC_SystemReset();
}
… есть закомментированная функция, с помощью которой можно ресетить плату (а вместе с ней и модуль). Ошибки обрабатываются не только при начальной настройке, но и в процессе дальнейшей работы.
Всё что связано c отправкой/получением по HTTP, находится в функции
void send_http(uint8_t a, uint8_t b)
{
char buf[64] = {0,}; // строка должна быть не больше 64 символов
snprintf(buf, 64, "AT+HTTPPARA=\"URL\",\"http://some_site.ru/gsm.php?a=%d&b=%d\"\r\n", a, b); // адрес страницы
//snprintf(buf, 64, "AT+HTTPPARA=\"URL\",\"http://example.com/\"\r\n");
...
Сейчас запрос с аргументами закомментирован и указан просто тестовый сайт. Если загрузить программу, то вернётся запрошенная страничка…
Чтобы отправить данные на сервер, нужно чтоб у вас был этот самый сервер , а для проверки работы надо создать на нём файлик
<?php
$today = date("Y.m.d H:i:s"); //получаем текущие дату и время
$argument_a = $_REQUEST['a']; //получаем значение посланной переменной "а"
$argument_b = $_REQUEST['b']; //получаем значение посланной переменной "b"
echo "Hello, reciv - "." $argument_a "." $argument_b ".", date - ". "$today";
?>
Раскомментить верхнюю строчку и вписать в неё ваш адрес. Аргументов может быть больше, но нужно следить за тем, чтобы строка (начиная с AT...) была не больше 64-ёх символов.
Если строка получается больше, тогда отправлять её нужно частями, и только последняя часть должна содержать символы
То есть, если строка у вас такая...
"AT+HTTPPARA=\"URL\",\"http://some_site.ru/bla_bla_bla_bla_bla_bla_bla_bla_bla/gsm.php?a=45&b=78\"\r\n" // 93 символа
Тогда отправка будет выглядеть так...
snprintf(buf, HTTP_BUFF_SIZE, "AT+HTTPPARA=\"URL\",\"http://some_site.ru/bla_bla_bla_bla_bla");
HAL_UART_Transmit(GSM, (uint8_t*)buf, strlen(buf), 1000);
snprintf(buf, HTTP_BUFF_SIZE, "_bla_bla_bla_bla/gsm.php?a=%d&b=%d\"\r\n", a, b);
HAL_UART_Transmit(GSM, (uint8_t*)buf, strlen(buf), 1000);
Вернётся то, что отправили, и дату/время…
Далее в функции производятся проверки и если всё хорошо, то посылается команда отправки данных —
После этого снова идут проверки и в случае успеха отправляется команда чтения ответа от сервера —
Данные вычитываются по 1024 байта (можно увеличить в файле usart_ring.h) и выводятся в терминал. Обрабатывать данные нужно там где написано «тут можно парсить ответ».
///////////////////////////////// чтение ответа сервера /////////////////////////////////////
if(flag)
{
flag = 0;
HAL_Delay(500);
char read_buf[GPRS_RX_BUFFER_SIZE] = {0,};
while(gsm_available())
{
uint16_t i = 0;
memset(read_buf, 0, GPRS_RX_BUFFER_SIZE);
while(gsm_available())
{
read_buf[i++] = gsm_read();
if(i > GPRS_RX_BUFFER_SIZE - 1) break;
}
HAL_UART_Transmit(DEBUG, (uint8_t*)"\n----------\nREAD_BUF:\n----------\n", strlen("\n----------\nREAD_BUF:\n----------\n"), 1000);
HAL_UART_Transmit(DEBUG, (uint8_t*)read_buf, strlen(read_buf), 1000);
// тут можно парсить ответ
}
}
Там у меня ещё есть комменты — «как-то обрабатываем ошибку», я не знаю что лучше делать в этом случае. С одной стороны это может быть разовая ошибка (допустим вы периодически отправляете данные, а сервер по какой-то причине не принял запрос) и дальше всё будет работать нормально, а с другой стороны это может быть долговременная проблема (сбой сервера, сбой модуля, Вселенский апокалипсис), тогда надо что-то делать. Самое простое решение, это добавить туда счётчик ошибок, типа — «если десять раз насчёлкало, тогда ресетим плату», ну или ещё что-то.
Чтоб посмотреть как всё происходит, дайте в терминале команды…
AT+HTTPPARA="URL","http://example.com/"
Вернёт ОК.
AT+HTTPACTION=0
Сначала вернёт ОК. Потом после паузы должно вернуть +HTTPACTION:0,200,1270.
0 — данные были получены GET-запросом.
200 — код ответа сервера.
1270 — кол-во принятых байт.
AT+HTTPREAD
Вернёт +HTTPREAD:1270 и данные.
При отсылке команд через терминал, данные будут вычитываться в функции
Если в течении некоторого времени (около 4-х часов) ничего не посылать серверу, то происходит разрыв GPRS-соединения, модуль присылает уведомление
else if(strstr(buf, "+SAPBR") != NULL)
{
if(strstr(buf, "DEACT") != NULL)
{
set_comand(ATSAPBR11); // установить соединение
}
}
Все команды описаны в файле
Если в бесконечном цикле раскомментировать функцию
if(count > 59) // каждые 60 секунд
{
count = 0;
//send_http(57, 69);
}
TCP
Здесь почти всё то же самое, различие только в методе запроса к серверу. При старте производятся настройка, проверка и обработка ошибок…
Добавлена функция
Вся работа с сетью происходит в функции
Запрос состоит из следующих команд…
Если дать команду так — AT+CIPSEND=23 (цифра — это количество байт для отправки), то модуль отправит данные на сервер после ввода указанного количества символов, при этом
Строка с данными
"GET / HTTP/1.1\r\nHost: example.com\r\nConnection: keep-alive\r\n\r\n"
В подтверждение что данные отправлены модуль вернёт «SEND OK». После этого можно ловить ответ от сервера…
По завершении приёма данных мы посылаем команду закрытия соединения — «AT+CIPCLOSE». Однако может так случиться, что пока мы вычитываем данные, модуль уже сам (автоматически) закроет соединение, тогда эта команда вернёт ошибку —
Функция
Если долго ничего не отправлять, то модуль деактивирует GPRS и пришлёт сообщение «DEACT» — эта ситуация обрабатывается в бесконечном цикле.
В примерах предусмотрена возможность позвонить на модуль и при определении номера сделать что-то, например перезагрузку. Другие функции можно добавить из первой части.
Чтобы использовать модуль как сервер, нужно иметь сим-карту с «белым» IP (настройки APN будут другие) и немножко изменить инициализацию. Вместо
И в довершение, пример для передачи и чтения данных с Thingspeak.
Всем спасибо
Телеграм-чат istarik
Телеграм-чат STM32
- 0
- stD
16698
Поддержать автора
Комментарии (0)