Guest User

Untitled

a guest
Jul 15th, 2023
129
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.07 KB | Source Code | 0 0
  1. #include <WiFi.h>
  2. #include <AsyncTCP.h>
  3. #include <ESPAsyncWebServer.h>
  4. #include <SPIFFS.h>
  5.  
  6. const char* ssid = "ChainsawNetwork";
  7. const char* password = "password";
  8.  
  9. const int hallPin = 4; // GPIO pin connected to the Hall effect sensor
  10. const float wheelDiameterInches = 20.0; // Wheel diameter in inches
  11. const float wheelCircumference = wheelDiameterInches * PI; // Wheel circumference in inches
  12. volatile unsigned long lastTriggerTime = 0;
  13. volatile unsigned long rpm = 0;
  14. volatile unsigned long totalDistance = 0;
  15. volatile bool hallEffectState = false;
  16.  
  17. // AsyncWebSocket server and clients
  18. AsyncWebSocket ws("/ws");
  19. AsyncWebSocketClient *client = NULL;
  20.  
  21. // Function to calculate RPM and distance
  22. void IRAM_ATTR hallEffectISR() {
  23.   unsigned long currentTime = micros();
  24.   unsigned long timeSinceLastTrigger = currentTime - lastTriggerTime;
  25.  
  26.   if (timeSinceLastTrigger > 2000) { // Noise filter (ignore false triggers)
  27.     rpm = 60000000 / timeSinceLastTrigger;
  28.     lastTriggerTime = currentTime;
  29.     hallEffectState = true;
  30.  
  31.     if (client && client->status() == WS_CONNECTED) {
  32.       // Send RPM to WebSocket client
  33.       String rpmData = String(rpm);
  34.       client->text(rpmData);
  35.     }
  36.  
  37.     // Calculate distance
  38.     float distance = wheelCircumference / 63360.0; // Convert to miles
  39.     totalDistance += distance;
  40.   }
  41. }
  42.  
  43. // Handle WebSocket events
  44. void onWebSocketEvent(AsyncWebSocket* server, AsyncWebSocketClient* client, AwsEventType type, void* arg, uint8_t* data, size_t len) {
  45.   if (type == WS_EVT_CONNECT) {
  46.     Serial.println("WebSocket client connected");
  47.     client->ping();
  48.   } else if (type == WS_EVT_DISCONNECT) {
  49.     Serial.println("WebSocket client disconnected");
  50.     client = NULL;
  51.   }
  52. }
  53.  
  54. // Handle root endpoint
  55. void handleRoot(AsyncWebServerRequest* request) {
  56.   String htmlContent = getHTMLContent();
  57.   request->send(200, "text/html", htmlContent);
  58. }
  59.  
  60. // Handle wheel size adjustment
  61. void handleWheelSize(AsyncWebServerRequest* request) {
  62.   if (request->hasParam("size")) {
  63.     float newSize = request->getParam("size")->value().toFloat();
  64.     // Update wheel circumference
  65.     // wheelCircumference = newSize;
  66.     request->send(200);
  67.   } else {
  68.     request->send(400);
  69.   }
  70. }
  71.  
  72. // Handle clear distance data
  73. void handleClearDistance(AsyncWebServerRequest* request) {
  74.   totalDistance = 0;
  75.   request->send(200);
  76. }
  77.  
  78. String getHTMLContent() {
  79.   String htmlContent = R"HTML(
  80.    <!DOCTYPE html>
  81.    <html>
  82.    <head>
  83.      <title>Speedometer</title>
  84.      <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
  85.       <style>
  86.         #chartContainer {
  87.           width: 100%;
  88.           height: 300px;
  89.         }
  90.         #sizeForm {
  91.           margin-top: 20px;
  92.         }
  93.         .indicator {
  94.           display: inline-block;
  95.           width: 15px;
  96.           height: 15px;
  97.           border-radius: 50%;
  98.           margin-right: 5px;
  99.         }
  100.         .indicator-on {
  101.           background-color: green;
  102.         }
  103.         .indicator-off {
  104.           background-color: red;
  105.         }
  106.       </style>
  107.       <script>
  108.         var rpmValue = document.getElementById('rpmValue');
  109.         var speedValue = document.getElementById('speedValue');
  110.         var wheelSizeInput = document.getElementById('wheelSize');
  111.         var chart = null;
  112.         var rpmData = [];
  113.         var speedData = [];
  114.         var hallEffectIndicator = document.getElementById('hallEffectIndicator');
  115.  
  116.         // WebSocket connection
  117.         var ws = new WebSocket('ws://' + location.host + '/ws');
  118.         ws.onmessage = function(event) {
  119.           var rpm = event.data;
  120.           rpmValue.textContent = rpm;
  121.  
  122.           // Calculate speed in mph
  123.           var speed = rpm * wheelCircumference * 60 / 63360.0; // Convert RPM to MPH
  124.           speedValue.textContent = speed.toFixed(2);
  125.  
  126.           // Add RPM and speed to data arrays
  127.           var timestamp = new Date().getTime();
  128.           rpmData.push({ x: timestamp, y: parseInt(rpm) });
  129.           speedData.push({ x: timestamp, y: parseFloat(speed) });
  130.  
  131.           // Remove old data points
  132.           var currentTime = timestamp;
  133.           rpmData = rpmData.filter(function(data) {
  134.             return (currentTime - data.x) <= 60000; // Keep data for the last 60 seconds
  135.           });
  136.           speedData = speedData.filter(function(data) {
  137.             return (currentTime - data.x) <= 60000; // Keep data for the last 60 seconds
  138.           });
  139.  
  140.           // Update the chart
  141.           if (chart) {
  142.             chart.update();
  143.           }
  144.         };
  145.  
  146.         // Form submission for wheel size adjustment
  147.         var sizeForm = document.getElementById('sizeForm');
  148.         sizeForm.addEventListener('submit', function(event) {
  149.           event.preventDefault();
  150.  
  151.           var newSize = wheelSizeInput.value;
  152.           var formData = new FormData();
  153.           formData.append('size', newSize);
  154.  
  155.           fetch('/wheel', {
  156.             method: 'POST',
  157.             body: formData
  158.           }).then(function(response) {
  159.             if (response.ok) {
  160.               console.log('Wheel size updated successfully');
  161.             } else {
  162.               console.log('Failed to update wheel size');
  163.             }
  164.           }).catch(function(error) {
  165.             console.log('Error:', error);
  166.           });
  167.         });
  168.  
  169.         // Chart initialization
  170.         document.addEventListener('DOMContentLoaded', function() {
  171.           var ctx = document.getElementById('chartContainer').getContext('2d');
  172.           chart = new Chart(ctx, {
  173.             type: 'line',
  174.             data: {
  175.               datasets: [
  176.                 {
  177.                   label: 'RPM',
  178.                   data: rpmData,
  179.                   borderColor: 'blue',
  180.                   fill: false
  181.                 },
  182.                 {
  183.                   label: 'Speed (MPH)',
  184.                   data: speedData,
  185.                   borderColor: 'green',
  186.                   fill: false
  187.                 }
  188.               ]
  189.             },
  190.             options: {
  191.               scales: {
  192.                 x: {
  193.                   type: 'time',
  194.                   time: {
  195.                     unit: 'second'
  196.                   }
  197.                 },
  198.                 y: {
  199.                   beginAtZero: true,
  200.                   title: {
  201.                     display: true,
  202.                     text: 'Value'
  203.                   }
  204.                 }
  205.               }
  206.             }
  207.           });
  208.         });
  209.  
  210.         // Hall effect indicator update
  211.         setInterval(function() {
  212.           if (hallEffectIndicator) {
  213.             if (hallEffectState) {
  214.               hallEffectIndicator.className = 'indicator indicator-on';
  215.             } else {
  216.               hallEffectIndicator.className = 'indicator indicator-off';
  217.             }
  218.           }
  219.         }, 500);
  220.  
  221.         // Function to display Hall effect sensor status in Serial Monitor
  222.         setInterval(function() {
  223.           if (hallEffectState) {
  224.             console.log("Hall effect sensor: ON");
  225.           } else {
  226.             console.log("Hall effect sensor: OFF");
  227.           }
  228.         }, 1000);
  229.       </script>
  230.     </head>
  231.     <body>
  232.       <h1>Speedometer</h1>
  233.       <h2>Current RPM: <span id="rpmValue">0</span></h2>
  234.       <h2>Current Speed: <span id="speedValue">0.00</span> mph</h2>
  235.       <div class="indicator" id="hallEffectIndicator"></div>
  236.      
  237.       <div id="chartContainer"></div>
  238.  
  239.       <form id="sizeForm">
  240.         <label for="wheelSize">Wheel Size (in):</label>
  241.         <input type="number" id="wheelSize" step="0.01" value="20.0">
  242.         <button type="submit">Update</button>
  243.       </form>
  244.  
  245.       <h2>Total Distance: <span id="totalDistance">0.00</span> miles</h2>
  246.       <button onclick="clearDistance()">Clear Distance</button>
  247.     </body>
  248.     </html>
  249.   )HTML";
  250.  
  251.  return htmlContent;
  252. }
  253.  
  254. void setup() {
  255.  Serial.begin(115200);
  256.  
  257.  // Create access point (Wi-Fi network)
  258.  WiFi.softAP(ssid, password);
  259.  
  260.  // Get the IP address of the access point
  261.  IPAddress IP = WiFi.softAPIP();
  262.  Serial.print("Access Point IP address: ");
  263.  Serial.println(IP);
  264.  
  265.  pinMode(hallPin, INPUT_PULLUP);
  266.  attachInterrupt(digitalPinToInterrupt(hallPin), hallEffectISR, FALLING);
  267.  
  268.  if (SPIFFS.begin(true)) {
  269.    Serial.println("SPIFFS mounted successfully");
  270.  } else {
  271.    Serial.println("An error occurred while mounting SPIFFS");
  272.    return;
  273.  }
  274.  
  275.  // Create WebSocket server
  276.  ws.onEvent(onWebSocketEvent);
  277.  
  278.  // Create HTTP server
  279.  AsyncWebServer server(80);
  280.  server.addHandler(&ws);
  281.  server.on("/", HTTP_GET, handleRoot);
  282.  server.on("/wheel", HTTP_POST, handleWheelSize);
  283.  server.on("/cleardistance", HTTP_POST, handleClearDistance);
  284.  
  285.  server.begin();
  286.  
  287.  Serial.println("Access the web interface at:");
  288.  Serial.print("Web address: http://");
  289.   Serial.println(IP);
  290.   Serial.print("WebSocket address: ws://");
  291.   Serial.println(IP);
  292. }
  293.  
  294. void loop() {
  295.   if (Serial.available()) {
  296.     // Forward serial input to WebSocket client
  297.     if (client && client->status() == WS_CONNECTED) {
  298.       String input = Serial.readStringUntil('\n');
  299.       client->text(input);
  300.     }
  301.   }
  302. }
Advertisement
Add Comment
Please, Sign In to add comment