tuttelikz

arduino [no accelerometer longing]

May 15th, 2018
116
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 16.98 KB | None | 0 0
  1. // General Library
  2. #include <Arduino.h>
  3. #include "binary.h"
  4. // Math operation
  5. #include <math.h>
  6. // I2C & TWI communication
  7. #include <Wire.h>
  8. #include "I2Cdev.h"
  9. // Serial connection
  10. #include <SoftwareSerial.h>
  11. // LiquidCrystal Display
  12. #include <hd44780.h>
  13. #include <hd44780ioClass/hd44780_I2Cexp.h>
  14. // 7 segment
  15. #include "LedControl.h"
  16. // Library for heart rate & oxymeter
  17. #include "MAX30100_new.h"
  18. // Library for RTC
  19. #include <MyRealTimeClock.h>
  20. // Library for accelerometer
  21. #include "MPU6050_6Axis_MotionApps20.h"
  22.  
  23. // Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation
  24. // is used in I2Cdev.h
  25. #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
  26.     #include "Wire.h"
  27. #endif
  28.  
  29. // Definiting constants
  30. #define aref_voltage 3.3
  31.  
  32. // uncomment "OUTPUT_READABLE_QUATERNION" if you want to see the actual
  33. // quaternion components in a [w, x, y, z] format (not best for parsing
  34. // on a remote host such as Processing or something though)
  35. // #define OUTPUT_READABLE_QUATERNION
  36.  
  37. // uncomment "OUTPUT_READABLE_YAWPITCHROLL" if you want to see the yaw/
  38. // pitch/roll angles (in degrees) calculated from the quaternions coming
  39. // from the FIFO. Note this also requires gravity vector calculations.
  40. // Also note that yaw/pitch/roll angles suffer from gimbal lock (for
  41. // more info, see: http://en.wikipedia.org/wiki/Gimbal_lock)
  42. #define OUTPUT_READABLE_YAWPITCHROLL
  43.  
  44. // uncomment "OUTPUT_TEAPOT" if you want output that matches the
  45. // format used for the InvenSense teapot demo
  46. //#define OUTPUT_TEAPOT
  47.  
  48. // MCU defaults
  49.  
  50. #define INTERRUPT_PIN 2  // use pin 2 on Arduino Uno & most boards
  51. #define LED_PIN 13 // (Arduino is 13, Teensy is 11, Teensy++ is 6)
  52. bool blinkState = false; //Indicate activity state
  53.  
  54. // MPU control/status vars
  55. bool dmpReady = false;  // set true if DMP init was successful
  56. uint8_t mpuIntStatus;   // holds actual interrupt status byte from MPU
  57. uint8_t devStatus;      // return status after each device operation (0 = success, !0 = error)
  58. uint16_t packetSize;    // expected DMP packet size (default is 42 bytes)
  59. uint16_t fifoCount;     // count of all bytes currently in FIFO
  60. uint8_t fifoBuffer[64]; // FIFO storage buffer
  61.  
  62. // orientation/motion vars
  63. Quaternion q;           // [w, x, y, z]         quaternion container
  64. VectorInt16 aa;         // [x, y, z]            accel sensor measurements
  65. VectorInt16 aaReal;     // [x, y, z]            gravity-free accel sensor measurements
  66. VectorInt16 aaWorld;    // [x, y, z]            world-frame accel sensor measurements
  67. VectorFloat gravity;    // [x, y, z]            gravity vector
  68. float euler[3];         // [psi, theta, phi]    Euler angle container
  69. float ypr[3];           // [yaw, pitch, roll]   yaw/pitch/roll container and gravity vector
  70.  
  71. // packet structure for InvenSense teapot demo
  72. uint8_t teapotPacket[14] = { '$', 0x02, 0,0, 0,0, 0,0, 0,0, 0x00, 0x00, '\r', '\n' };
  73.  
  74. // Sensor class objects
  75. MAX30100_new* pulseOxymeter;
  76. SoftwareSerial BTserial(8,9); // RX | TX
  77. hd44780_I2Cexp lcd;
  78. LedControl lc=LedControl(12,11,10,1);
  79. MyRealTimeClock myRTC(5, 6, 7); // Assign Digital Pins
  80. MPU6050 mpu;
  81.  
  82. // Constants
  83. const int LCD_COLS = 16;
  84. const int LCD_ROWS = 2;
  85. const int buttonPin = 3;
  86.  
  87. // Temperature Sensor
  88. int tempSensorPin = A0;
  89.  
  90. // Sound Sensor
  91. int audioVal = 0;
  92. int soundSensorPin = A3;
  93.  
  94. // Pulse Oxymeter
  95. int heartRate = 0;
  96. int oxSat = 0;
  97.  
  98. // Button
  99. int buttonState = 0;
  100.  
  101. // Common variable for temp and stretch
  102. int readIndex = 0;              // the index of the current reading
  103. const int numReadings = 50;     // averaging parameter for stretch and temp
  104.  
  105. // Averaging temperature parameter details
  106. //const int numReadingsTemp = 10;
  107. int readingsTemp[numReadings];      // the readings from the analog input
  108. int averageTemp = 0;                // the average
  109. int totalTemp = 0;                  // the running total
  110.  
  111. // Averaging stretching sensor values
  112. //const int numReadingsStretch = 10;
  113. int readingsStretch[numReadings];      // the readings from the analog input
  114. int averageStretch = 0;                // the average
  115. int totalStretch = 0;                  // the running total
  116.  
  117. // Variables for accelerometer
  118. //float yaw = 0.0;
  119. //float pitch = 0.0;
  120. //float roll = 0.0;
  121. long yaw = 0.0;
  122. long pitch = 0.0;
  123. long roll = 0.0;
  124.  
  125. //Averaging accelerometer data
  126. long yawAvg = 0.0;
  127. long pitchAvg = 0.0;
  128. long rollAvg = 0.0;
  129. long yawTtl = 0.0;
  130. long pitchTtl = 0.0;
  131. long rollTtl = 0.0;
  132. long yprCount = 0;
  133.  
  134. // Timer settings for printing each second
  135. int interval = 1000;
  136. unsigned long previousMillis = 0;
  137. unsigned long currentMillis;
  138.  
  139. int heartBeatNotDetected = 0;
  140.  
  141. // disp heart boundary
  142. byte sf[8]= {B00000000,B00100100,B01011010,B10000001,B10000001,B01000010,B00100100,B00011000};
  143. // disp heart inside
  144. byte nf[8]={B00000000, B00100100,B01111110,B11111111,B11111111,B01111110,B00111100,B00011000};
  145.  
  146. // ================================================================
  147. // ===               INTERRUPT DETECTION ROUTINE                ===
  148. // ================================================================
  149.  
  150. // ================================================================
  151.  
  152. volatile bool mpuInterrupt = false;     // indicates whether MPU interrupt pin has gone high
  153.  
  154. void dmpDataReady() {
  155.     mpuInterrupt = true;
  156. }
  157.  
  158.  
  159. void setup()
  160. {
  161.     // ================================================================
  162.    
  163.       // join I2C bus (I2Cdev library doesn't do this automatically)
  164.     #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
  165.         Wire.begin();
  166.         Wire.setClock(400000); // 400kHz I2C clock. Comment this line if having compilation difficulties
  167.     #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
  168.         Fastwire::setup(400, true);
  169.     #endif
  170.    
  171.    
  172.     // Serial monitor settings
  173.     Wire.begin();
  174.     Serial.begin(115200); // pulse oxymeter
  175.     //Serial.begin(9600); //temperature sensor
  176.     BTserial.begin(9600);
  177.     //BTserial.begin(115200);
  178.     while (!Serial); // wait for Leonardo enumeration, others continue immediately
  179.  
  180.     // initialize device
  181.     Serial.println(F("Initializing I2C devices..."));
  182.     mpu.initialize();
  183.     pinMode(INTERRUPT_PIN, INPUT);
  184.  
  185.     // verify connection
  186.     Serial.println(F("Testing device connections..."));
  187.     Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));
  188.  
  189.     // wait for ready
  190.     Serial.println(F("\nSend any character to begin DMP programming and demo: "));
  191.     /* Read for sensor from bluetooth of mobile
  192.     while (Serial.available() && Serial.read()); // empty buffer
  193.     while (!Serial.available());                 // wait for data
  194.     while (Serial.available() && Serial.read()); // empty buffer again
  195.     */
  196.     while (BTserial.available() && BTserial.read()); // empty buffer
  197.     while (!BTserial.available());                 // wait for data
  198.     while (BTserial.available() && BTserial.read()); // empty buffer again
  199.     //
  200.     // load and configure the DMP
  201.  
  202.     // ================================================================
  203.  
  204.     Serial.println(F("Initializing DMP..."));
  205.     devStatus = mpu.dmpInitialize();
  206.  
  207.     // supply your own gyro offsets here, scaled for min sensitivity
  208.     mpu.setXGyroOffset(220);
  209.     mpu.setYGyroOffset(76);
  210.     mpu.setZGyroOffset(-85);
  211.     mpu.setZAccelOffset(1788); // 1688 factory default for my test chip
  212.  
  213.      // make sure it worked (returns 0 if so)
  214.     if (devStatus == 0) {
  215.         // turn on the DMP, now that it's ready
  216.         Serial.println(F("Enabling DMP..."));
  217.         mpu.setDMPEnabled(true);
  218.  
  219.         // enable Arduino interrupt detection
  220.         Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
  221.         attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), dmpDataReady, RISING);
  222.         mpuIntStatus = mpu.getIntStatus();
  223.  
  224.         // set our DMP Ready flag so the main loop() function knows it's okay to use it
  225.         Serial.println(F("DMP ready! Waiting for first interrupt..."));
  226.         dmpReady = true;
  227.  
  228.         // get expected DMP packet size for later comparison
  229.         packetSize = mpu.dmpGetFIFOPacketSize();
  230.     } else {
  231.         // ERROR!
  232.         // 1 = initial memory load failed
  233.         // 2 = DMP configuration updates failed
  234.         // (if it's going to break, usually the code will be 1)
  235.         Serial.print(F("DMP Initialization failed (code "));
  236.         Serial.print(devStatus);
  237.         Serial.println(F(")"));
  238.     }
  239.  
  240.     // configure LED for output
  241.     pinMode(LED_PIN, OUTPUT);
  242.    
  243.     // Board settings
  244.     analogReference(EXTERNAL);
  245.    
  246.     // Necessary printing
  247.     Serial.println("Pulse oxymeter initialized!");
  248.    
  249.     // Oxymeter settings
  250.     pulseOxymeter = new MAX30100_new();
  251.  
  252.     // Reset clock to a new time while needed
  253.     //myRTC.setDS1302Time(00, 14, 17, 4, 10, 5, 2018);
  254.    
  255.     // LCD settings
  256.     lc.shutdown(0,false);
  257.     lc.setIntensity(0,8);
  258.     lc.clearDisplay(0);  
  259.  
  260.     int status;
  261.  
  262.     status = lcd.begin(LCD_COLS, LCD_ROWS);
  263.     if(status) // non zero status means it was unsuccesful
  264.     {
  265.     status = -status; // convert negative status value to positive number
  266.    
  267.     // begin() failed so blink error code using the onboard LED if possible
  268.     hd44780::fatalError(status); // does not return
  269.     }
  270.  
  271.     Serial.println("LCD initialized!");
  272.     // Temp sensor settings
  273.     for (int thisReading = 0; thisReading < numReadings; thisReading++) {
  274.       readingsTemp[thisReading] = 0;
  275.       readingsStretch[thisReading] = 0;
  276.     }
  277.  
  278.     Serial.println("Temp Sensor initialized!");
  279.     // Button settings
  280.     pinMode(buttonPin, INPUT);
  281.  
  282.     // setSyncProvider( requestSync);  //set function to call when sync required
  283.     //Serial.println("Waiting for sync message");
  284.  
  285.     //setTime(11,58,00,16,4,2018);
  286. }
  287.  
  288. void drawEmptyHeart(){
  289.     lc.setRow(0,0,sf[0]);
  290.     lc.setRow(0,1,sf[1]);
  291.     lc.setRow(0,2,sf[2]);
  292.     lc.setRow(0,3,sf[3]);
  293.     lc.setRow(0,4,sf[4]);
  294.     lc.setRow(0,5,sf[5]);
  295.     lc.setRow(0,6,sf[6]);
  296.     lc.setRow(0,7,sf[7]);
  297. }
  298.  
  299. void drawHeart(){
  300.     // Display no heart
  301.     lc.setRow(0,0,nf[0]);
  302.     lc.setRow(0,1,nf[1]);
  303.     lc.setRow(0,2,nf[2]);
  304.     lc.setRow(0,3,nf[3]);
  305.     lc.setRow(0,4,nf[4]);
  306.     lc.setRow(0,5,nf[5]);
  307.     lc.setRow(0,6,nf[6]);
  308.     lc.setRow(0,7,nf[7]);
  309.     delay(10);
  310. }
  311.  
  312. void printTerminal(uint8_t hourVal,uint8_t minVal, uint8_t secVal, uint8_t hrVal, uint8_t oxSatVal, uint8_t tempVal, uint8_t stretchVal, uint8_t audVal, long yawVal, long pitVal, long rollVal) {
  313.     Serial.print(hourVal); // Element 4
  314.     Serial.print(":");
  315.     Serial.print(minVal); // Element 5
  316.     Serial.print(":");
  317.     Serial.println(secVal);
  318.     Serial.print("HR: ");
  319.     Serial.print(hrVal);
  320.     Serial.print("bpm / O2: ");
  321.     Serial.print(oxSatVal);
  322.     Serial.print("% / T: ");
  323.     Serial.print(tempVal);
  324.     Serial.print(" / Stretch: ");
  325.     Serial.println(stretchVal);
  326.     Serial.print("Audio: ");
  327.     Serial.print(audVal);
  328.     Serial.print(" / Y: ");
  329.     Serial.print(yawVal);
  330.     Serial.print(" / P: ");
  331.     Serial.print(pitVal);
  332.     Serial.print(" / R: ");
  333.     Serial.println(rollVal);
  334. }
  335.  
  336. void printBT(uint8_t hourVal,uint8_t minVal, uint8_t secVal, uint8_t hrVal, uint8_t oxSatVal, uint8_t tempVal, uint8_t stretchVal, uint8_t audVal, long yawVal, long pitVal, long rollVal) {
  337.     BTserial.write(Serial.read());
  338.     BTserial.print("Time: /");
  339.     BTserial.print(hourVal); // Element 4
  340.     BTserial.print(":");
  341.     BTserial.print(minVal); // Element 5
  342.     BTserial.print(":");
  343.     BTserial.print(secVal);
  344.     BTserial.print("/\t");
  345.     BTserial.print("HR: /");
  346.     BTserial.print(hrVal);
  347.     BTserial.print("/\tO2: /");
  348.     BTserial.print(oxSatVal);
  349.     BTserial.print("/% \tT: /");
  350.     BTserial.print(tempVal);
  351.     BTserial.print("/C\t Y:/");
  352.     BTserial.print(yawVal);
  353.     BTserial.print("/\t P:/");
  354.     BTserial.print(pitVal);
  355.     BTserial.print("/\t R:/");
  356.     BTserial.print(rollVal);
  357.     BTserial.print("/\t Aud:/");
  358.     BTserial.print(audVal);
  359.     BTserial.print("/\t Str:/");
  360.     BTserial.print(stretchVal);
  361.     BTserial.println("/");
  362. }
  363.  
  364. void printLCD(uint8_t hourVal, uint8_t minVal, uint8_t tempVal, uint8_t hrVal, uint8_t oxSatVal) {
  365.     lcd.clear();
  366.     lcd.setCursor(0,0);
  367.     lcd.print(hourVal); // Element 4
  368.     lcd.print(":");
  369.     lcd.print(minVal); // Element 5
  370.     lcd.print(" / T: ");
  371.     lcd.print(tempVal);
  372.     lcd.print("C");
  373.     lcd.setCursor(0,1);
  374.     lcd.print("HR: ");
  375.     lcd.print(hrVal);
  376.     lcd.print("b / O2: ");
  377.     lcd.print(oxSatVal);
  378.     lcd.print("%");
  379. }
  380.  
  381. void loop()
  382. {    
  383.       // ================================================================
  384.  
  385.     // if programming failed, don't try to do anything
  386.     if (!dmpReady) return;
  387.  
  388.     // wait for MPU interrupt or extra packet(s) available
  389.     while (!mpuInterrupt && fifoCount < packetSize) {
  390.     }
  391.     //while (!mpuInterrupt);
  392.    
  393.     // Update time
  394.     myRTC.updateTime();
  395.  
  396.     // Default behavior
  397.     drawEmptyHeart();
  398.  
  399.     // Button logic
  400.     buttonState = digitalRead(buttonPin);
  401.  
  402.     // Sound sensor logic
  403.     audioVal = analogRead(soundSensorPin);
  404.  
  405.     // Temp sensor reading
  406.     int readingTemp = analogRead(tempSensorPin);
  407.  
  408.      //Reading Stretch Sensor
  409.     int readingStretch = analogRead(A1);
  410.     float tempVoltage = readingTemp * aref_voltage;
  411. //    voltage /= 1024.0;
  412. //    float temperatureC = (voltage - 0.5) * 100 ;
  413.  
  414.     // Averaging Temperature Results
  415.     totalTemp = totalTemp - readingsTemp[readIndex];
  416.     totalStretch = totalStretch - readingsStretch[readIndex];
  417.    
  418.     readingsTemp[readIndex] = tempVoltage;
  419.     readingsStretch[readIndex] = readingStretch;
  420.    
  421.     totalTemp = totalTemp + readingsTemp[readIndex];
  422.     totalStretch = totalStretch + readingsStretch[readIndex];
  423.    
  424.     readIndex = readIndex + 1;
  425.  
  426.     if (readIndex >= numReadings) {
  427.       readIndex = 0;
  428.     }
  429.    
  430.     averageTemp = totalTemp / numReadings;
  431.     averageStretch = totalStretch / numReadings;
  432.  
  433.     // ================================================================
  434.  
  435.     // MCU Accelerometer
  436.     // reset interrupt flag and get INT_STATUS byte
  437.     mpuInterrupt = false;
  438.     mpuIntStatus = mpu.getIntStatus();
  439.  
  440.     // get current FIFO count
  441.     fifoCount = mpu.getFIFOCount();
  442.  
  443.     // check for overflow (this should never happen unless our code is too inefficient)
  444.     // ================================================================
  445.     mpu.resetFIFO();
  446.     if ((mpuIntStatus & 0x10) || fifoCount == 1024) {
  447.         // reset so we can continue cleanly
  448.         mpu.resetFIFO();
  449.         Serial.println(F("FIFO overflow!"));
  450.         // otherwise, check for DMP data ready interrupt (this should happen frequently)
  451.     } else if (mpuIntStatus & 0x02) {
  452.       // wait for correct available data length, should be a VERY short wait
  453.       while (fifoCount < packetSize) {
  454.         fifoCount = mpu.getFIFOCount();
  455.       }
  456.  
  457.       // read a packet from FIFO
  458.       mpu.getFIFOBytes(fifoBuffer, packetSize);
  459.       // ================================================================
  460.       //mpu.resetFIFO();
  461.      
  462.       // track FIFO count here in case there is > 1 packet available
  463.       // (this lets us immediately read more without waiting for an interrupt)
  464.       fifoCount -= packetSize;
  465.      
  466.       mpu.dmpGetQuaternion(&q, fifoBuffer);
  467.       mpu.dmpGetGravity(&gravity, &q);
  468.       mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
  469.       yaw = ypr[0] * 180/M_PI;
  470.       pitch = ypr[1] * 180/M_PI;
  471.       roll = ypr[2] * 180/M_PI;
  472.      
  473.       // blink LED to indicate activity
  474.       blinkState = !blinkState;
  475.       digitalWrite(LED_PIN, blinkState);
  476.       //delay(50);
  477.       mpu.resetFIFO();
  478.      
  479.     }
  480.    
  481.     // Pulse oxymeter logic
  482.     pulseoxymeter_t result = pulseOxymeter->update();
  483.  
  484.     if(result.pulseDetected == true) {
  485.         drawHeart();
  486.        
  487.         // Receving Sensor Values
  488.         heartRate = result.heartBPM;
  489.     } else {
  490.         heartBeatNotDetected = heartBeatNotDetected + 1;
  491.        
  492.         if (heartBeatNotDetected >= 500) {
  493.           heartRate = 0;
  494.           oxSat = 0;
  495.           heartBeatNotDetected = 0;
  496.         }
  497.     }
  498.  
  499.     // Averaging Yaw, Pitch, Roll
  500.     yawTtl = yawTtl + yaw;
  501.     pitchTtl = pitchTtl + pitch;
  502.     rollTtl = rollTtl + roll;
  503.     yprCount = yprCount + 1;
  504.    
  505.     currentMillis = millis();
  506.    
  507.     if((unsigned long)(currentMillis - previousMillis) >= interval) {
  508.       yawAvg = yawTtl / yprCount;
  509.       pitchAvg = pitchTtl / yprCount;
  510.       rollAvg = rollTtl / yprCount;
  511.      
  512.      
  513.       printTerminal(myRTC.hours, myRTC.minutes, myRTC.seconds, heartRate, oxSat, averageTemp, averageStretch, audioVal, yawAvg, pitchAvg, rollAvg);
  514.       printBT(myRTC.hours, myRTC.minutes, myRTC.seconds, heartRate, oxSat, averageTemp, averageStretch, audioVal, yawAvg, pitchAvg, rollAvg);
  515.       printLCD(myRTC.hours, myRTC.minutes,averageTemp, heartRate, oxSat);
  516.  
  517.       previousMillis = currentMillis;
  518.  
  519.       yprCount = 0;
  520.       yawTtl = 0;
  521.       pitchTtl = 0;
  522.       rollTtl = 0;
  523.       yawAvg = 0;
  524.       pitchAvg = 0;
  525.       rollAvg = 0;
  526.     }
  527. }
Advertisement
Add Comment
Please, Sign In to add comment