esp8266_mqtt.ino 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. /*
  2. *******************************************************************************
  3. *
  4. * Purpose: Example of using the Arduino MqttClient with Esp8266WiFiClient
  5. * to show backup status of Freedombone
  6. * Project URL: https://github.com/monstrenyatko/ArduinoMqtt
  7. *
  8. *******************************************************************************
  9. * Copyright Oleg Kovalenko 2017, Bob Mottram 2019
  10. *
  11. * Distributed under the MIT License.
  12. * (See accompanying file LICENSE or copy at http://opensource.org/licenses/MIT)
  13. *******************************************************************************
  14. */
  15. #include <Arduino.h>
  16. #include <ESP8266WiFi.h>
  17. #include <string.h>
  18. // Enable MqttClient logs
  19. #define MQTT_LOG_ENABLED 1
  20. // Include library
  21. #include <MqttClient.h>
  22. #define LOG_PRINTFLN(fmt, ...) logfln(fmt, ##__VA_ARGS__)
  23. #define LOG_SIZE_MAX 128
  24. void logfln(const char *fmt, ...) {
  25. char buf[LOG_SIZE_MAX];
  26. va_list ap;
  27. va_start(ap, fmt);
  28. vsnprintf(buf, LOG_SIZE_MAX, fmt, ap);
  29. va_end(ap);
  30. Serial.println(buf);
  31. }
  32. #define LED_BACKUP_OK 13
  33. #define LED_BACKUP_FAIL 14
  34. #define HW_UART_SPEED 115200L
  35. #define MQTT_ID "fbone"
  36. const char* MQTT_TOPIC_SUB = "freedombone/admin";
  37. static MqttClient *mqtt = NULL;
  38. static WiFiClient network;
  39. // ============== Object to supply system functions ============================
  40. class System: public MqttClient::System {
  41. public:
  42. unsigned long millis() const {
  43. return ::millis();
  44. }
  45. void yield(void) {
  46. ::yield();
  47. }
  48. };
  49. // ============== Setup all objects ============================================
  50. void setup() {
  51. // Setup hardware serial for logging
  52. Serial.begin(HW_UART_SPEED);
  53. // setup backup status leds
  54. pinMode(LED_BACKUP_OK,OUTPUT);
  55. pinMode(LED_BACKUP_FAIL,OUTPUT);
  56. digitalWrite(LED_BACKUP_OK,LOW);
  57. digitalWrite(LED_BACKUP_FAIL,LOW);
  58. digitalWrite(LED_BUILTIN,LOW);
  59. // Setup WiFi network
  60. WiFi.mode(WIFI_STA);
  61. WiFi.hostname("ESP_" MQTT_ID);
  62. WiFi.begin("YourSSID", "YourPassword");
  63. LOG_PRINTFLN("\n");
  64. LOG_PRINTFLN("Connecting to WiFi");
  65. while (WiFi.status() != WL_CONNECTED) {
  66. delay(500);
  67. LOG_PRINTFLN(".");
  68. }
  69. LOG_PRINTFLN("Connected to WiFi");
  70. LOG_PRINTFLN("IP: %s", WiFi.localIP().toString().c_str());
  71. // Setup MqttClient
  72. MqttClient::System *mqttSystem = new System;
  73. MqttClient::Logger *mqttLogger = new MqttClient::LoggerImpl<HardwareSerial>(Serial);
  74. MqttClient::Network * mqttNetwork = new MqttClient::NetworkClientImpl<WiFiClient>(network, *mqttSystem);
  75. //// Make 128 bytes send buffer
  76. MqttClient::Buffer *mqttSendBuffer = new MqttClient::ArrayBuffer<128>();
  77. //// Make 128 bytes receive buffer
  78. MqttClient::Buffer *mqttRecvBuffer = new MqttClient::ArrayBuffer<128>();
  79. //// Allow up to 2 subscriptions simultaneously
  80. MqttClient::MessageHandlers *mqttMessageHandlers = new MqttClient::MessageHandlersImpl<2>();
  81. //// Configure client options
  82. MqttClient::Options mqttOptions;
  83. ////// Set command timeout to 10 seconds
  84. mqttOptions.commandTimeoutMs = 10000;
  85. //// Make client object
  86. mqtt = new MqttClient(
  87. mqttOptions, *mqttLogger, *mqttSystem, *mqttNetwork, *mqttSendBuffer,
  88. *mqttRecvBuffer, *mqttMessageHandlers
  89. );
  90. }
  91. // ============== Subscription callback ========================================
  92. void processMessage(MqttClient::MessageData& md) {
  93. const MqttClient::Message& msg = md.message;
  94. char payload[msg.payloadLen + 1];
  95. memcpy(payload, msg.payload, msg.payloadLen);
  96. payload[msg.payloadLen] = '\0';
  97. if (strstr(payload,"Backup")) {
  98. if (strstr(payload,"succeed")) {
  99. digitalWrite(LED_BACKUP_OK,HIGH);
  100. digitalWrite(LED_BACKUP_FAIL,LOW);
  101. }
  102. else {
  103. digitalWrite(LED_BACKUP_OK,LOW);
  104. digitalWrite(LED_BACKUP_FAIL,HIGH);
  105. }
  106. }
  107. LOG_PRINTFLN(
  108. "Message arrived: qos %d, retained %d, dup %d, packetid %d, payload:[%s]",
  109. msg.qos, msg.retained, msg.dup, msg.id, payload
  110. );
  111. }
  112. // ============== Main loop ====================================================
  113. void loop() {
  114. // Check connection status
  115. if (!mqtt->isConnected()) {
  116. // Close connection if exists
  117. network.stop();
  118. // Re-establish TCP connection with MQTT broker
  119. LOG_PRINTFLN("Connecting");
  120. network.connect("192.168.1.95", 1883);
  121. if (!network.connected()) {
  122. LOG_PRINTFLN("Can't establish the TCP connection");
  123. delay(5000);
  124. ESP.reset();
  125. }
  126. // Start new MQTT connection
  127. MqttClient::ConnectResult connectResult;
  128. // Connect
  129. {
  130. MQTTPacket_connectData options = MQTTPacket_connectData_initializer;
  131. options.MQTTVersion = 4;
  132. options.clientID.cstring = (char*)MQTT_ID;
  133. options.cleansession = true;
  134. options.keepAliveInterval = 15; // 15 seconds
  135. MqttClient::Error::type rc = mqtt->connect(options, connectResult);
  136. if (rc != MqttClient::Error::SUCCESS) {
  137. LOG_PRINTFLN("Connection error: %i", rc);
  138. return;
  139. }
  140. }
  141. {
  142. MqttClient::Error::type rc = mqtt->subscribe(
  143. MQTT_TOPIC_SUB, MqttClient::QOS0, processMessage
  144. );
  145. if (rc != MqttClient::Error::SUCCESS) {
  146. LOG_PRINTFLN("Subscribe error: %i", rc);
  147. LOG_PRINTFLN("Drop connection");
  148. mqtt->disconnect();
  149. return;
  150. }
  151. }
  152. } else {
  153. // Idle for 30 seconds
  154. mqtt->yield(30000L);
  155. }
  156. }