На скорости 115200 никого переполнения буфера не возникает. Скорость оборота буфера легко проверить включив мониториг времени вывода строк. Ещё раз повторю, к использованию 100 герц нет никаких предпосылок, кроме красивого числа.
Вывод на LCD не зависит от времени цикла. При выполнении программы глюки LCD связаны с тем, что команды вывода на экран даются раньше, чем LCD готов их воспринимать. Например lcd.clear(); может выполняться до секунды на некоторых дисплеях. Поэтому после каждой команды необходимо проверять занят дисплей или нет. Сейчас этого не делают. И имеют проблемы. Например Команда установки курсора выполняется около 40 мкс. Если начать писать после неё чуть раньше, то получим глюк. Попробуйте вставить delayMicroseconds(40); после каждой команды LCD и посмотреть что получится.
В варианте с ЖКИ вывод в serial ВООБЩЕ не нужен. Компорт интересен ТОЛЬКО при отладке. Там вообще можно закомментить всё подчистую - и для плоттера, и для монитора. Строгоновский скетч интересен мне прежде всего математической обработкой данных. Которая, в отличие от других библиотек, демонстрирует видимую адекватность показаний пульса, и, как следствие - сатурации. Я просто не в курсе, где именно у системы находится узкое место в смысле вывода данных: размер ли это буфера, кол-во выводимых в сериал строк/символов, бодрейт, или вообще - тактовая частота процессора Ардуины (у меня, кстати, 8 МГц х 3,3В). Или всё вместе, в комплексе.
Пробовал по-всякому. Добавлял задержки, комментил компорт, снимал мост усб/уарт, менял датчики... Ничего не помогает. Система работает нестабильно, эксплуатировать её невозможно. Когда вывод идёт чисто в компорт (залил исходный скетч) - всё работает вполне предсказуемо и ПОЧТИ стабильно. Иногда бывают РЕДКИЕ затыки (несколько раз в день, а это сотни пусков), которые лечатся кнопкой ресет или переподключением питания. А с ЖКИ - через пять на шестой раз сработает, поработает несколько минут, выводя адекватный пульс и сатурацию, и зависнет. Наглухо: стационарные цифры на ЖКИ. Проблема, судя по всему, именно в ЖКИ. Точнее не в железе ЖКИ, потому что с другим скетчем этот же экземпляр работает без замечаний, а в программной части, которая с ним общается. Какой-то нюанс не учтён. Надеюсь, что уважаемое сообщество всё-таки разберётся, в чём здесь кроется проблема, и найдёт практическое её решение.
Ниже привожу "рабочие" скетч и его библиотеку - кавычки в том смысле, что они нормально работают с указанным ЖКИ (строки показаний пульса и сатурации стабильно появляются после загрузки, а сами показания в процессе работы никогда не виснут), но НЕнормально - с датчиком 30100 (эти самые "стабильно выводимые" результаты пульса и сатурации - НЕадекватны, а потому никому не нужны):
#include <LiquidCrystal.h>
#include <Wire.h>
#include "MAX30100_PulseOximeter.h"
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
#define REPORTING_PERIOD_MS 1000
PulseOximeter pox;
uint32_t tsLastReport = 0;
void onBeatDetected()
{
Serial.println("Beat!");
}
void setup()
{
Serial.begin(115200);
Serial.print("Initializing pulse oximeter..");
lcd.begin(16,2);
lcd.print("Initializing...");
delay(3000);
lcd.clear();
// Initialize the PulseOximeter instance
// Failures are generally due to an improper I2C wiring, missing power supply
// or wrong target chip
if (!pox.begin()) {
Serial.println("FAILED");
for(;;);
} else {
Serial.println("SUCCESS");
}
pox.setIRLedCurrent(MAX30100_LED_CURR_50MA);
// Register a callback for the beat detection
pox.setOnBeatDetectedCallback(onBeatDetected);
}
void loop()
{
// Make sure to call update as fast as possible
pox.update();
if (millis() - tsLastReport > REPORTING_PERIOD_MS) {
Serial.print("Heart rate:");
Serial.print(pox.getHeartRate());
Serial.print("bpm / SpO2:");
Serial.print(pox.getSpO2());
Serial.println("%");
lcd.clear();
lcd.setCursor(1,0);
lcd.print("BPM: ");
lcd.print(pox.getHeartRate());
lcd.setCursor(6,1);
lcd.print("SpO2: ");
lcd.print(pox.getSpO2());
lcd.print(" %");
tsLastReport = millis();
}
}
Ну хорошо... А если попробовать выводить результаты на ЖКИ один раз в пять секунд, например? Попробую достучаться до автора библиотеки, может он что-то подскажет. Обидно, каких-то полшага осталось до опупея, и вот так покидать тему...
Или если попробовать другой ЖКИ? Может какой-нибудь популярный маленький OLED? И у меня есть в наличии модуль графического ЖКИ с Али, Нокиа 5110...
Нет у меня такого дисплея. Есть с i2c переходником. Подключил. Увидел глюки связанные с зависаниями программы в разных местах, в том числе затык вывода в сом порт. Отключил почти весь вывод, кроме вывода bmp SpO2, которые идут только на найденный удар сердца. Пришлось поиграться с задержкой в конце цикла - тоже влияла на результат. В общем вот так как то работает, но если палец убрать на долго - зависает. Причину найти некогда. Пока работает так- нажал ресет, положил палец на сенсор смотришь долго. Следующий раз опять начать с ресета. Зато срабатывает каждый раз. Что то в алгоритме надо менять. Но это не раньше чем через пару недель.
#include <Arduino.h>
#include <math.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include "MAX30100.h"
MAX30100* pulseOxymeter;
LiquidCrystal_I2C lcd(0x27,16,2);
void setup() {
Wire.begin();
Serial.begin(115200);
Serial.println("Pulse oxymeter test!");
lcd.init(); // initialize the lcd
// Print a message to the LCD.
lcd.backlight();
lcd.setCursor(3,0);
lcd.print("Pulse oxymeter");
lcd.setCursor(5,1);
lcd.print("test!");
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) );
}
Отлично... Послезавтра проверю на своём. Если всё повторится и в моём случае, то я даже знаю, как сделать так, чтобы уже с этим вариантом прошивки можно было пользоваться устройством по прямому назначению. Модуль клеится на толкатель большой тактильной нефиксируемой кнопки (12 х 12), которая запаяна на основную плату, жестко укреплённую в корпусе. Питание заведено через кнопку. В такой конфигурации железным образом обходятся текущие недостатки кода. Главное, чтобы была стабильность в той его части, где система работает адекватно. Если так оно и окажется, то на крайняк можно ограничиться и таким "железным костылём". Пружинный зажим в виде нежной прищепки завершит конструкцию...
Ха... У меня ЖКИ подключен напрямую, без И2Ц-переходника... Прошил в режиме "а вдруг?!" - квадратики кажет. И переходника такого нет в наличии. Ну что же, попробую самостоятельно адаптировать под свою схему...
то после загрузки (после пропадания слова "Инициализация") в подавляющем большинстве случаев вижу пустой экран - как я понимаю, система ждёт, когда клиент положит палец на сенсор и можно будет захватить пульс. Включается светодиод сенсора, кладу палец - всё адекватно работает. Вроде не виснет... Даже если снять - погулять - положить снова (не выключая питание) - пока не вижу, чтобы висло. Выход на показания и сами показания вполне адекватны (картина полностью повторяет FlexiPlot: сильный прижим, слабый прижим, холодные/тёплые пальцы). Продолжаю тестирование...
Вот рабочий скетч для 1602 без И2Ц-переходника:
#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);
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 )
{
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(" ");
/*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("}");
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) );
}
Сделал, как вы пишете. Вижу на экране своё приглашение "Put warm finger in the hole ...", но после того, как кладу палец, вместо появления строчек с показаниями, приглашение начинает мигать в такт с обновлением экрана:
...
...
}
else
lcd.setCursor(0,0);
lcd.print("Put warm finger");
lcd.setCursor(0,1);
lcd.print("in the hole ...");
...
...
Попробовал поиграться со скобками, но получаю стабильный отлуп от компилятора. Тут надо ПОНИМАТЬ, что делаешь... "Пуш-н-си" не прокатывает. Это как кодовый замок подбором открывать...
зы: Увеличил задержку в самом конце скетча до 15 мс. Вроде как ещё стабильнее стало работать. Когда 9 мс было, иногда не появлялись строки с показаниями, несмотря на то что и палец тёплый, и разные прижимы, и т.п. Не часто, но достаточно регулярно получалась такая ситуация. Тестирую 15 мс...
Смотрите, тут вроде как зависимость непонятная нащупалась... Но пока не точно... Сразу после прошивки несколько десятков циклов прибор загружается и работает исправно. Но потом начинаются пустые строки после загрузки, и как ты палец туда ни прикладывай - пусто на экране. Такое впечатление, что там в еепроме, или ещё где-то, записывается кол-во пусков, и по достижению определённого кол-ва ... ))))
Ну я не знаю, что ещё придумать на этот счёт... )) Странно всё это. Может ещё какой фактор такое поведение вызывает. Может датчик перегревается от частых перезапусков... Но тогда бы перепрошивка НЕ помогала: я ж его сразу же начинаю пытать - не жду, пока типа остынет... Фигня какая-то... Иногда в строке пульса выпадает оверфлоу (ovf); а в строке сатурации иногда пишет inf...
Может просто мучать его меньше надо. Но лучше, конечно, найти причину, и сделать всё по фэн-шую... Но это дело такое...
То же самое. Видно, что система чует приложенный палец - надпись начинает подмигивать примерно раз в секунду. Но строки с показаниями не появляются. Без приложенного пальца приглашение светится стационарно.
Ннну я с утречка, по холодку, отыграл на исходную - туда, с чего вчера с утречка же и начинал. Взял за основу ваш скетч, повыкосил-повставлял про ЖКИ, прошил - всё работает, ничего не виснет. Зависалово началось вчера - ВРОДЕ КАК - после того, как попытался почистить и привести в красоту-порядок сам текст скетча: убрал всё про компорт, всё закомменченное, красиво расставил строчки, абзацы и всё такое. Вот, и якобы именно после этой "генеральной уборки" и началась свистопляска, описанная чуть выше по ленте. Линейная логика говорит о том, что во время этой "уборки" я "убрал" что-то критичное. Может скобку (хотя тогда ругался бы компилятор), а может стабильность работы крайнего варианта скетча зависит от наличия строк, относящихся к выводу информации в компорт. Склоняюсь к последнему. Ну, может ещё какой-то третий вариант, мне неизвестный и непонятный...
В общем, пока скетч не трогаю - терзаю прошитое им железо: включаю-выключаю, тыкаю разные пальцы, смотрю за поведением... Вечером доложу о результатах.
Но нет, всё получилось намного быстрее. Фигня... Всё то же самое: пустой экран, в строке BPM пишет либо "nan", либо "ovf", либо непонятные значения. На пальцы не реагирует. Один раз с утра, сразу после первой прошивки (см. предыдущее сообщение) нормально всё сработало - и пошли беспросветные глюки...
В общем, пока не могу подтвердить успешность текущего варианта скетча. У меня он работает крайне нестабильно.
Железо:
ProMini 328, 8 MHz, 3V3;
USB/UART bridge (3V3/5V0), configured as 3V3;
LCD 1602, no I2C adapter;
18650, текущее напряжение 3V6;
Напряжение после стабилизатора Ардуины 3,3 В. Эта же Ардуина в других проектах работает без замечаний.
#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) );
}
Но если 16 МГц брать, то питание другое надо. Или дс-дс преобразователь ставить...
Буду пробовать!
зы: Т.е. отсылать сплошным потоком (сколько-то раз в секунду) в сериал точки ТРЁХ графиков - 8 МГц такта вроде как вполне себе хватает. Но вот если попробовать вместо (не "вместе с", а именно ВМЕСТО) этого натурального "числопада" отсылать всего каких-то несчастных ДВА ЧИСЛА В СЕКУНДУ в ЖКИ - 8 МГц такта уже не хватает... И это при том, что означенный ЖКИ имеет собственный контроллер для решения своих специфических задач, который призван максимально разгружать внешний микропроцессор... НЕ понимаю! ))
У меня вот такой датчик. На нём два стабилизатора и питать его надо от 5 вольт. 3.3 вольта при проходе через первый стабилизатор гробятся , но остаются в пределах спецификации. Так что Ваши слова по dc-dc меня напрягли, но после проверки отпустило. 5 вольт питания для него это хорошо.
Ваш датчик (как и мой), скорее всего, допускают питание до 15 В. Я читал ДШ на их стабилизаторы, но точно не помню сейчас. Там достаточно высокое входное напряжение допускается.
Я до сего момента питался от 18650-аккумулятора напряжением 3,7 В. Все напряжения на выходах стабилизаторов модуля датчика и ардуины соответствовали спецификациям (3,3 В, 1,8 В).
А вот что там у него не срастается с ЖКИ... Может как раз ЖКИ надо от пяти вольт питать? Может это контроллеру ЖКИ трёх вольт не хватает??? На нём нихрена не написано... Подсветка от 3,3 работает нормально; контраст нормальный, символы ярко-белые, фон ярко-синий... Пойду погуглю это дело...
Хотя, если бы контроллеру ЖКИ не хватало питания, то этот же экземпляр ЖКИ не работал бы нормально с другой прошивкой (с библиотекой oxullo) и с тем же аккумулятором... Если бы та библиотека ещё и с датчиком нормально работала... Там очень плохо определяется пульс, но ЖКИ при этом не вис ни разу.
Сверху вниз: китаец первый, китаец второй, убитый перегревом европеец (сам паял европейский чип с диджикея на самодельную плату).
Первый китаец демонстрирует шум по красному каналу амплитудой до 2000 попугаев. Хаотический.
Второй китаец шумит гораздо меньше, примерно одинаково по обоим каналам, но всё равно, картина далека от тех скринов, что в авторской статье. Там у него всё гладко.
Европейца убил по недосмотру, неправильными настройками ик-станции, дал на неё ~ 350 .. 400 С. Корпус поплыл, линзы остались без видимых изменений. И2Ц остался полностью живой, чип видится контроллером, коммуницируется, но в установившемся режиме сигналы по обоим каналам равны нулю.
Печаль-беда-непруха...
Владельцам модулей - вот ссылка на дистрибутив авторского плоттера, для унификации тестирования:
На скорости 115200 никого переполнения буфера не возникает. Скорость оборота буфера легко проверить включив мониториг времени вывода строк. Ещё раз повторю, к использованию 100 герц нет никаких предпосылок, кроме красивого числа.
Вывод на LCD не зависит от времени цикла. При выполнении программы глюки LCD связаны с тем, что команды вывода на экран даются раньше, чем LCD готов их воспринимать. Например lcd.clear(); может выполняться до секунды на некоторых дисплеях. Поэтому после каждой команды необходимо проверять занят дисплей или нет. Сейчас этого не делают. И имеют проблемы. Например Команда установки курсора выполняется около 40 мкс. Если начать писать после неё чуть раньше, то получим глюк. Попробуйте вставить delayMicroseconds(40); после каждой команды LCD и посмотреть что получится.
В варианте с ЖКИ вывод в serial ВООБЩЕ не нужен. Компорт интересен ТОЛЬКО при отладке. Там вообще можно закомментить всё подчистую - и для плоттера, и для монитора. Строгоновский скетч интересен мне прежде всего математической обработкой данных. Которая, в отличие от других библиотек, демонстрирует видимую адекватность показаний пульса, и, как следствие - сатурации. Я просто не в курсе, где именно у системы находится узкое место в смысле вывода данных: размер ли это буфера, кол-во выводимых в сериал строк/символов, бодрейт, или вообще - тактовая частота процессора Ардуины (у меня, кстати, 8 МГц х 3,3В). Или всё вместе, в комплексе.
Пробовал по-всякому. Добавлял задержки, комментил компорт, снимал мост усб/уарт, менял датчики... Ничего не помогает. Система работает нестабильно, эксплуатировать её невозможно. Когда вывод идёт чисто в компорт (залил исходный скетч) - всё работает вполне предсказуемо и ПОЧТИ стабильно. Иногда бывают РЕДКИЕ затыки (несколько раз в день, а это сотни пусков), которые лечатся кнопкой ресет или переподключением питания. А с ЖКИ - через пять на шестой раз сработает, поработает несколько минут, выводя адекватный пульс и сатурацию, и зависнет. Наглухо: стационарные цифры на ЖКИ. Проблема, судя по всему, именно в ЖКИ. Точнее не в железе ЖКИ, потому что с другим скетчем этот же экземпляр работает без замечаний, а в программной части, которая с ним общается. Какой-то нюанс не учтён. Надеюсь, что уважаемое сообщество всё-таки разберётся, в чём здесь кроется проблема, и найдёт практическое её решение.
Ниже привожу "рабочие" скетч и его библиотеку - кавычки в том смысле, что они нормально работают с указанным ЖКИ (строки показаний пульса и сатурации стабильно появляются после загрузки, а сами показания в процессе работы никогда не виснут), но НЕнормально - с датчиком 30100 (эти самые "стабильно выводимые" результаты пульса и сатурации - НЕадекватны, а потому никому не нужны):
Библиотека: https://mega.nz/file/xc9TFSob#KA6Uf6nwjmuPoq16a_Yz3eDvKmaVjUYiirozr6cc3UE
Ну хорошо... А если попробовать выводить результаты на ЖКИ один раз в пять секунд, например? Попробую достучаться до автора библиотеки, может он что-то подскажет. Обидно, каких-то полшага осталось до опупея, и вот так покидать тему...
Или если попробовать другой ЖКИ? Может какой-нибудь популярный маленький OLED? И у меня есть в наличии модуль графического ЖКИ с Али, Нокиа 5110...
Питания может не хватает на оба девайса ?
clear() - долгая операция, лучше поверху старого делать prit()
Нет у меня такого дисплея. Есть с i2c переходником. Подключил. Увидел глюки связанные с зависаниями программы в разных местах, в том числе затык вывода в сом порт. Отключил почти весь вывод, кроме вывода bmp SpO2, которые идут только на найденный удар сердца. Пришлось поиграться с задержкой в конце цикла - тоже влияла на результат. В общем вот так как то работает, но если палец убрать на долго - зависает. Причину найти некогда. Пока работает так- нажал ресет, положил палец на сенсор смотришь долго. Следующий раз опять начать с ресета. Зато срабатывает каждый раз. Что то в алгоритме надо менять. Но это не раньше чем через пару недель.
Отлично... Послезавтра проверю на своём. Если всё повторится и в моём случае, то я даже знаю, как сделать так, чтобы уже с этим вариантом прошивки можно было пользоваться устройством по прямому назначению. Модуль клеится на толкатель большой тактильной нефиксируемой кнопки (12 х 12), которая запаяна на основную плату, жестко укреплённую в корпусе. Питание заведено через кнопку. В такой конфигурации железным образом обходятся текущие недостатки кода. Главное, чтобы была стабильность в той его части, где система работает адекватно. Если так оно и окажется, то на крайняк можно ограничиться и таким "железным костылём". Пружинный зажим в виде нежной прищепки завершит конструкцию...
Ха... У меня ЖКИ подключен напрямую, без И2Ц-переходника... Прошил в режиме "а вдруг?!" - квадратики кажет. И переходника такого нет в наличии. Ну что же, попробую самостоятельно адаптировать под свою схему...
Нет, не получится. Достаточно заменить библиотеку на Вашу и прописать правильно инициализацию. В остальном разницы нет.
Ну вроде как победил... Склеил из двух один...
Поскольку у вас присутствует условие
if( result.pulseDetected == true )
то после загрузки (после пропадания слова "Инициализация") в подавляющем большинстве случаев вижу пустой экран - как я понимаю, система ждёт, когда клиент положит палец на сенсор и можно будет захватить пульс. Включается светодиод сенсора, кладу палец - всё адекватно работает. Вроде не виснет... Даже если снять - погулять - положить снова (не выключая питание) - пока не вижу, чтобы висло. Выход на показания и сами показания вполне адекватны (картина полностью повторяет FlexiPlot: сильный прижим, слабый прижим, холодные/тёплые пальцы). Продолжаю тестирование...
Вот рабочий скетч для 1602 без И2Ц-переходника:
Добавьте else и печатайте, что нет пульса. Будет не пустой экран.
Сделал, как вы пишете. Вижу на экране своё приглашение "Put warm finger in the hole ...", но после того, как кладу палец, вместо появления строчек с показаниями, приглашение начинает мигать в такт с обновлением экрана:
То же самое. Видно, что система чует приложенный палец - надпись начинает подмигивать примерно раз в секунду. Но строки с показаниями не появляются. Без приложенного пальца приглашение светится стационарно.
Ннну я с утречка, по холодку, отыграл на исходную - туда, с чего вчера с утречка же и начинал. Взял за основу ваш скетч, повыкосил-повставлял про ЖКИ, прошил - всё работает, ничего не виснет. Зависалово началось вчера - ВРОДЕ КАК - после того, как попытался почистить и привести в красоту-порядок сам текст скетча: убрал всё про компорт, всё закомменченное, красиво расставил строчки, абзацы и всё такое. Вот, и якобы именно после этой "генеральной уборки" и началась свистопляска, описанная чуть выше по ленте. Линейная логика говорит о том, что во время этой "уборки" я "убрал" что-то критичное. Может скобку (хотя тогда ругался бы компилятор), а может стабильность работы крайнего варианта скетча зависит от наличия строк, относящихся к выводу информации в компорт. Склоняюсь к последнему. Ну, может ещё какой-то третий вариант, мне неизвестный и непонятный...
В общем, пока скетч не трогаю - терзаю прошитое им железо: включаю-выключаю, тыкаю разные пальцы, смотрю за поведением... Вечером доложу о результатах.
Но нет, всё получилось намного быстрее. Фигня... Всё то же самое: пустой экран, в строке BPM пишет либо "nan", либо "ovf", либо непонятные значения. На пальцы не реагирует. Один раз с утра, сразу после первой прошивки (см. предыдущее сообщение) нормально всё сработало - и пошли беспросветные глюки...
В общем, пока не могу подтвердить успешность текущего варианта скетча. У меня он работает крайне нестабильно.
Железо:
ProMini 328, 8 MHz, 3V3;
USB/UART bridge (3V3/5V0), configured as 3V3;
LCD 1602, no I2C adapter;
18650, текущее напряжение 3V6;
Напряжение после стабилизатора Ардуины 3,3 В. Эта же Ардуина в других проектах работает без замечаний.
Ну вот. У меня 16 МГц и то не хватает скорости. Я собираюсь на блюпил перевести - там 72 МГц. И математику считает быстрее.
Т.е. причина в низкой тактовой частоте Ардуины?
Но если 16 МГц брать, то питание другое надо. Или дс-дс преобразователь ставить...
Буду пробовать!
зы: Т.е. отсылать сплошным потоком (сколько-то раз в секунду) в сериал точки ТРЁХ графиков - 8 МГц такта вроде как вполне себе хватает. Но вот если попробовать вместо (не "вместе с", а именно ВМЕСТО) этого натурального "числопада" отсылать всего каких-то несчастных ДВА ЧИСЛА В СЕКУНДУ в ЖКИ - 8 МГц такта уже не хватает... И это при том, что означенный ЖКИ имеет собственный контроллер для решения своих специфических задач, который призван максимально разгружать внешний микропроцессор... НЕ понимаю! ))
У меня вот такой датчик. На нём два стабилизатора и питать его надо от 5 вольт. 3.3 вольта при проходе через первый стабилизатор гробятся , но остаются в пределах спецификации. Так что Ваши слова по dc-dc меня напрягли, но после проверки отпустило. 5 вольт питания для него это хорошо.
Ваш датчик (как и мой), скорее всего, допускают питание до 15 В. Я читал ДШ на их стабилизаторы, но точно не помню сейчас. Там достаточно высокое входное напряжение допускается.
Я до сего момента питался от 18650-аккумулятора напряжением 3,7 В. Все напряжения на выходах стабилизаторов модуля датчика и ардуины соответствовали спецификациям (3,3 В, 1,8 В).
А вот что там у него не срастается с ЖКИ... Может как раз ЖКИ надо от пяти вольт питать? Может это контроллеру ЖКИ трёх вольт не хватает??? На нём нихрена не написано... Подсветка от 3,3 работает нормально; контраст нормальный, символы ярко-белые, фон ярко-синий... Пойду погуглю это дело...
Хотя, если бы контроллеру ЖКИ не хватало питания, то этот же экземпляр ЖКИ не работал бы нормально с другой прошивкой (с библиотекой oxullo) и с тем же аккумулятором... Если бы та библиотека ещё и с датчиком нормально работала... Там очень плохо определяется пульс, но ЖКИ при этом не вис ни разу.
Установил авторский плоттер - тот, что из статьи. Получил тестер модулей на предмет их пригодности к измерениям.
https://mega.nz/file/oQ0RRRKJ#qMwcMd5j3ZLIvx-vV68hOADskvDtykn236KUqzmIHr4
https://mega.nz/file/tYthRZKS#ffE6Zguy1aPh97nnET5cbvrsrgBvZlvGVc8q3bNJLEc
https://mega.nz/file/JF1VzTJL#SKq1Bnxb42iKblnZ1By7zeUNQVnVnEPl1qbd3Hsoj0g
Сверху вниз: китаец первый, китаец второй, убитый перегревом европеец (сам паял европейский чип с диджикея на самодельную плату).
Первый китаец демонстрирует шум по красному каналу амплитудой до 2000 попугаев. Хаотический.
Второй китаец шумит гораздо меньше, примерно одинаково по обоим каналам, но всё равно, картина далека от тех скринов, что в авторской статье. Там у него всё гладко.
Европейца убил по недосмотру, неправильными настройками ик-станции, дал на неё ~ 350 .. 400 С. Корпус поплыл, линзы остались без видимых изменений. И2Ц остался полностью живой, чип видится контроллером, коммуницируется, но в установившемся режиме сигналы по обоим каналам равны нулю.
Печаль-беда-непруха...
Владельцам модулей - вот ссылка на дистрибутив авторского плоттера, для унификации тестирования:
https://github.com/xcoder123/FlexiPlot/releases
Проверьте свои модули, поделИтесь скринами!
Как установить плотер, подскажите