Skip to content

Instantly share code, notes, and snippets.

@martinius96
Created September 10, 2022 16:07
Show Gist options
  • Save martinius96/e045fe8e605b5fd0f640e3978901fef4 to your computer and use it in GitHub Desktop.
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.
/*|----------------------------------------------------------------------------|*/
/*|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