Advertisement
bitwise_gamgee

Untitled

Oct 19th, 2023
155
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.32 KB | Fixit | 0 0
  1. #include <Wire.h>
  2. #include <MechaQMC5883.h>
  3. #include <TinyGPSPlus.h>
  4. #include <SoftwareSerial.h>
  5. #include <TinyStepper_28BYJ_48.h>
  6.  
  7. #define RXPin 3
  8. #define TXPin 4
  9. #define GPSBaud 9600
  10. #define LEDPin 13
  11.  
  12. MechaQMC5883 qmc;
  13. TinyGPSPlus gps;
  14. SoftwareSerial ss(RXPin, TXPin);
  15. TinyStepper_28BYJ_48 stepper;
  16.  
  17. float HOME_LAT = 0.0;
  18. float HOME_LON = 0.0;
  19. float DECLINATION_ANGLE = +2.20;
  20.  
  21. const int stepsPerRevolution = 2048;
  22. float currentHeading = 0;
  23. const float MIN_HEADING_DIFF = 5.0;
  24.  
  25. void setup() {
  26.   initializeComponents();
  27.   Serial.println(F("GPS, Compass, and Stepper Motor Test"));
  28.   Serial.println(F("Waiting for GPS data..."));
  29. }
  30.  
  31. void loop() {
  32.   updateGPSData();
  33.   if (gps.location.isValid()) {
  34.     executeNavigationLogic();
  35.   } else {
  36.     digitalWrite(LEDPin, LOW);
  37.   }
  38. }
  39.  
  40. void initializeComponents() {
  41.   Wire.begin();
  42.   Serial.begin(9600);
  43.   ss.begin(GPSBaud);
  44.   pinMode(LEDPin, OUTPUT);
  45.   digitalWrite(LEDPin, LOW);
  46.   qmc.init();
  47.   setupStepper();
  48. }
  49.  
  50. void setupStepper() {
  51.   stepper.connectToPins(8, 9, 10, 11);
  52.   stepper.setSpeedInStepsPerSecond(256);
  53.   stepper.setAccelerationInStepsPerSecondPerSecond(512);
  54. }
  55.  
  56. void updateGPSData() {
  57.   while (ss.available()) {
  58.     gps.encode(ss.read());
  59.   }
  60. }
  61.  
  62. void executeNavigationLogic() {
  63.   digitalWrite(LEDPin, HIGH);
  64.   displayGPSData();
  65.   float headingDegrees = readCompass();
  66.   float angleDegrees = calculateAngleToHome();
  67.   adjustMotor(headingDegrees, angleDegrees);
  68. }
  69.  
  70. void displayGPSData() {
  71.   Serial.print("Latitude: ");
  72.   Serial.println(gps.location.lat(), 6);
  73.   Serial.print("Longitude: ");
  74.   Serial.println(gps.location.lng(), 6);
  75. }
  76.  
  77. float readCompass() {
  78.   int x, y, z;
  79.   qmc.read(&x, &y, &z);
  80.   float heading = atan2(y, x);
  81.   heading += DECLINATION_ANGLE;
  82.   normalizeAngle(heading);
  83.   float headingDegrees = heading * 180 / M_PI;
  84.   return headingDegrees;
  85. }
  86.  
  87. void normalizeAngle(float &angle) {
  88.   if (angle < 0) angle += 2 * PI;
  89.   if (angle > 2 * PI) angle -= 2 * PI;
  90. }
  91.  
  92. float calculateAngleToHome() {
  93.   float angleToHome = atan2(HOME_LON - gps.location.lng(), HOME_LAT - gps.location.lat());
  94.   angleToHome += DECLINATION_ANGLE;
  95.   normalizeAngle(angleToHome);
  96.   return angleToHome * 180 / M_PI;
  97. }
  98.  
  99. void adjustMotor(float headingDegrees, float angleDegrees) {
  100.   float headingDifference = angleDegrees - currentHeading;
  101.   normalizeHeadingDifference(headingDifference);
  102.   currentHeading = headingDegrees;
  103.   if (abs(headingDifference) >= MIN_HEADING_DIFF) {
  104.     int targetSteps = headingDifference * (stepsPerRevolution / 360);
  105.     for (int i = 0; i < abs(targetSteps); i++) {
  106.       stepMotor(targetSteps, headingDifference, angleDegrees);
  107.     }
  108.   }
  109. }
  110.  
  111. void normalizeHeadingDifference(float &headingDifference) {
  112.   if (headingDifference > 180) {
  113.     headingDifference -= 360;
  114.   } else if (headingDifference < -180) {
  115.     headingDifference += 360;
  116.   }
  117. }
  118.  
  119. void stepMotor(int targetSteps, float &headingDifference, float angleDegrees) {
  120.   float headingChangePerStep = headingDifference / targetSteps;
  121.   if (targetSteps > 0) {
  122.     currentHeading += headingChangePerStep;
  123.     stepper.moveRelativeInSteps(1);
  124.   } else {
  125.     currentHeading -= headingChangePerStep;
  126.     stepper.moveRelativeInSteps(-1);
  127.   }
  128.   normalizeAngle(currentHeading);
  129.   headingDifference = angleDegrees - currentHeading;
  130.   normalizeHeadingDifference(headingDifference);
  131.   delay(10);
  132. }
  133.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement