Подключение ESP32 к облачному MQTT-брокеру (TTGO T-Call ESP32 SIM800L)

Это руководство показывает, как подключить плату TTGO T-Call ESP32 SIM800L к интернету с помощью тарифного плана SIM-карты и публиковать/подписываться на облачный MQTT-брокер без использования Wi-Fi. Облачный MQTT-брокер Mosquitto будет установлен на сервере Digital Ocean. Мы также используем Node-RED для визуализации показаний и управления выходами из любой точки мира. Плата будет программироваться с помощью Arduino IDE.

Подключение ESP32 к облачному MQTT-брокеру TTGO T-Call ESP32 SIM800L

С такой настройкой вы можете отслеживать и управлять своим ESP32 из любой точки мира, и ESP32 не нужно подключаться к беспроводному маршрутизатору, потому что он подключается к интернету с помощью тарифного плана SIM-карты.

Знакомство с TTGO T-Call ESP32 SIM800L

TTGO T-Call — это плата разработки на базе ESP32, которая сочетает в себе модуль GSM/GPRS SIM800L. Вы можете приобрести её примерно за $11.

Плата TTGO T-Call ESP32 SIM800L GPS GPRS

Помимо Wi-Fi и Bluetooth, с этой платой ESP32 можно общаться с помощью SMS или телефонных звонков, а также подключать её к интернету через тарифный план SIM-карты. Это отлично подходит для IoT-проектов, которые не имеют доступа к ближайшему маршрутизатору.

Важно: SIM800L работает в сетях 2G, поэтому он будет работать в вашей стране только при наличии сетей 2G. Проверьте, есть ли в вашей стране сеть 2G, иначе модуль работать не будет.

Для использования возможностей этой платы вам понадобится nano SIM-карта с тарифным планом передачи данных и USB-C кабель для загрузки кода на плату.

Плата ESP32 SIM800L с USB-C кабелем для зарядки и передачи данных

В комплект входят штырьковые разъёмы, коннектор для батареи и внешняя антенна, которую следует подключить к плате.

Комплект поставки ESP32 SIM800L

Однако у нас возникли некоторые проблемы с этой антенной, поэтому мы решили заменить её на антенну другого типа, и все проблемы были решены. На следующем рисунке показана новая антенна.

Альтернативная антенна для ESP32 SIM800L

Обзор проекта

Идея этого проекта — подключить ваш ESP32 к облачному MQTT-брокеру для подписки на MQTT-топик и публикации данных датчиков в MQTT-топики. ESP32 не нужен доступ к маршрутизатору через Wi-Fi, потому что он подключается к интернету через тарифный план SIM-карты.

Обзор проекта подключения ESP32 к облачному MQTT-брокеру TTGO T-Call ESP32 SIM800L

В предыдущем проекте мы создали собственный сервер с базой данных для отображения показаний датчиков в графиках, к которым можно получить доступ из любой точки мира.

В этом проекте мы будем публиковать показания датчиков на сервер через MQTT, и мы будем использовать брокер Mosquitto. Вы можете публиковать показания датчиков на любой другой облачный брокер.

Вкратце, вот как работает проект:

  1. Плата T-Call ESP32 SIM800L подключена к интернету через тарифный план SIM-карты.

  2. Плата T-Call ESP32 SIM800L публикует показания датчиков через MQTT, и показания отображаются в панели Node-RED Dashboard.

  3. Через панель Node-RED Dashboard вы можете нажимать кнопки для отправки команд включения и выключения для управления GPIO ESP32.

Мы будем использовать датчик BME280, но вы можете использовать любой другой датчик, который лучше подходит для ваших нужд.

Облачный MQTT-брокер

Вы можете найти бесплатный облачный MQTT-брокер, однако мы будем использовать наш собственный облачный MQTT-брокер. Мы рекомендуем использовать Digital Ocean с MQTT Mosquitto Broker, потому что он может удовлетворить все требования проекта. Мы также будем использовать программное обеспечение Node-RED для визуализации показаний на индикаторах и публикации MQTT-сообщений на ESP32.

Предварительные требования

1. Дополнение ESP32 для Arduino IDE

Мы будем программировать ESP32 с помощью Arduino IDE. Поэтому вам нужно установить дополнение ESP32 в вашей Arduino IDE. Следуйте следующему руководству, если вы ещё этого не сделали.

2. Подготовка облачного MQTT-брокера

В этом проекте мы покажем вам, как обмениваться данными через MQTT с помощью облачного MQTT-брокера.

Мы будем использовать наш собственный облачный MQTT-брокер. Однако, если вы найдёте бесплатный MQTT-брокер со всеми необходимыми функциями, он тоже подойдёт…

Если вы хотите следовать именно этому проекту, вам следует пройти следующие два руководства для подготовки собственного сервера и программного обеспечения Node-RED.

ESP32 публикует показания температуры каждые 30 секунд в топики esp/temperature и esp/humidity. Он подписан на два топика esp/output1 и esp/output2 для обновления состояния выходных светодиодов.

Когда Node-RED запущен, перейдите по IP-адресу вашего сервера с портом :1880.

http://cloud-mqtt-broker-ip-address:1880

Соедините ваши узлы, как показано ниже:

ESP32 SIM800L GPRS GSM облачный MQTT-брокер Node-RED Arduino

Наконец, разверните ваш поток (нажмите кнопку в правом верхнем углу).

Кнопка Deploy в Node-RED

Также вы можете перейти в Menu > Import и скопировать следующее в ваш Clipboard для создания потока Node-RED.

[{"id":"a2c394d8.1544e8","type":"mqtt in","z":"537cca59.c4a014","name":"","topic":"esp/temperature","qos":"2","datatype":"auto","broker":"18f874c0.4a464b","x":140,"y":1020,"wires":[["6907217e.f39bf"]]},{"id":"b83c2ecf.8ab94","type":"mqtt in","z":"537cca59.c4a014","name":"","topic":"esp/humidity","qos":"2","datatype":"auto","broker":"18f874c0.4a464b","x":130,"y":1100,"wires":[["c92e354e.a27d48"]]},{"id":"ee844c66.3eda2","type":"mqtt out","z":"537cca59.c4a014","name":"","topic":"esp/output1","qos":"1","retain":"","broker":"18f874c0.4a464b","x":330,"y":1180,"wires":[]},{"id":"54540fba.e5877","type":"mqtt out","z":"537cca59.c4a014","name":"","topic":"esp/output2","qos":"1","retain":"","broker":"18f874c0.4a464b","x":330,"y":1260,"wires":[]},{"id":"56080a9a.c7bba4","type":"ui_switch","z":"537cca59.c4a014","name":"","label":"Output 1","tooltip":"","group":"1539f836.ed9378","order":0,"width":0,"height":0,"passthru":true,"decouple":"false","topic":"","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","x":120,"y":1180,"wires":[["ee844c66.3eda2"]]},{"id":"417bd6d1.1d1468","type":"ui_switch","z":"537cca59.c4a014","name":"","label":"Output 2","tooltip":"","group":"1539f836.ed9378","order":0,"width":0,"height":0,"passthru":true,"decouple":"false","topic":"","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","x":120,"y":1260,"wires":[["54540fba.e5877"]]},{"id":"6907217e.f39bf","type":"ui_gauge","z":"537cca59.c4a014","name":"","group":"1539f836.ed9378","order":2,"width":0,"height":0,"gtype":"gage","title":"Temperature","label":"Celsius Degrees","format":"{{value}}","min":"-10","max":"40","colors":["#00b500","#e6e600","#ca3838"],"seg1":"","seg2":"","x":350,"y":1020,"wires":[]},{"id":"c92e354e.a27d48","type":"ui_gauge","z":"537cca59.c4a014","name":"","group":"1539f836.ed9378","order":2,"width":0,"height":0,"gtype":"gage","title":"Humidity","label":"%","format":"{{value}}","min":"0","max":"100","colors":["#93dae6","#0074cc","#002561"],"seg1":"","seg2":"","x":340,"y":1100,"wires":[]},{"id":"18f874c0.4a464b","type":"mqtt-broker","z":"","name":"","broker":"localhost","port":"1883","clientid":"","usetls":false,"compatmode":false,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"1539f836.ed9378","type":"ui_group","z":"","name":"Dashboard","tab":"38becbd0.c13714","order":1,"disp":true,"width":"6","collapse":false},{"id":"38becbd0.c13714","type":"ui_tab","z":"","name":"Home","icon":"dashboard","disabled":false,"hidden":false}]

Просмотр исходного кода

3. SIM-карта с тарифным планом

Для использования платы TTGO T-Call ESP32 SIM800L вам нужна nano SIM-карта с тарифным планом передачи данных. Мы рекомендуем использовать SIM-карту с предоплаченным или ежемесячным тарифным планом, чтобы вы точно знали, сколько потратите.

4. Данные APN

Для подключения вашей SIM-карты к интернету вам нужно иметь данные APN вашего оператора связи. Вам нужно доменное имя, имя пользователя и пароль.

В моём случае я использую vodafone Portugal. Если вы поищете GPRS APN settings и название вашего оператора связи (в моём случае это: «GPRS APN vodafone Portugal»), вы обычно можете найти на форуме или на их сайте всю необходимую информацию.

Я нашёл этот сайт, который может быть очень полезен для поиска всей необходимой информации.

Может быть немного сложно найти данные, если вы не используете известного оператора. В этом случае вам, возможно, придётся обратиться к оператору напрямую.

5. Библиотеки

Для продолжения работы над этим проектом вам нужно установить следующие библиотеки в Arduino IDE: Adafruit_BME280, Adafruit_Sensor, TinyGSM и PubSubClient. Следуйте инструкциям ниже для установки этих библиотек.

Установка библиотеки Adafruit BME280

Откройте Arduino IDE и перейдите в Sketch > Include Library > Manage Libraries. Должен открыться менеджер библиотек.

Введите «adafruit bme280» в поле поиска и установите библиотеку.

Установка библиотеки BME280 в Arduino IDE

Установка библиотеки Adafruit Sensor

Для использования библиотеки BME280 вам также нужно установить библиотеку Adafruit_Sensor. Следуйте следующим шагам для установки библиотеки в Arduino IDE:

Перейдите в Sketch > Include Library > Manage Libraries и введите «Adafruit Unified Sensor» в поле поиска. Прокрутите вниз, чтобы найти библиотеку, и установите её.

Установка библиотеки Adafruit Unified Sensor Driver

Установка библиотеки TinyGSM

В менеджере библиотек Arduino IDE найдите TinyGSM. Выберите библиотеку TinyGSM от Volodymyr Shymanskyy.

Установка библиотеки TinyGSM

Установка библиотеки PubSubClient

Найдите PubSubClient и прокрутите вниз. Выберите библиотеку PubSubClient от Nick O’Leary.

Установка библиотеки PubSubClient в Arduino IDE

После установки библиотек перезапустите Arduino IDE.

Необходимые компоненты

Для сборки этого проекта вам понадобятся следующие компоненты:

Вы можете воспользоваться ссылками выше или перейти на MakerAdvisor.com/tools для поиска всех компонентов по лучшей цене!

Схема подключения

Подключите датчик BME280 и два светодиода к плате T-Call ESP32 SIM800L, как показано на следующей схеме.

Схема подключения TTGO T-Call ESP32 SIM800L с датчиком BME280 и выходами

Мы подключаем вывод SDA датчика BME280 к GPIO 18, а вывод SCL — к GPIO 19.

Код

Скопируйте следующий код в вашу Arduino IDE, но пока не загружайте его. Сначала вам нужно внести некоторые изменения, чтобы он заработал.

/*
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/esp32-cloud-mqtt-broker-sim800l/

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.

  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*/

// Select your modem:
#define TINY_GSM_MODEM_SIM800 // Modem is SIM800L

// Set serial for debug console (to the Serial Monitor, default speed 115200)
#define SerialMon Serial
// Set serial for AT commands
#define SerialAT Serial1

// Define the serial console for debug prints, if needed
#define TINY_GSM_DEBUG SerialMon

// set GSM PIN, if any
#define GSM_PIN ""

// Your GPRS credentials, if any
const char apn[] = ""; // APN (example: internet.vodafone.pt) use https://wiki.apnchanger.org
const char gprsUser[] = "";
const char gprsPass[] = "";

// SIM card PIN (leave empty, if not defined)
const char simPIN[]   = "";

// MQTT details
const char* broker = "XXX.XXX.XXX.XXX";                    // Public IP address or domain name
const char* mqttUsername = "REPLACE_WITH_YOUR_MQTT_USER";  // MQTT username
const char* mqttPassword = "REPLACE_WITH_YOUR_MQTT_PASS";  // MQTT password

const char* topicOutput1 = "esp/output1";
const char* topicOutput2 = "esp/output2";
const char* topicTemperature = "esp/temperature";
const char* topicHumidity = "esp/humidity";

// Define the serial console for debug prints, if needed
//#define DUMP_AT_COMMANDS

#include <Wire.h>
#include <TinyGsmClient.h>

#ifdef DUMP_AT_COMMANDS
  #include <StreamDebugger.h>
  StreamDebugger debugger(SerialAT, SerialMon);
  TinyGsm modem(debugger);
#else
  TinyGsm modem(SerialAT);
#endif

#include <PubSubClient.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

TinyGsmClient client(modem);
PubSubClient mqtt(client);

// TTGO T-Call pins
#define MODEM_RST            5
#define MODEM_PWKEY          4
#define MODEM_POWER_ON       23
#define MODEM_TX             27
#define MODEM_RX             26
#define I2C_SDA              21
#define I2C_SCL              22

// BME280 pins
#define I2C_SDA_2            18
#define I2C_SCL_2            19

#define OUTPUT_1             2
#define OUTPUT_2             15

uint32_t lastReconnectAttempt = 0;

// I2C for SIM800 (to keep it running when powered from battery)
TwoWire I2CPower = TwoWire(0);

TwoWire I2CBME = TwoWire(1);
Adafruit_BME280 bme;

#define IP5306_ADDR          0x75
#define IP5306_REG_SYS_CTL0  0x00

float temperature = 0;
float humidity = 0;
long lastMsg = 0;

bool setPowerBoostKeepOn(int en){
  I2CPower.beginTransmission(IP5306_ADDR);
  I2CPower.write(IP5306_REG_SYS_CTL0);
  if (en) {
    I2CPower.write(0x37); // Set bit1: 1 enable 0 disable boost keep on
  } else {
    I2CPower.write(0x35); // 0x37 is default reg value
  }
  return I2CPower.endTransmission() == 0;
}

void mqttCallback(char* topic, byte* message, unsigned int len) {
  Serial.print("Message arrived on topic: ");
  Serial.print(topic);
  Serial.print(". Message: ");
  String messageTemp;

  for (int i = 0; i < len; i++) {
    Serial.print((char)message[i]);
    messageTemp += (char)message[i];
  }
  Serial.println();

  // Feel free to add more if statements to control more GPIOs with MQTT

  // If a message is received on the topic esp/output1, you check if the message is either "true" or "false".
  // Changes the output state according to the message
  if (String(topic) == "esp/output1") {
    Serial.print("Changing output to ");
    if(messageTemp == "true"){
      Serial.println("true");
      digitalWrite(OUTPUT_1, HIGH);
    }
    else if(messageTemp == "false"){
      Serial.println("false");
      digitalWrite(OUTPUT_1, LOW);
    }
  }
  else if (String(topic) == "esp/output2") {
    Serial.print("Changing output to ");
    if(messageTemp == "true"){
      Serial.println("true");
      digitalWrite(OUTPUT_2, HIGH);
    }
    else if(messageTemp == "false"){
      Serial.println("false");
      digitalWrite(OUTPUT_2, LOW);
    }
  }
}

boolean mqttConnect() {
  SerialMon.print("Connecting to ");
  SerialMon.print(broker);

  // Connect to MQTT Broker without username and password
  //boolean status = mqtt.connect("GsmClientN");

  // Or, if you want to authenticate MQTT:
  boolean status = mqtt.connect("GsmClientN", mqttUsername, mqttPassword);

  if (status == false) {
    SerialMon.println(" fail");
    ESP.restart();
    return false;
  }
  SerialMon.println(" success");
  mqtt.subscribe(topicOutput1);
  mqtt.subscribe(topicOutput2);

  return mqtt.connected();
}

void setup() {
  // Set console baud rate
  SerialMon.begin(115200);
  delay(10);

  // Start I2C communication
  I2CPower.begin(I2C_SDA, I2C_SCL, 400000);
  I2CBME.begin(I2C_SDA_2, I2C_SCL_2, 400000);

  // Keep power when running from battery
  bool isOk = setPowerBoostKeepOn(1);
  SerialMon.println(String("IP5306 KeepOn ") + (isOk ? "OK" : "FAIL"));

  // Set modem reset, enable, power pins
  pinMode(MODEM_PWKEY, OUTPUT);
  pinMode(MODEM_RST, OUTPUT);
  pinMode(MODEM_POWER_ON, OUTPUT);
  digitalWrite(MODEM_PWKEY, LOW);
  digitalWrite(MODEM_RST, HIGH);
  digitalWrite(MODEM_POWER_ON, HIGH);

  pinMode(OUTPUT_1, OUTPUT);
  pinMode(OUTPUT_2, OUTPUT);

  SerialMon.println("Wait...");

  // Set GSM module baud rate and UART pins
  SerialAT.begin(115200, SERIAL_8N1, MODEM_RX, MODEM_TX);
  delay(6000);

  // Restart takes quite some time
  // To skip it, call init() instead of restart()
  SerialMon.println("Initializing modem...");
  modem.restart();
  // modem.init();

  String modemInfo = modem.getModemInfo();
  SerialMon.print("Modem Info: ");
  SerialMon.println(modemInfo);

  // Unlock your SIM card with a PIN if needed
  if ( GSM_PIN && modem.getSimStatus() != 3 ) {
    modem.simUnlock(GSM_PIN);
  }

  // You might need to change the BME280 I2C address, in our case it's 0x76
  if (!bme.begin(0x76, &I2CBME)) {
    Serial.println("Could not find a valid BME280 sensor, check wiring!");
    while (1);
  }

  SerialMon.print("Connecting to APN: ");
  SerialMon.print(apn);
  if (!modem.gprsConnect(apn, gprsUser, gprsPass)) {
    SerialMon.println(" fail");
    ESP.restart();
  }
  else {
    SerialMon.println(" OK");
  }

  if (modem.isGprsConnected()) {
    SerialMon.println("GPRS connected");
  }

  // MQTT Broker setup
  mqtt.setServer(broker, 1883);
  mqtt.setCallback(mqttCallback);
}

void loop() {
  if (!mqtt.connected()) {
    SerialMon.println("=== MQTT NOT CONNECTED ===");
    // Reconnect every 10 seconds
    uint32_t t = millis();
    if (t - lastReconnectAttempt > 10000L) {
      lastReconnectAttempt = t;
      if (mqttConnect()) {
        lastReconnectAttempt = 0;
      }
    }
    delay(100);
    return;
  }

  long now = millis();
  if (now - lastMsg > 30000) {
    lastMsg = now;

    // Temperature in Celsius
    temperature = bme.readTemperature();
    // Uncomment the next line to set temperature in Fahrenheit
    // (and comment the previous temperature line)
    //temperature = 1.8 * bme.readTemperature() + 32; // Temperature in Fahrenheit

    // Convert the value to a char array
    char tempString[8];
    dtostrf(temperature, 1, 2, tempString);
    Serial.print("Temperature: ");
    Serial.println(tempString);
    mqtt.publish(topicTemperature, tempString);

    humidity = bme.readHumidity();

    // Convert the value to a char array
    char humString[8];
    dtostrf(humidity, 1, 2, humString);
    Serial.print("Humidity: ");
    Serial.println(humString);
    mqtt.publish(topicHumidity, humString);
  }

  mqtt.loop();
}

Просмотр исходного кода

Перед загрузкой кода вам нужно ввести данные APN, PIN-код SIM-карты (если применимо) и данные вашего облачного MQTT-сервера.

Как работает код

Введите ваши учётные данные GPRS APN в следующие переменные:

const char apn[]      = ""; // APN (example: internet.vodafone.pt) use https://wiki.apnchanger.org
const char gprsUser[] = ""; // GPRS User
const char gprsPass[] = ""; // GPRS Password

В нашем случае APN — это internet.vodafone.pt. Ваш должен быть другим. Мы объясняли ранее, как получить данные APN.

Введите PIN-код SIM-карты, если это применимо:

const char simPIN[] = "";

Вам также нужно ввести данные облачного MQTT-сервера в следующие переменные. Это может быть ваш собственный облачный MQTT-домен или любой другой MQTT-сервер, который вы хотите использовать.

const char* broker = "178.XXX.XXX.XXX";  // Public IP address or domain name
const char* mqttUsername = "REPLACE_WITH_YOUR_MQTT_USERNAME";
const char* mqttPassword = "REPLACE_WITH_YOUR_MQTT_PASSWORD";

ESP32 подписан на топики esp/output1 и esp/output2 для обновления выходов последним значением:

const char* topicOutput1 = "esp/output1";
const char* topicOutput2 = "esp/output2";

ESP32 публикует показания температуры и влажности в топики esp/temperature и esp/humidity каждые 30 секунд:

const char* topicTemperature = "esp/temperature";
const char* topicHumidity = "esp/humidity";

Код подробно прокомментирован, чтобы вы понимали назначение каждой строки.

Следующие строки определяют пины, используемые модулем SIM800L:

#define MODEM_RST       5
#define MODEM_PWKEY     4
#define MODEM_POWER_ON  23
#define MODEM_TX        27
#define MODEM_RX        26
#define I2C_SDA         21
#define I2C_SCL         22

Определение I2C-пинов BME280. В этом примере мы используем GPIO 18 и GPIO 19.

#define I2C_SDA_2  18
#define I2C_SCL_2  19

Определение последовательного соединения для монитора порта и другого для связи с модулем SIM800L:

// Set serial for debug console (to Serial Monitor, default speed 115200)
#define SerialMon Serial
// Set serial for AT commands (to SIM800 module)
#define SerialAT Serial1

Настройка библиотеки TinyGSM для работы с модулем SIM800L.

#define TINY_GSM_MODEM_SIM800

Подключение следующих библиотек для связи с SIM800L.

#include <Wire.h>
#include <TinyGsmClient.h>

А также библиотеки MQTT и библиотеки датчика BME280:

#include <PubSubClient.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

Создание экземпляра I2C-соединения для SIM800L (микросхема управления питанием от батареи).

TwoWire I2CPower = TwoWire(0);

И ещё одного I2C-соединения для датчика BME280.

TwoWire I2CBME = TwoWire(1);
Adafruit_BME280 bme;

Инициализация TinyGsmClient для интернет-соединения.

TinyGsmClient client(modem);

setup()

В setup() инициализируем монитор порта на скорости 115200 бод:

SerialMon.begin(115200);

Запуск I2C-соединения для модуля SIM800L и модуля датчика BME280:

I2CPower.begin(I2C_SDA, I2C_SCL, 400000);
I2CBME.begin(I2C_SDA_2, I2C_SCL_2, 400000);

Настройка пинов SIM800L в правильное состояние для работы:

pinMode(MODEM_PWKEY, OUTPUT);
pinMode(MODEM_RST, OUTPUT);
pinMode(MODEM_POWER_ON, OUTPUT);
digitalWrite(MODEM_PWKEY, LOW);
digitalWrite(MODEM_RST, HIGH);
digitalWrite(MODEM_POWER_ON, HIGH);

Инициализация последовательного соединения с модулем SIM800L.

SerialAT.begin(115200, SERIAL_8N1, MODEM_RX, MODEM_TX);

Инициализация модуля SIM800L и разблокировка PIN-кода SIM-карты при необходимости.

SerialMon.println("Initializing modem...");
modem.restart();

// Unlock your SIM card with a PIN if needed
if (strlen(simPIN) && modem.getSimStatus() != 3 ) {
  modem.simUnlock(simPIN);
}

Инициализация датчика BME280.

if (!bme.begin(0x76, &I2CBME)) {
  Serial.println("Could not find a valid BME280 sensor, check wiring!");
  while (1);
}

Наконец, в setup() происходит фактическое подключение к интернету. Следующие строки подключают модуль к интернету:

SerialMon.print("Connecting to APN: ");
SerialMon.print(apn);
if (!modem.gprsConnect(apn, gprsUser, gprsPass)) {
  SerialMon.println(" fail");
  ESP.restart();
}
else {
  SerialMon.println(" OK");
}

mqttConnect()

Функция mqttConnect() отвечает за подключение платы к MQTT-брокеру с использованием имени пользователя и пароля. Она также подписывает ESP32 на MQTT-топики esp/output1 и esp/output2.

boolean mqttConnect() {
  SerialMon.print("Connecting to ");
  SerialMon.print(broker);

  // Connect to MQTT Broker without username and password
  //boolean status = mqtt.connect("GsmClientN");

  // Or, if you want to authenticate MQTT:
  boolean status = mqtt.connect("GsmClientN", mqttUsername, mqttPassword);

  if (status == false) {
    SerialMon.println(" fail");
    ESP.restart();
    return false;
  }
  SerialMon.println(" success");
  mqtt.subscribe(topicOutput1);
  mqtt.subscribe(topicOutput2);

  return mqtt.connected();
}

loop()

В loop() есть таймер, который публикует показания температуры и влажности в ваш MQTT-брокер каждые 30 секунд.

long now = millis();
if (now - lastMsg > 30000) {
  lastMsg = now;

  // Temperature in Celsius
  temperature = bme.readTemperature();
  // Uncomment the next line to set temperature in Fahrenheit
  // (and comment the previous temperature line)
  //temperature = 1.8 * bme.readTemperature() + 32; // Temperature in Fahrenheit

  // Convert the value to a char array
  char tempString[8];
  dtostrf(temperature, 1, 2, tempString);
  Serial.print("Temperature: ");
  Serial.println(tempString);
  mqtt.publish(topicTemperature, tempString);

  humidity = bme.readHumidity();

  // Convert the value to a char array
  char humString[8];
  dtostrf(humidity, 1, 2, humString);
  Serial.print("Humidity: ");
  Serial.println(humString);
  mqtt.publish(topicHumidity, humString);
}

mqttCallback()

В функции mqttCallback() ESP32 получает MQTT-сообщения из подписанных топиков. В зависимости от MQTT-топика и сообщения, он включает или выключает выходы:

void mqttCallback(char* topic, byte* message, unsigned int len) {
  Serial.print("Message arrived on topic: ");
  Serial.print(topic);
  Serial.print(". Message: ");
  String messageTemp;
  for (int i = 0; i < len; i++) {
    Serial.print((char)message[i]);
    messageTemp += (char)message[i];
  }
  Serial.println();

  // Feel free to add more if statements to control more GPIOs with MQTT

  // If a message is received on the topic esp/output1, you check if the message is either "true" or "false".
  // Changes the output state according to the message
  if (String(topic) == "esp/output1") {
    Serial.print("Changing output to ");
    if(messageTemp == "true"){
      Serial.println("true");
      digitalWrite(OUTPUT_1, HIGH);
    }
    else if(messageTemp == "false"){
      Serial.println("false");
      digitalWrite(OUTPUT_1, LOW);
    }
  }
  else if (String(topic) == "esp/output2") {
    Serial.print("Changing output to ");
    if(messageTemp == "true"){
      Serial.println("true");
      digitalWrite(OUTPUT_2, HIGH);
    }
    else if(messageTemp == "false"){
      Serial.println("false");
      digitalWrite(OUTPUT_2, LOW);
    }
  }
}

Загрузка кода

После ввода всех необходимых данных вы можете загрузить код на плату.

Для загрузки кода на плату перейдите в Tools > Board и выберите ESP32 Dev module. Перейдите в Tools > Port и выберите COM-порт, к которому подключена ваша плата. Наконец, нажмите кнопку загрузки для загрузки кода на плату.

Кнопка загрузки в Arduino IDE

Примечание: на данный момент для платы T-Call ESP32 SIM800L нет отдельной конфигурации, но мы выбрали ESP32 Dev Module и она работает нормально.

Демонстрация

Откройте монитор порта на скорости 115200 бод и нажмите кнопку RST на плате.

Сначала модуль инициализируется, а затем пытается подключиться к интернету. Обратите внимание, что это может занять некоторое время (в некоторых случаях это заняло почти 1 минуту).

После подключения к интернету модуль подключится к вашему MQTT-брокеру.

ESP32 SIM800L подключение к интернету через SIM-карту демонстрация облачного MQTT-брокера

В этом примере новые показания датчиков публикуются каждые 30 секунд, но для целей тестирования вы можете использовать более короткий интервал.

Затем откройте браузер и введите домен вашего сервера с URL /ui. Вы должны увидеть индикаторы с последними показаниями датчиков и переключатели для управления выходами.

Демонстрация панели ESP32 SIM800L GPRS GSM облачный MQTT-брокер Node-RED Dashboard

Устранение неполадок

Если на данном этапе ваш модуль не может подключиться к интернету, это может быть вызвано одной из следующих причин:

  • Учётные данные APN могут быть неправильными;

  • Антенна может работать неправильно. В нашем случае нам пришлось заменить антенну;

  • Возможно, вам нужно выйти на улицу для лучшего покрытия сигнала;

  • Или вы можете подавать недостаточно тока на модуль. Если вы подключаете модуль к компьютеру через USB-хаб без внешнего источника питания, он может не обеспечить достаточный ток для работы.

Заключение

Мы надеемся, что вам понравился этот проект. По нашему мнению, плата T-Call SIM800 ESP32 может быть очень полезна для IoT-проектов, которые не имеют доступа к ближайшему маршрутизатору через Wi-Fi. Вы можете довольно легко подключить плату к интернету, используя тарифный план SIM-карты.

Вам также могут понравиться следующие проекты:

Узнайте больше об ESP32 с помощью наших ресурсов:

Спасибо за чтение.


Источник: randomnerdtutorials.com/esp32-cloud-mqtt-broker-sim800l/