I am working on a project that uses an Arduino to take in readings from a pulse sensor and temperature sensor for one minute. First, the Pi would send the Arduino an instruction ("s\n") to tell the Arduino to start the pulse sensor reading. As the pulse sensor data is coming in, the Pi stores it in an array. When there is no more incoming pulse sensor readings coming from the Arduino (i.e. one minute is over), the Pi sends the Arduino another instruction ("f\n") to tell the Arduino that the data collection and blinks the LED.
Right now I am just testing the pulse sensor part of it but it doesn't seem like the Pi even has any serial data to read. When I try to run the code on the Pi it gives an error after about 25s saying there is a zero division error in the avgbpm function i.e. datalist is empty. When I debug it, the code skips the body of the if statement in the while loop and just goes to pulse = avgbpm(pulsedata). Meaning that ser.in_waiting is not available. So I've written the getdata function incorrectly, but I don't see why. Here is my Arduino and Pi code, I appreciate all the help.
Arduino:
#define USE_ARDUINO_INTERRUPTS true
#include <PulseSensorPlayground.h>
const int led = 13; // led pin
const int pulsePin = A0; // pulse pin
unsigned long start;
unsigned long period;
const int threshold = 550; // use get started project to find this val
int pulse;
String process;
PulseSensorPlayground pulseSensor;
void setup()
{
Serial.begin(9600);
pulseSensor.analogInput(pulsePin);
pulseSensor.setThreshold(threshold);
pulseSensor.setSerial(Serial); // output serial pulse data
}
void loop()
{
if (Serial.available()) // if there is instruction coming from the Pi
{
process = Serial.readStringUntil('\n'); // read the instruction
process.trim();
if (process.equals("r")) // recording starts, led on
{
digitalWrite(led, HIGH);
}
else if (process.equals("e")) // recording ends, led off
{
digitalWrite(led, LOW);
}
else if (process.equals("f")) // blink led when finish data collection
{
blinkfinish();
}
else if (process.equals("s")) // start data collection
{
start = millis(); // measure temp and bpm for one minute
getdata();
}
}
}
void getdata() // function to get pulse sensor data
{
while (millis() <= start + 60000) // will stop collecting data after one minute
{
pulse = pulseSensor.getBeatsPerMinute(); // bpm
if (pulseSensor.sawStartOfBeat()) // check if a reading is detected
{
Serial.println(pulse); // if it is detected, output bpm
}
delay(20);
}
}
void blinkfinish()
{
digitalWrite(led, HIGH);
delay(1000);
digitalWrite(led, LOW);
delay(1000);
digitalWrite(led, HIGH);
delay(1000);
digitalWrite(led, LOW);
}
Pi:
import serial
def avgbpm(datalist): # average bpm int
return float(sum(datalist)/len(datalist))
ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=1) # open serial port
pulsedata = []
ser.write(b"s\n") # tell arduino to start data collection
while True:
if ser.in_waiting > 0:
data = ser.readline().decode('utf-8').rstrip()
pulsedata.append(int(data))
else:
ser.write(b"f\n") # tell arduino data collection is done
break
pulse = avgbpm(pulsedata)