1. Design introduction
Currently, a heart rate detector is implemented based on STC89C52 microcontroller and PCF8591, PulseSensor heart rate sensor, SSD1306 OLED display and other components. The detector can collect the analog signal output by the heart rate sensor, calculate the real-time heart rate value after AD conversion, and then transmit the heart rate value to the OLED display for display through the IIC protocol. Users only need to fix the heart rate sensor on the body and start the heart rate detector to conveniently monitor their heart rate in real time.
This project has a wide range of applications and can be used in health management, fitness exercises, medical treatment and other fields. At home, people can use this heart rate monitor to monitor their own heart rate in a timely manner and effectively manage and control their health; in gyms or fitness coaching centers, coaches can use this heart rate monitor to monitor athletes' heart rate changes in order to target The training plan can be adjusted accordingly to improve the training effect; in medical institutions, medical staff can use the heart rate monitor to monitor the heart rate of patients, detect abnormalities in time, and provide a strong basis and reference for patient treatment.
2. Hardware selection
Hardware required for this project:
STC89C52 microcontroller: As the main control chip, it is responsible for reading the analog signal of the PulseSensor heart rate sensor, performing AD conversion, calculating the heart rate value, and transmitting the heart rate value to the OLED display for display through the IIC protocol.
PCF8591 module: used to implement the STC89C52 microcontroller to perform data acquisition and AD conversion on the PulseSensor heart rate sensor through the IIC bus.
PulseSensor heart rate sensor: used to collect the weak heartbeat signal of the human body and output the signal to the PCF8591 module.
SSD1306 OLED display: used to display heart rate detection results, including heart rate value and unit.
DuPont wire, breadboard: used to connect various hardware modules and build circuit prototypes.
3. Implement the code
The following is the core code of the project, which collects the heart rate through the PCF8591 connected to the PulseSensor heart rate sensor, and displays it on the 0.96-inch OLED display through the IIC protocol:
#include < reg52.h >
#include < intrins.h >
#define uchar unsigned char
#define uint unsigned int
sbit SCL = P1^0;
sbit SDA = P1^1;
sbit LED = P2^0;
#define ADDR_PCF8591 0x90 // IIC address of PCF8591: 1001 0000
#define CMD_PCF8591_WR 0x40 //PCF8591 write data command word: 0100 CCCC, CCCC is channel selection
#define CMD_PCF8591_RD 0x41 // PCF8591 read data command word: 0100 CCCC, CCCC is channel selection
#define ADDR_OLED 0x78 // IIC address of SSD1306 OLED display: 0111 1000
uchar heartRate[3]; // String to store heart rate value
/**
* Delay function to control IIC communication speed
*/
void Delay()
{
uint i, j;
for(i=0; i< 50; i++)
for(j=0; j< 500; j++);
}
/**
*IIC start signal
*/
void IIC_Start()
{
SCL = 1;
SDA = 1;
Delay();
SDA = 0;
Delay();
SCL = 0;
}
/**
*IIC stop signal
*/
void IIC_Stop()
{
SCL = 0;
SDA = 0;
Delay();
SCL = 1;
SDA = 1;
Delay();
}
/**
*IIC sends one byte of data
* @param byte sent byte
* @return received response bit
*/
volatile IIC_SendByte(volatile byte)
{
fly i, ack;
for(i=0; i< 8; i++)
{
SDA = (bit)(byte & 0x80);
byte < <= 1;
Delay();
SCL = 1;
Delay();
SCL = 0;
}
SDA = 1;
Delay();
SCL = 1;
Delay();
ack = SDA;
SCL = 0;
return ack;
}
/**
* Initialize PCF8591 module
*/
void Init_PCF8591()
{
IIC_Start();
IIC_SendByte(ADDR_PCF8591);
IIC_SendByte(CMD_PCF8591_WR | 0);
IIC_Stop();
}
/**
* Read the AD value of PCF8591
* @param ch The selected channel number
* @return the value after AD conversion
*/
fly Read_PCF8591(fly ch)
{
volatile value;
IIC_Start();
IIC_SendByte(ADDR_PCF8591);
IIC_SendByte(CMD_PCF8591_WR | ch);
IIC_Stop();
IIC_Start();
IIC_SendByte(ADDR_PCF8591 | 0x01);
value = IIC_SendByte(0xFF);
IIC_Stop();
return value;
}
/**
* Initialize SSD1306 OLED display
*/
void Init_OLED()
{
IIC_Start();
IIC_SendByte(ADDR_OLED);
IIC_SendByte(0xAE); //Close display
IIC_SendByte(0x00); //Lower 4 bits of column address
IIC_SendByte(0x10); //High 4 bits of column address
IIC_SendByte(0x40); // Starting row address
IIC_SendByte(0xB0); //Set page address
IIC_SendByte(0x81); // Contrast setting command
IIC_SendByte(0xCF); //Contrast value
IIC_SendByte(0xA1); // Segment multiplexing settings
IIC_SendByte(0xA6); //Normal display mode
IIC_SendByte(0xA8); // Multiplexing settings
IIC_SendByte(0x3F); //Number of pages-1
IIC_SendByte(0xC8); //Scan mode setting
IIC_SendByte(0xD3); //Set display offset
IIC_SendByte(0x00);
IIC_SendByte(0xD5); // Frequency setting command
IIC_SendByte(0x80); // Frequency division coefficient
IIC_SendByte(0xD9); //Set the precharge cycle
IIC_SendByte(0xF1);
IIC_SendByte(0xDA); //Set the COM hardware connection method
IIC_SendByte(0x12);
IIC_SendByte(0xDB); // VCOMH setting
IIC_SendByte(0x40);
IIC_SendByte(0xA4); // All lit/normal display
IIC_SendByte(0xA6); //Normal/reverse display control
IIC_SendByte(0xAF); // Turn on display
IIC_Stop();
}
/**
* Display string on OLED
* @param x start column address
* @param y start page address
* @param str The string to be displayed
*/
void ShowString_OLED(float x, float y, float *str)
{
fly i = 0;
IIC_Start();
IIC_SendByte(ADDR_OLED);
IIC_SendByte(0x00); //Lower 4 bits of column address
IIC_SendByte(0x10); //High 4 bits of column address
IIC_SendByte(0xB0 + y);//Set page address
for(i=0; str[i]!='\0'; i++)
{
IIC_SendByte(0xB0 + y);
IIC_SendByte((x + 8*i) & 0x0F);
IIC_SendByte(((x + 8*i) > > 4) | 0x10);
IIC_SendByte(str[i]);
}
IIC_Stop();
}
/**
* Main function, heart rate calculation and display
*/
void main()
{
Init_PCF8591(); // Initialize PCF8591 module
Init_OLED(); // Initialize OLED display
while(1)
{
uchar adValue = Read_PCF8591(0); // Read the AD value of PCF8591
uint timeInterval = 100; //Set the time interval for collecting heart rate, in milliseconds
uint count = 0; // Counter that counts the number of pulse beats
uint heartRateValue = 0; // Calculated heart rate value
for (uint i=0; i< timeInterval; i++) // Collect data within a certain period of time
{
if (adValue > 200) // When the AD value is higher than the threshold, count the number of pulse beats
{
count++;
while(adValue > 100) // Wait for a period of time to avoid the same pulse being counted repeatedly
{
adValue = Read_PCF8591(0);
}
}
adValue = Read_PCF8591(0); // Read the next AD value
}
heartRateValue = (uint)(count * 60.0 / timeInterval); // Calculate heart rate value
sprintf(heartRate, "%d", heartRateValue); // Convert heart rate value to string
ShowString_OLED(0, 0, "Heart Rate:"); // Display title on OLED
ShowString_OLED(80, 0, heartRate); // Display heart rate value on OLED
ShowString_OLED(96, 0, "bpm"); // Display units on OLED
}
}
Previous article:Design of multi-channel temperature and humidity cycle detection system using microcontroller AT89C2051 and AD7416 chips
Next article:Design of eight-way voltmeter using AT89C52 microcontroller
- Popular Resources
- Popular amplifiers
- Learn ARM development(16)
- Learn ARM development(17)
- Learn ARM development(18)
- Embedded system debugging simulation tool
- A small question that has been bothering me recently has finally been solved~~
- Learn ARM development (1)
- Learn ARM development (2)
- Learn ARM development (4)
- Learn ARM development (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- Detailed explanation of intelligent car body perception system
- How to solve the problem that the servo drive is not enabled
- Why does the servo drive not power on?
- What point should I connect to when the servo is turned on?
- How to turn on the internal enable of Panasonic servo drive?
- What is the rigidity setting of Panasonic servo drive?
- How to change the inertia ratio of Panasonic servo drive
- What is the inertia ratio of the servo motor?
- Is it better for the motor to have a large or small moment of inertia?
- What is the difference between low inertia and high inertia of servo motors?
- [SC8905 EVM Evaluation] + MCU I2C Communication Experiment
- Hikvision responds to US ban: All components used have alternatives
- How to implement BLUENRG1/2 Bluetooth MESH and BLE REMOTE at the same time?
- Does the PIC32MZ DA series have an FPU?
- Comprehensive electrical skills from entry level to mastery
- Linux serial communication 1——96-N-8-1 format
- [STM32WB55 Review] Summary
- 1000 posts, commemorating
- This is a circuit for detecting the grid voltage. I would like to ask how the differential circuit works.
- BMP library management based on FPGA.pdf