{"id":4327,"date":"2025-03-03T08:55:08","date_gmt":"2025-03-03T16:55:08","guid":{"rendered":"https:\/\/www.donluc.com\/?p=4327"},"modified":"2025-03-03T08:55:08","modified_gmt":"2025-03-03T16:55:08","slug":"project-25-movement-sd-mk12","status":"publish","type":"post","link":"https:\/\/www.donluc.com\/?p=4327","title":{"rendered":"Project #25 &#8211; Movement &#8211; SD &#8211; Mk12"},"content":{"rendered":"<div style=\"width: 720px;\" class=\"wp-video\"><video class=\"wp-video-shortcode\" id=\"video-4327-1\" width=\"720\" height=\"480\" preload=\"metadata\" controls=\"controls\"><source type=\"video\/mp4\" src=\"https:\/\/www.donluc.com\/wp-content\/uploads\/2025\/03\/DL2502Mk05W.mp4?_=1\" \/><a href=\"https:\/\/www.donluc.com\/wp-content\/uploads\/2025\/03\/DL2502Mk05W.mp4\">https:\/\/www.donluc.com\/wp-content\/uploads\/2025\/03\/DL2502Mk05W.mp4<\/a><\/video><\/div>\n<p>&#8212;&#8212;<\/p>\n<p>#DonLucElectronics #DonLuc #SD #GPS #RTC #EEPROM #Compass #Accelerometer #Movement #ESP32 #Bluetooth #Elecrow #DFRobot #Arduino #Project #Patreon #Electronics #Microcontrollers #IoT #Fritzing #Programming #Consultant<\/p>\n<p>&#8212;&#8212;<\/p>\n<p><a href=\"https:\/\/www.donluc.com\/wp-content\/uploads\/2025\/03\/DL2502Mk05a.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.donluc.com\/wp-content\/uploads\/2025\/03\/DL2502Mk05a.jpg\" alt=\"SD\" width=\"720\" height=\"808\" class=\"alignnone size-full wp-image-4329\" srcset=\"https:\/\/www.donluc.com\/wp-content\/uploads\/2025\/03\/DL2502Mk05a.jpg 720w, https:\/\/www.donluc.com\/wp-content\/uploads\/2025\/03\/DL2502Mk05a-267x300.jpg 267w\" sizes=\"auto, (max-width: 720px) 100vw, 720px\" \/><\/a><\/p>\n<p>&#8212;&#8212;<\/p>\n<p><a href=\"https:\/\/www.donluc.com\/wp-content\/uploads\/2025\/03\/DL2502Mk05b.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.donluc.com\/wp-content\/uploads\/2025\/03\/DL2502Mk05b.jpg\" alt=\"SD\" width=\"720\" height=\"480\" class=\"alignnone size-full wp-image-4330\" srcset=\"https:\/\/www.donluc.com\/wp-content\/uploads\/2025\/03\/DL2502Mk05b.jpg 720w, https:\/\/www.donluc.com\/wp-content\/uploads\/2025\/03\/DL2502Mk05b-300x200.jpg 300w\" sizes=\"auto, (max-width: 720px) 100vw, 720px\" \/><\/a><\/p>\n<p>&#8212;&#8212;<\/p>\n<p><a href=\"https:\/\/www.donluc.com\/wp-content\/uploads\/2025\/03\/DL2502Mk05c.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.donluc.com\/wp-content\/uploads\/2025\/03\/DL2502Mk05c.jpg\" alt=\"SD\" width=\"720\" height=\"480\" class=\"alignnone size-full wp-image-4331\" srcset=\"https:\/\/www.donluc.com\/wp-content\/uploads\/2025\/03\/DL2502Mk05c.jpg 720w, https:\/\/www.donluc.com\/wp-content\/uploads\/2025\/03\/DL2502Mk05c-300x200.jpg 300w\" sizes=\"auto, (max-width: 720px) 100vw, 720px\" \/><\/a><\/p>\n<p>&#8212;&#8212;<\/p>\n<p><strong>MicroSD Card Module<\/strong><\/p>\n<p>There are different microSD card modules compatible with the ESP32. We\u2019re using the microSD card module it communicates using SPI communication protocol. You can use any other microSD card module with an SPI interface. This microSD card module is also compatible with other microcontrollers like the Arduino boards. To learn how to use the microSD card module with the Arduino. You can connect it to the ESP32 using the default SPI pins.<\/p>\n<p><strong>DL2502Mk05<\/strong><\/p>\n<p>1 x DFRobot FireBeetle 2 ESP32-E<br \/>\n1 x Fermion: 2.0&#8243; 320&#215;240 IPS TFT LCD<br \/>\n1 x GDL Line 10 CM<br \/>\n1 x Crowtail &#8211; I2C Hub 2.0<br \/>\n1 x Crowtail &#8211; Switch 2.0<br \/>\n1 x Adafruit MicroSD card breakout board+<br \/>\n1 x MicroSD 4 GB<br \/>\n1 x Crowtail &#8211; LED(Red)<br \/>\n1 x GPS Receiver &#8211; GP-20U7<br \/>\n1 x Adafruit DS3231 Precision RTC FeatherWing<br \/>\n1 x CR1220 Battery<br \/>\n1 x Crowtail &#8211; 3-Axis Digital Compass<br \/>\n1 x Crowtail &#8211; 3-Axis Digital Accelerometer<br \/>\n1 x Lithium Ion Battery &#8211; 1000mAh<br \/>\n1 x Switch<br \/>\n1 x Bluetooth Serial Terminal<br \/>\n1 x USB 3.1 Cable A to C<\/p>\n<p><strong>FireBeetle 2 ESP32-E<\/strong><\/p>\n<p>SCL &#8211; 22<br \/>\nSDA &#8211; 21<br \/>\nSCK &#8211; 18<br \/>\nMOSI &#8211; 23<br \/>\nMISO &#8211; 19<br \/>\nCS &#8211; 4<br \/>\nPOT &#8211; 16<br \/>\nLED &#8211; 17<br \/>\nGPR &#8211; 0<br \/>\nGPT &#8211; 2<br \/>\nDC &#8211; D2<br \/>\nCS &#8211; D6<br \/>\nRST &#8211; D3<br \/>\nRX2 &#8211; Bluetooth<br \/>\nTX2 &#8211; Bluetooth<br \/>\nVIN &#8211; +3.3V<br \/>\nGND &#8211; GND<\/p>\n<p><strong>DL2502Mk05p<\/strong><\/p>\n<p><strong>DL2502Mk05p.ino<\/strong><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"arduino\" data-enlighter-title=\"\">\r\n\/****** Don Luc Electronics \u00a9 ******\r\n  Software Version Information\r\n  Project #25 - Movement - SD - Mk12\r\n  25-12\r\n  DL2502Mk05p.ino\r\n  DL2502Mk05\r\n  1 x DFRobot FireBeetle 2 ESP32-E\r\n  1 x Fermion: 2.0&quot; 320x240 IPS TFT LCD\r\n  1 x GDL Line 10 CM\r\n  1 x Crowtail - I2C Hub 2.0\r\n  1 x Crowtail - Switch 2.0\r\n  1 x Adafruit MicroSD card breakout board+\r\n  1 x MicroSD 4 GB\r\n  1 x Crowtail - LED(Red)\r\n  1 x GPS Receiver - GP-20U7\r\n  1 x Adafruit DS3231 Precision RTC FeatherWing\r\n  1 x CR1220 Battery\r\n  1 x Crowtail - 3-Axis Digital Compass\r\n  1 x Crowtail - 3-Axis Digital Accelerometer\r\n  1 x Lithium Ion Battery - 1000mAh\r\n  1 x Switch\r\n  1 x Bluetooth Serial Terminal\r\n  1 x USB 3.1 Cable A to C\r\n*\/\r\n\r\n\/\/ Include the Library Code\r\n\/\/ EEPROM Library to Read and Write EEPROM\r\n\/\/ with Unique ID for Unit\r\n#include &quot;EEPROM.h&quot;\r\n\/\/ Arduino\r\n#include &lt;Arduino.h&gt;\r\n\/\/ Wire\r\n#include &lt;Wire.h&gt;\r\n\/\/ DFRobot Display GDL API\r\n#include &lt;DFRobot_GDL.h&gt;\r\n\/\/ Bluetooth Serial\r\n#include &quot;BluetoothSerial.h&quot;\r\n#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)\r\n#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it\r\n#endif\r\n\/\/ Accelemeter ADXL345\r\n#include &lt;ADXL345.h&gt;\r\n\/\/ Compass HMC5883L\r\n#include &lt;HMC5883L.h&gt;\r\n\/\/ RTC (Real-Time Clock)\r\n#include &quot;RTClib.h&quot;\r\n\/\/ GPS Receiver\r\n#include &lt;TinyGPS++.h&gt;\r\n\/\/ ESP32 Hardware Serial\r\n#include &lt;HardwareSerial.h&gt;\r\n\/\/ SD Card\r\n#include &quot;FS.h&quot;\r\n#include &quot;SD.h&quot;\r\n#include &quot;SPI.h&quot;\r\n\r\n\/\/ Define LED Red\r\nint iLED = 17;\r\n\r\n\/\/ Switch\r\nint iSwitch = 16;\r\n\/\/ Variable for reading the Switch status\r\nint iSwitchState = 0;\r\n\r\n\/\/ MicroSD Card\r\nconst int chipSelect = 4;\r\nString zzzzzz = &quot;&quot;;\r\n\r\n\/\/ ESP32 HardwareSerial\r\nHardwareSerial tGPS(1);\r\n\r\n\/\/ GPS Receiver\r\n#define gpsRXPIN 0\r\n\/\/ This one is unused and doesnt have a conection\r\n#define gpsTXPIN 2\r\n\/\/ The TinyGPS++ object\r\nTinyGPSPlus gps;\r\n\/\/ Latitude\r\nfloat TargetLat;\r\n\/\/ Longitude\r\nfloat TargetLon;\r\n\/\/ GPS Date, Time, Speed, Altitude\r\n\/\/ GPS Date\r\nString TargetDat;\r\n\/\/ GPS Time\r\nString TargetTim;\r\n\/\/ GPS Speeds M\/S\r\nString TargetSMS;\r\n\/\/ GPS Speeds Km\/h\r\nString TargetSKH;\r\n\/\/ GPS Altitude Meters\r\nString TargetALTM;\r\n\/\/ GPS Altitude Feet\r\nString TargetALTF;\r\n\/\/ GPS Status\r\nString GPSSt = &quot;&quot;;\r\n\r\n\/\/ RTC (Real-Time Clock)\r\nRTC_DS3231 rtc;\r\nString dateRTC = &quot;&quot;;\r\nString timeRTC = &quot;&quot;;\r\nString tempRTC = &quot;&quot;;\r\n\r\n\/\/ Compass HMC5883L\r\nHMC5883L compass;\r\n\/\/ Heading\r\nfloat heading;\r\n\/\/ Heading Degrees\r\nfloat headingDegrees;\r\n\r\n\/\/ Variable ADXL345 library\r\nADXL345 adxl;\r\n\/\/ Accelerometer ADXL345\r\n\/\/ x, y, z\r\nint x;\r\nint y;\r\nint z;\r\n\/\/ Standard Gravity\r\n\/\/ xyz\r\ndouble xyz[3];\r\ndouble ax;\r\ndouble ay;\r\ndouble az;\r\n\r\n\/\/ FullString\r\nString FullString = &quot;&quot;;\r\n\r\n\/\/ Bluetooth Serial\r\nBluetoothSerial SerialBT;\r\n\r\n\/\/ Defined ESP32\r\n#define TFT_DC  D2\r\n#define TFT_CS  D6\r\n#define TFT_RST D3\r\n\r\n\/*dc=*\/ \/*cs=*\/ \/*rst=*\/\r\n\/\/ DFRobot Display 240x320\r\nDFRobot_ST7789_240x320_HW_SPI screen(TFT_DC, TFT_CS, TFT_RST);\r\n\r\n\/\/ EEPROM Unique ID Information\r\n#define EEPROM_SIZE 64\r\nString uid = &quot;&quot;;\r\n\r\n\/\/ Software Version Information\r\nString sver = &quot;25-12&quot;;\r\n\r\nvoid loop() {\r\n\r\n  \/\/ Accelemeter ADXL345\r\n  isADXL345();\r\n\r\n  \/\/ Compass HMC5883L\r\n  isHMC5883L();\r\n\r\n  \/\/ RTC (Real-Time Clock)\r\n  isRTC();\r\n\r\n  \/\/ isGPS\r\n  isGPS();\r\n\r\n  \/\/ Accelemeter ADXL345 Compass HMC5883L Display\r\n  isDisplayADXL345HMC5883L();\r\n\r\n  \/\/ Read the state of the Switch value\r\n  iSwitchState = digitalRead(iSwitch);\r\n\r\n  \/\/ The Switch is HIGH:\r\n  if (iSwitchState == HIGH) {\r\n\r\n    \/\/ LED Red HIGH\r\n    digitalWrite(iLED, HIGH);\r\n\r\n    \/\/ MicroSD Card\r\n    isSD();\r\n\r\n  } else {\r\n\r\n    \/\/ LED Red LOW\r\n    digitalWrite(iLED, LOW);\r\n\r\n  }\r\n\r\n  \/\/ Delay 0.5 Second\r\n  delay( 500 );\r\n\r\n}\r\n<\/pre>\n<p><strong>getAccelemeterADXL345.ino<\/strong><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"arduino\" data-enlighter-title=\"\">\r\n\/\/ Accelemeter ADXL345\r\n\/\/ Setup Accelemeter ADXL345\r\nvoid isSetupADXL345(){\r\n\r\n  \/\/ Power On\r\n  adxl.powerOn();\r\n\r\n  \/\/ Set activity inactivity thresholds (0-255)\r\n  \/\/ 62.5mg per increment\r\n  adxl.setActivityThreshold(75);\r\n  \/\/ 62.5mg per increment\r\n  adxl.setInactivityThreshold(75);\r\n  \/\/ How many seconds of no activity is inactive?\r\n  adxl.setTimeInactivity(10);\r\n \r\n  \/\/look of activity movement on this axes - 1 == on; 0 == off \r\n  adxl.setActivityX(1);\r\n  adxl.setActivityY(1);\r\n  adxl.setActivityZ(1);\r\n \r\n  \/\/look of inactivity movement on this axes - 1 == on; 0 == off\r\n  adxl.setInactivityX(1);\r\n  adxl.setInactivityY(1);\r\n  adxl.setInactivityZ(1);\r\n \r\n  \/\/ Look of tap movement on this axes - 1 == on; 0 == off\r\n  adxl.setTapDetectionOnX(0);\r\n  adxl.setTapDetectionOnY(0);\r\n  adxl.setTapDetectionOnZ(1);\r\n \r\n  \/\/ Set values for what is a tap, and what is a double tap (0-255)\r\n  \/\/ 62.5mg per increment\r\n  adxl.setTapThreshold(50);\r\n  \/\/ 625us per increment\r\n  adxl.setTapDuration(15);\r\n  \/\/ 1.25ms per increment\r\n  adxl.setDoubleTapLatency(80);\r\n  \/\/ 1.25ms per increment\r\n  adxl.setDoubleTapWindow(200);\r\n \r\n  \/\/ set values for what is considered freefall (0-255)\r\n  \/\/ (5 - 9) recommended - 62.5mg per increment\r\n  adxl.setFreeFallThreshold(7);\r\n  \/\/ (20 - 70) recommended - 5ms per increment\r\n  adxl.setFreeFallDuration(45);\r\n \r\n  \/\/ Setting all interrupts to take place on int pin 1\r\n  \/\/ I had issues with int pin 2, was unable to reset it\r\n  adxl.setInterruptMapping( ADXL345_INT_SINGLE_TAP_BIT,   ADXL345_INT1_PIN );\r\n  adxl.setInterruptMapping( ADXL345_INT_DOUBLE_TAP_BIT,   ADXL345_INT1_PIN );\r\n  adxl.setInterruptMapping( ADXL345_INT_FREE_FALL_BIT,    ADXL345_INT1_PIN );\r\n  adxl.setInterruptMapping( ADXL345_INT_ACTIVITY_BIT,     ADXL345_INT1_PIN );\r\n  adxl.setInterruptMapping( ADXL345_INT_INACTIVITY_BIT,   ADXL345_INT1_PIN );\r\n \r\n  \/\/ Register interrupt actions - 1 == on; 0 == off  \r\n  adxl.setInterrupt( ADXL345_INT_SINGLE_TAP_BIT, 1);\r\n  adxl.setInterrupt( ADXL345_INT_DOUBLE_TAP_BIT, 1);\r\n  adxl.setInterrupt( ADXL345_INT_FREE_FALL_BIT,  1);\r\n  adxl.setInterrupt( ADXL345_INT_ACTIVITY_BIT,   1);\r\n  adxl.setInterrupt( ADXL345_INT_INACTIVITY_BIT, 1);\r\n\r\n}\r\n\/\/ Accelemeter ADXL345\r\nvoid isADXL345(){\r\n\r\n  \/\/ Read the accelerometer values and store them in variables  x,y,z\r\n  adxl.readXYZ(&amp;x, &amp;y, &amp;z);\r\n\r\n  \/\/ Standard Gravity\r\n  \/\/ Acceleration\r\n  adxl.getAcceleration(xyz);\r\n\r\n  \/\/ Output\r\n  ax = xyz[0];\r\n  ay = xyz[1];\r\n  az = xyz[2];\r\n  \r\n}\r\n<\/pre>\n<p><strong>getCompassHMC5883L.ino<\/strong><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"arduino\" data-enlighter-title=\"\">\r\n\/\/ HMC5883L Triple Axis Digital Compass\r\n\/\/ Setup HMC5883L\r\nvoid isSetupHMC5883L(){\r\n\r\n  \/\/ Initialize Initialize HMC5883L\r\n  compass.begin();\r\n\r\n  \/\/ Set measurement range\r\n  compass.setRange(HMC5883L_RANGE_1_3GA);\r\n\r\n  \/\/ Set measurement mode\r\n  compass.setMeasurementMode(HMC5883L_CONTINOUS);\r\n\r\n  \/\/ Set data rate\r\n  compass.setDataRate(HMC5883L_DATARATE_30HZ);\r\n\r\n  \/\/ Set number of samples averaged\r\n  compass.setSamples(HMC5883L_SAMPLES_8);\r\n\r\n  \/\/ Set calibration offset\r\n  compass.setOffset(0, 0);\r\n  \r\n}\r\n\/\/ Compass HMC5883L\r\nvoid isHMC5883L(){\r\n\r\n  \/\/ Vector norm\r\n  Vector norm = compass.readNormalize();\r\n\r\n  \/\/ Calculate heading\r\n  heading = atan2(norm.YAxis, norm.XAxis);\r\n\r\n  \/\/ Set declination angle on your location and fix heading\r\n  \/\/ You can find your declination on: http:\/\/magnetic-declination.com\/\r\n  \/\/ (+) Positive or (-) for negative\r\n  \/\/ Latitude: 32\u00b0 39&#039; 7.9&quot; N\r\n  \/\/ Longitude: 115\u00b0 28&#039; 6.2&quot; W\r\n  \/\/ Magnetic Declination: +10\u00b0 35&#039;\r\n  \/\/ Declination is POSITIVE (EAST)\r\n  \/\/ Inclination: 58\u00b0 4&#039;\r\n  \/\/ Magnetic field strength: 45759.1 nT\r\n  \/\/ Formula: (deg + (min \/ 60.0)) \/ (180 \/ M_PI);\r\n  float declinationAngle = (10.0 + (35.0 \/ 60.0)) \/ (180 \/ M_PI);\r\n  heading += declinationAngle;\r\n\r\n  \/\/ Correct for heading &lt; 0deg and heading &gt; 360deg\r\n  if (heading &lt; 0)\r\n  {\r\n    heading += 2 * PI;\r\n  }\r\n\r\n  if (heading &gt; 2 * PI)\r\n  {\r\n    heading -= 2 * PI;\r\n  }\r\n\r\n  \/\/ Convert to degrees\r\n  headingDegrees = heading * 180\/M_PI; \r\n\r\n}\r\n<\/pre>\n<p><strong>getDisplay.ino<\/strong><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"arduino\" data-enlighter-title=\"\">\r\n\/\/ DFRobot Display 240x320\r\n\/\/ DFRobot Display 240x320 - UID\r\nvoid isDisplayUID(){\r\n\r\n  \/\/ DFRobot Display 240x320\r\n  \/\/ Text Display\r\n  \/\/ Text Wrap\r\n  screen.setTextWrap(false);\r\n  \/\/ Rotation\r\n  screen.setRotation(3);\r\n  \/\/ Fill Screen =&gt; black\r\n  screen.fillScreen(0x0000);\r\n  \/\/ Text Color =&gt; white\r\n  screen.setTextColor(0xffff);\r\n  \/\/ Font =&gt; Free Sans Bold 12pt\r\n  screen.setFont(&amp;FreeSansBold12pt7b);\r\n  \/\/ TextSize =&gt; 1.5\r\n  screen.setTextSize(1.5);\r\n  \/\/ Don Luc Electronics\r\n  screen.setCursor(0, 30);\r\n  screen.println(&quot;Don Luc Electronics&quot;);\r\n  \/\/ SD\r\n  screen.setCursor(0, 60);\r\n  screen.println(&quot;SD&quot;);\r\n  \/\/ Version\r\n  screen.setCursor(0, 90);\r\n  screen.println(&quot;Version&quot;);\r\n  screen.setCursor(0, 120);\r\n  screen.println( sver );\r\n  \/\/ EEPROM\r\n  screen.setCursor(0, 150);\r\n  screen.println(&quot;EEPROM&quot;);\r\n  screen.setCursor(0, 180);\r\n  screen.println( uid );\r\n\r\n}\r\n\/\/ Accelemeter and Compass, ADXL345 and HMC5883L\r\nvoid isDisplayADXL345HMC5883L(){\r\n\r\n  \/\/ DFRobot Display 240x320\r\n  \/\/ Text Display\r\n  \/\/ Text Wrap\r\n  screen.setTextWrap(false);\r\n  \/\/ Rotation\r\n  screen.setRotation(3);\r\n  \/\/ Fill Screen =&gt; white\r\n  screen.fillScreen(0xffff);\r\n  \/\/ Text Color =&gt; blue\r\n  screen.setTextColor(0x001F);\r\n  \/\/ Font =&gt; Free Sans Bold 12pt\r\n  screen.setFont(&amp;FreeSansBold12pt7b);\r\n  \/\/ TextSize =&gt; 1.5\r\n  screen.setTextSize(1.5);\r\n  \/\/ Accelemeter ADXL345\r\n  screen.setCursor(0, 30);\r\n  screen.println(&quot;Accelemeter ADXL345&quot;);\r\n  \/\/ Accelemeter ADXL345 X\r\n  screen.setCursor(0, 60);\r\n  screen.println(&quot;X: &quot;);\r\n  screen.setCursor(40, 60);\r\n  screen.println( x );\r\n  \/\/ Accelemeter ADXL345 Y\r\n  screen.setCursor(0, 90);\r\n  screen.println( &quot;Y: &quot; );\r\n  screen.setCursor(40, 90);\r\n  screen.println( y );\r\n  \/\/ Accelemeter ADXL345 Z\r\n  screen.setCursor(0, 120);\r\n  screen.println( &quot;Z: &quot; );\r\n  screen.setCursor(40, 120);\r\n  screen.println( z );\r\n  \/\/ Compass HMC5883L\r\n  screen.setCursor(0, 150);\r\n  screen.println( &quot;Compass HMC5883L&quot; );\r\n  \/\/ Heading\r\n  screen.setCursor(0, 180);\r\n  screen.println( &quot;Heading = &quot; );\r\n  screen.setCursor(130, 180);\r\n  screen.println( heading );\r\n  \/\/ Degress\r\n  screen.setCursor(0, 210);\r\n  screen.println( &quot;Degress = &quot; );\r\n  screen.setCursor(130, 210);\r\n  screen.println( headingDegrees );\r\n  \r\n}\r\n<\/pre>\n<p><strong>getEEPROM.ino<\/strong><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"arduino\" data-enlighter-title=\"\">\r\n\/\/ EEPROM\r\n\/\/ isUID EEPROM Unique ID\r\nvoid isUID() {\r\n  \r\n  \/\/ Is Unit ID\r\n  uid = &quot;&quot;;\r\n  for (int x = 0; x &lt; 7; x++)\r\n  {\r\n    uid = uid + char(EEPROM.read(x));\r\n  }\r\n  \r\n}\r\n<\/pre>\n<p><strong>getGPS.ino<\/strong><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"arduino\" data-enlighter-title=\"\">\r\n\/\/ GPS Receiver\r\n\/\/ Setup GPS\r\nvoid isSetupGPS() {\r\n\r\n  \/\/ Setup GPS\r\n  tGPS.begin(  9600 , SERIAL_8N1 , gpsRXPIN , gpsTXPIN );\r\n  \r\n}\r\n\/\/ isGPS\r\nvoid isGPS(){\r\n\r\n  \/\/ Receives NEMA data from GPS receiver\r\n  \/\/ This sketch displays information every time a new sentence is correctly encoded\r\n  while ( tGPS.available() &gt; 0)\r\n    \r\n    if (gps.encode( tGPS.read() ))\r\n    {\r\n     \r\n       \/\/ GPS Vector Pointer Target\r\n       displayInfo();\r\n       \/\/ GPS Date, Time, Speed, Altitude\r\n       displayDTS();\r\n       \r\n    }\r\n  \r\n  if (millis() &gt; 5000 &amp;&amp; gps.charsProcessed() &lt; 10)\r\n  {\r\n   \r\n     while(true);\r\n    \r\n  }\r\n\r\n}\r\n\/\/ GPS Vector Pointer Target\r\nvoid displayInfo(){\r\n\r\n  \/\/ Location\r\n  if (gps.location.isValid())\r\n  {\r\n    \r\n     \/\/ Latitude\r\n     TargetLat = gps.location.lat();\r\n     \/\/ Longitude\r\n     TargetLon = gps.location.lng();\r\n     \/\/ GPS Status 2\r\n     GPSSt = &quot;Yes&quot;;\r\n    \r\n  }\r\n  else\r\n  {\r\n\r\n     \/\/ GPS Status 0\r\n     GPSSt = &quot;No&quot;;\r\n    \r\n  }\r\n\r\n}\r\n\/\/ GPS Date, Time, Speed, Altitude\r\nvoid displayDTS(){\r\n\r\n  \/\/ Date\r\n  TargetDat = &quot;&quot;; \r\n  if (gps.date.isValid())\r\n  {\r\n    \r\n     \/\/ Date\r\n     \/\/ Year\r\n     TargetDat += String(gps.date.year(), DEC);\r\n     TargetDat += &quot;\/&quot;;\r\n     \/\/ Month\r\n     TargetDat += String(gps.date.month(), DEC);\r\n     TargetDat += &quot;\/&quot;;\r\n     \/\/ Day\r\n     TargetDat += String(gps.date.day(), DEC);\r\n    \r\n  }\r\n\r\n  \/\/ Time\r\n  TargetTim = &quot;&quot;;\r\n  if (gps.time.isValid())\r\n  {\r\n    \r\n     \/\/ Time\r\n     \/\/ Hour\r\n     TargetTim += String(gps.time.hour(), DEC);\r\n     TargetTim += &quot;:&quot;;\r\n     \/\/ Minute\r\n     TargetTim += String(gps.time.minute(), DEC);\r\n     TargetTim += &quot;:&quot;;\r\n     \/\/ Secound\r\n     TargetTim += String(gps.time.second(), DEC);\r\n    \r\n  }\r\n\r\n  \/\/ Speed\r\n  TargetSMS = &quot;&quot;;\r\n  TargetSKH = &quot;&quot;;\r\n  if (gps.speed.isValid())\r\n  {\r\n    \r\n     \/\/ Speed\r\n     \/\/ M\/S\r\n     int x = gps.speed.mps();\r\n     TargetSMS = String( x, DEC);\r\n     \/\/ Km\/h\r\n     int y = gps.speed.kmph();\r\n     TargetSKH = String( y, DEC);\r\n\r\n  }\r\n\r\n  \/\/ Altitude\r\n  TargetALTM = &quot;&quot;;\r\n  TargetALTF = &quot;&quot;;\r\n  if (gps.altitude.isValid())\r\n  {\r\n    \r\n     \/\/ Altitude\r\n     \/\/ Meters\r\n     int z = gps.altitude.meters();\r\n     TargetALTM = String( z, DEC);\r\n     \/\/ Feet\r\n     int zz = gps.altitude.feet();\r\n     TargetALTF = String( zz, DEC);\r\n\r\n  }\r\n\r\n}\r\n<\/pre>\n<p><strong>getRTC.ino<\/strong><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"arduino\" data-enlighter-title=\"\">\r\n\/\/ RTC (Real-Time Clock)\r\n\/\/ Setup RTC\r\nvoid isSetupRTC(){\r\n\r\n  \/\/ RTC (Real-Time Clock)\r\n  rtc.begin();\r\n  \r\n  \/\/ RTC Lost Power\r\n  if (rtc.lostPower()) {\r\n \r\n    \/\/ When time needs to be set on a new device, or after a power loss, the\r\n    \/\/ following line sets the RTC to the date &amp; time this sketch was compiled\r\n    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));\r\n    \/\/ This line sets the RTC with an explicit date &amp; time, for example to set\r\n    \/\/ January 21, 2014 at 3am you would call:\r\n    \/\/ rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0))\r\n    \r\n  }\r\n  \r\n}\r\n\/\/ RTC (Real-Time Clock)\r\nvoid isRTC(){\r\n\r\n  \/\/ RTC (Real-Time Clock)\r\n  DateTime now = rtc.now();\r\n  \r\n  \/\/ Date\r\n  dateRTC = now.year(), DEC; \r\n  dateRTC = dateRTC + &quot;\/&quot;;\r\n  dateRTC = dateRTC + now.month(), DEC;\r\n  dateRTC = dateRTC + &quot;\/&quot;;\r\n  dateRTC = dateRTC + now.day(), DEC;\r\n  \r\n  \/\/ Time\r\n  timeRTC = now.hour(), DEC;\r\n  timeRTC = timeRTC + &quot;:&quot;;\r\n  timeRTC = timeRTC + now.minute(), DEC;\r\n  timeRTC = timeRTC + &quot;:&quot;;\r\n  timeRTC = timeRTC + now.second(), DEC;\r\n\r\n  \/\/ Temperature\r\n  tempRTC = rtc.getTemperature();\r\n\r\n}\r\n<\/pre>\n<p><strong>getSD.ino<\/strong><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"arduino\" data-enlighter-title=\"\">\r\n\/\/ MicroSD Card\r\n\/\/ MicroSD Setup\r\nvoid isSetupSD() {\r\n\r\n    \/\/ MicroSD Card\r\n    pinMode( chipSelect , OUTPUT );\r\n    if(!SD.begin( chipSelect )){\r\n        ;  \r\n        return;\r\n    }\r\n    \r\n    uint8_t cardType = SD.cardType();\r\n\r\n    \/\/ CARD NONE\r\n    if(cardType == CARD_NONE){\r\n        ; \r\n        return;\r\n    }\r\n\r\n    \/\/ SD Card Type\r\n    if(cardType == CARD_MMC){\r\n        ; \r\n    } else if(cardType == CARD_SD){\r\n        ; \r\n    } else if(cardType == CARD_SDHC){\r\n        ; \r\n    } else {\r\n        ; \r\n    } \r\n\r\n    \/\/ Size\r\n    uint64_t cardSize = SD.cardSize() \/ (1024 * 1024);\r\n \r\n}\r\n\/\/ MicroSD Card\r\nvoid isSD() {\r\n\r\n  zzzzzz = &quot;&quot;;\r\n\r\n  \/\/DLE|EEPROM Unique ID|Version|Date|Time|Temperature|\r\n  \/\/Accelerometer X|Accelerometer Y|Accelerometer Z|\r\n  \/\/Accelerometer X|Accelerometer Y|Accelerometer Z|\r\n  \/\/Compass Heading|Compass Degress|\r\n  \/\/GPS|Latitude|Longitude|GPS Date|GPS Time|\r\n  \/\/GPS Speed M\/S|GPS Speed Km\/h|\r\n  \/\/GPS Altitude Feet|GPS Altitude Meters|*\\r\r\n  zzzzzz = &quot;DLE|&quot; + uid + &quot;|&quot; + sver + &quot;|&quot; + String( dateRTC ) + &quot;|&quot; \r\n  + String( timeRTC ) + &quot;|&quot; + String( tempRTC ) + &quot;|&quot; \r\n  + String(x) + &quot;|&quot; + String(y) + &quot;|&quot; + String(z) + &quot;|&quot; \r\n  + String(ax) + &quot;|&quot; + String(ay) + &quot;|&quot; + String(az) + &quot;|&quot;\r\n  + String( heading ) + &quot;|&quot; + String( headingDegrees ) + &quot;|&quot; \r\n  + String(GPSSt) + &quot;|&quot; + String(TargetLat) + &quot;|&quot; + String(TargetLon) + &quot;|&quot;\r\n  + String(TargetDat) + &quot;|&quot; + String(TargetTim) + &quot;|&quot; \r\n  + String(TargetSMS) + &quot;|&quot; + String(TargetSKH) + &quot;|&quot;\r\n  + String(TargetALTF) + &quot;|&quot; + String(TargetALTM)+ &quot;|*\\r&quot;;\r\n\r\n  \/\/ msg + 1\r\n  char msg[zzzzzz.length() + 1];\r\n\r\n  zzzzzz.toCharArray(msg, zzzzzz.length() + 1);\r\n\r\n  \/\/ Append File\r\n  appendFile(SD, &quot;\/dledata.txt&quot;, msg );\r\n\r\n  \/\/ FullString\r\n  \/\/ ************\r\n  FullString = &quot;************\\r\\n&quot;;\r\n  \/\/ FullString Bluetooth Serial + Serial\r\n  for(int i = 0; i &lt; FullString.length(); i++)\r\n  {\r\n    \r\n    \/\/ Bluetooth Serial\r\n    SerialBT.write(FullString.c_str()[i]);\r\n    \/\/ Serial\r\n    Serial.write(FullString.c_str()[i]);\r\n    \r\n  }\r\n\r\n  \/\/ FullString\r\n  \/\/ zzzzzz\r\n  FullString = zzzzzz;\r\n  \/\/ FullString Bluetooth Serial + Serial\r\n  for(int i = 0; i &lt; FullString.length(); i++)\r\n  {\r\n\r\n    \/\/ Bluetooth Serial\r\n    SerialBT.write(FullString.c_str()[i]);\r\n    \/\/ Serial\r\n    Serial.write(FullString.c_str()[i]);\r\n    \r\n  }\r\n\r\n  \r\n}\r\n\/\/ List Dir\r\nvoid listDir(fs::FS &amp;fs, const char * dirname, uint8_t levels){\r\n    \r\n    \/\/ List Dir\r\n    dirname;\r\n    \r\n    File root = fs.open(dirname);\r\n    \r\n    if(!root){\r\n        return;\r\n    }\r\n    \r\n    if(!root.isDirectory()){\r\n        return;\r\n    }\r\n\r\n    File file = root.openNextFile();\r\n    \r\n    while(file){\r\n        if(file.isDirectory()){\r\n            file.name();\r\n            if(levels){\r\n                listDir(fs, file.name(), levels -1);\r\n            }\r\n        } else {\r\n            file.name();\r\n            file.size();\r\n        }\r\n        file = root.openNextFile();\r\n    }\r\n    \r\n}\r\n\/\/ Write File\r\nvoid writeFile(fs::FS &amp;fs, const char * path, const char * message){\r\n    \r\n    \/\/ Write File\r\n    path;\r\n    \r\n    File file = fs.open(path, FILE_WRITE);\r\n    \r\n    if(!file){\r\n        return;\r\n    }\r\n    \r\n    if(file.print(message)){\r\n        ;  \r\n    } else {\r\n        ;  \r\n    }\r\n    \r\n    file.close();\r\n    \r\n}\r\n\/\/ Append File\r\nvoid appendFile(fs::FS &amp;fs, const char * path, const char * message){\r\n    \r\n    \/\/ Append File\r\n    path;\r\n    \r\n    File file = fs.open(path, FILE_APPEND);\r\n    \r\n    if(!file){\r\n        return;\r\n    }\r\n    \r\n    if(file.print(message)){\r\n        ;  \r\n    } else {\r\n        ;  \r\n    }\r\n    \r\n    file.close();\r\n    \r\n}\r\n<\/pre>\n<p><strong>setup.ino<\/strong><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"arduino\" data-enlighter-title=\"\">\r\n\/\/ Setup\r\nvoid setup()\r\n{\r\n \r\n  \/\/ Serial Begin\r\n  Serial.begin(115200);\r\n  Serial.println(&quot;Starting BLE work!&quot;);\r\n\r\n  \/\/ Bluetooth Serial\r\n  SerialBT.begin(&quot;DL2502Mk05&quot;);\r\n  Serial.println(&quot;Bluetooth Started! Ready to pair...&quot;);\r\n\r\n  \/\/ Delay\r\n  delay( 100 );\r\n\r\n  \/\/ EEPROM Size\r\n  EEPROM.begin(EEPROM_SIZE);\r\n  \r\n  \/\/ EEPROM Unique ID\r\n  isUID();\r\n  \r\n  \/\/ Delay\r\n  delay(100);\r\n\r\n  \/\/ Wire\r\n  Wire.begin();\r\n\r\n  \/\/ Delay\r\n  delay(100);\r\n  \r\n  \/\/ Setup RTC\r\n  isSetupRTC();\r\n  \r\n  \/\/ Delay\r\n  delay(100);\r\n\r\n  \/\/MicroSD Card\r\n  isSetupSD();\r\n\r\n  \/\/ Delay\r\n  delay(100);\r\n  \r\n  \/\/ DFRobot Display 240x320\r\n  screen.begin();\r\n\r\n  \/\/ Delay\r\n  delay(100);\r\n\r\n  \/\/ Setup Accelemeter ADXL345\r\n  isSetupADXL345();\r\n\r\n  \/\/ Setup HMC5883L\r\n  isSetupHMC5883L();\r\n\r\n  \/\/ Delay\r\n  delay( 100 );\r\n\r\n  \/\/ GPS Receiver\r\n  \/\/ Setup GPS\r\n  isSetupGPS();\r\n\r\n  \/\/ Delay\r\n  delay( 100 );\r\n\r\n  \/\/ iLED Red\r\n  pinMode(iLED, OUTPUT);\r\n\r\n  \/\/ LED Red LOW\r\n  digitalWrite(iLED, LOW);\r\n\r\n  \/\/ Delay\r\n  delay( 100 );\r\n\r\n  \/\/ Switch\r\n  pinMode(iSwitch,INPUT);\r\n\r\n  \/\/ Delay\r\n  delay( 100 );\r\n\r\n  \/\/ DFRobot Display 240x320 - UID\r\n  \/\/ Don Luc Electronics\r\n  \/\/ Version\r\n  isDisplayUID();\r\n\r\n  \/\/ Delay 5 Second\r\n  delay( 5000 );\r\n\r\n}\r\n<\/pre>\n<p>&#8212;&#8212;<\/p>\n<p><strong>People can contact us:<\/strong> https:\/\/www.donluc.com\/?page_id=1927<\/p>\n<p><strong>Electronics, IoT, Teacher, Instructor, R&#038;D and Consultant<\/strong><\/p>\n<ul>\n<li>Programming Language<\/li>\n<li>Single-Board Microcontrollers (PIC, Arduino, Raspberry Pi, Arm, Silicon Labs, Espressif, Etc&#8230;)<\/li>\n<li>IoT<\/li>\n<li>Wireless (Radio Frequency, Bluetooth, WiFi, Etc&#8230;)<\/li>\n<li>Robotics<\/li>\n<li>Automation<\/li>\n<li>Camera and Video Capture Receiver Stationary, Wheel\/Tank and Underwater Vehicle<\/li>\n<li>Unmanned Vehicles Terrestrial and Marine<\/li>\n<li>Machine Learning<\/li>\n<li>Artificial Intelligence (AI)<\/li>\n<li>RTOS<\/li>\n<li>Sensors, eHealth Sensors, Biosensor, and Biometric<\/li>\n<li>Research &#038; Development (R &#038; D)<\/li>\n<li>Consulting<\/li>\n<\/ul>\n<p><strong>Follow Us<\/strong><\/p>\n<p><strong>Luc Paquin \u2013 Curriculum Vitae &#8211; 2025<\/strong><br \/>\nhttps:\/\/www.donluc.com\/luc\/<\/p>\n<p><strong>Web:<\/strong> https:\/\/www.donluc.com\/<br \/>\n<strong>Facebook:<\/strong> https:\/\/www.facebook.com\/neosteam.labs.9\/<br \/>\n<strong>YouTube:<\/strong> https:\/\/www.youtube.com\/@thesass2063<br \/>\n<strong>Twitter:<\/strong> https:\/\/twitter.com\/labs_steam<br \/>\n<strong>Pinterest:<\/strong> https:\/\/www.pinterest.com\/NeoSteamLabs\/<br \/>\n<strong>Instagram:<\/strong> https:\/\/www.instagram.com\/neosteamlabs\/<br \/>\n<strong>Patreon:<\/strong> https:\/\/patreon.com\/DonLucElectronics59<br \/>\n<strong>DFRobot:<\/strong> https:\/\/learn.dfrobot.com\/user-10186.html<br \/>\n<strong>Hackster.io:<\/strong> https:\/\/www.hackster.io\/neosteam-labs<br \/>\n<strong>Elecrow:<\/strong> https:\/\/www.elecrow.com\/share\/sharepj\/center\/no\/760816d385ebb1edc0732fd873bfbf13<br \/>\n<strong>TikTok:<\/strong> https:\/\/www.tiktok.com\/@luc.paquin8<br \/>\n<strong>Twitch:<\/strong> https:\/\/www.twitch.tv\/lucpaquin<br \/>\n<strong>LinkedIn:<\/strong> https:\/\/www.linkedin.com\/in\/jlucpaquin\/<\/p>\n<p><strong>Don Luc<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>&#8212;&#8212; #DonLucElectronics #DonLuc #SD #GPS #RTC #EEPROM #Compass #Accelerometer #Movement #ESP32 #Bluetooth #Elecrow #DFRobot #Arduino #Project #Patreon #Electronics #Microcontrollers #IoT #Fritzing #Programming #Consultant &#8212;&#8212; &#8212;&#8212; &#8212;&#8212; &#8212;&#8212; MicroSD Card Module There are different microSD card modules compatible with the ESP32. We\u2019re using the microSD card module it communicates using SPI communication protocol. You can use &#8230; <a title=\"Project #25 &#8211; Movement &#8211; SD &#8211; Mk12\" class=\"read-more\" href=\"https:\/\/www.donluc.com\/?p=4327\" aria-label=\"Read more about Project #25 &#8211; Movement &#8211; SD &#8211; Mk12\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[240,50,49,317,38,368,80,59,115,5,138,287,58,82,10],"tags":[251,6,92,242,102,4,320,87,369,19,83,85,89,246,24,249,9,84,27,333,33,34,108],"class_list":["post-4327","post","type-post","status-publish","format-standard","hentry","category-movement","category-arduino","category-consultant","category-dfrobot","category-digitalelectronics","category-elecrow","category-esp32","category-fritzing","category-e-mentor","category-microcontrollers","category-patreon","category-program","category-arduino-programming","category-program-esp32","category-projects","tag-accelerometer","tag-arduino","tag-battery","tag-bluetooth","tag-components","tag-consultant","tag-dfrobot","tag-display","tag-elecrow","tag-electronics","tag-esp32","tag-fritzing","tag-gps-receiver","tag-magnetometer","tag-microcontroller","tag-movement","tag-programming","tag-programming-esp32","tag-projects-2","tag-sd","tag-technology","tag-video-blog","tag-vlog"],"_links":{"self":[{"href":"https:\/\/www.donluc.com\/index.php?rest_route=\/wp\/v2\/posts\/4327","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.donluc.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.donluc.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.donluc.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.donluc.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=4327"}],"version-history":[{"count":1,"href":"https:\/\/www.donluc.com\/index.php?rest_route=\/wp\/v2\/posts\/4327\/revisions"}],"predecessor-version":[{"id":4332,"href":"https:\/\/www.donluc.com\/index.php?rest_route=\/wp\/v2\/posts\/4327\/revisions\/4332"}],"wp:attachment":[{"href":"https:\/\/www.donluc.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4327"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.donluc.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4327"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.donluc.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4327"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}