В этой статье мы узнаем, как использовать GSM модуль SIM800 или SIM900 с микроконтроллером STM32 (платой STM32F103C8T6) и делать HTTP-запросы в формате JSON на любой API-сервер. Ранее мы уже использовали GSM модуль и плату STM32F103C8T6 (Blue Pill) для передачи данных на сервер Thingspeak и передачи SMS.
В данном проекте мы разработаем код для отправки данных на любой веб-адрес или веб-сервер с использованием API. Нам нужно будет отправлять данные в формате JSON, так как прямая отправка строковых данных выглядит довольно сложной.
Необходимые компоненты
- Отладочная плата STM32F103C8 (STM32 Blue Pill) (купить на AliExpress).
- GSM модуль SIM800/900 (купить на AliExpress).
- Датчик температуры и влажности DHT11 (купить на AliExpress).
- Модуль часов реального времени DS3231 (купить на AliExpress).
- Блок питания 12/9 В.
- Макетная плата.
- Соединительные провода.
Реклама: ООО "АЛИБАБА.КОМ (РУ)" ИНН: 7703380158
Что такое API?
API — это аббревиатура от Application Programming Interface, программного посредника, который позволяет двум приложениям общаться друг с другом. Каждый раз, когда вы используете приложение вроде Telegram, отправляете мгновенное сообщение или проверяете погоду на своем телефоне, вы используете API.
Пример API: когда вы используете приложение на своем мобильном телефоне, приложение подключается к Интернету и отправляет данные на сервер. Затем сервер извлекает эти данные, интерпретирует их, выполняет необходимые действия и отправляет их обратно на ваш телефон. Затем приложение интерпретирует эти данные и представляет вам нужную информацию в удобном для чтения виде. Вот что такое API — все это происходит через API.
Что такое формат JSON?
JSON означает JavaScript Object Notation. Это облегченный формат для хранения и транспортировки данных. Он часто используется при отправке данных с сервера на веб-страницу.
Например, ниже приведен пример простого объекта User, сериализованного в XML:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<xml> <user> <firstName>Jason</firstName> <middleName>Alexander</middleName> <lastName>Smith</lastName> <address> <street1>1234 Someplace Avenue</street1> <street2>Apt. 302</street2> <city>Anytown</city> <state>NY</state> <postalCode>12345</postalCode> <country>US</country> </address> </user> </xml> |
Как видите, те же данные, представленные в формате JSON, гораздо эффективнее, сохраняя при этом всю свою удобочитаемость для человека:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
{ "firstName" : "Jason", "middleName" : "Alexander", "lastName" : "Smith", "address" : { "street1" : "1234 Someplace Avenue", "street2" : "Apt. 302", "city" : "Anytown", "state" : "NY", "postalCode" : "12345", "country" : "US" } } |
JSON обычно используется вместе с протоколами IoT, которые не обеспечивают собственной поддержки сериализации структур данных, такими как HTTP/Rest, WebSockets, MQTT и SMQ.
В JSON данные структурированы определенным образом. JSON использует такие символы, как { } , : ” ” [ ] и имеет следующий синтаксис.
Данные представлены в парах ключ/значение:
1. Двоеточие (:) присваивает значение ключу.
2. Пары ключ/значение разделяются запятыми (,).
3. Фигурные скобки содержат объекты ({ }).
4. Квадратные скобки содержат массивы ([ ]).
Схема проекта
Давайте теперь сделаем настройку оборудования нашего проекта. В нем мы будем использовать 2 модуля, данные которых должны отправляться на сервер через API в формате JSON. Этими модулями будут датчик влажности и температуры DHT11 и модуль часов реального времени (RTC) DS3231 для проверки времени и отправки его на сервер.
Схема подключения GSM-модуля, датчика DHT11 и модуля часов реального времени DS3231 к плате STM32F103C8T6 представлена на следующем рисунке.
Таким образом, мы запитали GSM-модуль напряжением 12 В, а плату STM32 — напряжением 5 В от USB-порта компьютера.
Внешний вид собранной конструкции проекта показан на следующем рисунке.
Библиотека Arduino JSON
Самый простой способ декодировать и кодировать строки JSON с помощью Arduino IDE — использовать библиотеку ArduinoJson, которая была разработана как самая интуитивно понятная библиотека JSON с наименьшим объемом и наиболее эффективным управлением памятью для Arduino. ArduinoJson — это библиотека C++ JSON для Arduino и IoT (Интернет вещей).
Функции данной библиотеки:
1. Декодирование JSON (поддерживаются комментарии).
2. Кодирование JSON (с необязательным отступом).
3. Элегантный API, очень простой в использовании.
4. Фиксированное выделение памяти (ноль malloc).
5. Отсутствие дублирования данных (ноль копирования).
6. Переносимый (написан на C++98).
7. Автономный (без внешних зависимостей).
8. Малый размер.
9. Библиотека только для заголовков.
Исходный код программы
Исходный код для создания HTTP POST в формате JSON с API для GSM-модуля SIM900/800 и платы STM32 приведен ниже.
Перед этим вам понадобятся некоторые библиотеки. Загрузите библиотеки по следующей ссылке и добавьте в Arduino IDE.
1. RTC Lib для DS3231: Загрузить
2. Библиотека DHT для датчика DHT11: Загрузить
3. Библиотека Arduino JSON: Загрузить
В следующем коде внесите изменения в APN. Я использовал Airtel APN. Проверьте APN вашего оператора сотовой связи и внесите изменения в код программы. Также внесите изменения в веб-сервер или добавьте адрес вашего веб-сервера api, куда вы хотите отправлять данные.
Дополнительную информацию о подключении модуля часов реального времени DS3231 к плате STM32F103C8 можно посмотреть в этой статье.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
#include <RTClib.h> // Download the library from https://github.com/adafruit/RTClib #include <Wire.h> // Library for I2C Communication with DS3231 Module #include <DHT.h> #include <ArduinoJson.h> StaticJsonBuffer<200> jsonBuffer; #define BOARD_USART3_TX_PIN PB10 // Connect to TX3/RX3 #define BOARD_USART3_RX_PIN PB11 // Connect to TX3/RX3 #define DHTPIN PA0 #define DHTTYPE DHT11 RTC_DS3231 rtc; DHT dht(DHTPIN, DHTTYPE); char t[32]; char deviceID[12] = "MYTEST56"; void setup() { Serial3.begin(9600); // the GPRS baud rate Serial.begin(9600); Serial.println("Initializing.........."); dht.begin(); Wire.begin(); DynamicJsonBuffer jsonBuffer; if (! rtc.begin()) { Serial.println("Couldn't find RTC"); while (1); } rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); //rtc.adjust(DateTime(2020, 02, 29, 17, 50, 40)); delay(5000); } void loop() { Serial.println(""); Serial.println("************************************************************"); float humidity = dht.readHumidity(); float temperature = dht.readTemperature(); DateTime now = rtc.now(); sprintf(t, "%02d:%02d:%02d %02d/%02d/%02d", now.hour(), now.minute(), now.second(), now.day(), now.month(), now.year()); Serial.print("Device ID: "); Serial.println(deviceID); Serial.print("Temperature: "); Serial.print(temperature); Serial.println(" °C"); Serial.print("Humidity: "); Serial.print(humidity); Serial.println(" %"); Serial.print(F("Time/Date: ")); Serial.println(t); delay(1000); /********************GSM Communication Starts********************/ if (Serial3.available()) Serial.write(Serial3.read()); Serial3.println("AT"); delay(3000); Serial3.println("AT+SAPBR=3,1,\"Contype\",\"GPRS\""); delay(6000); ShowSerialData(); Serial3.println("AT+SAPBR=3,1,\"APN\",\"airtelgprs.com\"");//APN delay(6000); ShowSerialData(); Serial3.println("AT+SAPBR=1,1"); delay(6000); ShowSerialData(); Serial3.println("AT+SAPBR=2,1"); delay(6000); ShowSerialData(); Serial3.println("AT+HTTPINIT"); delay(6000); ShowSerialData(); Serial3.println("AT+HTTPPARA=\"CID\",1"); delay(6000); ShowSerialData(); StaticJsonBuffer<200> jsonBuffer; JsonObject& object = jsonBuffer.createObject(); object.set("deviceID",deviceID); object.set("humidity",humidity); object.set("temperature",temperature); object.set("timedate",t); object.printTo(Serial); Serial.println(" "); String sendtoserver; object.prettyPrintTo(sendtoserver); delay(4000); Serial3.println("AT+HTTPPARA=\"URL\",\"http://192.138.xxxxxxxxxxxxxxxx.php\""); //Server address delay(4000); ShowSerialData(); Serial3.println("AT+HTTPPARA=\"CONTENT\",\"application/json\""); delay(4000); ShowSerialData(); Serial3.println("AT+HTTPDATA=" + String(sendtoserver.length()) + ",100000"); Serial.println(sendtoserver); delay(6000); ShowSerialData(); Serial3.println(sendtoserver); delay(6000); ShowSerialData; Serial3.println("AT+HTTPACTION=1"); delay(6000); ShowSerialData(); Serial3.println("AT+HTTPREAD"); delay(6000); ShowSerialData(); Serial3.println("AT+HTTPTERM"); delay(10000); ShowSerialData; /********************GSM Communication Stops********************/ } void ShowSerialData() { while (Serial3.available() != 0) Serial.write(Serial3.read()); delay(1000); } |
Тестирование работы проекта
После загрузки кода в плату STM32 и включения модуля он попытается подключиться к Интернету и отправить данные в формате JSON.
Иногда вы можете пропустить данные и получить некоторые ошибки. Это можно уменьшить, увеличивая задержки после шаг за шагом в приведенном выше коде. Или, если сетевое подключение и уровень сигнала хорошие, вы можете получить данные в большинстве случаев.
Откройте окно последовательного монитора и вы должны увидеть следующую картину.
32 просмотров