├── .gitignore ├── 1_simple_linear_regression ├── 1_python_model │ └── bike-sharing.py ├── 2_c_model │ ├── bike-sharing-c-arduino-esp32-normal-equation │ │ └── bike-sharing-c-arduino-esp32-normal-equation.ino │ └── bike-sharing-c-arduino-esp32 │ │ └── bike-sharing-c-arduino-esp32.ino └── README.md ├── 3_naive_bayes ├── 1_python_model │ ├── fruit-classification.ipynb │ ├── intelligent-lighting-1.ipynb │ ├── intelligent-lighting-2.ipynb │ ├── intelligent-lighting.csv │ └── rain-prediction.ipynb └── 2_c_model │ ├── .gitignore │ ├── intelligent-lighting-c-arduino-esp32 │ └── intelligent-lighting-c-arduino-esp32.ino │ └── intelligent-lighting-c-gcc │ ├── .cproject │ ├── .gitignore │ ├── .project │ ├── .settings │ └── language.settings.xml │ └── src │ └── intelligent-lighting.c ├── LICENSE ├── README.md └── esp32_examples ├── esp32-devkit-arduino-adc-trimpot └── esp32-devkit-arduino-adc-trimpot.ino ├── esp32-devkit-arduino-button-interrupt └── esp32-devkit-arduino-button-interrupt.ino ├── esp32-devkit-arduino-button └── esp32-devkit-arduino-button.ino ├── esp32-devkit-arduino-chip-info └── esp32-devkit-arduino-chip-info.ino ├── esp32-devkit-arduino-dht11-oled-128x64 └── esp32-devkit-arduino-dht11-oled-128x64.ino ├── esp32-devkit-arduino-dht11 └── esp32-devkit-arduino-dht11.ino ├── esp32-devkit-arduino-ds1307-oled-128x64 └── esp32-devkit-arduino-ds1307-oled-128x64.ino ├── esp32-devkit-arduino-ds1307 └── esp32-devkit-arduino-ds1307.ino ├── esp32-devkit-arduino-led-on-board-pwm └── esp32-devkit-arduino-led-on-board-pwm.ino ├── esp32-devkit-arduino-led-on-board └── esp32-devkit-arduino-led-on-board.ino ├── esp32-devkit-arduino-oled-128x64-bitmap └── esp32-devkit-arduino-oled-128x64-bitmap.ino ├── esp32-devkit-arduino-oled-128x64 └── esp32-devkit-arduino-oled-128x64.ino ├── esp32-devkit-arduino-serial-print └── esp32-devkit-arduino-serial-print.ino ├── esp32-devkit-arduino-serial-read └── esp32-devkit-arduino-serial-read.ino ├── esp32-devkit-arduino-timer-interrupt └── esp32-devkit-arduino-timer-interrupt.ino ├── esp32-devkit-arduino-timer-millis └── esp32-devkit-arduino-timer-millis.ino ├── esp32-devkit-arduino-web-server-bootstrap-button ├── data │ ├── bootstrap.min.css │ ├── bootstrap.min.js │ ├── index.html │ ├── jquery-3.3.1.min.js │ └── popper.min.js └── esp32-devkit-arduino-web-server-bootstrap-button.ino ├── esp32-devkit-arduino-web-server-bootstrap-card ├── data │ ├── a076d05399.js │ ├── bootstrap.min.css │ ├── bootstrap.min.js │ ├── index.html │ ├── jquery-3.3.1.min.js │ └── popper.min.js └── esp32-devkit-arduino-web-server-bootstrap-card.ino ├── esp32-devkit-arduino-web-server-bootstrap-chart ├── data │ ├── bootstrap.min.css │ ├── bootstrap.min.js │ ├── highcharts.js │ ├── index.html │ ├── jquery-3.3.1.min.js │ └── popper.min.js └── esp32-devkit-arduino-web-server-bootstrap-chart.ino ├── esp32-devkit-arduino-web-server-bootstrap-gauge ├── data │ ├── bootstrap.min.css │ ├── bootstrap.min.js │ ├── index.html │ ├── jquery-3.3.1.min.js │ ├── justgage.js │ ├── popper.min.js │ └── raphael-2.1.4.min.js └── esp32-devkit-arduino-web-server-bootstrap-gauge.ino ├── esp32-devkit-arduino-web-server-bootstrap-label ├── data │ ├── bootstrap.min.css │ ├── bootstrap.min.js │ ├── index.html │ ├── jquery-3.3.1.min.js │ └── popper.min.js └── esp32-devkit-arduino-web-server-bootstrap-label.ino ├── esp32-devkit-arduino-web-server-read-button-ajax └── esp32-devkit-arduino-web-server-read-button-ajax.ino ├── esp32-devkit-arduino-web-server-read-button └── esp32-devkit-arduino-web-server-read-button.ino ├── esp32-devkit-arduino-web-server-read-dht11-ajax └── esp32-devkit-arduino-web-server-read-dht11-ajax.ino ├── esp32-devkit-arduino-web-server-spiffs ├── data │ └── index.html └── esp32-devkit-arduino-web-server-spiffs.ino ├── esp32-devkit-arduino-web-server-write-led-pwm-ajax └── esp32-devkit-arduino-web-server-write-led-pwm-ajax.ino ├── esp32-devkit-arduino-web-server-write-led-pwm └── esp32-devkit-arduino-web-server-write-led-pwm.ino ├── esp32-devkit-arduino-web-server-write-led └── esp32-devkit-arduino-web-server-write-led.ino ├── esp32-devkit-arduino-web-server └── esp32-devkit-arduino-web-server.ino ├── esp32-devkit-arduino-wifi-access-point └── esp32-devkit-arduino-wifi-access-point.ino ├── esp32-devkit-arduino-wifi-station-http-client └── esp32-devkit-arduino-wifi-station-http-client.ino ├── esp32-devkit-arduino-wifi-station-http-server └── esp32-devkit-arduino-wifi-station-http-server.ino ├── esp32-devkit-arduino-wifi-station-mqtt-publish └── esp32-devkit-arduino-wifi-station-mqtt-publish.ino ├── esp32-devkit-arduino-wifi-station-mqtt-subscribe └── esp32-devkit-arduino-wifi-station-mqtt-subscribe.ino ├── esp32-devkit-arduino-wifi-station-tcp-client └── esp32-devkit-arduino-wifi-station-tcp-client.ino ├── esp32-devkit-arduino-wifi-station-tcp-server └── esp32-devkit-arduino-wifi-station-tcp-server.ino └── esp32-devkit-arduino-wifi-station └── esp32-devkit-arduino-wifi-station.ino /.gitignore: -------------------------------------------------------------------------------- 1 | .ipynb_checkpoints 2 | */.ipynb_checkpoints/* -------------------------------------------------------------------------------- /1_simple_linear_regression/1_python_model/bike-sharing.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Sat Feb 15 17:29:07 2020 4 | 5 | @author: Erwin Ouyang 6 | """ 7 | 8 | # === Step 1: import libraries ================================================ 9 | # import library 10 | import numpy as np 11 | import matplotlib.pyplot as plt 12 | 13 | # === Step 2: create data set ================================================= 14 | # train set 15 | x_train = np.array([[16, 15, 16, 10, 16, 13, 9, 19, 10, 12, 15, 10, 16, 26, 18, 16, 20, 15, 16 | 10, 25, 17, 9, 21, 7, 8, 13, 18, 7, 12, 18, 19, 19, 11, 12, 19, 21, 17 | 21, 19, 16, 10, 13, 20, 7, 8, 15, 13, 11, 14, 16, 21, 15, 12, 17, 24, 18 | 17, 21, 17, 14, 24, 12, 15, 16, 17, 18, 24, 16, 15, 23, 23, 21, 13, 9, 19 | 13, 11, 8, 15, 16, 12, 14, 21]]) 20 | y_train = np.array([[40, 52, 48, 37, 48, 37, 37, 40, 38, 29, 42, 38, 52, 57, 47, 46, 53, 32, 21 | 43, 63, 44, 35, 43, 43, 37, 35, 45, 37, 40, 54, 40, 51, 39, 44, 43, 49, 22 | 62, 60, 45, 34, 49, 44, 35, 26, 45, 42, 43, 40, 49, 52, 42, 35, 43, 51, 23 | 41, 51, 52, 44, 54, 38, 48, 45, 37, 50, 62, 57, 41, 47, 49, 52, 32, 33, 24 | 44, 43, 31, 43, 42, 42, 47, 61]]) 25 | # test set 26 | x_test = np.array([[13, 5, 17, 15, 10, 23, 18, 12, 22, 14, 9, 14, 14, 20, 11, 19, 10, 13, 11, 16]]) 27 | y_test = np.array([[44, 23, 47, 38, 32, 48, 40, 45, 50, 36, 37, 48, 46, 57, 42, 50, 44, 42, 45, 46]]) 28 | 29 | # === Step 3: plot data set =================================================== 30 | # plot train set and test set 31 | plt.scatter(x_train, y_train, label='Train set') 32 | plt.scatter(x_test, y_test, label='Test set') 33 | plt.xlim(0, 30) 34 | plt.ylim(0, 100) 35 | plt.title('Correlation between temperature and bike rentals') 36 | plt.xlabel('Temperature $[^{\circ}C]$') 37 | plt.ylabel('Bike-sharing users') 38 | plt.legend() 39 | 40 | # === Step 4: build the model ================================================= 41 | # parameters 42 | theta_0 = 0 43 | theta_1 = 0 44 | # define the hypothesis function 45 | def hypothesis(x): 46 | return theta_0 + theta_1*x 47 | 48 | # === Step 5: train the model using gradient descent ========================== 49 | # define the gradient descent function 50 | def gradient_descent(x, y, iter, eta): 51 | global theta_0 52 | global theta_1 53 | for i in range(iter): 54 | # calculate hypothesis 55 | h = hypothesis(x) 56 | # calculate error 57 | e = h - y 58 | 59 | # calculate d_J/d_theta_0 60 | sum_e = np.sum(e) 61 | d_J_d_theta_0 = sum_e / np.size(x) 62 | # calculate d_J/d_theta_1 63 | e_mul_x = e * x 64 | sum_e_mul_x = np.sum(e_mul_x) 65 | d_J_d_theta_1 = sum_e_mul_x / np.size(x) 66 | 67 | # update theta 0 68 | theta_0 = theta_0 - eta*d_J_d_theta_0; 69 | # update theta 1 70 | theta_1 = theta_1 - eta*d_J_d_theta_1; 71 | return 72 | # find theta_0 and theta_1 using gradient descent 73 | gradient_descent(x_train, y_train, 10000, 0.005) 74 | 75 | # === Step 5a: train the model using normal equation [optional] =============== 76 | # define normal equation function 77 | def normal_equation(x_train, y_train): 78 | X_b = np.c_[np.ones((80, 1)), x_train.reshape(-1, 1)] 79 | y = y_train.reshape(-1, 1) 80 | X_transpose = X_b.T 81 | theta = np.linalg.inv(X_transpose.dot(X_b)).dot(X_transpose).dot(y) 82 | return theta 83 | # find theta_0 and theta_1 using normal equation 84 | theta_norm = normal_equation(x_train, y_train) 85 | 86 | # === Step 6: plot the trained model ========================================== 87 | # data for plotting the hypothesis function 88 | x_trained_model = np.arange(0, 31) 89 | y_trained_model = hypothesis(x_trained_model) 90 | # plot the hypothesis function 91 | plt.scatter(x_train, y_train, label='Train set') 92 | plt.scatter(x_test, y_test, label='Test set') 93 | plt.plot(x_trained_model, y_trained_model, '-r', label='$h_{\\theta}(x)$') 94 | plt.xlim(0, 30) 95 | plt.ylim(0, 100) 96 | plt.title('Correlation between temperature and bike rentals') 97 | plt.xlabel('Temperature $[^{\circ}C]$') 98 | plt.ylabel('Bike-sharing users') 99 | plt.legend() 100 | 101 | # === Step 7: making predictions ============================================== 102 | # make predictions using test set 103 | y_predict = hypothesis(x_test) 104 | # plot predictions result 105 | plt.scatter(x_test, y_test, label='Test set') 106 | plt.scatter(x_test, y_predict, label='Prediction') 107 | plt.xlim(0, 30) 108 | plt.ylim(0, 100) 109 | plt.title('Correlation between temperature and bike rentals') 110 | plt.xlabel('Temperature $[^{\circ}C]$') 111 | plt.ylabel('Bike-sharing users') 112 | plt.legend() -------------------------------------------------------------------------------- /1_simple_linear_regression/2_c_model/bike-sharing-c-arduino-esp32-normal-equation/bike-sharing-c-arduino-esp32-normal-equation.ino: -------------------------------------------------------------------------------- 1 | // Author: Erwin Ouyang, aiotedge.tech 2 | // Date : 22 Feb 2020 3 | 4 | #include 5 | 6 | using namespace BLA; 7 | 8 | // === Step 1: create data set ================================================= 9 | // Train set 10 | Matrix<80,1> x_train = {16, 15, 16, 10, 16, 13, 9, 19, 10, 12, 15, 10, 16, 26, 18, 16, 20, 15, 11 | 10, 25, 17, 9, 21, 7, 8, 13, 18, 7, 12, 18, 19, 19, 11, 12, 19, 21, 12 | 21, 19, 16, 10, 13, 20, 7, 8, 15, 13, 11, 14, 16, 21, 15, 12, 17, 24, 13 | 17, 21, 17, 14, 24, 12, 15, 16, 17, 18, 24, 16, 15, 23, 23, 21, 13, 9, 14 | 13, 11, 8, 15, 16, 12, 14, 21}; 15 | Matrix<80,1> y_train = {40, 52, 48, 37, 48, 37, 37, 40, 38, 29, 42, 38, 52, 57, 47, 46, 53, 32, 16 | 43, 63, 44, 35, 43, 43, 37, 35, 45, 37, 40, 54, 40, 51, 39, 44, 43, 49, 17 | 62, 60, 45, 34, 49, 44, 35, 26, 45, 42, 43, 40, 49, 52, 42, 35, 43, 51, 18 | 41, 51, 52, 44, 54, 38, 48, 45, 37, 50, 62, 57, 41, 47, 49, 52, 32, 33, 19 | 44, 43, 31, 43, 42, 42, 47, 61}; 20 | // Test set 21 | Matrix<20,1> x_test = {13, 5, 17, 15, 10, 23, 18, 12, 22, 14, 9, 14, 14, 20, 11, 19, 10, 13, 11, 16}; 22 | Matrix<20,1> y_test = {44, 23, 47, 38, 32, 48, 40, 45, 50, 36, 37, 48, 46, 57, 42, 50, 44, 42, 45, 46}; 23 | 24 | // Parameters 25 | Matrix<2,1> theta; 26 | 27 | // Define the normal equation function 28 | Matrix<2,1> normal_equation(Matrix<80,1> X, Matrix<80,1> y) 29 | { 30 | Matrix<80,1> b; 31 | b.Fill(1); 32 | Matrix<80,2> X_b = b || X; 33 | Matrix<2,80> X_b_transpose = ~X_b; 34 | Matrix<2,1> theta = (X_b_transpose * X_b).Inverse() * X_b_transpose * y; 35 | 36 | return theta; 37 | } 38 | 39 | void setup() 40 | { 41 | // Serial port for debugging purposes 42 | Serial.begin(115200); 43 | 44 | // === Step 2: train the model using normal equation ========================= 45 | Serial.print("Training ...\n"); 46 | theta = normal_equation(x_train, y_train); 47 | Serial.print("Training completed: "); 48 | Serial << "theta = " << theta << '\n'; 49 | 50 | // === Step 3: making predictions with multiple samples ====================== 51 | Matrix<20,1> b; 52 | b.Fill(1); 53 | Matrix<20,2> x_b_test = b || x_test; 54 | Matrix<2,20> x_b_test_transpose = ~x_b_test; 55 | Matrix<1,2> theta_transpose = ~theta; 56 | Matrix<1,20> y_pred = theta_transpose * x_b_test_transpose; 57 | Serial << "Multiple samples prediction: y_pred = " << y_pred << '\n'; 58 | } 59 | 60 | void loop() 61 | { 62 | // === Step 3a: making predictions with single sample ======================== 63 | Serial.println("Single sample prediction:"); 64 | for (int i = 0; i < 20; i++) 65 | { 66 | Matrix<1,2> theta_transpose = ~theta; 67 | Matrix<2,1> x_b_test = {1, x_test(i)}; 68 | Matrix<1,1> y_pred = theta_transpose * x_b_test; 69 | 70 | // Round the result to nearest integer 71 | int y_pred_rounded = round(y_pred(0)); 72 | // Print the result 73 | printf("Temperature = %.0f°C, Predicted Bike-Sharing Users = %d\n", x_test(i), y_pred_rounded); 74 | delay(1000); 75 | } 76 | } 77 | 78 | -------------------------------------------------------------------------------- /1_simple_linear_regression/2_c_model/bike-sharing-c-arduino-esp32/bike-sharing-c-arduino-esp32.ino: -------------------------------------------------------------------------------- 1 | // Author: Erwin Ouyang, aiotedge.tech 2 | // Date : 22 Feb 2020 3 | 4 | // === Step 1: create data set ================================================= 5 | // Train set 6 | int x_train[80] = {16, 15, 16, 10, 16, 13, 9, 19, 10, 12, 15, 10, 16, 26, 18, 16, 20, 15, 7 | 10, 25, 17, 9, 21, 7, 8, 13, 18, 7, 12, 18, 19, 19, 11, 12, 19, 21, 8 | 21, 19, 16, 10, 13, 20, 7, 8, 15, 13, 11, 14, 16, 21, 15, 12, 17, 24, 9 | 17, 21, 17, 14, 24, 12, 15, 16, 17, 18, 24, 16, 15, 23, 23, 21, 13, 9, 10 | 13, 11, 8, 15, 16, 12, 14, 21}; 11 | int y_train[80] = {40, 52, 48, 37, 48, 37, 37, 40, 38, 29, 42, 38, 52, 57, 47, 46, 53, 32, 12 | 43, 63, 44, 35, 43, 43, 37, 35, 45, 37, 40, 54, 40, 51, 39, 44, 43, 49, 13 | 62, 60, 45, 34, 49, 44, 35, 26, 45, 42, 43, 40, 49, 52, 42, 35, 43, 51, 14 | 41, 51, 52, 44, 54, 38, 48, 45, 37, 50, 62, 57, 41, 47, 49, 52, 32, 33, 15 | 44, 43, 31, 43, 42, 42, 47, 61}; 16 | // Test set 17 | int x_test[20] = {13, 5, 17, 15, 10, 23, 18, 12, 22, 14, 9, 14, 14, 20, 11, 19, 10, 13, 11, 16}; 18 | int y_test[20] = {44, 23, 47, 38, 32, 48, 40, 45, 50, 36, 37, 48, 46, 57, 42, 50, 44, 42, 45, 46}; 19 | 20 | // Parameters 21 | float theta_0 = 0.0; 22 | float theta_1 = 0.0; 23 | 24 | void setup() 25 | { 26 | // Serial port for debugging purposes 27 | Serial.begin(115200); 28 | 29 | // === Step 2: train the model using gradient descent ======================== 30 | Serial.print("Training ...\n"); 31 | gradient_descent(x_train, y_train, 80, 10000, 0.005); 32 | Serial.printf("Training completed: theta_0 = %.3f, theta_1 = %.3f\n", theta_0, theta_1); 33 | } 34 | 35 | void loop() 36 | { 37 | // === Step 3: making predictions ============================================ 38 | for (int i = 0; i < 20; i++) 39 | { 40 | // Make predictions using test set 41 | float y_pred = hypothesis(x_test[i]); 42 | // Round the result to nearest integer 43 | int y_pred_rounded = round(y_pred); 44 | // Print the result 45 | printf("Temperature = %d°C, Predicted Bike-Sharing Users = %d\n", x_test[i], y_pred_rounded); 46 | delay(1000); 47 | } 48 | } 49 | 50 | // Define the hypothesis function 51 | float hypothesis(int x) 52 | { 53 | return theta_0 + theta_1*x; 54 | } 55 | 56 | // Define the gradient descent function 57 | void gradient_descent(int x[], int y[], int m, int iter, float eta) 58 | { 59 | float h, e, sum_e, e_mul_x, sum_e_mul_x; 60 | 61 | for (int i = 0; i < iter; i++) 62 | { 63 | // Clear variable 64 | h = 0.0; 65 | e = 0.0; 66 | sum_e = 0.0; 67 | e_mul_x = 0.0; 68 | sum_e_mul_x = 0.0; 69 | 70 | for (int j = 0; j < m; j++) 71 | { 72 | // Calculate hypothesis 73 | h = hypothesis(x[j]); 74 | // Calculate error 75 | e = h - y[j]; 76 | // Calculate sum of error 77 | sum_e = sum_e + e; 78 | // Calculate error*x 79 | e_mul_x = e * x[j]; 80 | // Calculate sum of error*x 81 | sum_e_mul_x = sum_e_mul_x + e_mul_x; 82 | } 83 | 84 | // Calculate d_J/d_theta_0 85 | float d_J_d_theta_0 = sum_e / m; 86 | // Calculate d_J/d_theta_1 87 | float d_J_d_theta_1 = sum_e_mul_x / m; 88 | 89 | // Update theta 0 90 | theta_0 = theta_0 - eta*d_J_d_theta_0; 91 | // Update theta 1 92 | theta_1 = theta_1 - eta*d_J_d_theta_1; 93 | } 94 | } 95 | 96 | -------------------------------------------------------------------------------- /1_simple_linear_regression/README.md: -------------------------------------------------------------------------------- 1 | # Simple Linear Regression 2 | 3 | This project is an implementation of a simple linear regression algorithm. The simple linear regression algorithm has only one independent variable and one dependent variable. The algorithm is build from scratch in Python and C. 4 | 5 | ## Problem 6 | 7 | We want to build an AIoT device that can predict the number of bike-sharing users using temperature as the independent variable. We want to use real-time temperature value from sensor as input to our simple linear regression algorithm. We want to build a GUI for this system. 8 | 9 | ## Solution 10 | 11 | 1. Build the model in Python 12 | - Create and visualize data set 13 | - Build the hypothesis function 14 | - Train model using gradient descent 15 | - Train model using normal equation 16 | - Making predictions 17 | 2. Build the model in C Arduino 18 | 3. Deploy the model in ESP32 19 | -------------------------------------------------------------------------------- /3_naive_bayes/1_python_model/fruit-classification.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Naive Bayes, Part 1\n", 8 | "\n", 9 | "Derived from:\n", 10 | "\n", 11 | "https://www.machinelearningplus.com/predictive-modeling/how-naive-bayes-algorithm-works-with-example-and-full-code/\n", 12 | "https://medium.com/syncedreview/applying-multinomial-naive-bayes-to-nlp-problems-a-practical-explanation-4f5271768ebf\n", 13 | "\n", 14 | "### What is Naive Bayes?\n", 15 | "Naive Bayes is a probabilistic machine learning algorithm. It is based on Bayes' theorem. This algorithm makes an assumption that all features are independent of each other. In other words, changing the value of one feature, does not directly change the value of any of the other features. This assumption is naive because it is (almost) never true.\n", 16 | "\n", 17 | "For example, if you have temperature and humidity as input features, Naive Bayes assumes that temperature and humidity are independent of each other. So, changing the value of temperature, does not directly change the value of humidity. However, in reality, temperature and humidity are related to each other." 18 | ] 19 | }, 20 | { 21 | "cell_type": "markdown", 22 | "metadata": {}, 23 | "source": [ 24 | "### Conditional Probability\n", 25 | "Before you go into Naive Bayes, you need to understand what Conditional Probability is. Let's start with an example.\n", 26 | "\n", 27 | "When you toss a fair coin, it has a probability of 1/2 of getting heads or tails. Mathematically, it is written as\n", 28 | "$P(Head)=\\frac{1}{2}$ and $P(Tail)=\\frac{1}{2}$.\n", 29 | "\n", 30 | "Another example, suppose you pick a card from the deck and you already know that your card is an ace. What is the probability of getting a diamond given the card is an ace? Well, we have already a condition that the card is an ace. So, the population (denominator) is 4 not 52. There is only one diamond in aces. So, the probability of getting a diamond given the card is an ace is 1/4. Mathematically, it is written as $P(Diamond|Ace)=\\frac{1}{4}$. This is called conditional probability." 31 | ] 32 | }, 33 | { 34 | "cell_type": "markdown", 35 | "metadata": {}, 36 | "source": [ 37 | "### Naive Bayes by Example 1\n", 38 | "Let's start with a simple example of Naive Bayes algorithm. Suppose you have 100 fruits which could be either apple or orange. Your training data of these fruits is shown in the following table. In this training data, we have one feature which is color that has three possible values: red, green, and orange. Then, we have one label that has two possible values: apple and orange. We denote color as $X$ and fruit as $y$.\n", 39 | "\n", 40 | "| No. | Color | Fruit |\n", 41 | "|-----|--------|--------|\n", 42 | "| 1 | Red | Apple |\n", 43 | "| 2 | Red | Apple |\n", 44 | "| 3 | Green | Apple |\n", 45 | "| 4 | Green | Orange |\n", 46 | "| 5 | Orange | Orange |\n", 47 | "| ... | ... | ... |\n", 48 | "| 100 | Green | Orange |\n", 49 | "\n", 50 | "The objective of Naive Bayes classifier is to predict if a given fruit (by knowing its color) is an apple or orange. Let's say the color of a fruit is green ($X=green$), can you predict what fruit ($y$) is it? In other words, you can predict $y$ when only the $X$ variables in training data are known.\n", 51 | "\n", 52 | "The idea is to compute the two probabilities, that is the probability of the fruit being an apple or orange. Whichever fruit type gets the highest probability wins. Mathematically, you need to compute both $P(y=apple|X=green)$ and $P(y=orange|X=green)$, then compare the results. If $P(y=apple|X=green) > P(y=orange|X=green)$ then the prediction is an apple. If $P(y=apple|X=green) < P(y=orange|X=green)$ then the prediction is an orange.\n", 53 | "\n", 54 | "This is the Naive Bayes formula for computing these probabilities:\n", 55 | "$$P(y=apple|X=green) = \\frac{P(X=green|y=apple)P(y=apple)}{P(X=green)}$$\n", 56 | "$$P(y=orange|X=green) = \\frac{P(X=green|y=orange)P(y=orange)}{P(X=green)}$$\n", 57 | "\n", 58 | "The step-by-step of Naive Bayes algorithm:\n", 59 | "\n", 60 | "#### **Step 0: create a frequency table for each feature of the training data**\n", 61 | "First, you need to build a table called frequency table for each feature of the training data. Since we have only one feature, which is color, so we only need to build one frequency table.\n", 62 | "\n", 63 | "Given the training data, you need to count how many red apples, green apples and orange apples are there. The same for the oranges, you need to count how many red oranges, green oranges and orange oranges are there.\n", 64 | "\n", 65 | "| No. | Color | Fruit |\n", 66 | "|-----|--------|--------|\n", 67 | "| 1 | Red | Apple |\n", 68 | "| 2 | Red | Apple |\n", 69 | "| 3 | Green | Apple |\n", 70 | "| 4 | Green | Orange |\n", 71 | "| 5 | Orange | Orange |\n", 72 | "| ... | ... | ... |\n", 73 | "| 100 | Green | Orange |\n", 74 | "\n", 75 | "I have omitted the other rows for the sake of simplicity. The following table shows the frequency table. We have 33 red apples, 0 red orange, 20 green apples, 7 green oranges, 1 orange apple, and 39 orange oranges.\n", 76 | "\n", 77 | "| Color | Apple | Orange | Total |\n", 78 | "|--------|-------|--------|-------|\n", 79 | "| Red | 33 | 0 | 33 |\n", 80 | "| Green | 20 | 7 | 27 |\n", 81 | "| Orange | 1 | 39 | 40 |\n", 82 | "| Total | 54 | 46 | 100 |\n", 83 | "\n", 84 | "Finally, you need to add them together to get the total number of apples, oranges, and the total number of fruits are there. The same for every color, you need to add them together to get the total number red fruits, green fruits, orange fruits, and the total number of fruits are there.\n", 85 | "\n", 86 | "#### **Step 1: compute the probabilities for each of the fruits (label)**\n", 87 | "In this step, you need to compute the $P(y=apple)$ and $P(y=orange)$. Out of 100 fruits, you have 54 apples and 46 oranges. So the respective probabilities are:\n", 88 | "$$P(y=apple)=\\frac{54}{100}$$\n", 89 | "$$P(y=orange)=\\frac{46}{100}$$\n", 90 | "\n", 91 | "#### **Step 2: compute the probability of the color (feature)**\n", 92 | "In this step, you need to compute $P(X=green)$. Out of 100 fruits, you have 27 greens. So the probability is:\n", 93 | "$$P(X=green)=\\frac{27}{100}$$\n", 94 | "\n", 95 | "#### **Step 3: compute the conditional probabilities**\n", 96 | "In this step, you need to compute $P(X=green|y=apple)$ and $P(X=green|y=orange)$. Out of 54 apples, you have 20 greens. So the probability is:\n", 97 | "$$P(X=green|y=apple)=\\frac{20}{54}$$\n", 98 | "Out of 46 oranges, you have 7 greens. So the probability is:\n", 99 | "$$P(X=green|y=orange)=\\frac{7}{46}$$\n", 100 | "\n", 101 | "#### **Step 4: substitute all the three probabilities into the Naive Bayes formula**\n", 102 | "In this step, you need to subtitute all the three probabilities into the Naive Bayes formula.\n", 103 | "$$P(y=apple|X=green) = \\frac{\\frac{20}{54}\\frac{54}{100}}{\\frac{27}{100}}=\\frac{20}{27}$$\n", 104 | "$$P(y=orange|X=green) = \\frac{\\frac{7}{46}\\frac{46}{100}}{\\frac{27}{100}}=\\frac{7}{27}$$\n", 105 | "\n", 106 | "$P(y=apple|X=green)>P(y=orange|X=green)$, which means apple get higher probability than orange, therefore apple will be our predicted fruit." 107 | ] 108 | }, 109 | { 110 | "cell_type": "markdown", 111 | "metadata": {}, 112 | "source": [ 113 | "### The Naive Bayes Formula\n", 114 | "From the previous example, you can rewrite the Naive Bayes formula in more general form:\n", 115 | "$$P(y|X) = \\frac{P(X|y)P(y)}{P(X)}$$\n", 116 | "where $X$ is input feature and $y$ is output label that you want to predict. $P(y|X)$ is called posterior probability. $P(X|y)$ is called likelihood. $P(y)$ is called label/class prior probability. $P(X)$ is called feature/predictor prior probability.\n", 117 | "\n", 118 | "Now, if you notice in step 4, in the previous example, the value of denominators of both formulas remain constant ($\\frac{27}{100}$) for given input. Since we compare these two probabilities, you can remove that term. So, for Naive Bayes **classifier** you can simplify the formula to:\n", 119 | "$$P(y|X)\\propto P(X|y)P(y)$$" 120 | ] 121 | }, 122 | { 123 | "cell_type": "markdown", 124 | "metadata": {}, 125 | "source": [ 126 | "### Laplace Smoothing\n", 127 | "In the previous example, the $P(X=red|y=orange)$ is zero. It makes sense because out of 46 oranges you have 0 red, but if you have many input features, the entire probability will become zero because one of the feature’s value is zero. It will wipe out all the information in the other probabilities. This case is called zero frequency, and it needs to be avoided. You can use Laplace Smoothing to solve the problem of zero probability.\n", 128 | "\n", 129 | "Laplace Smoothing can best be explained by an example. Let's say we want to compute $P(X=red|y=orange)$.\n", 130 | "\n", 131 | "Without using Laplace Smoothing, the probability is\n", 132 | "$$P(X=red|y=orange)=\\frac{0}{46}=0$$\n", 133 | "It gives us a probability of zero.\n", 134 | "\n", 135 | "Laplace Smoothing is usullay applied by **adding one count to the numerator and adding number of possible values of feature to the denominator**. In this case, number of possible values of feature is three (red, green, and orange). So, the probability after Laplace Smoothing is\n", 136 | "$$P(X=red|y=orange)=\\frac{0+1}{46+3}=\\frac{1}{49}$$\n", 137 | "So, by using Laplace Smoothing, it gives us a non-zero probability." 138 | ] 139 | }, 140 | { 141 | "cell_type": "markdown", 142 | "metadata": {}, 143 | "source": [ 144 | "Even though Naive Bayes is naive, it perform very well in such applications, even when the features are not independent of each other. Furthermore, compared to other algorithms, Naive Bayes is fast. So, it could be used for making predictions in real time." 145 | ] 146 | }, 147 | { 148 | "cell_type": "code", 149 | "execution_count": null, 150 | "metadata": {}, 151 | "outputs": [], 152 | "source": [] 153 | } 154 | ], 155 | "metadata": { 156 | "kernelspec": { 157 | "display_name": "Python 3", 158 | "language": "python", 159 | "name": "python3" 160 | }, 161 | "language_info": { 162 | "codemirror_mode": { 163 | "name": "ipython", 164 | "version": 3 165 | }, 166 | "file_extension": ".py", 167 | "mimetype": "text/x-python", 168 | "name": "python", 169 | "nbconvert_exporter": "python", 170 | "pygments_lexer": "ipython3", 171 | "version": "3.8.3" 172 | } 173 | }, 174 | "nbformat": 4, 175 | "nbformat_minor": 4 176 | } 177 | -------------------------------------------------------------------------------- /3_naive_bayes/1_python_model/intelligent-lighting-2.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 74, 6 | "metadata": {}, 7 | "outputs": [ 8 | { 9 | "data": { 10 | "text/html": [ 11 | "
\n", 12 | "\n", 25 | "\n", 26 | " \n", 27 | " \n", 28 | " \n", 29 | " \n", 30 | " \n", 31 | " \n", 32 | " \n", 33 | " \n", 34 | " \n", 35 | " \n", 36 | " \n", 37 | " \n", 38 | " \n", 39 | " \n", 40 | " \n", 41 | " \n", 42 | " \n", 43 | " \n", 44 | " \n", 45 | " \n", 46 | " \n", 47 | " \n", 48 | " \n", 49 | " \n", 50 | " \n", 51 | " \n", 52 | " \n", 53 | " \n", 54 | " \n", 55 | " \n", 56 | " \n", 57 | " \n", 58 | " \n", 59 | " \n", 60 | " \n", 61 | " \n", 62 | " \n", 63 | " \n", 64 | " \n", 65 | " \n", 66 | "
Light SensorTimeLight State
00.000:00Off
10.001:00Off
20.002:00Off
30.003:00Off
40.004:00Off
\n", 67 | "
" 68 | ], 69 | "text/plain": [ 70 | " Light Sensor Time Light State\n", 71 | "0 0.0 00:00 Off\n", 72 | "1 0.0 01:00 Off\n", 73 | "2 0.0 02:00 Off\n", 74 | "3 0.0 03:00 Off\n", 75 | "4 0.0 04:00 Off" 76 | ] 77 | }, 78 | "execution_count": 74, 79 | "metadata": {}, 80 | "output_type": "execute_result" 81 | } 82 | ], 83 | "source": [ 84 | "# === Step 1: read data set ====================================================\n", 85 | "import pandas as pd\n", 86 | "df = pd.read_csv(\"intelligent-lighting.csv\")\n", 87 | "df.head()" 88 | ] 89 | }, 90 | { 91 | "cell_type": "code", 92 | "execution_count": 75, 93 | "metadata": {}, 94 | "outputs": [ 95 | { 96 | "data": { 97 | "text/html": [ 98 | "
\n", 99 | "\n", 112 | "\n", 113 | " \n", 114 | " \n", 115 | " \n", 116 | " \n", 117 | " \n", 118 | " \n", 119 | " \n", 120 | " \n", 121 | " \n", 122 | " \n", 123 | " \n", 124 | " \n", 125 | " \n", 126 | " \n", 127 | " \n", 128 | " \n", 129 | " \n", 130 | " \n", 131 | " \n", 132 | " \n", 133 | " \n", 134 | " \n", 135 | " \n", 136 | " \n", 137 | " \n", 138 | " \n", 139 | " \n", 140 | " \n", 141 | " \n", 142 | " \n", 143 | " \n", 144 | " \n", 145 | " \n", 146 | " \n", 147 | " \n", 148 | " \n", 149 | " \n", 150 | " \n", 151 | " \n", 152 | " \n", 153 | "
Light SensorTimeLight State
0000
1010
2020
3030
4040
\n", 154 | "
" 155 | ], 156 | "text/plain": [ 157 | " Light Sensor Time Light State\n", 158 | "0 0 0 0\n", 159 | "1 0 1 0\n", 160 | "2 0 2 0\n", 161 | "3 0 3 0\n", 162 | "4 0 4 0" 163 | ] 164 | }, 165 | "execution_count": 75, 166 | "metadata": {}, 167 | "output_type": "execute_result" 168 | } 169 | ], 170 | "source": [ 171 | "# === Step 2: data preprocessing ===============================================\n", 172 | "df_tmp = df.copy()\n", 173 | "# group light sensor value into 4 levels\n", 174 | "for i in range(len(df_tmp)):\n", 175 | " if (df_tmp.loc[i,'Light Sensor'] >= 0.0 and df_tmp.loc[i,'Light Sensor'] <= 0.25):\n", 176 | " df_tmp.loc[i,'Light Sensor'] = 0\n", 177 | " elif (df_tmp.loc[i,'Light Sensor'] >= 0.26 and df_tmp.loc[i,'Light Sensor'] <= 0.50):\n", 178 | " df_tmp.loc[i,'Light Sensor'] = 1\n", 179 | " elif (df_tmp.loc[i,'Light Sensor'] >= 0.51 and df_tmp.loc[i,'Light Sensor'] <= 0.75):\n", 180 | " df_tmp.loc[i,'Light Sensor'] = 2\n", 181 | " elif (df_tmp.loc[i,'Light Sensor'] >= 0.76 and df_tmp.loc[i,'Light Sensor'] <= 1.0):\n", 182 | " df_tmp.loc[i,'Light Sensor'] = 3\n", 183 | "df_tmp['Light Sensor'] = df_tmp['Light Sensor'].astype('int64') # convert float64 to int64\n", 184 | "# get just the hour of the time\n", 185 | "df_tmp['Time'] = pd.to_datetime(df_tmp['Time'], format='%H:%M').dt.hour\n", 186 | "# encode 'Off' to 0 and 'On' to 1\n", 187 | "df_tmp.replace({'Light State': {'Off': 0, 'On': 1}}, inplace=True)\n", 188 | "df_tmp.head()" 189 | ] 190 | }, 191 | { 192 | "cell_type": "code", 193 | "execution_count": 76, 194 | "metadata": {}, 195 | "outputs": [], 196 | "source": [ 197 | "# === Step 3: convert pandas data frame to numpy array =========================\n", 198 | "df_np = df_tmp.to_numpy()\n", 199 | "# print(df_np)\n", 200 | "# split the data into features and label\n", 201 | "X = df_np[:, 0:2] # features\n", 202 | "y = df_np[:, 2] # label" 203 | ] 204 | }, 205 | { 206 | "cell_type": "code", 207 | "execution_count": 77, 208 | "metadata": {}, 209 | "outputs": [ 210 | { 211 | "name": "stdout", 212 | "output_type": "stream", 213 | "text": [ 214 | "[[ 6. 12.]\n", 215 | " [ 4. 5.]\n", 216 | " [ 5. 0.]\n", 217 | " [ 5. 0.]]\n" 218 | ] 219 | } 220 | ], 221 | "source": [ 222 | "# === Step 4: create frequency table for parameter light sensor ================\n", 223 | "import numpy as np\n", 224 | "freq_table_lsensor = np.zeros((4, 2))\n", 225 | "for i in range(len(y)):\n", 226 | " freq_table_lsensor[X[i, 0], y[i]] += 1\n", 227 | "print(freq_table_lsensor)" 228 | ] 229 | }, 230 | { 231 | "cell_type": "code", 232 | "execution_count": 78, 233 | "metadata": {}, 234 | "outputs": [ 235 | { 236 | "name": "stdout", 237 | "output_type": "stream", 238 | "text": [ 239 | "[[1. 0.]\n", 240 | " [1. 0.]\n", 241 | " [1. 0.]\n", 242 | " [1. 0.]\n", 243 | " [2. 0.]\n", 244 | " [0. 1.]\n", 245 | " [0. 1.]\n", 246 | " [0. 1.]\n", 247 | " [1. 1.]\n", 248 | " [1. 1.]\n", 249 | " [1. 0.]\n", 250 | " [1. 0.]\n", 251 | " [2. 1.]\n", 252 | " [2. 0.]\n", 253 | " [1. 1.]\n", 254 | " [1. 1.]\n", 255 | " [1. 0.]\n", 256 | " [1. 1.]\n", 257 | " [1. 1.]\n", 258 | " [1. 1.]\n", 259 | " [0. 2.]\n", 260 | " [0. 2.]\n", 261 | " [0. 1.]\n", 262 | " [0. 1.]]\n" 263 | ] 264 | } 265 | ], 266 | "source": [ 267 | "# === Step 5: create frequency table for parameter time ========================\n", 268 | "freq_table_time = np.zeros((24, 2))\n", 269 | "for i in range(len(y)):\n", 270 | " freq_table_time[X[i, 1], y[i]] += 1\n", 271 | "print(freq_table_time)" 272 | ] 273 | }, 274 | { 275 | "cell_type": "code", 276 | "execution_count": 79, 277 | "metadata": {}, 278 | "outputs": [ 279 | { 280 | "data": { 281 | "text/plain": [ 282 | "0.5384615384615384" 283 | ] 284 | }, 285 | "execution_count": 79, 286 | "metadata": {}, 287 | "output_type": "execute_result" 288 | } 289 | ], 290 | "source": [ 291 | "# === Step 6: create function for calculating label prior probability ==========\n", 292 | "def label_prior_prob(light_state):\n", 293 | " count = 0\n", 294 | " for i in range(len(y)):\n", 295 | " if (y[i] == light_state):\n", 296 | " count += 1\n", 297 | " prob = count/len(y)\n", 298 | " prob_lap = (count+1)/(len(y)+2*1)\n", 299 | " return prob_lap\n", 300 | "\n", 301 | "# test the function\n", 302 | "label_prior_prob(0) # probability of 'Off'" 303 | ] 304 | }, 305 | { 306 | "cell_type": "code", 307 | "execution_count": 80, 308 | "metadata": {}, 309 | "outputs": [ 310 | { 311 | "data": { 312 | "text/plain": [ 313 | "0.017045454545454544" 314 | ] 315 | }, 316 | "execution_count": 80, 317 | "metadata": {}, 318 | "output_type": "execute_result" 319 | } 320 | ], 321 | "source": [ 322 | "# === Step 7: create function for calculating likelihood =======================\n", 323 | "def likelihood(light_sensor, time, light_state):\n", 324 | " # calculate probability of light sensor=light_sensor given light state=light_state\n", 325 | " prob_lsensor_lstate = freq_table_lsensor[light_sensor, light_state] / np.sum(freq_table_lsensor[:, light_state])\n", 326 | " prob_lsensor_lstate_lap = (freq_table_lsensor[light_sensor, light_state]+1) / (np.sum(freq_table_lsensor[:, light_state])+4*1)\n", 327 | " # calculate probability of time=time given light state=light_state\n", 328 | " prob_time_lstate = freq_table_time[time, light_state] / np.sum(freq_table_time[:, light_state])\n", 329 | " prob_time_lstate_lap = (freq_table_time[time, light_state]+1) / (np.sum(freq_table_time[:, light_state])+24*1)\n", 330 | " # calculate probability of light sensor=light_sensor and time=time given light state=light_state\n", 331 | " prob_lsensor_time_lstate = prob_lsensor_lstate * prob_time_lstate\n", 332 | " prob_lsensor_time_lstate_lap = prob_lsensor_lstate_lap * prob_time_lstate_lap\n", 333 | " return prob_lsensor_time_lstate_lap\n", 334 | "\n", 335 | "# test the function\n", 336 | "likelihood(2, 12, 0) # likelihood of light sensor level 2 and time = 12:00 given light state 'Off'" 337 | ] 338 | }, 339 | { 340 | "cell_type": "code", 341 | "execution_count": 81, 342 | "metadata": {}, 343 | "outputs": [], 344 | "source": [ 345 | "# === Step 8: create function for calculating posterior probability ============\n", 346 | "def posterior_prob(light_sensor, time, light_state):\n", 347 | " prob = (likelihood(light_sensor, time, light_state) * label_prior_prob(light_state))\n", 348 | " return prob" 349 | ] 350 | }, 351 | { 352 | "cell_type": "code", 353 | "execution_count": 82, 354 | "metadata": {}, 355 | "outputs": [ 356 | { 357 | "name": "stdout", 358 | "output_type": "stream", 359 | "text": [ 360 | "0.009178321678321678\n", 361 | "0.0010720986330742428\n" 362 | ] 363 | } 364 | ], 365 | "source": [ 366 | "# === Step 9: make prediction =================================================\n", 367 | "# probability of light state 'Off' given light sensor level 2 and time = 12:00 \n", 368 | "print(posterior_prob(2, 12, 0))\n", 369 | "# probability of light state 'On' given light sensor level 2 and time = 12:00 \n", 370 | "print(posterior_prob(2, 12, 1))" 371 | ] 372 | }, 373 | { 374 | "cell_type": "code", 375 | "execution_count": 83, 376 | "metadata": {}, 377 | "outputs": [ 378 | { 379 | "name": "stdout", 380 | "output_type": "stream", 381 | "text": [ 382 | "uint8_t X[37][2] = {{0,0},{0,1},{0,2},{0,3},{0,4},{0,4},{0,5},{0,6},{1,7},{1,8},{0,8},{1,9},{1,9},{2,10},{2,11},{3,12},{3,12},{1,12},{3,13},{3,13},{3,14},{1,14},{2,15},{0,15},{2,16},{2,17},{0,17},{1,18},{1,18},{1,19},{0,19},{0,20},{0,20},{0,21},{0,21},{0,22},{0,23}};\n" 383 | ] 384 | } 385 | ], 386 | "source": [ 387 | "# === Step 11: print features as C array =======================================\n", 388 | "print(\"uint8_t X[%d][%d] = {\" %(np.shape(X)[0], np.shape(X)[1]), end='')\n", 389 | "for i in range(np.shape(X)[0]): # rows\n", 390 | " print(\"{\", end='')\n", 391 | " for j in range(np.shape(X)[1]): # columns\n", 392 | " if (j == (np.shape(X)[1]-1)):\n", 393 | " print(\"%d\" %(X[i,j]), end='')\n", 394 | " else:\n", 395 | " print(\"%d,\" %(X[i,j]), end='')\n", 396 | " if (i == (np.shape(X)[0]-1)):\n", 397 | " print(\"}\", end='')\n", 398 | " else:\n", 399 | " print(\"},\", end='')\n", 400 | "print(\"};\")" 401 | ] 402 | }, 403 | { 404 | "cell_type": "code", 405 | "execution_count": 84, 406 | "metadata": {}, 407 | "outputs": [ 408 | { 409 | "name": "stdout", 410 | "output_type": "stream", 411 | "text": [ 412 | "uint8_t y[37] = {0,0,0,0,0,0,1,1,1,0,1,0,1,0,0,0,0,1,0,0,0,1,0,1,0,0,1,0,1,0,1,1,1,1,1,1,1};\n" 413 | ] 414 | } 415 | ], 416 | "source": [ 417 | "# === Step 12: print label as C array ==========================================\n", 418 | "print(\"uint8_t y[%d] = {\" %(np.shape(y)[0]), end='')\n", 419 | "for i in range(np.shape(y)[0]):\n", 420 | " if (i == (np.shape(y)[0]-1)):\n", 421 | " print(\"%d\" %(y[i]), end='')\n", 422 | " else:\n", 423 | " print(\"%d,\" %(y[i]), end='')\n", 424 | "print(\"};\")" 425 | ] 426 | }, 427 | { 428 | "cell_type": "code", 429 | "execution_count": null, 430 | "metadata": {}, 431 | "outputs": [], 432 | "source": [] 433 | } 434 | ], 435 | "metadata": { 436 | "kernelspec": { 437 | "display_name": "Python 3", 438 | "language": "python", 439 | "name": "python3" 440 | }, 441 | "language_info": { 442 | "codemirror_mode": { 443 | "name": "ipython", 444 | "version": 3 445 | }, 446 | "file_extension": ".py", 447 | "mimetype": "text/x-python", 448 | "name": "python", 449 | "nbconvert_exporter": "python", 450 | "pygments_lexer": "ipython3", 451 | "version": "3.8.3" 452 | } 453 | }, 454 | "nbformat": 4, 455 | "nbformat_minor": 4 456 | } 457 | -------------------------------------------------------------------------------- /3_naive_bayes/1_python_model/intelligent-lighting.csv: -------------------------------------------------------------------------------- 1 | Light Sensor,Time,Light State 2 | 0,00:00,Off 3 | 0,01:00,Off 4 | 0,02:00,Off 5 | 0,03:00,Off 6 | 0,04:00,Off 7 | 0.1,04:00,Off 8 | 0.1,05:00,On 9 | 0.2,06:00,On 10 | 0.3,07:00,On 11 | 0.4,08:00,Off 12 | 0.2,08:00,On 13 | 0.5,09:00,Off 14 | 0.3,09:00,On 15 | 0.6,10:00,Off 16 | 0.7,11:00,Off 17 | 0.9,12:00,Off 18 | 1,12:00,Off 19 | 0.4,12:00,On 20 | 0.9,13:00,Off 21 | 1,13:00,Off 22 | 0.8,14:00,Off 23 | 0.3,14:00,On 24 | 0.7,15:00,Off 25 | 0.2,15:00,On 26 | 0.6,16:00,Off 27 | 0.6,17:00,Off 28 | 0.1,17:00,On 29 | 0.5,18:00,Off 30 | 0.3,18:00,On 31 | 0.5,19:00,Off 32 | 0.2,19:00,On 33 | 0.1,20:00,On 34 | 0,20:00,On 35 | 0.1,21:00,On 36 | 0,21:00,On 37 | 0,22:00,On 38 | 0,23:00,On 39 | -------------------------------------------------------------------------------- /3_naive_bayes/1_python_model/rain-prediction.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Naive Bayes, Part 2\n", 8 | "\n", 9 | "Derived from:\n", 10 | "\n", 11 | "https://stackoverflow.com/questions/48177318/what-does-this-arg-max-notation-mean-in-the-scikit-learn-docs-for-naive-bayes\n", 12 | "\n", 13 | "### Naive Bayes by Example 2\n", 14 | "In part 1, you have seen a simple example of Naive Bayes classifier for fruit calssification. The model only has one input feature which is color. Now let's start with a slightly complex example that has more than one input feature.\n", 15 | "\n", 16 | "Consider a fictional training data that describes the weather conditions as shown in the following table. Given the weather conditions, each tuple classifies the conditions as will it rain ('Yes') or not ('No').\n", 17 | "\n", 18 | "| No. | Outlook | Temperature | Humidity | Rain |\n", 19 | "|-----|---------|-------------|----------|------|\n", 20 | "| 1 | Cloudy | Cool | High | Yes |\n", 21 | "| 2 | Sunny | Mild | High | No |\n", 22 | "| 3 | Cloudy | Hot | Normal | No |\n", 23 | "| 4 | Sunny | Cool | Normal | No |\n", 24 | "| 5 | Sunny | Hot | Low | No |\n", 25 | "| 6 | Cloudy | Mild | Normal | Yes |\n", 26 | "| 7 | Cloudy | Hot | High | Yes |\n", 27 | "| 8 | Cloudy | Cool | Low | No |\n", 28 | "| 9 | Sunny | Cool | High | Yes |\n", 29 | "| 10 | Sunny | Hot | High | No |\n", 30 | "| 11 | Cloudy | Hot | Low | No |\n", 31 | "| 12 | Cloudy | Cool | Normal | Yes |\n", 32 | "| 13 | Sunny | Mild | Low | No |\n", 33 | "| 14 | Cloudy | Cool | Low | Yes |\n", 34 | "| 15 | Sunny | Mild | Low | No |\n", 35 | "\n", 36 | "In this training data, we have three features which are outlook, temperature, and humidity. Outlook has two possible values: cloudy and sunny. Temperature has three possible values: cool, mild, and hot. Humidity has three possible values: low, normal, and high. Then, we have one label that has two possible values: yes and no.\n", 37 | "\n", 38 | "We denote features as $X_{i}$ where $i=\\{1, 2, 3\\}$ that corresponds to outlook, temperature, and humidity, repectively. We denote label as $y$. Naive Bayes classifier assumes each of the features is independence. In fact, the independence assumption is never true, but often works well in practice.\n", 39 | "\n", 40 | "In part 1, you have Naive Bayes classifier as follow:\n", 41 | "$$P(y|X)\\propto P(X|y)P(y)$$\n", 42 | "where $X$ is input feature and $y$ is output label that you want to predict. If you have more than one feature, then the Naive Bayes classifier formula becomes:\n", 43 | "$$P(y|X_{1},...,X_{n})\\propto P(X_{1}|y)...P(X_{n}|y)P(y)$$\n", 44 | "where $X_{1}$ to $X_{n}$ are input features. You can caclulate the likelihood probability by multiplying all conditional probability of the features $X_{i}$ given label $y$ which can be expressed as:\n", 45 | "$$P(y|X_{1},...,X_{n})\\propto P(y)\\prod_{i=1}^{n}P(X_{i}|y)$$\n", 46 | "\n", 47 | "Back to our example, let's say today is cloudy, the temperature is cool, and the humidity is normal, can you predict will it rain today? Well, let's apply the same steps as in the example in part 1. Here, we want to calculate the following:\n", 48 | "\n", 49 | "$$P(y=yes|X_{1}=cloudy,X_{2}=cool,X_{3}=normal) \\propto P(y=yes)P(X_{1}=cloudy|y=yes)P(X_{2}=cool|y=yes)P(X_{3}=normal|y=yes)$$\n", 50 | "$$P(y=no|X_{1}=cloudy,X_{2}=cool,X_{3}=normal) \\propto P(y=no)P(X_{1}=cloudy|y=no)P(X_{2}=cool|y=no)P(X_{3}=normal|y=no)$$\n", 51 | "\n", 52 | "First, create a frequency table for each feature of the training data as follows:\n", 53 | "\n", 54 | "| Outlook | Yes | No | Total |\n", 55 | "|---------|-------|--------|-------|\n", 56 | "| Cloudy | 5 | 3 | 8 |\n", 57 | "| Sunny | 1 | 6 | 7 |\n", 58 | "| Total | 6 | 9 | 15 |\n", 59 | "\n", 60 | "| Temperature | Yes | No | Total |\n", 61 | "|-------------|-------|--------|-------|\n", 62 | "| Cool | 4 | 2 | 6 |\n", 63 | "| Mild | 1 | 3 | 4 |\n", 64 | "| Hot | 1 | 4 | 5 |\n", 65 | "| Total | 6 | 9 | 15 |\n", 66 | "\n", 67 | "| Humidity | Yes | No | Total |\n", 68 | "|----------|-------|--------|-------|\n", 69 | "| Low | 1 | 5 | 6 |\n", 70 | "| Normal | 2 | 2 | 4 |\n", 71 | "| High | 3 | 2 | 5 |\n", 72 | "| Total | 6 | 9 | 15 |\n", 73 | "\n", 74 | "#### **Step 1: compute the probabilities for each value of the label**\n", 75 | "Out of 15 observations, you have 6 yes and 9 no. So the respective probabilities are:\n", 76 | "$$P(y=yes)=\\frac{6}{15}$$\n", 77 | "$$P(y=no)=\\frac{9}{15}$$\n", 78 | "\n", 79 | "#### **Step 2: compute the conditional probability**\n", 80 | "Out of 6 yes, you have 5 cloudy. So the probability is:\n", 81 | "$$P(X_{1}=cloudy|y=yes)=\\frac{5}{6}$$\n", 82 | "Out of 6 yes, you have 4 cool. So the probability is:\n", 83 | "$$P(X_{2}=cool|y=yes)=\\frac{4}{6}$$\n", 84 | "Out of 6 yes, you have 2 normal. So the probability is:\n", 85 | "$$P(X_{3}=normal|y=yes)=\\frac{2}{6}$$\n", 86 | "Out of 9 no, you have 3 cloudy. So the probability is:\n", 87 | "$$P(X_{1}=cloudy|y=no)=\\frac{3}{9}$$\n", 88 | "Out of 9 no, you have 2 cool. So the probability is:\n", 89 | "$$P(X_{2}=cool|y=no)=\\frac{2}{9}$$\n", 90 | "Out of 9 no, you have 2 normal. So the probability is:\n", 91 | "$$P(X_{3}=normal|y=no)=\\frac{2}{9}$$\n", 92 | "\n", 93 | "#### **Step 3: subtitute all the three probabilities into the Naive Bayes formula**\n", 94 | "$$P(y=yes|X_{1}=cloudy,X_{2}=cool,X_{3}=normal) \\propto \\frac{6}{15}\\frac{5}{6}\\frac{4}{6}\\frac{2}{6}=\\frac{240}{3240}=0.07407407407$$\n", 95 | "$$P(y=no|X_{1}=cloudy,X_{2}=cool,X_{3}=normal) \\propto \\frac{9}{15}\\frac{3}{9}\\frac{2}{9}\\frac{2}{9}=\\frac{108}{10935}=0.0098765432$$\n", 96 | "\n", 97 | "Since $P(y=yes|X_{1}=cloudy,X_{2}=cool,X_{3}=normal) > P(y=no|X_{1}=cloudy,X_{2}=cool,X_{3}=normal)$, which means 'yes' get higher probability than 'no', then 'yes' will be our predicted output." 98 | ] 99 | }, 100 | { 101 | "cell_type": "markdown", 102 | "metadata": {}, 103 | "source": [ 104 | "### The Naive Bayes Classifier Formula (Updated)\n", 105 | "To be more mathematically precise, you can rewrite the Naive Bayes classifier formula in this form:\n", 106 | "$$\\hat{y}=\\arg\\max_{y}P(y)\\prod_{i=1}^{n}P(X_{i}|y)$$\n", 107 | "where $\\hat{y}$ is the prediction. In statistics, the hat is used to denote an estimator or an estimated/predicted value. The $\\arg\\max$ of a function is the value of the input, i.e. the 'argument' at the maximum. In other words, it is the label $y$ that has maximum probability. In the above example, the label $y$ that has maximum probability is 'yes'. So, $\\hat{y}=yes$." 108 | ] 109 | }, 110 | { 111 | "cell_type": "code", 112 | "execution_count": null, 113 | "metadata": {}, 114 | "outputs": [], 115 | "source": [] 116 | } 117 | ], 118 | "metadata": { 119 | "kernelspec": { 120 | "display_name": "Python 3", 121 | "language": "python", 122 | "name": "python3" 123 | }, 124 | "language_info": { 125 | "codemirror_mode": { 126 | "name": "ipython", 127 | "version": 3 128 | }, 129 | "file_extension": ".py", 130 | "mimetype": "text/x-python", 131 | "name": "python", 132 | "nbconvert_exporter": "python", 133 | "pygments_lexer": "ipython3", 134 | "version": "3.8.3" 135 | } 136 | }, 137 | "nbformat": 4, 138 | "nbformat_minor": 4 139 | } 140 | -------------------------------------------------------------------------------- /3_naive_bayes/2_c_model/.gitignore: -------------------------------------------------------------------------------- 1 | /.metadata/ 2 | -------------------------------------------------------------------------------- /3_naive_bayes/2_c_model/intelligent-lighting-c-arduino-esp32/intelligent-lighting-c-arduino-esp32.ino: -------------------------------------------------------------------------------- 1 | // Author: Erwin Ouyang, aiotedge.tech 2 | // Date : 9 Aug 2020 3 | 4 | #define NUM_OF_ROWS(arr) ((int)(sizeof(arr)/sizeof(arr)[0])) 5 | #define NUM_OF_COLS(arr) ((int)(sizeof(arr)[0]/sizeof(arr)[0][0])) 6 | 7 | uint8_t X[37][2] = {{0,0},{0,1},{0,2},{0,3},{0,4},{0,4},{0,5},{0,6},{1,7},{1,8},{0,8},{1,9},{1,9},{2,10},{2,11},{3,12},{3,12},{1,12},{3,13},{3,13},{3,14},{1,14},{2,15},{0,15},{2,16},{2,17},{0,17},{1,18},{1,18},{1,19},{0,19},{0,20},{0,20},{0,21},{0,21},{0,22},{0,23}}; 8 | uint8_t y[37] = {0,0,0,0,0,0,1,1,1,0,1,0,1,0,0,0,0,1,0,0,0,1,0,1,0,0,1,0,1,0,1,1,1,1,1,1,1}; 9 | uint8_t freq_table_lsensor[4][2] = {{0}}; 10 | uint8_t freq_table_time[24][2] = {{0}}; 11 | 12 | void setup() 13 | { 14 | // Serial port for debugging purposes 15 | Serial.begin(115200); 16 | 17 | create_freq_table_lsensor(); 18 | create_freq_table_time(); 19 | 20 | Serial.printf("=== Intelligent Lighting =================================================\n"); 21 | Serial.printf("=== Learn the users' preferences to provide a suitable light condition ===\n"); 22 | } 23 | 24 | void loop() 25 | { 26 | if (Serial.available()) 27 | { 28 | String light_sensor_str = Serial.readStringUntil(','); 29 | uint8_t light_sensor_int = (uint8_t)light_sensor_str.toInt(); 30 | 31 | String time_str = Serial.readStringUntil('\n'); 32 | uint8_t time_int = (uint8_t)time_str.toInt(); 33 | 34 | Serial.printf("Light Sensor: %d, Time: %d:00\n", light_sensor_int, time_int); 35 | Serial.printf("P(y=Off|X)=%.6f, ", posterior_prob(light_sensor_int, time_int, 0)); 36 | Serial.printf("P(y=On|X)=%.6f\n", posterior_prob(light_sensor_int, time_int, 1)); 37 | Serial.printf("Prediction=%s\n", (!predict(light_sensor_int, time_int)) ? "Off" : "On"); 38 | } 39 | } 40 | 41 | void create_freq_table_lsensor() 42 | { 43 | for (int i = 0; i < sizeof(y); i++) 44 | freq_table_lsensor[X[i][0]][y[i]]++; 45 | } 46 | 47 | void create_freq_table_time() 48 | { 49 | for (int i = 0; i < sizeof(y); i++) 50 | freq_table_time[X[i][1]][y[i]]++; 51 | } 52 | 53 | float label_prior_prob(uint8_t light_state) 54 | { 55 | uint8_t count = 0; 56 | float prob_lap = 0.0; 57 | 58 | for (int i = 0; i < sizeof(y); i++) 59 | count += (y[i] == light_state) ? 1 : 0; 60 | prob_lap = (float)(count+1)/(sizeof(y)+2*1); 61 | 62 | return prob_lap; 63 | } 64 | 65 | float likelihood(uint8_t light_sensor, uint8_t time, uint8_t light_state) 66 | { 67 | float sum_freq_table_lsensor = 0; 68 | float sum_freq_table_time = 0; 69 | float prob_lsensor_lstate_lap = 0.0; 70 | float prob_time_lstate_lap = 0.0; 71 | float prob_lsensor_time_lstate_lap = 0.0; 72 | 73 | // calculate probability of light sensor=light_sensor given light state=light_state 74 | // and add laplace smoothing 75 | for (int i = 0; i < NUM_OF_ROWS(freq_table_lsensor); i++) 76 | sum_freq_table_lsensor += freq_table_lsensor[i][light_state]; 77 | prob_lsensor_lstate_lap = (float)(freq_table_lsensor[light_sensor][light_state]+1) / 78 | (sum_freq_table_lsensor+4*1); 79 | 80 | // calculate probability of time=time given light state=light_state 81 | // and add laplace smoothing 82 | for (int i = 0; i < NUM_OF_ROWS(freq_table_time); i++) 83 | sum_freq_table_time += freq_table_time[i][light_state]; 84 | prob_time_lstate_lap = (float)(freq_table_time[time][light_state]+1) / 85 | (sum_freq_table_time+24*1); 86 | 87 | // calculate probability of light sensor=light_sensor and time=time given 88 | // light state=light_state 89 | prob_lsensor_time_lstate_lap = prob_lsensor_lstate_lap * prob_time_lstate_lap; 90 | 91 | return prob_lsensor_time_lstate_lap; 92 | } 93 | 94 | float posterior_prob(uint8_t light_sensor, uint8_t time, uint8_t light_state) 95 | { 96 | return likelihood(light_sensor, time, light_state) * label_prior_prob(light_state); 97 | } 98 | 99 | uint8_t predict(uint8_t light_sensor, uint8_t time) 100 | { 101 | uint8_t light_state_prediction = 0; 102 | if (posterior_prob(light_sensor, time, 0) > posterior_prob(light_sensor, time, 1)) 103 | light_state_prediction = 0; 104 | else 105 | light_state_prediction = 1; 106 | 107 | return light_state_prediction; 108 | } 109 | -------------------------------------------------------------------------------- /3_naive_bayes/2_c_model/intelligent-lighting-c-gcc/.cproject: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 30 | 31 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 78 | 79 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /3_naive_bayes/2_c_model/intelligent-lighting-c-gcc/.gitignore: -------------------------------------------------------------------------------- 1 | /Debug/ 2 | -------------------------------------------------------------------------------- /3_naive_bayes/2_c_model/intelligent-lighting-c-gcc/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | intelligent-lighting-c-gcc 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder 10 | clean,full,incremental, 11 | 12 | 13 | 14 | 15 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder 16 | full,incremental, 17 | 18 | 19 | 20 | 21 | 22 | org.eclipse.cdt.core.cnature 23 | org.eclipse.cdt.managedbuilder.core.managedBuildNature 24 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature 25 | 26 | 27 | -------------------------------------------------------------------------------- /3_naive_bayes/2_c_model/intelligent-lighting-c-gcc/.settings/language.settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /3_naive_bayes/2_c_model/intelligent-lighting-c-gcc/src/intelligent-lighting.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define NUM_OF_ROWS(arr) ((int)(sizeof(arr)/sizeof(arr)[0])) 4 | #define NUM_OF_COLS(arr) ((int)(sizeof(arr)[0]/sizeof(arr)[0][0])) 5 | 6 | uint8_t X[37][2] = {{0,0},{0,1},{0,2},{0,3},{0,4},{0,4},{0,5},{0,6},{1,7},{1,8},{0,8},{1,9},{1,9},{2,10},{2,11},{3,12},{3,12},{1,12},{3,13},{3,13},{3,14},{1,14},{2,15},{0,15},{2,16},{2,17},{0,17},{1,18},{1,18},{1,19},{0,19},{0,20},{0,20},{0,21},{0,21},{0,22},{0,23}}; 7 | uint8_t y[37] = {0,0,0,0,0,0,1,1,1,0,1,0,1,0,0,0,0,1,0,0,0,1,0,1,0,0,1,0,1,0,1,1,1,1,1,1,1}; 8 | uint8_t freq_table_lsensor[4][2] = {{0}}; 9 | uint8_t freq_table_time[24][2] = {{0}}; 10 | 11 | void create_freq_table_lsensor(void); 12 | void create_freq_table_time(void); 13 | float label_prior_prob(uint8_t light_state); 14 | float likelihood(uint8_t light_sensor, uint8_t time, uint8_t light_state); 15 | float posterior_prob(uint8_t light_sensor, uint8_t time, uint8_t light_state); 16 | uint8_t predict(uint8_t light_sensor, uint8_t time); 17 | 18 | int main() 19 | { 20 | create_freq_table_lsensor(); 21 | create_freq_table_time(); 22 | 23 | uint8_t light_sensor = 2; 24 | uint8_t time = 12; 25 | printf("Light Sensor: %d, Time: %d:00\n", light_sensor, time); 26 | printf("P(y=Off|X)=%.6f, ", posterior_prob(light_sensor, time, 0)); 27 | printf("P(y=On|X)=%.6f\n", posterior_prob(light_sensor, time, 1)); 28 | printf("Prediction=%s\n", (!predict(light_sensor, time)) ? "Off" : "On"); 29 | 30 | return 0; 31 | } 32 | 33 | void create_freq_table_lsensor() 34 | { 35 | for (int i = 0; i < sizeof(y); i++) 36 | freq_table_lsensor[X[i][0]][y[i]]++; 37 | } 38 | 39 | void create_freq_table_time() 40 | { 41 | for (int i = 0; i < sizeof(y); i++) 42 | freq_table_time[X[i][1]][y[i]]++; 43 | } 44 | 45 | float label_prior_prob(uint8_t light_state) 46 | { 47 | uint8_t count = 0; 48 | float prob_lap = 0.0; 49 | 50 | for (int i = 0; i < sizeof(y); i++) 51 | count += (y[i] == light_state) ? 1 : 0; 52 | prob_lap = (float)(count+1)/(sizeof(y)+2*1); 53 | 54 | return prob_lap; 55 | } 56 | 57 | float likelihood(uint8_t light_sensor, uint8_t time, uint8_t light_state) 58 | { 59 | float sum_freq_table_lsensor = 0; 60 | float sum_freq_table_time = 0; 61 | float prob_lsensor_lstate_lap = 0.0; 62 | float prob_time_lstate_lap = 0.0; 63 | float prob_lsensor_time_lstate_lap = 0.0; 64 | 65 | // calculate probability of light sensor=light_sensor given light state=light_state 66 | // and add laplace smoothing 67 | for (int i = 0; i < NUM_OF_ROWS(freq_table_lsensor); i++) 68 | sum_freq_table_lsensor += freq_table_lsensor[i][light_state]; 69 | prob_lsensor_lstate_lap = (float)(freq_table_lsensor[light_sensor][light_state]+1) / 70 | (sum_freq_table_lsensor+4*1); 71 | 72 | // calculate probability of time=time given light state=light_state 73 | // and add laplace smoothing 74 | for (int i = 0; i < NUM_OF_ROWS(freq_table_time); i++) 75 | sum_freq_table_time += freq_table_time[i][light_state]; 76 | prob_time_lstate_lap = (float)(freq_table_time[time][light_state]+1) / 77 | (sum_freq_table_time+24*1); 78 | 79 | // calculate probability of light sensor=light_sensor and time=time given 80 | // light state=light_state 81 | prob_lsensor_time_lstate_lap = prob_lsensor_lstate_lap * prob_time_lstate_lap; 82 | 83 | return prob_lsensor_time_lstate_lap; 84 | } 85 | 86 | float posterior_prob(uint8_t light_sensor, uint8_t time, uint8_t light_state) 87 | { 88 | return likelihood(light_sensor, time, light_state) * label_prior_prob(light_state); 89 | } 90 | 91 | uint8_t predict(uint8_t light_sensor, uint8_t time) 92 | { 93 | uint8_t light_state_prediction = 0; 94 | if (posterior_prob(light_sensor, time, 0) > posterior_prob(light_sensor, time, 1)) 95 | light_state_prediction = 0; 96 | else 97 | light_state_prediction = 1; 98 | 99 | return light_state_prediction; 100 | } 101 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Erwin Ouyang 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Machine Learning on Arduino 2 | 3 | Machine learning algorithm implementation in Python and C Arduino from scratch. Machine learning deployment on Arduino, particulary ESP32. 4 | 5 | ## Donation 6 | If this project help you reduce time to develop, please make a small donation. I suggest **$5**, but you can choose the amount. We need your help to pay for web hosting, buy new components and equipment for new tutorials, and buy a cup of coffee :). Alternately, you can make a donation by sending me Bitcoin, at address **1JN3zEw8NqCr8bn4UQa3TfZXaz7UZnb5bH** 7 | 8 | [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://paypal.me/erwin168?locale.x=en_US) 9 | -------------------------------------------------------------------------------- /esp32_examples/esp32-devkit-arduino-adc-trimpot/esp32-devkit-arduino-adc-trimpot.ino: -------------------------------------------------------------------------------- 1 | // Author: Erwin Ouyang, aiotedge.tech 2 | // Date : 8 Mar 2020 3 | 4 | void setup() 5 | { 6 | // Initialize serial port 7 | Serial.begin(115200); 8 | } 9 | 10 | void loop() 11 | { 12 | // Read trimpot value using ADC 13 | int trimpot = analogRead(27); 14 | // Print the value to the serial monitor 15 | Serial.println(trimpot); 16 | delay(1000); 17 | } 18 | 19 | -------------------------------------------------------------------------------- /esp32_examples/esp32-devkit-arduino-button-interrupt/esp32-devkit-arduino-button-interrupt.ino: -------------------------------------------------------------------------------- 1 | // Author: Erwin Ouyang, aiotedge.tech 2 | // Date : 8 Mar 2020 3 | 4 | void IRAM_ATTR button_isr() 5 | { 6 | // *** Read button state *** 7 | if (digitalRead(12) == LOW) 8 | { 9 | // If button is pressed, then turn on the LED 10 | digitalWrite(2, HIGH); 11 | } 12 | else 13 | { 14 | // If button is not pressed, then turn off the LED 15 | digitalWrite(2, LOW); 16 | } 17 | } 18 | 19 | void setup() 20 | { 21 | // Set GPIO pin as output for on-board LED 22 | pinMode(2, OUTPUT); 23 | // Set GPIO pin as input with pull-up resistor for button 24 | pinMode(12, INPUT_PULLUP); 25 | // Attach interrupt handler (ISR) to the button 26 | attachInterrupt(digitalPinToInterrupt(12), button_isr, CHANGE); 27 | } 28 | 29 | void loop() 30 | { 31 | } 32 | 33 | -------------------------------------------------------------------------------- /esp32_examples/esp32-devkit-arduino-button/esp32-devkit-arduino-button.ino: -------------------------------------------------------------------------------- 1 | // Author: Erwin Ouyang, aiotedge.tech 2 | // Date : 8 Mar 2020 3 | 4 | void setup() 5 | { 6 | // Set GPIO pin as output for on-board LED 7 | pinMode(2, OUTPUT); 8 | // Set GPIO pin as input with pull-up resistor for button 9 | pinMode(12, INPUT_PULLUP); 10 | } 11 | 12 | void loop() 13 | { 14 | // *** Read button state *** 15 | if (digitalRead(12) == LOW) 16 | { 17 | // If button is pressed, then turn on the LED 18 | digitalWrite(2, HIGH); 19 | } 20 | else 21 | { 22 | // If button is not pressed, then turn off the LED 23 | digitalWrite(2, LOW); 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /esp32_examples/esp32-devkit-arduino-chip-info/esp32-devkit-arduino-chip-info.ino: -------------------------------------------------------------------------------- 1 | // Author: Erwin Ouyang, aiotedge.tech 2 | // Date : 8 Mar 2020 3 | 4 | void setup() 5 | { 6 | // Initialize serial port 7 | Serial.begin(115200); 8 | 9 | // Print chip information 10 | Serial.printf("Chip ID (eFuse MAC): 0x%X\n", ESP.getEfuseMac()); 11 | Serial.printf("Chip revision: %d\n", ESP.getChipRevision()); 12 | Serial.printf("CPU frequency: %d MHz\n", ESP.getCpuFreqMHz()); 13 | Serial.printf("Cycle count: %u\n", ESP.getCycleCount()); 14 | Serial.printf("Free heap: %d bytes\n", ESP.getFreeHeap()); 15 | Serial.printf("Flash chip size: %d bytes\n", ESP.getFlashChipSize()); 16 | Serial.printf("Flash chip speed: %d Hz\n", ESP.getFlashChipSpeed()); 17 | Serial.printf("Flash chip mode: 0x%X\n", ESP.getFlashChipMode()); 18 | Serial.printf("SDK version: %s\n", ESP.getSdkVersion()); 19 | } 20 | 21 | void loop() 22 | { 23 | } 24 | 25 | -------------------------------------------------------------------------------- /esp32_examples/esp32-devkit-arduino-dht11-oled-128x64/esp32-devkit-arduino-dht11-oled-128x64.ino: -------------------------------------------------------------------------------- 1 | // Author: Erwin Ouyang, aiotedge.tech 2 | // Date : 8 Mar 2020 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | // DHT11 pins 10 | #define DHTPIN 22 11 | #define DHTTYPE DHT11 12 | 13 | // I2C pins 14 | #define I2C_SDA 33 15 | #define I2C_SCL 32 16 | // *** Check library setting *** 17 | #if (SSD1306_LCDHEIGHT != 64) // 128 x 64 pixel display 18 | #error("Height incorrect, please fix Adafruit_SSD1306.h!"); 19 | #endif 20 | // OLED I2C address 21 | #define OLED_ADDR 0x3C 22 | 23 | // Setup DHT pin and type 24 | DHT dht(DHTPIN, DHTTYPE); 25 | // OLED object declaration 26 | Adafruit_SSD1306 oled; 27 | 28 | void setup() 29 | { 30 | // Initialize DHT11 31 | dht.begin(); 32 | 33 | // Initialize I2C pins 34 | Wire.begin(I2C_SDA, I2C_SCL, 400000); 35 | 36 | // *** Initialize and clear display *** 37 | oled.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR); 38 | // Clear OLED buffer 39 | oled.clearDisplay(); 40 | } 41 | 42 | void loop() 43 | { 44 | // *** Read temperature and humidity *** 45 | float celcius = dht.readTemperature(); 46 | float humidity = dht.readHumidity(); 47 | 48 | // *** Display temperature and humidity on OLED *** 49 | oled.clearDisplay(); 50 | oled.setTextSize(2); 51 | oled.setTextColor(WHITE); 52 | oled.setCursor(45, 12); 53 | oled.printf("%.0f%cC", celcius, (char)247); 54 | oled.setCursor(50, 38); 55 | oled.printf("%.0f%%", humidity); 56 | oled.display(); 57 | 58 | delay(1000); 59 | } 60 | 61 | -------------------------------------------------------------------------------- /esp32_examples/esp32-devkit-arduino-dht11/esp32-devkit-arduino-dht11.ino: -------------------------------------------------------------------------------- 1 | // Author: Erwin Ouyang, aiotedge.tech 2 | // Date : 23 Feb 2020 3 | 4 | #include 5 | 6 | #define DHTPIN 22 7 | #define DHTTYPE DHT11 8 | 9 | // Setup DHT pin and type 10 | DHT dht(DHTPIN, DHTTYPE); 11 | 12 | void setup() 13 | { 14 | // Initialize serial port 15 | Serial.begin(115200); 16 | // Initialize DHT sensor 17 | dht.begin(); 18 | } 19 | 20 | void loop() 21 | { 22 | // Read temperature 23 | float temp = dht.readTemperature(); 24 | // Read humidity 25 | float hum = dht.readHumidity(); 26 | 27 | // Print temperature 28 | Serial.print("Temperature: "); 29 | Serial.print(temp); 30 | Serial.print("°C "); 31 | Serial.print("Humidity: "); 32 | Serial.print(hum); 33 | Serial.println("%"); 34 | 35 | // Maximum sampling rate of DHT11 is 1Hz 36 | // So, the minimum delay is one second 37 | delay(1000); 38 | } 39 | 40 | -------------------------------------------------------------------------------- /esp32_examples/esp32-devkit-arduino-ds1307-oled-128x64/esp32-devkit-arduino-ds1307-oled-128x64.ino: -------------------------------------------------------------------------------- 1 | // Author: Erwin Ouyang, aiotedge.tech 2 | // Date : 8 Mar 2020 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | // I2C pins 10 | #define I2C_SDA 33 11 | #define I2C_SCL 32 12 | 13 | // *** Check library setting *** 14 | #if (SSD1306_LCDHEIGHT != 64) // 128 x 64 pixel display 15 | #error("Height incorrect, please fix Adafruit_SSD1306.h!"); 16 | #endif 17 | 18 | // OLED I2C address 19 | #define OLED_ADDR 0x3C 20 | 21 | // RTC object declaration 22 | RtcDS1307 rtc(Wire); 23 | 24 | // OLED object declaration 25 | Adafruit_SSD1306 oled; 26 | 27 | void setup() 28 | { 29 | // Initialize I2C pins 30 | Wire.begin(I2C_SDA, I2C_SCL, 400000); 31 | 32 | // Initialize RTC 33 | rtc.Begin(); 34 | // *** Set RTC date and time to code compiled time *** 35 | RtcDateTime compiled = RtcDateTime(__DATE__, __TIME__); 36 | rtc.SetDateTime(compiled); 37 | rtc.SetIsRunning(true); 38 | 39 | // *** Initialize and clear display *** 40 | oled.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR); 41 | // Clear OLED buffer 42 | oled.clearDisplay(); 43 | } 44 | 45 | void loop() 46 | { 47 | // Read RTC date and time 48 | RtcDateTime now = rtc.GetDateTime(); 49 | 50 | // *** Display RTC date and time on OLED *** 51 | oled.clearDisplay(); 52 | oled.setTextSize(1); 53 | oled.setTextColor(WHITE); 54 | oled.setCursor(8, 30); 55 | oled.printf("%04d/%02d/%02d %02d:%02d:%02d", 56 | now.Year(), now.Month(), now.Day(), 57 | now.Hour(), now.Minute(), now.Second()); 58 | oled.display(); 59 | 60 | delay(1000); 61 | } 62 | 63 | -------------------------------------------------------------------------------- /esp32_examples/esp32-devkit-arduino-ds1307/esp32-devkit-arduino-ds1307.ino: -------------------------------------------------------------------------------- 1 | // Author: Erwin Ouyang, aiotedge.tech 2 | // Date : 8 Mar 2020 3 | 4 | #include 5 | #include 6 | 7 | // I2C pins 8 | #define I2C_SDA 33 9 | #define I2C_SCL 32 10 | 11 | // RTC object declaration 12 | RtcDS1307 rtc(Wire); 13 | 14 | void setup() 15 | { 16 | // Initialize serial port 17 | Serial.begin(115200); 18 | 19 | // Initialize I2C pins 20 | Wire.begin(I2C_SDA, I2C_SCL, 400000); 21 | 22 | // Initialize RTC 23 | rtc.Begin(); 24 | // *** Set RTC date and time to code compiled time *** 25 | RtcDateTime compiled = RtcDateTime(__DATE__, __TIME__); 26 | rtc.SetDateTime(compiled); 27 | rtc.SetIsRunning(true); 28 | } 29 | 30 | void loop() 31 | { 32 | // Read RTC date and time 33 | RtcDateTime now = rtc.GetDateTime(); 34 | // Print RTC date and time to serial monitor 35 | Serial.printf("%04d/%02d/%02d %02d:%02d:%02d\n", 36 | now.Year(), now.Month(), now.Day(), 37 | now.Hour(), now.Minute(), now.Second()); 38 | delay(1000); 39 | } 40 | 41 | -------------------------------------------------------------------------------- /esp32_examples/esp32-devkit-arduino-led-on-board-pwm/esp32-devkit-arduino-led-on-board-pwm.ino: -------------------------------------------------------------------------------- 1 | // Author: Erwin Ouyang, aiotedge.tech 2 | // Date : 29 Feb 2020 3 | 4 | // On-board LED's GPIO pin 5 | #define LED_ON_BOARD 2 6 | 7 | // PWM parameters 8 | const int channel = 0; 9 | const int freq = 1000; 10 | const int res = 10; 11 | 12 | void setup() 13 | { 14 | // Configure PWM 15 | ledcSetup(channel, freq, res); 16 | // Attach the PWM channel to the LED 17 | ledcAttachPin(LED_ON_BOARD, channel); 18 | } 19 | 20 | void loop() 21 | { 22 | // *** Increase brightness *** 23 | for (int i = 0; i <= 1023; i += 20) 24 | { 25 | ledcWrite(channel, i); 26 | delay(25); 27 | } 28 | // *** Decrease brightness *** 29 | for (int i = 1023; i >= 0; i -= 20) 30 | { 31 | ledcWrite(channel, i); 32 | delay(25); 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /esp32_examples/esp32-devkit-arduino-led-on-board/esp32-devkit-arduino-led-on-board.ino: -------------------------------------------------------------------------------- 1 | // Author: Erwin Ouyang, aiotedge.tech 2 | // Date : 22 Feb 2020 3 | 4 | void setup() 5 | { 6 | // Set GPIO pin as output for on-board LED 7 | pinMode(2, OUTPUT); 8 | } 9 | 10 | void loop() 11 | { 12 | // Turn on LED 13 | digitalWrite(2, HIGH); 14 | delay(500); 15 | // Turn off LED 16 | digitalWrite(2, LOW); 17 | delay(500); 18 | } 19 | 20 | -------------------------------------------------------------------------------- /esp32_examples/esp32-devkit-arduino-oled-128x64-bitmap/esp32-devkit-arduino-oled-128x64-bitmap.ino: -------------------------------------------------------------------------------- 1 | // Author: Erwin Ouyang, aiotedge.tech 2 | // Date : 8 Mar 2020 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | // I2C pins 9 | #define I2C_SDA 33 10 | #define I2C_SCL 32 11 | 12 | // *** Check library setting *** 13 | #if (SSD1306_LCDHEIGHT != 64) // 128 x 64 pixel display 14 | #error("Height incorrect, please fix Adafruit_SSD1306.h!"); 15 | #endif 16 | 17 | // OLED I2C address 18 | #define OLED_ADDR 0x3C 19 | 20 | // OLED object declaration 21 | Adafruit_SSD1306 oled; 22 | 23 | // Bitmap 24 | static const unsigned char PROGMEM temperature_bmp[] = 25 | { 26 | B00000011, B11001111, 27 | B00000110, B01100000, 28 | B00000100, B00101111, 29 | B00000100, B00100000, 30 | B00000100, B00101111, 31 | B00000101, B10100000, 32 | B00000101, B10101111, 33 | B00000101, B10100000, 34 | B00001101, B10110000, 35 | B00011011, B11011000, 36 | B00110111, B11101100, 37 | B00101111, B11110100, 38 | B00101111, B11110100, 39 | B00110111, B11101100, 40 | B00011000, B00011000, 41 | B00001111, B11110000 42 | }; 43 | static const unsigned char PROGMEM humidity_bmp[] = 44 | { 45 | B00000001, B10000000, 46 | B00000011, B11000000, 47 | B00000110, B01100000, 48 | B00000100, B00100000, 49 | B00001100, B00110000, 50 | B00001000, B00010000, 51 | B00011000, B00011000, 52 | B00010000, B00001000, 53 | B00110100, B00001100, 54 | B00101100, B00000100, 55 | B00101100, B00000100, 56 | B00101100, B00000100, 57 | B00110110, B00001100, 58 | B00011011, B00011000, 59 | B00001100, B00110000, 60 | B00000111, B11100000 61 | }; 62 | 63 | void setup() 64 | { 65 | // Initialize I2C pins 66 | Wire.begin(I2C_SDA, I2C_SCL, 400000); 67 | 68 | // *** Initialize and clear display *** 69 | oled.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR); 70 | // Clear OLED buffer 71 | oled.clearDisplay(); 72 | 73 | // *** Display bitmap *** 74 | oled.drawBitmap(32, 16, temperature_bmp, 16, 16, 1); 75 | oled.drawBitmap(32, 36, humidity_bmp, 16, 16, 1); 76 | 77 | // *** Display text *** 78 | oled.setTextSize(2); 79 | oled.setTextColor(WHITE); 80 | oled.setCursor(55, 16); 81 | oled.printf("25%cC", (char)247); 82 | oled.setCursor(55, 36); 83 | oled.print("60%"); 84 | 85 | // Show OLED buffer on the display 86 | oled.display(); 87 | } 88 | 89 | void loop() 90 | { 91 | } 92 | 93 | -------------------------------------------------------------------------------- /esp32_examples/esp32-devkit-arduino-oled-128x64/esp32-devkit-arduino-oled-128x64.ino: -------------------------------------------------------------------------------- 1 | // Author: Erwin Ouyang, aiotedge.tech 2 | // Date : 8 Mar 2020 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | // I2C pins 9 | #define I2C_SDA 33 10 | #define I2C_SCL 32 11 | 12 | // *** Check library setting *** 13 | #if (SSD1306_LCDHEIGHT != 64) // 128 x 64 pixel display 14 | #error("Height incorrect, please fix Adafruit_SSD1306.h!"); 15 | #endif 16 | 17 | // OLED I2C address 18 | #define OLED_ADDR 0x3C 19 | 20 | // OLED object declaration 21 | Adafruit_SSD1306 oled; 22 | 23 | void setup() 24 | { 25 | // Initialize I2C pins 26 | Wire.begin(I2C_SDA, I2C_SCL, 400000); 27 | 28 | // *** Initialize and clear display *** 29 | oled.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR); 30 | // Clear OLED buffer 31 | oled.clearDisplay(); 32 | 33 | // *** Display text *** 34 | oled.setTextSize(1); 35 | oled.setTextColor(WHITE); 36 | oled.setCursor(27, 30); 37 | oled.print("Hello, world!"); 38 | 39 | // Show OLED buffer on the display 40 | oled.display(); 41 | } 42 | 43 | void loop() 44 | { 45 | } 46 | 47 | -------------------------------------------------------------------------------- /esp32_examples/esp32-devkit-arduino-serial-print/esp32-devkit-arduino-serial-print.ino: -------------------------------------------------------------------------------- 1 | // Author: Erwin Ouyang, aiotedge.tech 2 | // Date : 22 Feb 2020 3 | 4 | void setup() 5 | { 6 | // Initialize serial port 7 | Serial.begin(115200); 8 | } 9 | 10 | void loop() 11 | { 12 | // Print text 13 | Serial.println("Hello, World!"); 14 | delay(1000); 15 | } 16 | 17 | -------------------------------------------------------------------------------- /esp32_examples/esp32-devkit-arduino-serial-read/esp32-devkit-arduino-serial-read.ino: -------------------------------------------------------------------------------- 1 | // Author: Erwin Ouyang, aiotedge.tech 2 | // Date : 8 Mar 2020 3 | 4 | void setup() 5 | { 6 | // Initialize serial port 7 | Serial.begin(115200); 8 | } 9 | 10 | void loop() 11 | { 12 | // If there is data in receive buffer 13 | if (Serial.available() > 0) 14 | { 15 | // Read string from receive buffer 16 | String input = Serial.readString(); 17 | // Print to serial monitor 18 | Serial.print(input); 19 | } 20 | } 21 | 22 | -------------------------------------------------------------------------------- /esp32_examples/esp32-devkit-arduino-timer-interrupt/esp32-devkit-arduino-timer-interrupt.ino: -------------------------------------------------------------------------------- 1 | // Author: Erwin Ouyang, aiotedge.tech 2 | // Date : 8 Mar 2020 3 | 4 | #include 5 | 6 | Ticker ticker; 7 | 8 | void led_isr() 9 | { 10 | // Toggle LED 11 | digitalWrite(2, !digitalRead(2)); 12 | } 13 | 14 | void setup() 15 | { 16 | // Set GPIO pin as output for on-board LED 17 | pinMode(2, OUTPUT); 18 | // Set ticker to generate interrupt every 1 second 19 | ticker.attach(1, led_isr); 20 | } 21 | 22 | void loop() 23 | { 24 | } 25 | 26 | -------------------------------------------------------------------------------- /esp32_examples/esp32-devkit-arduino-timer-millis/esp32-devkit-arduino-timer-millis.ino: -------------------------------------------------------------------------------- 1 | // Author: Erwin Ouyang, aiotedge.tech 2 | // Date : 8 Mar 2020 3 | 4 | void setup() 5 | { 6 | // Initialize serial port 7 | Serial.begin(115200); 8 | } 9 | 10 | void loop() 11 | { 12 | // Get milliseconds value 13 | unsigned long ms = millis(); 14 | // Print milliseconds value to serial monitor 15 | Serial.println(ms); 16 | delay(1000); 17 | } 18 | 19 | -------------------------------------------------------------------------------- /esp32_examples/esp32-devkit-arduino-web-server-bootstrap-button/data/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | ESP32 Web Page 4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 |
12 |
13 |

Write LED State using AJAX

14 |
15 | 16 | 17 |
18 |
19 |
20 |
21 | 33 | 34 | -------------------------------------------------------------------------------- /esp32_examples/esp32-devkit-arduino-web-server-bootstrap-button/data/popper.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) Federico Zivolo 2017 3 | Distributed under the MIT License (license terms are at http://opensource.org/licenses/MIT). 4 | */(function(e,t){'object'==typeof exports&&'undefined'!=typeof module?module.exports=t():'function'==typeof define&&define.amd?define(t):e.Popper=t()})(this,function(){'use strict';function e(e){return e&&'[object Function]'==={}.toString.call(e)}function t(e,t){if(1!==e.nodeType)return[];var o=getComputedStyle(e,null);return t?o[t]:o}function o(e){return'HTML'===e.nodeName?e:e.parentNode||e.host}function n(e){if(!e)return document.body;switch(e.nodeName){case'HTML':case'BODY':return e.ownerDocument.body;case'#document':return e.body;}var i=t(e),r=i.overflow,p=i.overflowX,s=i.overflowY;return /(auto|scroll)/.test(r+s+p)?e:n(o(e))}function r(e){var o=e&&e.offsetParent,i=o&&o.nodeName;return i&&'BODY'!==i&&'HTML'!==i?-1!==['TD','TABLE'].indexOf(o.nodeName)&&'static'===t(o,'position')?r(o):o:e?e.ownerDocument.documentElement:document.documentElement}function p(e){var t=e.nodeName;return'BODY'!==t&&('HTML'===t||r(e.firstElementChild)===e)}function s(e){return null===e.parentNode?e:s(e.parentNode)}function d(e,t){if(!e||!e.nodeType||!t||!t.nodeType)return document.documentElement;var o=e.compareDocumentPosition(t)&Node.DOCUMENT_POSITION_FOLLOWING,i=o?e:t,n=o?t:e,a=document.createRange();a.setStart(i,0),a.setEnd(n,0);var l=a.commonAncestorContainer;if(e!==l&&t!==l||i.contains(n))return p(l)?l:r(l);var f=s(e);return f.host?d(f.host,t):d(e,s(t).host)}function a(e){var t=1=o.clientWidth&&i>=o.clientHeight}),l=0i[e]&&!t.escapeWithReference&&(n=_(p[o],i[e]-('right'===e?p.width:p.height))),pe({},o,n)}};return n.forEach(function(e){var t=-1===['left','top'].indexOf(e)?'secondary':'primary';p=se({},p,s[t](e))}),e.offsets.popper=p,e},priority:['left','right','top','bottom'],padding:5,boundariesElement:'scrollParent'},keepTogether:{order:400,enabled:!0,fn:function(e){var t=e.offsets,o=t.popper,i=t.reference,n=e.placement.split('-')[0],r=X,p=-1!==['top','bottom'].indexOf(n),s=p?'right':'bottom',d=p?'left':'top',a=p?'width':'height';return o[s]r(i[s])&&(e.offsets.popper[d]=r(i[s])),e}},arrow:{order:500,enabled:!0,fn:function(e,o){var i;if(!F(e.instance.modifiers,'arrow','keepTogether'))return e;var n=o.element;if('string'==typeof n){if(n=e.instance.popper.querySelector(n),!n)return e;}else if(!e.instance.popper.contains(n))return console.warn('WARNING: `arrow.element` must be child of its popper element!'),e;var r=e.placement.split('-')[0],p=e.offsets,s=p.popper,d=p.reference,a=-1!==['left','right'].indexOf(r),l=a?'height':'width',f=a?'Top':'Left',m=f.toLowerCase(),h=a?'left':'top',g=a?'bottom':'right',u=L(n)[l];d[g]-us[g]&&(e.offsets.popper[m]+=d[m]+u-s[g]),e.offsets.popper=c(e.offsets.popper);var b=d[m]+d[l]/2-u/2,w=t(e.instance.popper),y=parseFloat(w['margin'+f],10),E=parseFloat(w['border'+f+'Width'],10),v=b-e.offsets.popper[m]-y-E;return v=J(_(s[l]-u,v),0),e.arrowElement=n,e.offsets.arrow=(i={},pe(i,m,Math.round(v)),pe(i,h,''),i),e},element:'[x-arrow]'},flip:{order:600,enabled:!0,fn:function(e,t){if(k(e.instance.modifiers,'inner'))return e;if(e.flipped&&e.placement===e.originalPlacement)return e;var o=y(e.instance.popper,e.instance.reference,t.padding,t.boundariesElement),i=e.placement.split('-')[0],n=x(i),r=e.placement.split('-')[1]||'',p=[];switch(t.behavior){case le.FLIP:p=[i,n];break;case le.CLOCKWISE:p=q(i);break;case le.COUNTERCLOCKWISE:p=q(i,!0);break;default:p=t.behavior;}return p.forEach(function(s,d){if(i!==s||p.length===d+1)return e;i=e.placement.split('-')[0],n=x(i);var a=e.offsets.popper,l=e.offsets.reference,f=X,m='left'===i&&f(a.right)>f(l.left)||'right'===i&&f(a.left)f(l.top)||'bottom'===i&&f(a.top)f(o.right),g=f(a.top)f(o.bottom),b='left'===i&&h||'right'===i&&c||'top'===i&&g||'bottom'===i&&u,w=-1!==['top','bottom'].indexOf(i),y=!!t.flipVariations&&(w&&'start'===r&&h||w&&'end'===r&&c||!w&&'start'===r&&g||!w&&'end'===r&&u);(m||b||y)&&(e.flipped=!0,(m||b)&&(i=p[d+1]),y&&(r=K(r)),e.placement=i+(r?'-'+r:''),e.offsets.popper=se({},e.offsets.popper,S(e.instance.popper,e.offsets.reference,e.placement)),e=C(e.instance.modifiers,e,'flip'))}),e},behavior:'flip',padding:5,boundariesElement:'viewport'},inner:{order:700,enabled:!1,fn:function(e){var t=e.placement,o=t.split('-')[0],i=e.offsets,n=i.popper,r=i.reference,p=-1!==['left','right'].indexOf(o),s=-1===['top','left'].indexOf(o);return n[p?'left':'top']=r[o]-(s?n[p?'width':'height']:0),e.placement=x(t),e.offsets.popper=c(n),e}},hide:{order:800,enabled:!0,fn:function(e){if(!F(e.instance.modifiers,'hide','preventOverflow'))return e;var t=e.offsets.reference,o=T(e.instance.modifiers,function(e){return'preventOverflow'===e.name}).boundaries;if(t.bottomo.right||t.top>o.bottom||t.right 5 | #include 6 | #include 7 | 8 | // On-board LED's GPIO pin 9 | #define LED_ON_BOARD 2 10 | 11 | const char ssid[] = "Huawei-E5573"; 12 | const char pass[] = "huaweie5573"; 13 | 14 | // TCP server port for HTTP 15 | const uint16_t port = 80; 16 | 17 | // Create AsyncWebServer object 18 | AsyncWebServer server(port); 19 | 20 | void setup() 21 | { 22 | // Set GPIO pin as output for on-board LED 23 | pinMode(LED_ON_BOARD, OUTPUT); 24 | // Setup serial communication 25 | Serial.begin(115200); 26 | 27 | // Initialize SPIFFS 28 | if (!SPIFFS.begin(true)) 29 | { 30 | Serial.println("An error has occurred while mounting SPIFFS"); 31 | return; 32 | } 33 | 34 | // *** Connect to a WiFi access point *** 35 | Serial.printf("Connecting to %s ...\n", ssid); 36 | WiFi.mode(WIFI_STA); 37 | WiFi.begin(ssid, pass); 38 | if (WiFi.waitForConnectResult() != WL_CONNECTED) 39 | { 40 | Serial.printf("WiFi connect failed! Rebooting ...\n"); 41 | delay(1000); 42 | ESP.restart(); 43 | } 44 | Serial.printf("Connected\n"); 45 | Serial.printf("IP address: %s\n", WiFi.localIP().toString().c_str()); 46 | 47 | // Handler for root request 48 | server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) 49 | { 50 | request->send(SPIFFS, "/index.html"); 51 | }); 52 | 53 | // Handler for turning on the LED 54 | server.on("/on", HTTP_POST, [](AsyncWebServerRequest *request){ 55 | digitalWrite(LED_ON_BOARD, HIGH); 56 | request->send(303); 57 | }); 58 | 59 | // Handler for turning of the LED 60 | server.on("/off", HTTP_POST, [](AsyncWebServerRequest *request){ 61 | digitalWrite(LED_ON_BOARD, LOW); 62 | request->send(303); 63 | }); 64 | 65 | // Handler for Bootstrap libraries 66 | server.on("/bootstrap.min.css", HTTP_GET, [](AsyncWebServerRequest *request) { 67 | request->send(SPIFFS, "/bootstrap.min.css"); 68 | }); 69 | server.on("/jquery-3.3.1.min.js", HTTP_GET, [](AsyncWebServerRequest *request) { 70 | request->send(SPIFFS, "/jquery-3.3.1.min.js"); 71 | }); 72 | server.on("/popper.min.js", HTTP_GET, [](AsyncWebServerRequest *request) { 73 | request->send(SPIFFS, "/popper.min.js"); 74 | }); 75 | server.on("/bootstrap.min.js", HTTP_GET, [](AsyncWebServerRequest *request) { 76 | request->send(SPIFFS, "/bootstrap.min.js"); 77 | }); 78 | 79 | // Start server 80 | server.begin(); 81 | } 82 | 83 | void loop() 84 | { 85 | } 86 | 87 | -------------------------------------------------------------------------------- /esp32_examples/esp32-devkit-arduino-web-server-bootstrap-card/data/a076d05399.js: -------------------------------------------------------------------------------- 1 | window.FontAwesomeKitConfig = {"asyncLoading":{"enabled":true},"autoA11y":{"enabled":true},"baseUrl":"https://kit-free.fontawesome.com","license":"free","method":"css","minify":{"enabled":true},"v4shim":{"enabled":false},"version":"latest"}; 2 | !function(){!function(){if(!(void 0===window.Element||"classList"in document.documentElement)){var e,t,n,i=Array.prototype,o=i.push,a=i.splice,s=i.join;r.prototype={add:function(e){this.contains(e)||(o.call(this,e),this.el.className=this.toString())},contains:function(e){return-1!=this.el.className.indexOf(e)},item:function(e){return this[e]||null},remove:function(e){if(this.contains(e)){for(var t=0;t 2 | 3 | ESP32 Web Page 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 |
13 |
14 |
15 |
16 | DHT11 Sensor 17 |
18 |
19 |
20 |

N/A°C

21 |

N/A%

22 |
23 |
24 |
25 |
26 |
27 |
28 | 45 | 46 | -------------------------------------------------------------------------------- /esp32_examples/esp32-devkit-arduino-web-server-bootstrap-card/data/popper.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) Federico Zivolo 2017 3 | Distributed under the MIT License (license terms are at http://opensource.org/licenses/MIT). 4 | */(function(e,t){'object'==typeof exports&&'undefined'!=typeof module?module.exports=t():'function'==typeof define&&define.amd?define(t):e.Popper=t()})(this,function(){'use strict';function e(e){return e&&'[object Function]'==={}.toString.call(e)}function t(e,t){if(1!==e.nodeType)return[];var o=getComputedStyle(e,null);return t?o[t]:o}function o(e){return'HTML'===e.nodeName?e:e.parentNode||e.host}function n(e){if(!e)return document.body;switch(e.nodeName){case'HTML':case'BODY':return e.ownerDocument.body;case'#document':return e.body;}var i=t(e),r=i.overflow,p=i.overflowX,s=i.overflowY;return /(auto|scroll)/.test(r+s+p)?e:n(o(e))}function r(e){var o=e&&e.offsetParent,i=o&&o.nodeName;return i&&'BODY'!==i&&'HTML'!==i?-1!==['TD','TABLE'].indexOf(o.nodeName)&&'static'===t(o,'position')?r(o):o:e?e.ownerDocument.documentElement:document.documentElement}function p(e){var t=e.nodeName;return'BODY'!==t&&('HTML'===t||r(e.firstElementChild)===e)}function s(e){return null===e.parentNode?e:s(e.parentNode)}function d(e,t){if(!e||!e.nodeType||!t||!t.nodeType)return document.documentElement;var o=e.compareDocumentPosition(t)&Node.DOCUMENT_POSITION_FOLLOWING,i=o?e:t,n=o?t:e,a=document.createRange();a.setStart(i,0),a.setEnd(n,0);var l=a.commonAncestorContainer;if(e!==l&&t!==l||i.contains(n))return p(l)?l:r(l);var f=s(e);return f.host?d(f.host,t):d(e,s(t).host)}function a(e){var t=1=o.clientWidth&&i>=o.clientHeight}),l=0i[e]&&!t.escapeWithReference&&(n=_(p[o],i[e]-('right'===e?p.width:p.height))),pe({},o,n)}};return n.forEach(function(e){var t=-1===['left','top'].indexOf(e)?'secondary':'primary';p=se({},p,s[t](e))}),e.offsets.popper=p,e},priority:['left','right','top','bottom'],padding:5,boundariesElement:'scrollParent'},keepTogether:{order:400,enabled:!0,fn:function(e){var t=e.offsets,o=t.popper,i=t.reference,n=e.placement.split('-')[0],r=X,p=-1!==['top','bottom'].indexOf(n),s=p?'right':'bottom',d=p?'left':'top',a=p?'width':'height';return o[s]r(i[s])&&(e.offsets.popper[d]=r(i[s])),e}},arrow:{order:500,enabled:!0,fn:function(e,o){var i;if(!F(e.instance.modifiers,'arrow','keepTogether'))return e;var n=o.element;if('string'==typeof n){if(n=e.instance.popper.querySelector(n),!n)return e;}else if(!e.instance.popper.contains(n))return console.warn('WARNING: `arrow.element` must be child of its popper element!'),e;var r=e.placement.split('-')[0],p=e.offsets,s=p.popper,d=p.reference,a=-1!==['left','right'].indexOf(r),l=a?'height':'width',f=a?'Top':'Left',m=f.toLowerCase(),h=a?'left':'top',g=a?'bottom':'right',u=L(n)[l];d[g]-us[g]&&(e.offsets.popper[m]+=d[m]+u-s[g]),e.offsets.popper=c(e.offsets.popper);var b=d[m]+d[l]/2-u/2,w=t(e.instance.popper),y=parseFloat(w['margin'+f],10),E=parseFloat(w['border'+f+'Width'],10),v=b-e.offsets.popper[m]-y-E;return v=J(_(s[l]-u,v),0),e.arrowElement=n,e.offsets.arrow=(i={},pe(i,m,Math.round(v)),pe(i,h,''),i),e},element:'[x-arrow]'},flip:{order:600,enabled:!0,fn:function(e,t){if(k(e.instance.modifiers,'inner'))return e;if(e.flipped&&e.placement===e.originalPlacement)return e;var o=y(e.instance.popper,e.instance.reference,t.padding,t.boundariesElement),i=e.placement.split('-')[0],n=x(i),r=e.placement.split('-')[1]||'',p=[];switch(t.behavior){case le.FLIP:p=[i,n];break;case le.CLOCKWISE:p=q(i);break;case le.COUNTERCLOCKWISE:p=q(i,!0);break;default:p=t.behavior;}return p.forEach(function(s,d){if(i!==s||p.length===d+1)return e;i=e.placement.split('-')[0],n=x(i);var a=e.offsets.popper,l=e.offsets.reference,f=X,m='left'===i&&f(a.right)>f(l.left)||'right'===i&&f(a.left)f(l.top)||'bottom'===i&&f(a.top)f(o.right),g=f(a.top)f(o.bottom),b='left'===i&&h||'right'===i&&c||'top'===i&&g||'bottom'===i&&u,w=-1!==['top','bottom'].indexOf(i),y=!!t.flipVariations&&(w&&'start'===r&&h||w&&'end'===r&&c||!w&&'start'===r&&g||!w&&'end'===r&&u);(m||b||y)&&(e.flipped=!0,(m||b)&&(i=p[d+1]),y&&(r=K(r)),e.placement=i+(r?'-'+r:''),e.offsets.popper=se({},e.offsets.popper,S(e.instance.popper,e.offsets.reference,e.placement)),e=C(e.instance.modifiers,e,'flip'))}),e},behavior:'flip',padding:5,boundariesElement:'viewport'},inner:{order:700,enabled:!1,fn:function(e){var t=e.placement,o=t.split('-')[0],i=e.offsets,n=i.popper,r=i.reference,p=-1!==['left','right'].indexOf(o),s=-1===['top','left'].indexOf(o);return n[p?'left':'top']=r[o]-(s?n[p?'width':'height']:0),e.placement=x(t),e.offsets.popper=c(n),e}},hide:{order:800,enabled:!0,fn:function(e){if(!F(e.instance.modifiers,'hide','preventOverflow'))return e;var t=e.offsets.reference,o=T(e.instance.modifiers,function(e){return'preventOverflow'===e.name}).boundaries;if(t.bottomo.right||t.top>o.bottom||t.right 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #define DHTPIN 22 11 | #define DHTTYPE DHT11 12 | 13 | // Setup DHT pin and type 14 | DHT dht(DHTPIN, DHTTYPE); 15 | 16 | const char ssid[] = "Huawei-E5573"; 17 | const char pass[] = "huaweie5573"; 18 | 19 | // TCP server port for HTTP 20 | const uint16_t port = 80; 21 | 22 | // Create AsyncWebServer object 23 | AsyncWebServer server(port); 24 | 25 | void setup() 26 | { 27 | // Setup serial communication 28 | Serial.begin(115200); 29 | // Initialize DHT sensor 30 | dht.begin(); 31 | 32 | // Initialize SPIFFS 33 | if (!SPIFFS.begin(true)) 34 | { 35 | Serial.println("An error has occurred while mounting SPIFFS"); 36 | return; 37 | } 38 | 39 | // *** Connect to a WiFi access point *** 40 | Serial.printf("Connecting to %s ...\n", ssid); 41 | WiFi.mode(WIFI_STA); 42 | WiFi.begin(ssid, pass); 43 | if (WiFi.waitForConnectResult() != WL_CONNECTED) 44 | { 45 | Serial.printf("WiFi connect failed! Rebooting ...\n"); 46 | delay(1000); 47 | ESP.restart(); 48 | } 49 | Serial.printf("Connected\n"); 50 | Serial.printf("IP address: %s\n", WiFi.localIP().toString().c_str()); 51 | 52 | // Handler for root request 53 | server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) 54 | { 55 | request->send(SPIFFS, "/index.html"); 56 | }); 57 | 58 | // Handler for DHT11 AJAX request 59 | server.on("/dht11_ajax", HTTP_POST, [](AsyncWebServerRequest *request) 60 | { 61 | // Read temperature and humidity 62 | float temp = dht.readTemperature(); 63 | float hum = dht.readHumidity(); 64 | 65 | // Send JSON response 66 | AsyncResponseStream *response = request->beginResponseStream("application/json"); 67 | DynamicJsonBuffer jsonBuffer; 68 | JsonObject &dht11 = jsonBuffer.createObject(); 69 | dht11["temp"] = String(temp); 70 | dht11["hum"] = String(hum); 71 | dht11.printTo(*response); 72 | request->send(response); 73 | }); 74 | 75 | // Handler for Bootstrap libraries 76 | server.on("/bootstrap.min.css", HTTP_GET, [](AsyncWebServerRequest *request) { 77 | request->send(SPIFFS, "/bootstrap.min.css"); 78 | }); 79 | server.on("/jquery-3.3.1.min.js", HTTP_GET, [](AsyncWebServerRequest *request) { 80 | request->send(SPIFFS, "/jquery-3.3.1.min.js"); 81 | }); 82 | server.on("/popper.min.js", HTTP_GET, [](AsyncWebServerRequest *request) { 83 | request->send(SPIFFS, "/popper.min.js"); 84 | }); 85 | server.on("/bootstrap.min.js", HTTP_GET, [](AsyncWebServerRequest *request) { 86 | request->send(SPIFFS, "/bootstrap.min.js"); 87 | }); 88 | server.on("/a076d05399.js", HTTP_GET, [](AsyncWebServerRequest *request) { 89 | request->send(SPIFFS, "/a076d05399.js"); 90 | }); 91 | 92 | // Start server 93 | server.begin(); 94 | } 95 | 96 | void loop() 97 | { 98 | } 99 | 100 | -------------------------------------------------------------------------------- /esp32_examples/esp32-devkit-arduino-web-server-bootstrap-chart/data/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ESP32 Web Page 5 | 6 | 7 | 8 | 9 | 10 | 21 | 22 | 23 |
24 |
25 |
26 |
27 |
28 | Temperature 29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 | 100 | 101 | -------------------------------------------------------------------------------- /esp32_examples/esp32-devkit-arduino-web-server-bootstrap-chart/data/popper.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) Federico Zivolo 2017 3 | Distributed under the MIT License (license terms are at http://opensource.org/licenses/MIT). 4 | */(function(e,t){'object'==typeof exports&&'undefined'!=typeof module?module.exports=t():'function'==typeof define&&define.amd?define(t):e.Popper=t()})(this,function(){'use strict';function e(e){return e&&'[object Function]'==={}.toString.call(e)}function t(e,t){if(1!==e.nodeType)return[];var o=getComputedStyle(e,null);return t?o[t]:o}function o(e){return'HTML'===e.nodeName?e:e.parentNode||e.host}function n(e){if(!e)return document.body;switch(e.nodeName){case'HTML':case'BODY':return e.ownerDocument.body;case'#document':return e.body;}var i=t(e),r=i.overflow,p=i.overflowX,s=i.overflowY;return /(auto|scroll)/.test(r+s+p)?e:n(o(e))}function r(e){var o=e&&e.offsetParent,i=o&&o.nodeName;return i&&'BODY'!==i&&'HTML'!==i?-1!==['TD','TABLE'].indexOf(o.nodeName)&&'static'===t(o,'position')?r(o):o:e?e.ownerDocument.documentElement:document.documentElement}function p(e){var t=e.nodeName;return'BODY'!==t&&('HTML'===t||r(e.firstElementChild)===e)}function s(e){return null===e.parentNode?e:s(e.parentNode)}function d(e,t){if(!e||!e.nodeType||!t||!t.nodeType)return document.documentElement;var o=e.compareDocumentPosition(t)&Node.DOCUMENT_POSITION_FOLLOWING,i=o?e:t,n=o?t:e,a=document.createRange();a.setStart(i,0),a.setEnd(n,0);var l=a.commonAncestorContainer;if(e!==l&&t!==l||i.contains(n))return p(l)?l:r(l);var f=s(e);return f.host?d(f.host,t):d(e,s(t).host)}function a(e){var t=1=o.clientWidth&&i>=o.clientHeight}),l=0i[e]&&!t.escapeWithReference&&(n=_(p[o],i[e]-('right'===e?p.width:p.height))),pe({},o,n)}};return n.forEach(function(e){var t=-1===['left','top'].indexOf(e)?'secondary':'primary';p=se({},p,s[t](e))}),e.offsets.popper=p,e},priority:['left','right','top','bottom'],padding:5,boundariesElement:'scrollParent'},keepTogether:{order:400,enabled:!0,fn:function(e){var t=e.offsets,o=t.popper,i=t.reference,n=e.placement.split('-')[0],r=X,p=-1!==['top','bottom'].indexOf(n),s=p?'right':'bottom',d=p?'left':'top',a=p?'width':'height';return o[s]r(i[s])&&(e.offsets.popper[d]=r(i[s])),e}},arrow:{order:500,enabled:!0,fn:function(e,o){var i;if(!F(e.instance.modifiers,'arrow','keepTogether'))return e;var n=o.element;if('string'==typeof n){if(n=e.instance.popper.querySelector(n),!n)return e;}else if(!e.instance.popper.contains(n))return console.warn('WARNING: `arrow.element` must be child of its popper element!'),e;var r=e.placement.split('-')[0],p=e.offsets,s=p.popper,d=p.reference,a=-1!==['left','right'].indexOf(r),l=a?'height':'width',f=a?'Top':'Left',m=f.toLowerCase(),h=a?'left':'top',g=a?'bottom':'right',u=L(n)[l];d[g]-us[g]&&(e.offsets.popper[m]+=d[m]+u-s[g]),e.offsets.popper=c(e.offsets.popper);var b=d[m]+d[l]/2-u/2,w=t(e.instance.popper),y=parseFloat(w['margin'+f],10),E=parseFloat(w['border'+f+'Width'],10),v=b-e.offsets.popper[m]-y-E;return v=J(_(s[l]-u,v),0),e.arrowElement=n,e.offsets.arrow=(i={},pe(i,m,Math.round(v)),pe(i,h,''),i),e},element:'[x-arrow]'},flip:{order:600,enabled:!0,fn:function(e,t){if(k(e.instance.modifiers,'inner'))return e;if(e.flipped&&e.placement===e.originalPlacement)return e;var o=y(e.instance.popper,e.instance.reference,t.padding,t.boundariesElement),i=e.placement.split('-')[0],n=x(i),r=e.placement.split('-')[1]||'',p=[];switch(t.behavior){case le.FLIP:p=[i,n];break;case le.CLOCKWISE:p=q(i);break;case le.COUNTERCLOCKWISE:p=q(i,!0);break;default:p=t.behavior;}return p.forEach(function(s,d){if(i!==s||p.length===d+1)return e;i=e.placement.split('-')[0],n=x(i);var a=e.offsets.popper,l=e.offsets.reference,f=X,m='left'===i&&f(a.right)>f(l.left)||'right'===i&&f(a.left)f(l.top)||'bottom'===i&&f(a.top)f(o.right),g=f(a.top)f(o.bottom),b='left'===i&&h||'right'===i&&c||'top'===i&&g||'bottom'===i&&u,w=-1!==['top','bottom'].indexOf(i),y=!!t.flipVariations&&(w&&'start'===r&&h||w&&'end'===r&&c||!w&&'start'===r&&g||!w&&'end'===r&&u);(m||b||y)&&(e.flipped=!0,(m||b)&&(i=p[d+1]),y&&(r=K(r)),e.placement=i+(r?'-'+r:''),e.offsets.popper=se({},e.offsets.popper,S(e.instance.popper,e.offsets.reference,e.placement)),e=C(e.instance.modifiers,e,'flip'))}),e},behavior:'flip',padding:5,boundariesElement:'viewport'},inner:{order:700,enabled:!1,fn:function(e){var t=e.placement,o=t.split('-')[0],i=e.offsets,n=i.popper,r=i.reference,p=-1!==['left','right'].indexOf(o),s=-1===['top','left'].indexOf(o);return n[p?'left':'top']=r[o]-(s?n[p?'width':'height']:0),e.placement=x(t),e.offsets.popper=c(n),e}},hide:{order:800,enabled:!0,fn:function(e){if(!F(e.instance.modifiers,'hide','preventOverflow'))return e;var t=e.offsets.reference,o=T(e.instance.modifiers,function(e){return'preventOverflow'===e.name}).boundaries;if(t.bottomo.right||t.top>o.bottom||t.right 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #define DHTPIN 22 11 | #define DHTTYPE DHT11 12 | 13 | // Setup DHT pin and type 14 | DHT dht(DHTPIN, DHTTYPE); 15 | 16 | const char ssid[] = "Huawei-E5573"; 17 | const char pass[] = "huaweie5573"; 18 | 19 | // TCP server port for HTTP 20 | const uint16_t port = 80; 21 | 22 | // Create AsyncWebServer object 23 | AsyncWebServer server(port); 24 | 25 | // Global variable for storing temperature value 26 | int temp; 27 | 28 | void setup() 29 | { 30 | // Setup serial communication 31 | Serial.begin(115200); 32 | // Initialize DHT sensor 33 | dht.begin(); 34 | 35 | // Initialize SPIFFS 36 | if (!SPIFFS.begin(true)) 37 | { 38 | Serial.println("An error has occurred while mounting SPIFFS"); 39 | return; 40 | } 41 | 42 | // *** Connect to a WiFi access point *** 43 | Serial.printf("Connecting to %s ...\n", ssid); 44 | WiFi.mode(WIFI_STA); 45 | WiFi.begin(ssid, pass); 46 | if (WiFi.waitForConnectResult() != WL_CONNECTED) 47 | { 48 | Serial.printf("WiFi connect failed! Rebooting ...\n"); 49 | delay(1000); 50 | ESP.restart(); 51 | } 52 | Serial.printf("Connected\n"); 53 | Serial.printf("IP address: %s\n", WiFi.localIP().toString().c_str()); 54 | 55 | // Handler for root request 56 | server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) 57 | { 58 | request->send(SPIFFS, "/index.html"); 59 | }); 60 | 61 | // Handler for DHT11 AJAX request 62 | server.on("/temperature", HTTP_POST, [](AsyncWebServerRequest *request) 63 | { 64 | // Send temperature 65 | request->send(200, "text/plain", readDHT11Temperature()); 66 | }); 67 | 68 | // Handler for Bootstrap libraries 69 | server.on("/bootstrap.min.css", HTTP_GET, [](AsyncWebServerRequest *request) { 70 | request->send(SPIFFS, "/bootstrap.min.css"); 71 | }); 72 | server.on("/jquery-3.3.1.min.js", HTTP_GET, [](AsyncWebServerRequest *request) { 73 | request->send(SPIFFS, "/jquery-3.3.1.min.js"); 74 | }); 75 | server.on("/popper.min.js", HTTP_GET, [](AsyncWebServerRequest *request) { 76 | request->send(SPIFFS, "/popper.min.js"); 77 | }); 78 | server.on("/bootstrap.min.js", HTTP_GET, [](AsyncWebServerRequest *request) { 79 | request->send(SPIFFS, "/bootstrap.min.js"); 80 | }); 81 | server.on("/highcharts.js", HTTP_GET, [](AsyncWebServerRequest *request) { 82 | request->send(SPIFFS, "/highcharts.js"); 83 | }); 84 | 85 | // Start server 86 | server.begin(); 87 | } 88 | 89 | void loop() 90 | { 91 | } 92 | 93 | String readDHT11Temperature() 94 | { 95 | // Read temperature 96 | int t = (int)dht.readTemperature(); 97 | // Update temperature value only if it is not NaN and between -15 and 35 98 | temp = (isnan(t)) ? temp : (((t >= -15) && (t <= 35)) ? t : temp); 99 | 100 | return String(temp); 101 | } 102 | 103 | -------------------------------------------------------------------------------- /esp32_examples/esp32-devkit-arduino-web-server-bootstrap-gauge/data/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ESP32 Web Page 5 | 6 | 7 | 8 | 9 | 10 | 11 | 22 | 23 | 24 |
25 |
26 |
27 |
28 |
29 | Temperature 30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 | 71 | 72 | -------------------------------------------------------------------------------- /esp32_examples/esp32-devkit-arduino-web-server-bootstrap-gauge/data/popper.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) Federico Zivolo 2017 3 | Distributed under the MIT License (license terms are at http://opensource.org/licenses/MIT). 4 | */(function(e,t){'object'==typeof exports&&'undefined'!=typeof module?module.exports=t():'function'==typeof define&&define.amd?define(t):e.Popper=t()})(this,function(){'use strict';function e(e){return e&&'[object Function]'==={}.toString.call(e)}function t(e,t){if(1!==e.nodeType)return[];var o=getComputedStyle(e,null);return t?o[t]:o}function o(e){return'HTML'===e.nodeName?e:e.parentNode||e.host}function n(e){if(!e)return document.body;switch(e.nodeName){case'HTML':case'BODY':return e.ownerDocument.body;case'#document':return e.body;}var i=t(e),r=i.overflow,p=i.overflowX,s=i.overflowY;return /(auto|scroll)/.test(r+s+p)?e:n(o(e))}function r(e){var o=e&&e.offsetParent,i=o&&o.nodeName;return i&&'BODY'!==i&&'HTML'!==i?-1!==['TD','TABLE'].indexOf(o.nodeName)&&'static'===t(o,'position')?r(o):o:e?e.ownerDocument.documentElement:document.documentElement}function p(e){var t=e.nodeName;return'BODY'!==t&&('HTML'===t||r(e.firstElementChild)===e)}function s(e){return null===e.parentNode?e:s(e.parentNode)}function d(e,t){if(!e||!e.nodeType||!t||!t.nodeType)return document.documentElement;var o=e.compareDocumentPosition(t)&Node.DOCUMENT_POSITION_FOLLOWING,i=o?e:t,n=o?t:e,a=document.createRange();a.setStart(i,0),a.setEnd(n,0);var l=a.commonAncestorContainer;if(e!==l&&t!==l||i.contains(n))return p(l)?l:r(l);var f=s(e);return f.host?d(f.host,t):d(e,s(t).host)}function a(e){var t=1=o.clientWidth&&i>=o.clientHeight}),l=0i[e]&&!t.escapeWithReference&&(n=_(p[o],i[e]-('right'===e?p.width:p.height))),pe({},o,n)}};return n.forEach(function(e){var t=-1===['left','top'].indexOf(e)?'secondary':'primary';p=se({},p,s[t](e))}),e.offsets.popper=p,e},priority:['left','right','top','bottom'],padding:5,boundariesElement:'scrollParent'},keepTogether:{order:400,enabled:!0,fn:function(e){var t=e.offsets,o=t.popper,i=t.reference,n=e.placement.split('-')[0],r=X,p=-1!==['top','bottom'].indexOf(n),s=p?'right':'bottom',d=p?'left':'top',a=p?'width':'height';return o[s]r(i[s])&&(e.offsets.popper[d]=r(i[s])),e}},arrow:{order:500,enabled:!0,fn:function(e,o){var i;if(!F(e.instance.modifiers,'arrow','keepTogether'))return e;var n=o.element;if('string'==typeof n){if(n=e.instance.popper.querySelector(n),!n)return e;}else if(!e.instance.popper.contains(n))return console.warn('WARNING: `arrow.element` must be child of its popper element!'),e;var r=e.placement.split('-')[0],p=e.offsets,s=p.popper,d=p.reference,a=-1!==['left','right'].indexOf(r),l=a?'height':'width',f=a?'Top':'Left',m=f.toLowerCase(),h=a?'left':'top',g=a?'bottom':'right',u=L(n)[l];d[g]-us[g]&&(e.offsets.popper[m]+=d[m]+u-s[g]),e.offsets.popper=c(e.offsets.popper);var b=d[m]+d[l]/2-u/2,w=t(e.instance.popper),y=parseFloat(w['margin'+f],10),E=parseFloat(w['border'+f+'Width'],10),v=b-e.offsets.popper[m]-y-E;return v=J(_(s[l]-u,v),0),e.arrowElement=n,e.offsets.arrow=(i={},pe(i,m,Math.round(v)),pe(i,h,''),i),e},element:'[x-arrow]'},flip:{order:600,enabled:!0,fn:function(e,t){if(k(e.instance.modifiers,'inner'))return e;if(e.flipped&&e.placement===e.originalPlacement)return e;var o=y(e.instance.popper,e.instance.reference,t.padding,t.boundariesElement),i=e.placement.split('-')[0],n=x(i),r=e.placement.split('-')[1]||'',p=[];switch(t.behavior){case le.FLIP:p=[i,n];break;case le.CLOCKWISE:p=q(i);break;case le.COUNTERCLOCKWISE:p=q(i,!0);break;default:p=t.behavior;}return p.forEach(function(s,d){if(i!==s||p.length===d+1)return e;i=e.placement.split('-')[0],n=x(i);var a=e.offsets.popper,l=e.offsets.reference,f=X,m='left'===i&&f(a.right)>f(l.left)||'right'===i&&f(a.left)f(l.top)||'bottom'===i&&f(a.top)f(o.right),g=f(a.top)f(o.bottom),b='left'===i&&h||'right'===i&&c||'top'===i&&g||'bottom'===i&&u,w=-1!==['top','bottom'].indexOf(i),y=!!t.flipVariations&&(w&&'start'===r&&h||w&&'end'===r&&c||!w&&'start'===r&&g||!w&&'end'===r&&u);(m||b||y)&&(e.flipped=!0,(m||b)&&(i=p[d+1]),y&&(r=K(r)),e.placement=i+(r?'-'+r:''),e.offsets.popper=se({},e.offsets.popper,S(e.instance.popper,e.offsets.reference,e.placement)),e=C(e.instance.modifiers,e,'flip'))}),e},behavior:'flip',padding:5,boundariesElement:'viewport'},inner:{order:700,enabled:!1,fn:function(e){var t=e.placement,o=t.split('-')[0],i=e.offsets,n=i.popper,r=i.reference,p=-1!==['left','right'].indexOf(o),s=-1===['top','left'].indexOf(o);return n[p?'left':'top']=r[o]-(s?n[p?'width':'height']:0),e.placement=x(t),e.offsets.popper=c(n),e}},hide:{order:800,enabled:!0,fn:function(e){if(!F(e.instance.modifiers,'hide','preventOverflow'))return e;var t=e.offsets.reference,o=T(e.instance.modifiers,function(e){return'preventOverflow'===e.name}).boundaries;if(t.bottomo.right||t.top>o.bottom||t.right 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #define DHTPIN 22 11 | #define DHTTYPE DHT11 12 | 13 | // Setup DHT pin and type 14 | DHT dht(DHTPIN, DHTTYPE); 15 | 16 | const char ssid[] = "Huawei-E5573"; 17 | const char pass[] = "huaweie5573"; 18 | 19 | // TCP server port for HTTP 20 | const uint16_t port = 80; 21 | 22 | // Create AsyncWebServer object 23 | AsyncWebServer server(port); 24 | 25 | // Global variable for storing temperature value 26 | int temp; 27 | 28 | void setup() 29 | { 30 | // Setup serial communication 31 | Serial.begin(115200); 32 | // Initialize DHT sensor 33 | dht.begin(); 34 | 35 | // Initialize SPIFFS 36 | if (!SPIFFS.begin(true)) 37 | { 38 | Serial.println("An error has occurred while mounting SPIFFS"); 39 | return; 40 | } 41 | 42 | // *** Connect to a WiFi access point *** 43 | Serial.printf("Connecting to %s ...\n", ssid); 44 | WiFi.mode(WIFI_STA); 45 | WiFi.begin(ssid, pass); 46 | if (WiFi.waitForConnectResult() != WL_CONNECTED) 47 | { 48 | Serial.printf("WiFi connect failed! Rebooting ...\n"); 49 | delay(1000); 50 | ESP.restart(); 51 | } 52 | Serial.printf("Connected\n"); 53 | Serial.printf("IP address: %s\n", WiFi.localIP().toString().c_str()); 54 | 55 | // Handler for root request 56 | server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) 57 | { 58 | request->send(SPIFFS, "/index.html"); 59 | }); 60 | 61 | // Handler for DHT11 AJAX request 62 | server.on("/temperature", HTTP_POST, [](AsyncWebServerRequest *request) 63 | { 64 | // Send temperature 65 | request->send(200, "text/plain", readDHT11Temperature()); 66 | }); 67 | 68 | // Handler for Bootstrap libraries 69 | server.on("/bootstrap.min.css", HTTP_GET, [](AsyncWebServerRequest *request) { 70 | request->send(SPIFFS, "/bootstrap.min.css"); 71 | }); 72 | server.on("/jquery-3.3.1.min.js", HTTP_GET, [](AsyncWebServerRequest *request) { 73 | request->send(SPIFFS, "/jquery-3.3.1.min.js"); 74 | }); 75 | server.on("/popper.min.js", HTTP_GET, [](AsyncWebServerRequest *request) { 76 | request->send(SPIFFS, "/popper.min.js"); 77 | }); 78 | server.on("/bootstrap.min.js", HTTP_GET, [](AsyncWebServerRequest *request) { 79 | request->send(SPIFFS, "/bootstrap.min.js"); 80 | }); 81 | server.on("/raphael-2.1.4.min.js", HTTP_GET, [](AsyncWebServerRequest *request) { 82 | request->send(SPIFFS, "/raphael-2.1.4.min.js"); 83 | }); 84 | server.on("/justgage.js", HTTP_GET, [](AsyncWebServerRequest *request) { 85 | request->send(SPIFFS, "/justgage.js"); 86 | }); 87 | 88 | // Start server 89 | server.begin(); 90 | } 91 | 92 | void loop() 93 | { 94 | } 95 | 96 | String readDHT11Temperature() 97 | { 98 | // Read temperature 99 | int t = (int)dht.readTemperature(); 100 | // Update temperature value only if it is not NaN and between -15 and 35 101 | temp = (isnan(t)) ? temp : (((t >= -15) && (t <= 35)) ? t : temp); 102 | 103 | return String(temp); 104 | } 105 | 106 | -------------------------------------------------------------------------------- /esp32_examples/esp32-devkit-arduino-web-server-bootstrap-label/data/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | ESP32 Web Page 4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 |

Read Button State using AJAX

12 |

N/A

13 |
14 | 29 | 30 | -------------------------------------------------------------------------------- /esp32_examples/esp32-devkit-arduino-web-server-bootstrap-label/esp32-devkit-arduino-web-server-bootstrap-label.ino: -------------------------------------------------------------------------------- 1 | // Author: Erwin Ouyang, aiotedge.tech 2 | // Date : 8 Mar 2020 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | // Button's GPIO pin 9 | #define BUTTON 12 10 | 11 | const char ssid[] = "Huawei-E5573"; 12 | const char pass[] = "huaweie5573"; 13 | 14 | // TCP server port for HTTP 15 | const uint16_t port = 80; 16 | 17 | // Create AsyncWebServer object 18 | AsyncWebServer server(port); 19 | 20 | void setup() 21 | { 22 | // Set GPIO pin as input for button 23 | pinMode(BUTTON, INPUT_PULLUP); 24 | // Setup serial communication 25 | Serial.begin(115200); 26 | 27 | // Initialize SPIFFS 28 | if (!SPIFFS.begin(true)) 29 | { 30 | Serial.println("An error has occurred while mounting SPIFFS"); 31 | return; 32 | } 33 | 34 | // *** Connect to a WiFi access point *** 35 | Serial.printf("Connecting to %s ...\n", ssid); 36 | WiFi.mode(WIFI_STA); 37 | WiFi.begin(ssid, pass); 38 | if (WiFi.waitForConnectResult() != WL_CONNECTED) 39 | { 40 | Serial.printf("WiFi connect failed! Rebooting ...\n"); 41 | delay(1000); 42 | ESP.restart(); 43 | } 44 | Serial.printf("Connected\n"); 45 | Serial.printf("IP address: %s\n", WiFi.localIP().toString().c_str()); 46 | 47 | // Handler for root request 48 | server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) 49 | { 50 | request->send(SPIFFS, "/index.html"); 51 | }); 52 | 53 | // Handler for button AJAX request 54 | server.on("/button_ajax", HTTP_GET, [](AsyncWebServerRequest *request) 55 | { 56 | if (digitalRead(BUTTON)) 57 | { 58 | request->send(200, "text/plain", "OFF"); 59 | } 60 | else 61 | { 62 | request->send(200, "text/plain", "ON"); 63 | } 64 | }); 65 | 66 | // Handler for Bootstrap libraries 67 | server.on("/bootstrap.min.css", HTTP_GET, [](AsyncWebServerRequest *request) { 68 | request->send(SPIFFS, "/bootstrap.min.css"); 69 | }); 70 | server.on("/jquery-3.3.1.min.js", HTTP_GET, [](AsyncWebServerRequest *request) { 71 | request->send(SPIFFS, "/jquery-3.3.1.min.js"); 72 | }); 73 | server.on("/popper.min.js", HTTP_GET, [](AsyncWebServerRequest *request) { 74 | request->send(SPIFFS, "/popper.min.js"); 75 | }); 76 | server.on("/bootstrap.min.js", HTTP_GET, [](AsyncWebServerRequest *request) { 77 | request->send(SPIFFS, "/bootstrap.min.js"); 78 | }); 79 | 80 | // Start server 81 | server.begin(); 82 | } 83 | 84 | void loop() 85 | { 86 | } 87 | 88 | -------------------------------------------------------------------------------- /esp32_examples/esp32-devkit-arduino-web-server-read-button-ajax/esp32-devkit-arduino-web-server-read-button-ajax.ino: -------------------------------------------------------------------------------- 1 | // Author: Erwin Ouyang, aiotedge.tech 2 | // Date : 7 Mar 2020 3 | 4 | #include 5 | #include 6 | 7 | // Button's GPIO pin 8 | #define BUTTON 12 9 | 10 | const char ssid[] = "Huawei-E5573"; 11 | const char pass[] = "huaweie5573"; 12 | 13 | // TCP server port for HTTP 14 | const uint16_t port = 80; 15 | 16 | // Create AsyncWebServer object 17 | AsyncWebServer server(port); 18 | 19 | // Web page 20 | const char webpage[] PROGMEM = R"=====( 21 | 22 | 23 | ESP32 Web Page 24 | 25 | 26 |

Read Button State using AJAX

27 |

N/A

28 | 43 | 44 | 45 | )====="; 46 | 47 | void setup() 48 | { 49 | // Set GPIO pin as input for button 50 | pinMode(BUTTON, INPUT_PULLUP); 51 | // Setup serial communication 52 | Serial.begin(115200); 53 | 54 | // *** Connect to a WiFi access point *** 55 | Serial.printf("Connecting to %s ...\n", ssid); 56 | WiFi.mode(WIFI_STA); 57 | WiFi.begin(ssid, pass); 58 | if (WiFi.waitForConnectResult() != WL_CONNECTED) 59 | { 60 | Serial.printf("WiFi connect failed! Rebooting ...\n"); 61 | delay(1000); 62 | ESP.restart(); 63 | } 64 | Serial.printf("Connected\n"); 65 | Serial.printf("IP address: %s\n", WiFi.localIP().toString().c_str()); 66 | 67 | // Handler for root request 68 | server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) 69 | { 70 | request->send_P(200, "text/html", webpage); 71 | }); 72 | 73 | // Handler for button AJAX request 74 | server.on("/button_ajax", HTTP_GET, [](AsyncWebServerRequest *request) 75 | { 76 | if (digitalRead(BUTTON)) 77 | { 78 | request->send(200, "text/plain", "Released"); 79 | printf("Button released\n"); 80 | } 81 | else 82 | { 83 | request->send(200, "text/plain", "Pressed"); 84 | printf("Button pressed\n"); 85 | } 86 | }); 87 | 88 | // Start server 89 | server.begin(); 90 | } 91 | 92 | void loop() 93 | { 94 | } 95 | 96 | -------------------------------------------------------------------------------- /esp32_examples/esp32-devkit-arduino-web-server-read-button/esp32-devkit-arduino-web-server-read-button.ino: -------------------------------------------------------------------------------- 1 | // Author: Erwin Ouyang, aiotedge.tech 2 | // Date : 7 Mar 2020 3 | 4 | #include 5 | #include 6 | 7 | // Button's GPIO pin 8 | #define BUTTON 12 9 | 10 | const char ssid[] = "Huawei-E5573"; 11 | const char pass[] = "huaweie5573"; 12 | 13 | // TCP server port for HTTP 14 | const uint16_t port = 80; 15 | 16 | // Create AsyncWebServer object 17 | AsyncWebServer server(port); 18 | 19 | // Web page 20 | const char webpage[] PROGMEM = R"=====( 21 | 22 | 23 | ESP32 Web Page 24 | 25 | 26 | 27 |

Read Button State

28 |

%STATE%

29 | 30 | 31 | )====="; 32 | 33 | // Template processor for replacing placeholder with button state 34 | String processor(const String& var) 35 | { 36 | String button_state; 37 | 38 | if (var == "STATE") 39 | { 40 | // Read active-low button state 41 | if (digitalRead(BUTTON)) 42 | { 43 | button_state = "Released"; 44 | printf("Button released\n"); 45 | } 46 | else 47 | { 48 | button_state = "Pressed"; 49 | printf("Button pressed\n"); 50 | } 51 | return button_state; 52 | } 53 | 54 | return String(); 55 | } 56 | 57 | void setup() 58 | { 59 | // Set GPIO pin as input for button 60 | pinMode(BUTTON, INPUT_PULLUP); 61 | // Setup serial communication 62 | Serial.begin(115200); 63 | 64 | // *** Connect to a WiFi access point *** 65 | Serial.printf("Connecting to %s ...\n", ssid); 66 | WiFi.mode(WIFI_STA); 67 | WiFi.begin(ssid, pass); 68 | if (WiFi.waitForConnectResult() != WL_CONNECTED) 69 | { 70 | Serial.printf("WiFi connect failed! Rebooting ...\n"); 71 | delay(1000); 72 | ESP.restart(); 73 | } 74 | Serial.printf("Connected\n"); 75 | Serial.printf("IP address: %s\n", WiFi.localIP().toString().c_str()); 76 | 77 | // Handler for root request 78 | server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) 79 | { 80 | request->send_P(200, "text/html", webpage, processor); 81 | }); 82 | 83 | // Start server 84 | server.begin(); 85 | } 86 | 87 | void loop() 88 | { 89 | } 90 | 91 | -------------------------------------------------------------------------------- /esp32_examples/esp32-devkit-arduino-web-server-read-dht11-ajax/esp32-devkit-arduino-web-server-read-dht11-ajax.ino: -------------------------------------------------------------------------------- 1 | // Author: Erwin Ouyang, aiotedge.tech 2 | // Date : 7 Mar 2020 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #define DHTPIN 22 10 | #define DHTTYPE DHT11 11 | 12 | // Setup DHT pin and type 13 | DHT dht(DHTPIN, DHTTYPE); 14 | 15 | const char ssid[] = "Huawei-E5573"; 16 | const char pass[] = "huaweie5573"; 17 | 18 | // TCP server port for HTTP 19 | const uint16_t port = 80; 20 | 21 | // Create AsyncWebServer object 22 | AsyncWebServer server(port); 23 | 24 | // Web page 25 | const char webpage[] PROGMEM = R"=====( 26 | 27 | 28 | ESP32 Web Page 29 | 30 | 31 |

Read DHT11 Sensor using AJAX

32 |

Temperature: N/A°C

33 |

Humidity: N/A%

34 | 51 | 52 | 53 | )====="; 54 | 55 | void setup() 56 | { 57 | // Setup serial communication 58 | Serial.begin(115200); 59 | // Initialize DHT sensor 60 | dht.begin(); 61 | 62 | // *** Connect to a WiFi access point *** 63 | Serial.printf("Connecting to %s ...\n", ssid); 64 | WiFi.mode(WIFI_STA); 65 | WiFi.begin(ssid, pass); 66 | if (WiFi.waitForConnectResult() != WL_CONNECTED) 67 | { 68 | Serial.printf("WiFi connect failed! Rebooting ...\n"); 69 | delay(1000); 70 | ESP.restart(); 71 | } 72 | Serial.printf("Connected\n"); 73 | Serial.printf("IP address: %s\n", WiFi.localIP().toString().c_str()); 74 | 75 | // Handler for root request 76 | server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) 77 | { 78 | request->send_P(200, "text/html", webpage); 79 | }); 80 | 81 | // Handler for DHT11 AJAX request 82 | server.on("/dht11_ajax", HTTP_POST, [](AsyncWebServerRequest *request) 83 | { 84 | // Read temperature and humidity 85 | float temp = dht.readTemperature(); 86 | float hum = dht.readHumidity(); 87 | printf("Temperature: %.2f, Humidity: %.2f\n", temp, hum); 88 | 89 | // Send JSON response 90 | AsyncResponseStream *response = request->beginResponseStream("application/json"); 91 | DynamicJsonBuffer jsonBuffer; 92 | JsonObject &dht11 = jsonBuffer.createObject(); 93 | dht11["temp"] = String(temp); 94 | dht11["hum"] = String(hum); 95 | dht11.printTo(*response); 96 | request->send(response); 97 | }); 98 | 99 | // Start server 100 | server.begin(); 101 | } 102 | 103 | void loop() 104 | { 105 | } 106 | 107 | -------------------------------------------------------------------------------- /esp32_examples/esp32-devkit-arduino-web-server-spiffs/data/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | ESP32 Web Page 4 | 5 | 6 |

This web page is stored inside the SPI Flash File System (SPIFFS).

7 | 8 | -------------------------------------------------------------------------------- /esp32_examples/esp32-devkit-arduino-web-server-spiffs/esp32-devkit-arduino-web-server-spiffs.ino: -------------------------------------------------------------------------------- 1 | // Author: Erwin Ouyang, aiotedge.tech 2 | // Date : 8 Mar 2020 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | const char ssid[] = "Huawei-E5573"; 9 | const char pass[] = "huaweie5573"; 10 | 11 | // TCP server port for HTTP 12 | const uint16_t port = 80; 13 | 14 | // Create AsyncWebServer object 15 | AsyncWebServer server(port); 16 | 17 | void setup() 18 | { 19 | // Setup serial communication 20 | Serial.begin(115200); 21 | 22 | // Initialize SPIFFS 23 | if (!SPIFFS.begin(true)) 24 | { 25 | Serial.println("An error has occurred while mounting SPIFFS"); 26 | return; 27 | } 28 | 29 | // *** Connect to a WiFi access point *** 30 | Serial.printf("Connecting to %s ...\n", ssid); 31 | WiFi.mode(WIFI_STA); 32 | WiFi.begin(ssid, pass); 33 | if (WiFi.waitForConnectResult() != WL_CONNECTED) 34 | { 35 | Serial.printf("WiFi connect failed! Rebooting ...\n"); 36 | delay(1000); 37 | ESP.restart(); 38 | } 39 | Serial.printf("Connected\n"); 40 | Serial.printf("IP address: %s\n", WiFi.localIP().toString().c_str()); 41 | 42 | // Handler for root request 43 | server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) 44 | { 45 | request->send(SPIFFS, "/index.html"); 46 | }); 47 | 48 | // Start server 49 | server.begin(); 50 | } 51 | 52 | void loop() 53 | { 54 | } 55 | 56 | -------------------------------------------------------------------------------- /esp32_examples/esp32-devkit-arduino-web-server-write-led-pwm-ajax/esp32-devkit-arduino-web-server-write-led-pwm-ajax.ino: -------------------------------------------------------------------------------- 1 | // Author: Erwin Ouyang, aiotedge.tech 2 | // Date : 7 Mar 2020 3 | 4 | #include 5 | #include 6 | 7 | // On-board LED's GPIO pin 8 | #define LED_ON_BOARD 2 9 | 10 | // PWM parameters 11 | const int channel = 0; 12 | const int freq = 1000; 13 | const int res = 10; 14 | 15 | const char ssid[] = "Huawei-E5573"; 16 | const char pass[] = "huaweie5573"; 17 | 18 | // TCP server port for HTTP 19 | const uint16_t port = 80; 20 | 21 | // Create AsyncWebServer object 22 | AsyncWebServer server(port); 23 | 24 | // Web page 25 | const char webpage[] PROGMEM = R"=====( 26 | 27 | 28 | ESP32 Web Page 29 | 30 | 31 |

Write LED Value using AJAX

32 | 33 | 42 | 43 | 44 | )====="; 45 | 46 | void setup() 47 | { 48 | // Set GPIO pin as output for on-board LED 49 | pinMode(LED_ON_BOARD, OUTPUT); 50 | // Configure PWM 51 | ledcSetup(channel, freq, res); 52 | // Attach the PWM channel to the LED 53 | ledcAttachPin(LED_ON_BOARD, channel); 54 | 55 | // Setup serial communication 56 | Serial.begin(115200); 57 | 58 | // *** Connect to a WiFi access point *** 59 | Serial.printf("Connecting to %s ...\n", ssid); 60 | WiFi.mode(WIFI_STA); 61 | WiFi.begin(ssid, pass); 62 | if (WiFi.waitForConnectResult() != WL_CONNECTED) 63 | { 64 | Serial.printf("WiFi connect failed! Rebooting ...\n"); 65 | delay(1000); 66 | ESP.restart(); 67 | } 68 | Serial.printf("Connected\n"); 69 | Serial.printf("IP address: %s\n", WiFi.localIP().toString().c_str()); 70 | 71 | // Handler for root request 72 | server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) 73 | { 74 | request->send_P(200, "text/html", webpage); 75 | }); 76 | 77 | // Handler for button AJAX request 78 | server.on("/led_pwm_ajax", HTTP_POST, [](AsyncWebServerRequest *request) 79 | { 80 | // Get HTTP POST parameter 81 | AsyncWebParameter *p = request->getParam(0); 82 | if (p->isPost()) 83 | { 84 | // Print HTTP POST parameter to the serial monitor 85 | Serial.printf("POST[%s]: %s\n", p->name().c_str(), p->value().c_str()); 86 | } 87 | // Write PWM value to the LED 88 | ledcWrite(channel, p->value().toInt()); 89 | 90 | // Tell client that the HTTP POST has been performed 91 | request->send(303); 92 | }); 93 | 94 | // Start server 95 | server.begin(); 96 | } 97 | 98 | void loop() 99 | { 100 | } 101 | 102 | -------------------------------------------------------------------------------- /esp32_examples/esp32-devkit-arduino-web-server-write-led-pwm/esp32-devkit-arduino-web-server-write-led-pwm.ino: -------------------------------------------------------------------------------- 1 | // Author: Erwin Ouyang, aiotedge.tech 2 | // Date : 7 Mar 2020 3 | 4 | #include 5 | #include 6 | 7 | // On-board LED's GPIO pin 8 | #define LED_ON_BOARD 2 9 | 10 | // PWM parameters 11 | const int channel = 0; 12 | const int freq = 1000; 13 | const int res = 10; 14 | 15 | const char ssid[] = "Huawei-E5573"; 16 | const char pass[] = "huaweie5573"; 17 | 18 | // TCP server port for HTTP 19 | const uint16_t port = 80; 20 | 21 | // Create AsyncWebServer object 22 | AsyncWebServer server(port); 23 | 24 | // Web page 25 | const char webpage[] PROGMEM = R"=====( 26 | 27 | 28 | ESP32 Web Page 29 | 30 | 31 |

Write LED Value

32 |
33 |
34 | 35 |
36 | 37 | 38 | )====="; 39 | 40 | void setup() 41 | { 42 | // Set GPIO pin as output for on-board LED 43 | pinMode(LED_ON_BOARD, OUTPUT); 44 | // Configure PWM 45 | ledcSetup(channel, freq, res); 46 | // Attach the PWM channel to the LED 47 | ledcAttachPin(LED_ON_BOARD, channel); 48 | 49 | // Setup serial communication 50 | Serial.begin(115200); 51 | 52 | // *** Connect to a WiFi access point *** 53 | Serial.printf("Connecting to %s ...\n", ssid); 54 | WiFi.mode(WIFI_STA); 55 | WiFi.begin(ssid, pass); 56 | if (WiFi.waitForConnectResult() != WL_CONNECTED) 57 | { 58 | Serial.printf("WiFi connect failed! Rebooting ...\n"); 59 | delay(1000); 60 | ESP.restart(); 61 | } 62 | Serial.printf("Connected\n"); 63 | Serial.printf("IP address: %s\n", WiFi.localIP().toString().c_str()); 64 | 65 | // Handler for root request 66 | server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) 67 | { 68 | request->send_P(200, "text/html", webpage); 69 | }); 70 | 71 | // Handler for button request 72 | server.on("/led_pwm", HTTP_POST, [](AsyncWebServerRequest *request) 73 | { 74 | // Get HTTP POST parameter 75 | AsyncWebParameter *p = request->getParam(0); 76 | if (p->isPost()) 77 | { 78 | // Print HTTP POST parameter to the serial monitor 79 | Serial.printf("POST[%s]: %s\n", p->name().c_str(), p->value().c_str()); 80 | } 81 | // Write PWM value to the LED 82 | ledcWrite(channel, p->value().toInt()); 83 | 84 | request->redirect("/"); 85 | }); 86 | 87 | // Start server 88 | server.begin(); 89 | } 90 | 91 | void loop() 92 | { 93 | } 94 | 95 | -------------------------------------------------------------------------------- /esp32_examples/esp32-devkit-arduino-web-server-write-led/esp32-devkit-arduino-web-server-write-led.ino: -------------------------------------------------------------------------------- 1 | // Author: Erwin Ouyang, aiotedge.tech 2 | // Date : 7 Mar 2020 3 | 4 | #include 5 | #include 6 | 7 | // On-board LED's GPIO pin 8 | #define LED_ON_BOARD 2 9 | 10 | const char ssid[] = "Huawei-E5573"; 11 | const char pass[] = "huaweie5573"; 12 | 13 | // TCP server port for HTTP 14 | const uint16_t port = 80; 15 | 16 | // Create AsyncWebServer object 17 | AsyncWebServer server(port); 18 | 19 | // Web page 20 | const char webpage[] PROGMEM = R"=====( 21 | 22 | 23 | ESP32 Web Page 24 | 25 | 26 |

Write LED State

27 | 28 | 29 | 30 | 31 | )====="; 32 | 33 | void setup() 34 | { 35 | // Set GPIO pin as output for on-board LED 36 | pinMode(LED_ON_BOARD, OUTPUT); 37 | // Setup serial communication 38 | Serial.begin(115200); 39 | 40 | // *** Connect to a WiFi access point *** 41 | Serial.printf("Connecting to %s ...\n", ssid); 42 | WiFi.mode(WIFI_STA); 43 | WiFi.begin(ssid, pass); 44 | if (WiFi.waitForConnectResult() != WL_CONNECTED) 45 | { 46 | Serial.printf("WiFi connect failed! Rebooting ...\n"); 47 | delay(1000); 48 | ESP.restart(); 49 | } 50 | Serial.printf("Connected\n"); 51 | Serial.printf("IP address: %s\n", WiFi.localIP().toString().c_str()); 52 | 53 | // Handler for root request 54 | server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) 55 | { 56 | request->send_P(200, "text/html", webpage); 57 | }); 58 | 59 | // Handler for turning on the LED 60 | server.on("/on", HTTP_GET, [](AsyncWebServerRequest *request){ 61 | printf("%s/on\n", WiFi.localIP().toString().c_str()); 62 | digitalWrite(LED_ON_BOARD, HIGH); 63 | printf("LED On\n"); 64 | request->redirect("/"); 65 | }); 66 | 67 | // Handler for turning of the LED 68 | server.on("/off", HTTP_GET, [](AsyncWebServerRequest *request){ 69 | printf("%s/off\n", WiFi.localIP().toString().c_str()); 70 | digitalWrite(LED_ON_BOARD, LOW); 71 | printf("LED Off\n"); 72 | request->redirect("/"); 73 | }); 74 | 75 | // Start server 76 | server.begin(); 77 | } 78 | 79 | void loop() 80 | { 81 | } 82 | 83 | -------------------------------------------------------------------------------- /esp32_examples/esp32-devkit-arduino-web-server/esp32-devkit-arduino-web-server.ino: -------------------------------------------------------------------------------- 1 | // Author: Erwin Ouyang, aiotedge.tech 2 | // Date : 7 Mar 2020 3 | 4 | #include 5 | #include 6 | 7 | const char ssid[] = "Huawei-E5573"; 8 | const char pass[] = "huaweie5573"; 9 | 10 | // TCP server port for HTTP 11 | const uint16_t port = 80; 12 | 13 | // Create AsyncWebServer object 14 | AsyncWebServer server(port); 15 | 16 | // Web page 17 | const char webpage[] PROGMEM = R"=====( 18 | 19 | 20 | ESP32 Web Page 21 | 22 | 23 |

Hello, World!

24 | 25 | 26 | )====="; 27 | 28 | void setup() 29 | { 30 | // Setup serial communication 31 | Serial.begin(115200); 32 | 33 | // *** Connect to a WiFi access point *** 34 | Serial.printf("Connecting to %s ...\n", ssid); 35 | WiFi.mode(WIFI_STA); 36 | WiFi.begin(ssid, pass); 37 | if (WiFi.waitForConnectResult() != WL_CONNECTED) 38 | { 39 | Serial.printf("WiFi connect failed! Rebooting ...\n"); 40 | delay(1000); 41 | ESP.restart(); 42 | } 43 | Serial.printf("Connected\n"); 44 | Serial.printf("IP address: %s\n", WiFi.localIP().toString().c_str()); 45 | 46 | // Handler for root request 47 | server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) 48 | { 49 | request->send(200, "text/html", webpage); 50 | }); 51 | 52 | // Start server 53 | server.begin(); 54 | } 55 | 56 | void loop() 57 | { 58 | } 59 | 60 | -------------------------------------------------------------------------------- /esp32_examples/esp32-devkit-arduino-wifi-access-point/esp32-devkit-arduino-wifi-access-point.ino: -------------------------------------------------------------------------------- 1 | // Author: Erwin Ouyang, aiotedge.tech 2 | // Date : 29 Feb 2020 3 | 4 | #include 5 | 6 | const char ssid[] = "ESP32-AP"; 7 | const char pass[] = "esp32accesspoint"; 8 | 9 | IPAddress ip(192,168,1,1); 10 | IPAddress gateway(192,168,1,1); 11 | IPAddress subnet(255,255,255,0); 12 | 13 | int currentNumOfStation; 14 | 15 | void setup() 16 | { 17 | // Setup serial communication 18 | Serial.begin(115200); 19 | 20 | // *** Create a WiFi access point *** 21 | Serial.print("Setting AP ... "); 22 | Serial.println(WiFi.softAP(ssid, pass) ? "Ready" : "Failed!"); 23 | Serial.print("Setting AP configuration ... "); 24 | Serial.println(WiFi.softAPConfig(ip, gateway, subnet) ? "Ready" : "Failed!"); 25 | 26 | // *** Print WiFi AP configuration *** 27 | Serial.printf("IP address: %s\n", WiFi.softAPIP().toString().c_str()); 28 | Serial.printf("MAC address: %s\n", WiFi.softAPmacAddress().c_str()); 29 | } 30 | 31 | void loop() 32 | { 33 | // *** Print number of stations that are connected to AP *** 34 | if (WiFi.softAPgetStationNum() != currentNumOfStation) 35 | { 36 | currentNumOfStation = WiFi.softAPgetStationNum(); 37 | Serial.printf("Stations connected to AP: %d\n", currentNumOfStation); 38 | } 39 | } 40 | 41 | -------------------------------------------------------------------------------- /esp32_examples/esp32-devkit-arduino-wifi-station-http-client/esp32-devkit-arduino-wifi-station-http-client.ino: -------------------------------------------------------------------------------- 1 | // Author: Erwin Ouyang, aiotedge.tech 2 | // Date : 1 Mar 2020 3 | 4 | #include 5 | 6 | const char ssid[] = "Huawei-E5573"; 7 | const char pass[] = "huaweie5573"; 8 | 9 | const char host[] = "www.google.com"; 10 | const uint16_t port = 80; 11 | 12 | String httpRequest = 13 | "GET / HTTP/1.1\r\n" \ 14 | "Host: " + String(host) + "\r\n" \ 15 | "Connection: close\r\n\r\n"; 16 | 17 | void setup() 18 | { 19 | // Setup serial communication 20 | Serial.begin(115200); 21 | 22 | // *** Connect to a WiFi access point *** 23 | Serial.printf("Connecting to %s ...\n", ssid); 24 | WiFi.mode(WIFI_STA); 25 | WiFi.begin(ssid, pass); 26 | if (WiFi.waitForConnectResult() != WL_CONNECTED) 27 | { 28 | Serial.printf("WiFi connect failed! Rebooting...\n"); 29 | delay(1000); 30 | ESP.restart(); 31 | } 32 | Serial.printf("Connected\n"); 33 | Serial.printf("IP address: %s\n", WiFi.localIP().toString().c_str()); 34 | } 35 | 36 | void loop() 37 | { 38 | // TCP client object declaration 39 | WiFiClient client; 40 | 41 | // *** Connect to host server *** 42 | Serial.printf("Connecting to %s ...\n", host); 43 | if (!client.connect(host, port)) 44 | { 45 | Serial.printf("Connection failed\n"); 46 | Serial.println("Wait 5 sec ..."); 47 | delay(5000); 48 | return; 49 | } 50 | Serial.printf("Connected\n"); 51 | 52 | // Send HTTP request 53 | client.print(httpRequest); 54 | 55 | // *** Wait until server give response *** 56 | unsigned long timeout = millis(); 57 | while (client.available() == 0) 58 | { 59 | if (millis() - timeout > 5000) 60 | { 61 | Serial.printf("Client Timeout\n"); 62 | client.stop(); 63 | return; 64 | } 65 | } 66 | 67 | // *** Read HTTP response from server *** 68 | while(client.available()) 69 | { 70 | String line = client.readStringUntil('\n'); 71 | Serial.print(line); 72 | } 73 | 74 | // *** Close TCP connection *** 75 | Serial.printf("\nClosing connection\n"); 76 | client.stop(); 77 | 78 | Serial.println("Wait 5 sec ..."); 79 | delay(5000); 80 | } 81 | 82 | -------------------------------------------------------------------------------- /esp32_examples/esp32-devkit-arduino-wifi-station-http-server/esp32-devkit-arduino-wifi-station-http-server.ino: -------------------------------------------------------------------------------- 1 | // Author: Erwin Ouyang, aiotedge.tech 2 | // Date : 1 Mar 2020 3 | 4 | #include 5 | 6 | const char ssid[] = "Huawei-E5573"; 7 | const char pass[] = "huaweie5573"; 8 | 9 | // TCP server port for HTTP 10 | const uint16_t port = 80; 11 | 12 | // TCP server object declaration 13 | WiFiServer server(port); 14 | 15 | String httpResponseHeader = 16 | "HTTP/1.1 200 OK\r\n" \ 17 | "Content-Type: text/html\r\n" \ 18 | "Connection: close\r\n" \ 19 | "\r\n"; 20 | String webPage = 21 | "\r\n" \ 22 | "\r\n" \ 23 | "\r\n" \ 24 | "ESP32 HTTP Server\r\n" \ 25 | "\r\n" \ 26 | "\r\n" \ 27 | "

A web page from ESP32

\r\n" \ 28 | "\r\n" \ 29 | "\r\n"; 30 | 31 | void setup() 32 | { 33 | // Setup serial communication 34 | Serial.begin(115200); 35 | 36 | // *** Connect to a WiFi access point *** 37 | Serial.printf("Connecting to %s ...\n", ssid); 38 | WiFi.mode(WIFI_STA); 39 | WiFi.begin(ssid, pass); 40 | if (WiFi.waitForConnectResult() != WL_CONNECTED) 41 | { 42 | Serial.printf("WiFi connect failed! Rebooting ...\n"); 43 | delay(1000); 44 | ESP.restart(); 45 | } 46 | Serial.printf("Connected\n"); 47 | Serial.printf("IP address: %s\n", WiFi.localIP().toString().c_str()); 48 | 49 | // *** Start TCP server *** 50 | server.begin(); 51 | Serial.printf("TCP server started at port %d\n", port); 52 | } 53 | 54 | void loop() 55 | { 56 | // Get TCP client 57 | WiFiClient client = server.available(); 58 | 59 | // *** If a client connected *** 60 | if (client) 61 | { 62 | Serial.printf("[Client connected]\n"); 63 | 64 | // An http request ends with a blank line 65 | boolean currentLineIsBlank = true; 66 | while (client.connected()) 67 | { 68 | if (client.available()) 69 | { 70 | // *** Read a character from client *** 71 | char c = client.read(); 72 | Serial.write(c); 73 | 74 | // The new line is a blank line 75 | // The http request has ended 76 | if (c == '\n' && currentLineIsBlank) 77 | { 78 | // Send HTTP response header 79 | client.print(httpResponseHeader); 80 | // Send web page 81 | client.print(webPage); 82 | Serial.printf("[HTTP response sent]\n"); 83 | 84 | break; 85 | } 86 | 87 | // Every line of HTTP request ends with \r\n 88 | if (c == '\n') 89 | { 90 | // This is the last character of every line 91 | currentLineIsBlank = true; 92 | } 93 | else if (c != '\r') 94 | { 95 | // The new line is not a blank line 96 | currentLineIsBlank = false; 97 | } 98 | } 99 | } 100 | delay(1); 101 | 102 | // *** Close client *** 103 | client.stop(); 104 | Serial.printf("[Client disconnected]\n\n"); 105 | } 106 | } 107 | 108 | -------------------------------------------------------------------------------- /esp32_examples/esp32-devkit-arduino-wifi-station-mqtt-publish/esp32-devkit-arduino-wifi-station-mqtt-publish.ino: -------------------------------------------------------------------------------- 1 | // Author: Erwin Ouyang, aiotedge.tech 2 | // Date : 1 Mar 2020 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | const char ssid[] = "Huawei-E5573"; 9 | const char pass[] = "huaweie5573"; 10 | 11 | // *** MQTT server's IP and port *** 12 | const char mqtt_ip[] = "192.168.8.101"; 13 | const uint16_t mqtt_port = 1883; 14 | 15 | // *** Create a WiFi Client and an MQTT client *** 16 | WiFiClient client; 17 | Adafruit_MQTT_Client mqtt(&client, mqtt_ip, mqtt_port); 18 | 19 | // Setup an MQTT topic called '/test' for publishing 20 | Adafruit_MQTT_Publish test = Adafruit_MQTT_Publish(&mqtt, "/test"); 21 | 22 | void setup() 23 | { 24 | // Setup serial communication 25 | Serial.begin(115200); 26 | 27 | // *** Connect to a WiFi access point *** 28 | Serial.printf("Connecting to %s ...\n", ssid); 29 | WiFi.mode(WIFI_STA); 30 | WiFi.begin(ssid, pass); 31 | if (WiFi.waitForConnectResult() != WL_CONNECTED) 32 | { 33 | Serial.printf("WiFi connect failed! Rebooting ...\n"); 34 | delay(1000); 35 | ESP.restart(); 36 | } 37 | Serial.printf("Connected\n"); 38 | Serial.printf("IP address: %s\n", WiFi.localIP().toString().c_str()); 39 | } 40 | 41 | void loop() 42 | { 43 | // Connect to an MQTT server 44 | mqtt_connect(); 45 | 46 | // *** Publish a message *** 47 | if (!test.publish("Hello, World!")) 48 | { 49 | Serial.println("MQTT publish failed"); 50 | } 51 | else 52 | { 53 | Serial.println("MQTT publish succeed"); 54 | } 55 | delay(1000); 56 | } 57 | 58 | void mqtt_connect() 59 | { 60 | // Stop if already connected 61 | if (mqtt.connected()) 62 | { 63 | return; 64 | } 65 | 66 | // *** Connect to MQTT broker *** 67 | Serial.println("Connecting to MQTT broker ... "); 68 | while (mqtt.connect() != 0) 69 | { 70 | Serial.println("Retrying MQTT connection in 5 seconds ..."); 71 | mqtt.disconnect(); 72 | delay(5000); 73 | } 74 | Serial.println("MQTT Connected"); 75 | } 76 | 77 | -------------------------------------------------------------------------------- /esp32_examples/esp32-devkit-arduino-wifi-station-mqtt-subscribe/esp32-devkit-arduino-wifi-station-mqtt-subscribe.ino: -------------------------------------------------------------------------------- 1 | // Author: Erwin Ouyang, aiotedge.tech 2 | // Date : 1 Mar 2020 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | // On-board LED's GPIO pin 9 | #define LED_ON_BOARD 2 10 | 11 | const char ssid[] = "Huawei-E5573"; 12 | const char pass[] = "huaweie5573"; 13 | 14 | // *** MQTT server's IP and port *** 15 | const char mqtt_ip[] = "192.168.8.101"; 16 | const uint16_t mqtt_port = 1883; 17 | 18 | // *** Create a WiFi Client and an MQTT client *** 19 | WiFiClient client; 20 | Adafruit_MQTT_Client mqtt(&client, mqtt_ip, mqtt_port); 21 | 22 | // Setup an MQTT topic called '/onoff' for subscribing to changes to the button 23 | Adafruit_MQTT_Subscribe topic_onoff = Adafruit_MQTT_Subscribe(&mqtt, "/onoff"); 24 | // Setup an MQTT topic called '/uint' for subscribing to uint value 25 | Adafruit_MQTT_Subscribe topic_uint = Adafruit_MQTT_Subscribe(&mqtt, "/uint"); 26 | // Setup an MQTT topic called '/double' for subscribing to double value 27 | Adafruit_MQTT_Subscribe topic_double = Adafruit_MQTT_Subscribe(&mqtt, "/double"); 28 | 29 | // MQTT subscribe callback function 30 | void onoff_callback(char *cmd, uint16_t len) 31 | { 32 | // *** Process the command *** 33 | if (String(cmd).equals("LED+ON")) // Turn on LED 34 | { 35 | digitalWrite(LED_ON_BOARD, HIGH); 36 | } 37 | else if (String(cmd).equals("LED+OFF")) // Turn off LED 38 | { 39 | digitalWrite(LED_ON_BOARD, LOW); 40 | } 41 | } 42 | 43 | void uint_callback(uint32_t value) 44 | { 45 | Serial.println(value); 46 | } 47 | 48 | void double_callback(double value) 49 | { 50 | Serial.println(value); 51 | } 52 | 53 | void setup() 54 | { 55 | // Set GPIO pin as output for on-board LED 56 | pinMode(LED_ON_BOARD, OUTPUT); 57 | // Setup serial communication 58 | Serial.begin(115200); 59 | 60 | // *** Connect to a WiFi access point *** 61 | Serial.printf("Connecting to %s ...\n", ssid); 62 | WiFi.mode(WIFI_STA); 63 | WiFi.begin(ssid, pass); 64 | if (WiFi.waitForConnectResult() != WL_CONNECTED) 65 | { 66 | Serial.printf("WiFi connect failed! Rebooting ...\n"); 67 | delay(1000); 68 | ESP.restart(); 69 | } 70 | Serial.printf("Connected\n"); 71 | Serial.printf("IP address: %s\n", WiFi.localIP().toString().c_str()); 72 | 73 | // *** Setup MQTT subscription *** 74 | topic_onoff.setCallback(onoff_callback); 75 | topic_uint.setCallback(uint_callback); 76 | topic_double.setCallback(double_callback); 77 | mqtt.subscribe(&topic_onoff); 78 | mqtt.subscribe(&topic_uint); 79 | mqtt.subscribe(&topic_double); 80 | } 81 | 82 | void loop() 83 | { 84 | // Connect to an MQTT server 85 | mqtt_connect(); 86 | 87 | // This is our 'wait for incoming subscription packets and callback em' busy subloop 88 | // Try to spend your time here: 89 | mqtt.processPackets(10000); 90 | 91 | // Ping the server to keep the mqtt connection alive 92 | // NOT required if you are publishing once every KEEPALIVE seconds 93 | if (!mqtt.ping()) 94 | { 95 | mqtt.disconnect(); 96 | } 97 | } 98 | 99 | void mqtt_connect() 100 | { 101 | // Stop if already connected 102 | if (mqtt.connected()) 103 | { 104 | return; 105 | } 106 | 107 | // *** Connect to MQTT broker *** 108 | Serial.println("Connecting to MQTT broker ... "); 109 | while (mqtt.connect() != 0) 110 | { 111 | Serial.println("Retrying MQTT connection in 5 seconds ..."); 112 | mqtt.disconnect(); 113 | delay(5000); 114 | } 115 | Serial.println("MQTT Connected"); 116 | } 117 | 118 | -------------------------------------------------------------------------------- /esp32_examples/esp32-devkit-arduino-wifi-station-tcp-client/esp32-devkit-arduino-wifi-station-tcp-client.ino: -------------------------------------------------------------------------------- 1 | // Author: Erwin Ouyang, aiotedge.tech 2 | // Date : 1 Mar 2020 3 | 4 | #include 5 | 6 | const char ssid[] = "Huawei-E5573"; 7 | const char pass[] = "huaweie5573"; 8 | 9 | // *** TCP server IP and port *** 10 | const char ip[] = "192.168.8.101"; 11 | const uint16_t port = 23; 12 | 13 | void setup() 14 | { 15 | // Setup serial communication 16 | Serial.begin(115200); 17 | 18 | // *** Connect to a WiFi access point *** 19 | Serial.printf("Connecting to %s ...\n", ssid); 20 | WiFi.mode(WIFI_STA); 21 | WiFi.begin(ssid, pass); 22 | if (WiFi.waitForConnectResult() != WL_CONNECTED) 23 | { 24 | Serial.printf("WiFi connect failed! Rebooting ...\n"); 25 | delay(1000); 26 | ESP.restart(); 27 | } 28 | Serial.printf("Connected\n"); 29 | Serial.printf("IP address: %s\n", WiFi.localIP().toString().c_str()); 30 | } 31 | 32 | void loop() 33 | { 34 | // TCP client object declaration 35 | WiFiClient client; 36 | 37 | // *** Connect to a TCP server *** 38 | Serial.printf("Connecting to %s ...\n", ip); 39 | if (!client.connect(ip, port)) 40 | { 41 | Serial.printf("Connection failed\n"); 42 | Serial.println("Wait 5 sec ..."); 43 | delay(5000); 44 | return; 45 | } 46 | Serial.printf("Connected\n"); 47 | 48 | // Send a message to the TCP server 49 | client.printf("Message from TCP client\n"); 50 | 51 | // *** Read an echo from the TCP server *** 52 | String response = client.readStringUntil('\n'); 53 | Serial.print("Echoed message: "); 54 | Serial.println(response); 55 | 56 | // *** Close TCP connection *** 57 | Serial.printf("Closing connection\n"); 58 | client.stop(); 59 | 60 | Serial.println("Wait 5 sec ..."); 61 | delay(5000); 62 | } 63 | 64 | -------------------------------------------------------------------------------- /esp32_examples/esp32-devkit-arduino-wifi-station-tcp-server/esp32-devkit-arduino-wifi-station-tcp-server.ino: -------------------------------------------------------------------------------- 1 | // Author: Erwin Ouyang, aiotedge.tech 2 | // Date : 1 Mar 2020 3 | 4 | #include 5 | 6 | // On-board LED's GPIO pin 7 | #define LED_ON_BOARD 2 8 | 9 | const char ssid[] = "Huawei-E5573"; 10 | const char pass[] = "huaweie5573"; 11 | 12 | // TCP server port 13 | const uint16_t port = 23; 14 | 15 | // TCP server object declaration 16 | WiFiServer server(port); 17 | 18 | void setup() 19 | { 20 | // Set GPIO pin as output for on-board LED 21 | pinMode(LED_ON_BOARD, OUTPUT); 22 | // Setup serial communication 23 | Serial.begin(115200); 24 | 25 | // *** Connect to a WiFi access point *** 26 | Serial.printf("Connecting to %s ...\n", ssid); 27 | WiFi.mode(WIFI_STA); 28 | WiFi.begin(ssid, pass); 29 | if (WiFi.waitForConnectResult() != WL_CONNECTED) 30 | { 31 | Serial.printf("WiFi connect failed! Rebooting ...\n"); 32 | delay(1000); 33 | ESP.restart(); 34 | } 35 | Serial.printf("Connected\n"); 36 | Serial.printf("IP address: %s\n", WiFi.localIP().toString().c_str()); 37 | 38 | // *** Start TCP server *** 39 | server.begin(); 40 | Serial.printf("TCP server started at port %d\n", port); 41 | } 42 | 43 | void loop() 44 | { 45 | // Get TCP client 46 | WiFiClient client = server.available(); 47 | 48 | // If a client connected 49 | if (client) 50 | { 51 | Serial.printf("Client connected\n"); 52 | while (client.connected()) 53 | { 54 | if (client.available()) 55 | { 56 | // Read command from receive buffer 57 | String cmd = client.readStringUntil('\n'); 58 | 59 | // *** Process the command *** 60 | if (cmd == "LED+ON") // Turn on LED 61 | { 62 | digitalWrite(LED_ON_BOARD, HIGH); 63 | } 64 | else if (cmd == "LED+OFF") // Turn off LED 65 | { 66 | digitalWrite(LED_ON_BOARD, LOW); 67 | } 68 | else if (cmd == "LED") // Query the LED value 69 | { 70 | if (digitalRead(LED_ON_BOARD)) 71 | { 72 | client.println("LED is on"); 73 | } 74 | else 75 | { 76 | client.println("LED is off"); 77 | } 78 | } 79 | else 80 | { 81 | Serial.println("Unknown command"); 82 | } 83 | } 84 | } 85 | Serial.printf("Client disconnected\n"); 86 | } 87 | } 88 | 89 | -------------------------------------------------------------------------------- /esp32_examples/esp32-devkit-arduino-wifi-station/esp32-devkit-arduino-wifi-station.ino: -------------------------------------------------------------------------------- 1 | // Author: Erwin Ouyang, aiotedge.tech 2 | // Date : 29 Feb 2020 3 | 4 | #include 5 | 6 | const char ssid[] = "Huawei-E5573"; 7 | const char pass[] = "huaweie5573"; 8 | 9 | void setup() 10 | { 11 | // Setup serial communication 12 | Serial.begin(115200); 13 | 14 | // *** Connect to a WiFi access point *** 15 | Serial.printf("Connecting to %s ...\n", ssid); 16 | WiFi.mode(WIFI_STA); 17 | WiFi.begin(ssid, pass); 18 | if (WiFi.waitForConnectResult() != WL_CONNECTED) 19 | { 20 | Serial.printf("WiFi connect failed! Rebooting ...\n"); 21 | delay(1000); 22 | ESP.restart(); 23 | } 24 | Serial.printf("Connected\n"); 25 | 26 | // *** Print WiFi station configuration *** 27 | Serial.printf("SSID: %s\n", WiFi.SSID().c_str()); 28 | Serial.printf("RSSI: %d dBm\n", WiFi.RSSI()); 29 | Serial.printf("IP address: %s\n", WiFi.localIP().toString().c_str()); 30 | Serial.printf("Subnet mask: %s\n", WiFi.subnetMask().toString().c_str()); 31 | Serial.printf("Gateway: %s\n", WiFi.gatewayIP().toString().c_str()); 32 | Serial.printf("MAC address: %s\n", WiFi.macAddress().c_str()); 33 | } 34 | 35 | void loop() 36 | { 37 | } 38 | 39 | --------------------------------------------------------------------------------