ANEXO 1. CODIGO CODEWARRIOR ;**************************************************************************** ;Microcontrlador JL8 ;Cristal 5 Mhz ;PROGRAMA PRINCIPAL: LEE ADC, ACTUALIZA VALBS Y LEE PULSADOR EMERGENCIA ;**************************************************************************** include derivative.inc E EQU 2 ; PTD2 Habilita display RS EQU 3 ; PTD3 selecciona modo (comando=0, dato=1) COCO equ 7 ADCO equ 5 TSTOP EQU 5 TOF EQU 7 MOTORUP EQU 0 ; PTD0 Señal motor para tensionar MOTORDOWN EQU 1 ; PTD1 Señal motor para destensionar PULEMERG EQU 4 ; PTB4 Entrada señal de emergencia LED EQU 4 ; PTA4 SALIDA LED INDICADOR PUL PACIENTE PACIENTE EQU 5 ; PTA5 ENTRADA PULSADOR PACIENTE ;__________________________________________________________________________ ;BITS DE REGISTRO DE INTERRUPCION EXTERNA IRQ IMASK1 EQU 1 MODE1 EQU 0 ACK1 EQU 2 ;_________________________________________________________________________ ; Definición de variables en la RAM org VALADC TIME DIG1LBS DIG2LBS DIG1ADC DIG2ADC DIG3ADC NumAConv NumAConv1 sustraen sustraen1 contador VALBS CONT_DECE DIRH Z_RAMStart ds.b 1 ds.b 1 ds.b 1 ds.b 1 ds.b 1 ds.b 1 ds.b 1 ds.b 1 ds.b 1 ds.b 1 ds.b 1 ds.b 1 ds.b 1 ds.b 1 ds.b 1 DIRL ds.b 1 K1 ds.b 1 K2 ds.b 1 FLAGPULPAC ds.b 1 FLAGEMERG ds.b 1 BLORUTEMERG ds.b 1 FLAGLED ds.b 1 ; DEFINO VARIABLES DE ECUACION CARACTERISTICA DE CELDA DE CARGA INTACC1 ds.b 4 ; INTACC1:INTACC1+1:INTACC1+2:INTACC1+3 ; MULTIPLICANDO 1 DE 16 BITS Y RESULTADO DE 32 BITS ; INTACC1:INTACC1+1 MULTIPLICANDO 1 (VALADC) ; EL RESULTADO ES DE 32 BITS Y QUEDA EN INTACC1 HASTA INTACC1:3 INTACC2 ds.b 2 ; INTACC2:INTACC2+1 ; MULTIPLICANDO 2 (10000) INTACC3 ds.b 4 ; SUMANDO DE 4 BYTES (25622) INTACC4 ds.b 2 ; DIVISOR DE LA ECUACION (25282) ; Programa en la FLASH org ROMStart INICIO rsp clra clrh clrx bset clra clrh clrx clr clr clr clr clr clr clr clr clr clr clr ; Inicializa registros de la CPU 0,CONFIG1 contador sustraen sustraen1 NumAConv NumAConv1 FLAGPULPAC FLAGEMERG BLORUTEMERG DIG1ADC DIG2ADC DIG3ADC ; Desactiva el COP clr DIG1LBS clr DIG2LBS clr VALADC clr VALBS clr K1 clr K2 clr FLAGLED ;________________________________________________________________________________ INI_PORTS: mov #$10,DDRA ; Todo puerto A como entrada menos PTA4 mov #$0F,DDRB ; Configura e inicializa puertos mov #$1F,DDRD ; Todo puerto D como salida. mov #$FF,PTAPUE ; activo resistencias de pull up PTA clr clr clr PTA PTB PTD ; INICIALIZO PUERTOS ;________________________________________________________________________________ ;* Inicilizar LCD ;* Retardo 15ms INI_LCD ;150 en decimal lda #150T ;delay 15 mS sta TIME jsr VAR_DELAY ;* Enviar comando de incio CONFIGURACION PANTALLA POR PARTE BAJA DE PTB INSTRUCCION 30 ENVIO PARTE ALTA lda #$30 ;ANCHO BUS DE DATOS 8 BITS (DL=1) nsa ;UTILIZO NSA PARA PASAR PARTE ALTA DE COMANDO A LA SALIDA DE PTB PARTE BAJA sta PTB ;ENVIA COMANDO POR PTB A D0-D7 RS=0 bset E,PTD ;ACTIVA ENABLE bclr E,PTD ;DESACTIVA ENABLE ;* Retardo 4.1ms lda #41T sta TIME jsr VAR_DELAY ;Subrutina 4.1 mS delay ;* Enviar comando de incio lda #$30 nsa sta PTB ; COMANDO BUS 8 BITS (DL=1) ; SE CONFIGURA NUEVAMENTE LA PANTALLA , (Comando RS EN 0) bset E,PTD bclr E,PTD ;* Retardo 100us lda #1T ;RETARDO MAS CORTO sta TIME jsr VAR_DELAY ;* Enviar comando de incio lda #$30 ; COMANDO BUS 8 BITS (DL=0) nsa jsr LCD_WRITE ; Escribe dato a LCD ;* Enviar comando de configuración LCD ;* Bus de 4 bits, 2 renglones, 5x7 dots INSTRUCCION 20 PRIMERO Y LUEGO 28 SE PARTE POR ESTAR YA EN 4 BITS lda #$20 nsa ; COMANDO 20 BUS 4 BITS (DL=0) RS=0 WRITE COMANDO SOLO MSB, LSB=0 VAN A TIERRA EN LCD jsr LCD_WRITE ;A PARTIR DE AQUI QUEDA CONFIGURADO COMO BUS DE 4 BITS (SE DEBEN ENVIAR DATOS EN DOS PARTES, PRIMERO PARTE ALTA) lda #$02 ; COMANDO MSB 28 BUS 4 BITS (DL=0) DOS LINEAS (N=1), TAMAÑO CARACTER 5X7 (F=0) MSB jsr LCD_WRITE lda #$08 ;LSB jsr LCD_WRITE ;* Enviar comando de control display ;* Display on (D=1), cursor off(C=0), no parpadeo (B=0) INSTRUCCION 0C lda #$00 ;Comando de control display MSB EN PPARTE BAJA jsr LCD_WRITE lda #$0C ;Comando de control display LSB EN PARTE BAJA jsr LCD_WRITE ;* Enviar comando, clear display y cursor a ddr=0 INSTRUCCION 01 lda #$00 ; comando clear display MSB jsr LCD_WRITE lda #16T sta TIME jsr VAR_DELAY lda #$01 jsr LCD_WRITE lda #16T sta TIME jsr VAR_DELAY ; delay 1.6 mS ; comando clear display LSB ; delay 1.6 mS ;* Enviar comando modo de entrada INSTRUCCION 06 ;* Icrementa ,no desplaza lda #$00 ;modo de entrada comando MSB EN PARTE BAJA jsr LCD_WRITE lda #$06 ;modo de entrada comando LSB EN PARTE BAJA jsr LCD_WRITE ;FIN INICIALIZACION DISPLAY ;________________________________________________________________________________ INI_ADC: mov #$20,ADICLK ; Configura el ADC (frecuencia ADC=FBUS/4=312.5khz),conversion unica, no interrupciones mov #$06,ADSCR ; Selecciono canal 6 como entrada INI_TIM1: mov #$30,T1SC ; DETIENE Y RESETEA CONTADOR TIM1 mov #$63,T1SC ; FIJA PRESCALER 8 EN ,HABILITA INTERRUPCION TOF,CONTADOR PARADO mov #$F4,T1MODH ; Establece el tiempo 500 mS mov #$28,T1MODL INI_TIM2: mov #$30,T2SC ; DETIENE Y RESETEA CONTADOR TIM2 mov #$65,T2SC ; FIJA PRESCALER EN 64,HABILITA INTERRUPCIONES,CONTADOR PARADO mov #$98,T2MODH ; Carga el valor TMOD correspondiente a 1 Seg mov #$96,T2MODL ;*** Subrutina de inicializacion modulo SCI *** INI_SCI mov mov mov #$40,SCC1 #$2C,SCC2 #$01,SCBR ; Configura SCI (9600,8,N,1) ; habilito interrupcion por recepción cli ; Habilita interrupciones ;________________________________________________________________________________ ; PROGRAMA PRINCIPAL ********************************************************* jsr jsr MENSAJE1 MENSAJE2 LEE_ENT AQUI brclr PULEMERG,PTB,EMERGENCIA ; SI SE ACTIVA EMERGENCIA NO ENTRA clr BLORUTEMERG ; AL LIBERAR PULSADOR EMERG SE CLAREA BLORUTEMERG jsr MENSAJE5 brclr PACIENTE,PTA,SETFPULP bra CONTINUE SIGA SETFPULP mov jsr jsr jsr RETARDO brclr PACIENTE,PTA,* jsr RETARDO #1,FLAGPULPAC MENSAJE5 MENSAJE3 ; ENVIA MENSAJE A LCD lda FLAGLED cbeqa #0,ENCLED bclr LED,PTA clr FLAGLED bra CONTINUE ENCLED bset LED,PTA mov #1,FLAGLED CONTINUE jsr ADQ_ADC ; PROCESO DE LECTURA VALOR CELDA DE CARGA jsr ALCDADC jsr ECUACION jsr HEX2BCDLBS jsr ALCDLBS ;________________________________________________________________________________ bra LEE_ENT EMERGENCIA lda BLORUTEMERG cbeqa #1,CONTINUE ; PARA MOSTRAR LIBRAS MIENTRAS jsr RUT_EMERG ; SE RELAJA CON BOTON MANUAL ;________________________________________________________________________________ LOOP bra LEE_ENT ;SUBRUTINAS ****************************************************************** ;* Rutina lineas de control RS Y E para envio de direcciones o comandos al LCD LCD_ADDR: bclr RS,PTD ; coloca en cero RS sta PTB ; Carga dato en puerto de 4 bits bset E,PTD ; Habilita display bclr E,PTD ; Deshabilita display lda #13T ; Espera F4: deca bne F4 bset RS,PTD ; Coloca RS en uno rts ;________________________________________________________________________________ ;* Subrutina lineas de control RS Y E para envio de datos al LCD LCD_WRITE: sta PTB ;RECIBE CODIGO EN EL ACUMULADOR Y CARGA EN PTB A D4-D7 bset E,PTD ;habilita el display bclr E,PTD ;Deshabilita pin control lda #13T F2: deca bne F2 rts ;________________________________________________________________________________ ;* Subrurtina de retardo VAR_DELAY: lda #33T ;Retardo 1.6 mS F1: deca bne F1 dec TIME bne VAR_DELAY rts ;________________________________________________________________________________ ; Subutina para realizar adquisicion de voltaje y realizar conversion ADQ_ADC: brclr lda sta rts bclr ADCO,ADSCR ; Solicita una conversión COCO,ADSCR,* ; Espera por resultado de conversión ADR ; Carga el resultado de la conversión en registro ADR VALADC ;________________________________________________________________________________ START_TIM1 rts bclr TSTOP,T1SC ; ACTIVO CONTADOR TIM1 ;_____________________________________________________________________________ STOP_TIM1 mov #$30,T1SC ; DETIENE Y RESETEA CONTADOR TIM1 mov #$63,T1SC ; FIJA PRESCALER 8 EN ,HABILITA INTERRUPCION TOF,CONTADOR PARADO mov #$F4,T1MODH ; Establece el tiempo 500 mS mov #$28,T1MODL rts ;_____________________________________________________________________________ TENSIONAR bset MOTORUP,PTD bclr MOTORDOWN,PTD clr BLORUTEMERG rts ;_____________________________________________________________________________ RELAJAR bclr MOTORUP,PTD bset MOTORDOWN,PTD rts ;_____________________________________________________________________________ PARAR bclr MOTORUP,PTD bclr MOTORDOWN,PTD rts ;______________________________________________________________________________ RUT_EMERG jsr MENSAJE5 jsr MENSAJE4 ; ENVIA MENSAJE A LCD mov #1,FLAGEMERG mov #1,BLORUTEMERG clr FLAGPULPAC rts ;***************************************************************************** ; ECUACION ORIGINAL VALADC=2.6041(L)-1.9431 ; MULT Y DIVID0 POR 10000 Y DESPEJO L ; FUNCION L=((VALADC*10000)+19431)/26041 ; L= LIBRAS ; PARA TODAS LAS OPERACIONES EL RESULTADO QUEDA EN INTACC1 (32 BITS) ECUACION:ldhx $0000 clr INTACC1 clr INTACC1+1 clr INTACC1+2 clr INTACC1+3 clr INTACC2 clr INTACC2+1 clr INTACC3 clr INTACC3+1 clr INTACC3+2 clr INTACC3+3 clr INTACC4 clr INTACC4+1 mov VALADC,INTACC1+1 ; cargo mult1 de 16 bits en INTACC1: INTACC1+1 (VALADC) QUEDA EN ; INTACC1+1 PORQUE VALADC ES DE 8 BITS ldhx #10000 ; cargo mult2 de 16 bits en INTACC2 sthx INTACC2 ldhx #19431 ; Cargo sumando sthx INTACC3+2 ; CARGO INTACC3+2 E INTACC3+3 CON EL DECIMAL 25622 ldhx #26041 ; Cargo el divisor con el valor decimal 25282 sthx INTACC4 **************************************************************** * Subrutina de multiplicación 16X16, RESULTADO 32 BITS * **************************************************************** MULT16: ldx lda mul stx sta ldx lda mul add sta bcc incx NOINC1: clr ais #-6T ; Separa 6 niveles de la pila ; Esta sección Multiplica [INTACC1:INTACC1+1]xINTACC2+1 INTACC1+1 ; Carga los dos primeros operandos INTACC2+1 ; Multiplica los dos operandos anteriores 6,SP ; Almacena temporalmente la parte alta del resultado INTACC1+3 ; Almacena la parte baja del resultado INTACC1 ; Carga los otros dos operandos INTACC2+1 ; Multiplica los dos operandos anteriores 6,SP ; Tiene en cuenta el acarreo anterior 2,SP ; Almacena el producto intermedio NOINC1 ; Verifica si hay acarreo en la suma anterior ; Incrementa en caso de acarreo stx 1,SP ; Almacena producto intermedio 6,SP ; Borra el acarreo ; Esta sección Multiplica [INTACC1:INTACC1+1]xINTACC2 ldx lda mul stx sta ldx lda mul add sta bcc incx NOINC2: clr lda add sta lda adc sta lda adc sta ais INTACC1+1 ; Carga los dos primeros operandos INTACC2 ; Multiplica los dos operandos anteriores 6,SP ; Almacena temporalmente la parte alta del resultado 5,SP ; Almacena el producto intermedio INTACC1 ; Carga los otros dos operandos INTACC2 ; Multiplica los dos operandos anteriores 6,SP ; Tiene en cuenta el acarreo anterior 4,SP ; Almacena el producto intermedio NOINC2 ; Verifica si hay acarreo en la suma anterior ; Incrementa en caso de acarreo stx 3,SP ; Almacena producto intermedio 6,SP ; Borra el acarreo ; Esta sección suma los resultados intermedios 2,SP ; Suma los dos primeros productos intermedios 5,SP INTACC1+2 ; Almacena el resultado 1,SP ; Suma los otros productos intermedios 4,SP ; Tiene en cuenta el acarreo de la suma anterior INTACC1+1 ; Almacena el resultado 3,SP ; Suma el último operando #$00 ; Tiene en cuenta el acarreo INTACC1 ; Almacena el resultado #$06 ; Reestablece la posición del puntero de pila ******************************************************************************** * Subrutina de SUMA 32+32, RESULTADO 32 BITS en INTACC1 CON VALADC DE 255 ES SUFICIENTE 32 BITS * ******************************************************************************** SUM32: lda INTACC1+3 ;CARGO PARTE BAJA DE SUMANDO 1 add INTACC3+3 ;SUMO CON PARTE BAJA DE SUMANDO 2 sta INTACC1+3 ; guardo resultado parte 3 clra adc INTACC1+2 sta INTACC1+2 lda INTACC1+2 add INTACC3+2 ; SUMO ACARREO A SEGUNDA PARTE DE INTACC1 ; GUARDO SUMA DE CARRY EN INTACC1+2 ; PARA LUEGO SUMARLO CON SEGUNDA PARTE DE INTACC3 sta ; guardo resultado parte 2 INTACC1+2 clra adc INTACC1+1 sta INTACC1+1 ; GUARDO SUMA DE CARRY EN INTACC1+1 lda INTACC1+1 add INTACC3+1 sta INTACC1+1 clra adc INTACC1 sta INTACC1 add INTACC3 sta INTACC1 ; guardo resultado parte 1 ; GUARDO SUMA DE CARRY EN INTACC1+1 ; guardo resultado parte 0 ******************************************************************************** * Subrutina de DIVISION 32/16, RESULTADO 8 BITS en INTACC1+1 O 32 BIT TODO INTACC1 * ******************************************************************************** DIV32: ais #-3 ; Reserva 3 niveles de la pila lda #32 ; Carga el contador (32 iteraciones) sta 3,SP lda INTACC4 ; Carga el divisor parte alta en la pila sta 1,SP lda INTACC4+1 ; Carga el divisor parte baja en la pila sta 2,SP mov INTACC1+3,INTACC4+1 ; Cambia de posición el dividendo mov INTACC1+2,INTACC4 mov INTACC1+1,INTACC1+3 mov INTACC1,INTACC1+2 clr INTACC1 ; Pone en ceros el residuo clr INTACC1+1 LAZO_DIV: lda INTACC1 ; Pone el MSB del residuo en el bit de acarreo rola rol INTACC4+1 ; Rota a la izquierda el dividendo rol INTACC4 rol INTACC1+3 rol INTACC1+2 rol INTACC1+1 ; Rota a la izquierda el residuo rol INTACC1 lda INTACC1+1 ; Resta el LSB del divisor del residuo del LSB sub 2,SP sta INTACC1+1 ; Almacena el resultado parte baja lda INTACC1 ; Resta el MSB del divisor del residuo del MSB sbc 1,SP sta INTACC1 lda INTACC4+1 ; Tiene en cuenta el acarreo de la resta sbc #$00 sta INTACC4+1 ; Verifica si la resta da negativa o no brclr 0,INTACC4+1,UNO lda INTACC1+1 ; Suma el LSB del divisor del residuo del LSB add 2,SP sta INTACC1+1 ; Almacena el resultado parte baja lda INTACC1 ; Resta el MSB del divisor del residuo del MSB adc 1,SP sta INTACC1 lda INTACC4+1 ; Tiene en cuenta el acarreo de la suma adc #$00 sta INTACC4+1 bra DEC_CONT ; Decrementa el contador UNO: bset 0,INTACC4+1 ; Pone 1 en el LSB del divisor indicando resta DEC_CONT: dbnz 3,SP,LAZO_DIV ; Salta de nuevo si el contador no es cero lda INTACC1 ; Almacena temporalmente el residuo en la pila sta 1,SP lda INTACC1+1 sta 2,SP ; Cambia de posición el dividendo mov INTACC1+2,INTACC1 mov INTACC1+3,INTACC1+1 mov INTACC4,INTACC1+2 mov INTACC4+1,INTACC1+3 lda 1,SP ; Retorna el residuo de la pila sta INTACC4 lda 2,SP sta INTACC4+1 ais #$03 ; Regresa el puntero de pila a su posición inicial lda sta clrh clrx clra INTACC1+3 VALBS ;EL RESULTADO ES DE 8 BITS ; LIMPIO REGISTROS rts ;***************************************************************************** ;subrutina retardo Implementada con dos ciclos anidados -> Tret=[8+9k1+5K1K2]T T=0.4uS RETARDO mov #100,K1 ; Carga constante de retardo 1 LAZO1 mov #100,K2 ; Carga constante de retardo 2 dbnz K2,* ; Ciclo interno dbnz K1,LAZO1 ; Ciclo externo rts ;subrutina retardo Implementada con dos ciclos anidados -> Tret=[8+9k1+5K1K2]T T=0.4uS RETARDO2 mov #255,K1 ; Carga constante de retardo 1 LAZO2 mov #255,K2 ; Carga constante de retardo 2 dbnz K2,* ; Ciclo interno dbnz K1,LAZO2 ; Ciclo externo rts ;________________________________________________________________________________ ;SUBRUTINA PARA CONVERSION DE HEXADECIMAL A BCD (QUEDA CADA DIGITO EN HEXADECIMAL) HEX2BCDLBS lda VALBS clr CONT_DECE ; Contador de unidades en cero cbeqa #$00,SALIR ; Verifica si el número es cero DEC_10: sub #10 ; Resta 10 bcs INC_10 ; Salta si hay acarreo cuando la resta es negativa inc CONT_DECE bra DEC_10 INC_10: add #10 ; Suma 10 en caso de resta negativa SALIR: sta DIG2LBS ; Cargo unidades en DIG2 mov CONT_DECE,DIG1LBS ; Cargo decenas en DIG1 lda lda DIG2LBS DIG1LBS lda FLAGPULPAC cbeqa #1,CARGAR98 bra CONTINUAR ;CARGO 98 PULPAC CARGAR98 mov #$8,DIG2LBS mov #$9,DIG1LBS CONTINUAR lda FLAGEMERG cbeqa #1,CARGAR99 bra FOLLOW ;CARGO 99 EMERGENCIA CARGAR99 mov #$9,DIG2LBS mov #$9,DIG1LBS FOLLOW rts ;________________________________________________________________________________ ; ENVIO VALOR DE LIBRAS A DISPLAY ALCDLBS: ldx DIG1LBS ; Digito a enviar mov #$04,DIRH mov #$04,DIRL jsr ENVLCD ; Cargo la dirección del LCD PARTE ALTA ; Cargo la dirección del LCD PARTE BAJA ldx DIG2LBS mov #$04,DIRH mov #$05,DIRL jsr ENVLCD rts ;________________________________________________________________________________ ; Subrutina ENVIA A LCD UN DIGITO EN UNA POSICION ESPECIFICADA POR DIRL Y DIRH UN VALOR QUE ENTRA EN x EN BCD Y LO PASA A ASCII DE LA TABLA PARA ENVIARLO AL LCD ENVLCD: 48 lda DIRH ;PARTE ALTA DIRECCION EN PTB BAJA (inicio de mensaje en posicion add #$08 ;sumo 8 a parte alta para incluir el 1 de D7 jsr LCD_ADDR ;Envia direccion parte alta a LCD lda DIRL ;PARTE BAJA DIRECCION EN PTB BAJA jsr LCD_ADDR ;Envia direccion parte baja a LCD lda ASCII,x nsa ;cargo parte alta del caracter señalado por reg. ind en PTB bajo jsr LCD_WRITE ;Envia dato a LCD lda ASCII,x ;cargo parte baja del caracter señalado por reg. ind queda en PTB bajo jsr LCD_WRITE rts ;________________________________________________________________________________ ; RUTINA CONVIERTE VALOR DE ADC A BCD Y ENVIA A LCD MODO CALIBRAR ALCDADC mov VALADC,NumAConv1 ;Cargo valor de adc en Numaconv1 Displ1: mov #$00,sustraen mov #$64,sustraen1 jsr Conversion_BCD mov contador,DIG1ADC ldx DIG1ADC mov #$04,DIRH mov #$0D,DIRL jsr ENVLCD ;Carga partes alta y baja de 100 ;(sustraen:sustraen+1). ;Salta a rutina Resta. ;Coloca en dig3 el resultado de la rutina Resta. ;Centenas Displ2: mov #$00,sustraen mov #$0A,sustraen1 jsr Conversion_BCD mov contador,DIG2ADC ;Cargaa partes alta y baja de 10 ;(sustraen:sustraen+1) ;Salta a rutina Resta. ;Coloca en dig2 el resultado de la rutina Resta. ldx DIG2ADC mov #$04,DIRH mov #$0E,DIRL jsr ENVLCD ;Decenas ;Envia a lcd a posicion $45 Displ3: mov NumAConv1,DIG3ADC ;Coloca en dig1 el ultimo valor que queda en NumAConv. ldx DIG3ADC ;correspondiente a las unidades mov #$04,DIRH mov #$0F,DIRL jsr ENVLCD rts ;________________________________________________________________________________ ;SUBRUTINA PARA CONVERSION DE HEXADECIMAL A BCD DE VALOR DE ADC Conversion_BCD: clr contador Repite: lda NumAConv1 convertir y primero sub sustraen1 sta NumAConv1 luego para bcc Massigni en contador las dec NumAConv para dig3 el sustraendo es Massigni: lda NumAConv quedan las unidades sub sustraen sta NumAConv bmi Salida_Resta inc contador bra Repite ;en esta parte para dig1 se trae el valor del numero a ;se resta 1000 hasta que de negativo, luego se suma mil y queda ;NumAConvertir menor a mil y en contador las unidades de mil, ;dig2 se resta del numero que quedo el sustraendo 100 quedando ;unidades de cien y NumAconv queda menor de 100, luego ;es 10 quedando en contador las decenas y en NumAConv Salida_Resta: lda NumAConv1 add sustraen1 sta NumAConv1 lda NumAConv adc sustraen sta NumAConv rts ;________________________________________________________________________________ ;SUBRUTINAS DE ENVIO MENSAJES A LCD MENSAJE1: lda #$04 ;PARTE ALTA DIRECCION EN PTB BAJA (inicio de mensaje en posicion 04) add #$08 ;sumo 8 a parte alta para incluir el 1 de D7 jsr LCD_ADDR lda #$00 jsr LCD_ADDR ;PARTE BAJA DIRECCION EN PTB BAJA clrx L1: lda MENS1,x nsa ;PARTE ALTA CARACTER DEL MENSAJE SE LLEVA A PTB BAJO beq FINMENS1 jsr LCD_WRITE lda MENS1,x ;PARTE BAJA CARACTER DEL MENSAJE QUEDA EN PTB BAJO jsr LCD_WRITE incx bra L1 FINMENS1: rts MENSAJE2: lda #$04 ;PARTE ALTA DIRECCION EN PTB BAJA (inicio de mensaje en posicion 09 add #$08 ;sumo 8 a parte alta para incluir el 1 de D7 jsr LCD_ADDR lda #$09 ;PARTE BAJA DIRECCION EN PTB BAJA jsr LCD_ADDR clrx L2: lda MENS2,x nsa ;cargo parte alta del caracter señalado por reg. ind en PTB bajo beq FINMENS2 jsr LCD_WRITE lda MENS2,x ;cargo parte baja del caracter señalado por reg. ind queda en PTB bajo jsr LCD_WRITE incx bra L2 FINMENS2: rts MENSAJE3: lda #$00 ;PARTE ALTA DIRECCION EN PTB BAJA (inicio de mensaje en posicion 04) add #$08 ;sumo 8 a parte alta para incluir el 1 de D7 jsr LCD_ADDR lda #$00 ;PARTE BAJA DIRECCION EN PTB BAJA jsr LCD_ADDR clrx L3: lda MENS3,x nsa ;PARTE ALTA CARACTER DEL MENSAJE SE LLEVA A PTB BAJO beq FINMENS3 jsr LCD_WRITE lda MENS3,x ;PARTE BAJA CARACTER DEL MENSAJE QUEDA EN PTB BAJO jsr LCD_WRITE incx bra L3 FINMENS3: rts MENSAJE4: lda #$00 ;PARTE ALTA DIRECCION EN PTB BAJA (inicio de mensaje en posicion 04) add #$08 ;sumo 8 a parte alta para incluir el 1 de D7 jsr LCD_ADDR lda #$00 ;PARTE BAJA DIRECCION EN PTB BAJA jsr LCD_ADDR clrx L4: lda MENS4,x nsa ;PARTE ALTA CARACTER DEL MENSAJE SE LLEVA A PTB BAJO beq FINMENS4 jsr LCD_WRITE lda MENS4,x ;PARTE BAJA CARACTER DEL MENSAJE QUEDA EN PTB BAJO jsr LCD_WRITE incx bra L4 FINMENS4: rts MENSAJE5: lda #$00 ;PARTE ALTA DIRECCION EN PTB BAJA (inicio de mensaje en posicion 04) add #$08 ;sumo 8 a parte alta para incluir el 1 de D7 jsr LCD_ADDR lda #$00 ;PARTE BAJA DIRECCION EN PTB BAJA jsr LCD_ADDR clrx L5: lda MENS5,x nsa ;PARTE ALTA CARACTER DEL MENSAJE SE LLEVA A PTB BAJO beq FINMENS5 jsr LCD_WRITE lda MENS5,x ;PARTE BAJA CARACTER DEL MENSAJE QUEDA EN PTB BAJO jsr LCD_WRITE incx bra L5 FINMENS5: rts ;RUTINAS INTERRUPCIONES ****************************************************** INT_TOF1 bclr TOF,T1SC ; borra bandera de sobreflujo ; SI NO BORRO BANDERA SE BLOQUEA PROGRAMA rti ; ****************************************************************************** INT_REC: lda SCS1 ; Borra bandera de receptor lleno lda SCDR ; Carga dato del registro de receptor cbeqa #'0',CERO cbeqa #'T',TENS cbeqa #'R',RELA cbeqa #'P',PARA jmp SALIR_REC ; Envia 0% de DC ; Tensionar ; Relajar ; Parar TENS jsr TENSIONAR jmp SALIR_REC RELA jsr RELAJAR jmp SALIR_REC PARA jsr PARAR jmp SALIR_REC ;________________________________________________________________________________ ;ENVIO VALOR LIBRAS DE TENSION CERO jsr HEX2BCDLBS brclr 7,SCS1,* ; Verifica que el transmisor este vacio lda DIG1LBS ; Envía DECENAS en ASCII (HEX + 30 = ASCII) add #$30 sta SCDR brclr lda add sta 7,SCS1,* DIG2LBS #$30 SCDR ; Verifica que el transmisor este vacio ; ENVIO UNIDADES lda DIG1LBS cbeqa #$9,VERDIG2 bra SALIR_REC VERDIG2 lda DIG2LBS cbeqa #$8,CLRFP cbeqa #$9,CLRFE bra SALIR_REC CLRFP clr FLAGPULPAC bra SALIR_REC clr FLAGEMERG CLRFE SALIR_REC: rti ;TABLAS ********************************************************************** MENS1: MENS2: MENS3: MENS4: MENS5: dc.b 'LBS:' ; cada letra corresponde a 8 bits de memoria en ASCII dc.b 0 dc.b 'ADC:' dc.b 0 dc.b 'PUL PACIENTE ON' dc.b 0 dc.b 'PUL EMERGENCY ON' dc.b 0 dc.b ' ';BORRA LINEA SUPERIOR DE LCD dc.b 0 ;**************************************************************************** ; Tabla de caracteres en ASCII convierte BCD a ASCII ASCII dc.b '0' dc.b '1' dc.b '2' dc.b '3' dc.b '4' dc.b '5' dc.b '6' dc.b '7' dc.b '8' dc.b '9' ;**************************************************************************** ; Definición de vectores de interrupción org dc.w org dc.w org dc.w INT_RESET ; Vector de reset INICIO INT_TIM1Ovr ; Vector de sobreflujo del TIM1 INT_TOF1 INT_SCIReceive ; vector de interrupcion por recepción SCI INT_REC ANEXO 2. CODIGO JAVA PROGRAMA PRINCIPAL package com.example.traccion; import android.os.Bundle; import android.app.Activity; import android.content.Intent; import android.view.Menu; import android.view.View; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return true; } public void eventoProtocolos(View v) { Intent intent = new Intent(this, ProtocolosActivity.class); startActivity(intent); } public void eventoManual(View v) { Intent intent = new Intent(this, ManualActivity.class); startActivity(intent); } } PROGRAMA PARA INGRESO DE DATOS MODO MANUAL package com.example.traccion; import android.os.Bundle; import android.app.Activity; import android.content.Intent; import android.view.Menu; import android.view.View; public class ManualActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_manual); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.manual, menu); return true; } public void eventoEstatico(View v) { Intent intent = new Intent(this, RutinaEstaticoActivity.class); startActivity(intent); } public void eventoIntermitente(View v) { Intent intent = new Intent(this, RutinaIntermitenteActivity.class); startActivity(intent); } public void eventoProgresivo(View v) { Intent intent = new Intent(this, SubMenuProgresivoActivity.class); startActivity(intent); } } POGRAMA MODO PROTOCOLOS package com.example.traccion; import java.util.ArrayList; import android.os.Bundle; import android.app.Activity; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; import android.view.View; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; public class ProtocolosActivity extends Activity { private Context context; private int pesoInd = 0; private int alturaInd = 0; private int edadInd = 0; private String exc = ""; Integer[] vectorEstatico = new Integer[]{ 10, 15, 12, 12, 15, 13, 10, 15, 12, 12, 18, 15, 14, 16, 15, 15, 18, 16, 18, 16, 15, 20, 20, 18, 20, 20, 18 }; Integer[] vectorNoEstatico = new Integer[]{ 30, 40, 20, 30, 35, 25, 35, 40, 30, 35, 45, 25, 35, 40, 30, 40, 45, 35, 40, 50, 30, 40, 45, 35, 45, 50, 40 }; Integer[] vectorPasosProgEstatico = new Integer[]{ 3, 4, 2, 3, 3, 2, 3, 4, 3, 3, 4, 2, 3, 4, 3, 4, 4, 3, 4, 5, 3, 4, 4, 3, 4, 5, 4 }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_protocolos); context = this; } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.protocolos, menu); return true; } public void eventoCuello(View v) { AlertDialog.Builder builder = new AlertDialog.Builder(this); // Get the layout inflater LayoutInflater inflater = this.getLayoutInflater(); builder.setTitle("Configurar Protocolo"); // Inflate and set the layout for the dialog // Pass null as the parent view because its going in the dialog layout final View view = inflater.inflate(R.layout.protocolos_config_dialog, null); builder.setView(view) // Add action buttons .setPositiveButton("Aceptar", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { EditText editPeso = (EditText)view.findViewById(R.id.editPeso); EditText editAltura = (EditText)view.findViewById(R.id.editAltura); EditText editEdad = (EditText)view.findViewById(R.id.editEdad); int peso = Integer.valueOf(editPeso.getText().toString()); int altura = Integer.valueOf(editAltura.getText().toString()); int edad = Integer.valueOf(editEdad.getText().toString()); if( calcularIndex(peso , altura , edad) ) { int index = (pesoInd*9) + (alturaInd*3) + (edadInd); Intent intent = new Intent(context, RutinaEstaticoActivity.class); intent.putExtra("tiempoProgramado", 10); intent.putExtra("librasProgramadas", vectorEstatico[index]); startActivity(intent); } else { Toast.makeText(context, exc, Toast.LENGTH_LONG).show(); } } }) .setNegativeButton("Cancelar", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub } }); builder.create(); builder.show(); } public void eventoLumbar(View v) { AlertDialog.Builder builder = new AlertDialog.Builder(this); // Get the layout inflater LayoutInflater inflater = this.getLayoutInflater(); builder.setTitle("Configurar Protocolo"); // Inflate and set the layout for the dialog // Pass null as the parent view because its going in the dialog layout final View view = inflater.inflate(R.layout.protocolos_config_dialog, null); builder.setView(view) // Add action buttons .setPositiveButton("Aceptar", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { EditText editPeso = (EditText)view.findViewById(R.id.editPeso); EditText editAltura = (EditText)view.findViewById(R.id.editAltura); EditText editEdad = (EditText)view.findViewById(R.id.editEdad); int peso = Integer.valueOf(editPeso.getText().toString()); int altura = Integer.valueOf(editAltura.getText().toString()); int edad = Integer.valueOf(editEdad.getText().toString()); if( calcularIndex(peso , altura , edad) ) { int index = (pesoInd*9) + (alturaInd*3) + (edadInd); Intent intent = new Intent(context, RutinaIntermitenteActivity.class); intent.putExtra("tiempoProgramado", 10); intent.putExtra("librasProgramadas", vectorNoEstatico[index]); intent.putExtra("tiempoHold", 10); intent.putExtra("tiempoDescanso", 15); intent.putExtra("librasMinimas", startActivity(intent); } else { Toast.makeText(context, exc, Toast.LENGTH_LONG).show(); } } }) .setNegativeButton("Cancelar", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub } }); builder.create(); builder.show(); } 0); public void eventoHerniaDiscal(View v) { AlertDialog.Builder builder = new AlertDialog.Builder(this); // Get the layout inflater LayoutInflater inflater = this.getLayoutInflater(); builder.setTitle("Configurar Protocolo"); // Inflate and set the layout for the dialog // Pass null as the parent view because its going in the dialog layout final View view = inflater.inflate(R.layout.protocolos_config_dialog, null); builder.setView(view) // Add action buttons .setPositiveButton("Aceptar", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { EditText editPeso = (EditText)view.findViewById(R.id.editPeso); EditText editAltura = (EditText)view.findViewById(R.id.editAltura); EditText editEdad = (EditText)view.findViewById(R.id.editEdad); int peso = Integer.valueOf(editPeso.getText().toString()); int altura = Integer.valueOf(editAltura.getText().toString()); int edad = Integer.valueOf(editEdad.getText().toString()); if( calcularIndex(peso , altura , edad) ) { int index = (pesoInd*9) + (alturaInd*3) + (edadInd); Intent intent = new Intent(context, RutinaProgresivoEstaticoActivity.class); intent.putExtra("tiempoProgramado", 10); intent.putExtra("librasProgramadas", vectorNoEstatico[index]); intent.putExtra("tiempoHold", intent.putExtra("pasoLibras", vectorPasosProgEstatico[index]); startActivity(intent); } else { Toast.makeText(context, exc, Toast.LENGTH_LONG).show(); } } }) .setNegativeButton("Cancelar", new DialogInterface.OnClickListener() { 15); @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub } }); builder.create(); builder.show(); } public void eventoLumbalgia(View v) { AlertDialog.Builder builder = new AlertDialog.Builder(this); // Get the layout inflater LayoutInflater inflater = this.getLayoutInflater(); builder.setTitle("Configurar Protocolo"); // Inflate and set the layout for the dialog // Pass null as the parent view because its going in the dialog layout final View view = inflater.inflate(R.layout.protocolos_config_dialog, null); builder.setView(view) // Add action buttons .setPositiveButton("Aceptar", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { EditText editPeso = (EditText)view.findViewById(R.id.editPeso); EditText editAltura = (EditText)view.findViewById(R.id.editAltura); EditText editEdad = (EditText)view.findViewById(R.id.editEdad); int peso = Integer.valueOf(editPeso.getText().toString()); int altura = Integer.valueOf(editAltura.getText().toString()); int edad = Integer.valueOf(editEdad.getText().toString()); if( calcularIndex(peso , altura , edad) ) { int index = (pesoInd*9) + (alturaInd*3) + (edadInd); Intent intent = new Intent(context, RutinaProgresivoCiclicoActivity.class); intent.putExtra("tiempoProgramado", 10); intent.putExtra("librasProgramadas", vectorNoEstatico[index]); intent.putExtra("tiempoHold", intent.putExtra("pasoLibras", intent.putExtra("tiempoDescanso", 5); 5); 10); startActivity(intent); } else { Toast.makeText(context, exc, Toast.LENGTH_LONG).show(); } } }) .setNegativeButton("Cancelar", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub } }); builder.create(); builder.show(); } public void eventoCronicaVertebral(View v) { AlertDialog.Builder builder = new AlertDialog.Builder(this); // Get the layout inflater LayoutInflater inflater = this.getLayoutInflater(); builder.setTitle("Configurar Protocolo"); // Inflate and set the layout for the dialog // Pass null as the parent view because its going in the dialog layout final View view = inflater.inflate(R.layout.protocolos_config_dialog, null); builder.setView(view) // Add action buttons .setPositiveButton("Aceptar", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { EditText editPeso = (EditText)view.findViewById(R.id.editPeso); EditText editAltura = (EditText)view.findViewById(R.id.editAltura); EditText editEdad = (EditText)view.findViewById(R.id.editEdad); int peso Integer.valueOf(editPeso.getText().toString()); int altura Integer.valueOf(editAltura.getText().toString()); int edad Integer.valueOf(editEdad.getText().toString()); = = = if( calcularIndex(peso , altura , edad) ) { int index = (pesoInd*9) + (alturaInd*3) + (edadInd); Intent intent = new Intent(context, RutinaProgresivoRegresivoActivity.class); intent.putExtra("tiempoProgramado", 10); intent.putExtra("librasProgramadas", vectorNoEstatico[index]); intent.putExtra("tiempoHold", intent.putExtra("pasoLibras", intent.putExtra("tiempoDescanso", startActivity(intent); } else { Toast.makeText(context, exc, Toast.LENGTH_LONG).show(); } } }) .setNegativeButton("Cancelar", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub } }); builder.create(); builder.show(); } public void eventoAgudaVertebral(View v) { AlertDialog.Builder builder = new AlertDialog.Builder(this); // Get the layout inflater LayoutInflater inflater = this.getLayoutInflater(); builder.setTitle("Configurar Protocolo"); // Inflate and set the layout for the dialog // Pass null as the parent view because its going in the dialog layout final View view = inflater.inflate(R.layout.protocolos_config_dialog, null); builder.setView(view) // Add action buttons .setPositiveButton("Aceptar", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { EditText editPeso = (EditText)view.findViewById(R.id.editPeso); EditText editAltura = (EditText)view.findViewById(R.id.editAltura); 5); 5); 15); EditText editEdad (EditText)view.findViewById(R.id.editEdad); int peso Integer.valueOf(editPeso.getText().toString()); int altura Integer.valueOf(editAltura.getText().toString()); int edad Integer.valueOf(editEdad.getText().toString()); = = = = if( calcularIndex(peso , altura , edad) ) { int index = (pesoInd*9) + (alturaInd*3) + (edadInd); Intent intent = new Intent(context, RutinaProgresivoEstaticoActivity.class); intent.putExtra("tiempoProgramado", 10); intent.putExtra("librasProgramadas", vectorNoEstatico[index]); intent.putExtra("tiempoHold", 15); intent.putExtra("pasoLibras", vectorPasosProgEstatico[index]); startActivity(intent); } else { Toast.makeText(context, exc, Toast.LENGTH_LONG).show(); } } }) .setNegativeButton("Cancelar", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub } }); builder.create(); builder.show(); } private boolean calcularIndex(int peso , int altura , int edad) { boolean rangosOk = true; /////////////////// PESO /////////////////////////////////////////// if( (peso >= 40) && (peso <= 60) ) { pesoInd = 0; } else if( (peso > 60) && (peso <= 80) ) { pesoInd = 1; } else if( peso > 80 ) { pesoInd = 2; } else { rangosOk = false; exc = "Peso fuera de Rango."; } /////////////////// ALTURA if( (altura >= 150) && (altura <= 160) ) { alturaInd = 0; } else if( (altura > 160) && (altura <= 170) ) { alturaInd = 1; } else if( altura > 170 ) { alturaInd = 2; } else { rangosOk = false; exc = "Altura fuera de Rango."; } //////////////////////////////////// /////////////////// EDAD /////////////////////////////////////////// if( (edad >= 18) && (edad <= 30) ) { edadInd = 0; } else if( (edad > 30) && (edad <= 50) ) { edadInd = 1; } else if( edad > 50 ) { edadInd = 2; } else { rangosOk = false; exc = "Edad fuera de Rango."; } return rangosOk; } } PROGRAMA RUTINA MODO ESTÁTICO package com.example.traccion; import android.app.Activity; import android.app.AlertDialog; import android.graphics.*; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.SystemClock; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.WindowManager; import com.androidplot.xy.*; import com.androidplot.Plot; import com.androidplot.xy.SimpleXYSeries; import Drivers.BluetoothDriver; import java.io.IOException; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Random; import java.util.Set; import org.apache.http.message.LineParser; import android.os.Bundle; import android.provider.DocumentsContract.Document; import android.app.Activity; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.content.BroadcastReceiver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.graphics.Color; import android.view.Menu; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; public class RutinaEstaticoActivity extends Activity { Context context; private XYPlot plot; private XYSeries serieBase; private SimpleXYSeries serieReal = null; private BluetoothDriver blueDriver; private Thread hiloComandos = new Thread(); private int referencia = 10; long limitMuestreo = 1; long limitPuntoGrafico = 1000; private int tiempoRut; Number[] valoresBase; long base; long basePausa; String estadoRutinaStr = "Detenido"; String valorLibrasMedidas; String textoBtnPausa; int tiempoProgramado; int segTiempoProgramado; int librasProgramadas; private int COMANDO_PARAR private int COMANDO_RELAJAR private int COMANDO_TENSIONAR private int COMANDO_OBTENER_LIBRAS private boolean BANDERA_EN_CURSO private boolean BANDERA_FIN = 80; = 82; = 84; = 48; = false; = true; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_rutina_estatico); context = this; IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED); this.registerReceiver(mReceiver, filter); this.registerReceiver(mReceiverSetEstadoRutina, new IntentFilter("setEstadoRutina")); this.registerReceiver(mReceiverSetValorLibras, new IntentFilter("setValorLibras")); this.registerReceiver(mReceiverSetTextoBtnPausa, new IntentFilter("setTextoBtnPausa")); this.registerReceiver(mReceiverParadaUsuarioAlert, new IntentFilter("paradaUsuarioAlert")); this.registerReceiver(mReceiverParadaDoctorAlert, new IntentFilter("paradaDoctorAlert")); blueDriver = new BluetoothDriver(); blueDriverIni(); plot = (XYPlot) findViewById(R.id.mySimpleXYPlot); plot.setRangeStep(XYStepMode.INCREMENT_BY_VAL, 1); plot.setDomainStep(XYStepMode.INCREMENT_BY_VAL, 1); plot.setDomainValueFormat(new DecimalFormat("#")); plot.setRangeValueFormat(new DecimalFormat("#")); valoresBase = new Number[]{}; plot.setPlotPadding( 15 , 20 , 15 , 15 ); Bundle extras = getIntent().getExtras(); if( extras != null ) { tiempoProgramado librasProgramadas = extras.getInt("tiempoProgramado"); = extras.getInt("librasProgramadas"); TextView tProgramado = (TextView)(((RutinaEstaticoActivity)context).findViewById(R.id.txtTiempoProgramado)); TextView lProgramadas = (TextView)(((RutinaEstaticoActivity)context).findViewById(R.id.txtLibrasProgramadas)); tProgramado.setText(String.valueOf(tiempoProgramado) + " m"); lProgramadas.setText(String.valueOf(librasProgramadas) + " lb"); valoresBase = new Number[(int)tiempoProgramado*60]; valoresBase[0] = 0; for(int i=1 ; i<valoresBase.length ; i++) { valoresBase[i] = librasProgramadas; Log.w("valoresBase", String.valueOf(valoresBase[i])); } resetSerieBase(); } } private void blueDriverIni() { // TODO Auto-generated method stub if(blueDriver.isBlueDriverReady()) { Log.w("Socket_Est", "Bluetooth listo."); Set<BluetoothDevice> pairedDevices = blueDriver.getDevices(); boolean dispEncontrado = false; for(BluetoothDevice bt : pairedDevices) { if(bt.getName().toString().equals("Traccion")) { if(blueDriver.abrirSocket(bt)) { Toast.makeText(getApplicationContext(),"Conectado.",Toast.LENGTH_LONG).show(); Log.w("Socket_Est", "Bluetooth Conectado."); } else { Toast.makeText(getApplicationContext(),"Error al conectar.",Toast.LENGTH_LONG).show(); } dispEncontrado = true; } } if(!dispEncontrado) { Toast.makeText(getApplicationContext(),"El dispositivo no ha sido encontrado.",Toast.LENGTH_LONG).show(); Log.w("Socket_Est", "El dispositivo no ha sido encontrado."); } } else { Intent turnOn = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(turnOn, 0); } } public void eventoIniciar(View v) { Log.w("BANDERA_EN_CURSO", String.valueOf(BANDERA_EN_CURSO) ); Log.w("BANDERA_FIN", String.valueOf(BANDERA_FIN) ); Log.w("Estado_Hilo", String.valueOf(hiloComandos.isAlive())); if(blueDriver.isBlueDriverconnected() && blueDriver.isBlueDriverReady()) { if(!hiloComandos.isAlive()) { setReferencia(); } } else { Toast.makeText(this, "Dispositivo de tracción no conectado.", Toast.LENGTH_LONG).show(); } } public void eventoPausa(View v) { if( BANDERA_FIN == false ) { Button btn = (Button)v; if(btn.getText().toString().equals("Pausa")) { btn.setText("Continuar"); BANDERA_EN_CURSO = false; basePausa = SystemClock.uptimeMillis()-base; ordenSalida(COMANDO_PARAR); SetEstadoRutina("Pausado"); } else // Continuar { btn.setText("Pausa"); BANDERA_EN_CURSO = true; base = SystemClock.uptimeMillis() - basePausa; SetEstadoRutina("En Curso"); } } } public void eventoParar(View v) { if( BANDERA_FIN == false ) { BANDERA_FIN = true; resetSerieReal(); ((Button)findViewById(R.id.btnPausa)).setText("Detenido"); SetEstadoRutina("Detenido"); resetValorLibras(); resetValorTiempoProgramado(); } } public void eventoProgramar(View v) { AlertDialog.Builder builder = new AlertDialog.Builder(this); // Get the layout inflater LayoutInflater inflater = this.getLayoutInflater(); builder.setTitle("Configurar Rutina"); // Inflate and set the layout for the dialog // Pass null as the parent view because its going in the dialog layout final View view = inflater.inflate(R.layout.estatico_config_dialog, null); builder.setView(view) // Add action buttons .setPositiveButton("Aceptar", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { EditText tProg = (EditText)view.findViewById(R.id.editTiempoProgramado); EditText libProg = (EditText)view.findViewById(R.id.editLibrasProgramadas); tiempoProgramado Integer.valueOf(tProg.getText().toString()); librasProgramadas Integer.valueOf(libProg.getText().toString()); = = TextView tProgramado = (TextView)(((RutinaEstaticoActivity)context).findViewById(R.id.txtTiempoProgramado)); TextView lProgramadas = (TextView)(((RutinaEstaticoActivity)context).findViewById(R.id.txtLibrasProgramadas)); tProgramado.setText(String.valueOf(tiempoProgramado) + " m"); lProgramadas.setText(String.valueOf(librasProgramadas) + " lb"); ArrayList<Integer> base = new ArrayList<Integer>(); valoresBase = new Number[(int)tiempoProgramado*60]; resetSerieReal(); valoresBase[0] = 0; for(int i=1 ; i<valoresBase.length ; i++) { valoresBase[i] = librasProgramadas; Log.w("valoresBase", String.valueOf(valoresBase[i])); } resetSerieBase(); } }) .setNegativeButton("Cancelar", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub } }); builder.create(); builder.show(); } private void setReferencia() { hiloComandos = new Thread( new Runnable(){ @Override public void run(){ Looper.prepare(); BANDERA_FIN = false; base long actMuestreo int actPuntoGrafico BANDERA_EN_CURSO = true; irACero(); resetSerieReal(); = SystemClock.uptimeMillis(); = SystemClock.uptimeMillis(); = -1; textoBtnPausa = "Pausa"; context.sendBroadcast(new Intent("setTextoBtnPausa")); estadoRutinaStr = "En Curso"; context.sendBroadcast(new Intent("setEstadoRutina")); segTiempoProgramado = 0; while(!BANDERA_FIN) { Log.w("Socket_getLibras_EnCurso", "Si"); if(BANDERA_EN_CURSO) { int tiempoRutina = (int)( (SystemClock.uptimeMillis()-base)/1000); Integer val = blueDriver.getLibras(); valorLibrasMedidas = String.valueOf(val); Log.w("Socket_getLibras_Leido", "Leido : " + String.valueOf(val)); if( val > -1) { context.sendBroadcast(new Intent("setValorLibras")); if( tiempoRutina < valoresBase.length ) { referencia = (Integer) valoresBase[(int) tiempoRutina]; if( Math.abs( SystemClock.uptimeMillis() - actMuestreo ) >= limitMuestreo ) { if( Math.abs(val referencia) > 2 ) { if( val < referencia ) { ordenSalida(COMANDO_TENSIONAR); } else if( val > referencia ) { ordenSalida(COMANDO_RELAJAR); } } else { ordenSalida(COMANDO_PARAR); } actMuestreo = SystemClock.uptimeMillis(); } if( tiempoRutina != actPuntoGrafico ) { serieReal.addLast(null, val); plot.redraw(); actPuntoGrafico = tiempoRutina; Log.w("Segundo", String.valueOf(((int) tiempoRutina))); } } else { BANDERA_FIN = true; } } else { resetSerieReal(); BANDERA_FIN = true; if( val == -1 ) context.sendBroadcast(new Intent("paradaDoctorAlert")); else if ( val == -2 ) context.sendBroadcast(new Intent("paradaUsuarioAlert")); } } else { ordenSalida(COMANDO_PARAR); } } irACero(); base = SystemClock.uptimeMillis(); valorLibrasMedidas = ""; context.sendBroadcast(new Intent("setValorLibras")); estadoRutinaStr = "Detenido"; context.sendBroadcast(new Intent("setEstadoRutina")); } }); hiloComandos.start(); } public void irACero() { Integer val = blueDriver.getLibras(); if( val > 0) { ordenSalida(COMANDO_RELAJAR); while( blueDriver.getLibras() > 0 ){} ordenSalida(COMANDO_PARAR); } } private void SetEstadoRutina(String estado) { TextView tv = (TextView)findViewById(R.id.txtEstadoRutina); tv.setText(estado); } private void resetValorLibras() { TextView tv = (TextView)findViewById(R.id.txtLibrasMedidas); tv.setText(""); } private void resetValorTiempoProgramado() { TextView tv = (TextView)findViewById(R.id.txtTiempoProgramado); tv.setText(String.valueOf(tiempoProgramado) + " m"); } private void ordenSalida(int comando) { try { blueDriver.trigger(comando); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private void resetSerieReal() { plot.removeSeries(serieReal); serieReal = new SimpleXYSeries( Arrays.asList(new Number[]{}), // SimpleXYSeries takes a List so turn our array into a List SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, // Y_VALS_ONLY means use the element index as the x value "Real"); // Set the display title of the series LineAndPointFormatter series1Format = new LineAndPointFormatter(Color.GREEN, Color.TRANSPARENT, Color.TRANSPARENT, new PointLabelFormatter(Color.TRANSPARENT)); series1Format.getLinePaint().setStrokeWidth(4); plot.addSeries(serieReal, series1Format); plot.redraw(); } private void resetSerieBase() { plot.removeSeries(serieBase); serieBase = new SimpleXYSeries( Arrays.asList(valoresBase), SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "Programada"); Paint lineFill = new Paint(); lineFill.setAlpha(600); lineFill.setShader(new LinearGradient(0, 0, 0, 250, Color.WHITE, Color.WHITE, Shader.TileMode.MIRROR)); StepFormatter stepFormatter = new StepFormatter(Color.rgb(0, 0, 0), Color.BLACK); stepFormatter.getLinePaint().setStrokeWidth(3); stepFormatter.getLinePaint().setAntiAlias(false); stepFormatter.setFillPaint(lineFill); Paint pointPaint = new Paint(); pointPaint.setColor(Color.TRANSPARENT); stepFormatter.setVertexPaint(pointPaint); plot.addSeries(serieBase, stepFormatter); plot.setRangeBoundaries(0, BoundaryMode.FIXED, 50, BoundaryMode.GROW); plot.setTicksPerRangeLabel(5); Double dProg = (Double.valueOf(tiempoProgramado)*60)/15; int pasoDominio = (int)Math.floor(dProg); plot.setTicksPerDomainLabel(pasoDominio); plot.setDomainUpperBoundary( pasoDominio*16 , BoundaryMode.FIXED ); plot.setRangeUpperBoundary( ( librasProgramadas*1.4) , BoundaryMode.FIXED ); plot.redraw(); } private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) { final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR); switch (state) { case BluetoothAdapter.STATE_OFF: break; case BluetoothAdapter.STATE_TURNING_OFF: break; case BluetoothAdapter.STATE_ON: blueDriverIni(); break; case BluetoothAdapter.STATE_TURNING_ON: break; } } } }; private final BroadcastReceiver mReceiverSetEstadoRutina = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { TextView tv = (TextView)findViewById(R.id.txtEstadoRutina); tv.setText(estadoRutinaStr); } }; private final BroadcastReceiver mReceiverSetValorLibras = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { TextView tv = (TextView)findViewById(R.id.txtLibrasMedidas); if( !valorLibrasMedidas.equals("") ) tv.setText(valorLibrasMedidas + " lb"); else tv.setText(""); int tiempoRutina = (int)( ( (SystemClock.uptimeMillis()-base)/1000)/60 ); TextView tProgramado = (TextView)(((RutinaEstaticoActivity)context).findViewById(R.id.txtTiempoProgramado)); tProgramado.setText(String.valueOf(tiempoProgramado - tiempoRutina) + " m"); } }; private final BroadcastReceiver mReceiverSetTextoBtnPausa = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Button btn = (Button)findViewById(R.id.btnPausa); btn.setText(textoBtnPausa); } }; private final BroadcastReceiver mReceiverParadaUsuarioAlert = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { paradaUsuarioAlertShow(); } }; private final BroadcastReceiver mReceiverParadaDoctorAlert = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { paradaDoctorAlertShow(); } }; public void paradaUsuarioAlertShow(){ AlertDialog.Builder builder = new AlertDialog.Builder(this); // Get the layout inflater LayoutInflater inflater = this.getLayoutInflater(); builder.setTitle("Parada Activada"); // Inflate and set the layout for the dialog // Pass null as the parent view because its going in the dialog layout final View view = inflater.inflate(R.layout.parada_usuario_dialog, null); builder.setView(view) // Add action buttons .setPositiveButton("Aceptar", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }); builder.create(); builder.show(); } public void paradaDoctorAlertShow(){ AlertDialog.Builder builder = new AlertDialog.Builder(this); // Get the layout inflater LayoutInflater inflater = this.getLayoutInflater(); builder.setTitle("Parada Activada"); // Inflate and set the layout for the dialog // Pass null as the parent view because its going in the dialog layout final View view = inflater.inflate(R.layout.parada_doctor_dialog, null); builder.setView(view) // Add action buttons .setPositiveButton("Aceptar", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }); builder.create(); builder.show(); } @Override public void onBackPressed() { if(BANDERA_FIN) this.finish(); else Toast.makeText(this, "Rutina en proceso.", Toast.LENGTH_LONG).show(); } @Override public void onDestroy() { super.onDestroy(); if(BANDERA_FIN) { this.unregisterReceiver(mReceiver); this.unregisterReceiver(mReceiverSetEstadoRutina); this.unregisterReceiver(mReceiverSetValorLibras); this.unregisterReceiver(mReceiverSetTextoBtnPausa); this.unregisterReceiver(mReceiverParadaUsuarioAlert); this.unregisterReceiver(mReceiverParadaDoctorAlert); try { blueDriver.trigger(COMANDO_PARAR); blueDriver.cerrarSocket(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.rutina_estatico, menu); return true; } } PROGRAMA MODO INTERMITENTE package com.example.traccion; import android.app.Activity; import android.app.AlertDialog; import android.graphics.*; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.SystemClock; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.WindowManager; import com.androidplot.xy.*; import com.androidplot.Plot; import com.androidplot.xy.SimpleXYSeries; import Drivers.BluetoothDriver; import java.io.IOException; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Random; import java.util.Set; import org.apache.http.message.LineParser; import android.os.Bundle; import android.provider.DocumentsContract.Document; import android.app.Activity; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.content.BroadcastReceiver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.graphics.Color; import android.view.Menu; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; public class RutinaIntermitenteActivity extends Activity { Context context; private XYPlot plot; private XYSeries serieBase; private SimpleXYSeries serieReal = null; private BluetoothDriver blueDriver; private Thread hiloComandos = new Thread(); private int referencia = 10; long limitMuestreo = 1; long limitPuntoGrafico = 1000; private int tiempoRut; Number[] valoresBase; long base; long basePausa; String estadoRutinaStr = "Detenido"; String valorLibrasMedidas; String textoBtnPausa; int segTiempoProgramado; int tiempoProgramado; int librasProgramadas; int tiempoHold; int tiempoDescanso; int librasMinimas; private int COMANDO_PARAR private int COMANDO_RELAJAR private int COMANDO_TENSIONAR private int COMANDO_OBTENER_LIBRAS private boolean BANDERA_PARAR private boolean BANDERA_PAUSA private boolean BANDERA_EN_CURSO private boolean BANDERA_FIN = 80; = 82; = 84; = 48; = false; = false; = false; = true; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_rutina_intermitente); context = this; IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED); this.registerReceiver(mReceiver, filter); this.registerReceiver(mReceiverSetEstadoRutina, new IntentFilter("setEstadoRutina")); this.registerReceiver(mReceiverSetValorLibras, new IntentFilter("setValorLibras")); this.registerReceiver(mReceiverSetTextoBtnPausa, new IntentFilter("setTextoBtnPausa")); this.registerReceiver(mReceiverParadaUsuarioAlert, new IntentFilter("paradaUsuarioAlert")); this.registerReceiver(mReceiverParadaDoctorAlert, new IntentFilter("paradaDoctorAlert")); blueDriver = new BluetoothDriver(); blueDriverIni(); plot = (XYPlot) findViewById(R.id.mySimpleXYPlot); plot.setRangeStep(XYStepMode.INCREMENT_BY_VAL, 1); plot.setDomainStep(XYStepMode.INCREMENT_BY_VAL, 1); plot.setDomainValueFormat(new DecimalFormat("#")); plot.setRangeValueFormat(new DecimalFormat("#")); valoresBase = new Number[]{}; plot.setPlotPadding( 15 , 20 , 15 , 15 ); Bundle extras = getIntent().getExtras(); if( extras != null ) { tiempoProgramado = extras.getInt("tiempoProgramado"); librasProgramadas = extras.getInt("librasProgramadas"); tiempoHold = extras.getInt("tiempoHold"); tiempoDescanso = extras.getInt("tiempoDescanso"); librasMinimas = extras.getInt("librasMinimas"); TextView tProgramado = (TextView)(((RutinaIntermitenteActivity)context).findViewById(R.id.txtTiempoProgramado)); TextView lProgramadas = (TextView)(((RutinaIntermitenteActivity)context).findViewById(R.id.txtLibrasProgramadas)); TextView tmHold = (TextView)(((RutinaIntermitenteActivity)context).findViewById(R.id.txtTiempoHold)); TextView tmDesc = (TextView)(((RutinaIntermitenteActivity)context).findViewById(R.id.txtTiempoDescanso)); TextView lbMin = (TextView)(((RutinaIntermitenteActivity)context).findViewById(R.id.txtLibrasMinimas)); tProgramado.setText(String.valueOf(tiempoProgramado) + " m"); lProgramadas.setText(String.valueOf(librasProgramadas) + " lb"); tmHold.setText(String.valueOf(tiempoHold) + " s"); tmDesc.setText(String.valueOf(tiempoDescanso) + " s"); lbMin.setText(String.valueOf(librasMinimas) + " lb"); ArrayList<Integer> base = new ArrayList<Integer>(); for(int i=0 ; i<tiempoDescanso ; i++) { base.add(librasMinimas); } for(int i=0 ; i<tiempoHold ; i++) { base.add(librasProgramadas + librasMinimas); } int tiempoProgramadoEnSeg = (int)(tiempoProgramado*60); valoresBase = new Number[tiempoProgramadoEnSeg]; boolean fin = false; int i = 0; int j = 0; while(!fin) { if( i < tiempoProgramadoEnSeg ) { valoresBase[i] = base.get(j); //valoresBaseList.add(base.get(j)); j++; i++; if( j == base.size() ) j = 0; } else { fin = true; } } resetSerieBase(); } } private void blueDriverIni() { // TODO Auto-generated method stub if(blueDriver.isBlueDriverReady()) { Log.w("Socket_Est", "Bluetooth listo."); Set<BluetoothDevice> pairedDevices = blueDriver.getDevices(); boolean dispEncontrado = false; for(BluetoothDevice bt : pairedDevices) { if(bt.getName().toString().equals("Traccion")) { if(blueDriver.abrirSocket(bt)) { Toast.makeText(getApplicationContext(),"Conectado.",Toast.LENGTH_LONG).show(); Log.w("Socket_Est", "Bluetooth Conectado."); } else { Toast.makeText(getApplicationContext(),"Error al conectar.",Toast.LENGTH_LONG).show(); } dispEncontrado = true; } } if(!dispEncontrado) { Toast.makeText(getApplicationContext(),"El dispositivo no ha sido encontrado.",Toast.LENGTH_LONG).show(); Log.w("Socket_Est", "El dispositivo no ha sido encontrado."); } } else { Intent turnOn = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(turnOn, 0); } } public void eventoIniciar(View v) { Log.w("estado", String.valueOf(hiloComandos.isAlive())); if(blueDriver.isBlueDriverconnected() && blueDriver.isBlueDriverReady()) { if(!hiloComandos.isAlive()) { setReferencia(); } } else { Toast.makeText(this, "Dispositivo de tracción no conectado.", Toast.LENGTH_LONG).show(); } } public void eventoPausa(View v) { if( BANDERA_FIN == false ) { Button btn = (Button)v; if(btn.getText().toString().equals("Pausa")) { btn.setText("Continuar"); BANDERA_EN_CURSO = false; basePausa = SystemClock.uptimeMillis()-base; ordenSalida(COMANDO_PARAR); SetEstadoRutina("Pausado"); } else // Continuar { btn.setText("Pausa"); BANDERA_EN_CURSO = true; base = SystemClock.uptimeMillis() - basePausa; SetEstadoRutina("En Curso"); } } } public void eventoParar(View v) { if( BANDERA_FIN == false ) { BANDERA_FIN = true; resetSerieReal(); ((Button)findViewById(R.id.btnPausa)).setText("Detenido"); SetEstadoRutina("Detenido"); resetValorLibras(); resetValorTiempoProgramado(); } } public void eventoProgramar(View v) { AlertDialog.Builder builder = new AlertDialog.Builder(this); // Get the layout inflater LayoutInflater inflater = this.getLayoutInflater(); builder.setTitle("Configurar Rutina"); // Inflate and set the layout for the dialog // Pass null as the parent view because its going in the dialog layout final View view = inflater.inflate(R.layout.intermitente_config_dialog, null); builder.setView(view) // Add action buttons .setPositiveButton("Aceptar", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { EditText tProg = (EditText)view.findViewById(R.id.editTiempoProgramado); EditText libProg = (EditText)view.findViewById(R.id.editLibrasProgramadas); EditText tHold = (EditText)view.findViewById(R.id.editTiempoHold); EditText tDesc (EditText)view.findViewById(R.id.editTiempoDescanso); EditText lMin (EditText)view.findViewById(R.id.editLibrasMinimas); = tiempoProgramado Integer.valueOf(tProg.getText().toString()); librasProgramadas Integer.valueOf(libProg.getText().toString()); tiempoHold Integer.valueOf(tHold.getText().toString()); tiempoDescanso Integer.valueOf(tDesc.getText().toString()); librasMinimas Integer.valueOf(lMin.getText().toString()); = = = = = = TextView tProgramado = (TextView)(((RutinaIntermitenteActivity)context).findViewById(R.id.txtTiempoProgramado)); TextView lProgramadas = (TextView)(((RutinaIntermitenteActivity)context).findViewById(R.id.txtLibrasProgramadas)); TextView tmHold = (TextView)(((RutinaIntermitenteActivity)context).findViewById(R.id.txtTiempoHold)); TextView tmDesc = (TextView)(((RutinaIntermitenteActivity)context).findViewById(R.id.txtTiempoDescanso)); TextView lbMin = (TextView)(((RutinaIntermitenteActivity)context).findViewById(R.id.txtLibrasMinimas)); tProgramado.setText(String.valueOf(tiempoProgramado) + " m"); lProgramadas.setText(String.valueOf(librasProgramadas) + " lb"); tmHold.setText(String.valueOf(tiempoHold) + " s"); tmDesc.setText(String.valueOf(tiempoDescanso) + " s"); lbMin.setText(String.valueOf(librasMinimas) + " lb"); ArrayList<Integer> base = new ArrayList<Integer>(); for(int i=0 ; i<tiempoDescanso ; i++) { base.add(librasMinimas); } for(int i=0 ; i<tiempoHold ; i++) { base.add(librasProgramadas + librasMinimas); } int tiempoProgramadoEnSeg = (int)(tiempoProgramado*60); valoresBase = new Number[tiempoProgramadoEnSeg]; boolean fin = false; int i = 0; int j = 0; while(!fin) { if( i < tiempoProgramadoEnSeg ) { valoresBase[i] = base.get(j); //valoresBaseList.add(base.get(j)); j++; i++; if( j == base.size() ) j = 0; } else { fin = true; } } resetSerieBase(); } }) .setNegativeButton("Cancelar", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub } }); builder.create(); builder.show(); } private void setReferencia() { hiloComandos = new Thread( new Runnable(){ @Override public void run(){ Looper.prepare(); BANDERA_FIN = false; base long actMuestreo int actPuntoGrafico = SystemClock.uptimeMillis(); = SystemClock.uptimeMillis(); = -1; BANDERA_EN_CURSO = true; irACero(); resetSerieReal(); textoBtnPausa = "Pausa"; context.sendBroadcast(new Intent("setTextoBtnPausa")); estadoRutinaStr = "En Curso"; context.sendBroadcast(new Intent("setEstadoRutina")); segTiempoProgramado = 0; while(!BANDERA_FIN) { Log.w("Socket_getLibras_EnCurso", "Si"); if(BANDERA_EN_CURSO) { int tiempoRutina = (int)( (SystemClock.uptimeMillis()-base)/1000); Integer val = blueDriver.getLibras(); valorLibrasMedidas = String.valueOf(val); Log.w("Socket_getLibras_Leido", "Leido : " + String.valueOf(val)); if( val > -1) { context.sendBroadcast(new Intent("setValorLibras")); if( tiempoRutina < valoresBase.length ) { referencia = (Integer) valoresBase[(int) tiempoRutina]; if( Math.abs( SystemClock.uptimeMillis() - actMuestreo ) >= limitMuestreo ) { if( Math.abs(val referencia) > 2 ) { if( val < referencia ) { ordenSalida(COMANDO_TENSIONAR); } else if( val > referencia ) { ordenSalida(COMANDO_RELAJAR); } } else { ordenSalida(COMANDO_PARAR); } actMuestreo = SystemClock.uptimeMillis(); } if( tiempoRutina != actPuntoGrafico ) { serieReal.addLast(null, val); plot.redraw(); actPuntoGrafico = tiempoRutina; Log.w("Segundo", String.valueOf(((int) tiempoRutina))); } } else { BANDERA_FIN = true; } } else { resetSerieReal(); BANDERA_FIN = true; if( val == -1 ) context.sendBroadcast(new Intent("paradaDoctorAlert")); else if ( val == -2 ) context.sendBroadcast(new Intent("paradaUsuarioAlert")); } } else { ordenSalida(COMANDO_PARAR); } } irACero(); base = SystemClock.uptimeMillis(); valorLibrasMedidas = ""; context.sendBroadcast(new Intent("setValorLibras")); estadoRutinaStr = "Detenido"; context.sendBroadcast(new Intent("setEstadoRutina")); } }); hiloComandos.start(); } public void irACero() { Integer val = blueDriver.getLibras(); if( val > 0) { ordenSalida(COMANDO_RELAJAR); while( blueDriver.getLibras() > 0 ){} ordenSalida(COMANDO_PARAR); } } private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) { final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR); switch (state) { case BluetoothAdapter.STATE_OFF: break; case BluetoothAdapter.STATE_TURNING_OFF: break; case BluetoothAdapter.STATE_ON: blueDriverIni(); break; case BluetoothAdapter.STATE_TURNING_ON: break; } } } }; private void SetEstadoRutina(String estado) { TextView tv = (TextView)findViewById(R.id.txtEstadoRutina); tv.setText(estado); } private void resetValorLibras() { TextView tv = (TextView)findViewById(R.id.txtLibrasMedidas); tv.setText(""); } private void resetValorTiempoProgramado() { TextView tv = (TextView)findViewById(R.id.txtTiempoProgramado); tv.setText(String.valueOf(tiempoProgramado) + " m"); } private final BroadcastReceiver mReceiverSetEstadoRutina = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { TextView tv = (TextView)findViewById(R.id.txtEstadoRutina); tv.setText(estadoRutinaStr); } }; private final BroadcastReceiver mReceiverSetValorLibras = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { TextView tv = (TextView)findViewById(R.id.txtLibrasMedidas); if( !valorLibrasMedidas.equals("") ) tv.setText(valorLibrasMedidas + " lb"); else tv.setText(""); int tiempoRutina = (int)( ( (SystemClock.uptimeMillis()-base)/1000)/60 ); TextView tProgramado = (TextView)(((RutinaIntermitenteActivity)context).findViewById(R.id.txtTiempoProgramado)); tProgramado.setText(String.valueOf(tiempoProgramado - tiempoRutina) + " m"); } }; private final BroadcastReceiver mReceiverSetTextoBtnPausa = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Button btn = (Button)findViewById(R.id.btnPausa); btn.setText(textoBtnPausa); } }; private final BroadcastReceiver mReceiverParadaUsuarioAlert = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { paradaUsuarioAlertShow(); } }; private final BroadcastReceiver mReceiverParadaDoctorAlert = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { paradaDoctorAlertShow(); } }; public void paradaUsuarioAlertShow(){ AlertDialog.Builder builder = new AlertDialog.Builder(this); // Get the layout inflater LayoutInflater inflater = this.getLayoutInflater(); builder.setTitle("Parada Activada"); // Inflate and set the layout for the dialog // Pass null as the parent view because its going in the dialog layout final View view = inflater.inflate(R.layout.parada_usuario_dialog, null); builder.setView(view) // Add action buttons .setPositiveButton("Aceptar", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }); builder.create(); builder.show(); } public void paradaDoctorAlertShow(){ AlertDialog.Builder builder = new AlertDialog.Builder(this); // Get the layout inflater LayoutInflater inflater = this.getLayoutInflater(); builder.setTitle("Parada Activada"); // Inflate and set the layout for the dialog // Pass null as the parent view because its going in the dialog layout final View view = inflater.inflate(R.layout.parada_doctor_dialog, null); builder.setView(view) // Add action buttons .setPositiveButton("Aceptar", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }); builder.create(); builder.show(); } private void ordenSalida(int comando) { try { blueDriver.trigger(comando); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private void resetSerieReal() { plot.removeSeries(serieReal); serieReal = new SimpleXYSeries( Arrays.asList(new Number[]{}), // SimpleXYSeries takes a List so turn our array into a List SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, // Y_VALS_ONLY means use the element index as the x value "Real"); // Set the display title of the series LineAndPointFormatter series1Format = new LineAndPointFormatter(Color.GREEN, Color.TRANSPARENT, Color.TRANSPARENT, new PointLabelFormatter(Color.TRANSPARENT)); series1Format.getLinePaint().setStrokeWidth(4); plot.addSeries(serieReal, series1Format); plot.redraw(); } private void resetSerieBase() { plot.removeSeries(serieBase); serieBase = new SimpleXYSeries( Arrays.asList(valoresBase), SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "Programada"); Paint lineFill = new Paint(); lineFill.setAlpha(600); lineFill.setShader(new LinearGradient(0, 0, 0, 250, Color.WHITE, Color.WHITE, Shader.TileMode.MIRROR)); StepFormatter stepFormatter = new StepFormatter(Color.rgb(0, 0, 0), Color.BLACK); stepFormatter.getLinePaint().setStrokeWidth(3); stepFormatter.getLinePaint().setAntiAlias(false); stepFormatter.setFillPaint(lineFill); Paint pointPaint = new Paint(); pointPaint.setColor(Color.TRANSPARENT); stepFormatter.setVertexPaint(pointPaint); plot.addSeries(serieBase, stepFormatter); plot.setRangeBoundaries(0, BoundaryMode.FIXED, 50, BoundaryMode.GROW); plot.setTicksPerRangeLabel(5); Double dProg = (Double.valueOf(tiempoProgramado)*60)/15; int pasoDominio = (int)Math.floor(dProg); plot.setTicksPerDomainLabel(pasoDominio); plot.setDomainUpperBoundary( pasoDominio*16 , BoundaryMode.FIXED ); plot.setRangeUpperBoundary( ( librasProgramadas*1.4) , BoundaryMode.FIXED ); plot.redraw(); } @Override public void onBackPressed() { if(BANDERA_FIN) this.finish(); else Toast.makeText(this, "Rutina en proceso.", Toast.LENGTH_LONG).show(); } @Override public void onDestroy() { super.onDestroy(); if(BANDERA_FIN) { this.unregisterReceiver(mReceiver); this.unregisterReceiver(mReceiverSetEstadoRutina); this.unregisterReceiver(mReceiverSetValorLibras); this.unregisterReceiver(mReceiverSetTextoBtnPausa); this.unregisterReceiver(mReceiverParadaUsuarioAlert); this.unregisterReceiver(mReceiverParadaDoctorAlert); try { blueDriver.trigger(COMANDO_PARAR); blueDriver.cerrarSocket(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.rutina_estatico, menu); return true; } } PROGRAMA MODO PROGRESIVO CICLICO package com.example.traccion; import android.app.Activity; import android.app.AlertDialog; import android.graphics.*; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.SystemClock; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.WindowManager; import com.androidplot.xy.*; import com.androidplot.Plot; import com.androidplot.xy.SimpleXYSeries; import Drivers.BluetoothDriver; import java.io.IOException; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Random; import java.util.Set; import org.apache.http.message.LineParser; import android.os.Bundle; import android.provider.DocumentsContract.Document; import android.app.Activity; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.content.BroadcastReceiver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.graphics.Color; import android.view.Menu; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; public class RutinaProgresivoCiclicoActivity extends Activity { Context context; private XYPlot plot; private XYSeries serieBase; private SimpleXYSeries serieReal = null; private BluetoothDriver blueDriver; private Thread hiloComandos = new Thread(); private int referencia = 10; long limitMuestreo = 1; long limitPuntoGrafico = 1000; private int tiempoRut; Number[] valoresBase; long base; long basePausa; String estadoRutinaStr = "Detenido"; String valorLibrasMedidas; String textoBtnPausa; int segTiempoProgramado; int tiempoProgramado; int librasProgramadas; int tiempoHold; int pasoLibras; int tiempoDescanso; private int COMANDO_PARAR private int COMANDO_RELAJAR private int COMANDO_TENSIONAR private int COMANDO_OBTENER_LIBRAS private boolean BANDERA_PARAR private boolean BANDERA_PAUSA private boolean BANDERA_EN_CURSO private boolean BANDERA_FIN = 80; = 82; = 84; = 48; = false; = false; = false; = true; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_rutina_progresivo_ciclico); context = this; IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED); this.registerReceiver(mReceiver, filter); this.registerReceiver(mReceiverSetEstadoRutina, new IntentFilter("setEstadoRutina")); this.registerReceiver(mReceiverSetValorLibras, new IntentFilter("setValorLibras")); this.registerReceiver(mReceiverSetTextoBtnPausa, new IntentFilter("setTextoBtnPausa")); this.registerReceiver(mReceiverParadaUsuarioAlert, new IntentFilter("paradaUsuarioAlert")); this.registerReceiver(mReceiverParadaDoctorAlert, new IntentFilter("paradaDoctorAlert")); blueDriver = new BluetoothDriver(); blueDriverIni(); plot = (XYPlot) findViewById(R.id.mySimpleXYPlot); plot.setRangeStep(XYStepMode.INCREMENT_BY_VAL, 1); plot.setDomainStep(XYStepMode.INCREMENT_BY_VAL, 1); plot.setDomainValueFormat(new DecimalFormat("#")); plot.setRangeValueFormat(new DecimalFormat("#")); valoresBase = new Number[]{}; plot.setPlotPadding( 15 , 20 , 15 , 15 ); Bundle extras = getIntent().getExtras(); if( extras != null ) { tiempoProgramado = extras.getInt("tiempoProgramado"); librasProgramadas = extras.getInt("librasProgramadas"); tiempoHold = extras.getInt("tiempoHold"); pasoLibras = extras.getInt("pasoLibras"); tiempoDescanso = extras.getInt("tiempoDescanso"); TextView tProgramado = (TextView)(((RutinaProgresivoCiclicoActivity)context).findViewById(R.id.txtTiempoProgramado)); TextView lProgramadas = (TextView)(((RutinaProgresivoCiclicoActivity)context).findViewById(R.id.txtLibrasProgramadas)); TextView tmHold = (TextView)(((RutinaProgresivoCiclicoActivity)context).findViewById(R.id.txtTiempoHold)); TextView pLibras = (TextView)(((RutinaProgresivoCiclicoActivity)context).findViewById(R.id.txtPasoLibras)); TextView tmDesc = (TextView)(((RutinaProgresivoCiclicoActivity)context).findViewById(R.id.txtTiempoDescanso)); tProgramado.setText(String.valueOf(tiempoProgramado) + " m"); lProgramadas.setText(String.valueOf(librasProgramadas) + " lb"); tmHold.setText(String.valueOf(tiempoHold) + " s"); pLibras.setText(String.valueOf(pasoLibras) + " lb"); tmDesc.setText(String.valueOf(tiempoDescanso) + " s"); int tiempoProgramadoEnSeg = (int)(tiempoProgramado*60); ArrayList<Integer> base = new ArrayList<Integer>(); boolean cicloFin = false; int k = 0; int ref = 0; while(!cicloFin) { if( k >= tiempoHold ) { ref += pasoLibras; k = 0; } if( ref > librasProgramadas ) { for(int i=0 ; i<tiempoHold ; i++) base.add(librasProgramadas); cicloFin = true; } else { base.add(ref); } k++; } valoresBase = new Number[tiempoProgramadoEnSeg]; boolean fin = false; int i = 0; int j = 0; while(!fin) { if( i < tiempoProgramadoEnSeg ) { valoresBase[i] = base.get(j); //valoresBaseList.add(base.get(j)); j++; i++; if( j == base.size() ) j = 0; } else { fin = true; } } resetSerieBase(); } } private void blueDriverIni() { // TODO Auto-generated method stub if(blueDriver.isBlueDriverReady()) { Log.w("Socket_Est", "Bluetooth listo."); Set<BluetoothDevice> pairedDevices = blueDriver.getDevices(); boolean dispEncontrado = false; for(BluetoothDevice bt : pairedDevices) { if(bt.getName().toString().equals("Traccion")) { if(blueDriver.abrirSocket(bt)) { Toast.makeText(getApplicationContext(),"Conectado.",Toast.LENGTH_LONG).show(); Log.w("Socket_Est", "Bluetooth Conectado."); } else { Toast.makeText(getApplicationContext(),"Error al conectar.",Toast.LENGTH_LONG).show(); } dispEncontrado = true; } } if(!dispEncontrado) { Toast.makeText(getApplicationContext(),"El dispositivo no ha sido encontrado.",Toast.LENGTH_LONG).show(); Log.w("Socket_Est", "El dispositivo no ha sido encontrado."); } } else { Intent turnOn = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(turnOn, 0); } } public void eventoIniciar(View v) { Log.w("estado", String.valueOf(hiloComandos.isAlive())); if(blueDriver.isBlueDriverconnected() && blueDriver.isBlueDriverReady()) { if(!hiloComandos.isAlive()) { setReferencia(); } } else { Toast.makeText(this, "Dispositivo de tracción no conectado.", Toast.LENGTH_LONG).show(); } } public void eventoPausa(View v) { if( BANDERA_FIN == false ) { Button btn = (Button)v; if(btn.getText().toString().equals("Pausa")) { btn.setText("Continuar"); BANDERA_EN_CURSO = false; basePausa = SystemClock.uptimeMillis()-base; ordenSalida(COMANDO_PARAR); SetEstadoRutina("Pausado"); } else // Continuar { btn.setText("Pausa"); BANDERA_EN_CURSO = true; base = SystemClock.uptimeMillis() - basePausa; SetEstadoRutina("En Curso"); } } } public void eventoParar(View v) { if( BANDERA_FIN == false ) { BANDERA_FIN = true; resetSerieReal(); ((Button)findViewById(R.id.btnPausa)).setText("Detenido"); SetEstadoRutina("Detenido"); resetValorLibras(); resetValorTiempoProgramado(); } } public void eventoProgramar(View v) { AlertDialog.Builder builder = new AlertDialog.Builder(this); // Get the layout inflater LayoutInflater inflater = this.getLayoutInflater(); builder.setTitle("Configurar Rutina"); // Inflate and set the layout for the dialog // Pass null as the parent view because its going in the dialog layout final View view = inflater.inflate(R.layout.progresivo_ciclico_config_dialog, null); builder.setView(view) // Add action buttons .setPositiveButton("Aceptar", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { EditText tProg = (EditText)view.findViewById(R.id.editTiempoProgramado); EditText libProg = (EditText)view.findViewById(R.id.editLibrasProgramadas); EditText tHold = (EditText)view.findViewById(R.id.editTiempoHold); EditText lPaso = (EditText)view.findViewById(R.id.editPasoLibras); EditText tDesc = (EditText)view.findViewById(R.id.editTiempoDescanso); tiempoProgramado Integer.valueOf(tProg.getText().toString()); librasProgramadas Integer.valueOf(libProg.getText().toString()); tiempoHold Integer.valueOf(tHold.getText().toString()); pasoLibras Integer.valueOf(lPaso.getText().toString()); tiempoDescanso Integer.valueOf(tDesc.getText().toString()); = = = = = TextView tProgramado = (TextView)(((RutinaProgresivoCiclicoActivity)context).findViewById(R.id.txtTiempoProgramado)); TextView lProgramadas = (TextView)(((RutinaProgresivoCiclicoActivity)context).findViewById(R.id.txtLibrasProgramadas)); TextView tmHold = (TextView)(((RutinaProgresivoCiclicoActivity)context).findViewById(R.id.txtTiempoHold)); TextView pLibras = (TextView)(((RutinaProgresivoCiclicoActivity)context).findViewById(R.id.txtPasoLibras)); TextView tmDesc = (TextView)(((RutinaProgresivoCiclicoActivity)context).findViewById(R.id.txtTiempoDescanso)); tProgramado.setText(String.valueOf(tiempoProgramado) + " m"); lProgramadas.setText(String.valueOf(librasProgramadas) + " lb"); tmHold.setText(String.valueOf(tiempoHold) + " s"); pLibras.setText(String.valueOf(pasoLibras) + " lb"); tmDesc.setText(String.valueOf(tiempoDescanso) + " s"); int tiempoProgramadoEnSeg = (int)(tiempoProgramado*60); ArrayList<Integer> base = new ArrayList<Integer>(); boolean cicloFin = false; int k = 0; int ref = 0; while(!cicloFin) { if( k >= tiempoHold ) { ref += pasoLibras; k = 0; } if( ref > librasProgramadas ) { for(int i=0 ; i<tiempoHold ; i++) base.add(librasProgramadas); cicloFin = true; } else { base.add(ref); } k++; } valoresBase = new Number[tiempoProgramadoEnSeg]; boolean fin = false; int i = 0; int j = 0; while(!fin) { if( i < tiempoProgramadoEnSeg ) { valoresBase[i] = base.get(j); //valoresBaseList.add(base.get(j)); j++; i++; if( j == base.size() ) j = 0; } else { fin = true; } } resetSerieBase(); } }) .setNegativeButton("Cancelar", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub } }); builder.create(); builder.show(); } private void setReferencia() { hiloComandos = new Thread( new Runnable(){ @Override public void run(){ Looper.prepare(); BANDERA_FIN = false; base long actMuestreo int actPuntoGrafico BANDERA_EN_CURSO = true; irACero(); resetSerieReal(); textoBtnPausa = "Pausa"; = SystemClock.uptimeMillis(); = SystemClock.uptimeMillis(); = -1; context.sendBroadcast(new Intent("setTextoBtnPausa")); estadoRutinaStr = "En Curso"; context.sendBroadcast(new Intent("setEstadoRutina")); segTiempoProgramado = 0; while(!BANDERA_FIN) { Log.w("Socket_getLibras_EnCurso", "Si"); if(BANDERA_EN_CURSO) { int tiempoRutina = (int)( (SystemClock.uptimeMillis()-base)/1000); Integer val = blueDriver.getLibras(); valorLibrasMedidas = String.valueOf(val); Log.w("Socket_getLibras_Leido", "Leido : " + String.valueOf(val)); if( val > -1) { context.sendBroadcast(new Intent("setValorLibras")); if( tiempoRutina < valoresBase.length ) { referencia = (Integer) valoresBase[(int) tiempoRutina]; if( Math.abs( SystemClock.uptimeMillis() - actMuestreo ) >= limitMuestreo ) { if( Math.abs(val referencia) > 2 ) { if( val < referencia ) { ordenSalida(COMANDO_TENSIONAR); } else if( val > referencia ) { ordenSalida(COMANDO_RELAJAR); } } else { ordenSalida(COMANDO_PARAR); } actMuestreo = SystemClock.uptimeMillis(); } if( tiempoRutina != actPuntoGrafico ) { serieReal.addLast(null, val); plot.redraw(); actPuntoGrafico = tiempoRutina; Log.w("Segundo", String.valueOf(((int) tiempoRutina))); } } else { BANDERA_FIN = true; } } else { resetSerieReal(); BANDERA_FIN = true; if( val == -1 ) context.sendBroadcast(new Intent("paradaDoctorAlert")); else if ( val == -2 ) context.sendBroadcast(new Intent("paradaUsuarioAlert")); } } else { ordenSalida(COMANDO_PARAR); } } irACero(); base = SystemClock.uptimeMillis(); valorLibrasMedidas = ""; context.sendBroadcast(new Intent("setValorLibras")); estadoRutinaStr = "Detenido"; context.sendBroadcast(new Intent("setEstadoRutina")); } }); hiloComandos.start(); } public void irACero() { Integer val = blueDriver.getLibras(); if( val > 0) { ordenSalida(COMANDO_RELAJAR); while( blueDriver.getLibras() > 0 ){} ordenSalida(COMANDO_PARAR); } } private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) { final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR); switch (state) { case BluetoothAdapter.STATE_OFF: break; case BluetoothAdapter.STATE_TURNING_OFF: break; case BluetoothAdapter.STATE_ON: blueDriverIni(); break; case BluetoothAdapter.STATE_TURNING_ON: break; } } } }; private void SetEstadoRutina(String estado) { TextView tv = (TextView)findViewById(R.id.txtEstadoRutina); tv.setText(estado); } private void resetValorLibras() { TextView tv = (TextView)findViewById(R.id.txtLibrasMedidas); tv.setText(""); } private void resetValorTiempoProgramado() { TextView tv = (TextView)findViewById(R.id.txtTiempoProgramado); tv.setText(String.valueOf(tiempoProgramado) + " m"); } private final BroadcastReceiver mReceiverSetEstadoRutina = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { TextView tv = (TextView)findViewById(R.id.txtEstadoRutina); tv.setText(estadoRutinaStr); } }; private final BroadcastReceiver mReceiverSetValorLibras = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { TextView tv = (TextView)findViewById(R.id.txtLibrasMedidas); if( !valorLibrasMedidas.equals("") ) tv.setText(valorLibrasMedidas + " lb"); else tv.setText(""); int tiempoRutina = (int)( ( (SystemClock.uptimeMillis()-base)/1000)/60 ); TextView tProgramado = (TextView)(((RutinaProgresivoCiclicoActivity)context).findViewById(R.id.txtTiempoProgramado)); tProgramado.setText(String.valueOf(tiempoProgramado - tiempoRutina) + " m"); } }; private final BroadcastReceiver mReceiverSetTextoBtnPausa = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Button btn = (Button)findViewById(R.id.btnPausa); btn.setText(textoBtnPausa); } }; private final BroadcastReceiver mReceiverParadaUsuarioAlert = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { paradaUsuarioAlertShow(); } }; private final BroadcastReceiver mReceiverParadaDoctorAlert = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { paradaDoctorAlertShow(); } }; public void paradaUsuarioAlertShow(){ AlertDialog.Builder builder = new AlertDialog.Builder(this); // Get the layout inflater LayoutInflater inflater = this.getLayoutInflater(); builder.setTitle("Parada Activada"); // Inflate and set the layout for the dialog // Pass null as the parent view because its going in the dialog layout final View view = inflater.inflate(R.layout.parada_usuario_dialog, null); builder.setView(view) // Add action buttons .setPositiveButton("Aceptar", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }); builder.create(); builder.show(); } public void paradaDoctorAlertShow(){ AlertDialog.Builder builder = new AlertDialog.Builder(this); // Get the layout inflater LayoutInflater inflater = this.getLayoutInflater(); builder.setTitle("Parada Activada"); // Inflate and set the layout for the dialog // Pass null as the parent view because its going in the dialog layout final View view = inflater.inflate(R.layout.parada_doctor_dialog, null); builder.setView(view) // Add action buttons .setPositiveButton("Aceptar", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }); builder.create(); builder.show(); } private void ordenSalida(int comando) { try { blueDriver.trigger(comando); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private void resetSerieReal() { plot.removeSeries(serieReal); serieReal = new SimpleXYSeries( Arrays.asList(new Number[]{}), // SimpleXYSeries takes a List so turn our array into a List SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, // Y_VALS_ONLY means use the element index as the x value "Real"); // Set the display title of the series LineAndPointFormatter series1Format = new LineAndPointFormatter(Color.GREEN, Color.TRANSPARENT, Color.TRANSPARENT, new PointLabelFormatter(Color.TRANSPARENT)); series1Format.getLinePaint().setStrokeWidth(4); plot.addSeries(serieReal, series1Format); plot.redraw(); } private void resetSerieBase() { plot.removeSeries(serieBase); serieBase = new SimpleXYSeries( Arrays.asList(valoresBase), SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "Programada"); Paint lineFill = new Paint(); lineFill.setAlpha(600); lineFill.setShader(new LinearGradient(0, 0, 0, 250, Color.WHITE, Color.WHITE, Shader.TileMode.MIRROR)); StepFormatter stepFormatter = new StepFormatter(Color.rgb(0, 0, 0), Color.BLACK); stepFormatter.getLinePaint().setStrokeWidth(3); stepFormatter.getLinePaint().setAntiAlias(false); stepFormatter.setFillPaint(lineFill); Paint pointPaint = new Paint(); pointPaint.setColor(Color.TRANSPARENT); stepFormatter.setVertexPaint(pointPaint); plot.addSeries(serieBase, stepFormatter); plot.setRangeBoundaries(0, BoundaryMode.FIXED, 50, BoundaryMode.GROW); plot.setTicksPerRangeLabel(5); Double dProg = (Double.valueOf(tiempoProgramado)*60)/15; int pasoDominio = (int)Math.floor(dProg); plot.setTicksPerDomainLabel(pasoDominio); plot.setDomainUpperBoundary( pasoDominio*16 , BoundaryMode.FIXED ); plot.setRangeUpperBoundary( ( librasProgramadas*1.4) , BoundaryMode.FIXED ); plot.redraw(); } @Override public void onBackPressed() { if(BANDERA_FIN) this.finish(); else Toast.makeText(this, "Rutina en proceso.", Toast.LENGTH_LONG).show(); } @Override public void onDestroy() { super.onDestroy(); if(BANDERA_FIN) { this.unregisterReceiver(mReceiver); this.unregisterReceiver(mReceiverSetEstadoRutina); this.unregisterReceiver(mReceiverSetValorLibras); this.unregisterReceiver(mReceiverSetTextoBtnPausa); this.unregisterReceiver(mReceiverParadaUsuarioAlert); this.unregisterReceiver(mReceiverParadaDoctorAlert); try { blueDriver.trigger(COMANDO_PARAR); blueDriver.cerrarSocket(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.rutina_estatico, menu); return true; } } PROGRAMA PROGRESIVO ESTATICO package com.example.traccion; import android.app.Activity; import android.app.AlertDialog; import android.graphics.*; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.SystemClock; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.WindowManager; import com.androidplot.xy.*; import com.androidplot.Plot; import com.androidplot.xy.SimpleXYSeries; import Drivers.BluetoothDriver; import java.io.IOException; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Random; import java.util.Set; import org.apache.http.message.LineParser; import android.os.Bundle; import android.provider.DocumentsContract.Document; import android.app.Activity; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.content.BroadcastReceiver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.graphics.Color; import android.view.Menu; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; public class RutinaProgresivoEstaticoActivity extends Activity { Context context; private XYPlot plot; private XYSeries serieBase; private SimpleXYSeries serieReal = null; private BluetoothDriver blueDriver; private Thread hiloComandos = new Thread(); private int referencia = 10; long limitMuestreo = 1; long limitPuntoGrafico = 1000; private int tiempoRut; Number[] valoresBase; long base; long basePausa; String estadoRutinaStr = "Detenido"; String valorLibrasMedidas; String textoBtnPausa; int segTiempoProgramado; int tiempoProgramado; int librasProgramadas; int tiempoHold; int pasoLibras; private int COMANDO_PARAR private int COMANDO_RELAJAR private int COMANDO_TENSIONAR = 80; = 82; = 84; private int COMANDO_OBTENER_LIBRAS private boolean BANDERA_PARAR private boolean BANDERA_PAUSA private boolean BANDERA_EN_CURSO private boolean BANDERA_FIN = 48; = false; = false; = false; = true; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_rutina_progresivo_estatico); context = this; IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED); this.registerReceiver(mReceiver, filter); this.registerReceiver(mReceiverSetEstadoRutina, new IntentFilter("setEstadoRutina")); this.registerReceiver(mReceiverSetValorLibras, new IntentFilter("setValorLibras")); this.registerReceiver(mReceiverSetTextoBtnPausa, new IntentFilter("setTextoBtnPausa")); this.registerReceiver(mReceiverParadaUsuarioAlert, new IntentFilter("paradaUsuarioAlert")); this.registerReceiver(mReceiverParadaDoctorAlert, new IntentFilter("paradaDoctorAlert")); blueDriver = new BluetoothDriver(); blueDriverIni(); plot = (XYPlot) findViewById(R.id.mySimpleXYPlot); plot.setRangeStep(XYStepMode.INCREMENT_BY_VAL, 1); plot.setDomainStep(XYStepMode.INCREMENT_BY_VAL, 1); plot.setDomainValueFormat(new DecimalFormat("#")); plot.setRangeValueFormat(new DecimalFormat("#")); valoresBase = new Number[]{}; Number[] valoresReal = {}; plot.setPlotPadding( 15 , 20 , 15 , 15 ); Bundle extras = getIntent().getExtras(); if( extras != null ) { tiempoProgramado = extras.getInt("tiempoProgramado"); librasProgramadas = extras.getInt("librasProgramadas"); tiempoHold = extras.getInt("tiempoHold"); pasoLibras = extras.getInt("pasoLibras"); TextView tProgramado = (TextView)(((RutinaProgresivoEstaticoActivity)context).findViewById(R.id.txtTiempoProgramado)); TextView lProgramadas = (TextView)(((RutinaProgresivoEstaticoActivity)context).findViewById(R.id.txtLibrasProgramadas)); TextView tmHold = (TextView)(((RutinaProgresivoEstaticoActivity)context).findViewById(R.id.txtTiempoHold)); TextView pLibras = (TextView)(((RutinaProgresivoEstaticoActivity)context).findViewById(R.id.txtPasoLibras)); tProgramado.setText(String.valueOf(tiempoProgramado) + " m"); lProgramadas.setText(String.valueOf(librasProgramadas) + " lb"); tmHold.setText(String.valueOf(tiempoHold) + " s"); pLibras.setText(String.valueOf(pasoLibras) + " lb"); int tiempoProgramadoEnSeg = (int)(tiempoProgramado*60); valoresBase = new Number[tiempoProgramadoEnSeg]; boolean fin = false; int i = 0; int j = 0; int k = 0; int ref = 0; valoresBase[0] = ref; while(!fin) { if( i < tiempoProgramadoEnSeg ) { if( k >= tiempoHold ) { ref += pasoLibras; k = 0; } if( ref > librasProgramadas ) valoresBase[i] = librasProgramadas; else valoresBase[i] = ref; i++; k++; } else { fin = true; } } resetSerieBase(); } } private void blueDriverIni() { // TODO Auto-generated method stub if(blueDriver.isBlueDriverReady()) { Log.w("Socket_Est", "Bluetooth listo."); Set<BluetoothDevice> pairedDevices = blueDriver.getDevices(); boolean dispEncontrado = false; for(BluetoothDevice bt : pairedDevices) { if(bt.getName().toString().equals("Traccion")) { if(blueDriver.abrirSocket(bt)) { Toast.makeText(getApplicationContext(),"Conectado.",Toast.LENGTH_LONG).show(); Log.w("Socket_Est", "Bluetooth Conectado."); } else { Toast.makeText(getApplicationContext(),"Error al conectar.",Toast.LENGTH_LONG).show(); } dispEncontrado = true; } } if(!dispEncontrado) { Toast.makeText(getApplicationContext(),"El dispositivo no ha sido encontrado.",Toast.LENGTH_LONG).show(); Log.w("Socket_Est", "El dispositivo no ha sido encontrado."); } } else { Intent turnOn = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(turnOn, 0); } } public void eventoIniciar(View v) { Log.w("estado", String.valueOf(hiloComandos.isAlive())); if(blueDriver.isBlueDriverconnected() && blueDriver.isBlueDriverReady()) { if(!hiloComandos.isAlive()) { setReferencia(); } } else { Toast.makeText(this, "Dispositivo de tracción no conectado.", Toast.LENGTH_LONG).show(); } } public void eventoPausa(View v) { if( BANDERA_FIN == false ) { Button btn = (Button)v; if(btn.getText().toString().equals("Pausa")) { btn.setText("Continuar"); BANDERA_EN_CURSO = false; basePausa = SystemClock.uptimeMillis()-base; ordenSalida(COMANDO_PARAR); SetEstadoRutina("Pausado"); } else // Continuar { btn.setText("Pausa"); BANDERA_EN_CURSO = true; base = SystemClock.uptimeMillis() - basePausa; SetEstadoRutina("En Curso"); } } } public void eventoParar(View v) { if( BANDERA_FIN == false ) { BANDERA_FIN = true; resetSerieReal(); ((Button)findViewById(R.id.btnPausa)).setText("Detenido"); SetEstadoRutina("Detenido"); resetValorLibras(); resetValorTiempoProgramado(); } } public void eventoProgramar(View v) { AlertDialog.Builder builder = new AlertDialog.Builder(this); // Get the layout inflater LayoutInflater inflater = this.getLayoutInflater(); builder.setTitle("Configurar Rutina"); // Inflate and set the layout for the dialog // Pass null as the parent view because its going in the dialog layout final View view = inflater.inflate(R.layout.progresivo_estatico_config_dialog, null); builder.setView(view) // Add action buttons .setPositiveButton("Aceptar", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { EditText tProg = (EditText)view.findViewById(R.id.editTiempoProgramado); EditText libProg = (EditText)view.findViewById(R.id.editLibrasProgramadas); EditText tHold = (EditText)view.findViewById(R.id.editTiempoHold); EditText lPaso = (EditText)view.findViewById(R.id.editPasoLibras); tiempoProgramado Integer.valueOf(tProg.getText().toString()); librasProgramadas Integer.valueOf(libProg.getText().toString()); tiempoHold Integer.valueOf(tHold.getText().toString()); pasoLibras Integer.valueOf(lPaso.getText().toString()); = = = = TextView tProgramado = (TextView)(((RutinaProgresivoEstaticoActivity)context).findViewById(R.id.txtTiempoProgramado)); TextView lProgramadas = (TextView)(((RutinaProgresivoEstaticoActivity)context).findViewById(R.id.txtLibrasProgramadas)); TextView tmHold = (TextView)(((RutinaProgresivoEstaticoActivity)context).findViewById(R.id.txtTiempoHold)); TextView pLibras = (TextView)(((RutinaProgresivoEstaticoActivity)context).findViewById(R.id.txtPasoLibras)); tProgramado.setText(String.valueOf(tiempoProgramado) + " m"); lProgramadas.setText(String.valueOf(librasProgramadas) + " lb"); tmHold.setText(String.valueOf(tiempoHold) + " s"); pLibras.setText(String.valueOf(pasoLibras) + " lb"); int tiempoProgramadoEnSeg = (int)(tiempoProgramado*60); valoresBase = new Number[tiempoProgramadoEnSeg]; boolean fin = false; int i = 0; int j = 0; int k = 0; int ref = 0; valoresBase[0] = ref; while(!fin) { if( i < tiempoProgramadoEnSeg ) { if( k >= tiempoHold ) { ref += pasoLibras; k = 0; } if( ref > librasProgramadas ) valoresBase[i] = librasProgramadas; else valoresBase[i] = ref; i++; k++; } else { fin = true; } } resetSerieBase(); } }) .setNegativeButton("Cancelar", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub } }); builder.create(); builder.show(); } private void setReferencia() { hiloComandos = new Thread( new Runnable(){ @Override public void run(){ Looper.prepare(); BANDERA_FIN = false; base long actMuestreo int actPuntoGrafico BANDERA_EN_CURSO = true; irACero(); resetSerieReal(); = SystemClock.uptimeMillis(); = SystemClock.uptimeMillis(); = -1; textoBtnPausa = "Pausa"; context.sendBroadcast(new Intent("setTextoBtnPausa")); estadoRutinaStr = "En Curso"; context.sendBroadcast(new Intent("setEstadoRutina")); segTiempoProgramado = 0; while(!BANDERA_FIN) { Log.w("Socket_getLibras_EnCurso", "Si"); if(BANDERA_EN_CURSO) { int tiempoRutina = (int)( (SystemClock.uptimeMillis()-base)/1000); Integer val = blueDriver.getLibras(); valorLibrasMedidas = String.valueOf(val); Log.w("Socket_getLibras_Leido", "Leido : " + String.valueOf(val)); if( val > -1) { context.sendBroadcast(new Intent("setValorLibras")); if( tiempoRutina < valoresBase.length ) { referencia = (Integer) valoresBase[(int) tiempoRutina]; if( Math.abs( SystemClock.uptimeMillis() - actMuestreo ) >= limitMuestreo ) { if( Math.abs(val referencia) > 2 ) { if( val < referencia ) { ordenSalida(COMANDO_TENSIONAR); } else if( val > referencia ) { ordenSalida(COMANDO_RELAJAR); } } else { ordenSalida(COMANDO_PARAR); } actMuestreo = SystemClock.uptimeMillis(); } if( tiempoRutina != actPuntoGrafico ) { serieReal.addLast(null, val); plot.redraw(); actPuntoGrafico = tiempoRutina; Log.w("Segundo", String.valueOf(((int) tiempoRutina))); } } else { BANDERA_FIN = true; } } else { resetSerieReal(); BANDERA_FIN = true; if( val == -1 ) context.sendBroadcast(new Intent("paradaDoctorAlert")); else if ( val == -2 ) context.sendBroadcast(new Intent("paradaUsuarioAlert")); } } else { ordenSalida(COMANDO_PARAR); } } irACero(); base = SystemClock.uptimeMillis(); valorLibrasMedidas = ""; context.sendBroadcast(new Intent("setValorLibras")); estadoRutinaStr = "Detenido"; context.sendBroadcast(new Intent("setEstadoRutina")); } }); hiloComandos.start(); } public void irACero() { Integer val = blueDriver.getLibras(); if( val > 0) { ordenSalida(COMANDO_RELAJAR); while( blueDriver.getLibras() > 0 ){} ordenSalida(COMANDO_PARAR); } } private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) { final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR); switch (state) { case BluetoothAdapter.STATE_OFF: break; case BluetoothAdapter.STATE_TURNING_OFF: break; case BluetoothAdapter.STATE_ON: blueDriverIni(); break; case BluetoothAdapter.STATE_TURNING_ON: break; } } } }; private void SetEstadoRutina(String estado) { TextView tv = (TextView)findViewById(R.id.txtEstadoRutina); tv.setText(estado); } private void resetValorLibras() { TextView tv = (TextView)findViewById(R.id.txtLibrasMedidas); tv.setText(""); } private void resetValorTiempoProgramado() { TextView tv = (TextView)findViewById(R.id.txtTiempoProgramado); tv.setText(String.valueOf(tiempoProgramado) + " m"); } private final BroadcastReceiver mReceiverSetEstadoRutina = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { TextView tv = (TextView)findViewById(R.id.txtEstadoRutina); tv.setText(estadoRutinaStr); } }; private final BroadcastReceiver mReceiverSetValorLibras = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { TextView tv = (TextView)findViewById(R.id.txtLibrasMedidas); if( !valorLibrasMedidas.equals("") ) tv.setText(valorLibrasMedidas + " lb"); else tv.setText(""); int tiempoRutina = (int)( ( (SystemClock.uptimeMillis()-base)/1000)/60 ); TextView tProgramado = (TextView)(((RutinaProgresivoEstaticoActivity)context).findViewById(R.id.txtTiempoProgramado)); tProgramado.setText(String.valueOf(tiempoProgramado - tiempoRutina) + " m"); } }; private final BroadcastReceiver mReceiverSetTextoBtnPausa = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Button btn = (Button)findViewById(R.id.btnPausa); btn.setText(textoBtnPausa); } }; private final BroadcastReceiver mReceiverParadaUsuarioAlert = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { paradaUsuarioAlertShow(); } }; private final BroadcastReceiver mReceiverParadaDoctorAlert = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { paradaDoctorAlertShow(); } }; public void paradaUsuarioAlertShow(){ AlertDialog.Builder builder = new AlertDialog.Builder(this); // Get the layout inflater LayoutInflater inflater = this.getLayoutInflater(); builder.setTitle("Parada Activada"); // Inflate and set the layout for the dialog // Pass null as the parent view because its going in the dialog layout final View view = inflater.inflate(R.layout.parada_usuario_dialog, null); builder.setView(view) // Add action buttons .setPositiveButton("Aceptar", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }); builder.create(); builder.show(); } public void paradaDoctorAlertShow(){ AlertDialog.Builder builder = new AlertDialog.Builder(this); // Get the layout inflater LayoutInflater inflater = this.getLayoutInflater(); builder.setTitle("Parada Activada"); // Inflate and set the layout for the dialog // Pass null as the parent view because its going in the dialog layout final View view = inflater.inflate(R.layout.parada_doctor_dialog, null); builder.setView(view) // Add action buttons .setPositiveButton("Aceptar", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }); builder.create(); builder.show(); } private void ordenSalida(int comando) { try { blueDriver.trigger(comando); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private void resetSerieReal() { plot.removeSeries(serieReal); serieReal = new SimpleXYSeries( Arrays.asList(new Number[]{}), // SimpleXYSeries takes a List so turn our array into a List SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, // Y_VALS_ONLY means use the element index as the x value "Real"); // Set the display title of the series LineAndPointFormatter series1Format = new LineAndPointFormatter(Color.GREEN, Color.TRANSPARENT, Color.TRANSPARENT, new PointLabelFormatter(Color.TRANSPARENT)); series1Format.getLinePaint().setStrokeWidth(4); plot.addSeries(serieReal, series1Format); plot.redraw(); } private void resetSerieBase() { plot.removeSeries(serieBase); serieBase = new SimpleXYSeries( Arrays.asList(valoresBase), SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "Programada"); Paint lineFill = new Paint(); lineFill.setAlpha(600); lineFill.setShader(new LinearGradient(0, 0, 0, 250, Color.WHITE, Color.WHITE, Shader.TileMode.MIRROR)); StepFormatter stepFormatter = new StepFormatter(Color.rgb(0, 0, 0), Color.BLACK); stepFormatter.getLinePaint().setStrokeWidth(3); stepFormatter.getLinePaint().setAntiAlias(false); stepFormatter.setFillPaint(lineFill); Paint pointPaint = new Paint(); pointPaint.setColor(Color.TRANSPARENT); stepFormatter.setVertexPaint(pointPaint); plot.addSeries(serieBase, stepFormatter); plot.setRangeBoundaries(0, BoundaryMode.FIXED, 50, BoundaryMode.GROW); plot.setTicksPerRangeLabel(5); Double dProg = (Double.valueOf(tiempoProgramado)*60)/15; int pasoDominio = (int)Math.floor(dProg); plot.setTicksPerDomainLabel(pasoDominio); plot.setDomainUpperBoundary( pasoDominio*16 , BoundaryMode.FIXED ); plot.setRangeUpperBoundary( ( librasProgramadas*1.4) , BoundaryMode.FIXED ); plot.redraw(); } @Override public void onBackPressed() { if(BANDERA_FIN) this.finish(); else Toast.makeText(this, "Rutina en proceso.", Toast.LENGTH_LONG).show(); } @Override public void onDestroy() { super.onDestroy(); if(BANDERA_FIN) { this.unregisterReceiver(mReceiver); this.unregisterReceiver(mReceiverSetEstadoRutina); this.unregisterReceiver(mReceiverSetValorLibras); this.unregisterReceiver(mReceiverSetTextoBtnPausa); this.unregisterReceiver(mReceiverParadaUsuarioAlert); this.unregisterReceiver(mReceiverParadaDoctorAlert); try { blueDriver.trigger(COMANDO_PARAR); blueDriver.cerrarSocket(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.rutina_estatico, menu); return true; } } PROGRAMA MODO PROGRESIVO REGRESIVO package com.example.traccion; import android.app.Activity; import android.app.AlertDialog; import android.graphics.*; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.SystemClock; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.WindowManager; import com.androidplot.xy.*; import com.androidplot.Plot; import com.androidplot.xy.SimpleXYSeries; import Drivers.BluetoothDriver; import java.io.IOException; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Random; import java.util.Set; import org.apache.http.message.LineParser; import android.os.Bundle; import android.provider.DocumentsContract.Document; import android.app.Activity; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.content.BroadcastReceiver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.graphics.Color; import android.view.Menu; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; public class RutinaProgresivoRegresivoActivity extends Activity { Context context; private XYPlot plot; private XYSeries serieBase; private SimpleXYSeries serieReal = null; private BluetoothDriver blueDriver; private Thread hiloComandos = new Thread(); private int referencia = 10; long limitMuestreo = 1; long limitPuntoGrafico = 1000; private int tiempoRut; Number[] valoresBase; long base; long basePausa; String estadoRutinaStr = "Detenido"; String valorLibrasMedidas; String textoBtnPausa; int segTiempoProgramado; int tiempoProgramado; int librasProgramadas; int tiempoHold; int pasoLibras; int tiempoDescanso; private int COMANDO_PARAR private int COMANDO_RELAJAR private int COMANDO_TENSIONAR private int COMANDO_OBTENER_LIBRAS private boolean BANDERA_PARAR private boolean BANDERA_PAUSA private boolean BANDERA_EN_CURSO private boolean BANDERA_FIN = 80; = 82; = 84; = 48; = false; = false; = false; = true; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_rutina_progresivo_regresivo); context = this; IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED); this.registerReceiver(mReceiver, filter); this.registerReceiver(mReceiverSetEstadoRutina, new IntentFilter("setEstadoRutina")); this.registerReceiver(mReceiverSetValorLibras, new IntentFilter("setValorLibras")); this.registerReceiver(mReceiverSetTextoBtnPausa, new IntentFilter("setTextoBtnPausa")); this.registerReceiver(mReceiverParadaUsuarioAlert, new IntentFilter("paradaUsuarioAlert")); this.registerReceiver(mReceiverParadaDoctorAlert, new IntentFilter("paradaDoctorAlert")); blueDriver = new BluetoothDriver(); blueDriverIni(); plot = (XYPlot) findViewById(R.id.mySimpleXYPlot); plot.setRangeStep(XYStepMode.INCREMENT_BY_VAL, 1); plot.setDomainStep(XYStepMode.INCREMENT_BY_VAL, 1); plot.setDomainValueFormat(new DecimalFormat("#")); plot.setRangeValueFormat(new DecimalFormat("#")); valoresBase = new Number[]{}; plot.setPlotPadding( 15 , 20 , 15 , 15 ); Bundle extras = getIntent().getExtras(); if( extras != null ) { tiempoProgramado = extras.getInt("tiempoProgramado"); librasProgramadas = extras.getInt("librasProgramadas"); tiempoHold = extras.getInt("tiempoHold"); pasoLibras = extras.getInt("pasoLibras"); tiempoDescanso = extras.getInt("tiempoDescanso"); TextView tProgramado = (TextView)(((RutinaProgresivoRegresivoActivity)context).findViewById(R.id.txtTiempoProgramado) ); TextView lProgramadas = (TextView)(((RutinaProgresivoRegresivoActivity)context).findViewById(R.id.txtLibrasProgramadas)) ; TextView tmHold = (TextView)(((RutinaProgresivoRegresivoActivity)context).findViewById(R.id.txtTiempoHold)); TextView pLibras = (TextView)(((RutinaProgresivoRegresivoActivity)context).findViewById(R.id.txtPasoLibras)); TextView tmDesc = (TextView)(((RutinaProgresivoRegresivoActivity)context).findViewById(R.id.txtTiempoDescanso)); tProgramado.setText(String.valueOf(tiempoProgramado) + " m"); lProgramadas.setText(String.valueOf(librasProgramadas) + " lb"); tmHold.setText(String.valueOf(tiempoHold) + " s"); pLibras.setText(String.valueOf(pasoLibras) + " lb"); tmDesc.setText(String.valueOf(tiempoDescanso) + " s"); int tiempoProgramadoEnSeg = (int)(tiempoProgramado*60); ArrayList<Integer> base = new ArrayList<Integer>(); boolean cicloFin = false; int k = 0; int ref = 0; while(!cicloFin) { if( k >= tiempoHold ) { ref += pasoLibras; k = 0; } if( ref > librasProgramadas ) { for(int i=0 ; i<tiempoHold ; i++) base.add(librasProgramadas); cicloFin = true; } else { base.add(ref); } k++; } for(int i=(base.size()-1) ; i>=0 ; i--) { base.add(base.get(i)); } valoresBase = new Number[tiempoProgramadoEnSeg]; boolean fin = false; int i = 0; int j = 0; while(!fin) { if( i < tiempoProgramadoEnSeg ) { valoresBase[i] = base.get(j); //valoresBaseList.add(base.get(j)); j++; i++; if( j == base.size() ) j = 0; } else { fin = true; } } resetSerieBase(); } } private void blueDriverIni() { // TODO Auto-generated method stub if(blueDriver.isBlueDriverReady()) { Log.w("Socket_Est", "Bluetooth listo."); Set<BluetoothDevice> pairedDevices = blueDriver.getDevices(); boolean dispEncontrado = false; for(BluetoothDevice bt : pairedDevices) { if(bt.getName().toString().equals("Traccion")) { if(blueDriver.abrirSocket(bt)) { Toast.makeText(getApplicationContext(),"Conectado.",Toast.LENGTH_LONG).show(); Log.w("Socket_Est", "Bluetooth Conectado."); } else { Toast.makeText(getApplicationContext(),"Error al conectar.",Toast.LENGTH_LONG).show(); } dispEncontrado = true; } } if(!dispEncontrado) { Toast.makeText(getApplicationContext(),"El dispositivo no ha sido encontrado.",Toast.LENGTH_LONG).show(); Log.w("Socket_Est", "El dispositivo no ha sido encontrado."); } } else { Intent turnOn = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(turnOn, 0); } } public void eventoIniciar(View v) { Log.w("estado", String.valueOf(hiloComandos.isAlive())); if(blueDriver.isBlueDriverconnected() && blueDriver.isBlueDriverReady()) { if(!hiloComandos.isAlive()) { setReferencia(); } } else { Toast.makeText(this, "Dispositivo de tracción no conectado.", Toast.LENGTH_LONG).show(); } } public void eventoPausa(View v) { if( BANDERA_FIN == false ) { Button btn = (Button)v; if(btn.getText().toString().equals("Pausa")) { btn.setText("Continuar"); BANDERA_EN_CURSO = false; basePausa = SystemClock.uptimeMillis()-base; ordenSalida(COMANDO_PARAR); SetEstadoRutina("Pausado"); } else // Continuar { btn.setText("Pausa"); BANDERA_EN_CURSO = true; base = SystemClock.uptimeMillis() - basePausa; SetEstadoRutina("En Curso"); } } } public void eventoParar(View v) { if( BANDERA_FIN == false ) { BANDERA_FIN = true; resetSerieReal(); ((Button)findViewById(R.id.btnPausa)).setText("Detenido"); SetEstadoRutina("Detenido"); resetValorLibras(); resetValorTiempoProgramado(); } } public void eventoProgramar(View v) { AlertDialog.Builder builder = new AlertDialog.Builder(this); // Get the layout inflater LayoutInflater inflater = this.getLayoutInflater(); builder.setTitle("Configurar Rutina"); // Inflate and set the layout for the dialog // Pass null as the parent view because its going in the dialog layout final View view = inflater.inflate(R.layout.progresivo_regresivo_config_dialog, null); builder.setView(view) // Add action buttons .setPositiveButton("Aceptar", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { EditText tProg = (EditText)view.findViewById(R.id.editTiempoProgramado); EditText libProg = (EditText)view.findViewById(R.id.editLibrasProgramadas); EditText tHold = (EditText)view.findViewById(R.id.editTiempoHold); EditText lPaso = (EditText)view.findViewById(R.id.editPasoLibras); EditText tDesc = (EditText)view.findViewById(R.id.editTiempoDescanso); tiempoProgramado Integer.valueOf(tProg.getText().toString()); librasProgramadas Integer.valueOf(libProg.getText().toString()); tiempoHold Integer.valueOf(tHold.getText().toString()); pasoLibras Integer.valueOf(lPaso.getText().toString()); tiempoDescanso Integer.valueOf(tDesc.getText().toString()); = = = = = TextView tProgramado = (TextView)(((RutinaProgresivoRegresivoActivity)context).findViewById(R.id.txtTiempoProgramado) ); TextView lProgramadas = (TextView)(((RutinaProgresivoRegresivoActivity)context).findViewById(R.id.txtLibrasProgramadas)) ; TextView tmHold = (TextView)(((RutinaProgresivoRegresivoActivity)context).findViewById(R.id.txtTiempoHold)); TextView pLibras = (TextView)(((RutinaProgresivoRegresivoActivity)context).findViewById(R.id.txtPasoLibras)); TextView tmDesc = (TextView)(((RutinaProgresivoRegresivoActivity)context).findViewById(R.id.txtTiempoDescanso)); tProgramado.setText(String.valueOf(tiempoProgramado) + " m"); lProgramadas.setText(String.valueOf(librasProgramadas) + " lb"); tmHold.setText(String.valueOf(tiempoHold) + " s"); pLibras.setText(String.valueOf(pasoLibras) + " lb"); tmDesc.setText(String.valueOf(tiempoDescanso) + " s"); int tiempoProgramadoEnSeg = (int)(tiempoProgramado*60); ArrayList<Integer> base = new ArrayList<Integer>(); boolean cicloFin = false; int k = 0; int ref = 0; while(!cicloFin) { if( k >= tiempoHold ) { ref += pasoLibras; k = 0; } if( ref > librasProgramadas ) { for(int i=0 ; i<tiempoHold ; i++) base.add(librasProgramadas); cicloFin = true; } else { base.add(ref); } k++; } for(int i=(base.size()-1) ; i>=0 ; i--) { base.add(base.get(i)); } valoresBase = new Number[tiempoProgramadoEnSeg]; boolean fin = false; int i = 0; int j = 0; while(!fin) { if( i < tiempoProgramadoEnSeg ) { valoresBase[i] = base.get(j); //valoresBaseList.add(base.get(j)); j++; i++; if( j == base.size() ) j = 0; } else { fin = true; } } resetSerieBase(); } }) .setNegativeButton("Cancelar", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub } }); builder.create(); builder.show(); } private void setReferencia() { hiloComandos = new Thread( new Runnable(){ @Override public void run(){ Looper.prepare(); BANDERA_FIN = false; base long actMuestreo int actPuntoGrafico BANDERA_EN_CURSO = true; irACero(); resetSerieReal(); = SystemClock.uptimeMillis(); = SystemClock.uptimeMillis(); = -1; textoBtnPausa = "Pausa"; context.sendBroadcast(new Intent("setTextoBtnPausa")); estadoRutinaStr = "En Curso"; context.sendBroadcast(new Intent("setEstadoRutina")); segTiempoProgramado = 0; while(!BANDERA_FIN) { Log.w("Socket_getLibras_EnCurso", "Si"); if(BANDERA_EN_CURSO) { int tiempoRutina = (int)( (SystemClock.uptimeMillis()-base)/1000); Integer val = blueDriver.getLibras(); valorLibrasMedidas = String.valueOf(val); Log.w("Socket_getLibras_Leido", "Leido : " + String.valueOf(val)); if( val > -1) { context.sendBroadcast(new Intent("setValorLibras")); if( tiempoRutina < valoresBase.length ) { referencia = (Integer) valoresBase[(int) tiempoRutina]; if( Math.abs( SystemClock.uptimeMillis() - actMuestreo ) >= limitMuestreo ) { if( Math.abs(val referencia) > 2 ) { if( val < referencia ) { ordenSalida(COMANDO_TENSIONAR); } else if( val > referencia ) { ordenSalida(COMANDO_RELAJAR); } } else { ordenSalida(COMANDO_PARAR); } actMuestreo = SystemClock.uptimeMillis(); } if( tiempoRutina != actPuntoGrafico ) { serieReal.addLast(null, val); plot.redraw(); actPuntoGrafico = tiempoRutina; Log.w("Segundo", String.valueOf(((int) tiempoRutina))); } } else { BANDERA_FIN = true; } } else { resetSerieReal(); BANDERA_FIN = true; if( val == -1 ) context.sendBroadcast(new Intent("paradaDoctorAlert")); else if ( val == -2 ) context.sendBroadcast(new Intent("paradaUsuarioAlert")); } } else { ordenSalida(COMANDO_PARAR); } } irACero(); base = SystemClock.uptimeMillis(); valorLibrasMedidas = ""; context.sendBroadcast(new Intent("setValorLibras")); estadoRutinaStr = "Detenido"; context.sendBroadcast(new Intent("setEstadoRutina")); } }); hiloComandos.start(); } public void irACero() { Integer val = blueDriver.getLibras(); if( val > 0) { ordenSalida(COMANDO_RELAJAR); while( blueDriver.getLibras() > 0 ){} ordenSalida(COMANDO_PARAR); } } private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) { final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR); switch (state) { case BluetoothAdapter.STATE_OFF: break; case BluetoothAdapter.STATE_TURNING_OFF: break; case BluetoothAdapter.STATE_ON: blueDriverIni(); break; case BluetoothAdapter.STATE_TURNING_ON: break; } } } }; private void SetEstadoRutina(String estado) { TextView tv = (TextView)findViewById(R.id.txtEstadoRutina); tv.setText(estado); } private void resetValorLibras() { TextView tv = (TextView)findViewById(R.id.txtLibrasMedidas); tv.setText(""); } private void resetValorTiempoProgramado() { TextView tv = (TextView)findViewById(R.id.txtTiempoProgramado); tv.setText(String.valueOf(tiempoProgramado) + " m"); } private final BroadcastReceiver mReceiverSetEstadoRutina = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { TextView tv = (TextView)findViewById(R.id.txtEstadoRutina); tv.setText(estadoRutinaStr); } }; private final BroadcastReceiver mReceiverSetValorLibras = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { TextView tv = (TextView)findViewById(R.id.txtLibrasMedidas); if( !valorLibrasMedidas.equals("") ) tv.setText(valorLibrasMedidas + " lb"); else tv.setText(""); int tiempoRutina = (int)( ( (SystemClock.uptimeMillis()-base)/1000)/60 ); TextView tProgramado = (TextView)(((RutinaProgresivoRegresivoActivity)context).findViewById(R.id.txtTiempoProgramado) ); tProgramado.setText(String.valueOf(tiempoProgramado - tiempoRutina) + " m"); } }; private final BroadcastReceiver mReceiverSetTextoBtnPausa = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Button btn = (Button)findViewById(R.id.btnPausa); btn.setText(textoBtnPausa); } }; private final BroadcastReceiver mReceiverParadaUsuarioAlert = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { paradaUsuarioAlertShow(); } }; private final BroadcastReceiver mReceiverParadaDoctorAlert = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { paradaDoctorAlertShow(); } }; public void paradaUsuarioAlertShow(){ AlertDialog.Builder builder = new AlertDialog.Builder(this); // Get the layout inflater LayoutInflater inflater = this.getLayoutInflater(); builder.setTitle("Parada Activada"); // Inflate and set the layout for the dialog // Pass null as the parent view because its going in the dialog layout final View view = inflater.inflate(R.layout.parada_usuario_dialog, null); builder.setView(view) // Add action buttons .setPositiveButton("Aceptar", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }); builder.create(); builder.show(); } public void paradaDoctorAlertShow(){ AlertDialog.Builder builder = new AlertDialog.Builder(this); // Get the layout inflater LayoutInflater inflater = this.getLayoutInflater(); builder.setTitle("Parada Activada"); // Inflate and set the layout for the dialog // Pass null as the parent view because its going in the dialog layout final View view = inflater.inflate(R.layout.parada_doctor_dialog, null); builder.setView(view) // Add action buttons .setPositiveButton("Aceptar", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }); builder.create(); builder.show(); } private void ordenSalida(int comando) { try { blueDriver.trigger(comando); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private void resetSerieReal() { plot.removeSeries(serieReal); serieReal = new SimpleXYSeries( Arrays.asList(new Number[]{}), // SimpleXYSeries takes a List so turn our array into a List SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, // Y_VALS_ONLY means use the element index as the x value "Real"); // Set the display title of the series LineAndPointFormatter series1Format = new LineAndPointFormatter(Color.GREEN, Color.TRANSPARENT, Color.TRANSPARENT, new PointLabelFormatter(Color.TRANSPARENT)); series1Format.getLinePaint().setStrokeWidth(4); plot.addSeries(serieReal, series1Format); plot.redraw(); } private void resetSerieBase() { plot.removeSeries(serieBase); serieBase = new SimpleXYSeries( Arrays.asList(valoresBase), SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "Programada"); Paint lineFill = new Paint(); lineFill.setAlpha(600); lineFill.setShader(new LinearGradient(0, 0, 0, 250, Color.WHITE, Color.WHITE, Shader.TileMode.MIRROR)); StepFormatter stepFormatter = new StepFormatter(Color.rgb(0, 0, 0), Color.BLACK); stepFormatter.getLinePaint().setStrokeWidth(3); stepFormatter.getLinePaint().setAntiAlias(false); stepFormatter.setFillPaint(lineFill); Paint pointPaint = new Paint(); pointPaint.setColor(Color.TRANSPARENT); stepFormatter.setVertexPaint(pointPaint); plot.addSeries(serieBase, stepFormatter); plot.setRangeBoundaries(0, BoundaryMode.FIXED, 50, BoundaryMode.GROW); plot.setTicksPerRangeLabel(5); Double dProg = (Double.valueOf(tiempoProgramado)*60)/15; int pasoDominio = (int)Math.floor(dProg); plot.setTicksPerDomainLabel(pasoDominio); plot.setDomainUpperBoundary( pasoDominio*16 , BoundaryMode.FIXED ); plot.setRangeUpperBoundary( ( librasProgramadas*1.4) , BoundaryMode.FIXED ); plot.redraw(); } @Override public void onBackPressed() { if(BANDERA_FIN) this.finish(); else Toast.makeText(this, "Rutina en proceso.", Toast.LENGTH_LONG).show(); } @Override public void onDestroy() { super.onDestroy(); if(BANDERA_FIN) { this.unregisterReceiver(mReceiver); this.unregisterReceiver(mReceiverSetEstadoRutina); this.unregisterReceiver(mReceiverSetValorLibras); this.unregisterReceiver(mReceiverSetTextoBtnPausa); this.unregisterReceiver(mReceiverParadaUsuarioAlert); this.unregisterReceiver(mReceiverParadaDoctorAlert); try { blueDriver.trigger(COMANDO_PARAR); blueDriver.cerrarSocket(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.rutina_estatico, menu); return true; } } PROGRAMA SUBMENU PROGRESIVO package com.example.traccion; import android.os.Bundle; import android.app.Activity; import android.content.Intent; import android.view.Menu; import android.view.View; public class SubMenuProgresivoActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_sub_menu_progresivo); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.sub_menu_progresivo, menu); return true; } public void eventoEstatico(View v) { Intent intent = new Intent(this, RutinaProgresivoEstaticoActivity.class); startActivity(intent); } public void eventoCiclico(View v) { Intent intent = new Intent(this, RutinaProgresivoCiclicoActivity.class); startActivity(intent); } public void eventoRegresivo(View v) { Intent intent = new Intent(this, RutinaProgresivoRegresivoActivity.class); startActivity(intent); } } PROGRAMA COMUNICACIÓN BLUETOOTH package com.example.traccion; import android.os.Bundle; import android.app.Activity; import android.content.Intent; import android.view.Menu; import android.view.View; public class SubMenuProgresivoActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_sub_menu_progresivo); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.sub_menu_progresivo, menu); return true; } public void eventoEstatico(View v) { Intent intent = new Intent(this, RutinaProgresivoEstaticoActivity.class); startActivity(intent); } public void eventoCiclico(View v) { Intent intent = new Intent(this, RutinaProgresivoCiclicoActivity.class); startActivity(intent); } public void eventoRegresivo(View v) { Intent intent = new Intent(this, RutinaProgresivoRegresivoActivity.class); startActivity(intent); } }