esp32 add new file
parent
6617c12935
commit
346cce37a8
@ -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-----
|
||||
@ -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-----
|
||||
@ -0,0 +1,165 @@
|
||||
#include <WiFi.h>
|
||||
#include <PubSubClient.h>
|
||||
#include <WiFiClientSecure.h>
|
||||
#include <ArduinoJson.h>
|
||||
#include <OneWire.h>
|
||||
#include <DallasTemperature.h>
|
||||
|
||||
// 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
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
*.pyc
|
||||
|
||||
venv/
|
||||
.idea/
|
||||
__pycache__/
|
||||
article/
|
||||
|
||||
*.db
|
||||
|
||||
@ -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.
|
||||
|
||||

|
||||
|
||||
## 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
|
||||

|
||||
|
||||
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
|
||||
```
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 992 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.5 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 436 KiB |
@ -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.
|
||||
@ -0,0 +1,165 @@
|
||||
#include <WiFi.h>
|
||||
#include <PubSubClient.h>
|
||||
#include <WiFiClientSecure.h>
|
||||
#include <ArduinoJson.h>
|
||||
#include <OneWire.h>
|
||||
#include <DallasTemperature.h>
|
||||
|
||||
// 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
|
||||
}
|
||||
@ -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__/
|
||||
|
||||
|
||||
@ -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"]
|
||||
@ -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 <number_of_instances>`.
|
||||
|
||||
### 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.
|
||||
@ -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.
|
||||
@ -0,0 +1 @@
|
||||
# coding: utf-8
|
||||
@ -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"<a href='{redirect_url}'>Go to Temperature chart 😁</a>"
|
||||
|
||||
|
||||
@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)
|
||||
@ -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-----
|
||||
@ -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-----
|
||||
@ -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"
|
||||
@ -0,0 +1,3 @@
|
||||
Flask==2.3.2
|
||||
Flask-MQTT==1.1.1
|
||||
requests==2.31.0
|
||||
@ -0,0 +1,64 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>Temperature Chart</title>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||
<meta http-equiv="refresh" content="60">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<select id="hours" onchange="fetchData()">
|
||||
<option value="1" selected>Last 1 hour</option>
|
||||
<option value="12">Last 12 hours</option>
|
||||
<option value="24">Last 24 hours</option>
|
||||
</select>
|
||||
<canvas id="chart"></canvas>
|
||||
<script>
|
||||
const ctx = document.getElementById('chart').getContext('2d');
|
||||
const hoursSelect = document.getElementById('hours');
|
||||
const chart = new Chart(ctx, {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: [],
|
||||
datasets: [{
|
||||
label: 'Temperature',
|
||||
data: [],
|
||||
fill: false,
|
||||
borderColor: 'rgb(75, 192, 192)',
|
||||
tension: 0.1
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
x: {
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Time (UTC)'
|
||||
}
|
||||
},
|
||||
y: {
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Temperature'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
async function fetchData() {
|
||||
const hours = hoursSelect.value;
|
||||
const response = await fetch(`/data?hours=${hours}`);
|
||||
const data = await response.json();
|
||||
chart.data.labels = data.times.map(time => new Date(time).toLocaleString());
|
||||
chart.data.datasets[0].data = data.temperatures;
|
||||
chart.update();
|
||||
}
|
||||
|
||||
fetchData();
|
||||
setInterval(fetchData, 60000);
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@ -0,0 +1,101 @@
|
||||
#include <WiFi.h>
|
||||
#include <PubSubClient.h>
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,139 @@
|
||||
#include <WiFi.h>
|
||||
#include <PubSubClient.h>
|
||||
#include <WiFiClientSecure.h>
|
||||
|
||||
// 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();
|
||||
}
|
||||
@ -0,0 +1,144 @@
|
||||
#include <WiFi.h>
|
||||
#include <PubSubClient.h>
|
||||
#include <WiFiClientSecure.h>
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
// 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
|
||||
}
|
||||
@ -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)
|
||||
@ -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)
|
||||
|
||||
|
||||
|
||||
@ -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-----
|
||||
@ -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-----
|
||||
@ -0,0 +1,166 @@
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <PubSubClient.h>
|
||||
#include <time.h>
|
||||
|
||||
// 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();
|
||||
}
|
||||
@ -0,0 +1,105 @@
|
||||
//安装mqtt客户端 PubSubClient 库
|
||||
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <PubSubClient.h>
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,86 @@
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <PubSubClient.h>
|
||||
|
||||
// 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
|
||||
}
|
||||
@ -0,0 +1,67 @@
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <PubSubClient.h>
|
||||
#include <ArduinoJson.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 = "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);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,76 @@
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <PubSubClient.h>
|
||||
#include <ArduinoJson.h>
|
||||
#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);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue