Пульсоксиметр MAX30100 (китайский модуль): настроить, чтобы РАБОТАЛ

igniter

✩✩✩✩✩✩✩
11 Июн 2020
16
2
Мой топик на arduino.ru: http://arduino.ru/forum/pesochnitsa...-kitaiskii-modul-nastroit-chtoby-vse-rabotalo
Сейчас там люди заняты, может здесь кто заинтересуется... В принципе, всё работает, но вышел на затык при попытке подключить ЖКИ. В том смысле, что и с ЖКИ якобы "работает", но постоянно виснет. С компортом работает отлично: рисует графики, детектирует пульс, вычисляет сатурацию... Допилить бы до победы... Милости просим!
 
Изменено:

igniter

✩✩✩✩✩✩✩
11 Июн 2020
16
2
ProMini 328: 8 МГц, 3,3 В;
ЖКИ 1602: (не написано, на какое напряжение, но подстветка и контраст от 3,3 В вполне себе яркие);
max30100: зелёный модуль с Али (который идёт с подтяжкой И2Ц к 1,8 В), исправленный;
либо max30100: самодельный модуль на основе дорогого оригинального чипа, купленного на DigiKey;
18650: напряжение 3,7 В

Всё работает, но надо допилить до ума. Чтобы не дублировать пройденное, нижайшая просьба почитать топик по указанной выше ссылке. Текущий скетч и библа во вложении.
 

Вложения

Arhat109

★★★★✩✩✩
9 Июн 2019
473
203
C++:
#include <Arduino.h>
#include <math.h>
#include <Wire.h>
#include <LiquidCrystal.h>
#include "MAX30100.h"

MAX30100* pulseOxymeter;
LiquidCrystal lcd(13, 12, 11, 10, 9, 8);

// LCD 1206   1   2   4    5   6   11   12   13   14   15   16
// Arduino   GND  +5  13  GND  12  11   10   9    8   +5V   GND

// MAX30100  SDA SCL
// Arduino   A4  A5

void setup() {
  Wire.begin();
  Serial.begin(115200);
  Serial.println("Pulse oxymeter test!");

  lcd.begin(16,2);
  lcd.print("Initializing...");
  delay(3000);
  lcd.clear();

  delay(2000);
  //pulseOxymeter = new MAX30100( DEFAULT_OPERATING_MODE, DEFAULT_SAMPLING_RATE, DEFAULT_LED_PULSE_WIDTH, DEFAULT_IR_LED_CURRENT, true, true );
  pulseOxymeter = new MAX30100();
  pinMode(2, OUTPUT);

  //pulseOxymeter->printRegisters();
}

void loop() {
  //return;
  //You have to call update with frequency at least 37Hz. But the closer you call it to 100Hz the better, the filter will work.
  pulseoxymeter_t result = pulseOxymeter->update();


  if( result.pulseDetected == true )
  {
    Serial.println("BEAT");
   
    Serial.print( "BPM: " );
    Serial.print( result.heartBPM );
    Serial.print( " | " );

    Serial.print( "SaO2: " );
    Serial.print( result.SaO2 );
    Serial.println( "%" );

  /*  Serial.print("{P2|BPM|255,40,0|");
    Serial.print(result.heartBPM);
    Serial.print("|SaO2|0,0,255|");
    Serial.print(result.SaO2);
    Serial.println("}"); */
    lcd.setCursor(0,0);
    lcd.print("BPM: ");
    lcd.print(result.heartBPM);
    lcd.print("      ");
    lcd.setCursor(0,1);
    lcd.print("SpO2: ");
    lcd.print(result.SaO2);
    lcd.print(" %");
    lcd.print("    ");
  }


   
/*  //These are special packets for FlexiPlot plotting tool
  Serial.print("{P0|IR|0,0,255|");
  Serial.print(result.dcFilteredIR);
  Serial.print("|RED|255,0,0|");
  Serial.print(result.dcFilteredRed);
  Serial.println("}");

  Serial.print("{P1|RED|255,0,255|");
  Serial.print(result.irCardiogram);
  Serial.print("|BEAT|0,0,255|");
  Serial.print(result.lastBeatThreshold);
  Serial.println("}");

  Serial.print("{P3|IR|255,0,255|");
  Serial.print(result.rawIR);
  Serial.print("|RED|0,0,255|");
  Serial.print(result.rawRed);
  Serial.println("}");
*/


  delay(9);

  //Basic way of determening execution of the loop via oscoliscope
// digitalWrite( 2, !digitalRead(2) );
}
Пока так, позже гляну, сейчас по работе уже упластался..

P.S. Дисплей получается не на I2C ..
 

Arhat109

★★★★✩✩✩
9 Июн 2019
473
203
Не вижу проблем со скетчем. В чем заключается это самое "виснет"?

Ну и ещё. В той теме Вам написали про задержки для дисплея .. для этой (конкретно) библиотеки - факт совершенно не существенный ибо она работает через прослойку из того же набора классов что и Serial. К сожалению есть только дисплей на шине I2C, подключаемого напрямую нет, но сильно подозреваю что проблема где-то не там.

Можете опубликовать фото платы, схему соединений и т.п. .. может где-то банальный "контакт пропадает"? В части самого скетча - вопросов скорее всего нет.

И ещё: В zip-архиве лежит пример. Он работает стабильно, не зависает? А если в нем заменить весь вывод на lcd.print() с подключением дисплея - тоже работает стабильно или как?
 
Изменено:

igniter

✩✩✩✩✩✩✩
11 Июн 2020
16
2
Слетела ИДЕ с Вин7. Появляется титульное окно загрузки, несколько секунд видно сообщение "Инициализация пакетов", потом окно пропадает, И ВСЁ. И больше ничего не происходит. Другого компа нет в доступе. Переустановка ИДЕ не помогает. Безопасный режим не помогает. Откат системы до точки восстановления не помогает... Получается, только винду осталось переустанавливать? Только этого не хватало...

Библиотечный пример запускал ТОЧНО, только сейчас чёткого ответа дать не могу. Не помню, что там и как получилось... Думаю, что ничего особенного с тем примером не добился, иначе бы запомнилось. С компортом девайс нормально работает и этой прошивкой. Там вообще вопросов нет. Проблемы начинаются только после подключения ЖКИ. Работает ли компорт с подключенным ЖКИ? Тоже не помню. Вроде бы продолжает работать, но это не точно... Пока не имею возможности проверить.

Зависания выражаются в том, что довольно часто только ПЕРВЫЙ запуск после прошивки приводит к нормальной работе устройства. Потом, если выключить-включить, то после загрузки (пропадания сообщения "Инициализация...") не появляются строки с данными пульса и сатурации. Т.е. экран остаётся совершенно пустым, работает только подсветка. Иногда, если долго включать-выключать, могут появиться строки с данными, только в самих данных - мусор: либо многозначные числа, либо "nan", либо "ovf".

За контакты ручаюсь. Все соединения паяные, бредбордами не пользуюсь. ЭТОТ ЖЕ макет прекрасно работает с пульсоксиметрическим примером из инета - но только в части ЖКИ. В том смысле, что всё показывается, но пульс гуляет от пары десятков до пары сотен, а сатурацию кажет стационарно 94 с копейками - т.е. получается дурилка картонная...

А вот именно ЭТА библиотека, прибалтийская - она именно чётко детектирует пульс. У меня с недавних пор наблюдаются экстрасистолии (нарушения сердечного ритма), по словам врача, скорее всего связанные с остеохондрозом. И вот эти спорадические пропадания импульсов прибалтийская библа определяет ЧЁТКО: палец на датчике, чуть сердце "трепыхнулось" - наблюдаю на графике, как проезжает пустое место между импульсами. Пару раз присяду - битрейт моментально лезет вверх, потом восстанавливается... Т.е. то, что я вижу на компортовском графике - это именно МОЙ ПУЛЬС, а не какая-то левая наводка, как в вашей системе, с самодельным датчиком на ОУ... Только палец должен быть тёплым (у меня хронически холодные руки-ноги). Сейчас-то жара наступила, но недели две назад было прохладно, и были проблемы с детекцией пульса. Додумался подогревать палец под лампой накаливания - перед тем, как класть его на датчик. И все проблемы ушли. Вообще всё заработало как часы. Но только с компортом. А с ЖКИ - грей, не грей - никактого толку...
 
Изменено:

Arhat109

★★★★✩✩✩
9 Июн 2019
473
203
Слетела ИДЕ с Вин7. Появляется титульное окно загрузки, несколько секунд видно сообщение "Инициализация пакетов", потом окно пропадает, И ВСЁ. И больше ничего не происходит. Другого компа нет в доступе. Переустановка ИДЕ не помогает. Безопасный режим не помогает. Откат системы до точки восстановления не помогает... Получается, только винду осталось переустанавливать? Только этого не хватало...
Не помощник. Работаю с Линукс, Винды нет, даже в варианте wine и не предполагается в т.ч. из "политических соображений". ;)
Попробуйте перепостить вопрос в иной раздел или отдельной темой .. тут есть кому помочь и в достатке.

Библиотечный пример запускал ТОЧНО, только сейчас чёткого ответа дать не могу. Не помню, что там и как получилось... Думаю, что ничего особенного с тем примером не добился, иначе бы запомнилось. С компортом девайс нормально работает и этой прошивкой. Там вообще вопросов нет. Проблемы начинаются только после подключения ЖКИ. Работает ли компорт с подключенным ЖКИ? Тоже не помню. Вроде бы продолжает работать, но это не точно... Пока не имею возможности проверить.
Библиотека Serial не пересекается с вашим ЖКИ, как понимаю и ЖКИ не должен пересекаться с библиотекой MAX30100 .. т.к. у Вас прямой ЖКИ.
Отсюда: если код с ЖКИ "глючит" то вариантов вижу только два:
а) ЖКИ неверно подключен и что-то "подвешивает" в своей библиотеке .. например ожидание готовности ЖКИ принять следующий байт, сигнал которой .. не запаян куда следует. Проверяется загрузкой тестового примера от библиотеки ЖКИ и прогон его "в цикле" например .. вместо разового вывода текста повторить его в цикле раз 100 ...тыщу. И повторить после кнопки ресет, включения-выключения и т.д. То есть все те состояния где у Вас "глючит".
б) Пересечение библиотек ЖКИ и MAX30100 .. например там могут быть "единообозванные" переменные или массивы, которые смешиваются и пересекаются в своей работе как глобалы. Но это сильно врядли. Только если тест из "а" покажет что сам по себе ЖКИ работает успешно и надежно.
Бывает также что и функции обзывают одинаково, особенно когда они без параметров .. но это очень маловероятно.

Вариант "кривой ЖКИ" не рассматриваю. К сожалению проверить мне - не на чем, у меня есть ЖКИ только с I2C интерфесом и отсутствует MAX30100 .. собственно из-за чего и парился с "фоторезистором" (есть тема в проектах).

Зависания выражаются в том, что довольно часто только ПЕРВЫЙ запуск после прошивки приводит к нормальной работе устройства. Потом, если выключить-включить, то после загрузки (пропадания сообщения "Инициализация...") не появляются строки с данными пульса и сатурации. Т.е. экран остаётся совершенно пустым, работает только подсветка. Иногда, если долго включать-выключать, могут появиться строки с данными, только в самих данных - мусор: либо многозначные числа, либо "nan", либо "ovf".
Первый запуск от повторного после кнопки ресет ни чем не отличается друг от друга, если нет записи в EEPROM и оттуда не забираются какие-то данные. Как понимаю, ни в вашем коде ни в библиотеке пульсоксиметра ничего подобного нет. Соответственно, скорее всего проблема носит "аппаратный характер" для чего и просил схему устройства.
Тут можно гадать вечно. И таки да, аппаратный характер - это в т.ч. и изменение уровня питания с подключенным USB-шнурком (первый запуск) и без такового (от своего источника).

За контакты ручаюсь. Все соединения паяные, бредбордами не пользуюсь. ЭТОТ ЖЕ макет прекрасно работает с пульсоксиметрическим примером из инета - но только в части ЖКИ. В том смысле, что всё показывается, но пульс гуляет от пары десятков до пары сотен, а сатурацию кажет стационарно 94 с копейками - т.е. получается дурилка картонная...
Там "дурилка картонная" заложена изначально. Не знаю о каком примере из сети идет речь, видел несколько. В т.ч. и такой, где результат берется из .. заранее прошитой таблички, причем по сути "не взирая на результат замера" ;)
Это в целом очень чувствительный и тщательно собираемый прибор, если хотите получить нечто внятное.
Поэтому и просил "фото сборки". Важна не только схема, но и КАК в реальности запаяны провода, особенно Земли. Величина наводок в моих попытках превышала полезный сигнал от 10 до 100 раз. Некоторые из них честно принимал за пульс, пока не дошло что пульса с частотой 50Гц .. не бывает. :)

А вот именно ЭТА библиотека, прибалтийская - она именно чётко детектирует пульс. У меня с недавних пор наблюдаются экстрасистолии (нарушения сердечного ритма), по словам врача, скорее всего связанные с остеохондрозом. И вот эти пропадания импульсов прибалтийская библа определяет ЧЁТКО. Т.е. то, что я вижу на компортовском графике - это именно МОЙ ПУЛЬС, а не какая-то левая наводка, как в вашей системе, с самодельным датчиком на ОУ. Только палец должен быть тёплым (у меня хронически холодные руки-ноги). Сейчас-то жара наступила, но недели две назад было прохладно, и были проблемы с детекцией пульса. Додумался подогревать палец под лампой накаливания - перед тем, как класть его на датчик. И все проблемы ушли. Вообще всё заработало как часы. Но только с компортом. А с ЖКИ - грей, не грей - никактого толку...
Да, смотрел уже. Библиотека не самая плохая .. :) Есть ли лучше - не знаю. Хуже есть, видел. :)
Ещё раз: проблемы надо исключать последовательно.

Если проблема в работе с ЖКИ - первым делом гоним тест ЖКИ отдельно от остального. Работает? Исключаем проблему в самом ЖКИ, его подключении к схеме и его библиотеках как таковых. Нет? ура, копаем тут.

Далее, смотрим согласование библиотеки ЖКИ с библиотекой датчика. Если оно не работает только в связке - значит проблема здесь.. конфликт библиотек. Внимательно и вдумчиво изучаем обе и ищем "хде они могут пересекаться".
Ещё, как вариант, они могут пересекаться на каком-нибудь "пине", несмотря на то что MAX30100 подключен по I2C (А4,А5) и I2C у Вас не задействован в ЖКИ.. так бывает тоже.
 

igniter

✩✩✩✩✩✩✩
11 Июн 2020
16
2
Насчёт примера в архиве - так вроде бы про этот пример и идёт разговор? Насколько я помню, за основу взят именно этот пример: закомменчен сериал и вставлен ЖКИ... Другому взяться неоткуда - я не умею писать скетчи с нуля. Максимум что у меня получается, так это склеить из двух один, да и то с горем пополам...

Куски про ЖКИ взяты из рабочего примера из инета:
В этой статье первый вариант - с сериалом, а потом идёт вариант с ЖКИ. Там я посмотрел, как подключается ЖКИ, скопировал куски, и вставил в пример из прибалтийского архива (автор raivis strogonovs), что во втором сообщении ветки.

Вариант по ссылке чуть выше с датчиком у меня нормально не работает, как я уже писал. ЖКИ там показывает исправно, загружается, чует палец, показания обновляются раз в секунду, но проблема в том, что эти показания = мусор. А прибалтика чётко детектирует пульс, и даже, судя по всему, считает сатурацию, но с ЖКИ - полный затык.

Тут один путь - вам нужно приобрести зелёный модуль на Али (или хотя бы какой-нибудь), 1602 без адаптера, спаять всё как у меня, и СРАВНИТЬ. И только потом пытаться что-то делать с кодом. А иначе, думаю, мы будем лишь пытаться повысить дисперсность оксида водорода механическим путём...

Исключаем проблему в самом ЖКИ, его подключении к схеме и его библиотеках как таковых.
На мой взгляд - уже исключена. ЭТОТ ЖЕ макет прекрасно работает (работал - сейчас разобрал) с примером по ссылке в предыдущем сообщении.

Да, по мне больше похоже на конфликт. Или где-то одинаковые названия чего-то, или ещё что... А что до "нормальной работы после прошивки и глюков после переподключения питания"... Может простая случайность... Я столько её терзал, что уже и не помню точно, что там и как... Неистовые пляски были, беспощадные, бубен порвал... Пытался в своей башке какой-то лог оставить - всё, что получилось записать, записывал в теме по ссылке в первом сообщении.

Сейчас надо восстановить ИДЕ прежде всего. С лирикой пора заканчивать - разговоры ни о чём...
 

Arhat109

★★★★✩✩✩
9 Июн 2019
473
203
Не, увольте. Покупать чего-либо только ради помощи и повторения не нужной мне конструкции .. это конечно круто.
Если Вы сами не умеете, попробуйте поискать исполнителя, тут есть раздел аналогичный ардуиновскому "ищу исполнителя".
Если хотите добить самостоятельно, возможно с помощью форума, то начните заново по шагам, раз ничего уже не помните из предыдущих попыток и "всё перемешалось", с записью экспериментов, как это делал мой сын в свое время.

С восстановлением ИДЕ под винду - это не комне. Восстанавливайте. Как сделаете - можем продолжить.
 

igniter

✩✩✩✩✩✩✩
11 Июн 2020
16
2
Спасибо за готовность помочь! Но я просто подумал, что вам интересен этот прибор как таковой, а не как проблема. Исходя из этого допущения, а также поскольку ваши эксперименты с самодельным датчиком зашли в некий тупик, я и предложил купить одинаковые запчасти, чтобы двигаться далее... Ну нет так нет... ПРИНЯТО, занимаемся!
 

Arhat109

★★★★✩✩✩
9 Июн 2019
473
203
Не, я решал иную задачу, а именно вопрос применимости дешевого датчика на фоторезисторе в качестве измерительного прибора.
Как измерительный прибор он не годится, но как "показометр" - вполне "сойдет". Как раз свой вопрос я решил. Бросил потому что пилить математику, типа вашей эстонской библиотеки мне было откровенно лениво.

Что ваш датчик, что фоторезистор .. вполне показометры одного уровня. Чуть лучше - чуть хуже .. не принципиально. Там для нормальных медицинских измерений надо нечто совсем иное, что мне рассказали те, кто ими занимался на ином ресурсе в свое время.

Поэтому помочь готов, ибо на своем поигрался, кое-какой опыт приобрел, но вот повторять вашу конструкцию .. не, не готов. ;)
Поднимайте ИДЕ, и можно начать сначала.
 

igniter

✩✩✩✩✩✩✩
11 Июн 2020
16
2
Восстановил схему, заменив Про Мини 328 / 8 МГц / 3,3 В на Нано 168 /16 МГц / 5 В. ЖКИ 1602 подключил согласно схемы (таблицы соединений) в скетче, что в сообщении №3.
Начал с начала - с примера из библиотеки в сообщении #2 (без ЖКИ в коде). Всё скомпилировалось и прошилось нормально: красный светодиод датчика включается после загрузки, ЖКИ кажет строчку (верхнюю) квадратиков по числу знакомест. Прикладываю палец - пульс чётко детектируется на любом пальце рук. Другие части тела не пробовал. Гхм... Да. Вздыхаю глубоко, задерживаю дыхание (как при нырянии) - график сатурации отрабатывает чудную картинку:

глубокий вздох задержка 10 сек.png

Справа вверху виднеется кусочек окна детекции пульса. Т.е. система работает без замечаний, кроме того, разве, что показания сатурации плавно растут на две-три десятых процента примерно за минуту, но потом стабилизируются, и пляшут вокруг некоего среднего значения, никуда более не уползая. Списываю на усреднение. Больше всего радует график сатурации, явным образом откликающийся на воздействие на организм. ОК.

Теперь прошиваю эту же систему скетчем из #3. Скетч компилируется и прошивается нормально, после загрузки появляется надпись "Инициализация...", справа от которой иногда (от включения к включению) наблюдаю закрашенный прямоугольник знакоместа, (а иногда его нет). Надпись с квадратиком (если он есть) через несколько секунд пропадает, оставляя пустой экран, после чего, с некоторой задержкой, включается красный светодиод датчика. На прикладывание пальца иногда нет вообще никакой реакции, а иногда ЖКИ начинает показывать невменяемые данные - показания пульса скачут, появляются какие-то сотни ударов в минуту, сатурация тоже кажет шо попало... Привожу фото:

IMG_20200618_141542.jpg
Плоттер и сериал-монитор при этом НЕ работают - окна остаются пустыми.
Такова ситуация на данный момент. Питается система от УСБ-шнурка, через штатный разъём ардуины. Входное напряжение тестер видит как 4,4 В. От пяти вольт питать пока не пробовал, завтра принесу БП...
 
Изменено:

Arhat109

★★★★✩✩✩
9 Июн 2019
473
203
От USB-шнурка питания вполне достаточно. БП тут не причем, разве что может дать меньше/больше наводок на палец.

Итого: тест из примера работает. ЖКИ не "висит", стало быть в контуре ЖКИ можно предполагать вопросов нет. Остается Ваш глючный скетч.

Выкладывайте новым постом его глючную версию .. тут в трех точках есть специальный спойлер "код" в нем выберите язык С++ и скопипастите в него сам код, так будет удобней и может ещё кто подтянется из глазастых. ;)
 

igniter

✩✩✩✩✩✩✩
11 Июн 2020
16
2
Вот скетч с ЖКИ без И2Ц адаптера, подключенного напрямую к Ардуине Нано 5 В 16 МГц (фото макета выше). Описание поведения чуть выше. С этим скетчем сериал-монитор не работает: окна графиков остаются пустыми вне зависимости от того, показывает ли ЖКИ что-нибудь, или его экран остаётся пустым.

max30100_LCD:
#include <Arduino.h>
#include <math.h>
#include <Wire.h>
#include <LiquidCrystal.h>
#include "MAX30100.h"

MAX30100* pulseOxymeter;
LiquidCrystal lcd(13, 12, 11, 10, 9, 8);

// LCD 1206   1   2   4    5   6   11   12   13   14   15   16
// Arduino   GND  +5  13  GND  12  11   10   9    8   +5V   GND

// MAX30100  SDA SCL
// Arduino   A4  A5

void setup() {
  Wire.begin();
  Serial.begin(115200);
  Serial.println("Pulse oxymeter test!");

  lcd.begin(16,2);
  lcd.print("Initializing...");
  delay(3000);
  lcd.clear();

  delay(2000);
  //pulseOxymeter = new MAX30100( DEFAULT_OPERATING_MODE, DEFAULT_SAMPLING_RATE, DEFAULT_LED_PULSE_WIDTH, DEFAULT_IR_LED_CURRENT, true, true );
  pulseOxymeter = new MAX30100();
  pinMode(2, OUTPUT);

  //pulseOxymeter->printRegisters();
}

void loop() {
  //return;
  //You have to call update with frequency at least 37Hz. But the closer you call it to 100Hz the better, the filter will work.
  pulseoxymeter_t result = pulseOxymeter->update();


  if( result.pulseDetected == true )
  {
    Serial.println("BEAT");

    Serial.print( "BPM: " );
    Serial.print( result.heartBPM );
    Serial.print( " | " );

    Serial.print( "SaO2: " );
    Serial.print( result.SaO2 );
    Serial.println( "%" );

  /*  Serial.print("{P2|BPM|255,40,0|");
    Serial.print(result.heartBPM);
    Serial.print("|SaO2|0,0,255|");
    Serial.print(result.SaO2);
    Serial.println("}"); */
    lcd.setCursor(0,0);
    lcd.print("BPM: ");
    lcd.print(result.heartBPM);
    lcd.print("      ");
    lcd.setCursor(0,1);
    lcd.print("SpO2: ");
    lcd.print(result.SaO2);
    lcd.print(" %");
    lcd.print("    ");
  }



/*  //These are special packets for FlexiPlot plotting tool
  Serial.print("{P0|IR|0,0,255|");
  Serial.print(result.dcFilteredIR);
  Serial.print("|RED|255,0,0|");
  Serial.print(result.dcFilteredRed);
  Serial.println("}");

  Serial.print("{P1|RED|255,0,255|");
  Serial.print(result.irCardiogram);
  Serial.print("|BEAT|0,0,255|");
  Serial.print(result.lastBeatThreshold);
  Serial.println("}");

  Serial.print("{P3|IR|255,0,255|");
  Serial.print(result.rawIR);
  Serial.print("|RED|0,0,255|");
  Serial.print(result.rawRed);
  Serial.println("}");
*/


  delay(9);

  //Basic way of determening execution of the loop via oscoliscope
// digitalWrite( 2, !digitalRead(2) );
}
 
Изменено:

Arhat109

★★★★✩✩✩
9 Июн 2019
473
203
Так .. я был очень невнимателен. ТАК - не пойдет. Работающий пример БЕЗ ЖКИ - это ни о чем!

Запустите такой пример (БЕЗ датчика):
C++:
/*
  LiquidCrystal Library - Hello World

 Demonstrates the use a 16x2 LCD display.  The LiquidCrystal
 library works with all LCD displays that are compatible with the
 Hitachi HD44780 driver. There are many of them out there, and you
 can usually tell them by the 16-pin interface.

 This sketch prints "Hello World!" to the LCD
 and shows the time.

  The circuit:
 * LCD RS pin to digital pin 12
 * LCD Enable pin to digital pin 11
 * LCD D4 pin to digital pin 5
 * LCD D5 pin to digital pin 4
 * LCD D6 pin to digital pin 3
 * LCD D7 pin to digital pin 2
 * LCD R/W pin to ground
 * LCD VSS pin to ground
 * LCD VCC pin to 5V
 * 10K resistor:
 * ends to +5V and ground
 * wiper to LCD VO pin (pin 3)

 Library originally added 18 Apr 2008
 by David A. Mellis
 library modified 5 Jul 2009
 by Limor Fried (http://www.ladyada.net)
 example added 9 Jul 2009
 by Tom Igoe
 modified 22 Nov 2010
 by Tom Igoe
 modified 7 Nov 2016
 by Arturo Guadalupi

 This example code is in the public domain.

 http://www.arduino.cc/en/Tutorial/LiquidCrystalHelloWorld

*/

// include the library code:
#include <LiquidCrystal.h>

// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

void setup() {
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("hello, world!");
}

void loop() {
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 1);
  // print the number of seconds since reset:
  lcd.print(millis() / 1000);
}
Работает ЖКИ? После нажатий кнопки reset, повторным включением/выключением дуньки - устойчиво?
Потом продолжим. Пример взят из Ардуино ИДЕ меню "Файл - Примеры - LuquidCrystal - Display". Залейте и попробуйте другие примеры этой библиотеки. Все работают штатно и устойчиво?
Потом продолжим.
 

igniter

✩✩✩✩✩✩✩
11 Июн 2020
16
2
Хотелось бы уточнить, на всякий случай, что прибалтийский пример (который нормально работает с датчиком и сериал-монитором) прошит в схему, где также подключен и ЖКИ. Последний при этом ничего не показывает, кроме ряда квадратиков в верхней строчке - что ожидаемо, потому как в прибалтийском скетче нет упоминаний о ЖКИ. Я к тому, что чисто железно подключенный ЖКИ не создаёт проблем для работы с сериал-монитором. А вот уже подключенный В КОДЕ - таки создаёт (см. выше).

Перепаял ЖКИ по схеме, описанной в ардуинском "хелло ворлд". Прошил указанным примером - всё работает устойчиво. После ресета происходит только сброс "секундомера" в ноль с последующим возобновлением посекундного счёта, при этом "хелло ворлд!" остаётся без изменений. После переподключения - загружается с верхней строчкой квадратиков, потом на их месте появляется "хелло ворлд!", а в нижней строчке начинает считать "секундомер", от нуля. Всё работает устойчиво, воспроизводимо, без глюков и зависаний. Модуль max30100 во время описанных экспериментов НЕ отключал; его красный светодиод ожидаемо не включался.

зы: Попробовал модифицировать прибалтийский пример, по-новому подключив ЖКИ (как в ардуинском примере). После загрузки и пропадания слова "Initializing..." наблюдаю пустой экран. Красный светодиод датчика после пропадания "Initializing..." остаётся выключенным. Ресет и переподключение воспроизводят описанную картину без изменений. Т.е. экран получает и воспроизводит отсылаемые ему символы ("Initializing..."), но и только. Система не работает... Чисто визуально, изменение схемы подключения ЖКИ к каким-то изменениям поведения системы НЕ привело - тот же пустой экран, тот же не включающийся светодиод датчика.
 
Изменено:

Arhat109

★★★★✩✩✩
9 Июн 2019
473
203
Проблема стало быть в "схеме", "пайке" и вашей переработке скетчей.

И да, ваше устройство можно было не разбирать и не перепаивать. Достаточно было поменять в примере номера ног подключения ЖКИ. Датчик можно было не выпаивать.

Схему вашей пайки, фото девайса, так чтобы можно было посмотреть с разных ракурсов.
 

igniter

✩✩✩✩✩✩✩
11 Июн 2020
16
2
Можно было и не перепаивать, но хотелось "от печки", с нуля. Перепаял (мне не трудно), тестовый "хелло" ЖКИ работает без замечаний. И датчик работает без замечаний, но только на сериал-монитор, и с другой прошивкой. А вместе - не хотят.

IMG_20200619_150704.jpgIMG_20200619_150713.jpgIMG_20200619_150813.jpg

зы: > "схеме" ... "пайке"
Кавычки ваши о чём?

Амплитуда пульса в окне графика детекции пульса сейчас под 1000 единиц - с лёту. Любой палец, почти в любом положении. А недели три назад, когда в помещении было холодно (и пальцы тоже были холодными) выше 400 никак не получалось - как ни подбирай положение и силу прижатия. Единственное, что смогло переломить ситуацию - ПРОГРЕВ ПАЛЬЦЕВ (в моём случае - под лампой накаливания). Это был именно прорыв от "шопопало" до "это РАБОТАЕТ!" Вывод: ТЕМПЕРАТУРА МЯСА в этом деле имеет большое значение.
 
Изменено:
  • Лойс +1
Реакции: Arhat109

Arhat109

★★★★✩✩✩
9 Июн 2019
473
203
Не очень внятно видно что и куда подпаяно из-за одного цвета проводов и их не очень удачного расположения, но кмк, в соединениях особых проблем нет. Как понимаю, питаете всю конструкцию от компа через USB порт. Резисторы подтяжки шины I2C как вижу 4.7 кОм .. маловато, но в целом сойдет.

То есть, с конкретно этой пайкой, без переделок есть два результата (от USB):
1. Скетч из примера MAX30100 работает с COM-портом без проблем, несмотря на то, что дергает пином 2 у ЖКИ..
2. Скетч из примера ЖКИ работает также нормально и устойчиво.

Это - верно?

P.S. то есть, ничего не перепаивая, заливаем "пример1" и он пашет на монитор. Затем перезаливаем "пример2" и он пашет на ЖКИ. Всё так?
 

igniter

✩✩✩✩✩✩✩
11 Июн 2020
16
2
Не понял насчёт "дёргает пином 2 у ЖКИ"...
Пин 2 у ЖКИ - это +5 В.
Пин 2 Ардуины (Д2) действительно идёт на пин Д7 ЖКИ. Значит, чем-то он таки дёргает. Или его дёргают.
Провода одноцветные, это правда, но "что куда идёт" на фото я могу проследить без труда... С качеством пайки, уверяю вас, тоже всё в порядке.

1. Скетч из примера МАХ30100 работает с СОМ-портом без проблем - именно в той конфигурации, которую вы видите на фото. ЖКИ при этом кажет рядок квадратиков в верхней своей строчке.
2. Скетч из ардуинского примера ЖКИ "хелло ворлд!" с "секундомером" также работает нормально и устойчиво.
 

Arhat109

★★★★✩✩✩
9 Июн 2019
473
203
Отлично. Значит "пайка не при делах". Остается разобраться что Вы "объединили не так" из обоих примеров.

P.S. Пример из библиотеки MAX30100 из первого поста в строке 66 дергает пином 2 Ардуины. Он у Вас запаян на шину данных ЖКИ дисплея. Это не критично в данном опыте запуска тестов "по очереди".

Ок. Собираем ОБА примера в один скетч:
C++:
/*
 * Arhat109: тут была лицензия .. дополняем пример работой с ЖКИ
 */
#include <Arduino.h>
#include <math.h>
#include <Wire.h>
#include "MAX30100.h"
#include <LiquidCrystal.h>

// Заменяем пин2 на 13, т.к. у него есть встроенный светодиод
#define pinLed 13

MAX30100* pulseOxymeter;

// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

void setup()
{
  Wire.begin();
  Serial.begin(115200);
  Serial.println("Pulse oxymeter test!");

  //pulseOxymeter = new MAX30100( DEFAULT_OPERATING_MODE, DEFAULT_SAMPLING_RATE, DEFAULT_LED_PULSE_WIDTH, DEFAULT_IR_LED_CURRENT, true, true );
  pulseOxymeter = new MAX30100();
  pinMode(pinLed, OUTPUT);

  //pulseOxymeter->printRegisters();

  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("hello, world!");
  delay(2000);
}

void loop() {
  //return;
  //You have to call update with frequency at least 37Hz. But the closer you call it to 100Hz the better, the filter will work.
  pulseoxymeter_t result = pulseOxymeter->update();
 

  if( result.pulseDetected == true )
  {
    Serial.println("BEAT");
    
    Serial.print( "BPM: " );
    Serial.print( result.heartBPM );
    Serial.print( " | " );
 
    Serial.print( "SaO2: " );
    Serial.print( result.SaO2 );
    Serial.println( "%" );

    Serial.print("{P2|BPM|255,40,0|");
    Serial.print(result.heartBPM);
    Serial.print("|SaO2|0,0,255|");
    Serial.print(result.SaO2);
    Serial.println("}");
  }

  //These are special packets for FlexiPlot plotting tool
  Serial.print("{P0|IR|0,0,255|");
  Serial.print(result.dcFilteredIR);
  Serial.print("|RED|255,0,0|");
  Serial.print(result.dcFilteredRed);
  Serial.println("}");
 
  Serial.print("{P1|RED|255,0,255|");
  Serial.print(result.irCardiogram);
  Serial.print("|BEAT|0,0,255|");
  Serial.print(result.lastBeatThreshold);
  Serial.println("}");

  delay(10);

  //Basic way of determening execution of the loop via oscoliscope
  // изменяем, т.к. в ЖКИ этот пин занят.
  digitalWrite( pinLed, !digitalRead(pinLed) );

  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 1);
  // print the number of seconds since reset:
  lcd.print(millis() / 1000);
}
Так - работают? Каждый делает свое дело: один измеряет и выводит в COM-порт, второй считает миллисекунды на ЖКИ.
 
Изменено:
  • Лойс +1
Реакции: runaway

igniter

✩✩✩✩✩✩✩
11 Июн 2020
16
2
Не работает. Ни графики не строятся в плоттере, ни ЖКИ не показывает. Вот плоттер, которым пользуюсь я. Думаю, его нужно установить и вам, чтобы иметь общую "систему координат": https://github.com/xcoder123/FlexiPlot/releases
Пользоваться им достаточно просто: чтобы открыть окна, нужно нажать синюю квадратную кнопку "Add line chart" (вспл. подсказка) - столько раз, сколько нужно окон графиков. Я нажимаю три раза, и получаю окна графиков: сырые данные, детекция пульса и сатурация. Если всё в порядке, то после нажатия кнопки "Connect to device" (предварительно выбрав нужные номер порта и скорость соединения) в первых двух окнах появляются графики шумов, примерно как на осциллографе. После прижатия пальца к датчику, в первых двух окнах шумы постепенно замещаются сигналами, изображёнными на приведённом скриншоте, а в третьем окне постепенно появляется (вызжает из-за правого края) кривая графика сатурации. Всё происходит в режиме реального времени.
Есть небольшие нюансы - типа передёрнуть питание ардуины, перекликнуть кнопки "коннект" и "дисконнект", очерёдность включения ардуины и плоттера, но это такое... Если скетч рабочий - всё получается достаточно быстро, и графические данные появляются в окнах без особых проблем. Но со скетчем из предыдущего сообщения ничего не получается. Окна остаются пустыми, ЖКИ тоже кажет ряд квадратиков в верхней строчке, и на том всё... Вот скрин работающего плоттера:

plotter_works.png

Такая картина наблюдается с прибалтийским примером. С вариантом из предыдущего поста все окна остаются пустыми, как я ни тыкал, как ни перетыкивал... Пока - глуховато, одним словом.
 

Arhat109

★★★★✩✩✩
9 Июн 2019
473
203
Код прибалтийского примера, с которым получаются такие графики - в студию, дабы не разыскать что-то "не то" снова.
И таки ещё раз: у меня нет вашего датчика MAX30100 и его приобретение НЕ ПРЕДВИДИТСЯ. Общаемся в режиме: я Вас прошу что-то сделать, Вы - делаете и выкладываете результат сюда.

Сейчас нужен тот код, который рисует эти графики на той схеме, фотография которой приведена выше. Ровно так как написано, без перепаек и любых модификаций схемы.

P.S. Стоп .. а так - работает?
C++:
/*
 * Arhat109: тут была лицензия .. дополняем пример работой с ЖКИ
 */
#include <Arduino.h>
#include <math.h>
#include <Wire.h>
#include "MAX30100.h"
#include <LiquidCrystal.h>

// Заменяем пин2 на 13, т.к. у него есть встроенный светодиод
#define pinLed 13

MAX30100* pulseOxymeter;

// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

void setup()
{
  Wire.begin();
  Serial.begin(115200);
  Serial.println("Pulse oxymeter test!");

  //pulseOxymeter = new MAX30100( DEFAULT_OPERATING_MODE, DEFAULT_SAMPLING_RATE, DEFAULT_LED_PULSE_WIDTH, DEFAULT_IR_LED_CURRENT, true, true );
  pulseOxymeter = new MAX30100();
  pinMode(pinLed, OUTPUT);

  //pulseOxymeter->printRegisters();

  // set up the LCD's number of columns and rows:
//  lcd.begin(16, 2);
  // Print a message to the LCD.
//  lcd.print("hello, world!");
  delay(2000);
}

void loop() {
  //return;
  //You have to call update with frequency at least 37Hz. But the closer you call it to 100Hz the better, the filter will work.
  pulseoxymeter_t result = pulseOxymeter->update();
 

  if( result.pulseDetected == true )
  {
    Serial.println("BEAT");
    
    Serial.print( "BPM: " );
    Serial.print( result.heartBPM );
    Serial.print( " | " );
 
    Serial.print( "SaO2: " );
    Serial.print( result.SaO2 );
    Serial.println( "%" );

    Serial.print("{P2|BPM|255,40,0|");
    Serial.print(result.heartBPM);
    Serial.print("|SaO2|0,0,255|");
    Serial.print(result.SaO2);
    Serial.println("}");
  }

  //These are special packets for FlexiPlot plotting tool
  Serial.print("{P0|IR|0,0,255|");
  Serial.print(result.dcFilteredIR);
  Serial.print("|RED|255,0,0|");
  Serial.print(result.dcFilteredRed);
  Serial.println("}");
 
  Serial.print("{P1|RED|255,0,255|");
  Serial.print(result.irCardiogram);
  Serial.print("|BEAT|0,0,255|");
  Serial.print(result.lastBeatThreshold);
  Serial.println("}");

  delay(10);

  //Basic way of determening execution of the loop via oscoliscope
  // изменяем, т.к. в ЖКИ этот пин занят.
  digitalWrite( pinLed, !digitalRead(pinLed) );

  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
//  lcd.setCursor(0, 1);
  // print the number of seconds since reset:
//  lcd.print(millis() / 1000);
}
 
Изменено:

igniter

✩✩✩✩✩✩✩
11 Июн 2020
16
2
Не работает. Пустые окна. Максимум, чего удалось добиться - вспыхивания светодиода на модуле Ардуины в момент нажатия кнопок "Коннект" / "Дисконнект" в указанном выше плоттере. Т.е. я к тому, что если имеет место неправильная последовательность включения "плоттер - - устройство", то может получиться так, что на клики кнопок "Коннект" / "Дисконнект" ардуина вообще никак не реагирует. Но если всё передёрнуть-подключить в ПРАВИЛЬНОЙ последовательности, то при загруженном в ардуину РАБОЧЕМ скетче, в момент клика кнопки "Коннект", на Ардуине кратковременно вспыхивает светодиод, и через полсекунды из-за правого края окон появляются и едут справа налево розово-голубые кривые, в первых двух окнах плоттера (сырец и детекция пульса). С вашим же скетчем только светодиод на ардуине блымает, и всё... Если же открыть ШТАТНЫЙ ардуинов сериал-монитор, имея ваш скетч загруженным в Ардуину, то в момент клика по кнопке открытия монитора на Ардуине вспыхивает вышепомянутый огонёк, а примерно через секунду, в открывшемся пустом окне монитора, появляется и статически висит сообщение "Pulse oxymeter test!" И на том всё. Ниже - рабочий (прибалтийский) скетч, с которым нормально работает прибалтийский же плоттер (того же автора). С этим же скетчем вполне нормально работает и штатный сериал-монитор ардуинской ИДЕ, в котором "цифропадом" льются координаты точек для построения графиков, а также строчки с данными пульса и сатурации в моменты детекции пульса. Схему не изменял - как принёс её с работы, вместе с фанеркой, так и воткнул в УСБ-удлинитель. Единственное, что отличается - на работе стоит ИДЕ 1.8.8, а здесь 1.8.12.
C++:
/*
MIT License

Copyright (c) 2017 Raivis Strogonovs (https://morf.lv)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

*/
#include <Arduino.h>
#include <math.h>
#include <Wire.h>

#include "MAX30100.h"

MAX30100* pulseOxymeter;

void setup() {
  Wire.begin();
  Serial.begin(115200);
  Serial.println("Pulse oxymeter test!");

  //pulseOxymeter = new MAX30100( DEFAULT_OPERATING_MODE, DEFAULT_SAMPLING_RATE, DEFAULT_LED_PULSE_WIDTH, DEFAULT_IR_LED_CURRENT, true, true );
  pulseOxymeter = new MAX30100();
  pinMode(2, OUTPUT);

  //pulseOxymeter->printRegisters();
}

void loop() {
  //return;
  //You have to call update with frequency at least 37Hz. But the closer you call it to 100Hz the better, the filter will work.
  pulseoxymeter_t result = pulseOxymeter->update();


  if( result.pulseDetected == true )
  {
    Serial.println("BEAT");

    Serial.print( "BPM: " );
    Serial.print( result.heartBPM );
    Serial.print( " | " );

    Serial.print( "SaO2: " );
    Serial.print( result.SaO2 );
    Serial.println( "%" );

    Serial.print("{P2|BPM|255,40,0|");
    Serial.print(result.heartBPM);
    Serial.print("|SaO2|0,0,255|");
    Serial.print(result.SaO2);
    Serial.println("}");
  }



  //These are special packets for FlexiPlot plotting tool
  Serial.print("{P0|IR|0,0,255|");
  Serial.print(result.dcFilteredIR);
  Serial.print("|RED|255,0,0|");
  Serial.print(result.dcFilteredRed);
  Serial.println("}");

  Serial.print("{P1|RED|255,0,255|");
  Serial.print(result.irCardiogram);
  Serial.print("|BEAT|0,0,255|");
  Serial.print(result.lastBeatThreshold);
  Serial.println("}");



  delay(10);

  //Basic way of determening execution of the loop via oscoliscope
  digitalWrite( 2, !digitalRead(2) );
}
 
Изменено:

Arhat109

★★★★✩✩✩
9 Июн 2019
473
203
Не нашел отличий между скетчами в постах 22 и 23. Они с т.з. ПО - одинаковы.
Что-то Вы делаете не так. Чем помочь дальше - "ума не приложу", может кто-то подключится у кого есть такая же железяка - МАХ30100?
Я дальше - пас.

Поясню.
1. Скетчи в этих постах - идентичны с т.з. того что они делают. Но у получается один работает, а второй нет. - ТАК не бывает;
2. Посмотрел тексты библиотек. Пересекаться там негде, соответственно скетч 22 - работать должен, ибо он отличается от вашего только подключением .H файла, который не добавляет код к программе, а только вводит определения компилятору.

Что-то тут не так, и возможно Вы правы - надо воспроизводить ваше устройство целиком и/или вместе с конкретно вашими действиями. Но это уже "без меня".
 
Изменено:

igniter

✩✩✩✩✩✩✩
11 Июн 2020
16
2
Записать видео? Может, я что-то упускаю? И я ума не приложу. Что-то очень простое, скорее всего.