Programa Prototipo Setex

Dependencies:   BatteryPanel-prot-prod Slave-prot-prod mbed GraphicLCD-prot-prod ThermalPrinter-prot-prod LimitSwitches-prot-prod ParkingMeter-prot-prod

Revision:
0:a1ce6cdc3045
Child:
1:4cdf726a3497
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Tue Jun 04 19:53:44 2019 +0000
@@ -0,0 +1,3640 @@
+#include    "mbed.h"
+#include    "BatteryPanel.h"
+#include    "ParkingMeter.h"
+#include    "ThermalPrinter.h"
+#include    "LimitSwitches.h"
+#include    "GraphicLCD.h"
+#include    "Slave.h"
+
+#define     NO_KEY              0x00
+#define     NO_DATA             0x87
+
+#define     COMMAND_ON          0X70
+#define     COMMAND_INIT        0X71
+#define     COMMAND_GPRS        0X72
+#define     COMMAND_DATA        0X73
+#define     COMMAND_POST        0X74
+#define     COMMAND_ANSWER      0X75
+#define     COMMAND_SIGNAL      0X76
+#define     COMMAND_CONNECT     0X77
+#define     COMMAND_OFF         0X78
+#define     HOSTING_STEP1       0x79
+#define     HOSTING_STEP2       0x7A
+#define     HOSTING_STEP3       0x7B
+#define     HOSTING_STEP4       0x7C
+#define     HOSTING_STEP5       0x7D
+#define     HOSTING_STEP6       0x7E
+#define     HOSTING_STEP7       0x7F
+#define     HOSTING_STEP8       0x80
+#define     HOSTING_STEP9       0x81
+#define     HOSTING_STEP10      0x82
+#define     HOSTING_STEP11      0x83
+#define     HOSTING_OFF         0x84
+#define     NEXT_STEP           0x85
+#define     NEXT_SLEEP          0x86
+#define     COMMAND_END         0X88
+
+#define     USER_INIT           0xA0
+#define     USER_PLACE          0xA1
+#define     USER_CARD           0xA2
+#define     USER_TIME           0xA3
+#define     USER_DATA           0xA4
+#define     USER_PRINT          0xA5
+#define     USER_TICKET         0xA6
+#define     USER_FINISH         0xA7
+#define     USER_POST           0xA8
+#define     USER_ANSWER         0xA9
+#define     USER_INIT2          0xAA
+#define     USER_INIT3          0xB0
+#define     USER_INIT4          0xB1
+#define     USER_CARD2          0xB2
+#define     USER_INIT5          0xB3
+#define     USER_CARD3          0xB4
+
+#define     M_SISTEMA           0x40
+#define     M_RED               0x41
+#define     M_IMPRESORA         0x42
+#define     M_TECLADO           0x43
+#define     M_LECTORA           0X44
+#define     M_INFORMACION       0x45
+#define     M_OFF               0x46
+#define     M_PARQUIMETRO       0x47
+#define     M_MUNICIPIO         0x48
+#define     M_PRECIO            0x49
+#define     M_ATRAS             0x4A
+#define     M_SENAL             0x4B
+#define     M_HOSTING           0x4C
+#define     M_CONEXION_SIM      0x4E
+#define     M_PAPEL             0x4F
+#define     M_IMPRESION         0x50
+#define     M_CONEXION_IMP      0x51
+#define     M_LECTURA           0x52
+#define     M_CONEXION_LEC      0x53
+#define     M_PRUEBA_TECLA      0x54
+
+PARKING_METER ParkingMeter(LED1, LED3, LED2, PC_8);
+
+// PARKING_METER(ManteLed,UserLed,HostLed,MAX232);
+// ParkingMeter.h es una clase creada para encender y apagar los leds que se usan en las operaciones:
+// por ejemplo el led azul se enciende durante una operacion de hosting, verde en una operacion de
+// mantenimiento  y rojo para operaciones de usuario. Agregando que en tambien se enciende y apagan los
+// integrados MAX232 usados en la comunicacion  RS232. Adicionalmente se controla la frecuencia con la que 
+// el parquimetro actualiza su estado en el sistema y controla las alarmas.
+
+BATTERY_PANEL Charger(PF_9, PF_7, PG_1);
+
+// BATTERY_PANEL Charger(AnalogBattery, AnalogPanel, ControlCarga);
+// La clase batteryPanel.h es una clase creada para controlar la carga de la bateria, este nos nos permite
+// por medio de entradas analogas junto con divisores de tension conocer aproximadamente el voltaje en la 
+// bateria y salida del panel, agregango un tercera salida que permite controlar le paso de corriente entre
+// el panel solar y la bateria.
+
+GLCD         Screen(PD_8,PE_10,PD_9,PE_12,PE_8,PE_14,PE_7,PE_15,PE_9,PE_11,PF_15,PE_13,PF_13,PB_1,PF_14);
+
+// CLASS     GLCD(D1,D2,D3,D4,D5,D6,D7,D8,CD,RESET,CE,WR,RD,Power,Light)
+// GraphicLCD es una clase creada exclusivamente para el manejo de la pantalla grafica, en la cual tenemos
+// un puerto paralelo de ocho bits y cinco senales de control, salida de encendido y para la retroiluminacion
+// de la pantalla
+
+PRINTER      Impresora(PC_10,PC_11,PE_0,PB_10,PB_0,PC_2);
+
+// CLASS     PRINTER(TX,RX,PAPER,SELECT,RESET,POWER)
+// La Clase ThermalPrinter es exclusiva para el manejo de la impresora, donde tenemos 5 hilos de control de los cuales
+// dos son de comunicacion serial, tambien se tiene un salida para cortar la alimentacion electrica a la impresora, con
+// la intension de disminuir el consumo de energia.
+
+SLAVE        Slave(PD_5,PD_6,PD_7);
+
+// CLASS     SLAVE(TX,RX,AWAKE)
+// La clase Slave.h controla la tarjeta STM32-86 tiene una comunicacion serial bidiraccional entre las tarjetas, ademas
+// de controlar el estado ya sea Sleep o Awake de la tarjeta esclava. Los #define que comienzan con Command y Hosting, son 
+// son las posibles intrucciones que se pueden enviar al esclavo para que este realice alguna operacion.
+
+SWITCHES     Doors(PC_4,PC_1);
+
+// CLASS     SWITCHES(SENSOR1,SENSOR2)
+// La clase LimitSwitches.h se utiliza para controlar los finales de carrera colocados en las puertas del parquimtro, por
+// trabaja de la mano con la clase parquimtro en las alarmas del sistema
+
+RawSerial    CardReader(PC_12,PD_2,9600);
+DigitalOut   CardReaderPower(PF_3);
+
+// Serial    CardReader(TX,RX,BAUT) y CardReaderPower(PF_3), son las salida para controlar el lector de tarjetas, este se enciende 
+// y apaga su interaccion con el usuario para reducir el consumo de enerigia. 
+
+Serial       Computer(USBTX,USBRX,9600);
+
+// Serial Computer es una herramienta para debuguear el sistema que me permite mostrar en el computador mediantre una conexion USB
+// datos e instrucciones del priceso.
+
+InterruptIn  Configuracion(USER_BUTTON);
+
+// Interrupt Configuration es una entrada en forma de push button que nos permite ingresar al modo de configuracion, por lo que se debe
+// presionar dicho boton para ingresar a esta interfaz, esta entrada no se puede cambiar debido a que no todos los pines de la tarjeta soportan
+// interrupciones de hardware en modo sleep.
+
+DigitalOut   Regulator5V(PA_1);//(PF_0);
+DigitalOut   Keypad_F1(PE_3);//(PF_0);
+DigitalOut   Keypad_F2(PF_0);//(PE_3);
+DigitalOut   Keypad_F3(PF_8);//(PF_1);
+DigitalOut   Keypad_F4(PF_1);//(PF_8);
+InterruptIn  Keypad_C1(PA_2);//(PA_0);
+InterruptIn  Keypad_C2(PA_0);//(PE_6);
+InterruptIn  Keypad_C3(PE_6);//(PC_5);
+InterruptIn  Keypad_C4(PC_5);//(PA_2);
+
+// Corresponde a las entradas para el teclado de matrix 4x4 donde 4 de estos trabajan como salidas y los restantes como interrupciones,
+// de las combinaciones del teclado de salidas e interrupciones se obtiene la tecla presionada por el usuario, indispensable considerar que las
+// interrupciones no se pueden cambiar, debido a no todos los pines de la tarjeta soportan interrupciones de hardware en estado Sleep.
+
+//-----------------------Conexiones GLCD T6963C---------------------------------
+//          1  2       Vss Vss          Ti  Ti(NO Conectada)
+//          3  4       Vcc Cte          Vc  Po
+//          5  6       WR  RD           D14 D15
+//          7  8       CE  CD           F12 F13
+//          9  10      -V  RST          Po  E9
+//          11 12      D0  D1           E11 F14
+//          13 14      D2  D3           E13 F15
+//          15 16      D4  D5           D8  D9
+//          17 18      D6  D7           E8  E7
+//          19 20      NC  NC
+//
+//-----------Conexiones Usadas---------  //-------Conexiones Usadas STM32-------
+//              ____________             //             ___________
+//               2  4  6  8              //             F8 F5 F2 F0
+//               1  3  5  7              //             F9 F7 F3 F1
+//              ____________             //             ___________
+//                  APEM                 //                 APEM
+//          Serial number 12470157       //         Serial number 12470157
+//-------------------------------------  //-------------------------------------
+//
+//----------------------CONEXIONES FUJITSU SERIAL PRINTER-----------------------
+// Conector RS232C(ZHR-8)
+//   _ _ _ _ _ _ _ _
+//  ! ! ! ! ! ! ! ! !             1->RXD    2->TXD    3->DTR    4->GND
+//   1 2 3 4 5 6 7 8              5->DST    6->SLCTIN 7->INPRM  8->AFT
+//
+// Conector Power(PHR-2)
+//   _ _ _ _ _ _
+//  ! ! ! ! ! ! !             1->VCC Logic Supply    2->GND Logic
+//   1 2 3 4 5 6            4,3->GND Head/Motor    5,6->VCC Head/Motor
+
+const char SOH=1;
+const char EOT=4;
+const char ADDR=0;
+const char LEN=0;
+const char CARD_POSITION='8';
+const char DEV_RESET=127;
+const char ARM_MODE='P';
+const char ARM_DEBUG='p';
+const char ARM_ABORT=27;
+const char MAG_ISO_T2='R';
+const char BBCA='=';
+const char BBCE='U';
+const char BBCF='u';
+const char BBCG=30;
+const char BBCI='z';
+const char BBCK='W';
+const char R_ACTION='^';
+const char R_ERROR='*';
+const char R_INVALID='!';
+const char R_NO_DATA='+';
+const char R_COMAND_ERROR='?';
+const char R_START=':';
+const char R_POSITION1='q';
+const char R_POSITION2='s';
+const char R_NO_MAG_CARD='>';
+const char R_MAG_DETECT_ON='(';
+const char R_MAG_DETECT_OFF=')';
+
+char StateReader[7]= "AAAAAA";
+char CardReader_Buffer[255];
+int  CardReader_Counter=0;
+
+char Tecla;
+char Tecla_Before;
+char Comando;
+char InByte;
+uint32_t Inicio, Fin, Transcurrido;
+
+char Tiempo[6];
+int  TiempoMinutos;
+int  NumeroTiquetePrueba=1;
+char Importe[8];
+char Espacio[6];
+char Track2[38]="0000000000000000000000000000000000000";
+
+char Parquimetro[5]="1069";
+char Municipio[9]="San Jose";//"San Jose";
+char CodigoMunicipio[3]="01";
+
+char NumeroRespuesta[7]="000000";
+char FechaRespuesta[11]="00-00-0000";
+char HoraRespuesta[6]="00:00";
+char HoraFinal[6]="00:00";
+char Alarmas[7]="AAAAAA";
+
+char PapelDisponible[5]="0000";
+char Clave[4]= {'4','3','2','2'};
+char Progreso[3];
+int  Precio=300;
+int  Papel=4000;
+bool MantenimientoInterruption=0;
+uint8_t Message[] ="{\"municipio\":\"Santa Ana\",\"id\":1068,\"place\":\"2222\",\"time\":120,\"t2\":\"%5303105315252296=2108?\"}";
+
+Ticker Host;
+Timer  BaseClock;
+
+void Keypad_Init()
+{
+    Tecla_Before=NO_KEY;
+    Keypad_F1=0;
+    Keypad_F2=0;
+    Keypad_F3=0;
+    Keypad_F4=0;
+}
+
+char KeyPad_Read(void)
+{
+    Keypad_F1=1;
+    Keypad_F2=0;
+    Keypad_F3=0;
+    Keypad_F4=0;
+    wait_us(10);
+    if(Keypad_C1.read()) {
+        if(Tecla_Before!='1') {
+            Tecla_Before='1';
+            return '1';
+        } else {
+            return NO_KEY;
+        }
+    }
+    if(Keypad_C2.read()) {
+        if(Tecla_Before!='2') {
+            Tecla_Before='2';
+            return '2';
+        } else {
+            return NO_KEY;
+        }
+    }
+    if(Keypad_C3.read()) {
+        if(Tecla_Before!='3') {
+            Tecla_Before='3';
+            return '3';
+        } else {
+            return NO_KEY;
+        }
+    }
+    if(Keypad_C4.read()) {
+        if(Tecla_Before!='A') {
+            Tecla_Before='A';
+            return 'A';
+        } else {
+            return NO_KEY;
+        }
+    }
+
+    Keypad_F1=0;
+    Keypad_F2=1;
+    Keypad_F3=0;
+    Keypad_F4=0;
+    wait_us(10);
+    if(Keypad_C1.read()) {
+        if(Tecla_Before!='4') {
+            Tecla_Before='4';
+            return '4';
+        } else {
+            return NO_KEY;
+        }
+    }
+    if(Keypad_C2.read()) {
+        if(Tecla_Before!='5') {
+            Tecla_Before='5';
+            return '5';
+        } else {
+            return NO_KEY;
+        }
+    }
+    if(Keypad_C3.read()) {
+        if(Tecla_Before!='6') {
+            Tecla_Before='6';
+            return '6';
+        } else {
+            return NO_KEY;
+        }
+    }
+    if(Keypad_C4.read()) {
+        if(Tecla_Before!='B') {
+            Tecla_Before='B';
+            return 'B';
+        } else {
+            return NO_KEY;
+        }
+    }
+
+    Keypad_F1=0;
+    Keypad_F2=0;
+    Keypad_F3=1;
+    Keypad_F4=0;
+    wait_us(10);
+    if(Keypad_C1.read()) {
+        if(Tecla_Before!='7') {
+            Tecla_Before='7';
+            return '7';
+        } else {
+            return NO_KEY;
+        }
+    }
+    if(Keypad_C2.read()) {
+        if(Tecla_Before!='8') {
+            Tecla_Before='8';
+            return '8';
+        } else {
+            return NO_KEY;
+        }
+    }
+    if(Keypad_C3.read()) {
+        if(Tecla_Before!='9') {
+            Tecla_Before='9';
+            return '9';
+        } else {
+            return NO_KEY;
+        }
+    }
+    if(Keypad_C4.read()) {
+        if(Tecla_Before!='C') {
+            Tecla_Before='C';
+            return 'C';
+        } else {
+            return NO_KEY;
+        }
+    }
+
+    Keypad_F1=0;
+    Keypad_F2=0;
+    Keypad_F3=0;
+    Keypad_F4=1;
+    wait_us(10);
+    if(Keypad_C1.read()) {
+        if(Tecla_Before!='F') {
+            Tecla_Before='F';
+            return 'F';
+        } else {
+            return NO_KEY;
+        }
+    }
+    if(Keypad_C2.read()) {
+        if(Tecla_Before!='0') {
+            Tecla_Before='0';
+            return '0';
+        } else {
+            return NO_KEY;
+        }
+    }
+    if(Keypad_C3.read()) {
+        if(Tecla_Before!='E') {
+            Tecla_Before='E';
+            return 'E';
+        } else {
+            return NO_KEY;
+        }
+    }
+    if(Keypad_C4.read()) {
+        if(Tecla_Before!='D') {
+            Tecla_Before='D';
+            return 'D';
+        } else {
+            return NO_KEY;
+        }
+    }
+
+    Tecla_Before=NO_KEY;
+    return NO_KEY;
+}
+
+void KeyPad_InterruptDisable()
+{
+    Keypad_C1.disable_irq();
+    Keypad_C2.disable_irq();
+    Keypad_C3.disable_irq();
+    Keypad_C4.disable_irq();
+}
+
+void KeyPad_InterruptEnable()
+{
+    Keypad_C1.enable_irq();
+    Keypad_C2.enable_irq();
+    Keypad_C3.enable_irq();
+    Keypad_C4.enable_irq();
+    Keypad_F1=1;
+    Keypad_F2=1;
+    Keypad_F3=1;
+    Keypad_F4=1;
+}
+
+//-----------------------------------------------------------------------------------------------------------------------------------------------------
+void PantallaInicio()
+{
+    Computer.printf("Pantala de Inicio\n");
+
+    Screen.Limits();
+    Screen.PutString(45,19,"Prueba E-Park");
+    Screen.Show();
+    wait_ms(2000);
+
+    Screen.Limits();
+    Screen.PutString(58,12,"Grupo Setex");
+    Screen.PutString(65,34,"Costa Rica");
+    Screen.Show();
+    wait_ms(3000);
+}
+
+char GetTime(char Salida,uint32_t TimeOut)
+{
+    int PositionTime=3;
+    int Hora=PositionTime/6;
+    int Minuto=(PositionTime%6)*10;
+    int Costo=(PositionTime*Precio)/3;
+    TiempoMinutos=PositionTime*10;
+        
+    sprintf(Tiempo,"0:30");
+    sprintf(Importe,"%i*",Costo);
+
+    Screen.PutString(15,12,"Tiempo:");
+    Screen.PutString(88,12,Tiempo);
+    Screen.PutString(15,34,"Precio:");
+    Screen.PutString(85,34,Importe);
+    Screen.PutString(141,46,"Confirmar");
+    Screen.Limits();
+    Screen.Show();
+
+    Computer.printf("Tiempo y precio \n");
+    Computer.printf("%s %s\n",Tiempo,Importe);
+    
+    Inicio=BaseClock.read_ms();
+    Keypad_Init();
+    while(true) {
+
+        Fin=BaseClock.read_ms();
+        Transcurrido=Fin-Inicio;
+        if(Transcurrido>TimeOut) {
+            Screen.Clean();
+            return USER_FINISH;
+        }
+
+        Tecla=KeyPad_Read();
+        if (Tecla!=NO_KEY) {                                // Se valida que se ingrese una tecla valida por el teclado
+            Inicio=BaseClock.read_ms();
+
+            if ((Tecla=='E')&&(PositionTime<72)) {          // Sumar 30 minutos, maximos 12 horas
+                PositionTime+=3;
+            }  
+            if ((Tecla=='F')&&(PositionTime>3)) {           // Restar 10 minutos, minimo 30 minutos
+                if(CodigoMunicipio[1]=='1'){
+                    PositionTime-=1;
+                }
+                if(CodigoMunicipio[1]=='3'){
+                    PositionTime-=3;
+                }
+            }                       
+            if (Tecla=='C') {                               // Cancelar operacion
+                Screen.Clean();
+                return USER_FINISH;
+            }                  
+            if (Tecla=='D') {                               // En caso de confirmacion
+                Screen.PutString(15,12,"Realizando");
+                Screen.PutString(15,34,"Operacion...");
+                Screen.PutChar(84,33,'!');
+                Screen.Limits();
+                Screen.Show();
+                Slave.Set_Time(TiempoMinutos);
+                return Salida;
+            }
+
+            Hora=PositionTime/6;
+            Minuto=(PositionTime%6)*10;
+            Costo=(PositionTime*Precio)/3;
+            TiempoMinutos=PositionTime*10;
+            
+            if(Minuto==0) {                             // Calcular tiempo en horas y minutos
+                sprintf(Tiempo,"%i:0%i",Hora,Minuto);
+                sprintf(Importe,"%i*",Costo);
+            } else {
+                sprintf(Tiempo,"%i:%i",Hora,Minuto);
+                sprintf(Importe,"%i*",Costo);
+            }
+            
+            //-------Mostrar en Patalla-------
+            Screen.PutString(15,12,"Tiempo:");
+            Screen.PutString(88,12,Tiempo);
+            Screen.PutString(15,34,"Precio:");
+            Screen.PutString(85,34,Importe);
+            Screen.PutString(141,46,"Confirmar");
+            Screen.Limits();
+            Screen.Show();
+
+            Computer.printf("%s %s\n",Tiempo,Importe);
+        }
+    }
+}
+
+char GetPlace(char Salida,uint32_t TimeOut)
+{
+    uint8_t PositionPlace=0;
+    
+    sprintf(Espacio,"_    ");
+
+    Screen.Limits();
+    Screen.PutString(15,12,"Numero de espacio:");
+    Screen.PutChar(28,11,'!');
+    Screen.PutString(15,34,Espacio);
+    Screen.Show();
+
+    Computer.printf("Numero de espacio:\n");
+    Computer.printf("%s\n",Espacio);
+
+    Inicio=BaseClock.read_ms();
+    Keypad_Init();
+    while(true) {
+        Fin=BaseClock.read_ms();
+        Transcurrido=Fin-Inicio;
+        if(Transcurrido>TimeOut) {
+            Screen.Clean();
+            return USER_FINISH;
+        }
+
+        Tecla=KeyPad_Read();
+        if (Tecla!=NO_KEY) {                                        // Se valida que se ingrese una tecla valida
+            Inicio=BaseClock.read_ms();
+            if (((Tecla=='0')||(Tecla=='1')||(Tecla=='2')||(Tecla=='3')||(Tecla=='4')||(Tecla=='5')||(Tecla=='6')||(Tecla=='7')||(Tecla=='8')||(Tecla=='9'))&&(PositionPlace<4)) {                      //Agregar un digito
+                Espacio[PositionPlace]=Tecla;
+                PositionPlace++;
+                Espacio[PositionPlace]='_';
+                Espacio[4]=' ';
+                Espacio[5]='\0';
+            }
+            if ((Tecla=='B')&&(PositionPlace>0)) {                   //Borrar el ultimo digito
+                Espacio[PositionPlace]=' ';
+                PositionPlace--;
+                Espacio[PositionPlace]='_';
+                Espacio[4]=' ';
+                Espacio[5]='\0';
+            }                                
+            if (Tecla=='C') {                                       //Cancelar operacion
+                Screen.Clean();
+                return USER_FINISH;
+            }         
+            if ((Tecla=='D')&&(PositionPlace==4)) {                 //En caso de confirmacion
+                Slave.Set_Place(Espacio);
+                return Salida;                
+            }
+            if(PositionPlace==4) {                                  //Se debe confirmar cuando estan los 4 digitos
+                Screen.Limits();
+                Screen.PutString(15,12,"Numero de espacio:");
+                Screen.PutChar(28,11,'!');
+                Screen.PutString(15,34,Espacio);
+                Screen.PutString(141,46,"Confirmar");
+                Screen.Show();
+            } else {
+                Screen.Limits();
+                Screen.PutString(15,12,"Numero de espacio:");
+                Screen.PutChar(28,11,'!');
+                Screen.PutString(15,34,Espacio);
+                Screen.Show();
+            }
+            Computer.printf("%s\n",Espacio);
+        }
+    }
+}
+
+
+void Interrupt_CardReader()
+{
+    if(CardReader.readable()) {
+        CardReader_Buffer[CardReader_Counter]=CardReader.getc();
+        CardReader_Counter++;
+    }
+}
+
+int ResetCard()
+{
+    CardReader_Counter=0;
+    StateReader[0]='S';
+    Computer.printf("\n Reset card reader");
+    if(CardReader.writeable()) {
+        CardReader.putc(SOH);           // 00000001
+        CardReader.putc(ADDR);          // 00000000
+        CardReader.putc(LEN);           // 00000000
+        CardReader.putc(LEN);           // 00000000
+        CardReader.putc(DEV_RESET);     // 01111111
+        CardReader.putc(EOT);           // 00000100
+        CardReader.putc(BBCI);          // 01111010
+    }
+    wait_ms(2000);
+    for(int i=0; i<=CardReader_Counter; i++) {
+        if(CardReader_Buffer[i]==R_START) {
+            Computer.printf("\n Start\n");            // Encendido
+            StateReader[0]='A';
+            ParkingMeter.AlarmCall(1,'A');
+            return 1;
+        }
+        if(CardReader_Buffer[i]==R_INVALID) {
+            Computer.printf("\n Invalid ");         // Comando Invalido
+            StateReader[0]='N';
+            ParkingMeter.AlarmCall(1,'E');
+            return 0;
+        }
+        if(CardReader_Buffer[i]==R_ERROR) {
+            Computer.printf("\n Error ");           // Error
+            StateReader[0]='E';
+            ParkingMeter.AlarmCall(1,'E');
+            return 0;
+        }
+        if(CardReader_Buffer[i]==R_COMAND_ERROR) {
+            Computer.printf("\n Comando error ");    // Error en comando
+            StateReader[0]='C';
+            ParkingMeter.AlarmCall(1,'E');
+            return 0;
+        }
+    }
+    ParkingMeter.AlarmCall(1,'E');
+    return 2;
+}
+
+void DetectionCard(uint32_t TimeOut)
+{
+    CardReader_Counter=0;
+    StateReader[1]='S';
+    StateReader[2]='S';
+    StateReader[3]='S';
+    if(StateReader[0]=='A') {               // Se envia el comando Arm Debug
+        Computer.printf("\n Introducir tarjeta");
+        if(CardReader.writeable()) {
+            CardReader.putc(SOH);
+            CardReader.putc(ADDR);
+            CardReader.putc(LEN);
+            CardReader.putc(LEN);
+            CardReader.putc(ARM_DEBUG);
+            CardReader.putc(EOT);
+            CardReader.putc(BBCF);
+        }
+        wait_ms(500);
+        for(int i=0; i<=CardReader_Counter; i++) {
+            if(CardReader_Buffer[i]==R_ACTION) {
+                Computer.printf("\n ACTION ");      // Accion ejecutada
+                StateReader[1]='A';
+                ParkingMeter.AlarmCall(1,'A');
+            }
+            if(CardReader_Buffer[i]==R_INVALID) {
+                Computer.printf("\n Invalido ");     // Comando Invalido
+                StateReader[1]='N';
+                ParkingMeter.AlarmCall(1,'E');
+            }
+            if(CardReader_Buffer[i]==R_ERROR) {
+                Computer.printf("\n Error ");       // Error
+                StateReader[1]='E';
+                ParkingMeter.AlarmCall(1,'E');
+            }
+            if(CardReader_Buffer[i]==R_COMAND_ERROR) {
+                Computer.printf("\n Comando error ");// Error en comando
+                StateReader[1]='C';
+                ParkingMeter.AlarmCall(1,'E');
+            }
+        }
+        CardReader_Counter=0;
+
+        Inicio=BaseClock.read_ms();
+        while(CardReader_Counter==0) {       // Esperando introduccion de tarjeta
+            Fin=BaseClock.read_ms();
+            Transcurrido=Fin-Inicio;
+            if(StateReader[1]=='C'||StateReader[1]=='E'||StateReader[1]=='N') {
+                Computer.printf("\n Error en comando");
+                break;
+            }
+            if(StateReader[1]=='S') {
+                Computer.printf("\n Sin respuesta");
+                break;
+            }
+            Tecla=KeyPad_Read();
+            if(Tecla=='C') {
+                Computer.printf("\n Cancelar operacion");
+                if(CardReader.writeable()) {
+                    CardReader.putc(SOH);
+                    CardReader.putc(ADDR);
+                    CardReader.putc(LEN);
+                    CardReader.putc(LEN);
+                    CardReader.putc(ARM_ABORT);
+                    CardReader.putc(EOT);
+                    CardReader.putc(BBCG);
+                }
+                break;
+            }
+            if(Transcurrido>TimeOut) {
+                Computer.printf("\n Tiempo de respuesta");
+                if(CardReader.writeable()) {
+                    CardReader.putc(SOH);
+                    CardReader.putc(ADDR);
+                    CardReader.putc(LEN);
+                    CardReader.putc(LEN);
+                    CardReader.putc(ARM_ABORT);
+                    CardReader.putc(EOT);
+                    CardReader.putc(BBCG);
+                }
+                break;
+            }
+        }
+        wait_ms(1000);
+        for(int i=0; i<=CardReader_Counter; i++) {
+            Computer.printf("%c",CardReader_Buffer[i]);
+            if(CardReader_Buffer[i]==R_NO_MAG_CARD) {
+                Computer.printf("\n Deteccion nula ");      // No se detecta banda magnetica
+                StateReader[2]='N';
+                StateReader[3]='N';
+            }
+            if(CardReader_Buffer[i]==R_MAG_DETECT_ON) {
+                Computer.printf("\n Deteccion on ");        // Se inicia verificacion de banda
+                StateReader[2]='A';
+            }
+            if(CardReader_Buffer[i]==R_MAG_DETECT_OFF) {
+                Computer.printf("\n Deteccion off ");       // Se termina verificacion de banda
+                StateReader[3]='A';
+            }
+            if(CardReader_Buffer[i]==R_ACTION) {
+                Computer.printf("\n Action arm abort ");    // Accion ejecutada
+                StateReader[1]='T';
+            }
+        }
+    }
+}
+
+int PositionCard()
+{
+    CardReader_Counter=0;
+    StateReader[4]='S';
+    Computer.printf("\n Detectando tarjeta");
+    if(CardReader.writeable()) {
+        CardReader.putc(SOH);
+        CardReader.putc(ADDR);
+        CardReader.putc(LEN);
+        CardReader.putc(LEN);
+        CardReader.putc(CARD_POSITION);
+        CardReader.putc(EOT);
+        CardReader.putc(BBCA);
+    }
+    wait_ms(250);
+    for(int i=0; i<=CardReader_Counter; i++) {
+        Computer.printf("%c",CardReader_Buffer[i]);
+        if(CardReader_Buffer[i]==R_POSITION1) {
+            Computer.printf("\n Tarjeta en posicion incorrecta ");   // Mal colocada la tarjeta
+            StateReader[4]='N';
+            ParkingMeter.AlarmCall(1,'A');
+            return 0;
+        }
+        if(CardReader_Buffer[i]==R_POSITION2) {
+            Computer.printf("\n Tarjeta en posicion correcta ");     // Bien colocada la tarjeta
+            StateReader[4]='A';
+            ParkingMeter.AlarmCall(1,'A');
+            return 1;
+        }
+        if(CardReader_Buffer[i]==R_INVALID) {
+            Computer.printf("\n Invalido ");     // Comando Invalido
+            StateReader[4]='N';
+            return 0;
+        }
+        if(CardReader_Buffer[i]==R_ERROR) {
+            Computer.printf("\n Error ");       // Error
+            StateReader[4]='E';
+            return 0;
+        }
+        if(CardReader_Buffer[i]==R_COMAND_ERROR) {
+            Computer.printf("\n Comando error ");// Error en comando
+            StateReader[4]='C';
+            return 0;
+        }
+    }
+    return 2;
+}
+
+int ReadCard(uint32_t TimeOut)
+{
+    CardReader_Counter=0;
+    StateReader[5]='S';
+    StateReader[6]='S';
+    if(StateReader[4]=='A') {
+        Computer.printf("\n Retirar Tarjeta en un solo movimiento");
+        if(CardReader.writeable()) {
+            CardReader.putc(SOH);
+            CardReader.putc(ADDR);
+            CardReader.putc(LEN);
+            CardReader.putc(LEN);
+            CardReader.putc(ARM_MODE);
+            CardReader.putc(EOT);
+            CardReader.putc(BBCE);
+        }
+        wait_ms(300);
+        for(int i=0; i<=CardReader_Counter; i++) {
+            Computer.printf("%c",CardReader_Buffer[i]);
+            if(CardReader_Buffer[i]==R_ACTION) {
+                Computer.printf("\n Accion");      // Accion ejecutada
+                StateReader[5]='A';
+            }
+            if(CardReader_Buffer[i]==R_INVALID) {
+                Computer.printf("\n Invalido ");     // Comando Invalido
+                StateReader[5]='N';
+            }
+            if(CardReader_Buffer[i]==R_ERROR) {
+                Computer.printf("\n Error ");       // Error
+                StateReader[5]='E';
+            }
+            if(CardReader_Buffer[i]==R_COMAND_ERROR) {
+                Computer.printf("\n Comando error ");// Error en comando
+                StateReader[5]='C';
+            }
+        }
+        CardReader_Counter=0;
+        Inicio=BaseClock.read_ms();
+        Keypad_Init();
+        while(CardReader_Counter==0) {       // Esperando introduccion de tarjeta
+            Fin=BaseClock.read_ms();
+            Transcurrido=Fin-Inicio;
+            if(StateReader[5]=='C'||StateReader[5]=='E'||StateReader[5]=='N') {
+                Computer.printf("\n Error en comando");
+                break;
+            }
+            if(StateReader[5]=='S') {
+                Computer.printf("\n Sin Respuesta");
+                break;
+            }
+            if(Transcurrido>TimeOut) {
+                Computer.printf("\n Tiempo de respuesta superado");
+                if(CardReader.writeable()) {
+                    CardReader.putc(SOH);
+                    CardReader.putc(ADDR);
+                    CardReader.putc(LEN);
+                    CardReader.putc(LEN);
+                    CardReader.putc(ARM_ABORT);
+                    CardReader.putc(EOT);
+                    CardReader.putc(BBCG);
+                }
+                StateReader[5]='T';
+                break;
+            }
+            Tecla=KeyPad_Read();
+            if(Tecla=='C') {
+                Computer.printf("\n Cancelar operacion");
+                if(CardReader.writeable()) {
+                    CardReader.putc(SOH);
+                    CardReader.putc(ADDR);
+                    CardReader.putc(LEN);
+                    CardReader.putc(LEN);
+                    CardReader.putc(ARM_ABORT);
+                    CardReader.putc(EOT);
+                    CardReader.putc(BBCG);
+                }
+                StateReader[5]='T';
+                return 2;
+            }
+        }
+        wait_ms(200);
+        for(int i=0; i<=CardReader_Counter; i++) {
+            Computer.printf("%c",CardReader_Buffer[i]);
+            Computer.printf("-%2X-",CardReader_Buffer[i]);
+            if(CardReader_Buffer[i]==R_NO_MAG_CARD) {
+                Computer.printf("\n Deteccion nula ");      // No se detecta banda magnetica
+                StateReader[6]='N';
+                return 0;
+            }
+            if(CardReader_Buffer[i]==R_ACTION) {
+                Computer.printf("\n Tarjeta leida ");       // Tarjeta leida
+                StateReader[6]='A';
+                return 1;
+            }
+            if(CardReader_Buffer[i]==R_INVALID) {
+                Computer.printf("\n Invalido ");             // Comando Invalido
+                StateReader[6]='N';
+                return 0;
+            }
+            if(CardReader_Buffer[i]==R_ERROR) {
+                Computer.printf("\n Error ");               // Error
+                StateReader[6]='E';
+                return 0;
+            }
+            if(CardReader_Buffer[i]==R_COMAND_ERROR) {
+                Computer.printf("\n Error comando ");        // Error en comando
+                StateReader[6]='C';
+                return 0;
+            }
+        }
+    }
+    return 0;
+}
+
+int RecibeDataCard()
+{
+    if (StateReader[6]=='A') {
+        CardReader_Counter=0;
+        if(CardReader.writeable()) {
+            CardReader.putc(SOH);               // 00000001
+            CardReader.putc(ADDR);              // 00000000
+            CardReader.putc(LEN);               // 00000000
+            CardReader.putc(LEN);               // 00000000
+            CardReader.putc(MAG_ISO_T2);        // 01010101
+            CardReader.putc(EOT);               // 00000100
+            CardReader.putc(BBCK);
+        }
+        wait_ms(200);
+        for(int i=0; i<=CardReader_Counter; i++) {
+            if(CardReader_Buffer[i]==R_NO_DATA) {
+                Computer.printf("Sin lectura\n");
+                return 0;
+            }
+            Computer.putc(CardReader_Buffer[i]);
+            if(CardReader_Buffer[i]=='=') {
+                Computer.printf("Datos leidos ");
+                for(int i=0; i<37; i++) {
+                    Track2[i]=CardReader_Buffer[i+4];
+                }
+                Computer.printf("<%s>\n",Track2);
+                Slave.Set_Track(Track2);
+                return 1;
+            }
+        }
+    }
+    return 2;
+}
+
+int RetiroTarjeta(uint32_t TiempoFuera)
+{
+    Computer.printf("Retiro tarjeta\n");
+    Inicio=BaseClock.read_ms();
+    while(true) {
+        if(PositionCard()==0) {
+            return 1;
+        } else {
+            Screen.Limits();                 // Se pide al usuario por pantalla el retiro de la tarjeta
+            Screen.PutString(15,12,"Retire tarjeta");
+            Screen.Show();
+        }
+        Fin=BaseClock.read_ms();
+        Transcurrido=Fin-Inicio;
+        if(Transcurrido>TiempoFuera) {
+            StateReader[1]='T';
+            return 0;
+        }
+    }
+}
+
+uint8_t IngresoTarjeta(uint32_t TimeOut)
+{
+    Computer.printf("Funcion ingreso de tarjeta\n");
+
+    Inicio=BaseClock.read_ms();
+    Keypad_Init();
+    while(true) {
+        if(PositionCard()==1) {
+            Computer.printf("Tarjeta ingresada\n");
+            StateReader[1]='A';
+            StateReader[2]='A';
+            StateReader[3]='A';
+            return 1;
+        }
+        Fin=BaseClock.read_ms();
+        Transcurrido=Fin-Inicio;
+        if(Transcurrido>TimeOut) {
+            Computer.printf("Tiempo limite\n");
+            StateReader[1]='T';
+            StateReader[2]='N';
+            StateReader[3]='N';
+            return 0;
+        }
+        Tecla=KeyPad_Read();
+        if(Tecla=='C') {
+            Computer.printf("Operacion cancelada\n");
+            StateReader[1]='T';
+            StateReader[2]='N';
+            StateReader[3]='N';
+            return 2;
+        }
+    }
+}
+
+uint8_t GetCard(char Salida,uint32_t TimeOutEntrada,uint32_t TimeOutSalida)
+{
+    //CardReaderStatus=[Reset,ArmDebug,DetectionOn,DetectionOff,Position,Arm,Read]
+    // C-> Command error
+    // A-> Accepted
+    // N-> Invalid
+    // E-> Error
+    // N-> No detection
+    // S-> Without answer
+    // T-> Time out
+    // Se pide al usuario por pantalla la intrduccion de la tarjeta
+
+    Screen.Limits();                     
+    Screen.PutString(15,12,"Introduzca tarjeta");
+    Screen.PutString(15,34,"debito o credito");
+    Screen.PutChar(26,33,'!');
+    Screen.PutChar(110,33,'!');
+    Screen.Show();
+    sprintf(Track2,"0000000000000000000000000000000000000");
+
+    if(ResetCard()==1) {
+        while(true) {
+            uint8_t RespuestaIngresoTarjeta = IngresoTarjeta(TimeOutEntrada);
+            if(RespuestaIngresoTarjeta==1) {
+                Screen.Limits();
+                Screen.PutString(15,12,"Retire tarjeta");
+                Screen.Show();
+            }
+            if(RespuestaIngresoTarjeta==0) {
+                Screen.PutString(15,12,"Sin deteccion");
+                Screen.PutChar(111,11,'!');
+                Screen.Limits();
+                Screen.Show();
+                wait(3);
+                Screen.Clean();
+                return USER_FINISH;
+            }
+            if(RespuestaIngresoTarjeta==2) {
+                Screen.Clean();
+                return USER_FINISH;
+            }
+
+            uint8_t RespuestaReadCard=ReadCard(TimeOutSalida); // Se le la tarjeta al retirarse
+            if(RespuestaReadCard==2) {
+                Screen.Clean();
+                return USER_FINISH;
+            }
+            
+            uint8_t DataResult=RecibeDataCard();                    // Se corrobora que la informacion de la tajeta es la corre
+            if(DataResult==0) {
+                Screen.PutString(15,12,"Banda magnetica");
+                Screen.PutChar(125,11,'!');
+                Screen.PutString(15,34,"ilegible");
+                Screen.Limits();
+                Screen.Show();
+                wait(2);
+                if(RetiroTarjeta(7000)) {
+                    Screen.Limits();
+                    Screen.PutString(15,12,"Introduzca tarjeta");
+                    Screen.PutString(15,34,"debito o credito");
+                    Screen.PutChar(26,33,'!');
+                    Screen.PutChar(110,33,'!');
+                    Screen.Show();
+                } else {
+                    Screen.Clean();
+                    return USER_FINISH;
+                }
+            }
+            if(DataResult==1) {
+                return Salida;
+            }
+            if(DataResult==2) {
+                Screen.PutString(15,12,"Banda magnetica");
+                Screen.PutChar(125,11,'!');
+                Screen.PutString(15,34,"ilegible");
+                Screen.Limits();
+                Screen.Show();
+                wait(2);
+                if(RetiroTarjeta(7000)) {
+                    Screen.Limits();
+                    Screen.PutString(15,12,"Introduzca tarjeta");
+                    Screen.PutString(15,34,"debito o credito");
+                    Screen.PutChar(26,33,'!');
+                    Screen.PutChar(110,33,'!');
+                    Screen.Show();
+                } else {
+                    Screen.Clean();
+                    return USER_FINISH;
+                }
+            }
+        }
+    } else {
+        Screen.Limits();
+        Screen.PutString(15,20,"Error");
+        Screen.Show();
+        wait(3);
+        Screen.Clean();
+        CardReaderPower=0;  
+        return USER_FINISH;
+    }
+}
+
+uint8_t Continuar(uint8_t Salida,uint32_t TimeOut)
+{
+    Inicio=BaseClock.read_ms();
+    while(true) {
+        if(Slave.Answer()) {
+            Computer.printf("Continuar\n");
+            return Salida;
+        }
+        Fin=BaseClock.read_ms();
+        Transcurrido=Fin-Inicio;
+        if(Transcurrido>TimeOut) {
+            Computer.printf("Continuar tiempo\n");
+            Screen.PutString(15,12,"Operacion");
+            Screen.PutChar(84,11,'!');
+            Screen.PutString(15,34,"no disponible");
+            Screen.Limits();
+            Screen.Show();
+            wait(4);
+            return USER_FINISH;
+        }
+
+    }
+}
+uint8_t Respuesta1(uint8_t Salida,uint32_t TimeOut)
+{
+    Screen.PutString(15,12,"Realizando");
+    Screen.PutString(15,34,"Operacion...");
+    Screen.PutChar(84,33,'!');
+    Screen.Limits();
+    Screen.Show();
+    wait_ms(TimeOut);
+    return Salida;
+}
+uint8_t Respuesta2(uint8_t Salida,uint32_t TimeOut)
+{
+    Inicio=BaseClock.read_ms();
+    while(true) {
+        if(Slave.Message()) {
+            Computer.printf("Respuesta recibida\n");
+            wait_ms(100);
+            break;
+        }
+        Fin=BaseClock.read_ms();
+        Transcurrido=Fin-Inicio;
+        if(Transcurrido>TimeOut) {
+            break;
+        }
+    }
+    InByte=Slave.Recibe();
+    Computer.printf("%c",InByte);
+    if(InByte=='A') {
+        Screen.PutString(15,12,"Operacion");
+        Screen.PutChar(84,11,'!');
+        Screen.PutString(15,34,"Aceptada");
+        Screen.Limits();
+        Screen.Show();
+        wait_ms(1000);
+        FechaRespuesta[9]=Slave.Recibe();
+        FechaRespuesta[9]=Slave.Recibe();
+        FechaRespuesta[8]=Slave.Recibe();
+        FechaRespuesta[7]=Slave.Recibe();
+        FechaRespuesta[6]=Slave.Recibe();
+        FechaRespuesta[5]=Slave.Recibe();
+        FechaRespuesta[4]=Slave.Recibe();
+        FechaRespuesta[3]=Slave.Recibe();
+        FechaRespuesta[2]=Slave.Recibe();
+        FechaRespuesta[1]=Slave.Recibe();
+        FechaRespuesta[0]=Slave.Recibe();
+        HoraRespuesta[4]=Slave.Recibe();
+        HoraRespuesta[4]=Slave.Recibe();
+        HoraRespuesta[3]=Slave.Recibe();
+        HoraRespuesta[2]=Slave.Recibe();
+        HoraRespuesta[1]=Slave.Recibe();
+        HoraRespuesta[0]=Slave.Recibe();
+        NumeroRespuesta[5]=Slave.Recibe();
+        NumeroRespuesta[5]=Slave.Recibe();
+        NumeroRespuesta[4]=Slave.Recibe();
+        NumeroRespuesta[3]=Slave.Recibe();
+        NumeroRespuesta[2]=Slave.Recibe();
+        NumeroRespuesta[1]=Slave.Recibe();
+        NumeroRespuesta[0]=Slave.Recibe();
+        Inicio=BaseClock.read_ms();
+        while(true) {
+            InByte=Slave.Recibe();
+            if(InByte==NO_DATA) {
+                break;
+            }
+            Fin=BaseClock.read_ms();
+            Transcurrido=Fin-Inicio;
+            if(Transcurrido>100) {
+                break;
+            }
+        }
+        Computer.printf("<%s> <%s> <%s>\n",FechaRespuesta,HoraRespuesta,NumeroRespuesta);
+        return Salida;
+    } else {
+        Screen.PutString(15,12,"Operacion");
+        Screen.PutString(15,34,"Rechazada");
+        Screen.PutChar(84,11,'!');
+        Screen.Limits();
+        Screen.Show();
+        wait_ms(3000);
+        Inicio=BaseClock.read_ms();
+        while(true) {
+            InByte=Slave.Recibe();
+            if(InByte==NO_DATA) {
+                break;
+            }
+            Fin=BaseClock.read_ms();
+            Transcurrido=Fin-Inicio;
+            if(Transcurrido>100) {
+                break;
+            }
+        }
+        return USER_FINISH;
+    }
+}
+
+void CalculoHoraFinal()
+{
+    int MinutoEstacionamiento=TiempoMinutos%60;
+    int HoraEstacionamiento=TiempoMinutos/60;
+
+    int HoraServicio=((uint8_t)HoraRespuesta[0]-48)*10+((uint8_t)HoraRespuesta[1]-48);
+    int MinutoServicio=((uint8_t)HoraRespuesta[3]-48)*10+((uint8_t)HoraRespuesta[4]-48);
+
+    if(HoraServicio<8){
+        HoraServicio=8;
+        MinutoServicio=0;
+    }
+    
+    int MinutosTotal = MinutoServicio + MinutoEstacionamiento;
+    int HorasTotal = HoraServicio + HoraEstacionamiento;
+
+    while(MinutosTotal >= 60) {
+        MinutosTotal = MinutosTotal - 60;
+        HorasTotal = HorasTotal + 1;
+    }
+    if(HorasTotal>=24) {
+        HorasTotal=HorasTotal-24;
+    }
+
+    if(MinutosTotal<10) {                             // Calcular tiempo en horas y minutos
+        sprintf(HoraFinal,"%i:0%i",HorasTotal,MinutosTotal);
+    } else {
+        sprintf(HoraFinal,"%i:%i",HorasTotal,MinutosTotal);
+    }
+
+}
+uint8_t ImpresoraIniciar(){
+    
+    if(Impresora.Power(1)){
+        uint8_t  val = Impresora.Reset();
+        return val;             
+    }
+    return 0;   
+}
+
+uint8_t Imprimir(uint8_t Salida,uint8_t Inicio)
+{
+    int State=Inicio;
+    if(State){
+        Screen.PutString(15,12,"Imprimiendo");
+        Screen.PutString(15,34,"Tiquete");
+        Screen.Limits();
+        Screen.Show();
+        CalculoHoraFinal();
+    }    
+
+    if(State==0) {
+        Screen.Limits();
+        Screen.PutString(15,12,"Operacion aceptada");
+        Screen.PutChar(84,11,'!');
+        Screen.PutString(15,34,"Tiquete no disponible");
+        Screen.Limits();
+        Screen.Show();
+        wait(2);
+        Computer.printf("Error.\n");
+        Impresora.End();
+        ParkingMeter.AlarmCall(2,'E');
+        wait(4);
+    }
+    if(State==2) {
+        Screen.Limits();
+        Screen.PutString(15,12,"Operacion aceptada");
+        Screen.PutChar(84,11,'!');
+        Screen.PutString(15,34,"Tiquete no disponible");
+        Screen.Limits();
+        Screen.Show();
+        wait(2);
+        Computer.printf("Error.\n");
+        Impresora.End();
+        ParkingMeter.AlarmCall(2,'E');
+        wait(4);
+    }
+    if(State==1) {        
+        State=Impresora.Output(FechaRespuesta,HoraRespuesta,HoraFinal,Espacio,Tiempo,NumeroRespuesta,Importe);
+        if(State==0) {
+            Computer.printf("Alarma Output\n");
+            ParkingMeter.AlarmCall(2,'E');
+        } else {
+            ParkingMeter.AlarmCall(2,'A');
+        }
+
+        State=Impresora.Paper(400);
+        if(State==0) {
+            Computer.printf("Alarma Papel\n");
+            ParkingMeter.AlarmCall(2,'E');
+        } else {
+            ParkingMeter.AlarmCall(2,'A');
+        }
+
+        State=Impresora.Cutter(1);
+        if(State==0) {
+            Computer.printf("Alarma Cutter\n");
+            ParkingMeter.AlarmCall(2,'E');
+        } else {
+            ParkingMeter.AlarmCall(2,'A');
+        }
+
+        Screen.PutString(15,12,"Retire");
+        Screen.PutString(15,34,"Tiquete");
+        Screen.Limits();
+        Screen.Show();
+        wait(1);
+        
+        State=Impresora.End();
+        if(State==0) {
+            Computer.printf("Alarma Cutter\n");
+            ParkingMeter.AlarmCall(2,'E');
+        } else {
+            ParkingMeter.AlarmCall(2,'A');
+        } 
+        wait(1);       
+    }
+
+    State=Impresora.Power(0);
+    int TiquetesDisponibles=Papel-Impresora.Ticket(1);
+    if(TiquetesDisponibles<200) {
+        sprintf(PapelDisponible,"%i",TiquetesDisponibles);
+        ParkingMeter.AlarmCall(3,'E');
+    } else {
+        sprintf(PapelDisponible,"%i",TiquetesDisponibles);
+        ParkingMeter.AlarmCall(3,'A');
+    }
+    return Salida;
+}
+
+
+void Usuario_OperacionConsecutiva()
+{
+    uint8_t Comando=USER_INIT;
+    int PrinterState;
+    if(Comando==USER_INIT) {
+        Computer.printf("Usuario operacion consecutiva\n");
+        Impresora.PowerMax(1);
+        Screen.On();
+        wait_ms(20);
+        Screen.Init();
+        Screen.Clean();
+        BaseClock.reset();
+        Comando=USER_PLACE;
+    }
+
+    if(Comando==USER_PLACE) {
+        Computer.printf("Usuario espacio\n");
+        CardReaderPower=1;
+        Comando=GetPlace(USER_CARD,15000);
+        if(Comando==USER_CARD) {
+            Slave.Command(COMMAND_INIT);
+        }
+    }
+
+    if(Comando==USER_CARD) {
+        Computer.printf("Usuario tarjeta\n");
+        Comando=GetCard(USER_TIME,20000,5000);
+        if(Comando==USER_TIME) {
+            Slave.Command(COMMAND_GPRS);
+        }
+    }
+
+    if(Comando==USER_TIME) {
+        Computer.printf("Usuario tiempo\n");
+        CardReaderPower=0;
+        Comando=GetTime(USER_DATA,15000);
+        if (Comando==USER_FINISH){
+            Slave.Command(COMMAND_END);
+        }
+        Comando=Continuar(Comando,7000);
+    }
+
+    if(Comando==USER_DATA) {
+        Computer.printf("Usuario datos\n");
+        Slave.Command(COMMAND_DATA);
+        Slave.Encryption_Data(Parquimetro,Municipio,TiempoMinutos,Espacio,Track2);
+        Slave.Encryption_Execute();
+        Slave.Encryption_Send();           
+        Computer.printf("Tiempo: %i\n",TiempoMinutos);
+        Computer.printf("Parquimetro: %s\n",Parquimetro);
+        Computer.printf("Municipio: %s\n",Municipio);
+        Computer.printf("Espacio: %s\n",Espacio);
+        Computer.printf("Track2: %s\n",Track2);        
+        Comando=Continuar(USER_POST,20000);
+        if (Comando==USER_FINISH){
+            Slave.Command(COMMAND_END);
+        } 
+    }
+
+    if(Comando==USER_POST) {
+        Computer.printf("Usuario operacion\n");
+        Slave.Command(COMMAND_POST);
+        Comando=Respuesta1(USER_ANSWER,20);
+    }
+
+    if(Comando==USER_ANSWER) {
+        Computer.printf("Usuario respuesta\n");
+        Slave.Command(COMMAND_ANSWER);
+        PrinterState = ImpresoraIniciar();
+        Comando=Respuesta2(USER_PRINT,50000);
+    }
+
+    if(Comando==USER_PRINT) {
+        Computer.printf("Usuario imprimiendo\n");
+        Comando=Imprimir(USER_FINISH,PrinterState);
+    }
+
+    if(Comando==USER_FINISH) {
+        Computer.printf("Usuario finalizar\n");
+        Comando=Impresora.End();
+        Screen.Clean();
+        CardReaderPower=0;
+        Impresora.Power(0);
+        Screen.Off();
+    }
+}
+
+void Usuario(uint8_t Entrada)
+{
+    int PrinterState;
+    uint8_t Comando=Entrada;
+    if(Comando==USER_INIT) {
+        Host.detach();//1800 30 minutosHost.attach(&Interrupt_Host,5);//1800 30 minutos
+        Computer.printf("Usuario iniciar 1\n");
+        ParkingMeter.Max232(1);
+        Impresora.PowerMax(1);
+        Screen.On();
+        Screen.Init();
+        Slave.Awake();
+        Slave.Command(COMMAND_ON);
+        BaseClock.start();
+        BaseClock.reset();
+        Comando=USER_PLACE;
+    }
+
+    if(Comando==USER_INIT2) {
+        Computer.printf("Usuario iniciar 2\n");
+        ParkingMeter.Max232(1);
+        Impresora.PowerMax(1);
+        BaseClock.start();
+        BaseClock.reset();
+        Comando=USER_PLACE;
+    }
+    
+    if(Comando==USER_INIT3) {
+        Computer.printf("Usuario iniciar 3\n");
+        ParkingMeter.Max232(1);
+        Impresora.PowerMax(1);
+        Computer.printf("Usuario espacio\n");
+        BaseClock.start();
+        BaseClock.reset();
+        CardReaderPower=1;
+        Comando=GetPlace(USER_CARD,15000);
+    }
+    
+    if(Comando==USER_INIT4) {
+        Computer.printf("Usuario iniciar 4\n");
+        ParkingMeter.Max232(1);
+        Impresora.PowerMax(1);
+        Computer.printf("Usuario espacio\n");
+        BaseClock.start();
+        BaseClock.reset();
+        CardReaderPower=1;
+        Comando=GetPlace(USER_CARD2,15000);
+    }    
+    
+    if(Comando==USER_INIT5) {
+        Computer.printf("Usuario iniciar 5\n");
+        ParkingMeter.Max232(1);
+        Impresora.PowerMax(1);
+        Computer.printf("Usuario espacio\n");
+        BaseClock.start();
+        BaseClock.reset();
+        CardReaderPower=1;
+        Comando=GetPlace(USER_CARD2,15000);
+        if(Comando==USER_CARD2) {
+            Slave.Command(HOSTING_OFF);
+        }
+    }
+
+    if(Comando==USER_PLACE) {
+        Computer.printf("Usuario espacio\n");
+        CardReaderPower=1;
+        Comando=GetPlace(USER_CARD,15000);        
+        if(Comando==USER_CARD) {
+            Slave.Command(COMMAND_INIT);
+        }
+    }
+    
+    if(Comando==USER_CARD) {
+        Computer.printf("Usuario tarjeta\n");
+        Comando=GetCard(USER_TIME,20000,5000);
+        if(Comando==USER_TIME) {
+            Slave.Command(COMMAND_GPRS);
+        }
+    }
+    
+    if(Comando==USER_CARD2) {
+        Computer.printf("Usuario tarjeta 2\n");
+        Comando=GetCard(USER_TIME,20000,5000);
+    }
+
+    if(Comando==USER_TIME) {
+        Computer.printf("Usuario tiempo\n");
+        CardReaderPower=0;
+        Comando=GetTime(USER_DATA,15000);
+        if (Comando==USER_FINISH){
+            Slave.Command(COMMAND_END);
+        }
+        Comando=Continuar(Comando,8000);
+    }
+
+    if(Comando==USER_DATA) {
+        Computer.printf("Usuario datos\n");
+        Slave.Command(COMMAND_DATA);
+        Slave.Encryption_Data(Parquimetro,Municipio,TiempoMinutos,Espacio,Track2);
+        Slave.Encryption_Execute();
+        Slave.Encryption_Send();           
+        Computer.printf("Tiempo: %i\n",TiempoMinutos);
+        Computer.printf("Parquimetro: %s\n",Parquimetro);
+        Computer.printf("Municipio: %s\n",Municipio);
+        Computer.printf("Espacio: %s\n",Espacio);
+        Computer.printf("Track2: %s\n",Track2);
+        Comando=Continuar(USER_POST,20000);
+        if (Comando==USER_FINISH){
+            Slave.Command(COMMAND_END);
+        }        
+    }
+
+    if(Comando==USER_POST) {
+        Computer.printf("Usuario operacion\n");
+        Slave.Command(COMMAND_POST);
+        Slave.Encryption_Print();
+        Comando=Respuesta1(USER_ANSWER,50);
+    }
+
+    if(Comando==USER_ANSWER) {
+        Computer.printf("Usuario respuesta\n");
+        Slave.Command(COMMAND_ANSWER);
+        PrinterState = ImpresoraIniciar();
+        Comando=Respuesta2(USER_PRINT,50000);
+    }
+
+    if(Comando==USER_PRINT) {
+        Computer.printf("Usuario imprimiendo\n");
+        Comando=Imprimir(USER_FINISH,PrinterState);
+    }
+
+    if(Comando==USER_FINISH) {
+        Computer.printf("Usuario finalizar\n");
+        Impresora.End();
+        Impresora.Power(0);
+        CardReaderPower=0;
+        Screen.Clean();
+        Screen.Off();
+        Inicio=BaseClock.read_ms();
+        Keypad_Init();
+        while(true) {
+            Fin=BaseClock.read_ms();
+            Transcurrido=Fin-Inicio;
+            if(Transcurrido>10000) {
+                break;
+            }
+            Tecla=KeyPad_Read();
+            if (Tecla!=NO_KEY) {
+                Usuario_OperacionConsecutiva();
+                Inicio=BaseClock.read_ms();
+            }
+        }
+        Slave.Command(COMMAND_OFF);
+    }
+}
+
+void EsperarSim900(int TimeOut)
+{
+    Computer.printf("Espera sim900\n");
+    Inicio=BaseClock.read_ms();
+    Keypad_Init();     
+    while(true) {
+        Fin=BaseClock.read_ms();
+        Transcurrido=Fin-Inicio; 
+        if(Transcurrido>TimeOut) {
+            Computer.printf("Espera sim900 salir\n");
+            BaseClock.stop();
+            ParkingMeter.Max232(0);
+            break;
+        }
+        Tecla=KeyPad_Read();
+        if (Tecla!=NO_KEY) { 
+            Computer.printf("Espera sim900 teclado\n");
+            Screen.On();
+            Screen.Init();
+            PantallaInicio();
+            Usuario(USER_INIT);
+            Inicio=BaseClock.read_ms();         
+        }
+    }
+}
+
+//-----------------------------------------------------------------------------------------------------------------------------------------------------
+
+void Interrupt_Mantenimiento()
+{
+    MantenimientoInterruption=1;
+}
+
+void M_PantallaConfiguracion()
+{
+    Computer.printf("Pantala modo configuracion\n");
+    Screen.Limits();
+    Screen.PutString(35,19,"Modo Configuracion");
+    Screen.Show();
+    wait_ms(1000);
+}
+
+uint8_t M_MenuConfiguracion(uint32_t Delay)
+{
+    int Selection=1;
+    uint8_t Salida=M_SISTEMA;
+    int SelectionBox[2]= {4,7};
+    Inicio=BaseClock.read_ms();
+
+    Screen.Limits();
+    Screen.Rectangle(SelectionBox[0],SelectionBox[1],8,8);
+    Screen.PutString(15,4,"Sistema");
+    Screen.PutString(15,23,"Red");
+    Screen.PutString(15,42,"Impresora");
+    Screen.PutString(135,4,"Teclado");
+    Screen.PutString(135,23,"Lectora");
+    Screen.PutString(135,42,"Informacion");
+    Screen.Show();
+
+    Computer.printf("Sistema\n");
+
+    while(true) {
+        Fin=BaseClock.read_ms();
+        Transcurrido=Fin-Inicio;
+        if(Transcurrido>Delay) {
+            return M_OFF;
+        }
+        Tecla = KeyPad_Read();
+        if (Tecla!=NO_KEY) {                        // Se valida que se ingrese algo en el teclado
+            Inicio=BaseClock.read_ms();
+            if (Tecla=='F') {                       //Subir puntero
+                Selection++;
+                if(Selection==7) {
+                    Selection=1;
+                }
+            }
+            if (Tecla=='E') {                       //Bajar puntero
+                Selection--;
+                if(Selection==0) {
+                    Selection=6;
+                }
+            }              
+            if (Tecla=='C') {                       //Cancelar Operacion
+                return M_OFF;
+            }         
+            if (Tecla=='D') {                       //En caso de confirmacion
+                return Salida;
+            }
+            switch (Selection) {
+                case 1:
+                    SelectionBox[0]=4;
+                    SelectionBox[1]=7;
+                    Computer.printf("Sistema\n");
+                    Salida=M_SISTEMA;
+                    break;
+                case 2:
+                    SelectionBox[0]=4;
+                    SelectionBox[1]=26;
+                    Computer.printf("Red\n");
+                    Salida=M_RED;
+                    break;
+                case 3:
+                    SelectionBox[0]=4;
+                    SelectionBox[1]=45;
+                    Computer.printf("Impresora\n");
+                    Salida=M_IMPRESORA;
+                    break;
+                case 4:
+                    SelectionBox[0]=124;
+                    SelectionBox[1]=7;
+                    Computer.printf("Teclado\n");
+                    Salida=M_TECLADO;
+                    break;
+                case 5:
+                    SelectionBox[0]=124;
+                    SelectionBox[1]=26;
+                    Computer.printf("Lectora\n");
+                    Salida=M_LECTORA;
+                    break;
+                case 6:
+                    SelectionBox[0]=124;
+                    SelectionBox[1]=45;
+                    Computer.printf("Informacion\n");
+                    Salida=M_INFORMACION;
+                    break;
+            }
+
+            Screen.Limits();
+            Screen.Rectangle(SelectionBox[0],SelectionBox[1],8,8);
+            Screen.PutString(15,4,"Sistema");
+            Screen.PutString(15,23,"Red");
+            Screen.PutString(15,42,"Impresora");
+            Screen.PutString(135,4,"Teclado");
+            Screen.PutString(135,23,"Lectora");
+            Screen.PutString(135,42,"Informacion");
+            Screen.Show();
+        }
+    }
+}
+
+uint8_t M_MenuSistema(uint32_t Delay)
+{
+    uint8_t Salida=M_PARQUIMETRO;
+    int Selection=1;
+    int SelectionBox[2]= {4,7};
+    Inicio=BaseClock.read_ms();
+
+    Screen.Limits();
+    Screen.Rectangle(SelectionBox[0],SelectionBox[1],8,8);
+    Screen.PutString(15,4,"Id Parquimetro");
+    Screen.PutString(15,23,"Id Municipalidad");
+    Screen.PutString(15,42,"Precio 30 mins");
+    Screen.Show();
+    Computer.printf("Id parquimetro\n");
+
+    while(true) {
+        Fin=BaseClock.read_ms();
+        Transcurrido=Fin-Inicio;
+        if(Transcurrido>Delay) {
+            return M_OFF;
+        }
+        Tecla = KeyPad_Read();
+        if (Tecla!=NO_KEY) {                  // Se valida que se ingrese algo en el teclado
+            Inicio=BaseClock.read_ms();
+            if (Tecla=='F') {                       //Subir puntero
+                Selection++;
+                if(Selection==4) {
+                    Selection=1;
+                }
+            }
+            if (Tecla=='E') {                        //Bajar puntero
+                Selection--;
+                if(Selection==0) {
+                    Selection=3;
+                }
+            }            
+            if (Tecla=='C') {                        //Cancelar Operacion
+                return M_OFF;
+            }
+            if (Tecla=='B') {                        //Atras en menu
+                return M_ATRAS;
+            }
+            if (Tecla=='D') {                        //En caso de confirmacion
+                return Salida;
+            }
+            switch (Selection) {
+                case 1:
+                    SelectionBox[1]=7;
+                    Computer.printf("Id Parquimetro\n");
+                    Salida=M_PARQUIMETRO;
+                    break;
+                case 2:
+                    SelectionBox[1]=26;
+                    Computer.printf("Id Municipalidad\n");
+                    Salida=M_MUNICIPIO;
+                    break;
+                case 3:
+                    SelectionBox[1]=45;
+                    Computer.printf("Precio 30mins\n");
+                    Salida=M_PRECIO;
+                    break;
+            }
+            Screen.Limits();
+            Screen.Rectangle(SelectionBox[0],SelectionBox[1],8,8);
+            Screen.PutString(15,4,"Id Parquimetro");
+            Screen.PutString(15,23,"Id Municipalidad");
+            Screen.PutString(15,42,"Precio 30 mins");
+            Screen.Show();
+        }
+    }
+}
+
+uint8_t M_MenuConexion(uint32_t Delay)
+{
+    uint8_t Salida=M_SENAL;
+    int Selection=1;
+    int SelectionBox[2]= {4,7};
+    Inicio=BaseClock.read_ms();
+
+    Screen.Limits();
+    Screen.Rectangle(SelectionBox[0],SelectionBox[1],8,8);
+    Screen.Rectangle(129,6,5,0);
+    Screen.PutString(15,4,"Intensidad senal");
+    Screen.PutString(15,23,"Prueba hosting");
+    Screen.PutString(15,42,"Conexion red");
+    Screen.Show();
+
+    Computer.printf("Intensidad senal\n");
+
+    while(true) {
+        Fin=BaseClock.read_ms();
+        Transcurrido=Fin-Inicio;
+        if(Transcurrido>Delay) {
+            return M_OFF;
+        }
+        Tecla = KeyPad_Read();
+        if (Tecla!=NO_KEY) {                  // Se valida que se ingrese algo en el teclado
+            Inicio=BaseClock.read_ms();
+            if (Tecla=='F') {                    //Subir puntero
+                Selection++;
+                if(Selection==4) {
+                    Selection=1;
+                }
+            }
+            if (Tecla=='E') {                       //Bajar puntero
+                Selection--;
+                if(Selection==0) {
+                    Selection=3;
+                }
+            }
+            if (Tecla=='B') {                       //Atras en menu
+                return M_ATRAS;
+            }            
+            if (Tecla=='C') {                       //Cancelar Operacion
+                return M_OFF;
+            }     
+            if (Tecla=='D') {                       //En caso de confirmacion
+                return Salida;
+            }
+            switch (Selection) {
+                case 1:
+                    SelectionBox[1]=7;
+                    Computer.printf("Intensidad senal\n");
+                    Salida=M_SENAL;
+                    break;
+                case 2:
+                    SelectionBox[1]=26;
+                    Computer.printf("Prueba hosting\n");
+                    Salida=M_HOSTING;
+                    break;
+                case 3:
+                    SelectionBox[1]=45;
+                    Computer.printf("Conexion red\n");
+                    Salida=M_CONEXION_SIM ;
+                    break;
+            }
+            Screen.Limits();
+            Screen.Rectangle(SelectionBox[0],SelectionBox[1],8,8);
+            Screen.Rectangle(129,6,5,0);
+            Screen.PutString(15,4,"Intensidad senal");
+            Screen.PutString(15,23,"Prueba hosting");
+            Screen.PutString(15,42,"Conexion red");
+            Screen.Show();
+        }
+    }
+}
+
+uint8_t M_MenuImpresora(uint32_t Delay)
+{
+    uint8_t Salida=M_PAPEL;
+    int Selection=1;
+    int SelectionBox[2]= {4,7};
+    Inicio=BaseClock.read_ms();
+
+    Screen.Limits();
+    Screen.Rectangle(SelectionBox[0],SelectionBox[1],8,8);
+    Screen.PutString(15,4,"Cambio de papel");
+    Screen.PutString(15,23,"Tiquete de prueba");
+    Screen.PutString(15,42,"Conexion impresora");
+    Screen.Show();
+
+    Computer.printf("Cambio de papel\n");
+
+    while(true) {
+        Fin=BaseClock.read_ms();
+        Transcurrido=Fin-Inicio;
+        if(Transcurrido>Delay) {
+            return M_OFF;
+        }
+        Tecla = KeyPad_Read();
+        if (Tecla!=NO_KEY) {                  // Se valida que se ingrese algo en el teclado
+            Inicio=BaseClock.read_ms();
+            if (Tecla=='F') {                    //Subir puntero
+                Selection++;
+                if(Selection==4) {
+                    Selection=1;
+                }
+            }
+            if (Tecla=='E') {                     //Bajar puntero
+                Selection--;
+                if(Selection==0) {
+                    Selection=3;
+                }
+            }            
+            if (Tecla=='C') {                     //Cancelar Operacion
+                return M_OFF;
+            }
+            if (Tecla=='B') {                     //Atras en menu
+                return M_ATRAS;
+            }      
+            if (Tecla=='D') {                     //En caso de confirmacion
+                return Salida;
+            }
+            switch (Selection) {
+                case 1:
+                    SelectionBox[1]=7;
+                    Computer.printf("Cambio de papel\n");
+                    Salida=M_PAPEL;
+                    break;
+                case 2:
+                    SelectionBox[1]=26;
+                    Computer.printf("Tiquete de prueba\n");
+                    Salida=M_IMPRESION;
+                    break;
+                case 3:
+                    SelectionBox[1]=45;
+                    Computer.printf("Conexion impresora\n");
+                    Salida=M_CONEXION_IMP;
+                    break;
+            }
+            Screen.Limits();
+            Screen.Rectangle(SelectionBox[0],SelectionBox[1],8,8);
+            Screen.PutString(15,4,"Cambio de papel");
+            Screen.PutString(15,23,"Tiquete de prueba");
+            Screen.PutString(15,42,"Conexion impresora");
+            Screen.Show();
+        }
+    }
+}
+
+uint8_t M_MenuLectora(uint32_t Delay)
+{
+    uint8_t Salida=M_LECTURA;
+    int Selection=1;
+    int SelectionBox[2]= {4,7};
+    Inicio=BaseClock.read_ms();
+
+    Screen.Limits();
+    Screen.Rectangle(SelectionBox[0],SelectionBox[1],8,8);
+    Screen.PutString(15,4,"Prueba de lectura");
+    Screen.PutString(15,23,"Conexion lectora");
+    Screen.Show();
+
+    Computer.printf("Prueba de lectura\n");
+
+    while(true) {
+        Fin=BaseClock.read_ms();
+        Transcurrido=Fin-Inicio;
+        if(Transcurrido>Delay) {
+            return M_OFF;
+        }
+        Tecla = KeyPad_Read();
+        if (Tecla!=NO_KEY) {                  // Se valida que se ingrese algo en el teclado
+            Inicio=BaseClock.read_ms();
+            if (Tecla=='F') {                    //Subir puntero
+                Selection++;
+                if(Selection==3) {
+                    Selection=1;
+                }
+            }
+            if (Tecla=='E') {                     //Bajar puntero
+                Selection--;
+                if(Selection==0) {
+                    Selection=2;
+                }
+            }
+            if (Tecla=='C') {                     //Cancelar Operacion
+                return M_OFF;
+            }
+            if (Tecla=='B') {                     //Atras en menu
+                return M_ATRAS;
+            }        
+            if (Tecla=='D') {                     //En caso de confirmacion
+                return Salida;
+            }
+            switch (Selection) {
+                case 1:
+                    SelectionBox[1]=7;
+                    Computer.printf("Prueba de lectura\n");
+                    Salida=M_LECTURA;
+                    break;
+                case 2:
+                    SelectionBox[1]=26;
+                    Computer.printf("Conexion lectora\n");
+                    Salida=M_CONEXION_LEC;
+                    break;
+            }
+            Screen.Limits();
+            Screen.Rectangle(SelectionBox[0],SelectionBox[1],8,8);
+            Screen.PutString(15,4,"Prueba de lectura");
+            Screen.PutString(15,23,"Conexion lectora");
+            Screen.Show();
+        }
+    }
+}
+
+uint8_t M_MenuTeclado(long Delay)
+{
+    uint8_t Salida=M_PRUEBA_TECLA;
+    int Selection=1;
+    int SelectionBox[2]= {4,7};
+    Inicio=BaseClock.read_ms();
+
+    Screen.Limits();
+    Screen.Rectangle(SelectionBox[0],SelectionBox[1],8,8);
+    Screen.PutString(15,4,"Prueba de teclado");
+    Screen.Show();
+    Computer.printf("Prueba de teclado\n");
+
+    while(true) {
+        Fin=BaseClock.read_ms();
+        Transcurrido=Fin-Inicio;
+        if(Transcurrido>Delay) {
+            return M_OFF;
+        }
+        Tecla = KeyPad_Read();
+        if (Tecla!=NO_KEY) {                  // Se valida que se ingrese algo en el teclado
+            Inicio=BaseClock.read_ms();
+            if (Tecla=='F') {                    //Subir puntero
+                Selection++;
+                if(Selection==2) {
+                    Selection=1;
+                }
+            }
+            if (Tecla=='E') {                     //Bajar puntero
+                Selection--;
+                if(Selection==0) {
+                    Selection=1;
+                }
+            }              
+            if (Tecla=='C') {                     //Cancelar Operacion
+                return M_OFF;
+            }
+            if (Tecla=='B') {                     //Atras en menu
+                return M_ATRAS;
+            }        
+            if (Tecla=='D') {                     //En caso de confirmacion
+                return Salida;
+            }
+            switch (Selection) {
+                case 1:
+                    SelectionBox[1]=7;
+                    Computer.printf("Prueba de teclado\n");
+                    Salida=M_PRUEBA_TECLA;
+                    break;
+            }
+            Screen.Limits();
+            Screen.Rectangle(SelectionBox[0],SelectionBox[1],8,8);
+            Screen.PutString(15,4,"Prueba de teclado");
+            Screen.Show();
+        }
+    }
+}
+
+uint8_t M_MenuInformacion()
+{
+    return M_INFORMACION;
+}
+
+bool M_ClaveIngreso(uint32_t TimeOut)
+{
+    char Clave_Actual[5]="))))";
+    int SelectionLine=99;
+    int Line=1;
+    Inicio=BaseClock.read_ms();
+
+    Screen.Rectangle(SelectionLine,32,8,0);
+    Screen.Rectangle(SelectionLine,50,8,0);
+    Screen.PutString(15,12,"Ingrese password");
+    Screen.PutChar(100,34,Clave_Actual[0]);
+    Screen.PutChar(110,34,Clave_Actual[1]);
+    Screen.PutChar(120,34,Clave_Actual[2]);
+    Screen.PutChar(130,34,Clave_Actual[3]);
+    Screen.Limits();
+    Screen.Show();
+    Computer.printf("Ingrese password\n");
+    Computer.printf("%s\n",Clave);
+
+    while(true) {
+        Fin=BaseClock.read_ms();
+        Transcurrido=Fin-Inicio;
+        if(Transcurrido>TimeOut) {
+            return 0;
+        }
+        Tecla=KeyPad_Read();
+        if (Tecla!=NO_KEY) {                  // Se valida que se ingrese algo en el teclado
+            Inicio=BaseClock.read_ms();
+             if ((Tecla=='0')||(Tecla=='1')||(Tecla=='2')||(Tecla=='3')||(Tecla=='4')||(Tecla=='5')||(Tecla=='6')||(Tecla=='7')||(Tecla=='8')||(Tecla=='9')) {                     //Cambiar numero
+                Clave_Actual[Line-1]=Tecla;
+                Line++;
+                Screen.Rectangle(SelectionLine,32,8,0);
+                Screen.Rectangle(SelectionLine,50,8,0);
+                Screen.PutString(15,12,"Ingrese password");
+                Screen.PutChar(100,34,Clave_Actual[0]);
+                Screen.PutChar(111,34,Clave_Actual[1]);
+                Screen.PutChar(122,34,Clave_Actual[2]);
+                Screen.PutChar(133,34,Clave_Actual[3]);
+                Screen.Limits();
+                Screen.Show();
+                if(Line==5) {
+                    Line=1;
+                }
+                if(Line==0) {
+                    Line=4;
+                }
+                wait_ms(100);
+            }
+            if (Tecla=='E') {                     //Subir puntero
+                Line++;
+                if(Line==5) {
+                    Line=1;
+                }
+            }
+            if (Tecla=='F') {                     //Bajar puntero
+                Line--;
+                if(Line==0) {
+                    Line=4;
+                }
+            }         
+            if (Tecla=='C') {                    //Cancelar Operacion
+                return 0;
+            }
+            if (Tecla=='B') {                     //Atras en menu
+                return 0;
+            }        
+            if (Tecla=='D') {                     //En caso de confirmacion
+                if((Clave_Actual[0]==Clave[0])&&(Clave_Actual[1]==Clave[1])&&(Clave_Actual[2]==Clave[2])&&(Clave_Actual[3]==Clave[3])) {
+                    return 1;
+                } else {
+                    return 0;
+                }
+            }
+            switch (Line) {
+                case 1:
+                    SelectionLine=99;
+                    break;
+                case 2:
+                    SelectionLine=110;
+                    break;
+                case 3:
+                    SelectionLine=121;
+                    break;
+                case 4:
+                    SelectionLine=132;
+                    break;
+            }
+            //-------Mostrar en Patalla-------
+            Screen.Rectangle(SelectionLine,32,8,0);
+            Screen.Rectangle(SelectionLine,50,8,0);
+            Screen.PutString(15,12,"Ingrese password");
+            Screen.PutChar(100,34,')');
+            Screen.PutChar(111,34,')');
+            Screen.PutChar(122,34,')');
+            Screen.PutChar(133,34,')');
+            Screen.Limits();
+            Screen.Show();
+            Computer.printf("%s\n",Clave);
+        }
+    }
+}
+
+void M_Parquimetro(uint32_t TimeOut)
+{
+    char ID_Actual[5];   //Lectura de valor en memoria
+    sprintf(ID_Actual,"%s",Parquimetro);
+    int SelectionLine = 99;
+    int Line=1;
+
+    Inicio=BaseClock.read_ms();
+
+    Screen.Rectangle(SelectionLine,32,9,0);
+    Screen.Rectangle(SelectionLine,50,9,0);
+    Screen.PutString(15,12,"Id Parquimetro");
+    Screen.PutChar(100,34,ID_Actual[0]);
+    Screen.PutChar(110,34,ID_Actual[1]);
+    Screen.PutChar(120,34,ID_Actual[2]);
+    Screen.PutChar(130,34,ID_Actual[3]);
+    Screen.Limits();
+    Screen.Show();
+    Computer.printf("Id Parquimetro\n");
+    Computer.printf("%s\n",ID_Actual);
+
+    while(true) {
+        Fin=BaseClock.read_ms();
+        Transcurrido=Fin-Inicio;
+        if(Transcurrido>TimeOut) {
+            break;
+        }
+        Tecla=KeyPad_Read();
+        if (Tecla!=NO_KEY) {                  // Se valida que se ingrese algo en el teclado
+            Inicio=BaseClock.read_ms();
+            if ((Tecla=='0')||(Tecla=='1')||(Tecla=='2')||(Tecla=='3')||(Tecla=='4')||(Tecla=='5')||(Tecla=='6')||(Tecla=='7')||(Tecla=='8')||(Tecla=='9')) {                     //Cambiar numero
+                if((Tecla=='0')&&(Line==1)) {
+                    ID_Actual[Line-1]='1';
+                } else {
+                    ID_Actual[Line-1]=Tecla;
+                }
+                Line++;
+                if(Line==5) {
+                    Line=1;
+                }
+                if(Line==0) {
+                    Line=4;
+                }
+            }
+            if (Tecla=='E') {                    //Subir puntero
+                Line++;
+                if(Line==5) {
+                    Line=1;
+                }
+            }
+            if (Tecla=='F') {                     //Bajar puntero
+                Line--;
+                if(Line==0) {
+                    Line=4;
+                }
+            }              
+            if (Tecla=='C') {                     //Cancelar Operacion
+                break;
+            }
+            if (Tecla=='B') {                     //Atras en menu
+                break;
+            }
+            if (Tecla=='D') {                     //En caso de confirmacion
+                sprintf(Parquimetro,"%s",ID_Actual);
+                break;
+            }
+            switch (Line) {
+                case 1:
+                    SelectionLine=99;
+                    break;
+                case 2:
+                    SelectionLine=109;
+                    break;
+                case 3:
+                    SelectionLine=119;
+                    break;
+                case 4:
+                    SelectionLine=129;
+                    break;
+            }
+            //-------Mostrar en Patalla-------
+            Screen.Rectangle(SelectionLine,32,9,0);
+            Screen.Rectangle(SelectionLine,50,9,0);
+            Screen.PutString(15,12,"Id Parquimetro");
+            Screen.PutChar(100,34,ID_Actual[0]);
+            Screen.PutChar(110,34,ID_Actual[1]);
+            Screen.PutChar(120,34,ID_Actual[2]);
+            Screen.PutChar(130,34,ID_Actual[3]);
+            Screen.Limits();
+            Screen.Show();
+            Computer.printf("%s\n",ID_Actual);
+        }
+    }
+}
+
+void M_Municipio(uint32_t TimeOut)
+{
+    char CodigoMunicipio_Actual[3];   //Lectura de valor en memoria
+    sprintf(CodigoMunicipio_Actual,"%s",CodigoMunicipio);
+
+    int SelectionLine=109;
+    int Line=1;
+
+    Inicio=BaseClock.read_ms();
+
+    Screen.Rectangle(SelectionLine,32,9,0);
+    Screen.Rectangle(SelectionLine,50,9,0);
+    Screen.PutString(15,12,"Id Municipalidad");
+    Screen.PutChar(110,34,CodigoMunicipio_Actual[0]);
+    Screen.PutChar(120,34,CodigoMunicipio_Actual[1]);
+    Screen.Limits();
+    Screen.Show();
+    Computer.printf("Id Municipalidad\n");
+    Computer.printf("%s\n",CodigoMunicipio_Actual);
+
+    while(true) {
+        Fin=BaseClock.read_ms();
+        Transcurrido=Fin-Inicio;
+        if(Transcurrido>TimeOut) {
+            break;
+        }
+        Tecla=KeyPad_Read();
+        if (Tecla!=NO_KEY) {                  // Se valida que se ingrese algo en el teclado
+            Inicio=BaseClock.read_ms();
+            if ((Tecla=='0')||(Tecla=='1')||(Tecla=='2')||(Tecla=='3')||(Tecla=='4')||(Tecla=='5')||(Tecla=='6')||(Tecla=='7')||(Tecla=='8')||(Tecla=='9')) {                     //Cambiar numero
+                CodigoMunicipio_Actual[Line-1]=Tecla;
+                Line++;
+                if(Line==3) {
+                    Line=1;
+                }
+                if(Line==0) {
+                    Line=2;
+                }
+            }
+            if (Tecla=='E') {                    //Subir puntero
+                Line++;
+                if(Line==3) {
+                    Line=1;
+                }
+            }
+            if (Tecla=='F') {                     //Bajar puntero
+                Line--;
+                if(Line==0) {
+                    Line=2;
+                }
+            }          
+            if (Tecla=='C') {                    //Cancelar Operacion
+                break;
+            }
+            if (Tecla=='B') {                     //Atras en menu
+                break;
+            }         
+            if (Tecla=='D') {                     //En caso de confirmacion
+                sprintf(CodigoMunicipio,"%s",CodigoMunicipio_Actual);
+                if((CodigoMunicipio[0]=='0')&&(CodigoMunicipio[1]=='1')) {
+                    sprintf(Municipio,"San Jose ");
+                    Computer.printf("San Jose\n");
+                }
+                if((CodigoMunicipio[0]=='0')&&(CodigoMunicipio[1]=='2')) {
+                    sprintf(Municipio,"Tibas    ");
+                    Computer.printf("Tibas\n");
+                }
+                if((CodigoMunicipio[0]=='0')&&(CodigoMunicipio[1]=='3')) {
+                    sprintf(Municipio,"Santa Ana");
+                    Computer.printf("Santa Ana\n");
+                }
+                break;
+            }
+            switch (Line) {
+                case 1:
+                    SelectionLine=109;
+                    break;
+                case 2:
+                    SelectionLine=119;
+                    break;
+            }
+            //-------Mostrar en Patalla-------
+            Screen.Rectangle(SelectionLine,32,9,0);
+            Screen.Rectangle(SelectionLine,50,9,0);
+            Screen.PutString(15,12,"Id Municipalidad");
+            Screen.PutChar(110,34,CodigoMunicipio_Actual[0]);
+            Screen.PutChar(120,34,CodigoMunicipio_Actual[1]);
+            Screen.Limits();
+            Screen.Show();
+            Computer.printf("%s\n",CodigoMunicipio_Actual);
+        }
+    }
+}
+
+void M_Precio(uint32_t TimeOut)
+{
+    char Precio_Actual[5];   //Lectura de valor en memoria
+    if(Precio>999) {
+        sprintf(Precio_Actual,"%i",Precio);
+    }
+    if(Precio<1000) {
+        sprintf(Precio_Actual,"0%i",Precio);
+    }
+    if(Precio<100) {
+        sprintf(Precio_Actual,"00%i",Precio);
+    }
+    if(Precio<10) {
+        sprintf(Precio_Actual,"000%i",Precio);
+    }
+
+    int SelectionLine=99;
+    int Line=1;
+    Inicio=BaseClock.read_ms();
+
+    Screen.Rectangle(SelectionLine,32,9,0);
+    Screen.Rectangle(SelectionLine,50,9,0);
+    Screen.PutString(15,12,"Precio establecido");
+    Screen.PutChar(100,34,Precio_Actual[0]);
+    Screen.PutChar(110,34,Precio_Actual[1]);
+    Screen.PutChar(120,34,Precio_Actual[2]);
+    Screen.PutChar(130,34,Precio_Actual[3]);
+    Screen.PutChar(140,34,'*');
+    Screen.Limits();
+    Screen.Show();
+    Computer.printf("Precio establecido\n");
+    Computer.printf("%s\n",Precio_Actual);
+
+    while(true) {
+        Fin=BaseClock.read_ms();
+        Transcurrido=Fin-Inicio;
+        if(Transcurrido>TimeOut) {
+            break;
+        }
+        Tecla=KeyPad_Read();
+        if (Tecla!=NO_KEY) {                  // Se valida que se ingrese algo en el teclado
+            Inicio=BaseClock.read_ms();
+
+            if ((Tecla=='0')||(Tecla=='1')||(Tecla=='2')||(Tecla=='3')||(Tecla=='4')||(Tecla=='5')||(Tecla=='6')||(Tecla=='7')||(Tecla=='8')||(Tecla=='9')) {                     //Cambiar numero
+                Precio_Actual[Line-1]=Tecla;
+                Line++;
+                if(Line==5) {
+                    Line=1;
+                }
+                if(Line==0) {
+                    Line=4;
+                }
+            }
+            if (Tecla=='E') {                    //Subir puntero
+                Line++;
+                if(Line==5) {
+                    Line=1;
+                }
+            }
+            if (Tecla=='F') {                     //Bajar puntero
+                Line--;
+                if(Line==0) {
+                    Line=4;
+                }
+            }            
+            if (Tecla=='C') {                     //Cancelar Operacion
+                break;
+            }
+            if (Tecla=='B') {                     //Atras en menu
+                break;
+            }          
+            if (Tecla=='D') {                     //En caso de confirmacion
+                Precio=((uint8_t)Precio_Actual[0]-48)*1000+((uint8_t)Precio_Actual[1]-48)*100+((uint8_t)Precio_Actual[2]-48)*10+((uint8_t)Precio_Actual[3]-48);
+                break;
+            }
+            switch (Line) {
+                case 1:
+                    SelectionLine=99;
+                    break;
+                case 2:
+                    SelectionLine=109;
+                    break;
+                case 3:
+                    SelectionLine=119;
+                    break;
+                case 4:
+                    SelectionLine=129;
+                    break;
+            }
+            //-------Mostrar en Patalla-------
+            Screen.Rectangle(SelectionLine,32,9,0);
+            Screen.Rectangle(SelectionLine,50,9,0);
+            Screen.PutString(15,12,"Precio establecido");
+            Screen.PutChar(100,34,Precio_Actual[0]);
+            Screen.PutChar(110,34,Precio_Actual[1]);
+            Screen.PutChar(120,34,Precio_Actual[2]);
+            Screen.PutChar(130,34,Precio_Actual[3]);
+            Screen.PutChar(140,34,'*');
+            Screen.Limits();
+            Screen.Show();
+            Computer.printf("%s\n",Precio_Actual);
+        }
+    }
+}
+
+void M_IntensidadSenal()
+{
+    char Senal[]="000";
+    Slave.Command(COMMAND_SIGNAL);
+    Screen.Rectangle(129,14,5,0);
+    Screen.PutString(15,12,"Intensidad senal");
+    Screen.PutString(15,34,"Conectando...");
+    Screen.Limits();
+    Screen.Show();
+    Computer.printf("Conectando...\n");
+    wait(3);
+
+    Inicio=BaseClock.read_ms();
+    while(true) {
+        if(Slave.Available()) {
+            Computer.putc('A');
+            wait_ms(100);
+            break;
+        }
+        Fin=BaseClock.read_ms();
+        Transcurrido=Fin-Inicio;
+        if(Transcurrido>20000) {
+            Computer.putc('E');
+            break;
+        }
+    }
+    InByte=Slave.Recibe();
+    if(InByte=='A') {
+        Senal[2]=Slave.Recibe();
+        Senal[1]=Slave.Recibe();
+        Senal[0]=Slave.Recibe();
+        Screen.Rectangle(129,14,5,0);
+        Screen.PutString(15,12,"Intensidad senal");
+        Screen.PutString(15,34,"CSQ:");
+        Screen.PutChar(70,34,Senal[0]);
+        Screen.PutChar(80,34,Senal[1]);
+        Screen.PutChar(92,34,'.');
+        Screen.PutChar(96,34,Senal[2]);
+        Screen.Limits();
+        Screen.Show();
+        Computer.printf("CSQ: %s\n",Senal);
+        wait(3);
+    } else {
+        Screen.Rectangle(129,14,5,0);
+        Screen.PutString(15,12,"Intensidad senal");
+        Screen.PutString(15,34,"Error.");
+        Screen.Limits();
+        Screen.Show();
+        Computer.printf("Error\n");
+        wait(3);
+    }
+}
+
+void M_ConexionSim900()
+{
+    Screen.PutString(15,12,"Conexion red");
+    Screen.PutString(15,34,"Conetando...");
+    Screen.Limits();
+    Screen.Show();
+    Computer.printf("Conectando...\n");
+
+    Slave.Command(COMMAND_CONNECT);
+    while(true) {
+        if(Slave.Available()) {
+            wait_ms(200);
+            break;
+        }
+        Fin=BaseClock.read_ms();
+        Transcurrido=Fin-Inicio;
+        if(Transcurrido>20000) {
+            Computer.putc('E');
+            break;
+        }
+    }
+    InByte=Slave.Recibe();
+    if(InByte=='A') {
+        Screen.PutString(15,12,"Conexion red");
+        Screen.PutString(15,34,"Conectado.");
+        Screen.Limits();
+        Screen.Show();
+        wait(3);
+    } else {
+        Screen.PutString(15,12,"Conexion red");
+        Screen.PutString(15,34,"Error.");
+        Screen.Limits();
+        Screen.Show();
+        wait(3);
+    }
+}
+
+void M_PruebaTiquete()
+{
+    Screen.PutString(15,12,"Tiquete de prueba");
+    Screen.PutString(15,34,"Conectando...");
+    Screen.Limits();
+    Screen.Show();
+    wait(1);
+    Computer.printf("Conectando...\n");
+
+    Impresora.Power(1);
+    wait_ms(1000);
+    Comando=Impresora.Reset();
+
+    if(Comando==2) {
+        Screen.PutString(15,12,"Tiquete de prueba");
+        Screen.PutString(15,34,"Error.");
+        Screen.Limits();
+        Screen.Show();
+        Computer.printf("Error\n");
+
+        Impresora.End();
+        ParkingMeter.AlarmCall(2,'E');
+        wait(3);
+    }
+    if(Comando==1) {
+        Screen.PutString(15,12,"Tiquete de prueba");
+        Screen.PutString(15,34,"Imprimiendo...");
+        Screen.Limits();
+        Screen.Show();
+        Computer.printf("Imprimiendo...\n");
+
+        Comando=Impresora.Output(FechaRespuesta,"00:00","00:00","0000","00:00","000000","0000*");
+        if(Comando==0) {
+            Computer.printf("Alarma Output\n");
+            ParkingMeter.AlarmCall(2,'E');
+        } else {
+            ParkingMeter.AlarmCall(2,'A');
+        }
+
+        Comando=Impresora.Paper(600);
+        if(Comando==0) {
+            Computer.printf("Alarma Papel\n");
+            ParkingMeter.AlarmCall(2,'E');
+        } else {
+            ParkingMeter.AlarmCall(2,'A');
+        }
+
+        Comando=Impresora.Cutter(1);
+        if(Comando==0) {
+            Computer.printf("Alarma Cutter\n");
+            ParkingMeter.AlarmCall(2,'E');
+        } else {
+            ParkingMeter.AlarmCall(2,'A');
+        }
+
+        Screen.PutString(15,12,"Tiquete de prueba");
+        Screen.PutString(15,34,"Retire.");
+        Screen.Limits();
+        Screen.Show();
+        Computer.printf("Retire\n");
+        wait(1);
+        Comando=Impresora.End();
+        wait(2);
+    }
+    if(Comando==0) {
+        Screen.PutString(15,12,"Tiquete de prueba");
+        Screen.PutString(15,34,"Error.");
+        Screen.Limits();
+        Screen.Show();
+        Computer.printf("Error\n");
+        Comando=Impresora.End();
+        ParkingMeter.AlarmCall(2,'E');
+        wait(3);
+    }
+    Impresora.Power(0);
+
+    int TiquetesDisponibles=Papel-Impresora.Ticket(1);
+    if(TiquetesDisponibles<200) {
+        sprintf(PapelDisponible,"%i",TiquetesDisponibles);
+        ParkingMeter.AlarmCall(3,'E');
+    } else {
+        sprintf(PapelDisponible,"%i",TiquetesDisponibles);
+        ParkingMeter.AlarmCall(3,'A');
+    }
+}
+
+void M_ConexionImpresora()
+{
+    Screen.PutString(15,12,"Conexion impresora");
+    Screen.PutString(15,34,"Conectando...");
+    Screen.Limits();
+    Screen.Show();
+    Computer.printf("Conectando...\n");
+
+    Impresora.Power(1);
+    wait_ms(1000);
+    Comando=Impresora.Reset();
+
+    if(Comando==2) {
+        Screen.PutString(15,12,"Conexion impresora");
+        Screen.PutString(15,34,"Desconectada.");
+        Screen.Limits();
+        Screen.Show();
+        Computer.printf("Desconectada\n");
+        Impresora.End();
+        ParkingMeter.AlarmCall(2,'E');
+        wait(3);
+    }
+    if(Comando==1) {
+        Screen.PutString(15,12,"Conexion impresora");
+        Screen.PutString(15,34,"Conectada.");
+        Screen.Limits();
+        Screen.Show();
+        Computer.printf("Conectada\n");
+        Comando=Impresora.End();
+        ParkingMeter.AlarmCall(2,'A');
+        wait(3);
+    }
+    if(Comando==0) {
+        Screen.PutString(15,12,"Conexion impresora");
+        Screen.PutString(15,34,"Conectada error.");
+        Screen.Limits();
+        Screen.Show();
+        Computer.printf("Error\n");
+        Comando=Impresora.End();
+        ParkingMeter.AlarmCall(2,'E');
+        wait(3);
+    }
+    Impresora.Power(0);
+}
+
+void M_CambioPapel(uint32_t TimeOut)
+{
+    char Papel_Actual[5];   //Lectura de valor en memoria
+    if(Papel>999) {
+        sprintf(Papel_Actual,"%i",Papel);
+    }
+    if(Papel<1000) {
+        sprintf(Papel_Actual,"0%i",Papel);
+    }
+    if(Papel<100) {
+        sprintf(Papel_Actual,"00%i",Papel);
+    }
+    if(Papel<10) {
+        sprintf(Papel_Actual,"000%i",Papel);
+    }
+
+    int SelectionLine= 99;
+    int Line=1;
+
+    Inicio=BaseClock.read_ms();
+
+    Screen.Rectangle(SelectionLine,32,9,0);
+    Screen.Rectangle(SelectionLine,50,9,0);
+    Screen.PutString(15,12,"Cambio de papel");
+    Screen.PutChar(100,34,Papel_Actual[0]);
+    Screen.PutChar(110,34,Papel_Actual[1]);
+    Screen.PutChar(120,34,Papel_Actual[2]);
+    Screen.PutChar(130,34,Papel_Actual[3]);
+    Screen.Limits();
+    Screen.Show();
+    Computer.printf("Cambio de papel\n");
+    Computer.printf("%s\n",Papel_Actual);
+
+    while(true) {
+        Fin=BaseClock.read_ms();
+        Transcurrido=Fin-Inicio;
+        if(Transcurrido>TimeOut) {
+            break;
+        }
+        Tecla=KeyPad_Read();
+        if (Tecla!=NO_KEY) {                  // Se valida que se ingrese algo en el teclado
+            Inicio=BaseClock.read_ms();
+            if ((Tecla=='0')||(Tecla=='1')||(Tecla=='2')||(Tecla=='3')||(Tecla=='4')||(Tecla=='5')||(Tecla=='6')||(Tecla=='7')||(Tecla=='8')||(Tecla=='9')) {                     //Cambiar numero
+                Papel_Actual[Line-1]=Tecla;
+                Line++;
+                if(Line==5) {
+                    Line=1;
+                }
+                if(Line==0) {
+                    Line=4;
+                }
+            }
+            if (Tecla=='E') {                    //Subir puntero
+                Line++;
+                if(Line==5) {
+                    Line=1;
+                }
+            }
+            if (Tecla=='F') {                     //Bajar puntero
+                Line--;
+                if(Line==0) {
+                    Line=4;
+                }
+            }             
+            if (Tecla=='C') {                     //Cancelar Operacion
+                break;
+            }
+            if (Tecla=='B') {                //Atras en menu
+                break;
+            }         
+            if (Tecla=='D') {                 //En caso de confirmacion
+                Papel=((uint8_t)Papel_Actual[0]-48)*1000+((uint8_t)Papel_Actual[1]-48)*100+((uint8_t)Papel_Actual[2]-48)*10+((uint8_t)Papel_Actual[3]-48);
+                int TiquetesDisponibles=Papel-Impresora.Ticket(1);
+                if(TiquetesDisponibles<200) {
+                    sprintf(PapelDisponible,"%i",TiquetesDisponibles);
+                    ParkingMeter.AlarmCall(3,'E');
+                } else {
+                    sprintf(PapelDisponible,"%i",TiquetesDisponibles);
+                    ParkingMeter.AlarmCall(3,'A');
+                }
+                break;
+            }
+            switch (Line) {
+                case 1:
+                    SelectionLine=99;
+                    break;
+                case 2:
+                    SelectionLine=109;
+                    break;
+                case 3:
+                    SelectionLine=119;
+                    break;
+                case 4:
+                    SelectionLine=129;
+                    break;
+            }
+            //-------Mostrar en Patalla-------
+            Screen.Rectangle(SelectionLine,32,9,0);
+            Screen.Rectangle(SelectionLine,50,9,0);
+            Screen.PutString(15,12,"Cambio de papel");
+            Screen.PutChar(100,34,Papel_Actual[0]);
+            Screen.PutChar(110,34,Papel_Actual[1]);
+            Screen.PutChar(120,34,Papel_Actual[2]);
+            Screen.PutChar(130,34,Papel_Actual[3]);
+            Screen.Limits();
+            Screen.Show();
+            Computer.printf("%s\n",Papel_Actual);
+        }
+    }
+}
+void M_PruebaTeclado(uint32_t TimeOut)
+{
+    bool Numero;
+    int  Line=0;
+    char Secuencia[16]= {'1','2','3','A','4','5','6','B','7','8','9','C','F','0','E','D'};
+    char SecuenciaSelect[2];
+    SecuenciaSelect[0]='1';
+    SecuenciaSelect[1]='\0';
+    Inicio=BaseClock.read_ms();
+
+    Screen.Limits();
+    Screen.PutString(15,12,"Prueba de teclado");
+    Screen.PutString(15,34,">    <");
+    Screen.PutString(33,34,SecuenciaSelect);
+    Screen.Show();
+    Computer.putc(SecuenciaSelect[0]);
+
+    while(true) {
+        Fin=BaseClock.read_ms();
+        Transcurrido=Fin-Inicio;
+        if(Transcurrido>TimeOut) {
+            Screen.Limits();
+            Screen.PutString(15,12,"Prueba de teclado");
+            Screen.PutString(15,34,"Error.");
+            Screen.Show();
+            Computer.printf("\nError\n");
+            wait(2);
+            break;
+        }
+        Tecla = KeyPad_Read();
+        if (Tecla!=NO_KEY) {                  // Se valida que se ingrese algo en el teclado
+            Inicio=BaseClock.read_ms();
+
+            Numero=(Tecla==Secuencia[Line]);
+            if (Numero) {                     //Cambiar numero
+                Line++;
+                SecuenciaSelect[0]=Secuencia[Line];
+            }
+
+            if (Line>15) {                     //Cambiar numero
+                Screen.Limits();
+                Screen.PutString(15,12,"Prueba de teclado");
+                Screen.PutString(15,34,"Aprobada.");
+                Screen.Show();
+                Computer.printf("\nAprobada\n");
+                wait(3);
+                break;
+            }
+
+            Screen.Limits();
+            Screen.PutString(15,12,"Prueba de teclado");
+            Screen.PutString(15,34,">    <");
+            Screen.PutString(33,34,SecuenciaSelect);
+            Screen.Show();
+            Computer.putc(SecuenciaSelect[0]);
+        }
+    }
+
+}
+int M_RetiroTarjeta(uint32_t TiempoFuera)
+{
+    Computer.printf("Retiro tarjeta\n");
+    Inicio=BaseClock.read_ms();
+    while(true) {
+        if(PositionCard()==0) {
+            return 1;
+        } else {
+            Screen.Limits();                 // Se pide al usuario por pantalla el retiro de la tarjeta
+            Screen.PutString(15,12,"Prueba de lectura");
+            Screen.PutString(15,34,"Retire tarjeta.");
+            Screen.Show();
+        }
+        Fin=BaseClock.read_ms();
+        Transcurrido=Fin-Inicio;
+        if(Transcurrido>TiempoFuera) {
+            StateReader[1]='T';
+            return 0;
+        }
+    }
+}
+
+void M_PruebaLectora()
+{
+    Impresora.PowerMax(1);
+    CardReaderPower=1;
+    Screen.PutString(15,12,"Prueba de lectura");
+    Screen.PutString(15,34,"Conectando...");
+    Screen.Limits();                     // Se inicia el lector de tarjetas
+    Screen.Show();
+    wait(2);
+
+
+    if(ResetCard()==1) {
+        
+        Screen.Limits();                     // Se pide al usuario por pantalla la intrduccion de la tarjeta
+        Screen.PutString(15,12,"Prueba de lectura");
+        Screen.PutString(15,34,"Introduzca tarjeta.");
+        Screen.Show();
+        
+        while(true) {
+
+            uint8_t RespuestaIngresoTarjeta = IngresoTarjeta(10000);
+            if(RespuestaIngresoTarjeta==1) {
+                Screen.Limits();
+                Screen.PutString(15,12,"Prueba de lectura");
+                Screen.PutString(15,34,"Retire tarjeta.");
+                Screen.Show();
+            }
+            if(RespuestaIngresoTarjeta==0) {
+                Screen.PutString(15,12,"Prueba de lectura");
+                Screen.PutString(15,34,"Sin deteccion.");
+                Screen.Limits();
+                Screen.Show();
+                wait(3);
+                Screen.Clean();
+                break;
+            }
+            if(RespuestaIngresoTarjeta==2) {
+                Screen.PutString(15,12,"Prueba de lectura");
+                Screen.PutString(15,34,"Error.");
+                Screen.Limits();
+                Screen.Show();
+                wait(3);
+                break;
+            }
+
+            uint8_t RespuestaReadCard=ReadCard(5000);
+            if(RespuestaReadCard==2) {
+                Screen.PutString(15,12,"Prueba de lectura");
+                Screen.PutString(15,34,"Error.");
+                Screen.Limits();
+                Screen.Show();
+                wait(3);
+                break;
+            }
+
+
+            // Se le la tarjeta al retirarse
+            int DataResult=RecibeDataCard();    // Se corrobora que la informacion de la tajeta es la corre
+            if(DataResult==0) {
+                Screen.PutString(15,12,"Prueba de lectura");
+                Screen.PutString(15,34,"ilegible.");
+                Screen.Limits();
+                Screen.Show();
+                wait(2);
+                if(M_RetiroTarjeta(7000)) {
+                    Screen.Limits();
+                    Screen.PutString(15,12,"Prueba de lectura");
+                    Screen.PutString(15,34,"Introduzca tarjeta.");
+                    Screen.Show();
+                } else {
+                    Screen.PutString(15,12,"Prueba de lectura");
+                    Screen.PutString(15,34,"Error.");
+                    Screen.Limits();
+                    Screen.Show();
+                    wait(3);
+                    break;
+                }
+            }
+            if(DataResult==1) {
+                Screen.PutString(15,12,"Prueba de lectura");
+                Screen.PutString(15,34,"Aprobada.");
+                Screen.Limits();
+                Screen.Show();
+                Computer.printf("\nAprobada\n");
+                wait(3);
+                break;
+            }
+            if(DataResult==2) {
+                Screen.PutString(15,12,"Prueba de lectura");
+                Screen.PutString(15,34,"ilegible.");
+                Screen.Limits();
+                Screen.Show();
+                wait(2);
+                if(M_RetiroTarjeta(7000)) {
+                    Screen.Limits();
+                    Screen.PutString(15,12,"Prueba de lectura");
+                    Screen.PutString(15,34,"Introduzca tarjeta.");
+                    Screen.Show();
+                } else {
+                    Screen.PutString(15,12,"Prueba de lectura");
+                    Screen.PutString(15,34,"Error.");
+                    Screen.Limits();
+                    Screen.Show();
+                    wait(3);
+                    break;
+                }
+            }
+        }
+    } else {
+        Screen.PutString(15,12,"Prueba de lectura");
+        Screen.PutString(15,34,"Error.");
+        Screen.Limits();
+        Screen.Show();
+        wait(3);
+    }
+    CardReaderPower=0;  
+    Impresora.PowerMax(0);  
+}
+
+void M_ConexionLectora()
+{
+    Impresora.PowerMax(1);
+    CardReaderPower=1;
+    Screen.Limits();
+    Screen.PutString(15,12,"Conexion lectora");
+    Screen.PutString(15,34,"Conectando...");
+    Screen.Show();
+    Computer.printf("Conectando...\n");
+    wait(2);
+    int RespuestaConexion=ResetCard();
+
+    if(RespuestaConexion==2) {
+        Screen.Limits();
+        Screen.PutString(15,12,"Conexion lectora");
+        Screen.PutString(15,34,"Desconectada.");
+        Screen.Show();
+        Computer.printf("Desconectada\n");
+        wait(3);
+    }
+    if(RespuestaConexion==1) {
+        Screen.Limits();
+        Screen.PutString(15,12,"Conexion lectora");
+        Screen.PutString(15,34,"Conectada.");
+        Screen.Show();
+        Computer.printf("Conectada\n");
+        wait(3);
+    }
+    if(RespuestaConexion==0) {
+        Screen.Limits();
+        Screen.PutString(15,12,"Conexion lectora");
+        Screen.PutString(15,34,"Conectada error.");
+        Screen.Show();
+        Computer.printf("Conectada error\n");
+        wait(3);
+    }
+    CardReaderPower=0;
+    Impresora.PowerMax(0);
+}
+
+void M_Informacion()
+{
+    int TiquetesDisponibles=Papel-Impresora.Ticket(1);
+    if(TiquetesDisponibles<200) {
+        sprintf(PapelDisponible,"%i",TiquetesDisponibles);
+        ParkingMeter.AlarmCall(3,'E');
+    } else {
+        sprintf(PapelDisponible,"%i",TiquetesDisponibles);
+        ParkingMeter.AlarmCall(3,'A');
+    }
+    
+    char Alarmas[7]="AAAAAA";
+    Alarmas[0]=ParkingMeter.AlarmReader();
+    Alarmas[1]=ParkingMeter.AlarmPrinter();
+    Alarmas[2]=ParkingMeter.AlarmPaper();
+    Alarmas[3]=ParkingMeter.AlarmDoor1();
+    Alarmas[4]=ParkingMeter.AlarmDoor2();
+    Alarmas[5]=ParkingMeter.AlarmBattery();
+
+    Screen.PutString(15,4,"Transaccion:");
+    Screen.PutString(129,4,FechaRespuesta);
+    Screen.PutString(15,23,"Papel:");
+    Screen.PutString(129,23,PapelDisponible);
+    Screen.PutString(15,42,"Estado:");
+    Screen.PutString(129,42,Alarmas);
+    Screen.Limits();
+    Screen.Show();
+    wait(5);
+}
+
+
+uint8_t ImprimirHosting()
+{
+    int PrinterState;
+    wait(2);
+    PrinterState = Impresora.Power(1);
+    if(PrinterState){
+        PrinterState=Impresora.Reset();
+    }
+
+    if(PrinterState==0) {
+        wait(2);
+        Computer.printf("Error.\n");
+        Impresora.End();
+        wait(4);
+    }
+    if(PrinterState==2) {
+        wait(2);
+        Computer.printf("Error.\n");
+        Impresora.End();
+        wait(4);
+    }
+    if(PrinterState==1) {        
+        PrinterState=Impresora.Output(FechaRespuesta,"00:00",HoraRespuesta,"0000","00:00","000000","0000*");
+        if(PrinterState==0) {
+            Computer.printf("Alarma Output\n");
+            return 0;
+        } 
+        PrinterState=Impresora.Paper(250);
+        if(PrinterState==0) {
+            Computer.printf("Alarma Papel\n");
+            return 0;
+        }
+
+        PrinterState=Impresora.Cutter(1);
+        if(PrinterState==0) {
+            Computer.printf("Alarma Cutter\n");
+            return 0;
+        }
+        wait(1);        
+        PrinterState=Impresora.End();
+        wait(1);       
+    }
+
+    PrinterState=Impresora.Power(0);
+    return 1;
+}
+
+//------------------------------------------------------------------------------------------------------------------------------------------------------
+void Interrupt_Host()
+{
+    ParkingMeter.Hosting();    
+    Screen.Light();     
+    
+    if(Doors.Read()>0) {
+        Computer.printf("Alarma puertas\n");
+        ParkingMeter.AlarmCall((3+Doors.Read()),'E');
+    } else {
+        ParkingMeter.AlarmCall(4,'A');
+        ParkingMeter.AlarmCall(5,'A');
+    }
+    
+    if(Charger.Control()>0){
+        ParkingMeter.AlarmCall(6,'A');
+        Computer.printf("Bateria ok\n");
+        Computer.printf("B:%.2f  P:%.2f\n",Charger.BatteryRead(),Charger.PanelRead());  
+    } else {
+        ParkingMeter.AlarmCall(6,'E');
+        Computer.printf("Bateria baja\n");   
+    }
+}
+
+void H_EnviarPaso(uint8_t Entrada_Comando)
+{   
+    switch (Entrada_Comando) {
+        case 1:
+            Slave.Command(HOSTING_STEP1);
+            Progreso[0]=' ';
+            Progreso[1]='1';
+            Progreso[2]='0';
+            break;
+        case 2:
+            Slave.Command(HOSTING_STEP2);
+            Progreso[0]=' ';
+            Progreso[1]='2';
+            Progreso[2]='0';
+            break;
+        case 3:
+            Slave.Command(HOSTING_STEP3);
+            Progreso[0]=' ';
+            Progreso[1]='3';
+            Progreso[2]='0';
+            break;
+        case 4:
+            Slave.Command(HOSTING_STEP4);
+            Progreso[0]=' ';
+            Progreso[1]='4';
+            Progreso[2]='0';
+            break;
+        case 5:
+            Slave.Command(HOSTING_STEP5);
+            Progreso[0]=' ';
+            Progreso[1]='5';
+            Progreso[2]='0';
+            break;
+        case 6:
+            Slave.Command(HOSTING_STEP6);
+            Progreso[0]=' ';
+            Progreso[1]='6';
+            Progreso[2]='0';
+            break;
+        case 7:
+            Slave.Command(HOSTING_STEP7);
+            Progreso[0]=' ';
+            Progreso[1]='7';
+            Progreso[2]='0';
+            break;
+        case 8:             
+            Alarmas[0]=ParkingMeter.AlarmReader();
+            Alarmas[1]=ParkingMeter.AlarmPrinter();
+            Alarmas[2]=ParkingMeter.AlarmPaper();
+            Alarmas[3]=ParkingMeter.AlarmDoor1();
+            Alarmas[4]=ParkingMeter.AlarmDoor2();
+            Alarmas[5]=ParkingMeter.AlarmBattery();
+            Slave.Command(HOSTING_STEP8);
+            Slave.Send_Hosting(Parquimetro,Municipio,Alarmas);
+            Computer.printf("Parquimetro: %s\n",Parquimetro);
+            Computer.printf("Municipio: %s\n",Municipio);
+            Computer.printf("Alarmas: %s\n",Alarmas);
+            Progreso[0]=' ';
+            Progreso[1]='8';
+            Progreso[2]='0';
+            break;
+        case 9:
+            Slave.Command(HOSTING_STEP9);
+            Progreso[0]=' ';
+            Progreso[1]='9';
+            Progreso[2]='0';
+            break;
+        case 10:
+            Slave.Command(HOSTING_STEP10);
+            Progreso[0]='1';
+            Progreso[1]='0';
+            Progreso[2]='0';
+            break;
+        case 11:
+            Slave.Command(HOSTING_STEP11);
+            Progreso[0]='1';
+            Progreso[1]='0';
+            Progreso[2]='0';
+            break;
+    }
+}
+
+void Hosting()
+{
+    Host.detach();
+    ParkingMeter.LedHosting(1);
+    uint8_t PasoHostingNum=1;
+    H_EnviarPaso(PasoHostingNum);
+    Computer.printf("Hosting iniciando\n");
+    Computer.printf("Paso %i\n", PasoHostingNum);
+    Inicio=BaseClock.read_ms();
+    BaseClock.start();
+    while(true) {
+        if(PasoHostingNum>10) {
+            Computer.printf("Paso final\n");
+            Inicio=BaseClock.read_ms();
+            while(true) {
+                if(Slave.Message()) {
+                    wait_ms(75);
+                    break;
+                }
+                Fin=BaseClock.read_ms();
+                Transcurrido=Fin-Inicio;//49
+                if(Transcurrido>10000) {
+                    break;
+                }
+            }
+            char HostingRespuesta[7];
+            HoraRespuesta[4]=Slave.Recibe();
+            HoraRespuesta[3]=Slave.Recibe();
+            HoraRespuesta[2]=Slave.Recibe();
+            HoraRespuesta[1]=Slave.Recibe();
+            HoraRespuesta[0]=Slave.Recibe();
+            HoraRespuesta[5]=Slave.Recibe();
+            HoraRespuesta[5]='\0';
+            HostingRespuesta[5]=Slave.Recibe();
+            HostingRespuesta[4]=Slave.Recibe();
+            HostingRespuesta[3]=Slave.Recibe();
+            HostingRespuesta[2]=Slave.Recibe();
+            HostingRespuesta[1]=Slave.Recibe();
+            HostingRespuesta[0]=Slave.Recibe();
+                   
+            Computer.printf("Respuesta: %s\n",HostingRespuesta);
+            Computer.printf("Hora:%s\n",HoraRespuesta);
+            if(HoraRespuesta[2]==':'){
+                Screen.LightSet(HoraRespuesta);
+            }    
+            if((HostingRespuesta[0]=='O')&&(HostingRespuesta[1]=='K')&&(HostingRespuesta[2]=='+')){
+                 Precio = ((uint8_t)HostingRespuesta[3]-48)*100 +((uint8_t)HostingRespuesta[4]-48)*10 +((uint8_t)HostingRespuesta[5]-48);    
+                 Computer.printf("Precio: %i\n",Precio) ;     
+            }
+            //ParkingMeter.Max232(1);
+            //ImprimirHosting();
+            //ParkingMeter.Max232(0);
+            Inicio=BaseClock.read_ms();
+            while(true) {
+                if(Slave.Answer()) {
+                    wait_ms(50);
+                    break;
+                }
+                Fin=BaseClock.read_ms();
+                Transcurrido=Fin-Inicio;//49
+                if(Transcurrido>15000) {
+                    break;
+                }
+            }
+            if((HostingRespuesta[0]=='O')&&(HostingRespuesta[1]=='K')) {
+                Computer.printf("Alarmas aprobada\n");
+                ParkingMeter.HostingOk();
+                break;
+            } else {
+                Computer.printf("Alarmas fallo\n");
+                break;
+            }
+        }
+        
+        Tecla=KeyPad_Read();
+        if(Tecla!=NO_KEY) {
+            Screen.On();
+            wait_ms(20);
+            Screen.Init();
+            if(PasoHostingNum==1) {
+                Computer.printf("Teclado encender Paso==1\n");
+                Usuario(USER_INIT);
+                break;
+            }            
+            if(PasoHostingNum<3) {
+                Computer.printf("Teclado Paso<3\n");
+                Usuario(USER_INIT2);
+                break;
+            }
+            if(PasoHostingNum<6) {
+                Computer.printf("Teclado Paso<6\n");
+                Usuario(USER_INIT3);
+                break;
+            }
+            if(PasoHostingNum==6) {
+                Computer.printf("Teclado Paso==6\n");
+                Usuario(USER_INIT4);
+                break;
+            }
+            if(PasoHostingNum<=8) {
+                Computer.printf("Teclado Paso<=8\n");
+                Usuario(USER_INIT5);
+                break;
+            }
+            if(PasoHostingNum<=10) {
+                Computer.printf("Teclado Paso<=10\n");
+                Usuario(USER_INIT5);
+                break;
+            }
+            if(PasoHostingNum<=11) {
+                Computer.printf("Teclado Paso<=11\n");
+                PantallaInicio();
+                Usuario(USER_INIT5);
+            }
+        }
+        
+        if (Slave.Answer()) {
+            PasoHostingNum++;
+            Computer.printf("Paso %i\n", PasoHostingNum);
+            H_EnviarPaso(PasoHostingNum);
+            Inicio=BaseClock.read_ms();
+        }
+        Fin=BaseClock.read_ms();
+        Transcurrido=Fin-Inicio;//49
+        if(Transcurrido>10000) {
+            Computer.printf("Hosting tiempo\n");
+            break;
+        }
+    }
+    Slave.Command(COMMAND_OFF);
+    EsperarSim900(5000);
+    ParkingMeter.LedHosting(0);
+    Host.attach(&Interrupt_Host,5);//1800 30 minutos
+}
+
+void M_PruebaHosting()
+{
+    int Paso=1;
+    int PasoSiguiente=1;
+
+    while(true) {
+        if (Paso==PasoSiguiente) {
+            Computer.printf("Paso %i\n",Paso);
+            H_EnviarPaso(Paso);
+            Paso=Paso+1;
+            if(Paso>11) {
+                Computer.printf("Paso %i final\n",Paso);
+                Inicio=BaseClock.read_ms();
+                while(true) {
+                    if(Slave.Message()) {
+                        wait_ms(75);
+                        break;
+                    }
+                    Fin=BaseClock.read_ms();
+                    Transcurrido=Fin-Inicio;//49
+                    if(Transcurrido>10000) {
+                        break;
+                    }
+                }
+                
+                char HostingRespuesta[7];
+                HoraRespuesta[5]=Slave.Recibe();
+                HoraRespuesta[4]=Slave.Recibe();
+                HoraRespuesta[3]=Slave.Recibe();
+                HoraRespuesta[2]=Slave.Recibe();
+                HoraRespuesta[1]=Slave.Recibe();
+                HoraRespuesta[0]=Slave.Recibe();
+                HostingRespuesta[5]=Slave.Recibe();
+                HostingRespuesta[4]=Slave.Recibe();
+                HostingRespuesta[3]=Slave.Recibe();
+                HostingRespuesta[2]=Slave.Recibe();
+                HostingRespuesta[1]=Slave.Recibe();
+                HostingRespuesta[0]=Slave.Recibe();
+                
+                Computer.printf("Respuesta: %s\n",HostingRespuesta);
+                Computer.printf("Hora: %s\n",HoraRespuesta); 
+                Inicio=BaseClock.read_ms();
+                while(true) {
+                    if(Slave.Answer()) {
+                        wait_ms(50);
+                        break;
+                    }
+                    Fin=BaseClock.read_ms();
+                    Transcurrido=Fin-Inicio;//49
+                    if(Transcurrido>10000) {
+                        break;
+                    }
+                }
+                if((HostingRespuesta[0]=='O')&&(HostingRespuesta[1]=='K')) {
+                    Computer.printf("Alarmas aprobada\n");
+                    Screen.PutString(15,12,"Prueba hosting");
+                    Screen.PutString(15,34,"Aprobada.");
+                    Screen.Limits();
+                    Screen.Show();
+                    wait_ms(2000);
+                    ParkingMeter.HostingOk();
+                    break;
+                } else {
+                    Computer.printf("Alarmas fallo\n");
+                    Screen.PutString(15,12,"Prueba hosting");
+                    Screen.PutString(15,34,"Error.");
+                    Screen.Limits();
+                    Screen.Show();
+                    wait_ms(2000);
+                    break;
+                }
+            }
+            Screen.PutString(15,12,"Prueba hosting");
+            Screen.PutString(15,34,"Progreso:");
+            Screen.PutChar(105,34,Progreso[0]);
+            Screen.PutChar(115,34,Progreso[1]);
+            Screen.PutChar(125,34,Progreso[2]);
+            Screen.PutChar(135,34,'%');
+            Screen.Limits();
+            Screen.Show();
+        }
+        if (Slave.Answer()) {
+            PasoSiguiente=PasoSiguiente+1;
+            Computer.printf("Next\n");
+        }
+    }
+}
+
+void Mantenimiento()
+{
+    ParkingMeter.Max232(1);
+    Impresora.PowerMax(1);
+    ParkingMeter.LedMantenimiento(1);    
+    Screen.On();
+    Screen.Init();
+    BaseClock.start();
+    M_PantallaConfiguracion();
+    bool ClaveAceptada=M_ClaveIngreso(5000);
+    while(ClaveAceptada) {
+        Comando=M_MenuConfiguracion(30000);
+        switch(Comando) {
+            case M_SISTEMA:
+                Computer.printf("--> Sistema\n");
+                Comando=M_MenuSistema(30000);
+                if(Comando==M_PARQUIMETRO) {
+                    Computer.printf("--> Id parquimetro\n");
+                    M_Parquimetro(30000);
+                }
+                if(Comando==M_MUNICIPIO) {
+                    Computer.printf("--> Id municipalidad\n");
+                    M_Municipio(30000);
+                }
+                if(Comando==M_PRECIO) {
+                    Computer.printf("--> Precio 10mins\n");
+                    M_Precio(30000);
+                }
+                break;
+
+            case M_RED:
+                Computer.printf("--> Red\n");
+                Comando=M_MenuConexion(30000);
+                if(Comando==M_SENAL) {
+                    Computer.printf("--> Intensidad senal\n");
+                    M_IntensidadSenal();
+                }
+                if(Comando==M_HOSTING) {
+                    Computer.printf("--> Prueba hosting\n");
+                    M_PruebaHosting();
+                }
+                if(Comando==M_CONEXION_SIM) {
+                    Computer.printf("--> Conexion modulo\n");
+                    M_ConexionSim900();
+                }
+                break;
+
+            case M_IMPRESORA:
+                Computer.printf("--> Impresora\n");
+                Comando=M_MenuImpresora(30000);
+                if(Comando==M_PAPEL) {
+                    Computer.printf("--> Cambio de papel\n");
+                    M_CambioPapel(30000);
+                }
+                if(Comando==M_IMPRESION) {
+                    Computer.printf("--> Tiquete de prueba\n");
+                    M_PruebaTiquete();
+                }
+                if(Comando==M_CONEXION_IMP) {
+                    Computer.printf("--> Conexion impresora\n");
+                    M_ConexionImpresora();
+                }
+                break;
+
+            case M_TECLADO:
+                Computer.printf("--> Teclado\n");
+                Comando=M_MenuTeclado(30000);
+                if(Comando==M_PRUEBA_TECLA) {
+                    Computer.printf("--> Prueba de teclado\n");
+                    M_PruebaTeclado(2000);
+                }
+                break;
+
+            case M_LECTORA:
+                Computer.printf("--> Lectora\n");
+                Comando=M_MenuLectora(30000);
+                if(Comando==M_LECTURA) {
+                    Computer.printf("--> Prueba de lectura\n");
+                    M_PruebaLectora();
+                }
+                if(Comando==M_CONEXION_LEC) {
+                    Computer.printf("--> Conexion lectora\n");
+                    M_ConexionLectora();
+                }
+                break;
+
+            case M_INFORMACION:
+                Comando=M_MenuInformacion();
+                if(Comando==M_INFORMACION) {
+                    Computer.printf("--> Informacion\n");
+                    M_Informacion();
+                }
+                break;
+
+            default:
+                Comando=M_OFF;
+        }
+
+        if(Comando==M_OFF) {
+            Computer.printf("Cerrando modo configuracion\n");
+            break;
+        }
+    }
+    MantenimientoInterruption=0;
+    ParkingMeter.LedMantenimiento(0);
+    ParkingMeter.Max232(0);
+    Impresora.PowerMax(0);
+    BaseClock.stop();
+    Screen.Clean();
+    Screen.Off();
+}
+
+void InitSistema(){
+    Regulator5V=1;
+    wait_ms(50);
+    Screen.On();
+    Screen.Init();
+    Screen.Clean();
+    Keypad_C1.rise(&KeyPad_InterruptDisable);
+    Keypad_C2.rise(&KeyPad_InterruptDisable);
+    Keypad_C3.rise(&KeyPad_InterruptDisable);
+    Keypad_C4.rise(&KeyPad_InterruptDisable);
+    Configuracion.rise(&Interrupt_Mantenimiento);
+    CardReader.attach(&Interrupt_CardReader);
+    Host.attach(&Interrupt_Host,5);//1800 30 minutos
+    Computer.printf("Prototipo Completo 4\n");
+    Screen.Off(); 
+    Regulator5V=0;   
+}
+
+int main()
+{
+    InitSistema(); 
+    while(1) {
+        KeyPad_InterruptEnable();
+        Doors.InterruptEnable();
+        
+        hal_sleep();
+        
+        if(KeyPad_Read() != NO_KEY) {
+            Regulator5V=1;
+            wait_ms(50);
+            ParkingMeter.LedUsuario(1); 
+            Usuario(USER_INIT); 
+            EsperarSim900(5000);
+            Host.attach(&Interrupt_Host,5);
+            ParkingMeter.LedUsuario(0);    
+            Regulator5V=0;    
+        }
+        if(MantenimientoInterruption) {     
+            Regulator5V=1;
+            wait_ms(50);       
+            Mantenimiento();
+            Regulator5V=0;
+        }             
+        if(ParkingMeter.AlarmState()) {
+            Regulator5V=1;
+            wait_ms(50);
+            Hosting();
+            Regulator5V=0;
+        }
+    }
+}