WorldFamousElectronics / PulseSensorPlayground

A PulseSensor library (for Arduino) that collects our most popular projects in one place.
https://PulseSensor.com
MIT License
201 stars 97 forks source link

Delay and High BPM #137

Closed AnyaSengupta closed 1 year ago

AnyaSengupta commented 3 years ago

Hello, I am still getting this issue although I purchased a brand new pulse sensor (my third pulse sensor purchased).

I am using the playground pulse sensor in my program along with ESP8266-01 and GY-521. I am getting a delay of around five seconds between. There is also really high values and a huge increase in between. Here is the output, I am receiving.

proof

Thank you so much.

biomurph commented 3 years ago

@AnyaSengupta It looks like your serial output is smooshed. Are you obscuring personal data? I will need to see your code to help you out. Do you have a repo or can you post it here?

AnyaSengupta commented 3 years ago

Yes, here is my code. GITTESTpostsensor.zip Thank you so much.

biomurph commented 3 years ago

@AnyaSengupta

First thing that you need to do is change the define USE_ARDUINO_INTERRUPTS true and make it false. interrupts are not supported for ESP yet. You will need to work from the BPM_Alternative sketch and build from there.

You have a 1 second delay in your loop and a 2 second delay in your postToCloud. That will definitely cause the Pulse Sensor data to be incorrect. Combining ESP and Pulse Sensor is not trivial. ESP code can be cumbersome and some of the functions to send and receive wifi can be time consuming.

How much data do you need to send? Can you do something like watch the Pulse Sensor for a while to get some data, and then do the accelerometer and wifi stuff and then watch the Pulse Sensor again? If you do that, you will need to watch the Pulse Sensor for a few seconds (5+) before getting good BPM data. What do you need the accelerometer data for? Does it need to be coming in all the time?

I'm posting the important bits of your code below for the sake of making it a little easier.

#define USE_ARDUINO_INTERRUPTS true    // creates the most acurate BPM math

#include <SoftwareSerial.h>
#include <stdlib.h>
#include <PulseSensorPlayground.h>     // Imports the PulseSensorPlayground Library. 
#include <Wire.h>

#define DEBUG true
SoftwareSerial esp8266(2,3); 
#define SSID ""     // Enter Your WiFi Name Here 
#define PASS ""       // Enter Your WiFi Password Here
#define IP ""// thingspeak.com ip

String msg = "GET /#/#/#.php"; //Enter your API key

String WIFI_SSID = "";       // Your WiFi ssid
String PASSWORD = "";         // Password
String DEVICE_SECRET_KEY  = "";

//Variables
int error;

PulseSensorPlayground pulseSensor;  // Creates an instance of the PulseSensorPlayground object called "pulseSensor"

int16_t accelerometer_x=0;
int16_t accelerometer_y=0;
int16_t accelerometer_z=0;

const int MPU_ADDR = 0x68;

void setup()  {
  Serial.begin(9600); //or use default 115200.
  esp8266.begin(9600);
  Serial.println("AT");
  esp8266.println("AT");
  delay(3000);
  if(esp8266.find("OK"))  {
    connectWiFi();
  }
  sensorSetup(); 
}

void loop() {
  start: //label 
  error=0;
  getSensorData();
  //Resend if transmission is not completed 
  if (error==1) {
    goto start; 
  }

  delay(1000); 
}

void getSensorData() {
  Wire.beginTransmission(MPU_ADDR);
  Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H) [MPU-6000 and MPU-6050 Register Map and Descriptions Revision 4.2, p.40]
  Wire.endTransmission(false); // the parameter indicates that the Arduino will restart or if the connection is still established

  Wire.requestFrom(MPU_ADDR, 7*2, true); // request 14 registers
  /*
  old_x= accelerometer_x;
  old_y= accelerometer_y;
  old_z= accelerometer_z;
  */
  // "Wire.read()<<8 | Wire.read();" means two registers are read and stored in the same variable
  accelerometer_x = Wire.read()<<8 | Wire.read(); // stores the X data found by the accelerometer
  accelerometer_y = Wire.read()<<8 | Wire.read(); // stores the y data found by the accelerometer
  accelerometer_z = Wire.read()<<8 | Wire.read(); // stores the z data found by the accelerometer

  int myBPM = pulseSensor.getBeatsPerMinute();
  if (pulseSensor.sawStartOfBeat()) {            // Constantly test to see if "a beat happened".
    Serial.println("♥  A HeartBeat Happened ! "); // If test is "true", print a message "a heartbeat happened".
    Serial.print("BPM: ");                        // Print phrase "BPM: "
    Serial.println(myBPM);                      // Print the value inside of myBPM.
    postToCloud( accelerometer_x,  accelerometer_y, accelerometer_z,  myBPM);
  }
}
void postToCloud(int16_t accelerometer_x,int16_t accelerometer_y,int16_t accelerometer_z, int myBPM) {
  String cmd = "AT+CIPSTART=\"TCP\",\"";
  cmd += IP;
  cmd += "\",80";
  Serial.println(cmd);
  esp8266.println(cmd);
  delay(2000);
  if(esp8266.find("Error")) {
    return;
  }
  cmd = msg ;

  cmd += "?myBPM=";   
  cmd += myBPM;
  cmd += "&accelerometer_x=";   
  cmd += accelerometer_x;
  cmd += "&accelerometer_y=";   
  cmd += accelerometer_y;
  cmd += "&accelerometer_z=";   
  cmd += accelerometer_z;

  Serial.println(cmd);
  cmd += "\r\n";
  Serial.print("AT+CIPSEND=");
  esp8266.print("AT+CIPSEND=");
  Serial.println(cmd.length());
  esp8266.println(cmd.length());
  if(esp8266.find(">")) {
    Serial.print(cmd);
    esp8266.print(cmd);
  }
  else{
   Serial.println("AT+CIPCLOSE");
   esp8266.println("AT+CIPCLOSE");
    //Resend...
    error=1;
  }
}

boolean connectWiFi() {
  Serial.println("AT+CWMODE=1");
  esp8266.println("AT+CWMODE=1");
  delay(2000);
  String cmd="AT+CWJAP=\"";
  cmd+=SSID;
  cmd+="\",\"";
  cmd+=PASS;
  cmd+="\"";
  Serial.println(cmd);
  esp8266.println(cmd);
  delay(5000);
  if(esp8266.find("OK"))  {
    Serial.println("OK");
    return true;    
  }else {
    return false;
  }
}

void sensorSetup() {     
  const int PulseWire = 0;       // PulseSensor PURPLE WIRE connected to ANALOG PIN 0
  int Threshold = 550;           // Determines which Signal to "count as a beat" and the ones to avoid

  Wire.begin();
  Wire.beginTransmission(MPU_ADDR); // Begins a transmission to the GY-521 board
  Wire.write(0x6B); 
  Wire.write(0); // set to zero (wakes up the MPU-6050)pulse
  Wire.endTransmission(true);

  pulseSensor.analogInput(PulseWire);
  pulseSensor.setThreshold(Threshold);
     if (pulseSensor.begin()) {
    Serial.println("We created a pulseSensor Object !");  //This prints one time at Arduino power-up,  or on Arduino reset.  
  }

}