safwan092

Untitled

Nov 2nd, 2025
45
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 23.94 KB | None | 0 0
  1. #include <Wire.h>
  2. #include <TinyGPSPlus.h>
  3.  
  4. //02-11-2025 Latest
  5. //////////////////////
  6. /*
  7. get_gps_data();
  8. sendSMSLocation();
  9. */
  10. //////////////////////
  11. ////////////////////////////////////////////////
  12. String s = "http://www.google.com/maps/place/";//"www.google.com/maps/dir/";
  13. static const uint32_t GPSBaud = 9600;
  14. String Lat = "";
  15. String Lng = "";
  16. int SendSMS_Now = 0;
  17. const size_t BUFSIZE = 300;
  18. char f_buffer[BUFSIZE];
  19. float *f_buf = (float*)f_buffer;
  20. TinyGPSPlus gps;
  21. ////////////////////////////////////////////////
  22.  
  23. ////////////////////////////////////////////////
  24. const int MPU_ADDR = 0x68;
  25. // MPU6050 register addresses
  26. const int PWR_MGMT_1 = 0x6B;
  27. const int ACCEL_XOUT_H = 0x3B;
  28. const int GYRO_XOUT_H = 0x43;
  29. const int TEMP_OUT_H = 0x41;
  30. // Calibration offsets
  31. float accelOffsetX = 0;
  32. float accelOffsetY = 0;
  33. float accelOffsetZ = 0;
  34. float gyroOffsetX = 0;
  35. float gyroOffsetY = 0;
  36. float gyroOffsetZ = 0;
  37. // Adaptive thresholds - will adjust based on normal motion
  38. float adaptiveAccelThreshold = 3.0; // Start with reasonable value
  39. float adaptiveGyroThreshold = 50.0; // Start with reasonable value
  40. // Impact detection
  41. const unsigned long IMPACT_WINDOW = 100; // Time to analyze impact (ms)
  42. const unsigned long HIT_COOLDOWN = 2000; // Prevent multiple detections
  43. const float SUDDEN_CHANGE_FACTOR = 3.0; // Must be 3x normal motion
  44. // Fall detection parameters
  45. const float FREE_FALL_THRESHOLD = 0.5; // Low G-force for free fall
  46. const float FALL_IMPACT_THRESHOLD = 4.0; // G-force for fall impact
  47. const unsigned long FALL_TIME_WINDOW = 3000; // Max time for fall sequence
  48. const unsigned long FALL_COOLDOWN = 5000; // Cooldown between fall detections
  49. // State variables
  50. bool hitDetected = false;
  51. bool fallDetected = false;
  52. unsigned long lastHitTime = 0;
  53. unsigned long lastFallTime = 0;
  54. unsigned long impactStartTime = 0;
  55. bool analyzingImpact = false;
  56. // Fall detection states
  57. bool inFreeFall = false;
  58. unsigned long fallStartTime = 0;
  59. bool waitingForFallImpact = false;
  60. // For adaptive threshold calculation
  61. float normalAccelMax = 0;
  62. float normalGyroMax = 0;
  63. unsigned long lastNormalUpdate = 0;
  64. const unsigned long NORMAL_LEARNING_TIME = 5000; // Learn normal motion for 5 sec
  65. // Impact analysis
  66. float impactAccelPeaks[10] = {0};
  67. float impactGyroPeaks[10] = {0};
  68. int peakCount = 0;
  69. // Filtering
  70. const int MOVING_AVERAGE_SAMPLES = 5;
  71. float accelBuffer[MOVING_AVERAGE_SAMPLES] = {0};
  72. float gyroBuffer[MOVING_AVERAGE_SAMPLES] = {0};
  73. int bufferIndex = 0;
  74. bool calibrated = false;
  75. const int CALIBRATION_SAMPLES = 100;
  76. bool learningPhase = true;
  77. ////////////////////////////////////////////////
  78. #define LED_PIN 18
  79.  
  80.  
  81. void setup() {
  82. Serial.begin(115200);
  83. Wire.begin();
  84. pinMode(LED_PIN, OUTPUT);
  85. digitalWrite(LED_PIN, 0);
  86. // Wake up MPU6050
  87. Wire.beginTransmission(MPU_ADDR);
  88. Wire.write(PWR_MGMT_1);
  89. Wire.write(0);
  90. Wire.endTransmission(true);
  91.  
  92. Serial.println("HEAD IMPACT & FALL DETECTION SYSTEM");
  93. Serial.println("Learning normal motion for 5 seconds...");
  94. Serial.println("Please walk around normally");
  95. calibrateSensor();
  96. Serial.println("Calibration complete!");
  97. Serial.println("======================================");
  98. lastNormalUpdate = millis();
  99.  
  100. setupA9G();
  101. Serial.println("Setup Executed");
  102. }
  103.  
  104. void send_SMS_NOW() {
  105. SendSMS_Now = 1;
  106. }
  107.  
  108. void calibrateSensor() {
  109. float accelXSum = 0, accelYSum = 0, accelZSum = 0;
  110. float gyroXSum = 0, gyroYSum = 0, gyroZSum = 0;
  111.  
  112. for (int i = 0; i < CALIBRATION_SAMPLES; i++) {
  113. int16_t accelX = readSensor(ACCEL_XOUT_H);
  114. int16_t accelY = readSensor(ACCEL_XOUT_H + 2);
  115. int16_t accelZ = readSensor(ACCEL_XOUT_H + 4);
  116. int16_t gyroX = readSensor(GYRO_XOUT_H);
  117. int16_t gyroY = readSensor(GYRO_XOUT_H + 2);
  118. int16_t gyroZ = readSensor(GYRO_XOUT_H + 4);
  119.  
  120. accelXSum += accelX / 16384.0;
  121. accelYSum += accelY / 16384.0;
  122. accelZSum += accelZ / 16384.0;
  123. gyroXSum += gyroX / 131.0;
  124. gyroYSum += gyroY / 131.0;
  125. gyroZSum += gyroZ / 131.0;
  126.  
  127. delay(10);
  128. }
  129.  
  130. accelOffsetX = accelXSum / CALIBRATION_SAMPLES;
  131. accelOffsetY = accelYSum / CALIBRATION_SAMPLES;
  132. accelOffsetZ = accelZSum / CALIBRATION_SAMPLES - 1.0;
  133.  
  134. gyroOffsetX = gyroXSum / CALIBRATION_SAMPLES;
  135. gyroOffsetY = gyroYSum / CALIBRATION_SAMPLES;
  136. gyroOffsetZ = gyroZSum / CALIBRATION_SAMPLES;
  137.  
  138. calibrated = true;
  139. }
  140.  
  141. float movingAverage(float buffer[], float newValue) {
  142. buffer[bufferIndex] = newValue;
  143. bufferIndex = (bufferIndex + 1) % MOVING_AVERAGE_SAMPLES;
  144.  
  145. float sum = 0;
  146. for (int i = 0; i < MOVING_AVERAGE_SAMPLES; i++) {
  147. sum += buffer[i];
  148. }
  149. return sum / MOVING_AVERAGE_SAMPLES;
  150. }
  151.  
  152.  
  153. //////////////////////////////////////////////////////////
  154. /////////////////// LOOP //////////////////////////
  155. //////////////////////////////////////////////////////////
  156. void loop() {
  157. digitalWrite(LED_PIN, 1);
  158. fullGPSSerial();
  159. readGPS_Data();
  160. showLATLON();
  161.  
  162. if (SendSMS_Now == 1) {
  163. digitalWrite(LED_PIN, 1);
  164. delay(50);
  165. digitalWrite(LED_PIN, 0);
  166. delay(50);
  167. digitalWrite(LED_PIN, 1);
  168. delay(50);
  169. digitalWrite(LED_PIN, 0);
  170. delay(50);
  171. digitalWrite(LED_PIN, 1);
  172. delay(50);
  173. digitalWrite(LED_PIN, 0);
  174. delay(50);
  175. digitalWrite(LED_PIN, 1);
  176. delay(50);
  177. digitalWrite(LED_PIN, 0);
  178. delay(50);
  179. get_gps_data();
  180. sendSMSLocation();
  181. delay(2000);
  182. s = "http://www.google.com/maps/place/";//"www.google.com/maps/dir/";
  183. SendSMS_Now = 0;
  184. }
  185. //digitalWrite(LED_PIN, 0);
  186. // Read sensor data
  187. int16_t rawAccelX = readSensor(ACCEL_XOUT_H);
  188. int16_t rawAccelY = readSensor(ACCEL_XOUT_H + 2);
  189. int16_t rawAccelZ = readSensor(ACCEL_XOUT_H + 4);
  190.  
  191. int16_t rawGyroX = readSensor(GYRO_XOUT_H);
  192. int16_t rawGyroY = readSensor(GYRO_XOUT_H + 2);
  193. int16_t rawGyroZ = readSensor(GYRO_XOUT_H + 4);
  194.  
  195. // Convert and apply calibration
  196. float accelX_g = rawAccelX / 16384.0 - accelOffsetX;
  197. float accelY_g = rawAccelY / 16384.0 - accelOffsetY;
  198. float accelZ_g = rawAccelZ / 16384.0 - accelOffsetZ;
  199.  
  200. float gyroX_deg = rawGyroX / 131.0 - gyroOffsetX;
  201. float gyroY_deg = rawGyroY / 131.0 - gyroOffsetY;
  202. float gyroZ_deg = rawGyroZ / 131.0 - gyroOffsetZ;
  203.  
  204. // Calculate magnitudes with moving average filtering
  205. float accelMagnitude = sqrt(accelX_g * accelX_g + accelY_g * accelY_g + accelZ_g * accelZ_g);
  206. float gyroMagnitude = sqrt(gyroX_deg * gyroX_deg + gyroY_deg * gyroY_deg + gyroZ_deg * gyroZ_deg);
  207.  
  208. float filteredAccel = movingAverage(accelBuffer, accelMagnitude);
  209. float filteredGyro = movingAverage(gyroBuffer, gyroMagnitude);
  210.  
  211. unsigned long currentTime = millis();
  212.  
  213. // Learning phase - understand normal motion
  214. if (learningPhase) {
  215. updateNormalMotionLevels(filteredAccel, filteredGyro, currentTime);
  216. }
  217.  
  218. // Run both detection systems
  219. checkForImpact(filteredAccel, filteredGyro, currentTime);
  220. checkForFall(filteredAccel, currentTime);
  221.  
  222. // Print status
  223. static unsigned long lastPrint = 0;
  224. if (currentTime - lastPrint > 1000) {
  225. printStatus(accelX_g, accelY_g, accelZ_g, gyroX_deg, gyroY_deg, gyroZ_deg,
  226. filteredAccel, filteredGyro, currentTime);
  227. lastPrint = currentTime;
  228. }
  229.  
  230. delay(20);
  231.  
  232. }// end of LOOP
  233. ///////////////////////////////////////////////////////////////
  234. ///////////////////////////////////////////////////////////////
  235.  
  236. ////////////////////////////////////////////////////////////
  237. void sendSMSLocation() {
  238. Serial.println("WARNING! Helmit Impact Detected");
  239.  
  240. /*
  241. /////
  242. Serial2.println("AT+CMGF=1\r");
  243. delay(1000);
  244.  
  245. Serial2.println("AT+CNMI=2,2,0,0,0\r");
  246. delay(1000);
  247.  
  248. Serial2.print("AT+CMGS=\"+966543522266\"\r");//Replace this with your mobile number
  249. delay(1000);
  250. Serial2.print(s);
  251. Serial2.write(0x1A);
  252. delay(3000);
  253. */
  254. /////
  255.  
  256. Serial2.println("AT+CMGF=1\r");
  257. delay(1000);
  258. Serial2.println("AT+CNMI=2,2,0,0,0\r");
  259. delay(1000);
  260. Serial2.print("AT+CMGS=\"+966543522266\"\r");//Replace this with your mobile number
  261. delay(1000);
  262. Serial2.print("WARNING! Helmit Impact Detected\n");
  263. Serial2.print(s);
  264. Serial2.write(0x1A);
  265.  
  266. Serial.println("Sending SMS is Done check your Phone!!!!!!!!!!!!!!!");
  267. delay(1000);
  268. s = "http://www.google.com/maps/place/";//"www.google.com/maps/dir/";
  269. }
  270. ////////////////////////////////////////////////////////////
  271.  
  272. void updateNormalMotionLevels(float accel, float gyro, unsigned long currentTime) {
  273. // Update maximum normal motion levels during learning phase
  274. if (accel > normalAccelMax) normalAccelMax = accel;
  275. if (gyro > normalGyroMax) normalGyroMax = gyro;
  276.  
  277. // End learning phase after 5 seconds
  278. if (currentTime - lastNormalUpdate > NORMAL_LEARNING_TIME) {
  279. learningPhase = false;
  280.  
  281. // Set adaptive thresholds based on learned normal motion
  282. adaptiveAccelThreshold = normalAccelMax * SUDDEN_CHANGE_FACTOR;
  283. adaptiveGyroThreshold = normalGyroMax * SUDDEN_CHANGE_FACTOR;
  284.  
  285. // Ensure minimum thresholds
  286. if (adaptiveAccelThreshold < 2.0) adaptiveAccelThreshold = 2.0;
  287. if (adaptiveGyroThreshold < 30.0) adaptiveGyroThreshold = 30.0;
  288.  
  289. Serial.println("\n*** LEARNING PHASE COMPLETE ***");
  290. Serial.print("Normal motion - Max Accel: "); Serial.print(normalAccelMax, 2); Serial.println("g");
  291. Serial.print("Normal motion - Max Gyro: "); Serial.print(normalGyroMax, 1); Serial.println("Β°/s");
  292. Serial.print("Adaptive thresholds - Accel: "); Serial.print(adaptiveAccelThreshold, 2); Serial.println("g");
  293. Serial.print("Adaptive thresholds - Gyro: "); Serial.print(adaptiveGyroThreshold, 1); Serial.println("Β°/s");
  294. Serial.println("Now monitoring for impacts and falls...");
  295. }
  296. }
  297.  
  298. void checkForImpact(float accel, float gyro, unsigned long currentTime) {
  299. // Check if we have a sudden change that might be an impact
  300. bool suddenChange = (accel > adaptiveAccelThreshold) || (gyro > adaptiveGyroThreshold);
  301.  
  302. if (suddenChange && !analyzingImpact) {
  303. // Start analyzing potential impact
  304. analyzingImpact = true;
  305. impactStartTime = currentTime;
  306. peakCount = 0;
  307. impactAccelPeaks[0] = accel;
  308. impactGyroPeaks[0] = gyro;
  309. Serial.println("πŸ’₯ Potential impact detected - analyzing...");
  310. }
  311.  
  312. if (analyzingImpact) {
  313. // Track peaks during impact window
  314. if (accel > impactAccelPeaks[peakCount]) impactAccelPeaks[peakCount] = accel;
  315. if (gyro > impactGyroPeaks[peakCount]) impactGyroPeaks[peakCount] = gyro;
  316.  
  317. // Check if impact analysis period is over
  318. if (currentTime - impactStartTime > IMPACT_WINDOW) {
  319. analyzeImpactPattern(currentTime);
  320. analyzingImpact = false;
  321. }
  322.  
  323. // Move to next peak every 20ms
  324. if (currentTime - impactStartTime > (peakCount + 1) * 20 && peakCount < 9) {
  325. peakCount++;
  326. impactAccelPeaks[peakCount] = accel;
  327. impactGyroPeaks[peakCount] = gyro;
  328. }
  329. }
  330.  
  331. // Reset hit detection after cooldown
  332. if (currentTime - lastHitTime > HIT_COOLDOWN) {
  333. hitDetected = false;
  334. }
  335. }
  336.  
  337. void analyzeImpactPattern(unsigned long currentTime) {
  338. // Find maximum values during impact window
  339. float maxAccel = 0;
  340. float maxGyro = 0;
  341.  
  342. for (int i = 0; i <= peakCount; i++) {
  343. if (impactAccelPeaks[i] > maxAccel) maxAccel = impactAccelPeaks[i];
  344. if (impactGyroPeaks[i] > maxGyro) maxGyro = impactGyroPeaks[i];
  345. }
  346.  
  347. // Determine if this is a real head impact
  348. bool isHeadImpact = verifyHeadImpact(maxAccel, maxGyro);
  349.  
  350. if (isHeadImpact && !hitDetected) {
  351. hitDetected = true;
  352. lastHitTime = currentTime;
  353.  
  354.  
  355. Serial.println("🚨 🚨 🚨 🚨 🚨 🚨 🚨 🚨 🚨 🚨 🚨 🚨");
  356. Serial.println("🚨 HEAD IMPACT DETECTED! 🚨");
  357. Serial.println("🚨 🚨 🚨 🚨 🚨 🚨 🚨 🚨 🚨 🚨 🚨 🚨");
  358. Serial.print("Impact Force: "); Serial.print(maxAccel, 1); Serial.println("g");
  359.  
  360. if (maxAccel > 1) {//2.1
  361. SendSMS_Now = 1;
  362. Serial.println("Sending SMS - Please Wait ... ");
  363. Serial.println("Sending SMS - Please Wait ... ");
  364. Serial.println("Sending SMS - Please Wait ... ");
  365. delay(5000);
  366. }
  367. /*
  368. Serial.print("Rotational Force: "); Serial.print(maxGyro, 1); Serial.println("Β°/s");
  369. Serial.print("Thresholds: "); Serial.print(adaptiveAccelThreshold, 1);
  370. Serial.print("g / "); Serial.print(adaptiveGyroThreshold, 1); Serial.println("Β°/s");
  371. Serial.println("⚠️ CHECK USER FOR CONCUSSION SYMPTOMS!");
  372. Serial.println();
  373. */
  374. } else if (!isHeadImpact) {
  375.  
  376. Serial.print("❌ False alarm: ");
  377. Serial.print(maxAccel, 1); Serial.print("g, ");
  378. Serial.print(maxGyro, 1); Serial.println("Β°/s - Normal motion pattern");
  379. /*
  380. if (maxAccel > 1) {//2.1
  381. SendSMS_Now = 1;
  382. Serial.println("Sending SMS - Please Wait ... ");
  383. Serial.println("Sending SMS - Please Wait ... ");
  384. Serial.println("Sending SMS - Please Wait ... ");
  385. delay(5000);
  386. }*/
  387. }
  388. }
  389.  
  390. bool verifyHeadImpact(float maxAccel, float maxGyro) {
  391. // Real head impacts typically have:
  392. // 1. Very high acceleration OR very high rotation
  393. // 2. Both values significantly above normal motion
  394. // 3. Specific pattern characteristics
  395.  
  396. bool highAccel = maxAccel > (normalAccelMax * 4.0); // 4x normal motion
  397. bool highGyro = maxGyro > (normalGyroMax * 4.0); // 4x normal motion
  398.  
  399. // Head impact usually has both linear and rotational components
  400. bool hasBothComponents = (maxAccel > adaptiveAccelThreshold * 1.2) &&
  401. (maxGyro > adaptiveGyroThreshold * 1.2);
  402.  
  403. // Or extremely high values in one component
  404. bool extremeSingleComponent = (maxAccel > adaptiveAccelThreshold * 2.0) ||
  405. (maxGyro > adaptiveGyroThreshold * 2.0);
  406.  
  407. return (hasBothComponents || extremeSingleComponent) && (highAccel || highGyro);
  408. }
  409.  
  410. void checkForFall(float accel, unsigned long currentTime) {
  411. // Fall detection logic: Free fall followed by impact
  412.  
  413. // Step 1: Detect free fall (low acceleration)
  414. if (accel < FREE_FALL_THRESHOLD && !inFreeFall && !waitingForFallImpact) {
  415. inFreeFall = true;
  416. fallStartTime = currentTime;
  417. Serial.println("⚠️ Free fall detected! Monitoring for impact...");
  418. }
  419.  
  420. // Step 2: If we're in free fall, wait for impact
  421. if (inFreeFall) {
  422. // Check if free fall period is too long (might not be a real fall)
  423. if (currentTime - fallStartTime > FALL_TIME_WINDOW) {
  424. inFreeFall = false;
  425. Serial.println("❌ Free fall too long - probably not a real fall");
  426. }
  427.  
  428. // Check for impact after free fall
  429. if (accel > FALL_IMPACT_THRESHOLD) {
  430. // This is the impact after a fall
  431. if (!fallDetected && (currentTime - lastFallTime > FALL_COOLDOWN)) {
  432. fallDetected = true;
  433. lastFallTime = currentTime;
  434. inFreeFall = false;
  435. waitingForFallImpact = false;
  436.  
  437.  
  438. Serial.println("🚨 🚨 🚨 🚨 🚨 🚨 🚨 🚨 🚨 🚨 🚨 🚨");
  439. Serial.println("🚨 FALL DETECTED! 🚨");
  440. Serial.println("🚨 🚨 🚨 🚨 🚨 🚨 🚨 🚨 🚨 🚨 🚨 🚨");
  441. Serial.print("Fall Impact: "); Serial.print(accel, 1); Serial.println("g");
  442. Serial.print("Free fall duration: ");
  443. Serial.print(currentTime - fallStartTime);
  444. Serial.println("ms");
  445. Serial.println("⚠️ USER MAY HAVE FALLEN - CHECK IMMEDIATELY!");
  446. Serial.println();
  447.  
  448. }
  449. }
  450. }
  451.  
  452. // Reset fall detection after cooldown
  453. if (currentTime - lastFallTime > FALL_COOLDOWN) {
  454. fallDetected = false;
  455. }
  456.  
  457. // Reset free fall state if acceleration returns to normal
  458. if (inFreeFall && accel > FREE_FALL_THRESHOLD * 2.0) {
  459. inFreeFall = false;
  460. waitingForFallImpact = true;
  461. // Wait a bit to see if impact comes
  462. if (currentTime - fallStartTime > 1000) {
  463. waitingForFallImpact = false;
  464. }
  465. }
  466. }
  467.  
  468. void printStatus(float accelX, float accelY, float accelZ, float gyroX, float gyroY, float gyroZ,
  469. float accelMag, float gyroMag, unsigned long currentTime) {
  470. /*
  471. Serial.print("Accel: ");
  472. Serial.print(accelX, 2); Serial.print("g, ");
  473. Serial.print(accelY, 2); Serial.print("g, ");
  474. Serial.print(accelZ, 2); Serial.print("g");
  475. Serial.print(" | Total: "); Serial.print(accelMag, 2); Serial.println("g");
  476.  
  477. Serial.print("Gyro: ");
  478. Serial.print(gyroX, 1); Serial.print("Β°/s, ");
  479. Serial.print(gyroY, 1); Serial.print("Β°/s, ");
  480. Serial.print(gyroZ, 1); Serial.print("Β°/s");
  481. Serial.print(" | Total: "); Serial.print(gyroMag, 1); Serial.println("Β°/s");
  482. */
  483. if (learningPhase) {
  484. float remaining = (NORMAL_LEARNING_TIME - (currentTime - lastNormalUpdate)) / 1000.0;
  485. /*
  486. Serial.print("πŸ“š Learning normal motion: ");
  487. Serial.print(remaining, 0); Serial.println("s remaining");
  488. Serial.print("Current max - Accel: "); Serial.print(normalAccelMax, 2);
  489. Serial.print("g, Gyro: "); Serial.print(normalGyroMax, 1); Serial.println("Β°/s");
  490. */
  491. } else {
  492. /*
  493. Serial.print("🎯 Thresholds: "); Serial.print(adaptiveAccelThreshold, 1);
  494. Serial.print("g / "); Serial.print(adaptiveGyroThreshold, 1); Serial.println("Β°/s");
  495. */
  496. // Status display for both systems
  497. if (hitDetected) {
  498. //Serial.println("🚨 HEAD IMPACT DETECTED - CHECK USER!");
  499. } else if (fallDetected) {
  500. //Serial.println("🚨 FALL DETECTED - USER MAY HAVE FALLEN!");
  501. } else if (inFreeFall) {
  502. //Serial.println("⚠️ Free fall detected - watching for impact...");
  503. } else if (analyzingImpact) {
  504. //Serial.println("πŸ’₯ Analyzing potential impact...");
  505. } else {
  506. //Serial.println("βœ… Normal - Monitoring impacts & falls");
  507. }
  508. }
  509.  
  510. Serial.println("-----------------------");
  511. }
  512.  
  513. int16_t readSensor(uint8_t reg) {
  514. Wire.beginTransmission(MPU_ADDR);
  515. Wire.write(reg);
  516. Wire.endTransmission(false);
  517. Wire.requestFrom(MPU_ADDR, 2, true);
  518. return (Wire.read() << 8) | Wire.read();
  519. }
  520.  
  521.  
  522. void get_gps_data() {
  523. if (gps.location.lat() == 0 || gps.location.lng() == 0) {
  524. Serial.println("Return Executed");
  525. s = "http://www.google.com/maps/place/21.413024,39.355396";//"http://www.google.com/maps/dir/21.413024,39.355396";
  526. Serial.println(s);
  527. return;
  528. }
  529. Serial.print("Latitude (deg): ");
  530. Lat = String(gps.location.lat(), 6);
  531. Serial.println(Lat);
  532. Serial.print("Longitude (deg): ");
  533. Lng = String(gps.location.lng(), 6);
  534. Serial.println(Lng);
  535. Serial.println();
  536. s += String(gps.location.lat(), 6);
  537. s += ",";
  538. s += String(gps.location.lng(), 6);
  539. s += "/";
  540. Serial.println(s);
  541. }
  542.  
  543. void setupA9G() {
  544. Serial2.begin(GPSBaud);
  545. Serial.println("Starting...");
  546. Serial2.println("\r");
  547. Serial2.println("AT\r");
  548. delay(10);
  549. Serial2.println("\r");
  550. Serial2.println("AT+GPS=1\r");
  551. delay(100);
  552. Serial2.println("AT+CREG=2\r");
  553. delay(6000);
  554. //ss.print("AT+CREG?\r");
  555. Serial2.println("AT+CGATT=1\r");
  556. delay(6000);
  557. Serial2.println("AT+CGDCONT=1,\"IP\",\"WWW\"\r");
  558. delay(6000);
  559. // ss.println("AT+LOCATION=1\r");
  560. Serial2.println("AT+CGACT=1,1\r");
  561. delay(6000);
  562. //Initialize ends
  563. //Initialize GPS
  564. Serial2.println("\r");
  565. Serial2.println("AT+GPS=1\r");
  566. delay(1000);
  567. //ss.println("AT+GPSMD=1\r"); // Change to only GPS mode from GPS+BDS, set to 2 to revert to default.
  568. Serial2.println("AT+GPSRD=10\r");
  569. delay(100);
  570. // set SMS mode to text mode
  571. Serial2.println("AT+CMGF=1\r");
  572. delay(1000);
  573. //ss.println("AT+LOCATION=2\r");
  574. Serial.println(F("FullExample.ino"));
  575. Serial.println(F("An extensive example of many interesting TinyGPSPlus features"));
  576. Serial.print(F("Testing TinyGPSPlus library v. ")); Serial.println(TinyGPSPlus::libraryVersion());
  577. Serial.println(F("by Mikal Hart"));
  578. Serial.println();
  579. Serial.println(F("Sats HDOP Latitude Longitude Fix Date Time Date Alt Course Speed Card Distance Course Card Chars Sentences Checksum"));
  580. Serial.println(F(" (deg) (deg) Age Age (m) --- from GPS ---- ---- to London ---- RX RX Fail"));
  581. Serial.println(F("----------------------------------------------------------------------------------------------------------------------------------------"));
  582. }
  583.  
  584. void readGPS_Data() {
  585. smartDelay(200);
  586. if (millis() > 5000 && gps.charsProcessed() < 10)
  587. Serial.println(F("No GPS data received: check wiring"));
  588. }
  589.  
  590. void showLATLON() {
  591. Serial.print("Latitude (deg): ");
  592. Lat = String(gps.location.lat(), 6);
  593. Serial.println(Lat);
  594. Serial.print("Longitude (deg): ");
  595. Lng = String(gps.location.lng(), 6);
  596. Serial.println(Lng);
  597. Serial.println();
  598. }
  599.  
  600.  
  601. void fullGPSSerial() {
  602. static const double LONDON_LAT = 51.508131, LONDON_LON = -0.128002;
  603. printInt(gps.satellites.value(), gps.satellites.isValid(), 5);
  604. printFloat(gps.hdop.hdop(), gps.hdop.isValid(), 6, 1);
  605. printFloat(gps.location.lat(), gps.location.isValid(), 11, 6);
  606. printFloat(gps.location.lng(), gps.location.isValid(), 12, 6);
  607. printInt(gps.location.age(), gps.location.isValid(), 5);
  608. printDateTime(gps.date, gps.time);
  609. printFloat(gps.altitude.meters(), gps.altitude.isValid(), 7, 2);
  610. printFloat(gps.course.deg(), gps.course.isValid(), 7, 2);
  611. printFloat(gps.speed.kmph(), gps.speed.isValid(), 6, 2);
  612. printStr(gps.course.isValid() ? TinyGPSPlus::cardinal(gps.course.deg()) : "*** ", 6);
  613.  
  614. unsigned long distanceKmToLondon =
  615. (unsigned long)TinyGPSPlus::distanceBetween(
  616. gps.location.lat(),
  617. gps.location.lng(),
  618. LONDON_LAT,
  619. LONDON_LON) / 1000;
  620. printInt(distanceKmToLondon, gps.location.isValid(), 9);
  621.  
  622. double courseToLondon =
  623. TinyGPSPlus::courseTo(
  624. gps.location.lat(),
  625. gps.location.lng(),
  626. LONDON_LAT,
  627. LONDON_LON);
  628.  
  629. printFloat(courseToLondon, gps.location.isValid(), 7, 2);
  630.  
  631. const char *cardinalToLondon = TinyGPSPlus::cardinal(courseToLondon);
  632.  
  633. printStr(gps.location.isValid() ? cardinalToLondon : "*** ", 6);
  634.  
  635. printInt(gps.charsProcessed(), true, 6);
  636. printInt(gps.sentencesWithFix(), true, 10);
  637. printInt(gps.failedChecksum(), true, 9);
  638. Serial.println();
  639.  
  640. smartDelay(100);
  641. if (gps.charsProcessed() > 63) {
  642. }
  643. if (millis() > 5000 && gps.charsProcessed() < 10)
  644. Serial.println(F("No GPS data received: check wiring"));
  645. }
  646.  
  647.  
  648. // This custom version of delay() ensures that the gps object
  649. // is being "fed".
  650. static void smartDelay(unsigned long ms)
  651. {
  652. unsigned long start = millis();
  653. do
  654. {
  655. while (Serial2.available())
  656. gps.encode(Serial2.read());
  657. } while (millis() - start < ms);
  658. }
  659.  
  660. static void printFloat(float val, bool valid, int len, int prec)
  661. {
  662. if (!valid)
  663. {
  664. while (len-- > 1) {}
  665. Serial.print('*');
  666. Serial.print(' ');
  667. }
  668. else
  669. {
  670. Serial.print(val, prec);
  671. int vi = abs((int)val);
  672. int flen = prec + (val < 0.0 ? 2 : 1); // . and -
  673. flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
  674. for (int i = flen; i < len; ++i) {}
  675. Serial.print(' ');
  676. }
  677. smartDelay(0);
  678. }
  679.  
  680. static void printInt(unsigned long val, bool valid, int len)
  681. {
  682. char sz[32] = "*****************";
  683. if (valid)
  684. sprintf(sz, "%ld", val);
  685. sz[len] = 0;
  686. for (int i = strlen(sz); i < len; ++i)
  687. sz[i] = ' ';
  688. if (len > 0)
  689. sz[len - 1] = ' ';
  690. Serial.print(sz);
  691. smartDelay(0);
  692. }
  693.  
  694. static void printDateTime(TinyGPSDate &d, TinyGPSTime &t)
  695. {
  696. if (!d.isValid())
  697. {
  698. Serial.print(F("********** "));
  699. }
  700. else
  701. {
  702. char sz[32];
  703. sprintf(sz, "%02d/%02d/%02d ", d.month(), d.day(), d.year());
  704. Serial.print(sz);
  705. }
  706.  
  707. if (!t.isValid())
  708. {
  709. Serial.print(F("******** "));
  710. }
  711. else
  712. {
  713. char sz[32];
  714. sprintf(sz, "%02d:%02d:%02d ", t.hour(), t.minute(), t.second());
  715. Serial.print(sz);
  716. }
  717.  
  718. printInt(d.age(), d.isValid(), 5);
  719. smartDelay(0);
  720. }
  721.  
  722. static void printStr(const char *str, int len)
  723. {
  724. int slen = strlen(str);
  725. for (int i = 0; i < len; ++i)
  726. Serial.print(i < slen ? str[i] : ' ');
  727. smartDelay(0);
  728. }
  729.  
  730.  
Advertisement
Add Comment
Please, Sign In to add comment