Dispensador de pastillas

AUTORES: Alonso Callejo Blázquez, Lucía Jiménez García y Rodrigo Delgado Romero

OBJETIVOS DEL PROYECTO

El pastillero es un objeto muy práctico y útil para aquellas personas que deben seguir un tratamiento farmacológico que implica tomar una cantidad definida de pastillas al día. En particular; para personas mayores o que toman múltiples medicamentos, el pastillero es esencial para garantizar la adherencia efectiva al tratamiento prescrito.

El objetivo del proyecto es que el uso de un pastillero haga más fácil para el paciente realizar una toma correcta de los medicamentos o fármacos que debe ingerir en su día a día. Esto puede ayudar a asegurar que el tratamiento sea efectivo y que la enfermedad esté bajo control.

En general, los beneficios de usar un pastillero incluyen evitar confusiones en cuanto a cuándo tomar tus medicamentos y cuántos debes tomar; reducir el riesgo de errores de dosificación y de toma de medicamentos incorrectos y además mantener tus medicinas organizadas y separadas según su horario de toma para aumentar la adherencia al tratamiento.

IMPLEMENTACIÓN DEL PROYECTO

El paso inicial fue elegir el tema del proyecto. Queríamos algo que nos motivara y para ello buscamos algo útil y cercano que nosotros mismos pudiésemos llegar a dar uso. Como no encontramos una idea común pensamos en nuestros familiares y llegamos a la conclusión de que un pastillero sería una gran opción para que nuestros mayores pudiesen tomarse la gran cantidad de sus medicamentos diarios con seguridad y de forma organizada. De esta manera ninguno tendría excusa para tomarse correctamente todas sus pastillas.

Una vez elegido el proyecto a desarrollar valoramos que funciones esenciales debería desarrollar y así ideamos los diferentes casos de uso a implementar.

Con todo esto en mente procedimos a pensar en la estructura final y concluimos que el pastillero tendría una tapa fija con una puerta que diese acceso a uno de sus sietes compartimentos, según el requerido, y este tendría que ir rotando.

Nos pusimos manos a la obra, determinamos los materiales que íbamos a necesitar, nos hicimos con ellos y poco a poco fuimos montando el circuito. Primero probamos los componentes individualmente y luego fuimos juntándolos de dos en dos hasta llegar al circuito final. Así lo hicimos también de manera paralela con el código.

MATERIALES Y COSTES

COMPONENTEUSO
Motor paso a pasoGiro del pastillero
Servo motorMovimiento de apertura y cierre de la puerta del pastillero
Sensor ultrasónicoMedir la distancia que hay hasta el pastillero: cada vez que acercamos la mano se abrirá la puerta
Led verdeSe enciende cuando la puerta está abierta del todo
Led rojoSe enciende cuando la puerta está cerrada
PulsadorActivar el modo de recarga
Módulo RTCDetectar la hora local del sistema
Placa UNO arduino
Cable USB arduino
3 resistencias de 1kΩUsadas para los dos leds y el pulsador
2 protoboard + 1 mini protoboard
Cables dupont femenino a femenino, masculino a femenino y masculino a masculino
1 bisagra y 1 lámina de contrachapadoPara hacer la tapa del pastillero
1 pastillero de 7 compartimentosDepositar las pastillas
Cinta aislante
Sierra de calar, cúter, taladro y pistola termofusibleHerramientas usadas para realizar la estructura del proyecto

El coste de materiales se puede resumir en: 23,50€ (2 servomotores + pastillero), 6,5€ (bisagras + contrachapado), 8,50€ (módulo RTC), 2,5€ (cables extra), 6,5€ (materiales como pegamento para pistola termofusible, cinta aislante…). En total nos gastamos unos 16€ por cabeza aproximadamente al ser 3 los componentes del grupo ya que contábamos con gran parte del material en casa o gracias al kit que nos proporcionaron.

CASOS DE USO

Nuestro sistema implementa tres casos de uso diferentes:

  • Coger la pastilla correspondiente del pastillero:

Gracias al sensor ultrasónico, el sistema detectará que el paciente quiere recoger su pastilla cada vez que acerque la mano a la tapa y la abrirá.

  • Programar una hora para coger la pastilla:

El paciente tiene la opción de elegir la hora a la que necesita coger su pastilla. Podrá programar hasta 7 horas. Esta opción es muy útil cuando se necesita tomar una serie de medicamentos diarios a una hora específica.
Para ello el pastillero abrirá la puerta en el compartimento necesario a la hora especificada para que la pastilla requerida pueda ser recogida.

  • Modo de recarga:

Si se pulsa el botón del pastillero, este permitirá recargar sus 7 compartimentos con las pastillas correspondientes. Para ello el pastillero irá girando y abrirá la puerta cuando esté en la posición adecuada para que se depositen los fármacos. La puerta permanecerá abierta el tiempo suficiente para introducir los medicamentos y se cerrará para que el pastillero gire a la siguiente posición. Así se llevará a cabo para sus 7 huecos de manera que quede completamente recargado.

CÓDIGO DEL PROYECTO

#include <Servo.h> 
#include <Wire.h>
#include <RTClib.h>
#include <Stepper.h>
Servo myservo;
RTC_DS3231 rtc;
Stepper motor1(2048,8,10,9,11);
#define servoPin 5 
int angle = 0;
int trigPin = 12; //Disparador (Trigger)
int echoPin = 13; //Eco (Echo)
long duration, cm;
const int ledRojo = 7; //Led Rojo
const int ledVerde = 6; //Led Verde
const int buttonPin = 2; //Pin del boton
int buttonState = 0; // variable para saber el estado del botón

void setup(){
  Serial.begin(9600); //Inicia el serial port
  myservo.attach(servoPin); //Attach the Servo variable to a pin
  myservo.write(0);
  motor1.setSpeed(2);
  if (! rtc.begin()){
    Serial.println("Módulo RTC no encontrado !");
    while (1);
  }
  rtc.adjust(DateTime(__DATE__, __TIME__));
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(ledRojo, OUTPUT); 
  pinMode(ledVerde, OUTPUT); 
  pinMode(buttonPin, INPUT); // Se define buttonPin como puerto de entrada 
}

void loop(){

  buttonState = digitalRead(buttonPin); // Se lee el estado del botón 
  if (buttonState == HIGH){
    for(int i= 0; i<=6; i++){
      for(angle=0;angle<=25;angle+=1){
        myservo.write(angle);
        if(angle>=25){
          digitalWrite(ledVerde, HIGH);
          digitalWrite(ledRojo, LOW);
        }else{
          digitalWrite(ledRojo, HIGH);
          digitalWrite(ledVerde, LOW);
        }
        delay(50);
      }
      delay(10000);
      motor1.step(300);
      delay(10000);
      for(angle=25;angle<=0;angle-=1){
        myservo.write(angle);
        if(angle>=25){
          digitalWrite(ledVerde, HIGH);
          digitalWrite(ledRojo, LOW);
        }else{
          digitalWrite(ledRojo, HIGH);
          digitalWrite(ledVerde, LOW);
        }
        delay(50);
      }
      delay(5000);
    }
  }else{
    //El sensor se activa con un pulso ALTO de 10 microsegundos o más
    //Emite un breve pulso BAJO antes para asegurar un pulso ALTO
    digitalWrite(trigPin, LOW);
    delayMicroseconds(5);
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);

    //Lee la señal del sensor: un pulso ALTO cuya duracion 
    //es el tiempo (en microsegundos) desde el envío del 
    //ping hasta la recepcion del de su eco en un objeto
    pinMode(echoPin, INPUT);
    duration = pulseIn(echoPin, HIGH);

    //Convierte el tiempo en distancia
    cm = (duration/2) / 29.1;
  
    Serial.print(cm);
    Serial.print(" cm");
    Serial.println();
    delay(10000);

    if(cm<5){
      for(angle=0;angle<=25;angle+=1){
        myservo.write(angle);
        if(angle>=25){
          digitalWrite(ledVerde, HIGH);
          digitalWrite(ledRojo, LOW);
        }
        else{
          digitalWrite(ledRojo, HIGH);
          digitalWrite(ledVerde, LOW);
        }
        delay(50);
      }
      delay(10000);
      for(angle=25;angle>=0;angle-=1){
        myservo.write(angle);
        if(angle>=25){
          digitalWrite(ledVerde, HIGH);
          digitalWrite(ledRojo, LOW);
        }
        else{
          digitalWrite(ledRojo, HIGH);
          digitalWrite(ledVerde, LOW);
        }
        delay(50);
      }
    }

    DateTime fecha = rtc.now();
    int hora = fecha.hour();
    int minuto = fecha.minute();

    if((hora == 15)&&(minuto==45)){
      motor1.step(292);
      delay(2000);
      for(angle=0;angle<=25;angle+=1){
        myservo.write(angle);
        if(angle>=25){
          digitalWrite(ledVerde, HIGH);
          digitalWrite(ledRojo, LOW);
        }
        else{
          digitalWrite(ledRojo, HIGH);
          digitalWrite(ledVerde, LOW);
        }
        delay(50);
      }
      delay(60000);
      for(angle=25;angle>=0;angle-=1){
        myservo.write(angle);
        if(angle>=25){
          digitalWrite(ledVerde, HIGH);
          digitalWrite(ledRojo, LOW);
        }
        else{
          digitalWrite(ledRojo, HIGH);
          digitalWrite(ledVerde, LOW);
        }
        delay(50);
      }
    }

    if((hora == 15)&&(minuto==46)){
      motor1.step(292);
      delay(2000);
      for(angle=0;angle<=25;angle+=1){
        myservo.write(angle);
        if(angle>=25){
          digitalWrite(ledVerde, HIGH);
          digitalWrite(ledRojo, LOW);
        }
        else{
          digitalWrite(ledRojo, HIGH);
          digitalWrite(ledVerde, LOW);
        }
        delay(50);
      }
      delay(60000);
      for(angle=25;angle>=0;angle-=1){
        myservo.write(angle);
        if(angle>=25){
          digitalWrite(ledVerde, HIGH);
          digitalWrite(ledRojo, LOW);
        }
        else{
          digitalWrite(ledRojo, HIGH);
          digitalWrite(ledVerde, LOW);
        }
        delay(50);
      }
    }

    if((hora == 21)&&(minuto==13)){
      motor1.step(300);
      delay(2000);
      for(angle=0;angle<=25;angle+=1){
        myservo.write(angle);
        if(angle>=25){
          digitalWrite(ledVerde, HIGH);
          digitalWrite(ledRojo, LOW);
        }
        else{
          digitalWrite(ledRojo, HIGH);
          digitalWrite(ledVerde, LOW);
        }
        delay(50);
      }
      delay(60000);
      for(angle=25;angle>=0;angle-=1){
        myservo.write(angle);
        if(angle>=25){
          digitalWrite(ledVerde, HIGH);
          digitalWrite(ledRojo, LOW);
        }
        else{
          digitalWrite(ledRojo, HIGH);
          digitalWrite(ledVerde, LOW);
        }
        delay(50);
      }
    }

    if((hora == 18)&&(minuto==45)){
      motor1.step(292);
      delay(2000);
      for(angle=0;angle<=25;angle+=1){
        myservo.write(angle);
        if(angle>=25){
          digitalWrite(ledVerde, HIGH);
          digitalWrite(ledRojo, LOW);
        }
        else{
          digitalWrite(ledRojo, HIGH);
          digitalWrite(ledVerde, LOW);
        }
        delay(50);
      }
      delay(60000);
      for(angle=25;angle>=0;angle-=1){
        myservo.write(angle);
        if(angle>=25){
          digitalWrite(ledVerde, HIGH);
          digitalWrite(ledRojo, LOW);
        }
        else{
          digitalWrite(ledRojo, HIGH);
          digitalWrite(ledVerde, LOW);
        }
        delay(50);
      }
    }

    if((hora == 20)&&(minuto==20)){
      motor1.step(292);
      delay(2000);
      for(angle=0;angle<=25;angle+=1){
        myservo.write(angle);
        if(angle>=25){
          digitalWrite(ledVerde, HIGH);
          digitalWrite(ledRojo, LOW);
        }
        else{
          digitalWrite(ledRojo, HIGH);
          digitalWrite(ledVerde, LOW);
        }
        delay(50);
      }
      delay(60000);
      for(angle=25;angle>=0;angle-=1){
        myservo.write(angle);
        if(angle>=25){
          digitalWrite(ledVerde, HIGH);
          digitalWrite(ledRojo, LOW);
        }
        else{
          digitalWrite(ledRojo, HIGH);
          digitalWrite(ledVerde, LOW);
        }
        delay(50);
      }
    }

    if((hora == 20)&&(minuto==44)){
      motor1.step(300);
      delay(2000);
      for(angle=0;angle<=25;angle+=1){
        myservo.write(angle);
        if(angle>=25){
          digitalWrite(ledVerde, HIGH);
          digitalWrite(ledRojo, LOW);
        }
        else{
          digitalWrite(ledRojo, HIGH);
          digitalWrite(ledVerde, LOW);
        }
        delay(50);
      }
      delay(60000);
      for(angle=25;angle>=0;angle-=1){
        myservo.write(angle);
        if(angle>=25){
          digitalWrite(ledVerde, HIGH);
          digitalWrite(ledRojo, LOW);
        }
        else{
          digitalWrite(ledRojo, HIGH);
          digitalWrite(ledVerde, LOW);
        }
        delay(50);
      }
    }

    if((hora == 11)&&(minuto==10)){
      motor1.step(292);
      delay(2000);
      for(angle=0;angle<=25;angle+=1){
        myservo.write(angle);
        if(angle>=25){
          digitalWrite(ledVerde, HIGH);
          digitalWrite(ledRojo, LOW);
        }
        else{
          digitalWrite(ledRojo, HIGH);
          digitalWrite(ledVerde, LOW);
        }
        delay(50);
      }
      delay(60000);
      for(angle=25;angle>=0;angle-=1){
        myservo.write(angle);
        if(angle>=25){
          digitalWrite(ledVerde, HIGH);
          digitalWrite(ledRojo, LOW);
        }
        else{
          digitalWrite(ledRojo, HIGH);
          digitalWrite(ledVerde, LOW);
        }
        delay(50);
      }
    }
  }
}

Empezamos añadiendo las librerías pertinentes como que sirve para controlar el servo motor, para manejar el módulo RTC y la para manejar el motor paso a paso. Después procedimos a declarar las diferentes variables a utilizar y definir los pines a los que van los diferentes componentes usados.

En el setup añadimos los diferentes pines de entrada y de salida y algún otro detalle como poner el servo motor a 0 para que no realice movimientos agresivos cuando se conecta con arduino (myservo.write(0);).

Y finalmente en el loop definimos los casos de uso:
Un primer caso donde comprobamos si se ha pulsado el botón ( if (buttonState == HIGH)). En caso de ser así se activa el modo recarga y en caso contrario se comprueba si el sensor ultrasónico ha percibido movimiento.
De esta manera, cuando recibe movimiento a menos de 5 cm se abre el pastillero y se enciende el led verde, espera en esa posición unos segundos y luego se cierra y se enciende el led rojo(if(cm<5)).
Para terminar, determinamos la hora a la que queremos que el pastillero se abra (if((hora == xx)&&(minuto = xx))). Se pueden programar hasta 7 horas.

PROBLEMAS Y POSIBLES SOLUCIONES

Una posible mejora del proyecto podría ser incorporar al sistema la opción de que el usuario seleccione físicamente la hora a la que desea programar la apertura del pastillero sin necesidad de hacerlo directamente desde el software de arduino. Otra opción podría ser desarrollar un programa externo desde el cuál poder seleccionarla, como si fuese una aplicación.

Un aspecto que nos ha resultado laborioso ha sido implementar todas las conexiones necesarias para que los distintos componentes del sistema funcionen correctamente y empotrarlos en una estructura común. Otra posible mejora podría ser que estos estén estéticamente mejor colocados pero que sigan cumpliendo con su función. Por ejemplo, que los cables sean menos visibles o que la estructura de la tapa sea más uniforme.

Además, en el código tuvimos que implementar bastantes “delays” para que la puerta se abriese y cerrase una única vez a la hora seleccionada. Esto hizo que el tiempo de espera hasta que se abriese fuese más del realmente deseado. Otra posible mejora podría ser cuadrar mejor los “delays” para que el sistema funcione más eficientemente en su totalidad.

VÍDEO DEL FUNCIONAMIENTO

https://drive.google.com/file/d/10tMFzOpPMFcdJLtZnu21Q159P3mWHwPz/view?usp=share_link

También te podría gustar...

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *