ARDUINO Перевод ЭКГ модуля (ad8232) в ЭМГ

Kelll31

★✩✩✩✩✩✩
29 Дек 2018
25
24
Где то
Сап всем! Сегодня я расскажу про то как я перевёл ЭКГ модуль (ad8232) в ЭМГ. Первое что нам надо это ЭКГ модуль, купил я его на али (так дешевле). На глаза попался модуль ad8232, купил его с (офигенными, силиконовыми) электродами за 480 руб. Покупал здесь. Подключил по первой попавшейся схеме (ардуино/электроды) :
----------------------------------------------
GND
- подключается к выводу GND
3,3V
- подключается к выводу 3,3V
OUTPUT
- подключается к выводу A0
L0-
- подключается к выводу 11
L0+
- подключается к выводу 10
----------------------------------------------
R
в начало мышцы
COM в середину мышцы
L в конец мышцы
Особенности : расстояние между краями электродов должно быть минимальным (у меня примерно 10 мм) но они не должны касаться.
----------------------------------------------
Как датчик сердечного пульса он ничего, но как ЭМГ отстой т.к люто шумит. Поэтому я решил написать код с алгоритмом очистки. Первое что я заметил, это то что при холостом ходе (мышечная активность не зарегистрирована) датчик выдаёт треугольный сигнал в районе + - 10 единиц (каких хз)))). А при мышечной активности примерно + - 30-45 единиц. Это довольно ноесно т.к поиск мышечной активности сводится в одну строчку кода (пока что))). Потом я заметил что датчик выдаёт не равный треугольный сигнал. Т.к иногда датчик меняет значение "Ступеньками". Поэтому я написал алгоритм очистки на основе запоминания 3-х последних значений, записывая их в массив. Стало лучше, но не до конца. Сигнал стал довольно ровным, но не до конца. И я написал ещё один алгоритм очистки на основе первого, но используя только 2 последних значения. В конце концов, ОНО ЗАРАБОТАЛО!! P.S спасибо за прочтение. P.P.S Код ниже.
C++:
#define korector 12

int val[3]; // Первый этап очистки (Массив)
byte index; // Первый этап очистки (Индекс)

int val_2[2]; // Второй этап очистки (Массив)
byte index_2; // Второй этап очистки (Индекс)


int X; // Первое
int Y; // Второе
boolean ismenilos; // Корректирующий флаг
boolean flex;
boolean flex_2;

void setup() {
  Serial.begin(9600);
  pinMode(10, INPUT);
  pinMode(11, INPUT);
}

void loop() {
  proverka();
  logika();
  chistka_1();
  Serial.println(flex_2);
}
void proverka() {
  if ((digitalRead(10) == 1) || (digitalRead(11) == 1)) {
    Serial.println('Opa! Ne podkluchil elektrodi');
  }
}
void chistka_1() {
  if (index > 2) index = 0; // переключаем индекс с 0 до 2 (0, 1, 2, 0, 1, 2…)
  val[index] = ismenilos; // записываем значение с датчика в массив
  index = index + 1;
  if (index_2 > 1) index_2 = 0; // переключаем индекс с 0 до 1 (0, 1, 0, 1…)
  val_2[index_2] = flex; // записываем значение с датчика в массив
  index_2 = index_2 + 1;
  X = Y;
  Y = analogRead(A0);

}
void logika() {
  if ((X >= Y + korector) || (X <= Y - korector)) {
    ismenilos = true;
    if ((val[0] + val[1] + val[2] >= 1)) {
      flex = true;
      if (val_2[0] + val_2[1] >= 1) {
        flex_2 = true;
      }
      else {
        flex_2 = false;
      }
    }
    else {
      flex = false;
    }
  }
  else {
    ismenilos = false;
  }
}
 
  • Лойс +1
Реакции: NikOdn

Fantonrko

✩✩✩✩✩✩✩
29 Май 2019
4
0
Здравствуйте, вы еще занимаетесь разработкой подобного ? У меня есть парочку вопросов, хотелось бы услышать ответ)
 

Fantonrko

✩✩✩✩✩✩✩
29 Май 2019
4
0
К сожалению, ваш код не работает. Значения либо 1, либо 25705. И, кстати, не ясно, почему в массив нужно записывать значения TRUE или FALSE
Всё работает, но правда есть небольшие проблемы. Нужно ноги держать под собой, желательно не касаясь ничего другого помимо стула. провода не везде одинаковые, так как платы с китая, цвета бывают разные
 
Всё работает, но правда есть небольшие проблемы. Нужно ноги держать под собой, желательно не касаясь ничего другого помимо стула. провода не везде одинаковые, так как платы с китая, цвета бывают разные
Не совсем понимаю, как оно должно работать, если в Serial выводится переменная boolean. Данные с A0 записываются в переменную Y, и больше никаких действий не происходит.
Можете показать, как оно у вас работало?

UPD: понял, программа работает, как переключатель вкл/выкл. Переключение по сокращению мышцы. Я-то думал, она аналоговый сигнал фильтрует и переваривает в удобный вид, например, для пропорционального управления сервой
 
Изменено:

Fantonrko

✩✩✩✩✩✩✩
29 Май 2019
4
0
Не совсем понимаю, как оно должно работать, если в Serial выводится переменная boolean. Данные с A0 записываются в переменную Y, и больше никаких действий не происходит.
Можете показать, как оно у вас работало?

UPD: понял, программа работает, как переключатель вкл/выкл. Переключение по сокращению мышцы. Я-то думал, она аналоговый сигнал фильтрует и переваривает в удобный вид, например, для пропорционального управления сервой
увы, но нет. Я бы лично мог попробовать сделать такое, но всё же, там так же по типу булевых, ибо это же ЭКГ датчик, у него на плате фильтрация совсем другая и считывает он то что ему нужно
 
увы, но нет. Я бы лично мог попробовать сделать такое, но всё же, там так же по типу булевых, ибо это же ЭКГ датчик, у него на плате фильтрация совсем другая и считывает он то что ему нужно
Ну, насчёт ЭКГ-не ЭКГ: я тут купил Grove EMG Detector. Вроде специализированный датчик для EMG, стоит 3к с лишним. А по факту - то же самое, даже хуже. Сигнал с мышцы я получить не смог, зато прекрасно считывает кардиограмму. Или, может, я чего не понимаю.
 

Fantonrko

✩✩✩✩✩✩✩
29 Май 2019
4
0
Ну, насчёт ЭКГ-не ЭКГ: я тут купил Grove EMG Detector. Вроде специализированный датчик для EMG, стоит 3к с лишним. А по факту - то же самое, даже хуже. Сигнал с мышцы я получить не смог, зато прекрасно считывает кардиограмму. Или, может, я чего не понимаю.
Мне пришлось вручную писать код для триггера по экг, так же можешь попробовать, нужно всего лишь провести небольшую фильтрацию аналогового сигнала и сам заметишь что да как где меняется
 

Kelll31

★✩✩✩✩✩✩
29 Дек 2018
25
24
Где то
Здравствуйте, вы еще занимаетесь разработкой подобного ? У меня есть парочку вопросов, хотелось бы услышать ответ)
Здравствуйте! Данный проект находится в заморозке т.к он малорентабелен, но я с радостью сделал OpenSourse для всех.
P.s этот код предназначался для этого проекта.
 

Kelll31

★✩✩✩✩✩✩
29 Дек 2018
25
24
Где то
Вот более и менее допиленный огрызок логики.
C++:
 if (SignalSDatchika >= korector) {
    Srednie_1 = (val_0[0] + val_0[1] + val_0[2]) / 3;
  }

  if (val_Srednie_1[0] >= 1 || val_Srednie_1[1] >= 1 || val_Srednie_1[2] >= 1) {
    Srednie_2 = (val_Srednie_1[0] + val_Srednie_1[1] + val_Srednie_1[2]) / 3;
  }
  Srednie_2 = map(Srednie_2, 0, 820, 0, 255);
 

Salat

✩✩✩✩✩✩✩
25 Авг 2021
3
0
Доброго времени суток!
Не уверен что через столько времени вы ответите, но всё же. Хочу задать пару вопросов. Как различить электроды? Китай заботливо оставил одни и те же буквы на них. Второе : на сколько я понимаю, в компорт должен выходить график, но после подключения электродов график прямой, и время от времени скачет от 0 до 10 попугаев). Так и должно быть?

З.Ы. я не знаю что за значения по этому попугаи
 

Bruzzer

★★★✩✩✩✩
23 Май 2020
312
100
@Salat,
Втыкаете кабель для электродов в разъем на плате, и позваниваете с подписанными контактами на плате. На плате по ссылке из первого поста контакты на плате есть и подписаны. Если на вашей плате контакты не подписаны или их нет, тогда ваши затруднения понятны.
 
  • Лойс +1
Реакции: Kelll31