Compare commits
3 Commits
main
...
Access-Poi
Author | SHA1 | Date | |
---|---|---|---|
49f0510ce4 | |||
9ff331ba66 | |||
e2adb04342 |
Binary file not shown.
38
README.md
38
README.md
@ -1,38 +0,0 @@
|
||||
Work yourself from the Main, to the rest of the branches step by step, as they build on each other. Follow the following steps in this README before doing the branches and Main though for a good setup.
|
||||
|
||||
Tutorial additions (Everything not present in the Git folder) (origin: docx file) Installing the PlatformIO IDE extension In Visual Studio Code, go to “Extensions”. Search for “PlatformIO“ and install said extension. A little Icon should appear on the left sidebar, click on it to initialize everything. And you’re good to go!
|
||||
|
||||
Basics of the PlatformIO IDE There are the 3 most important features it provides:
|
||||
|
||||
Building your project and flashing it to the Board of choice (example: ESP32)
|
||||
A .ini file to manage everything you need for a setup (for example what framework to use, what board, library dependencies etc)
|
||||
Practical inbuilt terminal
|
||||
How do you build a project? You click on the little checkmark at the bottom bar. How do you flash / install your program on the board of choice? Right next to said little checkmark is an arrow pointing right. Click on it, and it builds your program and flashes it. How do you access the terminal quickly? You click on the cable-head symbol on the same bar.
|
||||
|
||||
“Oh no, none of those symbols are there?!” Do not worry. Check whether you initialized the extension by clicking on it and checking if
|
||||
“PIO Home” -> “Open” opens a site or not. If the second is not the case, deinstall and reinstall the extension to see if that solves the issue.
|
||||
|
||||
Creating a new project in PlatformIO You have now successfully installed the extension. Well done! Now you can start the coding. Almost. Go to
|
||||
“PlatformIO” -> “PIO Home” -> “Open” -> “New Project”
|
||||
If you are working on the ESP32 S1, you can use the exact board selected in the picture. If not, you must check what other board selection works for your board.
|
||||
|
||||
Once that is all said and done, click Finish and your new project opens. You want to mainly work in “src”, “main.cpp” for now.
|
||||
|
||||
Installing the library you need for the MPU6050 This is one method as to how to include and install this library for your project, but I personally deem this method the best. Here are the steps:
|
||||
|
||||
Go to the little icon of the PlatformIO extension and click on it. Then go to the “Libraries” option.
|
||||
Once there, search for “Adafruit MPU6050”, there should be 5 results.
|
||||
Click on it, and then on “Add to Project”
|
||||
Select your project and the version, then click “Add”.
|
||||
This will take a little moment before it’s added, but once that’s done, you’re all good to go regarding including the .h files in your program.
|
||||
|
||||
The test and setup of the ESP32 itself. What do you need?
|
||||
|
||||
An esp32 (s1 optionally, mind the board selection in vs code)
|
||||
An MPU6050 (Check datasheet if unsure)
|
||||
A few cables of your choice (Jumpwires for example)
|
||||
A USB cable to sustain the ESP
|
||||
Here are the pins you need to connect to each other: (ESP Pin -> MPU6050 Pin)
|
||||
3v3 -> VCC (IMPORTANT! Not 5V) | GND -> GND | G22 -> SCL | G21 -> SDA
|
||||
|
||||
The other pins can be used for other specific stuff if curious check the datasheet.
|
Binary file not shown.
@ -12,9 +12,3 @@
|
||||
platform = espressif32
|
||||
board = upesy_wroom
|
||||
framework = arduino
|
||||
lib_deps = adafruit/Adafruit MPU6050@^2.2.6
|
||||
|
||||
; How to change bit-per-second rate for your project:
|
||||
; Add right under [env:upesy_wroom]:
|
||||
; "monitor_speed = x" (without the "")
|
||||
; x == baudrate of selected choice, bsp: 115200, 8000, 300
|
@ -1,96 +0,0 @@
|
||||
//--------------------------------------------------------------------------------------------------------------------------//
|
||||
// This is the seconed way to use the MPU sensor:
|
||||
//--------------------------------------------------------------------------------------------------------------------------//
|
||||
|
||||
// Include the library you want to use: //
|
||||
#include "Wire.h"
|
||||
|
||||
// Define the address to the chip: //
|
||||
#define MPU6050_ADDR 0x68 // Alternatively set AD0 to HIGH --> Address = 0x69
|
||||
|
||||
// Set up some variables //
|
||||
int16_t _accX; // Acceleration
|
||||
int16_t _accY;
|
||||
int16_t _accZ;
|
||||
int16_t _gyroX; // Gyro
|
||||
int16_t _gyroY;
|
||||
int16_t _gyroZ;
|
||||
int16_t _tRaw; // Raw register values (accelaration, gyroscope, temperature)
|
||||
|
||||
// Another for specific use (in this case, convertion) //
|
||||
char _result[7]; // Temporary variable used in convert function
|
||||
|
||||
// Prototype to function at the end //
|
||||
char* toStr(int16_t _character);
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200); // Mind the Bit per second rate you selected here if blindly copying!
|
||||
|
||||
// Start service //
|
||||
Wire.begin();
|
||||
Wire.beginTransmission(MPU6050_ADDR);
|
||||
|
||||
// Set up register //
|
||||
Wire.write(0x6B); // PWR_MGMT_1 register
|
||||
Wire.write(0); // wake up!
|
||||
Wire.endTransmission(true);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Begin exchange with the sensor //
|
||||
Wire.beginTransmission(MPU6050_ADDR);
|
||||
|
||||
Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H)
|
||||
Wire.endTransmission(false); // The parameter indicates that the Arduino will send a restart.
|
||||
// As a result, the connection is kept active.
|
||||
Wire.requestFrom(MPU6050_ADDR, 14, true); // request a total of 7*2=14 registers
|
||||
|
||||
// "Wire.read()<<8 | Wire.read();" means two registers are read and stored in the same int16_t variable //
|
||||
_accX = Wire.read()<<8 | Wire.read(); // reading registers: 0x3B (ACCEL_XOUT_H) and 0x3C (ACCEL_XOUT_L)
|
||||
_accY = Wire.read()<<8 | Wire.read(); // reading registers: 0x3D (ACCEL_YOUT_H) and 0x3E (ACCEL_YOUT_L)
|
||||
_accZ = Wire.read()<<8 | Wire.read(); // reading registers: 0x3F (ACCEL_ZOUT_H) and 0x40 (ACCEL_ZOUT_L)
|
||||
_tRaw = Wire.read()<<8 | Wire.read(); // reading registers: 0x41 (TEMP_OUT_H) and 0x42 (TEMP_OUT_L)
|
||||
_gyroX = Wire.read()<<8 | Wire.read(); // reading registers: 0x43 (GYRO_XOUT_H) and 0x44 (GYRO_XOUT_L)
|
||||
_gyroY = Wire.read()<<8 | Wire.read(); // reading registers: 0x45 (GYRO_YOUT_H) and 0x46 (GYRO_YOUT_L)
|
||||
_gyroZ = Wire.read()<<8 | Wire.read(); // reading registers: 0x47 (GYRO_ZOUT_H) and 0x48 (GYRO_ZOUT_L)
|
||||
|
||||
// Printing the read in values in a String fromat //
|
||||
Serial.print("AcX = ");
|
||||
Serial.print(toStr(accX));
|
||||
|
||||
Serial.print(" | AcY = ");
|
||||
Serial.print(toStr(accY));
|
||||
|
||||
Serial.print(" | AcZ = ");
|
||||
Serial.print(toStr(accZ));
|
||||
|
||||
// from data sheet: //
|
||||
Serial.print(" | tmp = "); Serial.print((tRaw + 12412.0) / 340.0);
|
||||
Serial.print(" | GyX = "); Serial.print(toStr(gyroX));
|
||||
Serial.print(" | GyY = "); Serial.print(toStr(gyroY));
|
||||
Serial.print(" | GyZ = "); Serial.print(toStr(gyroZ));
|
||||
Serial.println();
|
||||
|
||||
delay(1000); // NOTE! This is just for demonstration purposes.
|
||||
// The function "delay({insert wanted value in ms})" stops your ENTIRE programm,
|
||||
// not allowing the ESP to do ANYTHING until the delay is canceled after the listed milliseconds have passed.
|
||||
// If possible, avoid using it at all.
|
||||
}
|
||||
|
||||
// Function to convert the incoming values to String (for printing purposes) //
|
||||
char* toStr(int16_t _character)
|
||||
{
|
||||
// Formats "int16_t" to "String" (Attention! Not "std::string", the two are)
|
||||
// (two seperate classes and are not the same.)
|
||||
|
||||
sprintf(_result, "%6d", _character);
|
||||
return _result;
|
||||
}
|
||||
|
||||
// Note that all the values are purely raw. Further computing is required for them to actually be of use.
|
||||
// This is a more watered down version as to how to do this, but let's be real, you really won't need to make everything
|
||||
// harder if this delivers all you need.
|
||||
|
||||
// If there is interest on how to do this on an even lower and detailed level, talk to me and I'll try to explain.
|
281
src/main.cpp
281
src/main.cpp
@ -1,169 +1,154 @@
|
||||
//--------------------------------------------------------------------------------------------------------------------------//
|
||||
// Setting up the Adafruit_MPU6050 library for the accelerator chip
|
||||
// Setting up an Access Point hosted by the ESP32
|
||||
//--------------------------------------------------------------------------------------------------------------------------//
|
||||
|
||||
// Check the other guide in the .docx as to how to INSTALL the necessary library //
|
||||
// What is the difference between an Access Point and using the ESP as a client? //
|
||||
// Well, there's a big difference as to how either work, and what is needed. As an Access Point, you can create your own little "network" hosted
|
||||
// over the small WLAN module on the developing board. That let's you access a website on the ESP for example, without
|
||||
// having to go over any of your internet provider's servers since it's purely local.
|
||||
// When hosting an Access Point, you CANNOT log into another Wlan network. Clients (for example your phone) can log into the one on the ESP though.
|
||||
// If you want to use an async Webserver, that works better with the use of a router inbetween, and has more advantages all in all.
|
||||
// If no internet connection is required and it's for little displayment, a local Access Point should be enough.
|
||||
|
||||
// Must be included for most things! //
|
||||
#include <Arduino.h> // Only include once of course.
|
||||
#include <Adafruit_MPU6050.h>
|
||||
#include <Adafruit_Sensor.h>
|
||||
#include <Arduino.h>
|
||||
|
||||
// Create instance of the sensor library //
|
||||
Adafruit_MPU6050 mpu;
|
||||
// Load Wifi library //
|
||||
#include <WiFi.h>
|
||||
|
||||
// Set your network credentials (you are entirely free to choose anything) //
|
||||
const char* _ssid = "ESP32-Access-Point"; // for example
|
||||
const char* _password = "1234IamAPassword"; // that's a bad example, but you get the gist
|
||||
|
||||
// Set up instance and the right port (default: 80) //
|
||||
WiFiServer server(80);
|
||||
|
||||
// String to save the http adress in //
|
||||
String _http = "";
|
||||
|
||||
// State variable for the example following in the loop() function later //
|
||||
String _output_state = "off";
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200); // For Serial communication, check if the right bit-per-second rate is selected!
|
||||
// If you want to change said bit-per-second, look in the .ini file for information.
|
||||
// How do you know the one selected does not work / there's something wrong in the .ini file?
|
||||
// Check the terminal, if that is the case everything printed is Unicode gibberish.
|
||||
Serial.println("Setting up access point...");
|
||||
WiFi.softAP(_ssid, _password);
|
||||
IPAddress _IP = WiFi.softAPIP(); // You can see what is hosted on the ESP over this IP address.
|
||||
Serial.print("AP IP Address: ");
|
||||
Serial.println(_IP);
|
||||
|
||||
while(!Serial) delay(10); // Wait until the Serial communication is set up and initialized.
|
||||
Serial.println("Starting...");
|
||||
|
||||
if(!mpu.begin()) // Exception for the case of the mpu not starting up
|
||||
{
|
||||
// If this is the case, check the wiring and whether or not the right pins are connected.
|
||||
// Another issue that could lead to this is too little or too much current going through the chip.
|
||||
Serial.println("Failed to find MPU6050 chip.");
|
||||
while(1)
|
||||
{
|
||||
delay(10);
|
||||
server.begin(); // starts WiFi server.
|
||||
}
|
||||
}
|
||||
Serial.println("MPU6050 has been found.");
|
||||
|
||||
mpu.setAccelerometerRange(MPU6050_RANGE_8_G); // Set to the range of your choice for the accelerator values
|
||||
// depending on the range you want your read in values to vary in.
|
||||
Serial.println("Accelerator range set to: ");
|
||||
switch(mpu.getAccelerometerRange()) // Check setting and print for insight.
|
||||
{
|
||||
case MPU6050_RANGE_2_G:
|
||||
Serial.println("+-2G");
|
||||
break;
|
||||
case MPU6050_RANGE_4_G:
|
||||
Serial.println("+-4G");
|
||||
break;
|
||||
case MPU6050_RANGE_8_G:
|
||||
Serial.println("+-8G");
|
||||
break;
|
||||
case MPU6050_RANGE_16_G:
|
||||
Serial.println("+-16G");
|
||||
break;
|
||||
}
|
||||
|
||||
mpu.setGyroRange(MPU6050_RANGE_500_DEG);
|
||||
Serial.print("Gyro range set to: ");
|
||||
switch (mpu.getGyroRange())
|
||||
{
|
||||
case MPU6050_RANGE_250_DEG:
|
||||
Serial.println("+- 250 deg/s");
|
||||
break;
|
||||
case MPU6050_RANGE_500_DEG:
|
||||
Serial.println("+- 500 deg/s");
|
||||
break;
|
||||
case MPU6050_RANGE_1000_DEG:
|
||||
Serial.println("+- 1000 deg/s");
|
||||
break;
|
||||
case MPU6050_RANGE_2000_DEG:
|
||||
Serial.println("+- 2000 deg/s");
|
||||
break;
|
||||
}
|
||||
|
||||
mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);
|
||||
Serial.print("Filter bandwidth set to: ");
|
||||
switch (mpu.getFilterBandwidth())
|
||||
{
|
||||
case MPU6050_BAND_260_HZ:
|
||||
Serial.println("260 Hz");
|
||||
break;
|
||||
case MPU6050_BAND_184_HZ:
|
||||
Serial.println("184 Hz");
|
||||
break;
|
||||
case MPU6050_BAND_94_HZ:
|
||||
Serial.println("94 Hz");
|
||||
break;
|
||||
case MPU6050_BAND_44_HZ:
|
||||
Serial.println("44 Hz");
|
||||
break;
|
||||
case MPU6050_BAND_21_HZ:
|
||||
Serial.println("21 Hz");
|
||||
break;
|
||||
case MPU6050_BAND_10_HZ:
|
||||
Serial.println("10 Hz");
|
||||
break;
|
||||
case MPU6050_BAND_5_HZ:
|
||||
Serial.println("5 Hz");
|
||||
break;
|
||||
}
|
||||
|
||||
delay(100);
|
||||
|
||||
// What is the difference between "void setup()" and "void loop()"? Why put all this in here? //
|
||||
// The setup fuction is only initialized once, and though that's true for the entire lifetime of the programm,
|
||||
// the started services continue to run in here on this threat, allowing the loop to be executed simultaniously.
|
||||
// Mind, and that's IMPORTANT!!, that you should refer from using "while(1)" in this function as much as possible.
|
||||
// (I'm aware there is one in here in this project, but only because it is handled correctly and carefully.)
|
||||
}
|
||||
|
||||
// Put your variables here for testing, otherwise I'd recommend putting it in a class //
|
||||
float _x_accel = 0; // x acceleration
|
||||
float _y_accel = 0; // y acceleration
|
||||
float _calc = 0; // for calculations
|
||||
|
||||
void loop()
|
||||
{
|
||||
// NOTICE! You might wonder why this looks different to the earlier commit.
|
||||
// This is a better example to understand what's going on, run it to find out how to read in the meassuremnts.
|
||||
// Listen for any incoming clients, you can also create a thread extra for this if little processing power is needed //
|
||||
WiFiClient _client = server.available();
|
||||
// If that is the case, make sure to keep the service running. It should not be stopped or interrupted at all if the programm is still running,
|
||||
// I'd advice to use an exeption / interrupt that is listening in on whether or not a new client or http request has been received.
|
||||
// Be careful with that in general if you try it.
|
||||
|
||||
// Get new sensor events with the readings //
|
||||
sensors_event_t _a, _g, _temp;
|
||||
mpu.getEvent(&_a, &_g, &_temp);
|
||||
// "_a" == acceleration
|
||||
// "_g" == gyroscope values
|
||||
// "_temp" == temperature
|
||||
if(_client)
|
||||
{
|
||||
String _current_line = "";
|
||||
while(_client.connected()) // As long as the client is connected...
|
||||
{
|
||||
if(_client.available()) // Checks whether or not there is bites to read from.
|
||||
{
|
||||
char _c = _client.read(); // reads a single bite.
|
||||
_http += _c; // assembling the full http request one by one.
|
||||
|
||||
// Reading acceleration //
|
||||
Serial.print("Acceleration X: "); // Note that all the values are in "m/s^2" for further calculations!
|
||||
Serial.print(_a.acceleration.x);
|
||||
Serial.print(", Y: ");
|
||||
Serial.print(_a.acceleration.y);
|
||||
Serial.print(", Z: ");
|
||||
Serial.print(_a.acceleration.z);
|
||||
Serial.println(" m/s^2");
|
||||
// You can of course use those values to calculate the position in 3D if so needed.
|
||||
// For that, please read into it and try to write it yourself.
|
||||
if(_c != 10) // Listen in for LF (new line / line feat) since that is
|
||||
// a signal for the end of the request.
|
||||
// (Side note: Using '\n' here should technicall work here, but can create some errors.)
|
||||
// (Use 10 (ASCII) instead to avoid any misleading errors.)
|
||||
{
|
||||
// Send a response here, since every request needs a response.
|
||||
// If something went wrong, be sure to send an error message instead of nothing.
|
||||
|
||||
// Reading rotation from the gyroscope //
|
||||
Serial.print("Rotation X: ");
|
||||
Serial.print(_g.gyro.x);
|
||||
Serial.print(", Y: ");
|
||||
Serial.print(_g.gyro.y);
|
||||
Serial.print(", Z: ");
|
||||
Serial.print(_g.gyro.z);
|
||||
Serial.println(" rad/s");
|
||||
// Rotation in directions of x, y and z, as for acceleration as well as you can see.
|
||||
// If you're getting confused as to what is what IRL, look at the top of
|
||||
// the MPU sensor to see the small directions symboles for reorientation.
|
||||
// Replying: //
|
||||
if(_current_line.length() == 0)
|
||||
{
|
||||
// HTTP headers always start a certain way. So be sure to keep the following format.
|
||||
_client.println("HTTP/1.1 200 OK");
|
||||
_client.println("Content-type:text/html");
|
||||
_client.println("Connection: close");
|
||||
_client.println();
|
||||
// And there you go, a correct response that a client can work with!
|
||||
|
||||
// Reading in temperature //'
|
||||
Serial.print("Temperature: ");
|
||||
Serial.print(_temp.temperature);
|
||||
Serial.println(" degC");
|
||||
// Mind that it's read in in Celcius, if needed for further calculations.
|
||||
// Now you can technically compute whatever changes the client might have requested,
|
||||
// whether that was a press of a button or a press on a link. Any action needs to be responded to,
|
||||
// or else one might end up in the void of white like a blank page, or nothing happens.
|
||||
// The following is an example of how you would process requests with a html button.
|
||||
|
||||
// NOTE! This is html code written inside a C/C++ code. It's far from optional, and SPIFFS is therefor recommended if a
|
||||
// seperate html & css file is prefered. You can read about that in the tutorial branch to the Async Server.
|
||||
// For now, this is purely for demonstration.
|
||||
|
||||
// Handling the change of the example button //
|
||||
if (_http.indexOf("GET Button on") >= 0)
|
||||
{
|
||||
Serial.println("Button turned on");
|
||||
_output_state = "on";
|
||||
// digitalWrite(PIN, HIGH); // == how you would pull a Pin up when the button activates.
|
||||
}
|
||||
else if (_http.indexOf("GET Button off") >= 0)
|
||||
{
|
||||
Serial.println("Button turned off");
|
||||
_output_state = "off";
|
||||
// digitalWrite(PIN, LOW); // again for example.
|
||||
}
|
||||
|
||||
// Little side information //
|
||||
// If you are wondering why there are two pins called "XDA" and "XCL", educate yourself on it, but you
|
||||
// won't need those most likely.
|
||||
// Displaying the site //
|
||||
_client.println("<!DOCTYPE html><html>");
|
||||
_client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
|
||||
_client.println("<link rel=\"icon\" href=\"data:,\">");
|
||||
|
||||
// Tecnically, you only need the library asset "Wire.h" for all of this and not the whole Adafruit library.
|
||||
// But then again, that's a harder, and not exactly better way to use this sensor if not all too familiar with the
|
||||
// syntax of C++, but if you'd want to, try it out!
|
||||
// I've left a ".txt" file in this "src" folder that has the code tackling the second option.
|
||||
// Try it out if you'd like, or go with the method described in here. Your choice.
|
||||
// Set up a button //
|
||||
_client.println("<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}");
|
||||
_client.println(".button { background-color: #4CAF50; border: none; color: white; padding: 16px 40px;");
|
||||
_client.println("text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}");
|
||||
_client.println("</style></head>"); // closes the style tag.
|
||||
|
||||
// And done! //
|
||||
// Mind that everything in this loop repeats itself over and over, only stopping until the programm fails to execute or
|
||||
// the current is cut. If you'd like to restart everything, press the little button titled "RST" or "BOOT" (if the first does nothing) on the ESP.
|
||||
if (_output_state=="off")
|
||||
{
|
||||
_client.println("<p><a href=\"Button on\"><button class=\"button\">ON</button></a></p>");
|
||||
}
|
||||
else
|
||||
{
|
||||
_client.println("<p><a href=\"Button off\"><button class=\"button button2\">OFF</button></a></p>");
|
||||
}
|
||||
|
||||
// End the HTTP response with a LF as well //
|
||||
_client.println();
|
||||
break;
|
||||
}
|
||||
else // received a LF, clear the current line for input.
|
||||
{
|
||||
_current_line = "";
|
||||
}
|
||||
} // end of if()
|
||||
else if(_c != 13) // Handles the exeption for if you got anything but a carriage return.
|
||||
// NOTE! Technically, '\r' should also work, but like '\n', it can cause issues.
|
||||
// (Once more use 13 (ASCII) instead)
|
||||
{
|
||||
_current_line += _c;
|
||||
}
|
||||
} // end of if()
|
||||
} // end of while()
|
||||
|
||||
// Clear the request variable for later use //
|
||||
_http = "";
|
||||
|
||||
// Close the connection to the client //
|
||||
_client.stop();
|
||||
Serial.println("Client disconnected.");
|
||||
Serial.println();
|
||||
|
||||
// For every time the loop repeats, a new client and a new http request is being processed.
|
||||
}
|
||||
}
|
||||
|
||||
// As said, the example is a tedious an impractical way to host reactive html code.
|
||||
// Yet, it's enough for simple and fast displaying of values over a local WiFi Webserver.
|
||||
|
||||
// Still, since it needs an entire thread to run, it's far from the ideal way.
|
Loading…
Reference in New Issue
Block a user