Guest User

Untitled

a guest
Mar 16th, 2016
70
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2.  *  eHealth sensor platform for Arduino and Raspberry from Cooking-hacks.
  3.  *
  4.  *  Description: "The e-Health Sensor Shield allows Arduino and Raspberry Pi
  5.  *  users to perform biometric and medical applications by using 9 different
  6.  *  sensors: Pulse and Oxygen in Blood Sensor (SPO2), Airflow Sensor (Breathing),
  7.  *  Body Temperature, Electrocardiogram Sensor (ECG), Glucometer, Galvanic Skin
  8.  *  Response Sensor (GSR - Sweating), Blood Pressure (Sphygmomanometer) and
  9.  *  Patient Position (Accelerometer)."
  10.  *
  11.  *  Copyright (C) 2012 Libelium Comunicaciones Distribuidas S.L.
  12.  *  http://www.libelium.com
  13.  *
  14.  *  This program is free software: you can redistribute it and/or modify
  15.  *  it under the terms of the GNU General Public License as published by
  16.  *  the Free Software Foundation, either version 3 of the License, or
  17.  *  (at your option) any later version.
  18.  *
  19.  *  This program is distributed in the hope that it will be useful,
  20.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  21.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  22.  *  GNU General Public License for more details.
  23.  *
  24.  *  You should have received a copy of the GNU General Public License
  25.  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
  26.  *
  27.  *  Version 2.0
  28.  *  Author: Luis Martín & Ahmad Saad
  29.  */
  30.  
  31.  
  32. // include this library's description file
  33. #include "eHealth.h"
  34.  
  35.  
  36. //***************************************************************
  37. // Accelerometer Variables and definitions                      *
  38. //***************************************************************
  39.  
  40.    
  41.     //! Breakout board defaults to 1, set to 0 if SA0 jumper is set
  42.     #define SA0 1  
  43.         #if SA0
  44.             #define MMA8452_ADDRESS 0x1D  //! SA0 is high, 0x1C if low
  45.         #else
  46.             #define MMA8452_ADDRESS 0x1C  
  47.         #endif
  48.  
  49.     #define int1Pin 2
  50.     #define int2Pin 3
  51.  
  52.     //! Set the scale below either 2, 4 or 8.
  53.     const byte scale = 2;
  54.  
  55.     //! Set the output data rate below. Value should be between 0 and 7.
  56.     //! 0=800Hz, 1=400, 2=200, 3=100, 4=50, 5=12.5, 6=6.25, 7=1.56
  57.     const byte dataRate = 0;
  58.  
  59.  
  60. //***************************************************************
  61. // Constructor of the class                                     *
  62. //***************************************************************
  63.  
  64.     //! Function that handles the creation and setup of instances
  65.     eHealthClass::eHealthClass(void) { /*void constructor*/ }
  66.    
  67.  
  68. //***************************************************************
  69. // Public Methods                                               *
  70. //***************************************************************
  71.  
  72.     //!******************************************************************************
  73.     //! Name:   initPositionSensor()                                                *
  74.     //! Description: Initializes the position sensor and configure some values.     *
  75.     //! Param : void                                                                *
  76.     //! Returns: void                                                               *
  77.     //! Example: eHealth.initPositionSensor();                                      *
  78.     //!******************************************************************************
  79.  
  80.     void eHealthClass::initPositionSensor(void)
  81.     {
  82.         Wire.begin();
  83.         byte c;
  84.  
  85.         /* Set up the interrupt pins, they're set as active high, push-pull */
  86.         pinMode(int1Pin, INPUT);
  87.         digitalWrite(int1Pin, LOW);
  88.         pinMode(int2Pin, INPUT);
  89.         digitalWrite(int2Pin, LOW);
  90.  
  91.         /* Read the WHO_AM_I register, this is a good test of communication */
  92.         c = readRegister(0x0D);  // Read WHO_AM_I register
  93.         if (c == 0x2A)  { // WHO_AM_I should always be 0x2A
  94.             initMMA8452(scale, dataRate);  // init the accelerometer if communication is good
  95.             Serial.println("MMA8452Q is online...");
  96.         } else {
  97.             Serial.print("Could not connect to MMA8452Q: 0x");
  98.             Serial.println(c, HEX);
  99.             //while (1);  // Loop forever if communication doesn't happen
  100.         }
  101.     }
  102.  
  103.  
  104.  
  105.     //!******************************************************************************
  106.     //! Name:   readBloodPressureSensor()                                           *
  107.     //! Description: Initializes the BloodPressureSensor sensor.                    *
  108.     //! Param : void                                                                *
  109.     //! Returns: void                                                               *
  110.     //! Example: eHealth.initBloodPressureSensor();                                 *
  111.     //!******************************************************************************
  112.  
  113.     void eHealthClass::readBloodPressureSensor(void)
  114.     {  
  115.         unsigned char _data;
  116.         int ia=0;
  117.         length=0;
  118.  
  119.         Serial1.begin(19200);
  120.         Serial1.write(0xAA);
  121.         delayMicroseconds(1);
  122.         Serial1.write(0x55);
  123.         delayMicroseconds(1);
  124.         Serial1.write(0x88);
  125.         delay(2500);
  126.  
  127.         Serial1.print("\n");
  128.  
  129.         if (Serial1.available() > 0) { // The protocol sends the measures
  130.  
  131.             for (int i = 0; i<4; i++){ // Read four dummy data 
  132.                 Serial1.read();
  133.             }
  134.            
  135.             while(_data != 0xD1){
  136.                 if (ia==0){
  137.                 _data = Serial1.read();
  138.                 }
  139.  
  140.             bloodPressureDataVector[length].year = swap(_data);
  141.             bloodPressureDataVector[length].month = swap(Serial1.read());
  142.             bloodPressureDataVector[length].day = swap(Serial1.read());
  143.             bloodPressureDataVector[length].hour = swap(Serial1.read());
  144.             bloodPressureDataVector[length].minutes = swap(Serial1.read());
  145.             bloodPressureDataVector[length].systolic = swap(Serial1.read());
  146.             bloodPressureDataVector[length].diastolic = swap(Serial1.read());
  147.             bloodPressureDataVector[length].pulse = swap(Serial1.read());
  148.             length++;
  149.             ia=1;
  150.             for (int i = 0; i<4; i++){ // CheckSum 1
  151.                 Serial1.read();
  152.             }
  153.            
  154.             _data = Serial1.read();
  155.             }
  156.  
  157.  
  158.             for (int i = 0; i<3; i++){ // CheckSum 2
  159.                 Serial1.read();
  160.             }  
  161.            
  162.         }
  163.     }
  164.  
  165.  
  166.    
  167.     //!******************************************************************************
  168.     //!     Name:   getTemperature()                                                *
  169.     //!     Description: Returns the corporal temperature.                          *
  170.     //!     Param : void                                                            *
  171.     //!     Returns: float with the corporal temperature value.                     *
  172.     //!     Example: float temperature = eHealth.getTemperature();                  *
  173.     //!******************************************************************************
  174.  
  175.     float eHealthClass::getTemperature(void)
  176.     {  
  177.         //Local variables
  178.         float Temperature; //Corporal Temperature
  179.         float Resistance;  //Resistance of sensor.
  180.         float ganancia=5.0;
  181.         float Vcc=3.3;
  182.         float RefTension=3.0; // Voltage Reference of Wheatstone bridge.
  183.         float Ra=4700.0; //Wheatstone bridge resistance.
  184.         float Rc=4700.0; //Wheatstone bridge resistance.
  185.         float Rb=821.0; //Wheatstone bridge resistance.
  186.         int sensorValue = analogRead(A3);
  187.        
  188.         float voltage2=((float)sensorValue*Vcc)/1023; // binary to voltage conversion  
  189.  
  190.         // Wheatstone bridge output voltage.
  191.         voltage2=voltage2/ganancia;
  192.         // Resistance sensor calculate  
  193.         float aux=(voltage2/RefTension)+Rb/(Rb+Ra);
  194.         Resistance=Rc*aux/(1-aux);    
  195.         if (Resistance >=1822.8) {
  196.             // if temperature between 25ºC and 29.9ºC. R(tª)=6638.20457*(0.95768)^t
  197.             Temperature=log(Resistance/6638.20457)/log(0.95768);  
  198.         } else {
  199.             if (Resistance >=1477.1){
  200.                     // if temperature between 30ºC and 34.9ºC. R(tª)=6403.49306*(0.95883)^t
  201.                     Temperature=log(Resistance/6403.49306)/log(0.95883);  
  202.             } else {
  203.                 if (Resistance >=1204.8){
  204.                     // if temperature between 35ºC and 39.9ºC. R(tª)=6118.01620*(0.96008)^t
  205.                     Temperature=log(Resistance/6118.01620)/log(0.96008);
  206.                 }
  207.                 else{
  208.                     if (Resistance >=988.1){
  209.                         // if temperature between 40ºC and 44.9ºC. R(tª)=5859.06368*(0.96112)^t
  210.                         Temperature=log(Resistance/5859.06368)/log(0.96112);
  211.                     }
  212.                     else {
  213.                         if (Resistance >=811.7){
  214.                             // if temperature between 45ºC and 50ºC. R(tª)=5575.94572*(0.96218)^t
  215.                             Temperature=log(Resistance/5575.94572)/log(0.96218);
  216.                         }
  217.                     }
  218.                 }
  219.             }  
  220.         }
  221.        
  222.         return Temperature;
  223.     }
  224.  
  225.  
  226.  
  227.     //!******************************************************************************
  228.     //!     Name:   getSkinConductance()                                            *
  229.     //!     Description: Returns the value of skin conductance.                     *
  230.     //!     Param : void                                                            *
  231.     //!     Returns: float with the value of skin conductance                       *
  232.     //!     Example: float conductance = eHealth.getSkinConductance();              *
  233.     //!******************************************************************************
  234.  
  235.     float eHealthClass::getSkinConductance(void)
  236.     {
  237.         // Local variable declaration.  
  238.         float resistance;
  239.         float conductance;
  240.         delay(1);
  241.        
  242.         // Read an analogic value from analogic2 pin.
  243.         float sensorValue = analogRead(A2);
  244.         float voltage = sensorValue*5.0/1023;
  245.  
  246.         conductance = 2*((voltage - 0.5) / 100000);
  247.  
  248.         // Conductance calculation
  249.         resistance = 1 / conductance;
  250.         conductance = conductance * 1000000;
  251.         delay(1);
  252.        
  253.         if (conductance > 1.0)  return conductance;
  254.         else return -1.0;
  255.     }
  256.  
  257.  
  258.     //!******************************************************************************
  259.     //!     Name:   getSkinResistance()                                             *
  260.     //!     Description: Returns the value of skin resistance.                      *
  261.     //!     Param : void                                                            *
  262.     //!     Returns: float with the value of skin resistance                        *
  263.     //!     Example: float resistance = eHealth.getSkinResistance();                *
  264.     //!******************************************************************************
  265.  
  266.     float eHealthClass::getSkinResistance(void)
  267.     {  
  268.         // Local variable declaration.  
  269.         float resistance;
  270.         float conductance;
  271.    
  272.         // Read an analogic value from analogic2 pin.
  273.         float sensorValue = analogRead(A2);
  274.         float voltage = (sensorValue * 5.0) / 1023;
  275.    
  276.         delay(2);
  277.         conductance = 2*((voltage - 0.5) / 100000);
  278.    
  279.         //Conductance calcultacion
  280.         resistance = 1 / conductance;
  281.         delay(2);
  282.    
  283.         if (resistance > 1.0 ) return resistance;
  284.         else return -1.0;
  285.     }
  286.  
  287.    
  288.     //!******************************************************************************
  289.     //!     Name:   getSkinConductanceVoltage()                                     *
  290.     //!     Description: Returns the skin conductance value in voltage .            *
  291.     //!     Param : void                                                            *
  292.     //!     Returns: float with the skin conductance value in voltage               *
  293.     //!     Example: float volt = eHealth.getSkinConductanceVoltage();              *
  294.     //!******************************************************************************
  295.  
  296.     float eHealthClass::getSkinConductanceVoltage(void)
  297.     {
  298.         delay(2);
  299.    
  300.         //Read analogic value from analogic2 pin.
  301.         int sensorValue = analogRead(A2);
  302.    
  303.         //Convert the readed value to voltage.
  304.         float voltage = ( sensorValue * 5.0 ) / 1023;
  305.  
  306.         delay(2);
  307.         return voltage;
  308.     }
  309.  
  310.  
  311.     //!******************************************************************************
  312.     //!     Name:   getECG()                                                        *
  313.     //!     Description: Returns an analogic value to represent the ECG.            *
  314.     //!     Param : void                                                            *
  315.     //!     Returns: float with the ECG value in voltage                            *
  316.     //!     Example: float volt = eHealth.getECG();                                 *
  317.     //!******************************************************************************
  318.  
  319.     float eHealthClass::getECG(void)
  320.     {
  321.         float analog0;
  322.         // Read from analogic in.
  323.         analog0=analogRead(0);
  324.         // binary to voltage conversion
  325.         return analog0 = (float)analog0 * 5 / 1023.0;  
  326.     }
  327.    
  328.  
  329.     //!******************************************************************************
  330.     //!     Name:   getEMG()                                                        *
  331.     //!     Description: Returns an analogic value to represent the EMG.            *
  332.     //!     Param : void                                                            *
  333.     //!     Returns: float with the EMG value in voltage                            *
  334.     //!     Example: float volt = eHealth.getEMG();                                 *
  335.     //!******************************************************************************
  336.  
  337.     int eHealthClass::getEMG(void)
  338.     {
  339.         int analog0;
  340.         // Read from analogic in.
  341.         analog0=analogRead(0);
  342.         // binary to voltage conversion
  343.         return analog0;  
  344.     }
  345.    
  346.  
  347.     //!******************************************************************************
  348.     //!     Name:   getBodyPosition()                                               *
  349.     //!     Description: Returns the current body position.                         *
  350.     //!     Param : void                                                            *
  351.     //!     Returns: uint8_t with the the position of the pacient.                  *
  352.     //!     Example: uint8_t position = eHealth.getBodyPosition();                  *
  353.     //!******************************************************************************
  354.  
  355.     uint8_t eHealthClass::getBodyPosition(void)
  356.     {
  357.         static byte source;
  358.  
  359.         /* If int1 goes high, all data registers have new data */
  360.         if (digitalRead(int1Pin)) {// Interrupt pin, should probably attach to interrupt function  
  361.             readRegisters(0x01, 6, &data[0]);  // Read the six data registers into data array.
  362.            
  363.             /* For loop to calculate 12-bit ADC and g value for each axis */
  364.             for (int i=0; i<6; i+=2) {
  365.                 accelCount[i/2] = ((data[i] << 8) | data[i+1]) >> 4;  // Turn the MSB and LSB into a 12-bit value
  366.                
  367.                     if (data[i] > 0x7F) {
  368.                         accelCount[i/2] = ~accelCount[i/2] + 1;
  369.                         accelCount[i/2] *= -1;  // Transform into negative 2's complement #
  370.                     }
  371.                    
  372.                 accel[i/2] = (float) accelCount[i/2]/((1<<12)/(2*scale));  // get actual g value, this depends on scale being set
  373.             }      
  374.         }
  375.        
  376.         /* If int2 goes high, either p/l has changed or there's been a single/double tap */
  377.         if (digitalRead(int2Pin)) {
  378.             source = readRegister(0x0C);  // Read the interrupt source reg.
  379.            
  380.             if ((source & 0x10)==0x10)  // If the p/l bit is set, go check those registers
  381.                 portraitLandscapeHandler();      
  382.  
  383.             delay(50); // Delay here for a little printing visibility, make it longer, or delete it
  384.         }
  385.  
  386.         delay(100);
  387.  
  388.         return bodyPos;
  389.     }
  390.  
  391.  
  392.     //!******************************************************************************
  393.     //!     Name:   getSystolicPressure()                                           *
  394.     //!     Description: Returns the  value of the systolic pressure.               *
  395.     //!     Param : void                                                            *
  396.     //!     Returns: int with the systolic pressure.                                *
  397.     //!     Example: int systolic = eHealth.getSystolicPressure();                  *
  398.     //!******************************************************************************
  399.  
  400.     int eHealthClass::getSystolicPressure(int i)
  401.     {
  402.         return bloodPressureDataVector[i].systolic;
  403.     }
  404.  
  405.  
  406.     //!******************************************************************************
  407.     //!     Name:   getDiastolicPressure()                                          *
  408.     //!     Description: Returns the  value of the diastolic pressure.              *
  409.     //!     Param : void                                                            *
  410.     //!     Returns: int with the diastolic pressure.                               *
  411.     //!     Example: int diastolic = eHealth.getDiastolicPressure();                *
  412.     //!******************************************************************************
  413.  
  414.     int eHealthClass::getDiastolicPressure(int i)
  415.     {
  416.         return bloodPressureDataVector[i].diastolic;
  417.     }
  418.  
  419.  
  420.     //!******************************************************************************
  421.     //!     Name:   getAirFlow()                                                    *
  422.     //!     Description: Returns an analogic value to represent the air flow.       *
  423.     //!     Param : void                                                            *
  424.     //!     Returns: int with the airFlow value (0-1023).                           *
  425.     //!     Example: int airFlow = eHealth.getAirFlow();                            *
  426.     //!******************************************************************************
  427.  
  428.     int eHealthClass::getAirFlow(void)
  429.     {
  430.         int airFlow = analogRead(A1);
  431.  
  432.        
  433.         return airFlow;
  434.     }
  435.  
  436.  
  437.     //!******************************************************************************
  438.     //!     Name:   printPosition()                                                 *
  439.     //!     Description: Returns an analogic value to represent the air flow.       *
  440.     //!     Param : uint8_t position : the current body position.                   *
  441.     //!     Returns: void                                                           *
  442.     //!     Example: eHealth.printPosition(position);                               *
  443.     //!******************************************************************************
  444.  
  445.     void eHealthClass::printPosition( uint8_t position )
  446.     {
  447.         if (position == 1) {
  448.             Serial.println("Supine position");    
  449.         } else if (position == 2) {
  450.             Serial.println("Left lateral decubitus");
  451.         } else if (position == 3) {
  452.             Serial.println("Rigth lateral decubitus");
  453.         } else if (position == 4) {
  454.             Serial.println("Prone position");
  455.         } else if (position == 5) {
  456.             Serial.println("Stand or sit position");
  457.         } else  {
  458.             Serial.println("non-defined position");
  459.         }
  460.     }
  461.  
  462.  
  463.  
  464.  
  465.     //!******************************************************************************
  466.     //!     Name: airflowWave()                                                     *
  467.     //!     Description: It prints air flow wave form in the serial monitor         *
  468.     //!     Param : int air with the analogic value                                 *
  469.     //!     Returns: void                                                           *
  470.     //!     Example: eHealth.airflowWave();                                         *
  471.     //!******************************************************************************
  472.  
  473.     void eHealthClass::airFlowWave(int air)
  474.     {
  475.         for (int i=0; i < (air / 5) ; i ++) {  
  476.                 Serial.print("..");  
  477.         }
  478.  
  479.         Serial.print("..");
  480.         Serial.print("\n");
  481.         delay(25);
  482.     }
  483.  
  484.  
  485.     //!******************************************************************************
  486.     //!     Name: readGlucometer()                                                  *
  487.     //!     Description: It reads the data stored in the glucometer                 *
  488.     //!     Param : void                                                            *
  489.     //!     Returns: void                                                           *
  490.     //!     Example: eHealth.readGlucometer();                                      *
  491.     //!******************************************************************************
  492.    
  493.     void eHealthClass::readGlucometer(void)
  494.     {
  495.         delay(100);
  496.         Serial1.begin(1200);
  497.         delay(100);
  498.         // Configuring digital pins like INPUTS
  499.         pinMode(5, OUTPUT);
  500.         digitalWrite(5, HIGH); 
  501.         delay(100);
  502.  
  503.         Serial1.write(0x55); // Start communication command.
  504.         delay(1000); // Wait while receiving data.
  505.  
  506.         Serial1.print("\n");
  507.         if (Serial1.available() > 0) {
  508.             length = Serial1.read();// The protocol sends the number of measures
  509.             Serial1.read(); // Read one dummy data
  510.  
  511.             for (int i = 0; i<length; i++) { // The protocol sends data in this order
  512.                 glucoseDataVector[i].year = Serial1.read();
  513.                 glucoseDataVector[i].month = Serial1.read();
  514.                 glucoseDataVector[i].day = Serial1.read();
  515.                 glucoseDataVector[i].hour = Serial1.read();
  516.                 glucoseDataVector[i].minutes = Serial1.read();
  517.  
  518.                 Serial1.read(); // Byte of separation must be 0x00.
  519.  
  520.                 glucoseDataVector[i].glucose = Serial1.read();
  521.                 glucoseDataVector[i].meridian = Serial1.read();
  522.  
  523.                 Serial1.read(); // CheckSum 1
  524.                 Serial1.read(); // CheckSum 2          
  525.             }
  526.         }
  527.         digitalWrite(5, LOW);  
  528.     }
  529.  
  530.     //!******************************************************************************
  531.     //!     Name: getGlucometerLength()                                             *
  532.     //!     Description: it returns the number of data stored in the glucometer     *
  533.     //!     Param : void                                                            *
  534.     //!     Returns: uint8_t with length                                            *
  535.     //!     Example: int length = eHealth.getGlucometerLength();                    *
  536.     //!******************************************************************************
  537.  
  538.     uint8_t eHealthClass::getGlucometerLength(void)
  539.     {
  540.         return length;
  541.     }
  542.  
  543.     //!******************************************************************************
  544.     //!     Name: getBloodPressureLength()                                          *
  545.     //!     Description: it returns the number of data stored in                    *
  546.     //!     the blood pressure sensor                                               *
  547.     //!     Param : void                                                            *
  548.     //!     Returns: uint8_t with length                                            *
  549.     //!     Example: int length = eHealth.getBloodPressureLength();                 *
  550.     //!******************************************************************************
  551.  
  552.     uint8_t eHealthClass::getBloodPressureLength(void)
  553.     {
  554.         return length;
  555.     }
  556.  
  557.  
  558.     //!******************************************************************************
  559.     //!     Name: numberToMonth()                                                   *
  560.     //!     Description: Convert month variable from numeric to character.          *
  561.     //!     Param : int month in numerical format                                   *
  562.     //!     Returns: String with the month characters (January, February...).       *
  563.     //!     Example: Serial.print(eHealth.numberToMonth(month));                    *
  564.     //!******************************************************************************
  565.    
  566.     String eHealthClass::numberToMonth(int month)
  567.     {
  568.         if (month == 1)  return "January";
  569.         else if (month == 2)  return "February";
  570.         else if (month == 3)  return "March";
  571.         else if (month == 4)  return "April";
  572.         else if (month == 5)  return "May";
  573.         else if (month == 6)  return "June";
  574.         else if (month == 7)  return "July";
  575.         else if (month == 8)  return "August";
  576.         else if (month == 9)  return "September";
  577.         else if (month == 10) return "October";
  578.         else if (month == 11) return "November";
  579.         else return "December";
  580.     }
  581.  
  582.    
  583.     //!******************************************************************************
  584.     //!     Name:   version()                                                       *
  585.     //!     Description: It check the version of the library                        *
  586.     //!     Param : void                                                            *
  587.     //!     Returns: void                                                           *
  588.     //!     Example: eHealth.version();                                             *
  589.     //!******************************************************************************
  590.  
  591.     int eHealthClass::version(void)
  592.     {
  593.         return 2.0;
  594.     }
  595.  
  596.  
  597. //***************************************************************
  598. // Private Methods                                              *
  599. //***************************************************************
  600.  
  601.     //! This function will read the p/l source register and
  602.     //! print what direction the sensor is now facing */
  603.    
  604.     void eHealthClass::portraitLandscapeHandler()
  605.     {
  606.         byte pl = readRegister(0x10);  // Reads the PL_STATUS register
  607.        
  608.         switch((pl&0x06)>>1)  // Check on the LAPO[1:0] bits
  609.         {
  610.             case 0:
  611.                 position[0] = 0;
  612.             break;
  613.            
  614.             case 1:
  615.                 position[0] = 1;
  616.             break;
  617.            
  618.             case 2:
  619.                 position[0] = 2;
  620.             break;
  621.            
  622.             case 3:
  623.                 position[0] = 3;
  624.             break;
  625.         }
  626.        
  627.         if (pl&0x01)  // Check the BAFRO bit
  628.             position[1] = 0;
  629.         else
  630.             position[1] = 1;
  631.         if (pl&0x40)  // Check the LO bit
  632.             position[2] = 0;
  633.         else
  634.             position[2] = 1;
  635.  
  636.         bodyPosition();  
  637.     }
  638.  
  639. /*******************************************************************************************************/
  640.  
  641.     //! Initialize the MMA8452 registers.
  642.  
  643.     //void eHealthClass::initMMA8452(byte fsr, byte dataRate)
  644.     void eHealthClass::initMMA8452(char fsr, char dataRate)
  645.     {
  646.         MMA8452Standby();  // Must be in standby to change registers
  647.  
  648.         /* Set up the full scale range to 2, 4, or 8g. */
  649.         if ((fsr==2)||(fsr==4)||(fsr==8))
  650.             writeRegister(0x0E, fsr >> 2);  
  651.         else
  652.             writeRegister(0x0E, 0);
  653.            
  654.         /* Setup the 3 data rate bits, from 0 to 7 */
  655.         writeRegister(0x2A, readRegister(0x2A) & ~(0x38));
  656.        
  657.         if (dataRate <= 7)
  658.             writeRegister(0x2A, readRegister(0x2A) | (dataRate << 3));
  659.            
  660.         /* Set up portrait/landscap registers */
  661.         writeRegister(0x11, 0x40);  // Enable P/L
  662.         writeRegister(0x13, 0x14);  // 29deg z-lock,
  663.         writeRegister(0x14, 0x84);  // 45deg thresh, 14deg hyst
  664.         writeRegister(0x12, 0x05);  // debounce counter at 100ms
  665.        
  666.         /* Set up single and double tap */
  667.         writeRegister(0x21, 0x7F);  // enable single/double taps on all axes
  668.         writeRegister(0x23, 0x20);  // x thresh at 2g
  669.         writeRegister(0x24, 0x20);  // y thresh at 2g
  670.         writeRegister(0x25, 0x8);  // z thresh at .5g
  671.         writeRegister(0x26, 0x30);  // 60ms time limit, the min/max here is very dependent on output data rate
  672.         writeRegister(0x27, 0x28);  // 200ms between taps min
  673.         writeRegister(0x28, 0xFF);  // 1.275s (max value) between taps max
  674.        
  675.         /* Set up interrupt 1 and 2 */
  676.         writeRegister(0x2C, 0x02);  // Active high, push-pull
  677.         writeRegister(0x2D, 0x19);  // DRDY int enabled, P/L enabled
  678.         writeRegister(0x2E, 0x01);  // DRDY on INT1, P/L on INT2
  679.        
  680.         MMA8452Active();  // Set to active to start reading
  681.     }
  682.  
  683. /*******************************************************************************************************/
  684.  
  685.     //! Sets the MMA8452 to standby mode. It must be in standby to change most register settings.
  686.    
  687.     void eHealthClass::MMA8452Standby()
  688.     {
  689.         byte c = readRegister(0x2A);
  690.         writeRegister(0x2A, c & ~(0x01));
  691.     }
  692.  
  693. /*******************************************************************************************************/
  694.  
  695.     //! Sets the MMA8452 to active mode. Needs to be in this mode to output data
  696.    
  697.     void eHealthClass::MMA8452Active()
  698.     {
  699.         byte c = readRegister(0x2A);
  700.         writeRegister(0x2A, c | 0x01);
  701.     }
  702.  
  703. /*******************************************************************************************************/  
  704.  
  705.     //! Read i registers sequentially, starting at address into the dest byte array.
  706.     void eHealthClass::readRegisters(byte address, int i, byte * dest)
  707.     {
  708.         Wire.beginTransmission(MMA8452_ADDRESS); // Open communications with device
  709.  
  710.         Wire.write(address);    // write register address
  711.         Wire.endTransmission(false); // don't send a stop
  712.  
  713.         Wire.requestFrom(MMA8452_ADDRESS, i);
  714.  
  715.         int j = 0;
  716.         while(Wire.available())    // slave may send less than requested
  717.         {
  718.          dest[j] = Wire.read();    // receive a byte as character
  719.          j++;
  720.         }
  721.         Wire.endTransmission();    // stop transmitting
  722.     }
  723.  
  724. /*******************************************************************************************************/
  725.  
  726.     //! Read a single byte from address and return it as a byte.
  727.    
  728.     byte eHealthClass::readRegister(uint8_t address)
  729.     {
  730.         byte data;
  731.  
  732. // From MMA8452Q Datasheet, Table 10. I2C Device Address Sequence
  733. // Command [6:1]Device Address  [0]SA0 [6:0]Device Address  R/W   8-bit Final Value
  734. // Read    001110               0       0x1C                1     0x39
  735. // Write   001110               0       0x1C                0     0x38
  736. // Read    001110               1       0x1D                1     0x3B
  737. // Write   001110               1       0x1D                0     0x3A
  738.  
  739.  
  740.   Wire.beginTransmission(MMA8452_ADDRESS); // Open communications with device
  741.  
  742.   Wire.write(address);  // write register address
  743.   Wire.endTransmission(false); // don't send a stop
  744.  
  745.   Wire.requestFrom(MMA8452_ADDRESS, 1);
  746.  
  747.   data = Wire.read();   // Get MSB result
  748.   Wire.endTransmission();    // stop transmitting
  749.    
  750.   return data;
  751.     }
  752.  
  753. /*******************************************************************************************************/
  754.  
  755.     //! Writes a single byte (data) into address
  756.     void eHealthClass::writeRegister(unsigned char address, unsigned char data)
  757.     {
  758.         Wire.beginTransmission(MMA8452_ADDRESS);  // Open communications with device
  759.         Wire.write(address);        // write register address
  760.         Wire.write(data);  
  761.         Wire.endTransmission();    // stop transmitting
  762.     }
  763.  
  764. /*******************************************************************************************************/
  765.  
  766.     //! Assigns a value depending on body position.
  767.  
  768.     void eHealthClass::bodyPosition( void )
  769.     {  
  770.         if (( position[0] == 0 ) && (position[1] == 1) && (position [2] == 0)) {
  771.             bodyPos = 1;
  772.         } else if (( position[0] == 1 ) && (position[1] == 1) && (position [2] == 0)) {
  773.             bodyPos = 1;
  774.         } else if (( position[0] == 3 ) && (position[1] == 1) && (position [2] == 0)) {
  775.             bodyPos = 1;
  776.         } else if (( position[0] == 2 ) && (position[1] == 0) && (position [2] == 0)) {
  777.             bodyPos = 1;
  778.         } else if (( position[0] == 2 ) && (position[1] == 1) && (position [2] == 1)) {
  779.             bodyPos = 1;
  780.         } else if (( position[0] == 2 ) && (position[1] == 1) && (position [2] == 0)) {
  781.             bodyPos = 1;
  782.            
  783.         } else if (( position[0] == 0 ) && (position[1] == 1) && (position [2] == 1)) {
  784.             bodyPos = 2;
  785.         } else if (( position[0] == 0 ) && (position[1] == 0) && (position [2] == 1)) {
  786.             bodyPos = 2;
  787.            
  788.         } else if (( position[0] == 1 ) && (position[1] == 1) && (position [2] == 1)) {
  789.             bodyPos = 3;
  790.         } else if (( position[0] == 1 ) && (position[1] == 0) && (position [2] == 1)) {
  791.             bodyPos = 3;
  792.          
  793.         } else if (( position[0] == 1 ) && (position[1] == 0) && (position [2] == 0)) {
  794.             bodyPos = 4;
  795.         } else if (( position[0] == 3 ) && (position[1] == 0) && (position [2] == 0)) {
  796.             bodyPos = 4;
  797.            
  798.         } else if (( position[0] == 3 ) && (position[1] == 0) && (position [2] == 1)) {
  799.             bodyPos = 5;
  800.         } else if (( position[0] == 3 ) && (position[1] == 1) && (position [2] == 1)) {
  801.             bodyPos = 5;
  802.         } else if (( position[0] == 2 ) && (position[1] == 0) && (position [2] == 1)) {
  803.             bodyPos = 5;
  804.         } else  {
  805.             bodyPos = 6;
  806.         }
  807.     }
  808.  
  809. /*******************************************************************************************************/
  810.  
  811.  
  812.     //! Swap data for blood pressure mesure
  813.    
  814.     char eHealthClass::swap(char _data)
  815.     {
  816.         char highBits = (_data & 0xF0) / 16;
  817.         char lowBits =  (_data & 0x0F) * 16;
  818.         return ~(highBits + lowBits);
  819.     }
  820.  
  821. /*******************************************************************************************************/
  822.  
  823. //***************************************************************
  824. // Preinstantiate Objects                                       *
  825. //***************************************************************
  826.  
  827.     eHealthClass eHealth = eHealthClass();
RAW Paste Data