Created
September 10, 2022 16:07
-
-
Save martinius96/e045fe8e605b5fd0f640e3978901fef4 to your computer and use it in GitHub Desktop.
Ultrasonic sensor node with ESP32 and PHY Ethernet LAN8720 (RMII interface). Client that measuring and sending datas to backend. FreeRTOS included.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*|----------------------------------------------------------------------------|*/ | |
/*|Project: Ultrasonic water level monitor - HC-SR04 / JSN-SR04T / HY-SRF05... |*/ | |
/*|ESP32 (DevKit, Generic) + PHY Ethernet LAN8720 / TLK110, RMII interface |*/ | |
/*|Author: Martin Chlebovec (martinius96) |*/ | |
/*|E-mail: martinius96@gmail.com |*/ | |
/*|Buy me a coffee at: paypal.me/chlebovec |*/ | |
/*|Project info: https://martinius96.github.io/hladinomer-studna-scripty/en |*/ | |
/*|Test web interface: https://hladinomer.000webhostapp.com |*/ | |
/*|Revision: 8. September 2022 |*/ | |
/*|----------------------------------------------------------------------------|*/ | |
#include <WiFiClientSecure.h> | |
#include <ETH.h> | |
#include <NewPingESP8266.h> | |
const char* host = "hladinomer.000webhostapp.com"; //webhost | |
String url = "/data.php"; //URL address to PHP file | |
boolean eth_state = false; | |
#define pinTrigger 4 | |
#define pinEcho 5 //CHANGED FROM D23 !!!! | |
#define maxVzdialenost 450 | |
NewPingESP8266 sonar(pinTrigger, pinEcho, maxVzdialenost); | |
/* | |
ETH_CLOCK_GPIO0_IN - default: external clock from crystal oscillator | |
ETH_CLOCK_GPIO0_OUT - 50MHz clock from internal APLL output on GPIO0 - possibly an inverter is needed for LAN8720 | |
ETH_CLOCK_GPIO16_OUT - 50MHz clock from internal APLL output on GPIO16 - possibly an inverter is needed for LAN8720 | |
ETH_CLOCK_GPIO17_OUT - 50MHz clock from internal APLL inverted output on GPIO17 - tested with LAN8720 | |
*/ | |
#ifdef ETH_CLK_MODE | |
#undef ETH_CLK_MODE | |
#endif | |
#define ETH_CLK_MODE ETH_CLOCK_GPIO17_OUT | |
// Pin# of the enable signal for the external crystal oscillator (-1 to disable for internal APLL source) | |
#define ETH_POWER_PIN -1 | |
// Type of the Ethernet PHY (LAN8720 or TLK110) | |
#define ETH_TYPE ETH_PHY_LAN8720 | |
// I²C-address of Ethernet PHY (0 or 1 for LAN8720, 31 for TLK110) | |
#define ETH_ADDR 1 | |
// Pin# of the I²C clock signal for the Ethernet PHY, DONT USE THIS PIN FOR ultrasonic sensor in this sketch | |
#define ETH_MDC_PIN 23 | |
// Pin# of the I²C IO signal for the Ethernet PHY | |
#define ETH_MDIO_PIN 18 | |
WiFiClientSecure client; //Secured client object for HTTPS connection | |
TaskHandle_t Task1; //ULTRASONIC MEASUREMENT | |
TaskHandle_t Task2; //PHY ETHERNET HTTP SOCKET | |
QueueHandle_t q = NULL; | |
//DigiCert Global Root CA in .pem format, stored in PROGMEM flash | |
//DST ROOT CA X3 EXAMPLE (https://i.imgur.com/fvw4huT.png) | |
const static char* test_root_ca PROGMEM = \ | |
"-----BEGIN CERTIFICATE-----\n" \ | |
"MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh\n" \ | |
"MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n" \ | |
"d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD\n" \ | |
"QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT\n" \ | |
"MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j\n" \ | |
"b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG\n" \ | |
"9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB\n" \ | |
"CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97\n" \ | |
"nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt\n" \ | |
"43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P\n" \ | |
"T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4\n" \ | |
"gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO\n" \ | |
"BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR\n" \ | |
"TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw\n" \ | |
"DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr\n" \ | |
"hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg\n" \ | |
"06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF\n" \ | |
"PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls\n" \ | |
"YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk\n" \ | |
"CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=\n" \ | |
"-----END CERTIFICATE-----\n"; | |
static void Task1code( void * parameter); | |
static void Task2code( void * parameter); | |
void WiFiEvent(WiFiEvent_t event); | |
void setup() { | |
Serial.begin(115200); | |
WiFi.onEvent(WiFiEvent); | |
ETH.begin(ETH_ADDR, ETH_POWER_PIN, ETH_MDC_PIN, ETH_MDIO_PIN, ETH_TYPE, ETH_CLK_MODE); | |
delay(5000); | |
client.setCACert(test_root_ca); | |
q = xQueueCreate(20, sizeof(int)); | |
if (q != NULL) { | |
Serial.println(F("Queue FIFO buffer is created")); | |
vTaskDelay(1000 / portTICK_PERIOD_MS); //wait for a second | |
xTaskCreatePinnedToCore( | |
Task1code, /* Task function. */ | |
"Task1", /* name of task. */ | |
10000, /* Stack size of task */ | |
NULL, /* parameter of the task */ | |
1, /* priority of the task */ | |
&Task1, /* Task handle to keep track of created task */ | |
1); /* pin task to core 1 */ | |
Serial.println(F("Ultrasonic measurement task started")); | |
xTaskCreatePinnedToCore( | |
Task2code, /* Task function. */ | |
"Task2", /* name of task. */ | |
10000, /* Stack size of task */ | |
NULL, /* parameter of the task */ | |
1, /* priority of the task */ | |
&Task2, /* Task handle to keep track of created task */ | |
0); /* pin task to core 0 */ | |
Serial.println(F("HTTPS Socket task started")); | |
} else { | |
Serial.println(F("Queue creation failed")); | |
} | |
} | |
void loop() { | |
yield(); | |
} | |
static void Task1code( void * parameter) { | |
if (q == NULL) { | |
Serial.println(F("Queue in Measurement task is not ready")); | |
return; | |
} | |
while (1) { | |
int distance = sonar.ping_cm(); | |
delay(50); | |
Serial.print(F("Test measurement: ")); | |
Serial.print(distance); | |
Serial.println(F(" cm")); | |
if (distance > 0) { | |
distance = 0; | |
for (int i = 0; i < 10; i++) { | |
distance += sonar.ping_cm(); | |
delay(50); | |
} | |
distance = distance / 10; | |
Serial.print(F("Distance to water level is: ")); | |
Serial.print(distance); | |
Serial.println(F(" cm.")); | |
xQueueSend(q, (void *)&distance, (TickType_t )0); //add the measurement value to Queue | |
for (int countdown = 300; countdown >= 0; countdown--) { | |
Serial.print(F("Next measurement in: ")); | |
Serial.print(countdown); | |
Serial.println(F(" seconds")); | |
vTaskDelay(1000 / portTICK_PERIOD_MS); | |
} | |
} | |
} | |
} | |
static void Task2code( void * parameter) { | |
int distance; | |
if (q == NULL) { | |
Serial.println(F("Queue in HTTP socket task is not ready")); | |
return; | |
} | |
while (1) { | |
xQueueReceive(q, &distance, portMAX_DELAY); //read measurement value from Queue and run code below, if no value, WAIT.... | |
String data = "hodnota=" + String(distance) + "&token=123456789"; | |
client.stop(); | |
while (eth_state != true) { | |
vTaskDelay(1 / portTICK_PERIOD_MS); | |
} | |
if (client.connect(host, 443)) { | |
Serial.println(F("Connected to server successfully")); | |
client.println("POST " + url + " HTTP/1.0"); | |
client.println("Host: " + (String)host); | |
client.println(F("User-Agent: ESP")); | |
client.println(F("Connection: close")); | |
client.println(F("Content-Type: application/x-www-form-urlencoded;")); | |
client.print(F("Content-Length: ")); | |
client.println(data.length()); | |
client.println(); | |
client.println(data); | |
Serial.println(F("Datas were sent to server successfully")); | |
while (client.connected()) { | |
String line = client.readStringUntil('\n'); | |
if (line == "\r") { | |
break; | |
} | |
} | |
String line = client.readStringUntil('\n'); | |
} else { | |
Serial.println(F("Connection to webserver was NOT successful")); | |
} | |
yield(); | |
client.stop(); | |
} | |
} | |
void WiFiEvent(WiFiEvent_t event) | |
{ | |
switch (event) { | |
case ARDUINO_EVENT_ETH_START: | |
eth_state = false; | |
Serial.println("ETH Started"); | |
//set eth hostname here | |
ETH.setHostname("esp32-ethernet"); | |
break; | |
case ARDUINO_EVENT_ETH_CONNECTED: | |
eth_state = false; | |
Serial.println("ETH Connected"); | |
break; | |
case ARDUINO_EVENT_ETH_GOT_IP: | |
eth_state = true; | |
Serial.print("ETH MAC: "); | |
Serial.print(ETH.macAddress()); | |
Serial.print(", IPv4: "); | |
Serial.print(ETH.localIP()); | |
if (ETH.fullDuplex()) { | |
Serial.print(", FULL_DUPLEX"); | |
} | |
Serial.print(", "); | |
Serial.print(ETH.linkSpeed()); | |
Serial.println("Mbps"); | |
break; | |
case ARDUINO_EVENT_ETH_DISCONNECTED: | |
eth_state = false; | |
Serial.println("ETH Disconnected"); | |
break; | |
case ARDUINO_EVENT_ETH_STOP: | |
eth_state = false; | |
Serial.println("ETH Stopped"); | |
break; | |
default: | |
break; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment