در این پروژه مقادیر شتاب و زاویه ژایرو را با استفاده از یک ماژول MPU6050 و یک برد ESP32 از طریق وب سرور نمایش خواهیم داد . می توانید از هر برد مبتنی بر ESP32 در این پروژه استفاده کنید . بهتر است از برد هایی مانند TTGO T Call که قابلیت اتصال باتری دارند استفاده کنید تا آزادی بیشتری در حرکت دادن برد داشته باشد .
عملکرد برنامه به صورت کلی :
کلیه استایل و اسکریپت و کد های HTML از طریق SPIFFS بر روی ماژول آپلود می شود . قابلیت SPIFFS را در آموزش های قبلی شرح دادیم . تحلیل کد های HTML، CSS و JS خارج از بحث این آموزش است و تنها آگاهی از کلیات آن مهم است . دراین برنامه از کتابخانه Three.js جاوا اسکریپت استفاده شده است . این کتابخانه جهت رسم شکل های سه بعدی می باشد . حتی بازی های گرافیکی و سه بعدی تحت وب را با استفاده از این کتابخانه می توان پیاده کرد اما در این پروژه ما تنها به رسم یک مکعب نیاز خواهیم داشت . مقادیر مربوط به ابعاد مکعب ثابت می باشند و تنها مقادیر مربوط به زاویه و موقعیت آن باید در حین برنامه بر اساس موقعیت و زاویه ماژول MPU6050 تغییر کنند . در برنامه ها و پروژه های قبلی که آموزش داده شده کلیه مقادیری که به صورت وب سرور و از طریق ماژوب های ESP8266 و ESP32 نمایش داده سدن به صورت لحظه ای نبودند و با هر بار رفرش صفحه مقادیر تغییر می کردند . اما در اینجا ما باید مقادیر را به صورت Real Time به سمت Client ارسال کنیم . به همین دلیل از کتابخانه وب سرور آسنکرئم استفاده خواهیم کرد .
ابتدا کتابخانه های نشان داده شده در تصاویر زیر را دانلود کنید :
1- کتابخانه AdafruitMPU6050 برای راه اندازی ماژول MPU6050 :
2- کتابخانه Adafruit Unified Sensor برای استاندارد سازی پارامتر های دریافتی از سنسور ها :
3- نصب کتابخانه Adafruit_BusIO . این کتابخانه برای راه اندازی سنسور ها و ماژول های با رابط I2C و SPI می باشد :
4- کتابخانه های زیر را باید جدا دانلود کرده و آن ها را نصب کنید :
5- برای مرتب بودن ساختار داده های ارسالی از json استفاده شده است . لذا باید کتابخانه json را دانلود کنید :
پس از نصب کتابخانه های کد های زیر را بر روی برد خود پروگرام کنید :
#include <Arduino.h> #include <WiFi.h> #include <AsyncTCP.h> #include <ESPAsyncWebServer.h> #include <Adafruit_MPU6050.h> #include <Adafruit_Sensor.h> #include <Arduino_JSON.h> #include "SPIFFS.h" // Replace with your network credentials const char* ssid = "در این قسمت نام وایفای خود را وارد کنید "; const char* password = "در این قمست رمز وایفای خود را وارد کنید "; // Create AsyncWebServer object on port 80 AsyncWebServer server(80); // Create an Event Source on /events AsyncEventSource events("/events"); // Json Variable to Hold Sensor Readings JSONVar readings; // Timer variables unsigned long lastTime = 0; unsigned long lastTimeTemperature = 0; unsigned long lastTimeAcc = 0; unsigned long gyroDelay = 10; unsigned long temperatureDelay = 1000; unsigned long accelerometerDelay = 200; // Create a sensor object Adafruit_MPU6050 mpu; sensors_event_t a, g, temp; float gyroX, gyroY, gyroZ; float accX, accY, accZ; float temperature; //Gyroscope sensor deviation float gyroXerror = 0.07; float gyroYerror = 0.03; float gyroZerror = 0.01; // Init MPU6050 void initMPU(){ if (!mpu.begin()) { Serial.println("Failed to find MPU6050 chip"); while (1) { delay(10); } } Serial.println("MPU6050 Found!"); } void initSPIFFS() { if (!SPIFFS.begin()) { Serial.println("An error has occurred while mounting SPIFFS"); } Serial.println("SPIFFS mounted successfully"); } // Initialize WiFi void initWiFi() { WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); Serial.println(""); Serial.print("Connecting to WiFi..."); while (WiFi.status() != WL_CONNECTED) { Serial.print("."); delay(1000); } Serial.println(""); Serial.println(WiFi.localIP()); } String getGyroReadings(){ mpu.getEvent(&a, &g, &temp); float gyroX_temp = g.gyro.x; if(abs(gyroX_temp) > gyroXerror) { gyroX += gyroX_temp/50.00; } float gyroY_temp = g.gyro.y; if(abs(gyroY_temp) > gyroYerror) { gyroY += gyroY_temp/70.00; } float gyroZ_temp = g.gyro.z; if(abs(gyroZ_temp) > gyroZerror) { gyroZ += gyroZ_temp/90.00; } readings["gyroX"] = String(gyroX); readings["gyroY"] = String(gyroY); readings["gyroZ"] = String(gyroZ); String jsonString = JSON.stringify(readings); return jsonString; } String getAccReadings() { mpu.getEvent(&a, &g, &temp); // Get current acceleration values accX = a.acceleration.x; accY = a.acceleration.y; accZ = a.acceleration.z; readings["accX"] = String(accX); readings["accY"] = String(accY); readings["accZ"] = String(accZ); String accString = JSON.stringify (readings); return accString; } String getTemperature(){ mpu.getEvent(&a, &g, &temp); temperature = temp.temperature; return String(temperature); } void setup() { Serial.begin(115200); initWiFi(); initSPIFFS(); initMPU(); // Handle Web Server server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){ request->send(SPIFFS, "/index.html", "text/html"); }); server.serveStatic("/", SPIFFS, "/"); server.on("/reset", HTTP_GET, [](AsyncWebServerRequest *request){ gyroX=0; gyroY=0; gyroZ=0; request->send(200, "text/plain", "OK"); }); server.on("/resetX", HTTP_GET, [](AsyncWebServerRequest *request){ gyroX=0; request->send(200, "text/plain", "OK"); }); server.on("/resetY", HTTP_GET, [](AsyncWebServerRequest *request){ gyroY=0; request->send(200, "text/plain", "OK"); }); server.on("/resetZ", HTTP_GET, [](AsyncWebServerRequest *request){ gyroZ=0; request->send(200, "text/plain", "OK"); }); // Handle Web Server Events events.onConnect([](AsyncEventSourceClient *client){ if(client->lastId()){ Serial.printf("Client reconnected! Last message ID that it got is: %u\n", client->lastId()); } // send event with message "hello!", id current millis // and set reconnect delay to 1 second client->send("hello!", NULL, millis(), 10000); }); server.addHandler(&events); server.begin(); } void loop() { if ((millis() - lastTime) > gyroDelay) { // Send Events to the Web Server with the Sensor Readings events.send(getGyroReadings().c_str(),"gyro_readings",millis()); lastTime = millis(); } if ((millis() - lastTimeAcc) > accelerometerDelay) { // Send Events to the Web Server with the Sensor Readings events.send(getAccReadings().c_str(),"accelerometer_readings",millis()); lastTimeAcc = millis(); } if ((millis() - lastTimeTemperature) > temperatureDelay) { // Send Events to the Web Server with the Sensor Readings events.send(getTemperature().c_str(),"temperature_reading",millis()); lastTimeTemperature = millis(); } }
سپس از لینک زیر یه فایل با فرمت های Html ، CSS و JS را دانلود و آن را از طریق SPIFFS بر روی برد خود پروگرام کنید . قابلیت SPIFFS در آموزش های قبلی شرح داده شد .
https://github.com/RuiSantosdotme/Random-Nerd-Tutorials/tree/master/Projects/ESP32/ESP32_MPU_6050_Web_Server/data
نحوه ذخیره فایل ها در فولدر مربوط به پروژه ( برای استفاده از SPIFFS حتما باید این ترتیب رعایت گردد ) .
پس پروگرام کردن برنامه و همچنین فایل های فوق بر روی ماژول ، وارد محیط Serial monito آردوینو IDE شوید و یکبار ماژور را ریست کنید . IP را که نشان داده می شود در مروگر خود سرچ کنید تا صفحه زیر باز شود :
شماتیک اتصال MPU6050 به برد ESP32 :
منبع :https://randomnerdtutorials.com/esp32-mpu-6050-web-server/