ECG simulador con Arduino

Qué tal amigos, hoy vengo a pedirles su colaboración, estoy haciendo un simulador ECG con la placa Arduino uno, en la simulación todo me sale perfecto como es de esperar, en las pruebas con el osciloscopio me funciona pero mi objetivo es visualizar dicha señal en monitor de signos vitales pero al conectarlo me sale lo que pueden apreciar en las siguientes imágenes.


SIMULACION EN PROTEUS/VISUALIZACION EN MONITOR DE SIGNOS VITALES
Screenshot_1.png 1569763805039.png
 
Qué tal amigos, hoy vengo a pedirles su colaboración, estoy haciendo un simulador ECG con la placa Arduino uno, en la simulación todo me sale perfecto como es de esperar, en las pruebas con el osciloscopio me funciona pero mi objetivo es visualizar dicha señal en monitor de signos vitales pero al conectarlo me sale lo que pueden apreciar en las siguientes imágenes. . . . .

¿ Te da la impresión que sin analizar la programación alguien podrá opinar seriamente ?

Comprime con Winrar o Winzip el archivo Proteus y lo subes al Foro
 
Código:
#include <Wire.h>
int frecuencia = 0;
int lookup = 0;
#include <Adafruit_MCP4725.h>
                          
unsigned int  Bpm;                                       





//This is the I2C Address of the MCP4725, by default (A0 pulled to GND).
//Please note that this breakout is for the MCP4725A0.
#define MCP4725_ADDR 0x60   

//int lookup = 0;//varaible for navigating through the tables


int sintab2[543] =
{
  939, 940, 941, 942, 944, 945, 946, 947, 951, 956,
962, 967, 973, 978, 983, 989, 994, 1000, 1005, 1015,
1024, 1034, 1043, 1053, 1062, 1075, 1087, 1100, 1112, 1121,
1126, 1131, 1136, 1141, 1146, 1151, 1156, 1164, 1172, 1179,
1187, 1194, 1202, 1209, 1216, 1222, 1229, 1235, 1241, 1248,
1254, 1260, 1264, 1268, 1271, 1275, 1279, 1283, 1287, 1286,
1284, 1281, 1279, 1276, 1274, 1271, 1268, 1266, 1263, 1261,
1258, 1256, 1253, 1251, 1246, 1242, 1237, 1232, 1227, 1222,
1218, 1215, 1211, 1207, 1203, 1199, 1195, 1191, 1184, 1178,
1171, 1165, 1159, 1152, 1146, 1141, 1136, 1130, 1125, 1120,
1115, 1110, 1103, 1096, 1088, 1080, 1073, 1065, 1057, 1049,
1040, 1030, 1021, 1012, 1004, 995, 987, 982, 978, 974,
970, 966, 963, 959, 955, 952, 949, 945, 942, 939,
938, 939, 940, 941, 943, 944, 945, 946, 946, 946,
946, 946, 946, 946, 946, 947, 950, 952, 954, 956,
958, 960, 962, 964, 965, 965, 965, 965, 965, 965,
963, 960, 957, 954, 951, 947, 944, 941, 938, 932,
926, 920, 913, 907, 901, 894, 885, 865, 820, 733,
606, 555, 507, 632, 697, 752, 807, 896, 977, 1023,
1069, 1127, 1237, 1347, 1457, 2085, 2246, 2474, 2549, 2595,
2641, 2695, 3083, 3135, 3187, 3217, 3315, 3403, 3492, 3581,
3804, 3847, 3890, 3798, 3443, 3453, 3297, 3053, 2819, 2810,
2225, 2258, 1892, 1734, 1625, 998, 903, 355, 376, 203,
30, 33, 61, 90, 119, 160, 238, 275, 292, 309,
325, 343, 371, 399, 429, 484, 542, 602, 652, 703,
758, 802, 838, 856, 875, 895, 917, 938, 967, 1016,
1035, 1041, 1047, 1054, 1060, 1066, 1066, 1064, 1061, 1058,
1056, 1053, 1051, 1048, 1046, 1043, 1041, 1038, 1035, 1033,
1030, 1028, 1025, 1022, 1019, 1017, 1014, 1011, 1008, 1006,
1003, 1001, 999, 998, 996, 994, 993, 991, 990, 988,
986, 985, 983, 981, 978, 976, 973, 971, 968, 966,
963, 963, 963, 963, 963, 963, 963, 963, 963, 963,
963, 963, 963, 963, 963, 963, 963, 963, 963, 963,
964, 965, 966, 967, 968, 969, 970, 971, 972, 974,
976, 978, 980, 983, 985, 987, 989, 991, 993, 995,
997, 999, 1002, 1006, 1011, 1015, 1019, 1023, 1028, 1032,
1036, 1040, 1045, 1050, 1055, 1059, 1064, 1069, 1076, 1082,
1088, 1095, 1101, 1107, 1114, 1120, 1126, 1132, 1141, 1149,
1158, 1166, 1173, 1178, 1183, 1188, 1193, 1198, 1203, 1208,
1214, 1221, 1227, 1233, 1240, 1246, 1250, 1254, 1259, 1263,
1269, 1278, 1286, 1294, 1303, 1309, 1315, 1322, 1328, 1334,
1341, 1343, 1345, 1347, 1349, 1351, 1353, 1355, 1357, 1359,
1359, 1359, 1359, 1359, 1358, 1356, 1354, 1352, 1350, 1347,
1345, 1343, 1341, 1339, 1336, 1334, 1332, 1329, 1327, 1324,
1322, 1320, 1317, 1315, 1312, 1307, 1301, 1294, 1288, 1281,
1275, 1270, 1265, 1260, 1256, 1251, 1246, 1240, 1233, 1227,
1221, 1214, 1208, 1201, 1194, 1186, 1178, 1170, 1162, 1154,
1148, 1144, 1140, 1136, 1131, 1127, 1123, 1118, 1114, 1107,
1099, 1090, 1082, 1074, 1069, 1064, 1058, 1053, 1048, 1043,
1038, 1034, 1029, 1025, 1021, 1017, 1013, 1009, 1005, 1001,
997, 994, 990, 991, 992, 994, 996, 997, 999, 998,
997, 996, 995, 994, 993, 991, 990, 989, 989, 989,
989, 989, 989, 989, 988, 986, 984, 983, 981, 980,
982, 984, 986, 988, 990, 993, 995, 997, 999, 1002,
1005, 1008, 1012
};


void setup()
{
  Wire.begin();
}
 
void loop()
{
//frecuencia = analogRead(A0);
//delayMicroseconds(analogRead(A0));

  Wire.beginTransmission(MCP4725_ADDR);
  Wire.write(64);                     // cmd to update the DAC
  Wire.write(sintab2[lookup] >> 4);        // the 8 most significant bits...
  Wire.write((sintab2[lookup] & 15) << 4); // the 4 least significant bits...
  Wire.endTransmission();
  lookup = (lookup + 1) & 511;
 



 frecuencia = analogRead(0);
 delayMicroseconds(analogRead(A0));


Bpm = map(analogRead(0),0,1023,120,30);


}
Archivo proteus
 

Adjuntos

  • lasalvacion.zip
    22 KB · Visitas: 103
Así a bulto tienes mal A0 y no espera nada. "Vomita" la tabla que simula el pulso a alta velocidad.

Si no, pon un valor fijo a delaymiliseconds y vas ajustando
 
En el simulador tiene el A0 pero en el DAC que adquirí no lo tiene (A0 se usa para direccionar cuando se desea usar dos DAC en el mismo bus entiendo), de igual forma el osciloscopio me muestra la siguiente imagen.
Respecto al A0 del arduino se le doy un valor fijo de retraso no puedo simular la aceleración del pulso (taquicardia y bracardia).

IMG_20190926_174603.jpg
 
Última edición:
Tienes una tabla de 543 valores que deber reproducir cierto BPM, entonces si eliges con el potenciometro algo entre 30 y 120 BPM o latidos x minuto pues debes ser fiel a eso.
30 BPM implica son 30 ppm = 30 / 60 pulsos / seg = 1/2 Hz
120 BPM = 120/60 pulsos/seg = 2 Hz
Si vemos el período debemos invertir
30 BPM => T = 2 seg
120 BPM => T = 0.5
Y debes insertar 543 muestras en esos períodos o sea.
Tu intervalo debe ser para 30 Bpm => 2.0 / 543 = ‭0,00368324 seg = 3683 useg
Tu intervalo debe ser para 120 Bpm => 0.5 / 543 = ‭9,20810313 10-4 seg = 920 useg

Entonces llevado a tu código
Código:
frecuencia = analogRead(0);
Bpm = map(analogRead(0),0,1023,120,30);
// la cuenta es 60 x 1000000 / 543 =  110497.237
long int intervalo = 110497 / Bpm;  // en microsegundos
delayMicroseconds(intervalo);  //

Ahora esta cuenta no debes hacerla a cada momento. Te recomiendo poner un pulsador para que cuando se presione, se efectúe la modificacion del intervalo y los Bpm sino alterará el sampleado de tu DAC.
 
Qué tal amigos, le añadí una pantalla LCD 16x2 para poder visualizar el valor del BPM que estoy enviando al monitor pero ahora la señal me sale mal, sin la LCD la señal se visualiza perfecta pero con ella ni se parece a un ECG.


Código:
#include <Wire.h>//Include the Wire library to talk I2C
int frecuencia = 0;
int lookup = 0;
#include <Adafruit_MCP4725.h>
#include <Wire.h>                
#include <LiquidCrystal_I2C.h>  
LiquidCrystal_I2C lcd(0x3f, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);//Direccion de LCD

unsigned int  Bpm;                                      





//This is the I2C Address of the MCP4725, by default (A0 pulled to GND).
//Please note that this breakout is for the MCP4725A0.
#define MCP4725_ADDR 0x60  
#define I2C_ADDR    0x3f

//int lookup = 0;//varaible for navigating through the tables


int sintab2[543] =
{
  939, 940, 941, 942, 944, 945, 946, 947, 951, 956,
962, 967, 973, 978, 983, 989, 994, 1000, 1005, 1015,
1024, 1034, 1043, 1053, 1062, 1075, 1087, 1100, 1112, 1121,
1126, 1131, 1136, 1141, 1146, 1151, 1156, 1164, 1172, 1179,
1187, 1194, 1202, 1209, 1216, 1222, 1229, 1235, 1241, 1248,
1254, 1260, 1264, 1268, 1271, 1275, 1279, 1283, 1287, 1286,
1284, 1281, 1279, 1276, 1274, 1271, 1268, 1266, 1263, 1261,
1258, 1256, 1253, 1251, 1246, 1242, 1237, 1232, 1227, 1222,
1218, 1215, 1211, 1207, 1203, 1199, 1195, 1191, 1184, 1178,
1171, 1165, 1159, 1152, 1146, 1141, 1136, 1130, 1125, 1120,
1115, 1110, 1103, 1096, 1088, 1080, 1073, 1065, 1057, 1049,
1040, 1030, 1021, 1012, 1004, 995, 987, 982, 978, 974,
970, 966, 963, 959, 955, 952, 949, 945, 942, 939,
938, 939, 940, 941, 943, 944, 945, 946, 946, 946,
946, 946, 946, 946, 946, 947, 950, 952, 954, 956,
958, 960, 962, 964, 965, 965, 965, 965, 965, 965,
963, 960, 957, 954, 951, 947, 944, 941, 938, 932,
926, 920, 913, 907, 901, 894, 885, 865, 820, 733,
606, 555, 507, 632, 697, 752, 807, 896, 977, 1023,
1069, 1127, 1237, 1347, 1457, 2085, 2246, 2474, 2549, 2595,
2641, 2695, 3083, 3135, 3187, 3217, 3315, 3403, 3492, 3581,
3804, 3847, 3890, 3798, 3443, 3453, 3297, 3053, 2819, 2810,
2225, 2258, 1892, 1734, 1625, 998, 903, 355, 376, 203,
30, 33, 61, 90, 119, 160, 238, 275, 292, 309,
325, 343, 371, 399, 429, 484, 542, 602, 652, 703,
758, 802, 838, 856, 875, 895, 917, 938, 967, 1016,
1035, 1041, 1047, 1054, 1060, 1066, 1066, 1064, 1061, 1058,
1056, 1053, 1051, 1048, 1046, 1043, 1041, 1038, 1035, 1033,
1030, 1028, 1025, 1022, 1019, 1017, 1014, 1011, 1008, 1006,
1003, 1001, 999, 998, 996, 994, 993, 991, 990, 988,
986, 985, 983, 981, 978, 976, 973, 971, 968, 966,
963, 963, 963, 963, 963, 963, 963, 963, 963, 963,
963, 963, 963, 963, 963, 963, 963, 963, 963, 963,
964, 965, 966, 967, 968, 969, 970, 971, 972, 974,
976, 978, 980, 983, 985, 987, 989, 991, 993, 995,
997, 999, 1002, 1006, 1011, 1015, 1019, 1023, 1028, 1032,
1036, 1040, 1045, 1050, 1055, 1059, 1064, 1069, 1076, 1082,
1088, 1095, 1101, 1107, 1114, 1120, 1126, 1132, 1141, 1149,
1158, 1166, 1173, 1178, 1183, 1188, 1193, 1198, 1203, 1208,
1214, 1221, 1227, 1233, 1240, 1246, 1250, 1254, 1259, 1263,
1269, 1278, 1286, 1294, 1303, 1309, 1315, 1322, 1328, 1334,
1341, 1343, 1345, 1347, 1349, 1351, 1353, 1355, 1357, 1359,
1359, 1359, 1359, 1359, 1358, 1356, 1354, 1352, 1350, 1347,
1345, 1343, 1341, 1339, 1336, 1334, 1332, 1329, 1327, 1324,
1322, 1320, 1317, 1315, 1312, 1307, 1301, 1294, 1288, 1281,
1275, 1270, 1265, 1260, 1256, 1251, 1246, 1240, 1233, 1227,
1221, 1214, 1208, 1201, 1194, 1186, 1178, 1170, 1162, 1154,
1148, 1144, 1140, 1136, 1131, 1127, 1123, 1118, 1114, 1107,
1099, 1090, 1082, 1074, 1069, 1064, 1058, 1053, 1048, 1043,
1038, 1034, 1029, 1025, 1021, 1017, 1013, 1009, 1005, 1001,
997, 994, 990, 991, 992, 994, 996, 997, 999, 998,
997, 996, 995, 994, 993, 991, 990, 989, 989, 989,
989, 989, 989, 989, 988, 986, 984, 983, 981, 980,
982, 984, 986, 988, 990, 993, 995, 997, 999, 1002,
1005, 1008, 1012
};


void setup()
{
  Wire.begin();
  //Serial.begin(9600);
lcd.begin(16,2);// Indicamos medidas de LCD
}

//---------------------------------------------------
void loop()
{

  Wire.beginTransmission(MCP4725_ADDR);
  Wire.write(64);                    
  Wire.write(sintab2[lookup] >> 4);      
  Wire.write((sintab2[lookup] & 15) << 4);
  Wire.endTransmission();
  lookup = (lookup + 1) & 511;


frecuencia = analogRead(0);

delayMicroseconds(analogRead(A0));

Bpm = map(analogRead(0),0,1023,120,30);

lcd.clear();//Elimina todos los simbolos del LCD
lcd.setCursor(2,0);//Posiciona la primera letra despues del segmento 5 en linea 1            
lcd.print("ECG");
lcd.setCursor(5,1);//Posiciona la primera letra despues del segmento 6 en linea 2  
lcd.print("Bpm");
lcd.setCursor(9,1);
lcd.print(Bpm);
delay (200);//Dura 2 segundos


lcd.clear();



}
 
Última edición:
Tienes idea de lo que hace esto


Código:
delay (200);//Dura 2 segundos

En tu loop? crea una demora de 200 mseg en cada ciclo. Obviamente no va a funciona.
Que te dije antes? Crea un evento por boton para cambiar los datos, eso es para priorizar la ejecucion del DAC.
Si le agregas demoras para presenetar cosas en el LCD perderás la señal.
Puedes hacerlo con un costo y usando una máquina de estados.
No usar delay(), delay DETIENE la ejecución del ciclo. Ya tienes un delayMicroseconds que multiplicado por 543 elementos crea un periodo de señal variable entre 2 y 0.5 segundos.
No hay modo que introduzcas mas demoras sin sacrificar la señal.
Espero lo comprendas.
 
Correcto, ese es el problema, gracias
Con el potenciometro no tengo problemas, hago la variación de la frecuencia y lo hace muy bien cuando esta en 66 va el pulso normal y a medida que voy aumentando los bpm la señal aumenta su frecuencia , se cumple lo que estoy buscando. (sin la LCD va todo bien)

Le quite el retardo a la LCD y aun así la señal sale extraña entonces decidí poner en comentarios toda la parte del código que corresponde a la LCD, volví a simular y sale perfecta. (No se si estare haciendo mal la conexion I2C)

(Pero a través de maquina de estados en mas engorroso entonces cómo podría asignarles valores a los pulsadores para que cambie el bpm y haga lo mismo que con el potenciometro.
 
Última edición:
Bueno a ver si evitamos la máquina de estados porque ahora que lo pienso no tienes mas que unos useg para hacer algo como presentar y no hace falta presentar en el LCD en cada ciclo porque no habrá nada nuevo.

Solo te presento el loop


Código:
void loop() {

  Wire.beginTransmission(MCP4725_ADDR);
  Wire.write(64);                   
  Wire.write(sintab2[lookup] >> 4);     
  Wire.write((sintab2[lookup] & 15) << 4);
  Wire.endTransmission();
  lookup = (lookup + 1) & 511;

  frecuencia = analogRead(0);
  if (abs(frecuencia-frecuenciaAnt > 10)  // el valor de 10 puede cambiarse para evitar ruido
      ajustoFreq();
  frecuenciaAnt = frecuencia;
}

void ajustoFreq() {

  Bpm = map(frecuencia,0,1023,120,30);
  // la cuenta es 60 x 1000000 / 543 =  110497.237
  long int intervalo = 110497 / Bpm;  // en microsegundos
  delayMicroseconds(intervalo);  //

  lcd.clear();//Elimina todos los simbolos del LCD
  lcd.setCursor(2,0);//Posiciona la primera letra despues del segmento 5 en linea 1           
  lcd.print("ECG");
  lcd.setCursor(5,1);//Posiciona la primera letra despues del segmento 6 en linea 2 
  lcd.print("Bpm");
  lcd.setCursor(9,1);
  lcd.print(Bpm);
}
 
Atrás
Arriba