/* Author : Tarek Mahmoud Last Revision : 08/06/2021 Version : 0.1 */ // Initialisation of Libraries ____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________ #include #include "ESPAsyncWebServer.h" #include #include #include // Set these to your desired credentials. // Initialisation of Variables ____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________ // A - GPS & Compass // Base GPS variables are initialised. Target variables will be intialised in server double baseLongitude; double baseLatitude; double baseAltitude; // Received from HTTP Post as double targetLongitude; double targetLatitude; double targetAltitude; double targetSpeed; // Compass double baseAzimuth; double targetAzimuth; // B - Manual Motor Control Commands String postedMotorDirection; String postedMotorSpeed; // D - Current Operation Mode - Defined by Phone App int currentMode; // E - WiFi Access Point const char *ssid = "AutoTracking Camera Station"; const char *password = "1234abcde"; // Initialisation of server port AsyncWebServer server(80); // F - Stepper Motor #define dirPin 32 // direction pin #define stepPin 33 //step Pin #define Motor_Enable 25 // Enable Pin int motorDirection = 0; int stepperSpeed = 100; double stepsFraction = 1.00 / 1.00; double fStepsPerRevolution = 200.00 / stepsFraction; // Define a stepper and the pins it will use AccelStepper stepper(AccelStepper::DRIVER, stepPin, dirPin); // Custom Functions _______________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________ double azimuthCalculator(double baseLong, double baseLat, double targetLong, double targetLat) { // Function used to determine the target Azimuth // Converting fron Degrees to Radians baseLong = baseLong * PI / 180; baseLat = baseLat * PI / 180; targetLat = targetLat * PI / 180; targetLong = targetLong * PI / 180; double deltaLong = targetLong - baseLong; double deltaLat = targetLat - baseLat; double A = sin(deltaLong) * cos(targetLat); double B = cos(baseLat) * sin(targetLat) - sin(baseLat) * cos(targetLat) * cos(deltaLong); // Converting Azimuth to degrees double O = atan2(A, B) * 180 / PI; if (O < 0) { O = 360 + O; } return O; } double motorStepsCalculator(double AzimuthA, double AzimuthB, double stepFraction) { // Function used to calculate the numer of steps required to align the motor's azimuth with the target azimuth double deltaAzim = AzimuthA - AzimuthB; if (deltaAzim < 0) { deltaAzim = 360 - deltaAzim; } double steps = deltaAzim / stepFraction; return steps * 100; } // Setup __________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________ // ________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________ void setup() { Serial.begin(115200); Serial.println(); // WiFi Network Set up Serial.println("Configuring access point..."); WiFi.softAP(ssid, password); IPAddress myIP = WiFi.softAPIP(); Serial.print("AP IP address: "); Serial.println(myIP); // Async Server - Post ____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________ // ________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________ // the below handle all post requests from the companion app. server.on("/control_mode", HTTP_POST, [](AsyncWebServerRequest * request) {}, NULL, [](AsyncWebServerRequest * request, uint8_t *data, size_t len, size_t index, size_t total) { // Handling of data received. String controlMode; for (size_t i = 0; i < len; i++) { controlMode += (char)data[i]; } currentMode = controlMode.toInt(); switch (currentMode) { case 1: Serial.println("Auto-Tracking Mode"); break; case 2: Serial.println("Manual Motor Control Mode"); break; case 3: Serial.println("Manual Positioning Mode"); break; } request->send(200); }); server.on("/target_latitude", HTTP_POST, [](AsyncWebServerRequest * request) {}, NULL, [](AsyncWebServerRequest * request, uint8_t *data, size_t len, size_t index, size_t total) { // Handling of data received. String targetLatitude; for (size_t i = 0; i < len; i++) { targetLatitude += (char)data[i]; } targetLatitude = targetLatitude.toDouble(); request->send(200); }); server.on("/target_longitude", HTTP_POST, [](AsyncWebServerRequest * request) {}, NULL, [](AsyncWebServerRequest * request, uint8_t *data, size_t len, size_t index, size_t total) { // Handling of data received. String targetLongitude; for (size_t i = 0; i < len; i++) { targetLongitude += (char)data[i]; } targetLongitude = targetLongitude.toDouble(); request->send(200); }); server.on("/target_altitude", HTTP_POST, [](AsyncWebServerRequest * request) {}, NULL, [](AsyncWebServerRequest * request, uint8_t *data, size_t len, size_t index, size_t total) { // Handling of data received. String targetAltitude; for (size_t i = 0; i < len; i++) { targetAltitude += (char)data[i]; } targetAltitude = targetAltitude.toDouble(); Serial.println("Altitude Received"); request->send(200); }); server.on("/target_speed", HTTP_POST, [](AsyncWebServerRequest * request) {}, NULL, [](AsyncWebServerRequest * request, uint8_t *data, size_t len, size_t index, size_t total) { // Handling of data received. String targetSpeed; for (size_t i = 0; i < len; i++) { targetSpeed += (char)data[i]; } targetSpeed = targetSpeed.toDouble(); request->send(200); }); server.on("/base_latitude", HTTP_POST, [](AsyncWebServerRequest * request) {}, NULL, [](AsyncWebServerRequest * request, uint8_t *data, size_t len, size_t index, size_t total) { // Handling of data received. String baseLatitude; for (size_t i = 0; i < len; i++) { baseLatitude += (char)data[i]; } baseLatitude = baseLatitude.toDouble(); request->send(200); }); server.on("/base_longitude", HTTP_POST, [](AsyncWebServerRequest * request) {}, NULL, [](AsyncWebServerRequest * request, uint8_t *data, size_t len, size_t index, size_t total) { // Handling of data received. String baseLongitude; for (size_t i = 0; i < len; i++) { baseLongitude += (char)data[i]; } baseLongitude = baseLongitude.toDouble(); request->send(200); }); server.on("/motor_speed", HTTP_POST, [](AsyncWebServerRequest * request) {}, NULL, [](AsyncWebServerRequest * request, uint8_t *data, size_t len, size_t index, size_t total) { // Handling of data received. String postedMotorspeed; for (size_t i = 0; i < len; i++) { postedMotorSpeed += (char)data[i]; } stepperSpeed = postedMotorSpeed.toInt(); request->send(200); }); server.on("/motor_direction", HTTP_POST, [](AsyncWebServerRequest * request) {}, NULL, [](AsyncWebServerRequest * request, uint8_t *data, size_t len, size_t index, size_t total) { // Handling of data received. String postedMotorDirection; for (size_t i = 0; i < len; i++) { postedMotorDirection += (char)data[i]; } motorDirection = postedMotorDirection.toInt(); Serial.println(motorDirection); request->send(200); }); // Async Server - Get _____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________ // ________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________ server.on("/base_latitude", HTTP_GET, [](AsyncWebServerRequest * request) { request->send_P(200, "text/plain", String(baseLatitude).c_str()); Serial.print("Received GET request for board from client with IP: "); Serial.println(request->client()->remoteIP()); }); server.on("/base_longitude", HTTP_GET, [](AsyncWebServerRequest * request) { request->send_P(200, "text/plain", String(baseLongitude).c_str()); Serial.print("Received GET request for board from client with IP: "); Serial.println(request->client()->remoteIP()); }); // ________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________ // ________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________ Serial.println("Starting Server on port 80"); server.begin(); Serial.println("Server Started"); stepper.setMaxSpeed(1000); } // loop ___________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________ // ________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________ void loop() { switch (currentMode) { case 1: //Auto-Tracking Mode targetAzimuth = azimuthCalculator(baseLongitude, baseLatitude, targetLongitude, targetLatitude); if (targetAzimuth == baseAzimuth) { break; } else { break; } break; case 2: // Manual Motor Control Mode if (motorDirection == 0) { break; } else if (motorDirection == 1) { Serial.println("Counter Clockwise Rotation"); stepper.move(-1); } else { Serial.println("Clockwise Rotation"); stepper.move(1); } stepper.setSpeed(stepperSpeed); stepper.runSpeed(); break; case 3: // Manual Positioning Mode break; } }