Dependencies:   mbed LSM9DS1 FastPWM

Revision:
0:33061e64e773
Child:
1:72bcbf11c621
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Tue Mar 05 13:55:16 2019 +0000
@@ -0,0 +1,409 @@
+#include "mbed.h"
+#include "LSM9DS1.h"
+#include "FastPWM.h"
+#include <math.h>
+// setting of MIX DEVICE 
+#define DA_PS_BT false //Digital Accelerometer + Pulse Sensor + Bluetooth
+#define AA_PS_BT false// Analog Accelerometer + Pulse Sensor + Bluetooth
+#define DA_PS_Op true//Digital Accelerometer + Pulse Sensor + Optical
+#define AA_PS_Op false// Analog Accelerometer + Pulse Sensor + Optical
+
+#define PS_MODE false // On/Off Pulse Sensor
+#define PS_PIN A3 //Pulse Sensor pin
+
+#define ACC_X_PIN A6
+#define ACC_Y_PIN A5 //Analog Accelerometer pins
+#define ACC_Z_PIN A4
+
+#define X0 1.69  //calibrated counts of analog Accelerometer
+#define Y0 1.67
+#define Z0 1.68
+#define Sx 0.65
+#define Sy 0.65
+#define Sz 0.65
+
+#define BT_TX_PIN PA_9 // Bluetooth pins
+#define BT_RX_PIN PA_10
+
+#define OPT_TX_PIN A7 // optical pins, pwm, baudrate
+#define OPT_RX_PIN A2 
+#define BAUD_RATE 19200
+#define PWM_PIN D10
+#define PWM_MODE 455
+
+#if (DA_PS_Op || DA_PS_BT) 
+    LSM9DS1 acc(D4, D5);
+    //acc.setAcceleroRange(LSM9DS1_ACCELERO_RANGE_2G);  
+#endif
+
+#if (AA_PS_BT || DA_PS_BT) // uart's init
+    Serial pc(SERIAL_TX, SERIAL_RX); // tx, rx
+    Serial BT(BT_TX_PIN, BT_RX_PIN); // tx, rx  
+    float acc_x,acc_y,acc_z;
+#endif
+
+#if (AA_PS_Op || DA_PS_Op)
+    Serial Serial2(OPT_TX_PIN,OPT_RX_PIN,BAUD_RATE);
+    int16_t acc_x,acc_y,acc_z;
+#endif
+
+#if (AA_PS_BT || AA_PS_Op)
+    AnalogIn X(ACC_X_PIN);
+    AnalogIn Y(ACC_Y_PIN);
+    AnalogIn Z(ACC_Z_PIN);
+#endif
+
+#if (PS_MODE)
+    AnalogIn P(ACC_X_PIN);
+#endif
+
+DigitalOut myled(LED1, 1);
+
+PwmOut buzz(A1);
+
+float ARes = 2.0 / 32768.0; // Digital ACC have datatype int16_t 
+
+int Signal = 0;
+int total = 0;
+
+int average = 0;
+int IsoLine = 0;
+int Tpulse = 0;
+int Tpulse2 = 0;
+uint16_t count2=0;
+uint16_t count3=0;
+int AccData[3];
+unsigned int  trame1,trame2,trame3,trame4,trame5,trame6,trame7,trame8, trame9,tramePULSE;
+int cptmesure;
+Timer t;
+Timer T1;
+Timer T2;
+
+//variables globals
+
+float delta;
+
+double Last, Now;
+bool START = false;
+int coun;
+
+float tableau_x[10], tableau_y[10], tableau_z[10], t_delta[10];
+
+int numReadings = 70;
+int Index = 0;
+int readings[70];
+int IndexBPM = 5;
+int IndexB = 0;
+int readingsBPM[5];
+int k;
+int totalBPM;
+int averageBPM;
+int verif;
+int patient;
+
+void setup()
+{
+    #if (AA_PS_Op || DA_PS_Op)
+        FastPWM mypwm(PWM_PIN,1); //Initializing of clock Output
+        //Clock settings for 38kHz
+        if (PWM_MODE == 38)
+        {
+            mypwm.period_us(26.3158);
+            mypwm.pulsewidth_us(13.1579);//Duty-Cycle 50% here
+        } 
+        //Clock settings for 455kHz
+        if (PWM_MODE == 455)
+        {
+            mypwm.period_us(2.1978);
+            mypwm.pulsewidth_us(1.0989);//Duty-Cycle 50% here
+        }
+    #endif
+    
+    #if (AA_PS_BT || DA_PS_BT)
+        BT.baud(115200);
+        pc.baud(115200); // Start serial at 115200 bps
+    #endif
+      
+    #if (DA_PS_BT || DA_PS_Op)
+         acc.setAcceleroRange(LSM9DS1_ACCELERO_RANGE_2G);
+    #endif
+    buzz.period_us(2272.7f);
+    buzz.write(0.0f);
+}
+#if (PS_MODE)
+    int readMean(int samples)
+    {
+        int sum = 0;
+        for (int i = 0; i < samples; i++)
+        {
+            sum = sum + (4096 * P);
+        }
+        return sum/samples;
+    }
+
+
+void pulse()
+{
+    Signal =  readMean(10);
+    total = total - readings[Index];
+    readings[Index] = Signal;  // ...которое было считано от сенсора:
+    total = total + readings[Index]; // добавляем его к общей сумме:
+    Index = Index + 1;        // продвигаемся к следующему значению в массиве:             
+    if (Index >= numReadings)
+        Index = 0;    // ...возвращаемся к началу:
+    int Maxn = 0;  //обнуляем максимальное значение предидущих выборок массив
+    for (int i = 0; i < numReadings; i++) // поиск макимальеого значения в масиве из "numReadings" выборок 
+    {
+        if (readings[i]>Maxn)
+            Maxn =  readings[i];
+    }                      
+    average = total/numReadings;
+    IsoLine =  average +  ((Maxn - average)*0.7);
+        
+    //Serial2.printf("%u %u %u\n", Signal, IsoLine ,average); 
+    if ((Signal > IsoLine) && (k > 0))
+    {
+        T1.stop();
+        Tpulse = Tpulse2 + T1.read_us();
+        int Tpulse22 = (long)(60L*1000L*1000L)/Tpulse;
+        totalBPM = totalBPM - readingsBPM[IndexB];
+        readingsBPM[IndexB] = Tpulse;  // ...которое было считано от сенсора:
+        totalBPM = totalBPM + readingsBPM[IndexB]; // добавляем его к общей сумме:
+        IndexB = IndexB + 1;       // продвигаемся к следующему значению в массиве:             
+        averageBPM = 60000000L/((long)totalBPM/IndexBPM);
+        if(IndexB >= 5)IndexB = 0;  // если мы в конце массива возвращаемся к началу:
+        //Serial2.printf("BPM: %d averageBPM: %d\n", Tpulse22, averageBPM);
+        T1.reset();
+        T1.start();
+        k--;
+    }
+    else
+    {
+        if (k < 1) 
+        {
+            T1.stop();
+            Tpulse2 = T1.read_us();
+            T1.reset();
+            T1.start();
+            k++;
+        }
+    }
+}
+#endif
+void matrice_euler()
+{
+    tableau_x[coun-1]=acc_x;
+    tableau_y[coun-1]=acc_y;
+    tableau_z[coun-1]=acc_z;
+    t_delta[coun-1]=delta;
+}
+
+void read_capteur()
+{
+    #if (DA_PS_BT) //Digital acc init
+        acc_x = -acc.getAcceleroRawY()*ARes;
+        acc_y =  acc.getAcceleroRawX()*ARes;
+        acc_z =  acc.getAcceleroRawZ()*ARes;
+    #elif (AA_PS_BT)                            // !!axis directions are correct!!
+        acc_x = (Y*3.3-Y0)/Sy;
+        acc_y = -(X*3.3-X0)/Sx;
+        acc_z = -(Z*3.3-Z0)/Sz;
+    #elif (AA_PS_Op)
+        acc_x = Y*4096;
+        acc_y = -X*4096;
+        acc_z = -Z*4096;
+    #elif (DA_PS_Op)
+        //acc.getAcceleroRaw(AccData);
+        acc_x = -acc.getAcceleroRawY();
+        acc_y =  acc.getAcceleroRawX();
+        acc_z =  acc.getAcceleroRawZ();
+    #endif
+    
+    #if (PS_MODE)
+        pulse();
+    #endif
+}
+
+void loop ()
+{
+    read_capteur();
+    matrice_euler();
+    
+    #if (AA_PS_BT || DA_PS_BT)
+        if (coun>=10 && count3>=20)
+        {
+            char s1[50]; //size of the number
+            char s2[50]; 
+            char s3[50]; 
+            char s4[50];
+            char s5[50];
+    
+            myled=!myled;
+            coun=0;
+            for(int i=0; i<10; i++)
+            {
+                sprintf(s1, "%g", tableau_x[i]);
+                sprintf(s2, "%g", tableau_y[i]);
+                sprintf(s4, "%g", tableau_z[i]);
+                sprintf(s3, "%g", t_delta[i]);
+                #if (PS_MODE)
+                    sprintf(s5, "%g", averageBPM);
+                    BT.printf("%s;%s;%s;%s;%s|", s1,s2,s4,s3,s5);
+                #else
+                    BT.printf("%s;%s;%s;%s|", s1,s2,s4,s3);
+                #endif
+            }
+        }
+    #else //(DA_PS_Op || AA_PS_Op)
+            //increment of measurement: avoids the redundancy of the display on the server
+            cptmesure++;
+            if(cptmesure == 8)
+                cptmesure = 0;
+                
+            trame2 = (acc_x & 0xFF00) >> 8;         // mask 1111 1111 0000 0000 (ACC 16 bit) int16_t
+            trame3 = (acc_x & 0xFF);                // mask 0000 0000 1111 1111 
+            trame4 = (acc_y & 0xFF00) >> 8;
+            trame5 = (acc_y & 0xFF);
+            trame6 = (acc_z & 0xFF00) >> 8;
+            trame7 = (acc_z & 0xFF);
+            
+            verif =  (trame2 << 3) + cptmesure ; 
+            
+            //first frame: patient + verif (2 bits high)
+            trame1 = (patient << 4) + ((verif & 0x700) >> 7);//mask 111 0000 0000
+            
+            trame8 = (verif & 0xFF);//mask 1111 1111
+            
+            //fifth frame: patient + increment measurement
+            trame9 = (patient << 4) + (cptmesure << 1);
+            
+/*            IMPORTANT TO UNDERSTAND (ONLY FOR NUCLEO)
+            We fill the table which gonna be sent
+            TrameTab[0] = 255;  
+            TrameTab[1] = trame1;
+                
+            TrameTab[2] = trame2;   
+            TrameTab[3] = trame3;
+                
+            TrameTab[4] = trame8;
+            TrameTab[5] = trame9;
+            
+            //We sent the table through the serial port
+            //Serial2.write(TrameTab,6,0,0);
+            //Serial.write to send the information under 8 bits. Serial.print sends a number digit by digit to use to have a display on the monitor.
+            //BUT if we will use write() then sketch will stuck after 166 seconds. putc() working same as write().
+*/
+            Serial2.putc(255);
+            Serial2.putc(trame1);
+            Serial2.putc(trame2);
+            Serial2.putc(trame3);
+            Serial2.putc(trame4);
+            Serial2.putc(trame5);
+            Serial2.putc(trame6);
+            Serial2.putc(trame7);
+            #if (PS_MODE)
+                Serial2.putc((uint8_t)averageBPM);
+            #endif
+            Serial2.putc(trame8);
+            Serial2.putc(trame9);
+            #if (!PS_MODE)
+                switch(BAUD_RATE)
+                {
+                    case 4800 :
+                        //wait_us(20000);
+                        wait_us(41666.66);
+                        wait_us(3200);                    
+                        break;
+                    case 9600 :
+                        wait_us(20833.33);
+                        wait_us(1100);
+                        break;
+                    case 19200 :
+                        wait_us(10416.66);
+                        wait_us(200);
+                        break;
+                    case 38400 :
+                        wait_us(4836.6);//data transfer compensation -351.7us for 38400 baud and 5208.3us delay
+                                         //for using the same resistor that we use for optical ECG we should save the equation T_delay = 2*T_transmission 
+                        break;
+                    default :
+                        wait_ms(50);
+                 }
+             #endif
+             #if (PS_MODE)
+                 switch(BAUD_RATE)
+                 {
+                    case 4800 :
+                        //wait_us(20000);
+                        wait_us(41666.66 + 4166.66);
+                        wait_us(3200 + 320);                    
+                        break;
+                    case 9600 :
+                        wait_us(20833.33 + 2083.33);
+                        wait_us(1100 + 110);
+                        break;
+                    case 19200 :
+                        wait_us(10416.66 + 1041.66);
+                        wait_us(200 + 20);
+                        break;
+                    case 38400 :
+                        wait_us(4836.6 + 520.83);//data transfer compensation -351.7us for 38400 baud and 5208.3us delay
+                                         //for using the same resistor that we use for optical ECG we should save the equation T_delay = 2*T_transmission 
+                        break;
+                    default :
+                        wait_ms(50);
+                  }
+             #endif
+    #endif
+}
+
+int main()
+{
+    
+    setup();
+    t.start();
+    Last = t.read_us();
+    coun=0;
+    count3=0;
+
+    while (true)
+    {
+        #if (AA_PS_BT || DA_PS_BT) //bluetooth mode
+            Now = t.read_us();
+            delta = (float)(Now-Last)/1000000.0f;
+            if (delta>=0.1f && START==true)
+            {
+                Last=Now;
+                coun+=1;
+                if (count3<=81)
+                {
+                    count3+=1;
+                }
+                
+                loop(); //Get sensor values
+            }
+            if (BT.readable())
+            {
+                char c = BT.getc();
+                if(c == '1'){
+                    //BT.printf("\nOK\n");
+                    START=true;
+                    count3=0;
+                }
+                if(c == '0')
+                {
+                    //BT.printf("\nOK\n");
+                    START=false;
+                    myled=1;
+                    buzz.write(0.50f);
+                    wait(3);
+                    buzz.write(0.0f);
+                }
+            }
+        #else
+            //optical
+            loop();
+        #endif
+    } 
+}
+