Kilian Polkov / Mbed 2 deprecated TP1_LAVADORA

Dependencies:   mbed

Fork of TP1_LAVADORA by Sistemas Embebidos

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /* BOTON ARRIBA: 2do izquierda, BOTON ABAJO: 3ero izquierda, BOTON OK/STOP: 1ero derecha*/
00002 
00003 /* consola */
00004 /* pc.printf("TEMP: %d\n", temperaturaActual);
00005    pc.printf("TIME: %d\n", tiempoActual);
00006    pc.printf("MOTOR: %d\n", MOTOR_estado);
00007 */
00008 
00009 #include "mbed.h"
00010 #include <string.h>
00011 
00012 /* -----definiciones----- */
00013 #define DATA                1   // para mandar caracter al display LCD
00014 #define CMND                0   // para configurar registro al display LCD
00015 #define APRETADO            0   // para indicar el apretado del pulsador
00016 #define NO_APRETADO         1   // para indicar el no apretado del pulsador
00017 
00018 /* -----enumeraciones----- */
00019 enum{MENU_MODO, MENU_TEMPERATURA, MENU_CENTRIFUGADO, MENU_TIEMPO, MENU_ENJUAGUE, MENU_LAVADO, CONFIG_MODO, CONFIG_TEMPERATURA, CONFIG_CENTRIFUGADO, CONFIG_TIEMPO, CONFIG_ENJUAGUE, LAVANDO, PAUSADO}; // SELECTOR_Step
00020 enum{OFF, ENJUAGADO, ENJABONADO, SUAVIZADO, DESAGOTE, CENTRIFUGADO};                                                                                        // LAVADO_Step
00021 enum{ALGODON, SINTETICO, PROGRAMA_BEBE, PESADO, RAPIDO};                                                                                                    // MODO_Step
00022 enum{RPM_OFF = 0, RPM_MIN = 3, RPM_NORMAL = 6, RPM_MAX = 9};                                                                                                // CENTRIFUGADO_Step
00023 enum{TEMP_MIN = 10, TEMP_BAJA = 20, TEMP_NORMAL = 30, TEMP_ALTA = 40, TEMP_MAX = 50};                                                                       // TEMP_Step
00024 enum{TIEMPO_FINAL_MIN = 30, TIEMPO_FINAL_BAJO = 40, TIEMPO_FINAL_NORMAL = 50, TIEMPO_FINAL_MEDIO = 60, TIEMPO_FINAL_ALTO = 70, TIEMPO_FINAL_MAX = 80};      // TIEMPO_Step
00025 enum{TIEMPO_OFF = 0, TIEMPO_MIN = 5, TIEMPO_NORMAL = 10, TIEMPO_MAX = 15};                                                                                  // ENJUAGUE_Step y variables tiempo
00026 enum{PULS_NO_APRETADO, PULS_FLANCO_1, PULS_APRETADO, PULS_FLANCO_2};                                                                                        // PULS_Step
00027 enum{NO_CALENTAR = 1, CALENTAR = 0};                                                                                                                        // ACTUADOR_Step
00028 enum{NO_GIRAR = 0, GIRAR = 1};                                                                                                                              // MOTOR_Step
00029 
00030 /* -----clases----- */
00031 /* entradas */
00032 DigitalIn PULSDOWN(PTB0);       // boton abajo
00033 DigitalIn PULSUP(PTB1);         // boton arriba
00034 DigitalIn PULSOK(PTB3);         // boton aceptar
00035 AnalogIn LM35(PTC1);            // sensor de temperatura analogico
00036 /* salidas */
00037 DigitalOut CALENTADOR(LED1);    // es un led para indicar el encendido/apagado del CALENTADOR
00038 DigitalOut MOTOR(PTC9);         // es el enable para el driver del MOTOR
00039 PwmOut pwm(PTA5);               // es la señal para variar la velocidad del MOTOR
00040 /* objetos */
00041 Ticker timerMili;               // instancia de la clase Ticker
00042 Ticker timerSeg;                // instancia de la clase Ticker
00043 Serial pc(USBTX, USBRX);        // instancia de la clase Serial
00044 I2C i2c(PTE0, PTE1);            // instancia de la clase I2C - PTEO: SDA (data), PTE1: SCL (clock)
00045 
00046 typedef unsigned char BYTE;     // sirve para escribir "BYTE" en ves de "unsigned char" que es mas largo
00047 
00048 /* -----variables globales----- */
00049 /* modulo i2c */
00050 const int address = 0x7E;       // address de 8bits I2C
00051 int i2c_error = 0;              // si hay error en el ACK se pone en 1, sino en 0
00052 char fila1[17];
00053 char fila2[17];
00054 /* sensor LM35 */
00055 char i = 0;
00056 float sensado[10], promedio;
00057 /* estados de funciones */
00058 BYTE SELECTOR_estado;           // SELECTOR_Step
00059 BYTE LAVADO_estado;             // LAVADO_Step
00060 BYTE LAVADO_ultimoEstado;       // LAVADO_Step
00061 BYTE MODO_estado;               // MODO_Step
00062 BYTE CENTRIFUGADO_estado;       // CENTRIFUGADO_Step
00063 BYTE TEMP_estado;               // TEMP_Step
00064 BYTE TIEMPO_estado;             // TIEMPO_Step
00065 BYTE ENJUAGUE_estado;           // ENJUAGUE_Step
00066 BYTE PULS_tout;                 // PULS_Step
00067 BYTE ACTUADOR_estado;           // ACTUADOR_Step
00068 BYTE MOTOR_estado;              // MOTOR_Step
00069 /* estados de pulsadores */
00070 BYTE PULSOK_estado, PULSUP_estado, PULSDOWN_estado; //variables utilizadas en la maquina de estados
00071 /* variables maquinas de estados */
00072 char temperaturaSeteada, temperaturaActual, rpmSeteado, vecesEnjuagado;
00073 char tiempoActual, tiempoDiferido, tiempoSeteado, tiempoEnjuague, tiempoEnjabonado, tiempoSuavizado, tiempoDesagote, tiempoCentrifugado; // tiempos
00074     
00075 /* -----prototipos funciones----- */
00076 /* funciones generales */
00077 void miliSegundo(void);                     // se ejecuta cada milisegundo
00078 void segundo(void);                         // se ejecuta cada segundo
00079 void initMCU(void);                         // se ejecuta una sola vez al inicializar el microcontrolador
00080 void showTimeNow(void);                     // imprime en pantalla el tiempo actual
00081 void detectForBack(void);                   // vuelve al menu principal MENU_MODO
00082 void readSensor(void);                      // lee 10 valores y saca el promedio del sensor LM35
00083 char isWashing(void);                       // devuelve true si esta lavando, sino false
00084 /* funciones maquina de estados */
00085 void SELECTOR_Step(void);                   // maquina de estados principal
00086 void LAVADO_Step(void);                     // maquina de estados lavado
00087 void MODO_Step(void);                       // maquina de estados para setear modo o programa (algodon, sintetico)
00088 void CENTRIFUGADO_Step(void);               // maquina de estados para setear centrifugado (configura las RPM, si esta en 0 RPM es que no centrifuga)
00089 void TEMP_Step(void);                       // maquina de estados para setear temperatura (para configurar manualmente la temperatura en vez de utilizar los modos o programas)
00090 void TIEMPO_Step(void);                     // maquina de estados para setear el tiempo diferido (cuando finaliza el ciclo de lavado)
00091 void ENJUAGUE_Step(void);                   // maquina de estados para setear ciclos de enjuague
00092 void ACTUADOR_Step(void);                   // maquina de estados para activar/desactivar el calentador
00093 void MOTOR_Step(void);                      // maquina de estados para activar/desactivar el motor
00094 BYTE PULS_Step(BYTE PULSADOR, BYTE& estado);// maquina de estados para detectar el flanco de los pulsadores
00095 /* funciones I2C */
00096 void LCD_wr( BYTE dato );                   // funcion para escritura de un byte
00097 /* funciones display LCD */
00098 void LCD_init(void);                        // inicializacion del display LCD
00099 void LCD_send(BYTE data, BYTE reset);       // manda 4 bits mas significativos, despues 4 bits menos significativos
00100 void printstr(char* s);                     // muestra en el display LCD un string
00101 void LCD_print(void);                       // muestra el display LCD       
00102     
00103 int main() {
00104     LCD_init();
00105     initMCU();
00106     while(1) {
00107         /* ejecuta */
00108         SELECTOR_Step();     // maquina de estados principal
00109         LCD_print();         // printea en el LCD
00110         
00111         /* girar o no girar el motor */
00112         if(LAVADO_estado == ENJUAGADO || LAVADO_estado == CENTRIFUGADO) 
00113             MOTOR_estado = GIRAR;
00114         else 
00115             MOTOR_estado = NO_GIRAR;
00116             
00117         /* activa o desactiva el motor dependiendo de MOTOR_estado */
00118         MOTOR_Step();
00119             
00120         /* si esta lavando */
00121         if(isWashing()) {    // si no para de girar cuando esta pausado, CAMBIAR ACA
00122             showTimeNow();
00123             ACTUADOR_Step(); // maquina de estados para activar/desactivar el calentador
00124         }
00125     }
00126 }
00127 
00128 /* -----contador que se decrementa cada milisegundo----- */
00129 void miliSegundo() {
00130     if(PULS_tout > 0) PULS_tout--;
00131 }
00132 
00133 /* -----cada segundo se decrementa el valor del temporizador(si no esta pausado) y tambien se lee el valor de temperatura del LM35----- */
00134 void segundo() {
00135     readSensor();
00136     if(isWashing()) tiempoActual--;
00137 }
00138 
00139 /* -----guarda en el vector de la fila1 el tiempoActual----- */
00140 void showTimeNow() {
00141     strcpy(fila1, "TIME ACTUAL:xxs ");
00142     fila1[12] = (tiempoActual / 10) + 0x30;
00143     fila1[13] = (tiempoActual % 10) + 0x30;    
00144 }
00145 
00146 /* -----vuelve al menu principal MENU_MODO----- */
00147 void detectForBack() {
00148     if(PULS_Step(PULSOK, PULSOK_estado) == PULS_FLANCO_1) SELECTOR_estado = MENU_MODO; // cuando se presiona el pulsador vuelve al menu principal
00149 }
00150 
00151 /* -----lee 10 valores y saca el promedio del sensor LM35----- */
00152 void readSensor(void) {
00153     promedio = 0;
00154     for(i = 0; i < 10; i++){
00155         sensado[i] = LM35.read(); 
00156     }
00157     for(i = 0; i < 10; i++){
00158         promedio += sensado[i]/10;
00159     }
00160     temperaturaActual = (promedio*3.25*100);
00161 }
00162 
00163 /* -----devuelve true si esta lavando, sino false----- */
00164 char isWashing() {
00165    if(LAVADO_estado == ENJUAGADO || LAVADO_estado == ENJABONADO || LAVADO_estado == SUAVIZADO || LAVADO_estado == DESAGOTE || LAVADO_estado == CENTRIFUGADO) return 1; // devuelve true
00166    return 0; // si no se cumple la sentencia if, devuelve false
00167 }
00168 
00169 /* -----se ejecuta una sola vez al inicializar el microcontrolador----- */
00170 void initMCU(void) {
00171     pc.printf("PROGRAMA INICIALIZADO\n");
00172     
00173     /* PWM */
00174     pwm.period_ms(10);
00175     pwm.pulsewidth_ms(RPM_OFF);
00176     pc.printf("pwm set to %.2f %%\n", pwm.read() * 100);
00177     
00178     /* TIMER */
00179     PULS_tout = TIEMPO_OFF;
00180     timerMili.attach(&miliSegundo, 0.001);  // timer en 1ms
00181     timerSeg.attach(&segundo, 1);           // timer en 1s
00182     
00183     /* SELECTOR_Step */
00184     SELECTOR_estado = MENU_MODO;
00185     
00186     /* LAVADO_Step */
00187     LAVADO_estado = OFF;
00188     tiempoCentrifugado = TIEMPO_OFF;    // se inicializa en 0s por si no se configura el centrifugado, se puede modificar
00189     tiempoEnjuague = TIEMPO_MIN;        // se inicializa en 5s, se puede modificar
00190     tiempoEnjabonado = TIEMPO_MIN;      // se inicializa en 5s, se puede modificar
00191     tiempoSuavizado = TIEMPO_MIN;       // se inicializa en 5s, se puede modificar
00192     tiempoDesagote = TIEMPO_MIN;        // se inicializa en 5s, se puede modificar
00193     vecesEnjuagado = 1;                 // se inicializa en 1, despues se incrementa hasta 3 porque es la cantidad maxima de enjuagues
00194     
00195     /* MODO_Step */
00196     MODO_estado = ALGODON;
00197     
00198     /* CENTRIFUGADO_Step */
00199     CENTRIFUGADO_estado = RPM_OFF;
00200     rpmSeteado = RPM_OFF; // se inicializa en 0rps, se puede modificar
00201     
00202     /* TEMP_Step */
00203     TEMP_estado = TEMP_MIN;
00204     
00205     /* TIEMPO_Step */
00206     TIEMPO_estado = TIEMPO_FINAL_BAJO;
00207     tiempoActual = tiempoDiferido = tiempoSeteado = TIEMPO_FINAL_BAJO; // se inicializa en 40s, se puede modificar
00208     
00209     /* PULSADORES */
00210     PULSOK_estado = PULS_NO_APRETADO;
00211     PULSUP_estado = PULS_NO_APRETADO;
00212     PULSDOWN_estado = PULS_NO_APRETADO;
00213     
00214     /* ACTUADOR_Step */
00215     ACTUADOR_estado = NO_CALENTAR;
00216     CALENTADOR = NO_CALENTAR;
00217     
00218     /* MOTOR_Step */
00219     MOTOR_estado = NO_GIRAR;
00220     
00221     /* ENJUAGUE_Step */
00222     ENJUAGUE_estado = TIEMPO_MIN;
00223 } 
00224 
00225 /* -----maquina de estados principal----- */
00226 void SELECTOR_Step() {
00227     switch(SELECTOR_estado) {
00228         default:
00229         case MENU_MODO:
00230             strcpy(fila1, "MENU:           ");
00231             strcpy(fila2, "CONFIG MODE     ");
00232             if(PULS_Step(PULSDOWN, PULSDOWN_estado) == PULS_FLANCO_1) SELECTOR_estado = MENU_LAVADO;
00233             if(PULS_Step(PULSUP, PULSUP_estado) == PULS_FLANCO_1) SELECTOR_estado = MENU_TEMPERATURA;
00234             if(PULS_Step(PULSOK, PULSOK_estado) == PULS_FLANCO_1) SELECTOR_estado = CONFIG_MODO;
00235             break;
00236         case MENU_TEMPERATURA:
00237             strcpy(fila2, "CONFIG TEMP     ");
00238             if(PULS_Step(PULSDOWN, PULSDOWN_estado) == PULS_FLANCO_1) SELECTOR_estado = MENU_MODO;
00239             if(PULS_Step(PULSUP, PULSUP_estado) == PULS_FLANCO_1) SELECTOR_estado = MENU_CENTRIFUGADO;
00240             if(PULS_Step(PULSOK, PULSOK_estado) == PULS_FLANCO_1) SELECTOR_estado = CONFIG_TEMPERATURA;
00241             break;
00242         case MENU_CENTRIFUGADO:
00243             strcpy(fila2, "CONFIG RPM      ");
00244             if(PULS_Step(PULSDOWN, PULSDOWN_estado) == PULS_FLANCO_1) SELECTOR_estado = MENU_TEMPERATURA;
00245             if(PULS_Step(PULSUP, PULSUP_estado) == PULS_FLANCO_1) SELECTOR_estado = MENU_TIEMPO;
00246             if(PULS_Step(PULSOK, PULSOK_estado) == PULS_FLANCO_1) SELECTOR_estado = CONFIG_CENTRIFUGADO;
00247             break;
00248         case MENU_TIEMPO:
00249             strcpy(fila2, "CONFIG TIME     ");
00250             if(PULS_Step(PULSDOWN, PULSDOWN_estado) == PULS_FLANCO_1) SELECTOR_estado = MENU_CENTRIFUGADO;
00251             if(PULS_Step(PULSUP, PULSUP_estado) == PULS_FLANCO_1) SELECTOR_estado = MENU_ENJUAGUE;
00252             if(PULS_Step(PULSOK, PULSOK_estado) == PULS_FLANCO_1) SELECTOR_estado = CONFIG_TIEMPO;
00253             break;
00254         case MENU_ENJUAGUE:
00255             strcpy(fila2, "CONFIG ENJUAGUE ");
00256             if(PULS_Step(PULSDOWN, PULSDOWN_estado) == PULS_FLANCO_1) SELECTOR_estado = MENU_TIEMPO;
00257             if(PULS_Step(PULSUP, PULSUP_estado) == PULS_FLANCO_1) SELECTOR_estado = MENU_LAVADO;
00258             if(PULS_Step(PULSOK, PULSOK_estado) == PULS_FLANCO_1) SELECTOR_estado = CONFIG_ENJUAGUE;
00259             break;
00260         case MENU_LAVADO:
00261             strcpy(fila2, "COMENZAR          ");
00262             if(PULS_Step(PULSDOWN, PULSDOWN_estado) == PULS_FLANCO_1) SELECTOR_estado = MENU_ENJUAGUE;
00263             if(PULS_Step(PULSUP, PULSUP_estado) == PULS_FLANCO_1) SELECTOR_estado = MENU_MODO;
00264             if(PULS_Step(PULSOK, PULSOK_estado) == PULS_FLANCO_1) {
00265                 SELECTOR_estado = LAVANDO;
00266                 LAVADO_estado = ENJUAGADO;
00267                 tiempoSeteado -= tiempoEnjuague; //primer ciclo de lavado
00268             }
00269             break;
00270         case CONFIG_MODO:
00271             MODO_Step();
00272             detectForBack();
00273             break;
00274         case CONFIG_TEMPERATURA:
00275             TEMP_Step();
00276             detectForBack();
00277             break;
00278         case CONFIG_CENTRIFUGADO:
00279             CENTRIFUGADO_Step();
00280             detectForBack();
00281             break;
00282         case CONFIG_TIEMPO:
00283             TIEMPO_Step();
00284             detectForBack();
00285             break;
00286         case CONFIG_ENJUAGUE:
00287             ENJUAGUE_Step();
00288             detectForBack();
00289             break;
00290         case LAVANDO:
00291             LAVADO_Step();
00292             if(PULS_Step(PULSOK, PULSOK_estado) == PULS_FLANCO_1) {
00293                 LAVADO_estado = OFF;        // pone en OFF, es decir, deja de lavar en LAVADO_Step
00294                 SELECTOR_estado = PAUSADO;  // va al estado PAUSADO del SELECTOR_Step
00295             }
00296             break;
00297         case PAUSADO:
00298             strcpy(fila2, "PAUSADO...      ");
00299             if(PULS_Step(PULSOK, PULSOK_estado) == PULS_FLANCO_1){ 
00300                 LAVADO_estado = LAVADO_ultimoEstado; // vuelve al ultimo estado de LAVADO_estado
00301                 SELECTOR_estado = LAVANDO;  // vuelve al estado LAVANDO del SELECTOR_Step
00302             }
00303             break;
00304     }
00305 }
00306 
00307 /* -----maquina de estados lavado----- */
00308 void LAVADO_Step() {
00309     switch(LAVADO_estado) {
00310         default:
00311         case OFF:
00312             tiempoSeteado = tiempoActual = tiempoDiferido;
00313             vecesEnjuagado = 1;
00314             CALENTADOR = NO_CALENTAR;
00315             SELECTOR_estado = MENU_MODO;
00316             break;
00317         case ENJUAGADO:
00318             strcpy(fila2, "ENJUAGANDO...   ");
00319             /* finaliza tiempo enjuagado */ 
00320             if(tiempoActual == tiempoSeteado) {
00321                 switch(vecesEnjuagado) {
00322                     case 1: /* finaliza primer enjuague */ 
00323                         tiempoSeteado -= tiempoEnjabonado; // segundo ciclo de lavado
00324                         LAVADO_estado = ENJABONADO;
00325                         break;
00326                     case 2: /* finaliza segundo enjuague, despues del enjabonado */
00327                         tiempoSeteado -= tiempoSuavizado; // cuarto ciclo de lavado
00328                         LAVADO_estado = SUAVIZADO;
00329                         break;
00330                     case 3: /* finaliza tercer enjuague, despues del suavizado */
00331                         tiempoSeteado -= tiempoDesagote; // sexto ciclo de lavado
00332                         LAVADO_estado = DESAGOTE;
00333                         break;
00334                 }
00335             }
00336             LAVADO_ultimoEstado = ENJUAGADO;
00337             break;
00338         case ENJABONADO:
00339             strcpy(fila2, "ENJABONANDO...  ");
00340             /* finaliza tiempo enjabonado */ 
00341             if(tiempoActual == tiempoSeteado) {
00342                 vecesEnjuagado++;
00343                 tiempoSeteado -= tiempoEnjuague; // tercer ciclo de lavado
00344                 LAVADO_estado = ENJUAGADO;
00345             }
00346             LAVADO_ultimoEstado = ENJABONADO;
00347             break;
00348         case SUAVIZADO:
00349             strcpy(fila2, "SUAVIZANDO...   ");
00350             /* finaliza tiempo suavizado */ 
00351             if(tiempoActual == tiempoSeteado) {
00352                 vecesEnjuagado++;
00353                 tiempoSeteado -= tiempoEnjuague; // quinto ciclo de lavado
00354                 LAVADO_estado = ENJUAGADO;
00355             }
00356             LAVADO_ultimoEstado = SUAVIZADO;
00357             break;
00358         case DESAGOTE:
00359             strcpy(fila2, "DESAGOTANDO...  ");
00360             /* finaliza tiempo desagote */
00361             if(tiempoActual == tiempoSeteado && rpmSeteado != RPM_OFF) {
00362                 tiempoSeteado -= tiempoCentrifugado; // septimo ciclo de lavado, se ejecuta solo si queres centrifugar
00363                 LAVADO_estado = CENTRIFUGADO;
00364             }
00365             LAVADO_ultimoEstado = DESAGOTE;
00366             if(tiempoActual == 0) LAVADO_estado = OFF;
00367             break;
00368         case CENTRIFUGADO:
00369             strcpy(fila2, "CENTRIFUGANDO...");
00370             LAVADO_ultimoEstado = CENTRIFUGADO;
00371             if(tiempoActual == 0) LAVADO_estado = OFF;
00372             break;
00373     }
00374 }
00375 
00376 /* -----maquina de estados para setear modo o programa (algodon, sintetico, etc)----- */
00377 void MODO_Step() {
00378     strcpy(fila1, "CONFIG:         ");
00379     switch(MODO_estado) {
00380         default:
00381         case ALGODON:
00382             strcpy(fila2, "MODO:ALGODON   ");
00383             temperaturaSeteada = TEMP_BAJA;
00384             tiempoEnjuague = TIEMPO_MAX; //15s tiempo enjuague
00385             if(rpmSeteado)
00386                 tiempoSeteado = tiempoActual = tiempoDiferido = TIEMPO_FINAL_ALTO; //70s tiempo total, 10s tiempo centrifugado  
00387             else
00388                 tiempoSeteado = tiempoActual = tiempoDiferido = TIEMPO_FINAL_MEDIO; //60s tiempo total, 0s tiempo centrifugado
00389             if(PULS_Step(PULSDOWN, PULSDOWN_estado) == PULS_FLANCO_1) MODO_estado = PESADO;
00390             if(PULS_Step(PULSUP, PULSUP_estado) == PULS_FLANCO_1) MODO_estado = SINTETICO;
00391             break;
00392         case SINTETICO:
00393             strcpy(fila2, "MODO:SINTETICO ");
00394             temperaturaSeteada = TEMP_NORMAL;
00395             tiempoEnjuague = TIEMPO_NORMAL; //10s tiempo enjuague
00396             if(rpmSeteado)
00397                 tiempoSeteado = tiempoActual = tiempoDiferido = TIEMPO_FINAL_MEDIO; //60s tiempo total, 15s tiempo centrifugado
00398             else
00399                 tiempoSeteado = tiempoActual = tiempoDiferido = TIEMPO_FINAL_NORMAL; //50s tiempo total, 0s tiempo centrifugado
00400             if(PULS_Step(PULSDOWN, PULSDOWN_estado) == PULS_FLANCO_1) MODO_estado = ALGODON;
00401             if(PULS_Step(PULSUP, PULSUP_estado) == PULS_FLANCO_1) MODO_estado = RAPIDO;
00402             break;
00403         case RAPIDO:
00404             strcpy(fila2, "MODO:RAPIDO    ");
00405             temperaturaSeteada = TEMP_NORMAL;
00406             tiempoEnjuague = TIEMPO_MIN; //5s tiempo enjuague
00407             if(rpmSeteado)
00408                 tiempoSeteado = tiempoActual = tiempoDiferido = TIEMPO_FINAL_BAJO; //40s tiempo total, 10s tiempo centrifugado
00409             else
00410                 tiempoSeteado = tiempoActual = tiempoDiferido = TIEMPO_FINAL_MIN; //30s tiempo total, 0s tiempo centrifugado
00411             if(PULS_Step(PULSDOWN, PULSDOWN_estado) == PULS_FLANCO_1) MODO_estado = SINTETICO;
00412             if(PULS_Step(PULSUP, PULSUP_estado) == PULS_FLANCO_1) MODO_estado = PROGRAMA_BEBE;
00413             break;
00414         case PROGRAMA_BEBE:
00415             strcpy(fila2, "MODO:BEBE      ");
00416             temperaturaSeteada = TEMP_MAX;
00417             tiempoEnjuague = TIEMPO_MAX; //15s tiempo enjuague
00418             tiempoSeteado = tiempoActual = tiempoDiferido = TIEMPO_FINAL_MAX; //80s tiempo total, 20s tiempo centrifugado
00419             if(PULS_Step(PULSDOWN, PULSDOWN_estado) == PULS_FLANCO_1) MODO_estado = RAPIDO;
00420             if(PULS_Step(PULSUP, PULSUP_estado) == PULS_FLANCO_1) MODO_estado = PESADO;
00421             break;
00422         case PESADO:
00423             strcpy(fila2, "MODO:PESADO    ");
00424             temperaturaSeteada = TEMP_NORMAL;
00425             tiempoEnjuague = TIEMPO_MIN; //5s tiempo enjuague
00426             tiempoSeteado = tiempoActual = tiempoDiferido = TIEMPO_FINAL_NORMAL; //50s tiempo total, 20s tiempo centrifugado
00427             if(PULS_Step(PULSDOWN, PULSDOWN_estado) == PULS_FLANCO_1) MODO_estado = PROGRAMA_BEBE;
00428             if(PULS_Step(PULSUP, PULSUP_estado) == PULS_FLANCO_1) MODO_estado = ALGODON;
00429             break;
00430     }
00431 }
00432 
00433 /* -----maquina de estados para setear centrifugado (configura las RPM, si esta en 0 RPM es que no centrifuga)----- */
00434 void CENTRIFUGADO_Step() {
00435     strcpy(fila1, "CONFIG:         ");
00436     strcpy(fila2, "RPM SET:xx      ");
00437     fila2[8] = (rpmSeteado / 10) + 0x30;
00438     fila2[9] = (rpmSeteado % 10) + 0x30; 
00439     switch(CENTRIFUGADO_estado) {
00440         default:
00441         case RPM_OFF:
00442             rpmSeteado = RPM_OFF;
00443             pwm.pulsewidth_ms(RPM_OFF);
00444             tiempoCentrifugado = TIEMPO_OFF;
00445             if(PULS_Step(PULSDOWN, PULSDOWN_estado) == PULS_FLANCO_1) CENTRIFUGADO_estado = RPM_MAX;
00446             if(PULS_Step(PULSUP, PULSUP_estado) == PULS_FLANCO_1) CENTRIFUGADO_estado = RPM_MIN;
00447             break;
00448         case RPM_MIN:
00449             rpmSeteado = RPM_MIN;
00450             pwm.pulsewidth_ms(RPM_MIN);
00451             tiempoCentrifugado = TIEMPO_MIN;
00452             if(PULS_Step(PULSDOWN, PULSDOWN_estado) == PULS_FLANCO_1) CENTRIFUGADO_estado = RPM_OFF;
00453             if(PULS_Step(PULSUP, PULSUP_estado) == PULS_FLANCO_1) CENTRIFUGADO_estado = RPM_NORMAL;
00454             break;
00455         case RPM_NORMAL:
00456             rpmSeteado = RPM_NORMAL;
00457             pwm.pulsewidth_ms(RPM_NORMAL);
00458             tiempoCentrifugado = TIEMPO_MIN;
00459             if(PULS_Step(PULSDOWN, PULSDOWN_estado) == PULS_FLANCO_1) CENTRIFUGADO_estado = RPM_MIN;
00460             if(PULS_Step(PULSUP, PULSUP_estado) == PULS_FLANCO_1) CENTRIFUGADO_estado = RPM_MAX;
00461             break;
00462         case RPM_MAX:
00463             rpmSeteado = RPM_MAX;
00464             pwm.pulsewidth_ms(RPM_MAX);
00465             tiempoCentrifugado = TIEMPO_MIN;
00466             if(PULS_Step(PULSDOWN, PULSDOWN_estado) == PULS_FLANCO_1) CENTRIFUGADO_estado = RPM_NORMAL;
00467             if(PULS_Step(PULSUP, PULSUP_estado) == PULS_FLANCO_1) CENTRIFUGADO_estado = RPM_OFF;
00468             break;
00469     }
00470 }
00471 
00472 /* -----maquina de estados para setear temperatura (para configurar manualmente la temperatura en vez de utilizar los modos o programas)----- */
00473 void TEMP_Step() {
00474     strcpy(fila1, "TEMP NOW:xxg    ");
00475     fila1[9] = (temperaturaActual / 10) + 0x30;
00476     fila1[10] = (temperaturaActual % 10) + 0x30;
00477     fila1[11] = 0xDF; // para el simbolo de grado
00478     strcpy(fila2, "TEMP SET:xxg    ");
00479     fila2[9] = (temperaturaSeteada / 10) + 0x30;
00480     fila2[10] = (temperaturaSeteada % 10) + 0x30;
00481     fila2[11] = 0xDF; // para el simbolo de grado
00482     switch(TEMP_estado) {
00483         default:
00484         case TEMP_MIN:
00485             temperaturaSeteada = TEMP_MIN;
00486             if(PULS_Step(PULSDOWN, PULSDOWN_estado) == PULS_FLANCO_1) TEMP_estado = TEMP_MAX;
00487             if(PULS_Step(PULSUP, PULSUP_estado) == PULS_FLANCO_1) TEMP_estado = TEMP_BAJA;
00488             break;
00489         case TEMP_BAJA:
00490             temperaturaSeteada = TEMP_BAJA;
00491             if(PULS_Step(PULSDOWN, PULSDOWN_estado) == PULS_FLANCO_1) TEMP_estado = TEMP_MIN;
00492             if(PULS_Step(PULSUP, PULSUP_estado) == PULS_FLANCO_1) TEMP_estado = TEMP_NORMAL;
00493             break;
00494         case TEMP_NORMAL:
00495             temperaturaSeteada = TEMP_NORMAL;
00496             if(PULS_Step(PULSDOWN, PULSDOWN_estado) == PULS_FLANCO_1) TEMP_estado = TEMP_BAJA;
00497             if(PULS_Step(PULSUP, PULSUP_estado) == PULS_FLANCO_1) TEMP_estado = TEMP_ALTA;
00498             break;
00499         case TEMP_ALTA:
00500             temperaturaSeteada = TEMP_ALTA;
00501             if(PULS_Step(PULSDOWN, PULSDOWN_estado) == PULS_FLANCO_1) TEMP_estado = TEMP_NORMAL;
00502             if(PULS_Step(PULSUP, PULSUP_estado) == PULS_FLANCO_1) TEMP_estado = TEMP_MAX;
00503             break;
00504         case TEMP_MAX:
00505             temperaturaSeteada = TEMP_MAX;
00506             if(PULS_Step(PULSDOWN, PULSDOWN_estado) == PULS_FLANCO_1) TEMP_estado = TEMP_ALTA;
00507             if(PULS_Step(PULSUP, PULSUP_estado) == PULS_FLANCO_1) TEMP_estado = TEMP_MIN;
00508             break;
00509     }
00510 }
00511 
00512 /* -----maquina de estados para setear el tiempo diferido (cuando finaliza el ciclo de lavado)----- */
00513 void TIEMPO_Step() {
00514     strcpy(fila1, "CONFIG:         ");
00515     strcpy(fila2, "TIME SET:x      ");
00516     fila2[9] = (tiempoDiferido / 10) + 0x30;
00517     fila2[10] = (tiempoDiferido % 10) + 0x30; 
00518     switch(TIEMPO_estado) {
00519         default:
00520         case TIEMPO_FINAL_BAJO:
00521             tiempoSeteado = tiempoActual = tiempoDiferido = TIEMPO_FINAL_BAJO;
00522             if(PULS_Step(PULSUP, PULSUP_estado) == PULS_FLANCO_1) TIEMPO_estado = TIEMPO_FINAL_NORMAL;
00523             if(PULS_Step(PULSDOWN, PULSDOWN_estado) == PULS_FLANCO_1) TIEMPO_estado = TIEMPO_FINAL_MAX;
00524             break;
00525         case TIEMPO_FINAL_NORMAL:
00526             tiempoSeteado = tiempoActual = tiempoDiferido = TIEMPO_FINAL_NORMAL;
00527             if(PULS_Step(PULSUP, PULSUP_estado) == PULS_FLANCO_1) TIEMPO_estado = TIEMPO_FINAL_MEDIO;
00528             if(PULS_Step(PULSDOWN, PULSDOWN_estado) == PULS_FLANCO_1) TIEMPO_estado = TIEMPO_FINAL_BAJO;
00529             break;
00530         case TIEMPO_FINAL_MEDIO:
00531             tiempoSeteado = tiempoActual = tiempoDiferido = TIEMPO_FINAL_MEDIO;
00532             if(PULS_Step(PULSUP, PULSUP_estado) == PULS_FLANCO_1) TIEMPO_estado = TIEMPO_FINAL_ALTO;
00533             if(PULS_Step(PULSDOWN, PULSDOWN_estado) == PULS_FLANCO_1) TIEMPO_estado = TIEMPO_FINAL_NORMAL;
00534             break;
00535         case TIEMPO_FINAL_ALTO:
00536             tiempoSeteado = tiempoActual = tiempoDiferido = TIEMPO_FINAL_ALTO;
00537             if(PULS_Step(PULSUP, PULSUP_estado) == PULS_FLANCO_1) TIEMPO_estado = TIEMPO_FINAL_MAX;
00538             if(PULS_Step(PULSDOWN, PULSDOWN_estado) == PULS_FLANCO_1) TIEMPO_estado = TIEMPO_FINAL_MEDIO;
00539             break;
00540         case TIEMPO_FINAL_MAX:
00541             tiempoSeteado = tiempoActual = tiempoDiferido = TIEMPO_FINAL_MAX;
00542             if(PULS_Step(PULSUP, PULSUP_estado) == PULS_FLANCO_1) TIEMPO_estado = TIEMPO_FINAL_BAJO;
00543             if(PULS_Step(PULSDOWN, PULSDOWN_estado) == PULS_FLANCO_1) TIEMPO_estado = TIEMPO_FINAL_ALTO;
00544             break; 
00545     }
00546 }
00547 
00548 /* -----maquina de estados para setear ciclos de enjuague----- */
00549 void ENJUAGUE_Step() {
00550     strcpy(fila1, "CONFIG:         ");
00551     strcpy(fila2, "TIME ENJUAGUE:xx");
00552     fila2[14] = (tiempoEnjuague / 10) + 0x30;
00553     fila2[15] = (tiempoEnjuague % 10) + 0x30;
00554     switch(ENJUAGUE_estado) {
00555         default:
00556         case TIEMPO_MIN:
00557             tiempoEnjuague = TIEMPO_MIN;
00558             if(PULS_Step(PULSUP, PULSUP_estado) == PULS_FLANCO_1) ENJUAGUE_estado = TIEMPO_NORMAL;
00559             if(PULS_Step(PULSDOWN, PULSDOWN_estado) == PULS_FLANCO_1) ENJUAGUE_estado = TIEMPO_MAX;
00560             break;
00561         case TIEMPO_NORMAL:
00562             tiempoEnjuague = TIEMPO_NORMAL;
00563             if(PULS_Step(PULSUP, PULSUP_estado) == PULS_FLANCO_1) ENJUAGUE_estado = TIEMPO_MAX;
00564             if(PULS_Step(PULSDOWN, PULSDOWN_estado) == PULS_FLANCO_1) ENJUAGUE_estado = TIEMPO_MIN;
00565             break;
00566         case TIEMPO_MAX:
00567             tiempoEnjuague = TIEMPO_MAX;
00568             if(PULS_Step(PULSUP, PULSUP_estado) == PULS_FLANCO_1) ENJUAGUE_estado = TIEMPO_MIN;
00569             if(PULS_Step(PULSDOWN, PULSDOWN_estado) == PULS_FLANCO_1) ENJUAGUE_estado = TIEMPO_NORMAL;
00570             break;
00571     }
00572 }
00573 
00574 /* -----maquina de estados para activar/desactivar el calentadorl----- */
00575 void ACTUADOR_Step() {
00576     switch(ACTUADOR_estado) {
00577         default:
00578         case NO_CALENTAR:
00579             CALENTADOR = NO_CALENTAR;
00580             if(temperaturaActual < temperaturaSeteada) ACTUADOR_estado = CALENTAR;
00581             break;
00582         case CALENTAR:
00583             CALENTADOR = CALENTAR;
00584             if(temperaturaActual >= temperaturaSeteada) ACTUADOR_estado = NO_CALENTAR;
00585             break;
00586     }
00587 }
00588 
00589 /* -----maquina de estados para activar/desactivar el motor----- */
00590 void MOTOR_Step() {
00591     switch(MOTOR_estado) {
00592         default:
00593         case NO_GIRAR:
00594             MOTOR = NO_GIRAR;
00595             break;
00596         case GIRAR:
00597             MOTOR = GIRAR;
00598             break;
00599     }
00600 }
00601 
00602 /* -----maquina de estados para detectar el flanco de los pulsadores----- */
00603 BYTE PULS_Step(BYTE PULSADOR, BYTE& estado) {
00604     switch(estado){
00605         default:
00606         case PULS_NO_APRETADO:
00607             if(PULSADOR == APRETADO && PULS_tout == 0){
00608                 estado = PULS_FLANCO_1;
00609                 PULS_tout = 5; // 5ms de espera
00610             }
00611             break;
00612         case PULS_FLANCO_1:
00613             if(PULSADOR == APRETADO && PULS_tout == 0){
00614                 estado = PULS_APRETADO;
00615                 PULS_tout = 5; // 5ms de espera
00616             }
00617             if(PULSADOR == NO_APRETADO && PULS_tout == 0){
00618                 estado = PULS_NO_APRETADO;
00619                 PULS_tout = 5; // 5ms de espera
00620             }
00621             break;  
00622         case PULS_APRETADO:
00623             if(PULSADOR == NO_APRETADO && PULS_tout == 0){
00624                 estado = PULS_NO_APRETADO;
00625                 PULS_tout = 5; //5ms de espera
00626             }
00627             break;  
00628     }
00629     return estado;
00630 }
00631 
00632 /* -----escribe un byte----- */
00633 void LCD_wr( BYTE dato ) {
00634     dato = dato & 0xF0; // hace una mascara con 0b11110000 para que queda los 4 MSB
00635     do{
00636         i2c.start();
00637         i2c_error = i2c.write( address );
00638     }while( i2c_error == 0 ); /* espera fin ciclo escritura (ACK polling) */
00639     /* Primero mando los 4 bits mas significativos */
00640     i2c.write( dato | 0x09 );  // esta mascara pone BACKLIGHT = 1, ENABLE = 0, RW = 0, RESET = 1
00641     i2c.write( dato | 0x0D );  // esta mascara pone BACKLIGHT = 1, ENABLE = 1, RW = 0, RESET = 1
00642     i2c.write( dato | 0x09 );  // esta mascara pone BACKLIGHT = 1, ENABLE = 0, RW = 0, RESET = 1
00643     /* Mando STOP */
00644     i2c.stop();
00645 }
00646 
00647 /* -----escribe 4 MSB, luego 4 LSB, si reset = 1 es porque manda un caracter, si reset = 0 configura registro----- */
00648 void LCD_send(BYTE data, BYTE reset) {
00649     BYTE DataHIGH, DataLOW;
00650     DataHIGH = data & 0xF0;         // hace una mascara con 0b11110000 para que queda los 4 MSB
00651     DataLOW = ( data << 4 ) & 0xF0; // mueve los 4 LSB a la izquierda
00652     do{
00653         i2c.start();
00654         i2c_error = i2c.write( address );
00655     }while( i2c_error == 0 ); /* espera fin ciclo escritura (ACK polling) */
00656     /* primero mando los 4 bits mas significativos */
00657     i2c.write( DataHIGH | ( 0x0C | reset ) );   // esta mascara pone BACKLIGHT = 1, ENABLE = 1, RW = 0, RESET = X
00658     i2c.write( DataHIGH | ( 0x08 | reset ) );   // esta mascara pone BACKLIGHT = 1, ENABLE = 0, RW = 0, RESET = X
00659     /* despues mando los 4 bits menos significativos */
00660     i2c.write( DataLOW | ( 0x0C | reset ) );    // esta mascara pone BACKLIGHT = 1, ENABLE = 1, RW = 0, RESET = X
00661     i2c.write( DataLOW | ( 0x08 | reset ) );    // esta mascara pone BACKLIGHT = 1, ENABLE = 0, RW = 0, RESET = X
00662     i2c.write( DataLOW | 0x0C );                // esta mascara pone BACKLIGHT = 1, ENABLE = 1, RW = 0, RESET = 0
00663     /* mando STOP */
00664     i2c.stop(); 
00665 }
00666 
00667 /* -----inicializacion LCD----- */
00668 void LCD_init() {
00669     i2c.frequency(300000);
00670     wait(0.4);
00671     LCD_wr( 0x30 );
00672     LCD_wr( 0x30 );
00673     LCD_wr( 0x30 );
00674     LCD_wr( 0x20 );             /* --- modo 4 bit --- */
00675     LCD_send( 0x28 , CMND );    /* --- modo 4b - 2 lin - car 5x7 --- */
00676     LCD_send( 0x08 , CMND );    /* --- apaga display --- */
00677     LCD_send( 0x01 , CMND );    /* --- clear --- */
00678     wait(0.2);
00679     LCD_send( 0x0C , CMND );    /* --- disp on - cur off - blink off --- */
00680     LCD_send( 0x06 , CMND );    /* --- inc - no scroll --- */
00681     pc.printf("DISPLAY INICIALIZADO\n");
00682 }
00683 
00684 /* -----muestra string en el display LCD----- */
00685 void printstr(char* s) {
00686     /* recorre el vector s (el string parametro de la funcion), hasta que llega al final "\0" */
00687     for (char i = 0; s[i] != '\0'; i++) LCD_send(s[i], DATA);
00688 }
00689 
00690 /* -----muestra en el display LCD los vectores fila1 y fila2----- */
00691 void LCD_print() {
00692     LCD_send( 0x80 , CMND );    // posiciona en columna de arriba, y en la primer linea
00693     printstr(fila1);            // una vez posicionado, muestra el texto en la fila 1
00694     LCD_send( 0xC0 , CMND );    // posiciona en columna de abajo, y en la segunda linea
00695     printstr(fila2);            // una vez posicionado, muestra el texto en la fila 2
00696 }