Llamado de enfermería con PIC18F4685

Buen día.

Amigos del foro, tengo un proyecto que se titula "llamado de enfermería"

Tengo los siguientes inconvenientes:
Son muchos puntos de llamado, y si varios pacientes realizan el llamado al mismo tiempo el PIC sólo toma el primer llamado y los otros se pierden.
Esto no puede ser posible porque son llamados importantes de un enfermo.

Necesito resolver como poner en cola los otros llamados.
El siguiente código es el que va en el tablero de la habitación.
Como pueden observar, es un PIC que me controla la activación de los pulsadores de cada llamado, y cada botón pulsado me envía un dato en binario por el puerto D para diferenciar el tipo de llamado.

El inconveniente es que son muchas habitaciones, estamos hablando de alrededor de 90.
Está la posibilidad de que varios pacientes realicen el llamado al mismo tiempo y no sea detectado, sino sólo el primero debido a que la consola o el PIC receptor sólo puede procesar un llamado al tiempo.

PHP:
#include <16f877a.h>
#fuses xt,nowdt,noprotect,nolvp,nowrt,nobrownout
#use delay(clock=4000000)
#include <stdlib.h>

#byte port_a=5
#byte port_b=6
#byte port_c=7
#byte port_d=8
#byte port_e=9

void main()
{

     set_tris_a(0x00);
     set_tris_b(0x00);
     set_tris_c(0xff);
     set_tris_d(0x00);
     set_tris_e(0x00);
     
     port_a=0x00;
     port_b=0x00;
     port_c=0x00;
     port_d=0x00;
     port_e=0x00;
     
         while(true)
            {
            if(input(pin_C0)==1) //boton enfermera on
                        {
                        port_d=0x01;//dato que va a la consola
                        output_high(pin_E0);
                        delay_ms(50);//tiempo en alto de los puertos
                        port_d=0x00;//poner en cero los puertos
                      //  delay_ms(50);//para evitar rebotes
                        }
            if(input(pin_C1)==1)   //boton enfermera off
                        {
                        port_d=0x02;//dato que va a la consola
                        output_low(pin_E0);
                        output_high(pin_B0);
                        delay_ms(100);
                        output_low(pin_B0);
                        port_d=0x00;
                    //    delay_ms(50);
                        }            
            if(input(pin_C2)==1)//boton baño on
                        {
                        port_d=0x03;//dato que va a la consola
                        output_high(pin_E1);
                        delay_ms(100);
                        port_d=0x00;
                        //delay_ms(50);
                        }
            if(input(pin_C3)==1)//boton baño off
                        {
                        port_d=0x04;//dato que va a la consola
                        output_low(pin_E1);
                        output_high(pin_B1);
                        delay_ms(100);
                        output_low(pin_B1);
                        port_d=0x00;
                        //delay_ms(50);
                        }                        
            if(input(pin_C4)==1)//boton codigo azul on
                        {
                        port_d=0x05;//dato que va a la consola
                        output_high(pin_E2);
                        delay_ms(100);
                        port_d=0x00;
                        //delay_ms(50);
                        }
            if(input(pin_C5)==1)//boton codigo azul off
                        {
                        port_d=0x06;//dato que va a la consola
                        output_low(pin_E2);
                        output_high(pin_B2);
                        delay_ms(100);
                        output_low(pin_B2);
                        port_d=0x00;
                        //delay_ms(50);
                        }               
            }
}
Éste es el programa de la consola que me recibe el dato que envía el PIC desde la habitación por medio de un cable UTP.
PHP:
#include <18f4685.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP,NOWRT,NOBROWNOUT,NODEBUG
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#define use_portB_lcd TRUE
#USE standard_io(B)
#USE standard_io(A)
#USE standard_io(C)
#USE standard_io(D)
#USE standard_io(E)
#include <stdlib.h>
#include <input.c>
#include <lcd.c>

#byte puertoA=5
#byte puertoC=7
#byte puertoD=8

int16 asignacion;            //variable de convercion de dato de binario a entero

void salto();
void salto1();
void pitoenfermera();
void pitobano();
void pitocodigoazul();
void pitoapagadoenfermera();
void pitobanoapagado();
void pitocodigoazulapagado();

Void main()
{
   set_tris_a(0x00);
   set_tris_c(0x00);
   set_tris_d(0xFF);
 
 lcd_init();
   
   puertoA=0x00;
   puertoC=0x00;
   puertoD=0x00;
   
   delay_ms(50);
   
   LCD_PUTC("\f   LLAMADO DE \n   ENFERMERIA");
    
    
   WHILE(TRUE)
     {
   delay_ms(100);  
     
if((input(pin_D7)==0) && (input(pin_D6)==0) && (input(pin_D5)==0) && (input(pin_D4)==0) && (input(pin_D3)==0) && (input(pin_D2)==0) && (input(pin_D1)==0) && (input(pin_D0)==1))
                        {
                        lcd_putc("\fHABITACION 100\nENFERMERA URGENTE");
                        asignacion=1; //0x01
                        printf("@%lu"asignacion);   //Se agrega el @ y # para enviar y diferenciar los datos
                        delay_ms(50);
                        pitoenfermera();
                        //reset_cpu(); 
                        }
if((input(pin_D7)==0) && (input(pin_D6)==0) && (input(pin_D5)==0) && (input(pin_D4)==0) && (input(pin_D3)==0) && (input(pin_D2)==0) && (input(pin_D1)==1) && (input(pin_D0)==0))
                        {
                        lcd_putc("\fHABITACION 100\nPACIENTE ATENDIDO");
                        asignacion=2;//0x02
                        printf("@%lu"asignacion);   //Se agrega el @ y # para enviar y diferenciar los datos
                        delay_ms(50);
                        pitoapagadoenfermera();
                        //reset_cpu();
                        }
if((input(pin_D7)==0) && (input(pin_D6)==0) && (input(pin_D5)==0) && (input(pin_D4)==0) && (input(pin_D3)==0) && (input(pin_D2)==0) && (input(pin_D1)==1) && (input(pin_D0)==1))
                        {
                        lcd_putc("\fHABITACION 100\nBANO URGENTE");
                        asignacion=3;//0x03
                        printf("@%lu"asignacion);   //Se agrega el @ y # para enviar y diferenciar los datos
                        delay_ms(50);
                        pitobano();
                        //reset_cpu();
                        }
if((input(pin_D7)==0) && (input(pin_D6)==0) && (input(pin_D5)==0) && (input(pin_D4)==0) && (input(pin_D3)==0) && (input(pin_D2)==1) && (input(pin_D1)==0) && (input(pin_D0)==0))                        {
                        lcd_putc("\fHABITACION 100\nBANO ATENDIDO");
                        asignacion=4;//0x04
                        printf("@%lu"asignacion);   //Se agrega el @ y # para enviar y diferenciar los datos
                        delay_ms(50);
                        pitobanoapagado();
                        //reset_cpu();
                        }
if((input(pin_D7)==0) && (input(pin_D6)==0) && (input(pin_D5)==0) && (input(pin_D4)==0) && (input(pin_D3)==0) && (input(pin_D2)==1) && (input(pin_D1)==0) && (input(pin_D0)==1))
                        {
                        lcd_putc("\fHABITACION 100\nCODIGO AZUL");
                        asignacion=5;//0x05
                        printf("@%lu"asignacion);   //Se agrega el @ y # para enviar y diferenciar los datos
                        delay_ms(50);
                        pitocodigoazul();
                        //reset_cpu();
                        }
if((input(pin_D7)==0) && (input(pin_D6)==0) && (input(pin_D5)==0) && (input(pin_D4)==0) && (input(pin_D3)==0) && (input(pin_D2)==1) && (input(pin_D1)==1) && (input(pin_D0)==0))
                        {
                        lcd_putc("\fHABITACION 100\nC.AZUL ATENDIDO");
                        asignacion=6;//0x06
                        printf("@%lu"asignacion);   //Se agrega el @ y # para enviar y diferenciar los datos
                        delay_ms(50);
                        pitocodigoazulapagado();
                        //reset_cpu();
                        }
 
Última edición por un moderador:
Y si utilizas registros de desplazamiento? podrías retener varios códigos a la vez y luego con el Pic decides cual lees primero. Lo difícil es el cableado.:unsure:

Es solo una idea.
 
1.-ese programa esta lleno de DELAYS y a mi gusto no sirve
2.-si podrias usar registros de corrimiento esa es buena idea "CD4021" paralelo a serie
3.-leer un dato de entrada y apilarlo es facil

para leer 1 registro de 8 bits

primero debes hacer una funcion que lea el CD4021 es muy parecido al SPI un pin LATCH que habilita el chip para leer , un clock por cada bit DATA leido

ejemplo

habilitamos el LATCH con 0 para empezar a leer el CD4021
enviamos un clock para leer 1 bit
para leer los 8 bits debemos enviar 8 clocks

una vez terminado de leer los 8 bits deshabilitamos el latch con 1

bien facil no?

char leer(char dato) //para leer el CD4021
{
//TU algoritmo
return dato;
}

void main()
{
char byte;

latch=0; //habilitamos el CD4021

byte=leer();

latch=1; //deshabilitamos el CD4021

}




para ir apilando

bien facil

digamos que leimos lo siguiente:

10101010 una habitacion SI y una NO

todo eso dentro de un BYTE

char byte;

byte=leer(); // la funcion leer cargo el byte con =0b10101010

printf("se va a impirmirlo que hay dentro del byte%d",byte);

varas que se imprime el numero 170

¿como sacamos los 1 y los 0?

debemos hacer uso de un string auxiliar para sacar los bits y hacer uso de la funcion de ROTAR BITS


eso se hace mas o menos asi:

char cadena[9]; //obtendremos un 1 o un 0
char bit; ira sacando los bits de el byte
char byte; //esta cargado con 10101010


for(i=0; i!=8 ; i++)
{


bit=byte<<i;

bit=bit&0b10000000;

if(bit==0)
{
cadena=0;

}
else
{

cadena=1;
}
}


y mas o menos asi :unsure:
 
Antes de meternos en líos de programación, pregunto ¿es un proyecto de demostración (maqueta de escuela, hobbie, etc?, porque de no serlo, y siendo objetivos, deberías primero pensar en la parte de la distribución del cableado en todas las habitación, inlcluso sopesar la idea que utilizar un medio de transmisión inalámbrico, etc. Ya con eso en mente si puedes entrarle a la programación.
 
Hola, a todos.

Tengo un problema parecido, después de declarar mi variable TRISX y POSTX como dice la hoja de datos (PIC16F877A) sin ningún problema.
PHP:
#include <string.h> 
int8 VGN_Estacion=0;
Int Vgn_Contador = 0,Vgn_act_cont = 0; 
#define CE PIN_E2 
#define parlant_zumb PIN_D7
#Byte Puerto_a  = 0x85
#Byte Prota     = 0X05
#Byte Puerto_b  = 0x86
#Byte Protb     = 0X06
#Byte Puerto_c  = 0x87
#Byte Protc     = 0X07
#Byte Puerto_d  = 0x88
#Byte Protd     = 0X08
#Byte Puerto_e  = 0x89
#Byte Prote     = 0X09
En el transcurso del programa necesito poner 4 pines en alto.
Por ejemplo: E0, E1, C5 y C4
Código:
Output_High(Pin_E0)
Output_High(Pin_E1)
Output_High(Pin_C4)
Output_High(Pin_C5)
El resultado que espero es que los pines estén en alto.
Pero me encuentro que por ejemplo, el Pin_E0 está en alto, el pin E1 está en bajo, el pin C4 está en alto y el Pin C5 está en bajo.

Es algo así como si la instrucción que sigue apagara el pin anterior.
¿Cómo solucioné este punto? Manejando los puerto de forma binaria.

Por ejemplo:
Porte = 0b011
Portc = 0b00011000

¿Pero qué sucede como mi proyecto?
Tengo dos PIC que comunico por el puerto C (C6 y C7)
Y cuando utilizo el lenguaje binario en el emulador me sale un error de que tengo como una especie de un corto.
Y esto se da porque tengo ocupado al pin_C6 y C7 con la transferencia de datos y a la vez le estoy diciendo que son de nivel bajo en la programación: Portc = 0b00011000

Mi pregunta es. ¿Cómo puedo manejar los pines a nivel binario sin modificar otro pin del puerto. (Por ejemplo, usar el C4 y C5 sin interrumpir el C6 y 7)?
¿O qué me puede estar generando este funcionamiento extraño con la función Output?

Gracias por su tiempo.
 
Última edición por un moderador:
buenas tardes amigos gracias por su colaboracion pero pensando hay una forma mas viable que es monitorear desde mi compu los estados de las habitaciones por puerto rs485 donde mi compu es el maestro y las habitaciones son los esclavos. para evitar problemas de cableado ya que inalambrico no se puede por seguridad del paciente de que el llamado se atienda.
 
PHP:
#include <16f877a.h>
#use delay(clock=4000000)
#fuses xt,NOWDT,NOPROTECT,NOLVP,NOWRT,NOBROWNOUT
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

#include <stdlib.h>
#include <input.c>
#include <stdio.h>

#byte port_a=5
#byte port_b=6
#byte port_c=7
#byte port_d=8
#byte port_e=9

char c;
int16 asignacion;

main ()
      {
         set_tris_c(0x3F);
         set_tris_d(0x00);
         set_tris_e(0x00);
         
         port_c=0x00;
         port_d=0x00;
         port_e=0x00;
         
        while (true)
        {
        c=getc();
       
         if(input(pin_C0)==1) //boton enfermera on
                        {
                        output_high(pin_D0);
                        output_high(pin_E0);
                        delay_ms(50);
                        asignacion=100;
                        printf("%lu"asignacion);   //retorna al pic de consola el dato 100 esta llamando a la enfermera
                        delay_ms(50);
                        }
         if (c=='1' && (pin_D0==1))
                        {
                        asignacion=101; 
                        printf("%lu"asignacion);   //retorna al compu el dato 101 esta llamando a la enfermera
                        delay_ms(50);
                        }    
         if (c=='1' && (pin_D0==0))
                        {
                        asignacion=102; 
                        printf("%lu"asignacion);   //retorna al compu el dato 102 esta apagado el llamado de enfermera
                        delay_ms(50);
                        }                   
         if (input(pin_C1==1)&& (pin_D0==1))//apaga el llamado de la enfermera con la condicion de que se halla activado el llamado
                        {
                        output_low(pin_D0);
                        output_high(pin_D1); 
                        delay_ms(50);
                        asignacion=103;//retorna al pic de la consola el dato 301 para indicar que se ha apagado el llamado de la enfermera
                        printf("%lu"asignacion);   
                        delay_ms(50);
                        }
        }
     }

Éste es el código que va en el cuarto o habitación, pero con RS-232 y quiero que sea con RS-485

Así sería el cableado.
 

Adjuntos

  • EasyCapture8.zip
    47.4 KB · Visitas: 19
Última edición por un moderador:
Si es proyecto "serio", "de verdad" ve enterrando para siempre los delays. Los borras de tu cabeza y no los usas nunca más. Siempre absolutamente siempre hay algo que hacer, y en tu aplicación es obvio que así es: los pulsadores se miran siempre, siempre, siempre, caiga quien caiga. Las enfermeras no deberían de echar siestas en su turno. Tu sistema tampoco puede echar cabezaditas porque las máquinas no se cansan.
Ejemplo: si haces un carricoche de madera para las fiestas de tu pueblo puedes frenar con el pie. No puedes ser fabricante de automóviles y hacer vehículos que se frenan con el pie en el suelo.
El pie y los frenos de disco con abs frenan igualmente...pero "no es lo mismo"

En el enunciado afirmas que se atiende al primero que pulsa, pero es falso. En muchos casos tu atiendes al primero que miras, no al primero que pulsa, y siempre miras al mismo. Te pasas la mayor parte del tiempo durmiendo la mona. Cuenta los ciclos del programa y los delays que seguramente te asustarás.

Al igual que te han dicho anteriormente, yo empezaría por definir el hardware. En esa aplicación vas a tener MUCHOS problemas de ruido eléctrico y es una aplicación MUY MUY MUY sensible; la vida de los pacientes puede depender de ella. No es un timbre común.
Después te lías con el software.
 
Última edición:
Es importante el protocolo: si un PIC envía un mensaje, DEBE recibir una confirmación desde el maestro de que ha sido entregado. Si no lo recibe, insistir pasado un tiempo.
 
Pues sí. Antes de empezar el programa y el micro, hay que definir un protocolo de cableado, comunicación, etc.

Ya una vez definido todo, hay que empezar con el programa.
Así como lo vi, parece un programa de 5º semestre de ingeniería.
Le falta mucho, más bien me quede corto, más bien todo está mal.
 
Última edición por un moderador:
si eres de méxico, dudo mucho que tu sistema sea utilizado, ya que las enfermeras van de cuarto en cuarto checando paciente por paciente, por intervalos de 30 a 40 min por cuarto. Solo le muestran prioridad a los pacientes moribundos, que no se pueden mover, o tienen demasiado dolor. Por eso siempre hay un familiar a fuerzas con cada paciente.

Otro detalle esta que en los cuartos (ya sea cirugia, medicina interna, etc) hay de 2 a 3 pacientes por cuarto (al menos en los hospitales de gobierno mexicano), tendrian que ser 3 botones por cuarto, despues ponerle prioridad a los pacientes, porque uno puede estar solo reciviendo medicación, mientras el de a lado, ya esta muriendo (me toco verlo). Los pacientes estan enumerdado (P233, P232, O233, P232) y distribuidos por area del hospital y los numeros se repiten, solo cambia una letra.

Deberías hablar con alguien que estudie enfermeria, o pedir un papel en tu escuela que te avale que es un proyecto escolar, y asi hablar con un doctor, enfermera, o de servicio social. Preguntar sus necesidades en algún area, y luego si te permiten hacer una investigación y desarrollo (te va a llevar tiempo) por eso solo me tomaria la molestia si es un trabajo de titulación o posgrado, si es proyecto escolar, no te mates la cabeza y haz algo más sencillo, ya que la vida o necesidades de las personas esta de por medio.
 
yo opino lo mesmo

se me hace ilogico pues los cuartos siempre estan vigilados por enfermeras, ami me toco hacer guardias en los ultimos dias de mi padre.
 
una necesidad que observe en el hospital es que todos los despachadores de jabón, desinfectante y papel son manuales, y al ser un hospital (todos tienen contacto con los enfermos) se me hace anti higienico, hay podrías checarlo. Tambíen las camillas (camas) donde tienen a los enfermos para subir o bajar la cabezera es igual manual, tambien podrías hacerlas automaticas para los pacientes con un control.

Otra necesidad es que las enfermeras deben empujar sus carritos donde traen todo lo que necesitan, podrías aplicar un seguidor de linea para que ellas presionen un boton con el pie o algun mecanismo optico y asi el carrito se detenga en la puerta de dicho paciente.

Solo son ideas, y buenas.
 
Atrás
Arriba