В этом уроке мы научимся получать данные с датчика пульса и выводить их на TFT дисплей в виде графика и среднего значения пульсаций в минуту.
Нам понадобится:
- Arduino х 1шт.
- TFT дисплей 2.8 - 320x240 х 1шт.
- Датчик пульса х 1шт.
- Trema зуммер х 1шт.
- Double Shield х 1шт.
- Trema Shield х 1шт.
Для реализации проекта нам необходимо установить библиотеки:
- Библиотека iarduino_SensorPulse для работы с датчиком пульса.
- Библиотека UTFT для работы с цветными TFT дисплеями
(в данную библиотеку нами добавлена поддержка текущего дисплея)
О том как устанавливать библиотеки, Вы можете ознакомиться на странице Wiki - Установка библиотек в Arduino IDE.
Видео:
Принцип действия датчика пульса:
Pulse Sensor - это аналоговый датчик позволяющий фиксировать пульс.
На датчике установлены светодиод и фотоприемник, расположенные так, что луч света излучаемый светодиодом, попадает на фотоприёмник только отразившись от препятствия, которым должна выступать подушечка пальца или мочка уха.
Сосуды, наполняясь кровью, меняют свою оптическую плотность, что влияет на изменение количества отражённого света. Следовательно, при постоянном уровне светового потока, излучаемого светодиодом, интенсивность света регистрируемая фотоприемником, будет зависеть от наполняемости сосудов кровью.
Электрическая схема датчика устроена так, чтобы регистрировать только динамическое изменение интенсивности принимаемого светового потока. При неизменном световом потоке (независимо от его интенсивности), напряжение на выходе датчика находится в районе половины напряжения питания. При изменении интенсивности светового потока, напряжение на выходе датчика отклоняется от среднего значения, в сторону уменьшения или увеличения, пропорционально изменению светового потока. Таким образом датчик не нуждается в подстройке под каждого человека.
Схема подключения:
TFT дисплей реализован в виде shield и использует следующие выводы arduino Uno: A0-A4 (управление), 2-9 (данные), 10-13 (SD-карта), питание. Датчик пульса подключается к аналоговому входу A5. Trema зуммер подключается к цифровому выводу 1.
Так как цифровой вывод 1 является линией TX шины UART, то при загрузке скетча будет слышен звук.
Код программы:
// Подключаем библиотеки: #include <iarduino_SensorPulse.h> // подключаем библиотеку для работы с датчиком пульса #include <UTFT.h> // подключаем библиотеку для работы с TFT дисплеями // Объявляем переменные и константы: extern uint8_t SmallFont[]; extern uint8_t BigFont[]; const uint16_t colorBG = VGA_BLACK; // цвет фона const uint16_t colorGR = VGA_GREEN; // цвет графика const uint16_t colorCD = VGA_WHITE; // цвет текста и символа пульса const uint16_t colorER = VGA_RED; // цвет текста об ошибке uint16_t graphY0; // положение предыдущей точки графика по оси Y uint16_t graphY; // положение текущей точки графика по оси Y uint16_t graphX; // положение текущей точки графика по оси X uint16_t screenW; // ширина дисплея uint16_t screenH; // высота дисплея UTFT myGLCD(TFT28UNO, A2,A1,A3,A4,A0); // подключаем дисплей TFT28UNO iarduino_SensorPulse Pulse(A5,1); // подключаем сенсор к 5 аналоговому входу, а зуммер к 1 цифровому выводу void setup(){ Pulse.begin(); // инициируем сенсор myGLCD.InitLCD(); // инициируем дисплей myGLCD.clrScr(); // стираем всю информацию с дисплея screenW = myGLCD.getDisplayXSize()-1; // получаем ширину дисплея screenH = myGLCD.getDisplayYSize()-1; // получаем высоту дисплея } void loop(){ // определяем координаты текущей точки графика graphX++; if(graphX>=screenW){graphX=0;} // сдвигаем точку графика по оси X graphY = map(Pulse.check(ISP_ANALOG),1024,0,0,screenH); // определяем точку графика по оси Y // если состояние сенсора изменилось, то ... if(Pulse.check(ISP_VALID)==ISP_CHANGED){ myGLCD.clrScr(); // стираем всю информацию с дисплея graphX=0; // сбрасываем координату текущей точки по оси X } // если сенсор подключён, то ... if(Pulse.check(ISP_VALID)==ISP_CONNECTED){ // выводим график myGLCD.setColor(colorBG); myGLCD.drawLine(graphX, 30, graphX, screenH ); if(graphX>0){ myGLCD.setColor(colorGR); myGLCD.drawLine(graphX, graphY0, graphX, graphY ); myGLCD.setColor(colorGR); myGLCD.drawLine(graphX-1,graphY0-1,graphX-1,graphY-1); // утолщаем линию } // выводим пульс и сердце if(Pulse.check(ISP_BEEP)==0){myGLCD.setColor(colorCD); myGLCD.fillCircle(20, 20, 4);} if(Pulse.check(ISP_BEEP)==1){myGLCD.setColor(colorBG); myGLCD.fillCircle(20, 20, 4);} if(Pulse.check(ISP_BEEP)==2){myGLCD.setColor(colorCD); myGLCD.setFont(SmallFont); myGLCD.printNumI(Pulse.check(ISP_PULSE),24,16,3);} // иначе, если сенсор отключён, то выводим сообщение об ошибке }else {myGLCD.setColor(colorER); myGLCD.setFont(BigFont); myGLCD.print("DISCONNECTED", CENTER,100);} // присваиваем координату текущей точки графика, координате предыдущей точки graphY0 = graphY; delay(5); } <span class="redactor-invisible-space">/* описание функции check() библиотеки iarduino_SensorPulse * Pulse.check(ISP_ANALOG); - возвращает число от 0 до 1024 - данные с аналогового входа, к которому подключён датчик * Pulse.check(ISP_PULSE); - возвращает число от 0 до 999 - пульс (количество пульсаций в минуту) * Pulse.check(ISP_BEEP); - возвращает число от 0 до 2621 - количество десятых долей секунды, прошедшее после последнего пика пульса * Pulse.check(ISP_VALID); - возвращает состояние датчика - ISP_DISCONNECTED - отключён (данные не соответствуют пульсу) * ISP_CONNECTED - подключён (данные похожи на пульс) * ISP_CHANGED - состояние сенсора изменилось (с подключён на отключён или наоборот) */</span>
Алгоритм работы:
В начале кода:
- подключаются библиотеки: iarduino_SensorPulse и UTFT;
- подключаются шрифты: SmallFont и BigFont для вывода текста на TFT дисплей;
- создаются константы: colorBG, colorGR, colorCD, colorER, которым присваиваются цвета в формате RGB565;
- создаются переменные, для вывода графика: graphY0, graphY, graphX, screenW и screenH;
- создаются объекты библиотек: myGLCD - для работы с дисплеем и Pulse - для работы с датчиком пульса.
В функции setup:
- инициируем дисплей и датчик пульса;
- стираем всю информацию с дисплея;
- сохраняем ширину и высоту дисплея в переменные screenW и screenH, вычитая по единице из каждого параметра, так как координаты для графических функций начинаются с 0, а не с 1.
В функции loop:
- определяем координаты конечной точки графика: graphX, graphY;
- если сенсор подключен, то выводим график и показания пульса;
- если сенсор отключен, то выводим сообщение "DISCONNECTED";
- если сенсор изменил своё состояние (с подключен на отключен или наоборот), то стираем всю информацию с дисплея;
- в конце кода устанавливается задержка на 5 мс., чем больше значение задержки, тем больше пульсаций уместится на графике.
Получение данных:
Данные датчика пульса возвращает функция check() библиотеки iarduino_SensorPulse, которая принимает в качестве аргумента 1 из 4 параметров: ISP_ANALOG, ISP_PULSE, ISP_BEEP, ISP_VALID.
- Pulse.check(ISP_ANALOG); - возвращает число от 0 до 1024 - данные с аналогового входа, к которому подключён датчик;
- Pulse.check(ISP_PULSE); - возвращает число от 0 до 999 - пульс (количество пульсаций в минуту);
- Pulse.check(ISP_BEEP); - возвращает число от 0 до 2621 - количество десятых долей секунды, прошедшее после последнего пика пульса;
- Pulse.check(ISP_VALID); - возвращает состояние датчика - ISP_CONNECTED, ISP_DISCONNECTED, ISP_CHANGED:
- ISP_CONNECTED - подключён (данные похожи на пульс);
- ISP_DISCONNECTED - отключён (данные не соответствуют пульсу);
- ISP_CHANGED - состояние сенсора изменилось (с подключён на отключён или наоборот).
Вывод данных:
С функциями библиотеки UTFT, для вывода данных на TFT дисплей, можно ознакомиться в разделе wiki - Работа с цветным графическим дисплеем.
- График выводится прорисовкой линий от предыдущей (graphX-1,graphY0), до текущей (graphX,graphY) точки.
- Координата graphX сдвигается от 0 до screenW, при каждом цикле loop.
- Координата graphY число возвращенное функцией Pulse.check(ISP_ANALOG) и преобразованное функцией map() от диапазона 1024-0 к диапазону 0-screenH;
- Координата graphY0 соответствует значению graphY предыдущего цикла loop. Перед прорисовкой линий графика, выводится чёрная вертикальная линия, стирающая точку предыдущего графика.
- Символ пульса (белый круг) выводится и стирается через определённый промежуток времени после фиксации пульса.
- если Pulse.check(ISP_BEEP)==0 (пульс только что зафиксирован), то выводим белый закрашенный круг.
- если Pulse.check(ISP_BEEP)==1 (после фиксации пульса прошла 0,1 сек), то закрашиваем белый круг, черным кругом.
- Значение пульса возвращается функцией Pulse.check(ISP_PULSE) и выводится на дисплей через 0,2 сек после фиксации пульса Pulse.check(ISP_BEEP)==2.
Обсуждение