safwan092

Untitled

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