我是编程新手,但我真的很想尝试这个项目。所以,我正在使用已编写的代码。我有一个全新的Arduino Uno和一个脉冲传感器。引脚13 LED不会停止闪烁,但我最终调整了代码,只输出低电压。最终,我得到了Arduino草图,我认为它应该是。但是 - 每当我进行处理时,心率都是疯狂的,没有我甚至触摸它(当我触摸它时,它什么都不做)并且在草图的底部说明了一个错误,禁用了针对usb调制解调器的serialEvent我我试图使用。
This program functions as a data visualizer for the Pulse Sensor
Serial input is designed to mate with arduino sketch "A_PulseSensor_xx"
This code made by Joel Murphy and Yury Gitman in Brooklyn, Summer 2011.
interactive features in this version:
press 'S' or 's' to take a picture of the data window. (.tif image)
import processing.serial.*; // this is how we talk to arduino
PFont font, rateFont, smallFont; // create font instances
Serial port; // create and name the serial port
int heart = 0; // used to time pulsing of heart graphic with your heart beat
int pulseRate = 0; // used to hold pulse rate value sent from arduino (beats per minute)
int Sensor = 0; // used to hold raw sensor data from arduino
int HRV; // time between this current beat and the last beat in mS (used for Heart Rate Variability)
int Ypos; // used to print the new Pulse Sensor data point
int[] pulseY; // used to hold pulse waveform Y positions
int[] rateY; // used to hold bpm waveform Y positions
// these variables will hold pulse window specs
int PulseWindowMin;
int PulseWindowMax;
int PulseWindowW;
int PulseWindowH;
int PulseWindowY;
int PulseWindowX;
int PulseDisplayBaseline = 712; // these variables are used to adjust the pulse window display
int PulseOffset = 712; // the max and min will auto adjust if the waveform drifts beyond the screen
color eggshell = color(255,253,248); // offwhite color for data display windows
color R = color(250,0,0); // red color for datapoints and heart graphic
int grey = 80; // grey color for numeric data windows
boolean beat = false; // used to advance heart rate graph
boolean newRate = false; // used to update heart rate display
void setup() {
size(800,600); // Stage size
frameRate(100); // refresh rate
font = loadFont("Arial-BoldMT-36.vlw"); // font for small text
rateFont = loadFont("Arial-BoldMT-80.vlw"); // font for larger text
smallFont = loadFont("Arial-BoldMT-14.vlw"); // font for smaller text
textFont(font); // set up to print small font
textAlign(RIGHT); // referemce points
rectMode(CENTER);
// define the size of the pulse window
PulseWindowW = 710; // width of pulse window
PulseWindowH = 400; // height of pulse window
PulseWindowX = width/2+30; // center X coordinate of pulse window
PulseWindowY = height-225; // center Y coordinate of pulse window
PulseWindowMin = PulseWindowY - PulseWindowH/2; // top Y position of pulse window
PulseWindowMax = PulseWindowY + PulseWindowH/2; // bottom Y position of pulse window
pulseY = new int[PulseWindowW+1]; // array to hold Y coordinate of pulse datapoints
rateY = new int[320]; // array to hold y coordinate of heart rate datapoints
// find and establish contact with the serial port
println(Serial.list()); // print a list of available serial ports
port = new Serial(this, Serial.list()[3], 115200); // choose the right one in square brackets
port.bufferUntil('\n'); // arduino will end each ascii string with a '\n' at the end (carriage return)
port.clear(); // flush the serial buffer
// set arbitrary initial data position at top of pulse window
Ypos = PulseWindowMin;
for (int i = 0; i < pulseY.length; i++){
pulseY[i] = PulseWindowMin;
}
// set the BPM visualizer line to 0
for (int i=0; i<rateY.length; i++){
rateY[i] = 162; // 162 is the pixel height for 0 heart rate
}
}
void draw(){
printScreen(); // DRAW THE MAJOR SCREEN COMPONENTS AND TEXT
// THESE ARE THE PULSE SENSOR WAVEFORM DRAWING ROUTINES
// fisrt, move the Y coordintae of previous pulse data points over one pixel to the left
for (int i = 0; i < pulseY.length-1; i++){
pulseY[i] = pulseY[i+1];
}
// new data enters on the right of the screen. sensor value is placed in the last array position
pulseY[pulseY.length-1] = Ypos; // Ypos is updated in the serialEvent tab
// This for loop renders the Pulse Sensor waveform
for (int x = 1; x < pulseY.length-1; x++){ // variable 'x' will take the place of pixel x position
stroke(R); // get ready to make a red line
// Here are a few ways to draw the datapoints.
// line(x+61, pulseY[x]+1, x+61, pulseY[x]-1); // display previous datapoint as vertical line
// point(x+61,pulseY[x]); //display previous datapoint as point
// ellipse(x+61,pulseY[x],1,1); // display previous datapoint as a small dot
line(x+76, pulseY[x], x+75, pulseY[x-1]); //display previous datapoint as a connected line
}
// THESE ARE THE HEART RATE DRAWING ROUTINES
if (beat == true){ // only move the heart rate line over once every time the heart beats (beat flag set in serialEvent tab)
beat = false; // reset beat flag
for (int i=0; i<rateY.length-1; i++){
rateY[i] = rateY[i+1]; // shif the bpm Y coordinates over one pixel to the left
}
}
// update the BPM display Y coordinate when arduino sends a new calculation
if (newRate == true){ // when the new rate is sent from arduino
float dummy = map(pulseRate,0,200,135,10); // map it to the heart rate window Y
rateY[rateY.length-1] = int(dummy); // set the rightmost pixel to the new data point value
}
// print out the graph of the heart rate
stroke(250,0,0); // color of heart rate graph
for (int x=0; x < rateY.length-1; x++){ // variable 'x' will take the place of pixel x position
line(x+76, rateY[x]+2, x+76, rateY[x]-2); // display previous heart rate datapoint as vertical line
}
} //end of draw loop
void printScreen(){ // DRAW MAJOR SCREEN ELEMENTS AND TEXT
background(0); // black background
noStroke();
fill(grey); // grey
rect(40,PulseWindowY,70,PulseWindowH); // draw box around pulse window numbers
rect(40,90,70,150); // draw box around rate window numbers
fill(eggshell); // eggshell
rect(PulseWindowX,PulseWindowY,PulseWindowW,PulseWindowH); // draw pulse terminal
rect(235,90,320,150); // draw bpm terminal
text("0",65,163); // print ʻ0ʻ at bottom of bpm terminal (min heart rate for zombies)
text("200",65,35); // print ʻ200ʻ at top of bpm terminal (max heart rate for young runners)
text(HRV,65,PulseWindowY); // print the waveform amplitude
text("BPM",width-215,100); // clarification (BPM = Beats Per Minute = heart rate)
text("Pulse Sensor Visualizer 0.6",width-35,160); // name of program, version
textFont(smallFont);
text("mS Time",72,PulseWindowY + 20);
text("Between",72,PulseWindowY + 40); // print the high number of visible datapoints (DEPENDS ON AUTO OFFSET)
text("Beats",72,PulseWindowY + 60); // print the low number of visible datapoints (DITTO)
textFont(rateFont); // set up to print large text
text(pulseRate,width-275,100); // print out the pulse rate
textFont(font); // set up to print small text
// DRAW THE HEART AND MAYBE MAKE IT BEAT
fill(250,0,0);
stroke(250,0,0);
heart--; // the heart variable is used to time how long the heart graphic swells when your heart beats
if (heart < 0){heart = 0;} // don't let the heart variable go into negative numbers
if (heart > 0){ // if a beat happened recently,
strokeWeight(8); // make the heart big
}
smooth(); // draw the heart with two bezier curves
bezier(width-125,30, width-45,-40, width-25,120, width-125,130);
bezier(width-125,30, width-215,-40, width-225,120, width-125,130);
strokeWeight(1); // reset the strokeWeight
} // END OF printScreen FUNCTION
// original heart design and positioning
// bezier(width-150,50, width-70,-20, width-50,140, width-150,150);
// bezier(width-150,50, width-230,-20, width-250,140, width-150,150);
答案 0 :(得分:0)
您尚未发布完整代码,但我假设serialEvent标签与example code相同。如果是这样的话,你可以尝试这样的事情:
boolean isConnected;
void serialEvent(Serial port){
try{
String inData = port.readStringUntil('\n');
inData = trim(inData); // cut off white space (carriage return)
if (inData.charAt(0) == 'S'){ // leading 'S' for sensor data
inData = inData.substring(1); // cut off the leading 'S'
Sensor = int(inData); // convert the string to usable int
}
if (inData.charAt(0) == 'B'){ // leading 'B' for BPM data
inData = inData.substring(1); // cut off the leading 'B'
BPM = int(inData); // convert the string to usable int
beat = true; // set beat flag to advance heart rate graph
heart = 20; // begin heart image 'swell' timer
}
if (inData.charAt(0) == 'Q'){ // leading 'Q' means IBI data
inData = inData.substring(1); // cut off the leading 'Q'
IBI = int(inData); // convert the string to usable int
}
println("Sensor: " + Sensor + "\tBPM: " + BPM + "\tIBI: " + IBI);
isConnected = ((IBI >= 300 && IBI <= 1100) && (Sensor >= 200 && Sensor <= 975) && (BPM >= 30 && BPM <= 120));
}catch(Exception e){
println("caught error parsing data:");
e.printStackTrace();
}
}
try ... catch块用于捕获潜在的解析错误。根据您连接传感器的时间和打开草图的时间,您可能会错过一两个字符,这可能会抛出下一行解析不完全存在的字符串。不是最干净的解决方案,但它应该有所帮助。
还要注意上面的isConnected变量。只有在有效数据可用时,您才能使用这些内容来处理数据或显示内容。如果您没有连接传感器,它仍然会发送数据,但它将无效且无法使用。更新每个读取的变量,将3个变量考虑在内:IBI(以毫秒为单位的峰值之间的时间),传感器(原始传感器值),BPM(平均BPM)。这些数字不是解决方案,而是提示过滤数据的一种方式。您可以随意使用这些值和条件来获得最适合您设置的结果。