diff --git a/ble-client-01/ble-client-01/ble-client-01.ino b/ble-client-01/ble-client-01/ble-client-01.ino index ede4d7d..09baa74 100644 --- a/ble-client-01/ble-client-01/ble-client-01.ino +++ b/ble-client-01/ble-client-01/ble-client-01.ino @@ -13,7 +13,7 @@ // The characteristic of the remote service we are interested in. //static BLEUUID charUUID("beb5483e-36e1-4688-b7f5-ea07361b26a8"); -static BLEUUID serviceUUID("6e400001-b5a3-f393-e0a9-e50e24dcca9e"); +static BLEUUID serviceUUID("6e400001-b5a3-f393-e0a9-e50e24dcca9e"); static BLEUUID charReadUUID("6e400003-b5a3-f393-e0a9-e50e24dcca9e"); static BLEUUID charWriteUUID("6e400002-b5a3-f393-e0a9-e50e24dcca9e"); diff --git a/mqtt-client-ESP32/README.md b/mqtt-client-ESP32/README.md new file mode 100644 index 0000000..1c32c57 --- /dev/null +++ b/mqtt-client-ESP32/README.md @@ -0,0 +1,34 @@ +# ESP32 MQTT Client Examples + +In this example we provide sample code for TCP protocol connection to the MQTT Broker. For more documentation on using the ESP32 MQTT client, see the [Pubsubclient Documentation](https://pubsubclient.knolleary.net/). + +## Prerequisites + +* Arduino ESP32 development board management address: https://dl.espressif.com/dl/package_esp32_index.json + +## Arduino settings + +* Installing the ESP32 Board + +``` +Tools -> Board -> Boards Manager... -> -> Type ESP32 in Search field -> Install +``` + +* Installing the PubSubClient Library + +```bash +Sketch -> Include Library -> Manage Libraries... -> Type PubSubClient in Search field -> Install PubSubClient by Nick O’Leary +``` + +## Ino File + +* esp32_connect_mqtt.ino: ESP32 connects to the MQTT broker +* esp32_connect_mqtt_via_tls.ino: ESP32 connects to the MQTT broker via TLS +* esp32_DS18B20_temp_chart: ESP32 connects to the MQTT broker and uploads DS18B20 temperature sensor data, while displaying the temperature chart in real time +* esp32_DS18B20_sensor_via_tls.ino: ESP32 connects to the MQTT broker via TLS and uploads DS18B20 temperature sensor data +* esp32_soil_moisture_sensor_via_tls.ino: ESP32 connects to the MQTT broker via TLS and uploads soil moisture sensor data + +## TLS Config + +For TLS connection example code, the default includes DigiCert Global Root G2 (broker.emqx.io.crt) and DigiCert Global Root CA (emqxsl-ca.crt) ca_cert certificates, please modify according to the usage scenario. + diff --git a/mqtt-client-ESP32/README_ZH.md b/mqtt-client-ESP32/README_ZH.md new file mode 100644 index 0000000..2d4b17b --- /dev/null +++ b/mqtt-client-ESP32/README_ZH.md @@ -0,0 +1,37 @@ +# ESP32 MQTT 客户端使用示例 + +在本示例中我们提供了 TCP 协议连接到 MQTT Broker 示例代码。 有关 ESP32 MQTT 客户端更多使用文档,请参阅 [PubSubClient 官方文档](https://pubsubclient.knolleary.net/)。 + +## 前提 + +* Arduino ESP32 开发板管理地址: https://dl.espressif.com/dl/package_esp32_index.json + +## Arduino 设置 + +* 安装 ESP32 开发板 + +``` +点击 工具 -> 开发板 -> 开发板管理 -> 搜索 ESP32 -> 点击安装 +``` + +* 安装 PubSub client + +``` +项目 -> 加载库 -> 管理库... -> 搜索 PubSubClient -> 安装 PubSubClient by Nick O’Leary +``` + +## 文件 + +* esp32_connect_mqtt.ino: ESP32 连接到 MQTT 服务器 +* esp32_connect_mqtt_via_tls.ino: ESP32 通过 TLS 连接到 MQTT 服务器 +* esp32_DS18B20_temp_chart: ESP32 通过 MQTT 连接到服务器并上传 DS18B20 温度传感器数据,同时实时显示温度图表 +* esp32_DS18B20_sensor_via_tls.ino: ESP32 通过 TLS 连接到 MQTT 服务器并上传 DS18B20 温度传感器数据 +* esp32_soil_moisture_sensor_via_tls.ino: ESP32 通过 TLS 连接到 MQTT 服务器并上传土壤湿度传感器数据 + +## TLS 配置 + +对于 TLS 连接示例代码,默认包含了 DigiCert Global Root G2 (broker.emqx.io-ca.crt) 和 DigiCert Global Root CA (emqxsl-ca.crt) ca_cert 证书,请依据使用场景自行修改。 + + + + diff --git a/mqtt-client-ESP32/broker.emqx.io-ca.crt b/mqtt-client-ESP32/broker.emqx.io-ca.crt new file mode 100644 index 0000000..9ea2d0a --- /dev/null +++ b/mqtt-client-ESP32/broker.emqx.io-ca.crt @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH +MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI +2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx +1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ +q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz +tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ +vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV +5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY +1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4 +NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG +Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91 +8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe +pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl +MrY= +-----END CERTIFICATE----- \ No newline at end of file diff --git a/mqtt-client-ESP32/emqxsl-ca.crt b/mqtt-client-ESP32/emqxsl-ca.crt new file mode 100644 index 0000000..8f3aea9 --- /dev/null +++ b/mqtt-client-ESP32/emqxsl-ca.crt @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD +QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB +CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 +nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt +43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P +T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 +gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR +TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw +DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr +hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg +06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF +PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls +YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk +CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= +-----END CERTIFICATE----- \ No newline at end of file diff --git a/mqtt-client-ESP32/esp32_DS18B20_sensor_via_tls.ino b/mqtt-client-ESP32/esp32_DS18B20_sensor_via_tls.ino new file mode 100644 index 0000000..cbbf8a5 --- /dev/null +++ b/mqtt-client-ESP32/esp32_DS18B20_sensor_via_tls.ino @@ -0,0 +1,165 @@ +#include +#include +#include +#include +#include +#include + +// WiFi credentials +const char *ssid = "WIFI_SSID"; // Replace with your WiFi name +const char *password = "WIFI_PASSWORD"; // Replace with your WiFi password + +// MQTT Broker configuration +const char *mqtt_broker = "broker.emqx.io"; +const char *mqtt_topic = "emqx/esp32/telemetry"; +const char *mqtt_username = "emqx"; +const char *mqtt_password = "public"; +const int mqtt_port = 8883; + +// WiFi and MQTT client initialization +WiFiClientSecure esp_client; +PubSubClient mqtt_client(esp_client); + +// Root CA Certificate +// Load DigiCert Global Root G2, which is used by EMQX Public Broker: broker.emqx.io +const char *ca_cert = R"EOF( +-----BEGIN CERTIFICATE----- +MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH +MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI +2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx +1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ +q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz +tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ +vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV +5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY +1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4 +NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG +Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91 +8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe +pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl +MrY= +-----END CERTIFICATE----- +)EOF"; + +// Load DigiCert Global Root CA ca_cert, which is used by EMQX Cloud Serverless Deployment +/* +const char* ca_cert = R"EOF( +-----BEGIN CERTIFICATE----- +MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD +QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB +CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 +nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt +43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P +T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 +gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR +TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw +DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr +hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg +06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF +PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls +YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk +CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= +-----END CERTIFICATE----- +*/ + +// GPIO pin for DS18B20 +const int one_wire_bus = 25; + +// Temperature Sensor Setup +OneWire oneWire(one_wire_bus); +DallasTemperature sensors(&oneWire); +DeviceAddress inside_thermometer; + + +// Function Declarations +void connectToWiFi(); + +void connectToMQTT(); + +void initializeSensors(); + +float readTemperature(); + +void publishTemperature(float temperature); + +void setup() { + Serial.begin(115200); + connectToWiFi(); + connectToMQTT(); + initializeSensors(); +} + +void connectToWiFi() { + WiFi.begin(ssid, password); + Serial.print("Connecting to WiFi"); + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + } + Serial.println("\nConnected to WiFi"); +} + +void connectToMQTT() { + esp_client.setCACert(ca_cert); + mqtt_client.setServer(mqtt_broker, mqtt_port); + mqtt_client.setKeepAlive(60); + + while (!mqtt_client.connected()) { + String client_id = "esp32-client-" + String(WiFi.macAddress()); + Serial.printf("Connecting to MQTT Broker as %s...\n", client_id.c_str()); + if (mqtt_client.connect(client_id.c_str(), mqtt_username, mqtt_password)) { + Serial.println("Connected to MQTT Broker"); + } else { + Serial.print("Failed to connect, rc="); + Serial.print(mqtt_client.state()); + Serial.println(" Retrying in 5 seconds."); + delay(5000); + } + } +} + +void initializeSensors() { + sensors.begin(); + if (!sensors.getAddress(inside_thermometer, 0)) { + Serial.println("Unable to find address for Device 0"); + } + sensors.setResolution(inside_thermometer, 12); +} + +float readTemperature() { + sensors.requestTemperatures(); + return sensors.getTempC(inside_thermometer); +} + +void publishTemperature(float temperature) { + StaticJsonDocument<200> json_doc; + json_doc["temp"] = temperature; + + char json_buffer[512]; + serializeJson(json_doc, json_buffer); + mqtt_client.publish(mqtt_topic, json_buffer); +} + + +void loop() { + if (!mqtt_client.connected()) { + connectToMQTT(); + } + mqtt_client.loop(); + + float temp_celsius = readTemperature(); + publishTemperature(temp_celsius); + delay(60000); // Delay between readings +} \ No newline at end of file diff --git a/mqtt-client-ESP32/esp32_DS18B20_temp_chart/.gitignore b/mqtt-client-ESP32/esp32_DS18B20_temp_chart/.gitignore new file mode 100644 index 0000000..748ae87 --- /dev/null +++ b/mqtt-client-ESP32/esp32_DS18B20_temp_chart/.gitignore @@ -0,0 +1,9 @@ +*.pyc + +venv/ +.idea/ +__pycache__/ +article/ + +*.db + diff --git a/mqtt-client-ESP32/esp32_DS18B20_temp_chart/README.md b/mqtt-client-ESP32/esp32_DS18B20_temp_chart/README.md new file mode 100644 index 0000000..c2538a9 --- /dev/null +++ b/mqtt-client-ESP32/esp32_DS18B20_temp_chart/README.md @@ -0,0 +1,102 @@ +# ESP32 Temperature Monitoring and Web Application Project + +This project consists of two main parts: an ESP32 device sending temperature data using MQTT and a Flask-based web application that displays this data. + +![webui.png](_assets/webui.png) + +## Part 1: ESP32 Temperature Monitoring + +### Requirements + +- ESP32 Development Board +- DS18B20 Temperature Sensor +- Arduino IDE with ESP32 support +- Wi-Fi connection + +### Configuration and Setup + +1. **Install the Arduino IDE**: + Download and install from [Arduino website](https://www.arduino.cc/en/software). + +2. **Add ESP32 Support in Arduino IDE**: + Follow the instructions [here](https://randomnerdtutorials.com/installing-the-esp32-board-in-arduino-ide-windows-instructions/). + +3. **Install Required Libraries**: + In Arduino IDE, go to `Sketch` > `Include Library` > `Manage Libraries...` and install: + - `WiFi` + - `PubSubClient` + - `ArduinoJson` + - `OneWire` + - `DallasTemperature` + +4. **Configure Wi-Fi and MQTT Settings**: + Modify the provided ESP32 code in Arduino IDE with your Wi-Fi and MQTT details. + +5. **Connect the DS18B20 Sensor to ESP32**: + - DS18B20 VCC to ESP32 3.3V + - DS18B20 GND to ESP32 GND + - DS18B20 Data to ESP32 GPIO 25 + ![esp32](./_assets/esp32.png) + +6. **Upload the Code**: + Connect ESP32 to your computer, select the correct board and port in Arduino IDE, and upload. + +## Part 2: Flask Web Application + +### Requirements + +- Python 3.8 or later +- Virtual environment tool (e.g., `virtualenv`) + +### Local Setup + +1. **Clone the Repository**: + ``` + git clone [Repository URL] + cd [Repository Name] + ``` + +2. **Create a Virtual Environment**: + ``` + python -m venv venv + source venv/bin/activate # Windows: venv\Scripts\activate + ``` + +3. **Install Dependencies**: + ``` + pip install -r requirements.txt + ``` + +4. **Configure MQTT Settings in `app.py`**: + Modify MQTT configuration in `app.py`. + +5. **Run the Application**: + ``` + python app.py + ``` + Access at `http://localhost:8080`. + +### Deploying to Fly.io + +1. **Install Fly.io CLI**: + Follow instructions on [Fly.io documentation](https://fly.io/docs/getting-started/installing-flyctl/). + +2. **Login to Fly.io**: + ``` + flyctl auth login + ``` + +3. **Initialize Fly.io App**: + ``` + flyctl launch + ``` + +4. **Deploy the App**: + ``` + flyctl deploy + ``` + +5. **Verify Deployment**: + ``` + flyctl status + ``` diff --git a/mqtt-client-ESP32/esp32_DS18B20_temp_chart/README_ZH.md b/mqtt-client-ESP32/esp32_DS18B20_temp_chart/README_ZH.md new file mode 100644 index 0000000..b9a2f58 --- /dev/null +++ b/mqtt-client-ESP32/esp32_DS18B20_temp_chart/README_ZH.md @@ -0,0 +1,107 @@ +# ESP32 温度监控及 Web 应用项目 + +该项目包括两个主要部分:使用 MQTT 发送温度数据的 ESP32 设备和一个用于显示这些数据的基于 Flask 的 Web 应用程序。 + +![webui.png](_assets/webui.png) + +## 第 1 部分:ESP32 温度监控 + +### 系统要求 + +- ESP32 开发板 +- DS18B20 温度传感器 +- 支持 ESP32 的 Arduino IDE +- Wi-Fi 连接 + +### 配置和设置 + +1. **安装 Arduino IDE**: + 从 [Arduino 网站](https://www.arduino.cc/en/software) 下载并安装。 + +2. **在 Arduino IDE 中添加 ESP32 支持**: + 按照[这里](https://randomnerdtutorials.com/installing-the-esp32-board-in-arduino-ide-windows-instructions/)的说明操作。 + +3. **安装所需的库**: + 在 Arduino IDE 中,转到 `Sketch` > `Include Library` > `Manage Libraries...` 并安装: + - `WiFi` + - `PubSubClient` + - `ArduinoJson` + - `OneWire` + - `DallasTemperature` + +4. **配置 Wi-Fi 和 MQTT 设置**: + 在 Arduino IDE 中用您的 Wi-Fi 和 MQTT 详细信息修改提供的 ESP32 代码。 + +5. **将 DS18B20 传感器连接到 ESP32**: + - DS18B20 VCC 接 ESP32 3.3V + + - DS18B20 GND 接 ESP32 GND + + - DS18B20 数据接 ESP32 GPIO 25 + + ![esp32](./_assets/esp32.png) + + +6. **上传代码**: + 将 ESP32 连接到计算机,在 Arduino IDE 中选择正确的板和端口,然后上传。 + +## 第 2 部分:Flask Web 应用程序 + +### 系统要求 + +- Python 3.8 或更高版本 +- 虚拟环境工具(如 `virtualenv`) + +### 本地设置 + +1. **克隆仓库**: + ``` + git clone [仓库 URL] + cd [仓库名称] + ``` + +2. **创建虚拟环境**: + ``` + python -m venv venv + source venv/bin/activate # Windows: venv\Scripts\activate + ``` + +3. **安装依赖**: + ``` + pip install -r requirements.txt + ``` + +4. **在 `app.py` 中配置 MQTT 设置**: + 修改 `app.py` 中的 MQTT 配置。 + +5. **运行应用程序**: + ``` + python app.py + ``` + 在 `http://localhost:8080` 访问。 + +### 部署到 Fly.io + +1. **安装 Fly.io CLI**: + 按照 [Fly.io 文档](https://fly.io/docs/getting-started/installing-flyctl/) 中的说明进行操作。 + +2. **登录 Fly.io**: + + ``` + flyctl auth login + ``` + +3. **初始化 Fly.io 应用**: + ``` + flyctl launch + ``` + +4. **部署应用程序**: + ``` + flyctl deploy + ``` + +5. **验证部署**: + ``` + flyctl status + ``` diff --git a/mqtt-client-ESP32/esp32_DS18B20_temp_chart/_assets/esp32.png b/mqtt-client-ESP32/esp32_DS18B20_temp_chart/_assets/esp32.png new file mode 100644 index 0000000..572ff03 Binary files /dev/null and b/mqtt-client-ESP32/esp32_DS18B20_temp_chart/_assets/esp32.png differ diff --git a/mqtt-client-ESP32/esp32_DS18B20_temp_chart/_assets/fly.png b/mqtt-client-ESP32/esp32_DS18B20_temp_chart/_assets/fly.png new file mode 100644 index 0000000..ca2376a Binary files /dev/null and b/mqtt-client-ESP32/esp32_DS18B20_temp_chart/_assets/fly.png differ diff --git a/mqtt-client-ESP32/esp32_DS18B20_temp_chart/_assets/webui.png b/mqtt-client-ESP32/esp32_DS18B20_temp_chart/_assets/webui.png new file mode 100644 index 0000000..cf79ee4 Binary files /dev/null and b/mqtt-client-ESP32/esp32_DS18B20_temp_chart/_assets/webui.png differ diff --git a/mqtt-client-ESP32/esp32_DS18B20_temp_chart/esp32/README.md b/mqtt-client-ESP32/esp32_DS18B20_temp_chart/esp32/README.md new file mode 100644 index 0000000..bf89a63 --- /dev/null +++ b/mqtt-client-ESP32/esp32_DS18B20_temp_chart/esp32/README.md @@ -0,0 +1,48 @@ +# ESP32 Temperature Monitoring Project + +This project involves an ESP32 device using MQTT to send temperature data. The ESP32 is configured with a DS18B20 temperature sensor and connects to an MQTT broker. + +### Requirements + +- ESP32 Development Board +- DS18B20 Temperature Sensor +- Arduino IDE with ESP32 support +- Wi-Fi connection + +### Configuration and Setup + +1. **Install the Arduino IDE**: + Download and install the Arduino IDE from [Arduino website](https://www.arduino.cc/en/software). + +2. **Add ESP32 Support in Arduino IDE**: + Follow the instructions [here](https://randomnerdtutorials.com/installing-the-esp32-board-in-arduino-ide-windows-instructions/) to add ESP32 board support to the Arduino IDE. + +3. **Install Required Libraries**: + Open the Arduino IDE, go to `Sketch` > `Include Library` > `Manage Libraries...`. Install the following libraries: + - `WiFi` + - `PubSubClient` + - `ArduinoJson` + - `OneWire` + - `DallasTemperature` + +4. **Configure Wi-Fi and MQTT Settings**: + Open the provided ESP32 code in Arduino IDE. Modify the following lines with your Wi-Fi and MQTT broker details: + ```cpp + const char* wifi_ssid = "your_wifi_ssid"; + const char* wifi_password = "your_wifi_password"; + const char* mqtt_broker = "your_mqtt_broker"; + const char* mqtt_username = "your_mqtt_username"; + const char* mqtt_password = "your_mqtt_password"; + ``` + +5. **Connect the DS18B20 Sensor to ESP32**: + Connect the DS18B20 sensor to your ESP32: + - DS18B20 VCC to ESP32 3.3V + - DS18B20 GND to ESP32 GND + - DS18B20 Data to ESP32 GPIO 25 (or change `one_wire_bus` in the code if using a different pin) + +6. **Upload the Code**: + Connect the ESP32 to your computer, select the correct board and port in Arduino IDE, and upload the code. + +7. **Monitor the Temperature Data**: + Once the code is uploaded, the ESP32 will start sending temperature data to the MQTT broker. diff --git a/mqtt-client-ESP32/esp32_DS18B20_temp_chart/esp32/README_ZH.md b/mqtt-client-ESP32/esp32_DS18B20_temp_chart/esp32/README_ZH.md new file mode 100644 index 0000000..cac8b2b --- /dev/null +++ b/mqtt-client-ESP32/esp32_DS18B20_temp_chart/esp32/README_ZH.md @@ -0,0 +1,51 @@ +# ESP32 温度监控项目 + +此项目涉及使用 MQTT 发送温度数据的 ESP32 设备。ESP32 配置了 DS18B20 温度传感器,并连接到 MQTT 代理。 + +### 系统要求 + +- ESP32 开发板 +- DS18B20 温度传感器 +- Arduino IDE 并支持 ESP32 +- Wi-Fi 连接 + +### 配置和设置 + +1. **安装 Arduino IDE**: + 从 [Arduino 网站](https://www.arduino.cc/en/software) 下载并安装 Arduino IDE。 + +2. **在 Arduino IDE 中添加 ESP32 支持**: + 按照[这里](https://randomnerdtutorials.com/installing-the-esp32-board-in-arduino-ide-windows-instructions/)的说明,将 ESP32 板支持添加到 Arduino IDE。 + +3. **安装所需的库**: + 打开 Arduino IDE,转到 `Sketch` > `Include Library` > `Manage Libraries...`。安装以下库: + + - `WiFi` + - `PubSubClient` + - `ArduinoJson` + - `OneWire` + - `DallasTemperature` + +4. **配置 Wi-Fi 和 MQTT 设置**: + 在 Arduino IDE 中打开提供的 ESP32 代码。用您的 Wi-Fi 和 MQTT 代理详细信息修改以下行: + + ```cpp + const char* wifi_ssid = "your_wifi_ssid"; + const char* wifi_password = "your_wifi_password"; + const char* mqtt_broker = "your_mqtt_broker"; + const char* mqtt_username = "your_mqtt_username"; + const char* mqtt_password = "your_mqtt_password"; + ``` + +5. **将 DS18B20 传感器连接到 ESP32**: + 将 DS18B20 传感器连接到您的 ESP32: + + - DS18B20 VCC 接 ESP32 3.3V + - DS18B20 GND 接 ESP32 GND + - DS18B20 数据接 ESP32 GPIO 25(如果使用不 同的引脚,请更改代码中的 `one_wire_bus`) + +6. **上传代码**: + 将 ESP32 连接到您的计算机,在 Arduino IDE 中选择正确的板和端口,然后上传代码。 + +7. **监控温度数据**: + 代码上传后,ESP32 将开始向 MQTT 代理发送温度数据。 \ No newline at end of file diff --git a/mqtt-client-ESP32/esp32_DS18B20_temp_chart/esp32/water_temperature_sensor.ino b/mqtt-client-ESP32/esp32_DS18B20_temp_chart/esp32/water_temperature_sensor.ino new file mode 100644 index 0000000..cbbf8a5 --- /dev/null +++ b/mqtt-client-ESP32/esp32_DS18B20_temp_chart/esp32/water_temperature_sensor.ino @@ -0,0 +1,165 @@ +#include +#include +#include +#include +#include +#include + +// WiFi credentials +const char *ssid = "WIFI_SSID"; // Replace with your WiFi name +const char *password = "WIFI_PASSWORD"; // Replace with your WiFi password + +// MQTT Broker configuration +const char *mqtt_broker = "broker.emqx.io"; +const char *mqtt_topic = "emqx/esp32/telemetry"; +const char *mqtt_username = "emqx"; +const char *mqtt_password = "public"; +const int mqtt_port = 8883; + +// WiFi and MQTT client initialization +WiFiClientSecure esp_client; +PubSubClient mqtt_client(esp_client); + +// Root CA Certificate +// Load DigiCert Global Root G2, which is used by EMQX Public Broker: broker.emqx.io +const char *ca_cert = R"EOF( +-----BEGIN CERTIFICATE----- +MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH +MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI +2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx +1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ +q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz +tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ +vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV +5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY +1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4 +NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG +Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91 +8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe +pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl +MrY= +-----END CERTIFICATE----- +)EOF"; + +// Load DigiCert Global Root CA ca_cert, which is used by EMQX Cloud Serverless Deployment +/* +const char* ca_cert = R"EOF( +-----BEGIN CERTIFICATE----- +MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD +QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB +CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 +nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt +43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P +T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 +gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR +TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw +DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr +hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg +06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF +PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls +YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk +CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= +-----END CERTIFICATE----- +*/ + +// GPIO pin for DS18B20 +const int one_wire_bus = 25; + +// Temperature Sensor Setup +OneWire oneWire(one_wire_bus); +DallasTemperature sensors(&oneWire); +DeviceAddress inside_thermometer; + + +// Function Declarations +void connectToWiFi(); + +void connectToMQTT(); + +void initializeSensors(); + +float readTemperature(); + +void publishTemperature(float temperature); + +void setup() { + Serial.begin(115200); + connectToWiFi(); + connectToMQTT(); + initializeSensors(); +} + +void connectToWiFi() { + WiFi.begin(ssid, password); + Serial.print("Connecting to WiFi"); + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + } + Serial.println("\nConnected to WiFi"); +} + +void connectToMQTT() { + esp_client.setCACert(ca_cert); + mqtt_client.setServer(mqtt_broker, mqtt_port); + mqtt_client.setKeepAlive(60); + + while (!mqtt_client.connected()) { + String client_id = "esp32-client-" + String(WiFi.macAddress()); + Serial.printf("Connecting to MQTT Broker as %s...\n", client_id.c_str()); + if (mqtt_client.connect(client_id.c_str(), mqtt_username, mqtt_password)) { + Serial.println("Connected to MQTT Broker"); + } else { + Serial.print("Failed to connect, rc="); + Serial.print(mqtt_client.state()); + Serial.println(" Retrying in 5 seconds."); + delay(5000); + } + } +} + +void initializeSensors() { + sensors.begin(); + if (!sensors.getAddress(inside_thermometer, 0)) { + Serial.println("Unable to find address for Device 0"); + } + sensors.setResolution(inside_thermometer, 12); +} + +float readTemperature() { + sensors.requestTemperatures(); + return sensors.getTempC(inside_thermometer); +} + +void publishTemperature(float temperature) { + StaticJsonDocument<200> json_doc; + json_doc["temp"] = temperature; + + char json_buffer[512]; + serializeJson(json_doc, json_buffer); + mqtt_client.publish(mqtt_topic, json_buffer); +} + + +void loop() { + if (!mqtt_client.connected()) { + connectToMQTT(); + } + mqtt_client.loop(); + + float temp_celsius = readTemperature(); + publishTemperature(temp_celsius); + delay(60000); // Delay between readings +} \ No newline at end of file diff --git a/mqtt-client-ESP32/esp32_DS18B20_temp_chart/web/.dockerignore b/mqtt-client-ESP32/esp32_DS18B20_temp_chart/web/.dockerignore new file mode 100644 index 0000000..2616e55 --- /dev/null +++ b/mqtt-client-ESP32/esp32_DS18B20_temp_chart/web/.dockerignore @@ -0,0 +1,15 @@ +# flyctl launch added from .idea/.gitignore +# Default ignored files +.idea/ + +# flyctl launch added from venv/.gitignore +# created by virtualenv automatically +venv/**/* + +fly.toml + +./data/database.db + +./__pycache__/ + + diff --git a/mqtt-client-ESP32/esp32_DS18B20_temp_chart/web/Dockerfile b/mqtt-client-ESP32/esp32_DS18B20_temp_chart/web/Dockerfile new file mode 100644 index 0000000..49aa6cd --- /dev/null +++ b/mqtt-client-ESP32/esp32_DS18B20_temp_chart/web/Dockerfile @@ -0,0 +1,11 @@ +FROM python:3.8-slim-buster + +WORKDIR /app + +COPY . /app + +RUN pip install --no-cache-dir -r requirements.txt + +EXPOSE 8080 + +CMD ["python", "app.py"] diff --git a/mqtt-client-ESP32/esp32_DS18B20_temp_chart/web/FLY_README.md b/mqtt-client-ESP32/esp32_DS18B20_temp_chart/web/FLY_README.md new file mode 100644 index 0000000..75b8afd --- /dev/null +++ b/mqtt-client-ESP32/esp32_DS18B20_temp_chart/web/FLY_README.md @@ -0,0 +1,54 @@ +Based on the provided `fly.toml` configuration file, here's a deployment guide for your `esp32-temp-chart` application on Fly.io. This guide assumes that you have already developed a Flask application that is ready to be deployed. + +### Prerequisites + +1. **Fly.io Account**: Ensure you have a Fly.io account. If not, sign up at [Fly.io](https://fly.io/). +2. **Fly CLI**: Install the Fly CLI tool. Instructions can be found on the [Fly.io documentation](https://fly.io/docs/hands-on/installing/). +3. **Docker**: Your application must be containerized with Docker. Install Docker if it's not already installed. +4. **Local Application Code**: Have your Flask application code ready on your local machine. + +### Step-by-Step Deployment Guide + +#### 1. Initialize Your Fly.io Application + +- Navigate to your project directory in the terminal. +- Run `flyctl apps create esp32-temp-chart`. This command creates a new application on Fly.io with the name specified in your `fly.toml` file. + +#### 2. Configure the `fly.toml` File + +- Place your `fly.toml` file in the root of your project directory. +- Review the `fly.toml` file to ensure all configurations are correct. Particularly, check the `app` name, `primary_region`, and the `http_service` configurations. + +#### 3. Set Up Docker + +- Create a `Dockerfile` in your project root. This file should contain instructions to build a Docker image for your Flask application. +- Ensure that your application listens on the port specified in `fly.toml` (8080 in this case). + +#### 4. Test Your Docker Container Locally (Optional) + +- Build your Docker image: `docker build -t esp32-temp-chart .` +- Run your container locally to ensure it works: `docker run --rm -p 8080:8080 esp32-temp-chart` +- Test the local deployment by navigating to `http://localhost:8080`. + +#### 5. Deploy Your Application + +- From your project directory, run `flyctl deploy`. This command will build your application's Docker image and deploy it to Fly.io. +- Monitor the deployment process in your terminal to ensure it completes successfully. + +#### 6. Verify the Deployment + +- Once deployed, you can access your application using the URL provided by Fly.io. +- Test the `/ping` endpoint to ensure your application responds correctly. + +#### 7. Monitoring and Management + +- Use `flyctl logs` to view real-time logs from your application. +- Use `flyctl status` to check the status of your application. +- To scale your application, use `flyctl scale count `. + +### Additional Notes + +- The `[[mounts]]` section in `fly.toml` is used to persist data. Ensure the `source` and `destination` are correctly set for your application's data needs. +- The `[checks]` section defines health checks for your application. Adjust the `path`, `interval`, and `headers` as needed for your application's health endpoint. + +Remember, always test your application locally before deploying to ensure it's working as expected. If you encounter issues, the Fly.io documentation and community forums are great resources for troubleshooting. \ No newline at end of file diff --git a/mqtt-client-ESP32/esp32_DS18B20_temp_chart/web/README.md b/mqtt-client-ESP32/esp32_DS18B20_temp_chart/web/README.md new file mode 100644 index 0000000..123e9a2 --- /dev/null +++ b/mqtt-client-ESP32/esp32_DS18B20_temp_chart/web/README.md @@ -0,0 +1,68 @@ +# ESP32 Temperature Chart Web Application + +This Flask-based web application displays temperature data sent from an ESP32 device using MQTT. It includes a web interface for visualizing the temperature chart and an API to fetch temperature data. + +### Requirements + +- Python 3.8 or later +- Virtual environment tool (like `virtualenv` or `conda`) +- MQTT Broker credentials + +### Local Setup + +1. **Clone the Repository:** + ``` + git clone [Repository URL] + cd [Repository Name] + ``` + +2. **Create a Virtual Environment:** + ``` + python -m venv venv + source venv/bin/activate # On Windows: venv\Scripts\activate + ``` + +3. **Install Dependencies:** + ``` + pip install -r requirements.txt + ``` + +4. **Configure MQTT Settings in `app.py`:** + Modify the MQTT configuration settings in `app.py`: + - `MQTT_BROKER_URL` + - `MQTT_BROKER_PORT` + - `MQTT_USERNAME` + - `MQTT_PASSWORD` + - `MQTT_CLIENT_ID` + +5. **Run the Application:** + ``` + python app.py + ``` + Access the web interface at `http://localhost:8080`. + +### Deploying to Fly.io + +1. **Install Fly.io CLI:** + Follow the instructions on [Fly.io documentation](https://fly.io/docs/getting-started/installing-flyctl/). + +2. **Login to Fly.io:** + ``` + flyctl auth login + ``` + +3. **Initialize Fly.io App:** + ``` + flyctl launch + ``` + +4. **Deploy the App:** + ``` + flyctl deploy + ``` + +5. **Verify Deployment:** + ``` + flyctl status + ``` + Visit the URL provided by Fly.io to access your application. diff --git a/mqtt-client-ESP32/esp32_DS18B20_temp_chart/web/README_ZH.md b/mqtt-client-ESP32/esp32_DS18B20_temp_chart/web/README_ZH.md new file mode 100644 index 0000000..afebf1d --- /dev/null +++ b/mqtt-client-ESP32/esp32_DS18B20_temp_chart/web/README_ZH.md @@ -0,0 +1,79 @@ +# ESP32 温度图表 Web 应用程序 + +这个基于 Flask 的 Web 应用程序用于显示通过 MQTT 从 ESP32 设备发送的温度数据。它包括一个用于可视化温度图表的 Web 界面和一个获取温度数据的 API。 + +### 系统要求 + +- Python 3.8 或更高版本 +- 虚拟环境工具(如 `virtualenv` 或 `conda`) +- MQTT 代理凭证 + +### 本地设置 + +1. **克隆仓库:** + + ``` + git clone [仓库 URL] + cd [仓库名称] + ``` + +2. **创建虚拟环境:** + + ``` + python -m venv venv + source venv/bin/activate # Windows 上: venv\Scripts\activate + ``` + +3. **安装依赖:** + + ``` + pip install -r requirements.txt + ``` + +4. **在 `app.py` 中配置 MQTT 设置:** + 修改 `app.py` 中的 MQTT 配置设置: + + - `MQTT_BROKER_URL` + - `MQTT_BROKER_PORT` + - `MQTT_USERNAME` + - `MQTT_PASSWORD` + - `MQTT_CLIENT_ID` + +5. **运行应用程序:** + + ``` + python app.py + ``` + + 在 `http://localhost:8080` 访问 Web 界面。 + +### 部署到 Fly.io + +1. **安装 Fly.io CLI:** + 按照 [Fly.io 文档](https://fly.io/docs/getting-started/installing-flyctl/) 中的说明进行操作。 + +2. **登录 Fly.io:** + + ``` + flyctl auth login + ``` + +3. **初始化 Fly.io 应用:** + + ``` + flyctl launch + ``` + +4. **部署应用程序:** + + ``` + flyctl deploy + ``` + +5. **验证部署:** + + ``` + flyctl status + ``` + + 访问 Fly.io 提供的 URL 以访问您的应用程序。 diff --git a/mqtt-client-ESP32/esp32_DS18B20_temp_chart/web/__init__.py b/mqtt-client-ESP32/esp32_DS18B20_temp_chart/web/__init__.py new file mode 100644 index 0000000..57d631c --- /dev/null +++ b/mqtt-client-ESP32/esp32_DS18B20_temp_chart/web/__init__.py @@ -0,0 +1 @@ +# coding: utf-8 diff --git a/mqtt-client-ESP32/esp32_DS18B20_temp_chart/web/app.py b/mqtt-client-ESP32/esp32_DS18B20_temp_chart/web/app.py new file mode 100644 index 0000000..4352a5b --- /dev/null +++ b/mqtt-client-ESP32/esp32_DS18B20_temp_chart/web/app.py @@ -0,0 +1,143 @@ +import datetime +import json +import logging +import os +import ssl +import random +import sqlite3 +from typing import Dict, Any, List, Optional + +import requests +from flask import Flask, jsonify, render_template, g, request +from flask_mqtt import Mqtt + + +# Configure logging +logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') + +app = Flask(__name__) + +DEBUG: bool = False +MQTT_CLIENT: Optional[Mqtt] = None +DATABASE: str = './data/database.db' +SLACK_WEBHOOK: str = 'https://hooks.slack.com/services' +MQTT_TOPIC: str = 'emqx/esp32/telemetry' +app.config['MQTT_BROKER_URL'] = 'broker.emqx.io' +app.config['MQTT_BROKER_PORT'] = 8883 +app.config['MQTT_USERNAME'] = '' +app.config['MQTT_PASSWORD'] = '' +app.config['MQTT_KEEPALIVE'] = 60 +app.config['MQTT_CLIENT_ID'] = f"flask-mqtt-{random.randint(0, 100000)}" +app.config['MQTT_TLS_ENABLED'] = True +# Load DigiCert Global Root G2, which is used by EMQX Public Broker: broker.emqx.io +app.config['MQTT_TLS_CA_CERTS'] = './certs/broker.emqx.io-ca.crt' +# Load DigiCert Global Root CA ca_cert, which is used by EMQX Cloud Serverless Deployment +# app.config['MQTT_TLS_CA_CERTS'] = './certs/emqxsl-ca.crt' +app.config['MQTT_TLS_VERSION'] = ssl.PROTOCOL_TLSv1_2 +app.config['MQTT_RECONNECT_DELAY'] = 3 + + +def init_mqtt(flask_app: Flask) -> None: + global MQTT_CLIENT + MQTT_CLIENT = Mqtt(flask_app) + + @MQTT_CLIENT.on_connect() + def handle_connect(client, userdata, flags, rc): + client_id = flask_app.config['MQTT_CLIENT_ID'] + mqtt_broker = flask_app.config['MQTT_BROKER_URL'] + if rc == 0: + logging.info(f"Client {client_id} connected to {mqtt_broker}!") + MQTT_CLIENT.subscribe(MQTT_TOPIC) + else: + logging.error(f"Failed to connect, return code {rc}") + + @MQTT_CLIENT.on_message() + def handle_mqtt_message(client, userdata, message) -> None: + try: + payload: Dict[str, Any] = json.loads(message.payload.decode()) + temp: float = payload['temp'] + except (json.JSONDecodeError, KeyError, TypeError) as e: + logging.error(f"Error processing message: {e}") + return + if temp > 25: + logging.warning("Temperature too high, sending alert to Slack!") + requests.post( + SLACK_WEBHOOK, + data=json.dumps({'text': f"Temperature too high: {temp}"}), + headers={'Content-Type': 'application/json'} + ) + uptime: str = datetime.datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S") + logging.info(f"Received message: {temp} at {uptime}") + with app.app_context(): + db = get_db() + db.execute( + "INSERT INTO temperature_data (uptime, temp) VALUES (?, ?)", + (uptime, temp) + ) + db.commit() + + +def get_db() -> sqlite3.Connection: + db: sqlite3.Connection = getattr(g, '_database', None) + if db is None: + db = g._database = sqlite3.connect(DATABASE) + return db + + +@app.teardown_appcontext +def close_connection(exception) -> None: + db = getattr(g, '_database', None) + if db is not None: + db.close() + + +@app.route('/') +def index(): + redirect_url = request.url_root + 'temp_chart' + return f"Go to Temperature chart 😁" + + +@app.route('/ping') +def ping(): + return "pong" + + +@app.route('/temp_chart') +def chart(): + return render_template('chart.html') + + +@app.route('/data') +def data(): + hours: int = int(request.args.get('hours', 1, type=int)) + if hours > 24 or hours < 1: + hours = 1 + + db = get_db() + min_time: datetime.datetime = datetime.datetime.utcnow() - datetime.timedelta(hours=hours) + cursor = db.execute( + "SELECT * FROM temperature_data WHERE uptime > ?", + (min_time.strftime("%Y-%m-%d %H:%M:%S"),) + ) + rows = cursor.fetchall() + times: List[str] = [row[1] for row in rows] + temperatures: List[float] = [row[2] for row in rows] + return jsonify({"times": times, "temperatures": temperatures}) + + +if __name__ == '__main__': + + with app.app_context(): + d = get_db() + d.execute( + "CREATE TABLE IF NOT EXISTS " + "temperature_data (id INTEGER PRIMARY KEY, uptime TEXT, temp REAL)" + ) + d.commit() + if DEBUG: + if os.environ.get('WERKZEUG_RUN_MAIN') == 'true': + init_mqtt(app) + else: + init_mqtt(app) + + app.run(host='0.0.0.0', debug=DEBUG, port=8080) diff --git a/mqtt-client-ESP32/esp32_DS18B20_temp_chart/web/certs/broker.emqx.io-ca.crt b/mqtt-client-ESP32/esp32_DS18B20_temp_chart/web/certs/broker.emqx.io-ca.crt new file mode 100644 index 0000000..9ea2d0a --- /dev/null +++ b/mqtt-client-ESP32/esp32_DS18B20_temp_chart/web/certs/broker.emqx.io-ca.crt @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH +MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI +2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx +1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ +q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz +tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ +vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV +5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY +1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4 +NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG +Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91 +8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe +pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl +MrY= +-----END CERTIFICATE----- \ No newline at end of file diff --git a/mqtt-client-ESP32/esp32_DS18B20_temp_chart/web/certs/emqxsl-ca.crt b/mqtt-client-ESP32/esp32_DS18B20_temp_chart/web/certs/emqxsl-ca.crt new file mode 100644 index 0000000..8f3aea9 --- /dev/null +++ b/mqtt-client-ESP32/esp32_DS18B20_temp_chart/web/certs/emqxsl-ca.crt @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD +QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB +CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 +nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt +43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P +T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 +gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR +TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw +DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr +hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg +06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF +PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls +YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk +CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= +-----END CERTIFICATE----- \ No newline at end of file diff --git a/mqtt-client-ESP32/esp32_DS18B20_temp_chart/web/fly.toml b/mqtt-client-ESP32/esp32_DS18B20_temp_chart/web/fly.toml new file mode 100644 index 0000000..ba5b2f1 --- /dev/null +++ b/mqtt-client-ESP32/esp32_DS18B20_temp_chart/web/fly.toml @@ -0,0 +1,34 @@ +# fly.toml app configuration file generated for esp32-temp-chart on 2023-08-18T10:04:07+08:00 +# +# See https://fly.io/docs/reference/configuration/ for information about how to use this file. +# + +app = "esp32-temp-chart" +primary_region = "sin" + +[build] + +[[mounts]] + source = "esp32tempchart" + destination = "/app/data" + +[http_service] + internal_port = 8080 + force_https = true + auto_stop_machines = false + auto_start_machines = true + min_machines_running = 1 + processes = ["app"] + +[checks] + [checks.name_of_your_http_check] + port = 8080 + type = "http" + interval = "15s" + timeout = "10s" + grace_period = "30s" + method = "get" + path = "/ping" + [checks.name_of_your_http_check.headers] + Authorization = "super-secret" + Content-Type = "application/json" diff --git a/mqtt-client-ESP32/esp32_DS18B20_temp_chart/web/requirements.txt b/mqtt-client-ESP32/esp32_DS18B20_temp_chart/web/requirements.txt new file mode 100644 index 0000000..cfbcf3d --- /dev/null +++ b/mqtt-client-ESP32/esp32_DS18B20_temp_chart/web/requirements.txt @@ -0,0 +1,3 @@ +Flask==2.3.2 +Flask-MQTT==1.1.1 +requests==2.31.0 \ No newline at end of file diff --git a/mqtt-client-ESP32/esp32_DS18B20_temp_chart/web/templates/chart.html b/mqtt-client-ESP32/esp32_DS18B20_temp_chart/web/templates/chart.html new file mode 100644 index 0000000..76f3493 --- /dev/null +++ b/mqtt-client-ESP32/esp32_DS18B20_temp_chart/web/templates/chart.html @@ -0,0 +1,64 @@ + + + + + Temperature Chart + + + + + + + + + + + diff --git a/mqtt-client-ESP32/esp32_connect_mqtt.ino/esp32_connect_mqtt.ino.ino b/mqtt-client-ESP32/esp32_connect_mqtt.ino/esp32_connect_mqtt.ino.ino new file mode 100644 index 0000000..382e4a7 --- /dev/null +++ b/mqtt-client-ESP32/esp32_connect_mqtt.ino/esp32_connect_mqtt.ino.ino @@ -0,0 +1,101 @@ +#include +#include + +// WiFi Credentials +const char *ssid = "rehome"; // Replace with your WiFi name +const char *password = "Ruihong123"; // Replace with your WiFi password + +// MQTT Broker Settings +const char *mqtt_broker = "mqtt.fileview123.com"; +const char *mqtt_topic = "/device/esp8266/+"; +const char *mqtt_username = "admin"; +const char *mqtt_password = "publish452131wW452131wW$"; +const int mqtt_port = 1883; +const char *mqtt_topic_publish = "/device/esp8266/status"; // MQTT topic publish + +WiFiClient espClient; +PubSubClient mqtt_client(espClient); + +// Function Declarations +void connectToWiFi(); + +void connectToMQTT(); + +void mqttCallback(char *mqtt_topic, byte *payload, unsigned int length); + +void setup() { + Serial.begin(115200); + connectToWiFi(); + mqtt_client.setServer(mqtt_broker, mqtt_port); + mqtt_client.setKeepAlive(60); + mqtt_client.setCallback(mqttCallback); // Corrected callback function name + connectToMQTT(); +} + +void connectToWiFi() { + delay(10); + Serial.println(); + Serial.print("正在连接: "); + Serial.println(ssid); + WiFi.begin(ssid, password); + Serial.print("Connecting to WiFi"); + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + } + Serial.println("\nConnected to WiFi"); + Serial.println(""); + Serial.println("WiFi 连接成功"); + Serial.println("IP 地址: "); + Serial.println(WiFi.localIP()); +} + +void connectToMQTT() { + while (!mqtt_client.connected()) { + Serial.print("尝试 MQTT 连接..."); + String client_id = "esp32-client-" + String(WiFi.macAddress()); + Serial.printf("Connecting to MQTT Broker as %s.....\n", client_id.c_str()); + if (mqtt_client.connect(client_id.c_str(), mqtt_username, mqtt_password)) { + Serial.println("连接成功"); + Serial.println("Connected to MQTT broker"); + mqtt_client.subscribe(mqtt_topic); + mqtt_client.publish(mqtt_topic_publish, "Hi EMQX I'm ESP32 ^^"); // Publish message upon successful connection + } else { + Serial.print("Failed, rc="); + Serial.print(mqtt_client.state()); + Serial.println(" try again in 5 seconds"); + delay(5000); + } + } +} + +void mqttCallback(char *mqtt_topic, byte *payload, unsigned int length) { + Serial.print("Message received on mqtt_topic: "); + Serial.println(mqtt_topic); + Serial.print("Message: "); + for (unsigned int i = 0; i < length; i++) { + Serial.print((char) payload[i]); + } + Serial.println("\n-----------------------"); +} + + +void loop() { + if(WiFi.status() != WL_CONNECTED){ + connectToWiFi(); + } + if (!mqtt_client.connected()) { + connectToMQTT(); + } + mqtt_client.loop(); + // 发布消息示例 + static unsigned long lastMsg = 0; + if (millis() - lastMsg > 5000) { + lastMsg = millis(); + + String message = "Hello from esp32 - esp32_connect_mqtt.ino_" + String(millis()); + mqtt_client.publish(mqtt_topic_publish, message.c_str()); + + Serial.println("消息已发布: " + message); + } +} \ No newline at end of file diff --git a/mqtt-client-ESP32/esp32_connect_mqtt_via_tls.ino b/mqtt-client-ESP32/esp32_connect_mqtt_via_tls.ino new file mode 100644 index 0000000..4b6f54c --- /dev/null +++ b/mqtt-client-ESP32/esp32_connect_mqtt_via_tls.ino @@ -0,0 +1,139 @@ +#include +#include +#include + +// WiFi credentials +const char *ssid = "WIFI_SSID"; // Replace with your WiFi name +const char *password = "WIFI_PASSWORD"; // Replace with your WiFi password + +// MQTT Broker settings +const char *mqtt_broker = "broker.emqx.io"; +const char *mqtt_topic = "emqx/esp32"; +const char *mqtt_username = "emqx"; +const char *mqtt_password = "public"; +const int mqtt_port = 8883; + +// WiFi and MQTT client initialization +WiFiClientSecure esp_client; +PubSubClient mqtt_client(esp_client); + +// Root CA Certificate +// Load DigiCert Global Root G2, which is used by EMQX Public Broker: broker.emqx.io +const char *ca_cert = R"EOF( +-----BEGIN CERTIFICATE----- +MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH +MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI +2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx +1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ +q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz +tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ +vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV +5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY +1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4 +NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG +Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91 +8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe +pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl +MrY= +-----END CERTIFICATE----- +)EOF"; + +// Load DigiCert Global Root CA ca_cert, which is used by EMQX Cloud Serverless Deployment +/* +const char* ca_cert = R"EOF( +-----BEGIN CERTIFICATE----- +MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD +QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB +CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 +nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt +43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P +T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 +gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR +TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw +DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr +hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg +06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF +PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls +YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk +CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= +-----END CERTIFICATE----- +*/ + + +// Function Declarations +void connectToWiFi(); + +void connectToMQTT(); + +void mqttCallback(char *topic, byte *payload, unsigned int length); + + +void setup() { + Serial.begin(115200); + connectToWiFi(); + + // Set Root CA certificate + esp_client.setCACert(ca_cert); + + mqtt_client.setServer(mqtt_broker, mqtt_port); + mqtt_client.setKeepAlive(60); + mqtt_client.setCallback(mqttCallback); + connectToMQTT(); +} + +void connectToWiFi() { + WiFi.begin(ssid, password); + Serial.print("Connecting to WiFi"); + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + } + Serial.println("\nConnected to WiFi"); +} + +void connectToMQTT() { + while (!mqtt_client.connected()) { + String client_id = "esp32-client-" + String(WiFi.macAddress()); + Serial.printf("Connecting to MQTT Broker as %s...\n", client_id.c_str()); + if (mqtt_client.connect(client_id.c_str(), mqtt_username, mqtt_password)) { + Serial.println("Connected to MQTT broker"); + mqtt_client.subscribe(mqtt_topic); + mqtt_client.publish(mqtt_topic, "Hi EMQX I'm ESP32 ^^"); // Publish message upon connection + } else { + Serial.print("Failed to connect to MQTT broker, rc="); + Serial.print(mqtt_client.state()); + Serial.println(" Retrying in 5 seconds."); + delay(5000); + } + } +} + +void mqttCallback(char *topic, byte *payload, unsigned int length) { + Serial.print("Message received on topic: "); + Serial.println(topic); + Serial.print("Message: "); + for (unsigned int i = 0; i < length; i++) { + Serial.print((char) payload[i]); + } + Serial.println("\n-----------------------"); +} + + +void loop() { + if (!mqtt_client.connected()) { + connectToMQTT(); + } + mqtt_client.loop(); +} \ No newline at end of file diff --git a/mqtt-client-ESP32/esp32_soil_moisture_sensor_via_tls.ino b/mqtt-client-ESP32/esp32_soil_moisture_sensor_via_tls.ino new file mode 100644 index 0000000..725868c --- /dev/null +++ b/mqtt-client-ESP32/esp32_soil_moisture_sensor_via_tls.ino @@ -0,0 +1,144 @@ +#include +#include +#include +#include + +// WiFi credentials +const char *ssid = "WIFI_SSID"; // Replace with your WiFi name +const char *password = "WIFI_PASSWORD"; // Replace with your WiFi password + +// MQTT Broker configuration +const char *mqtt_broker = "broker.emqx.io"; +const char *mqtt_topic = "emqx/esp32/moisture"; +const char *mqtt_username = "emqx"; +const char *mqtt_password = "public"; +const int mqtt_port = 8883; + +// WiFi and MQTT client initialization +WiFiClientSecure esp_client; +PubSubClient mqtt_client(esp_client); + +// GPIO pin for Soil Moisture, ESP32 pin GPIO36 (ADC0) that connects to AOUT pin of moisture sensor +#define sensorPIN 36 + +// Root CA Certificate +// Load DigiCert Global Root G2, which is used by EMQX Public Broker: broker.emqx.io +const char *ca_cert = R"EOF( +-----BEGIN CERTIFICATE----- +MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH +MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI +2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx +1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ +q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz +tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ +vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV +5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY +1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4 +NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG +Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91 +8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe +pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl +MrY= +-----END CERTIFICATE----- +)EOF"; + +// Load DigiCert Global Root CA ca_cert, which is used by EMQX Cloud Serverless Deployment +/* +const char* ca_cert = R"EOF( +-----BEGIN CERTIFICATE----- +MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD +QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB +CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 +nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt +43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P +T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 +gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR +TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw +DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr +hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg +06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF +PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls +YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk +CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= +-----END CERTIFICATE----- +*/ + + +// Function Declarations +void connectToWiFi(); + +void connectToMQTT(); + +void initializeSensors(); + +void publishSensorData(); + +void setup() { + Serial.begin(115200); + connectToWiFi(); + connectToMQTT(); +} + +void connectToWiFi() { + WiFi.begin(ssid, password); + Serial.print("Connecting to WiFi"); + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + } + Serial.println("\nConnected to WiFi"); +} + +void connectToMQTT() { + esp_client.setCACert(ca_cert); + mqtt_client.setServer(mqtt_broker, mqtt_port); + mqtt_client.setKeepAlive(60); + + while (!mqtt_client.connected()) { + String client_id = "esp32-client-" + String(WiFi.macAddress()); + Serial.printf("Connecting to MQTT Broker as %s...\n", client_id.c_str()); + if (mqtt_client.connect(client_id.c_str(), mqtt_username, mqtt_password)) { + Serial.println("Connected to MQTT Broker"); + } else { + Serial.print("Failed to connect, rc="); + Serial.print(mqtt_client.state()); + Serial.println(" Retrying in 5 seconds."); + delay(5000); + } + } +} + + +void publishSensorData() { + StaticJsonDocument<200> json_doc; + int moistureValue = analogRead(sensorPIN); + json_doc["moisture"] = moistureValue; + + char json_buffer[512]; + serializeJson(json_doc, json_buffer); + mqtt_client.publish(mqtt_topic, json_buffer); + Serial.printf("Published to %s: %d\n", mqtt_topic, moistureValue); +} + + +void loop() { + if (!mqtt_client.connected()) { + connectToMQTT(); + } + mqtt_client.loop(); + + publishSensorData(); + delay(60000); // Delay between readings +} \ No newline at end of file diff --git a/mqtt-client-ESP8266/README.md b/mqtt-client-ESP8266/README.md new file mode 100644 index 0000000..0821bc2 --- /dev/null +++ b/mqtt-client-ESP8266/README.md @@ -0,0 +1,23 @@ +# ESP8266 MQTT Client Examples +In this example we provide sample code for TCP protocol connection to the MQTT Broker. +For more documentation on using the ESP8266 MQTT client, see the [ESP8266 pubsubclient Documentation](https://pubsubclient.knolleary.net/). + +## Prerequisites +* Arduino ESP8266 development board management address: http://arduino.esp8266.com/stable/package_esp8266com_index.json + + +## Installation +```bash +Sketch -> Include Library -> Manage Libraries... -> Type PubSub in Search field -> Install +``` + +## Ino File +* esp_connect_mqtt.ino: ESP8266 connects to the MQTT broker +* esp_mqtt_led.ino: ESP8266 control led +* temp_hum.ino: getting started with the ESP8266 and DHT11 sensor +* esp_mqtt_moisture.ino: Soil Moisture Sensor example + + +## Other +* [ESP8266 connects to the free public MQTT broker](https://www.emqx.io/blog/esp8266-connects-to-the-public-mqtt-broker) +* [Upload sensor data to MQTT cloud service via ESP8266](https://www.emqx.io/blog/upload-sensor-data-to-mqtt-cloud-service-via-nodemcu-esp8266) \ No newline at end of file diff --git a/mqtt-client-ESP8266/README_ZH.md b/mqtt-client-ESP8266/README_ZH.md new file mode 100644 index 0000000..e1d4af5 --- /dev/null +++ b/mqtt-client-ESP8266/README_ZH.md @@ -0,0 +1,26 @@ +# ESP8266 MQTT 客户端使用示例 +在本示例中我们提供了 TCP 协议连接到 MQTT Broker 示例代码。 +有关 ESP8266 MQTT 客户端更多使用文档,请参阅 [ESP8266 MQTT 官方文档](https://pubsubclient.knolleary.net/)。 + + +## 前提 +* Arduino ESP8266 开发板管理地址: http://arduino.esp8266.com/stable/package_esp8266com_index.json + + +## 安装 +``` +Sketch -> Include Library -> Manage Libraries... -> Type PubSub in Search field -> Install +``` + +## 文件 +* esp_connect_mqtt.ino: ESP8266 连接到 MQTT 服务器 +* esp_mqtt_led.ino: ESP8266 远程控制 LED 灯 +* temp_hum.ino: ESP8266 上报温湿度数据 + +## 参阅 +* [ESP8266 连接到 MQTT 服务器](https://www.emqx.cn/blog/esp8266-connects-to-the-public-mqtt-broker) +* [ESP8266 远程控制 LED 灯](https://www.emqx.cn/blog/esp8266_mqtt_led) +* [ESP8266 上报温湿度数据](https://www.emqx.cn/blog/upload-sensor-data-to-mqtt-cloud-service-via-nodemcu-esp8266) + + + diff --git a/mqtt-client-ESP8266/broker.emqx.io-ca.crt b/mqtt-client-ESP8266/broker.emqx.io-ca.crt new file mode 100644 index 0000000..9ea2d0a --- /dev/null +++ b/mqtt-client-ESP8266/broker.emqx.io-ca.crt @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH +MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI +2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx +1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ +q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz +tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ +vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV +5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY +1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4 +NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG +Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91 +8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe +pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl +MrY= +-----END CERTIFICATE----- \ No newline at end of file diff --git a/mqtt-client-ESP8266/emqxsl-ca.crt b/mqtt-client-ESP8266/emqxsl-ca.crt new file mode 100644 index 0000000..8f3aea9 --- /dev/null +++ b/mqtt-client-ESP8266/emqxsl-ca.crt @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD +QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB +CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 +nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt +43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P +T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 +gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR +TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw +DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr +hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg +06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF +PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls +YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk +CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= +-----END CERTIFICATE----- \ No newline at end of file diff --git a/mqtt-client-ESP8266/esp8266_connect_mqtt_via_tls/esp8266_connect_mqtt_via_tls.ino b/mqtt-client-ESP8266/esp8266_connect_mqtt_via_tls/esp8266_connect_mqtt_via_tls.ino new file mode 100644 index 0000000..c6f2347 --- /dev/null +++ b/mqtt-client-ESP8266/esp8266_connect_mqtt_via_tls/esp8266_connect_mqtt_via_tls.ino @@ -0,0 +1,166 @@ +#include +#include +#include + +// WiFi credentials +const char *ssid = "WIFI_SSID"; // Replace with your WiFi name +const char *password = "WIFI_PASSWORD"; // Replace with your WiFi password + +// MQTT Broker settings +const int mqtt_port = 8883; // MQTT port (TLS) +const char *mqtt_broker = "broker.emqx.io"; // EMQX broker endpoint +const char *mqtt_topic = "emqx/esp8266"; // MQTT topic +const char *mqtt_username = "emqx"; // MQTT username for authentication +const char *mqtt_password = "public"; // MQTT password for authentication + +// NTP Server settings +const char *ntp_server = "pool.ntp.org"; // Default NTP server +// const char* ntp_server = "cn.pool.ntp.org"; // Recommended NTP server for users in China +const long gmt_offset_sec = 0; // GMT offset in seconds (adjust for your time zone) +const int daylight_offset_sec = 0; // Daylight saving time offset in seconds + +// WiFi and MQTT client initialization +BearSSL::WiFiClientSecure espClient; +PubSubClient mqtt_client(espClient); + +// SSL certificate for MQTT broker +// Load DigiCert Global Root G2, which is used by EMQX Public Broker: broker.emqx.io +static const char ca_cert[] +PROGMEM = R"EOF( +-----BEGIN CERTIFICATE----- +MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH +MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI +2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx +1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ +q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz +tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ +vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV +5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY +1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4 +NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG +Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91 +8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe +pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl +MrY= +-----END CERTIFICATE----- +)EOF"; + +// Load DigiCert Global Root CA ca_cert, which is used by EMQX Cloud Serverless Deployment +/* +static const char ca_cert[] PROGMEM = R"EOF( +-----BEGIN CERTIFICATE----- +MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD +QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB +CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 +nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt +43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P +T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 +gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR +TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw +DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr +hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg +06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF +PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls +YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk +CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= +-----END CERTIFICATE----- +)EOF"; +*/ + + +// Function declarations +void connectToWiFi(); + +void connectToMQTT(); + +void syncTime(); + +void mqttCallback(char *topic, byte *payload, unsigned int length); + + +void setup() { + Serial.begin(115200); + connectToWiFi(); + syncTime(); // X.509 validation requires synchronization time + mqtt_client.setServer(mqtt_broker, mqtt_port); + mqtt_client.setCallback(mqttCallback); + connectToMQTT(); +} + +void connectToWiFi() { + WiFi.begin(ssid, password); + while (WiFi.status() != WL_CONNECTED) { + delay(1000); + Serial.println("Connecting to WiFi..."); + } + Serial.println("Connected to WiFi"); +} + +void syncTime() { + configTime(gmt_offset_sec, daylight_offset_sec, ntp_server); + Serial.print("Waiting for NTP time sync: "); + while (time(nullptr) < 8 * 3600 * 2) { + delay(1000); + Serial.print("."); + } + Serial.println("Time synchronized"); + struct tm timeinfo; + if (getLocalTime(&timeinfo)) { + Serial.print("Current time: "); + Serial.println(asctime(&timeinfo)); + } else { + Serial.println("Failed to obtain local time"); + } +} + +void connectToMQTT() { + BearSSL::X509List serverTrustedCA(ca_cert); + espClient.setTrustAnchors(&serverTrustedCA); + while (!mqtt_client.connected()) { + String client_id = "esp8266-client-" + String(WiFi.macAddress()); + Serial.printf("Connecting to MQTT Broker as %s.....\n", client_id.c_str()); + if (mqtt_client.connect(client_id.c_str(), mqtt_username, mqtt_password)) { + Serial.println("Connected to MQTT broker"); + mqtt_client.subscribe(mqtt_topic); + // Publish message upon successful connection + mqtt_client.publish(mqtt_topic, "Hi EMQX I'm ESP8266 ^^"); + } else { + char err_buf[128]; + espClient.getLastSSLError(err_buf, sizeof(err_buf)); + Serial.print("Failed to connect to MQTT broker, rc="); + Serial.println(mqtt_client.state()); + Serial.print("SSL error: "); + Serial.println(err_buf); + delay(5000); + } + } +} + +void mqttCallback(char *topic, byte *payload, unsigned int length) { + Serial.print("Message received on topic: "); + Serial.print(topic); + Serial.print("]: "); + for (int i = 0; i < length; i++) { + Serial.print((char) payload[i]); + } + Serial.println(); +} + +void loop() { + if (!mqtt_client.connected()) { + connectToMQTT(); + } + mqtt_client.loop(); +} diff --git a/mqtt-client-ESP8266/esp_connect_mqtt/esp_connect_mqtt.ino b/mqtt-client-ESP8266/esp_connect_mqtt/esp_connect_mqtt.ino new file mode 100644 index 0000000..788c238 --- /dev/null +++ b/mqtt-client-ESP8266/esp_connect_mqtt/esp_connect_mqtt.ino @@ -0,0 +1,105 @@ +//安装mqtt客户端 PubSubClient 库 + +#include +#include + +// WiFi settings +const char *ssid = "rehome"; // Replace with your WiFi name +const char *password = "Ruihong123"; // Replace with your WiFi password + +// MQTT Broker settings +const char *mqtt_broker = "mqtt.fileview123.com"; // EMQX broker endpoint +const char *mqtt_topic = "/device/esp8266/+"; // MQTT topic +const char *mqtt_username = "admin"; // MQTT username for authentication +const char *mqtt_password = "publish452131wW452131wW$"; // MQTT password for authentication +const int mqtt_port = 1883; // MQTT port (TCP) +const char *mqtt_topic_publish = "/device/esp8266/status"; // MQTT topic publish + +WiFiClient espClient; +PubSubClient mqtt_client(espClient); + +void connectToWiFi(); + +void connectToMQTTBroker(); + +void mqttCallback(char *topic, byte *payload, unsigned int length); + +void setup() { + Serial.begin(115200); + connectToWiFi(); + mqtt_client.setServer(mqtt_broker, mqtt_port); + mqtt_client.setCallback(mqttCallback); + connectToMQTTBroker(); +} + +void connectToWiFi() { + delay(10); + Serial.println(); + Serial.print("正在连接: "); + Serial.println(ssid); + WiFi.begin(ssid, password); + Serial.print("Connecting to WiFi"); + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + } + Serial.println("\nConnected to the WiFi network"); + Serial.println(""); + Serial.println("WiFi 连接成功"); + Serial.println("IP 地址: "); + Serial.println(WiFi.localIP()); +} + +void connectToMQTTBroker() { + while (!mqtt_client.connected()) { + Serial.print("尝试 MQTT 连接..."); + //String client_id = "esp8266-client-" + String(WiFi.macAddress()); + String client_id = "esp8266-client-"; + client_id += String(random(0xffff), HEX); + Serial.printf("Connecting to MQTT Broker as %s.....\n", client_id.c_str()); + if (mqtt_client.connect(client_id.c_str(), mqtt_username, mqtt_password)) { + Serial.println("Connected to MQTT broker"); + Serial.println("连接成功"); + mqtt_client.subscribe(mqtt_topic); + // Publish message upon successful connection + //mqtt_client.publish(mqtt_topic, "Hi EMQX I'm ESP8266 ^^"); + } else { + Serial.print("Failed to connect to MQTT broker, rc="); + Serial.print(mqtt_client.state()); + Serial.println(" try again in 5 seconds"); + delay(5000); + } + } +} + +void mqttCallback(char *topic, byte *payload, unsigned int length) { + Serial.print("Message received on topic: "); + Serial.println(topic); + Serial.print("Message:"); + for (unsigned int i = 0; i < length; i++) { + Serial.print((char) payload[i]); + } + Serial.println(); + Serial.println("-----------------------"); +} + +void loop() { + if(WiFi.status() != WL_CONNECTED){ + connectToWiFi(); + } + if (!mqtt_client.connected()) { + connectToMQTTBroker(); + } + mqtt_client.loop(); + + // 发布消息示例 + static unsigned long lastMsg = 0; + if (millis() - lastMsg > 5000) { + lastMsg = millis(); + + String message = "Hello from esp8266 - esp_connect_mqtt.ino_" + String(millis()); + mqtt_client.publish(mqtt_topic_publish, message.c_str()); + + Serial.println("消息已发布: " + message); + } +} diff --git a/mqtt-client-ESP8266/esp_mqtt_led.ino b/mqtt-client-ESP8266/esp_mqtt_led.ino new file mode 100644 index 0000000..3d1e682 --- /dev/null +++ b/mqtt-client-ESP8266/esp_mqtt_led.ino @@ -0,0 +1,86 @@ +#include +#include + +// GPIO 5 D1 +#define LED 5 + +// WiFi +const char *ssid = "mousse"; // Enter your WiFi name +const char *password = "qweqweqwe"; // Enter WiFi password + +// MQTT Broker +const char *mqtt_broker = "broker.emqx.io"; +const char *topic = "esp8266/led"; +const char *mqtt_username = "emqx"; +const char *mqtt_password = "public"; +const int mqtt_port = 1883; + +bool ledState = false; + +WiFiClient espClient; +PubSubClient client(espClient); + + +void setup() { + // Set software serial baud to 115200; + Serial.begin(115200); + delay(1000); // Delay for stability + + // Connecting to a WiFi network + WiFi.begin(ssid, password); + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.println("Connecting to WiFi..."); + } + Serial.println("Connected to the WiFi network"); + + // Setting LED pin as output + pinMode(LED, OUTPUT); + digitalWrite(LED, LOW); // Turn off the LED initially + + // Connecting to an MQTT broker + client.setServer(mqtt_broker, mqtt_port); + client.setCallback(callback); + while (!client.connected()) { + String client_id = "esp8266-client-"; + client_id += String(WiFi.macAddress()); + Serial.printf("The client %s connects to the public MQTT broker\n", client_id.c_str()); + if (client.connect(client_id.c_str(), mqtt_username, mqtt_password)) { + Serial.println("Public EMQX MQTT broker connected"); + } else { + Serial.print("Failed with state "); + Serial.print(client.state()); + delay(2000); + } + } + + // Publish and subscribe + client.publish(topic, "hello emqx"); + client.subscribe(topic); +} + +void callback(char *topic, byte *payload, unsigned int length) { + Serial.print("Message arrived in topic: "); + Serial.println(topic); + Serial.print("Message: "); + String message; + for (int i = 0; i < length; i++) { + message += (char) payload[i]; // Convert *byte to string + } + Serial.print(message); + if (message == "on" && !ledState) { + digitalWrite(LED, HIGH); // Turn on the LED + ledState = true; + } + if (message == "off" && ledState) { + digitalWrite(LED, LOW); // Turn off the LED + ledState = false; + } + Serial.println(); + Serial.println("-----------------------"); +} + +void loop() { + client.loop(); + delay(100); // Delay for a short period in each loop iteration +} diff --git a/mqtt-client-ESP8266/esp_mqtt_moisture.ino b/mqtt-client-ESP8266/esp_mqtt_moisture.ino new file mode 100644 index 0000000..f13e9b0 --- /dev/null +++ b/mqtt-client-ESP8266/esp_mqtt_moisture.ino @@ -0,0 +1,67 @@ +#include +#include +#include + +// WiFi +const char *ssid = "mousse"; // Enter your WiFi name +const char *password = "qweqweqwe"; // Enter WiFi password + +// MQTT Broker +const char *mqtt_broker = "broker.emqx.io"; +const char *topic = "esp8266/test"; +const char *mqtt_username = "emqx"; +const char *mqtt_password = "public"; +const int mqtt_port = 1883; + +// Moisture +#define sensorPIN A0 +unsigned long previousMillis = 0; + +WiFiClient espClient; +PubSubClient client(espClient); + +void setup() { + // Set software serial baud to 115200; + Serial.begin(115200); + // connecting to a WiFi network + WiFi.begin(ssid, password); + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.println("Connecting to WiFi.."); + } + Serial.println("Connected to the WiFi network"); + //connecting to a mqtt broker + client.setServer(mqtt_broker, mqtt_port); + while (!client.connected()) { + String client_id = "esp8266-client-"; + client_id += String(WiFi.macAddress()); + Serial.printf("The client %s connects to the public mqtt broker\n", client_id.c_str()); + if (client.connect(client_id.c_str(), mqtt_username, mqtt_password)) { + Serial.println("Public emqx mqtt broker connected"); + } else { + Serial.print("failed with state "); + Serial.print(client.state()); + delay(2000); + } + } +} + + +void loop() { + client.loop(); + unsigned long currentMillis = millis(); + // temperature and humidity data are publish every five second + if (currentMillis - previousMillis >= 5000) { + previousMillis = currentMillis; + float moistureValue = analogRead(sensorPIN); + // json serialize + DynamicJsonDocument data(256); + data["moisture"] = moistureValue; + // publish moisture + char json_string[256]; + serializeJson(data, json_string); + // + Serial.println(json_string); + client.publish(topic, json_string, false); + } +} \ No newline at end of file diff --git a/mqtt-client-ESP8266/temp_hum.ino b/mqtt-client-ESP8266/temp_hum.ino new file mode 100644 index 0000000..500466b --- /dev/null +++ b/mqtt-client-ESP8266/temp_hum.ino @@ -0,0 +1,76 @@ +#include +#include +#include +#include "DHT.h" + +// WiFi +const char *ssid = "mousse"; // Enter your WiFi name +const char *password = "qweqweqwe"; // Enter WiFi password + +// MQTT Broker +const char *mqtt_broker = "broker.emqx.io"; +const char *topic = "temp_hum/kunming"; +const char *mqtt_username = "emqx"; +const char *mqtt_password = "public"; +const int mqtt_port = 1883; + +// DHT11 +#define DHTPIN D4 +#define DHTTYPE DHT11 // DHT 11 +unsigned long previousMillis = 0; + +WiFiClient espClient; +PubSubClient client(espClient); +DHT dht(DHTPIN, DHTTYPE); + +void setup() { + // Set software serial baud to 115200; + Serial.begin(115200); + // connecting to a WiFi network + WiFi.begin(ssid, password); + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.println("Connecting to WiFi.."); + } + Serial.println("Connected to the WiFi network"); + //connecting to a mqtt broker + client.setServer(mqtt_broker, mqtt_port); + client.setCallback(callback); + //connecting to a mqtt broker + while (!client.connected()) { + String client_id = "esp8266-client-"; + client_id += String(WiFi.macAddress()); + Serial.printf("The client %s connects to the public mqtt broker\n", client_id.c_str()); + if (client.connect(client_id, mqtt_username, mqtt_password)) { + Serial.println("Public emqx mqtt broker connected"); + } else { + Serial.print("failed with state "); + Serial.print(client.state()); + delay(2000); + } + } + // dht11 begin + dht.begin(); +} + + +void loop() { + client.loop(); + unsigned long currentMillis = millis(); + // temperature and humidity data are publish every five second + if (currentMillis - previousMillis >= 5000) { + previousMillis = currentMillis; + float temp = dht.readTemperature(); + float hum = dht.readHumidity(); + // json serialize + DynamicJsonDocument data(256); + data["temp"] = temp; + data["hum"] = hum; + // publish temperature and humidity + char json_string[256]; + serializeJson(data, json_string); + // {"temp":23.5,"hum":55} + Serial.println(json_string); + client.publish(topic, json_string, false); + } +} \ No newline at end of file