Proyecto de Tesis en Mecatrónica. Universidad Técnica del Norte. Ernesto Palacios <mecatronica.mid@gmail.com>
Dependencies: EthernetNetIf HTTPServer QEI_hw RPCInterface mbed
setup.cpp
- Committer:
- Yo_Robot
- Date:
- 2014-07-17
- Revision:
- 37:20f4a737cc13
- Parent:
- 34:bdf918bc9b59
File content as of revision 37:20f4a737cc13:
/** * @file setup.cpp * @author Ernesto Palacios * @brief Codigo Fuente de las funciones para el deslizador. * * Created on 25 de Marzo de 2012 * * Licencia GPL v3.0 * http://www.gnu.org/licenses/gpl-3.0.html */ #include "mbed.h" #include "qeihw.h" #include "setup.h" #include "EthernetNetIf.h" extern Serial pc; // Salida Serial de mbed extern Serial RS_232; // Salida Serial a MAX232 extern QEIHW encoder; extern Timer crono; // Cronometro interno del microcontrolador extern DigitalIn isPC; // Bit de configuracion serial en la placa extern DigitalOut pin_son; // SON extern DigitalOut pin_dir; // SIGN+ extern InterruptIn pin_alm; // ALM extern AnalogOut aout; // +-10V extern DigitalOut led_verde; // Led verde del conector Ethernet extern DigitalOut led_rojo; // Led naranja del conector Ethernet extern InterruptIn limite_1; extern InterruptIn limite_2; extern InterruptIn limite_3; extern InterruptIn limite_4; int fq_posicion = 10000; // Variable global donde se almacenara // la velocidad de posicionamiento en Hz float t_alto; // para el posicionamiento del motor int fq_actual = 0; // Ultimo valor seteado para el tren de pulsos int bandera_inicio = 0; int velocidad_rpm() { return encoder.GetVelocityCap(); } void clear_encoder() { encoder.Reset( QEI_RESET_POS ); // reset position } void setTimer2() { // Encender Timer2 (PCONP[22]) LPC_SC->PCONP |= 1 << 22; // Resetear y parar el Timer LPC_TIM2->TCR = 0x2; LPC_TIM2->CTCR = 0x0; // Establecer el Preescaler en cero // SIn Preesclaer LPC_TIM2->PR = 0; // Calcular el periodo Inicial uint32_t periodo = ( SystemCoreClock / 400 ); // Establecer los Registros de Coincidencia // ( Match Register ) LPC_TIM2->MR2 = periodo; LPC_TIM2->MR3 = periodo; // Legacy, salidas identicas LPC_TIM2->MCR |= 1 << 7; // Resetear Timer en MR2 LPC_TIM2->EMR |= 15UL << 8; // Alternar Pin MAT2.2 // y MAT2.3 LPC_PINCON->PINSEL0 |= 15UL << 16; //Activar MAT2.2 // y MAT2.3 como salidas } void ISR_Serial() { int value; // Nuevo Valor char command; // Comando al que aplicar el nuevo valor if( isPC ) pc.scanf( "%d-%c", &value, &command ); else RS_232.scanf( "%d-%c", &value, &command ); switch( command ) { case 'E': // Leer el contador del encoder. { //Leer la posición del encoder if( isPC ) pc.printf("%d\n\r",encoder.GetPosition()); else RS_232.printf("%d\n\r",encoder.GetPosition()); break; } case 'H': // Establecer nueva frecuencia { setPTO( value ); fq_actual = value; bandera_inicio = 0; //En caso que haya estado yendo a HOME, cancelar // Envia un OK de comando recibido if( isPC ) pc.printf("OK\r\n"); else RS_232.printf("OK\r\n"); break; } case 'K': { setPTO( value * 1000 ); fq_actual = value; bandera_inicio = 0; //En caso que haya estado yendo a HOME, cancelar // Envia un OK de comando recibido if( isPC ) pc.printf("OK\r\n"); else RS_232.printf("OK\r\n"); break; } case 'A': // Cambiar voltaje de salida { aout = (float)( value + 10000.0 ) / 20000.0; // Envia un OK de comando recibido if( isPC ) pc.printf("OK\r\n"); else RS_232.printf("OK\r\n"); break; } case 'D': // Cambiar la direccion { stopTimer2(); pin_dir = value; wait_us( 2 ); bandera_inicio = 0; //En caso que haya estado yendo a HOME, cancelar if ( fq_actual != 0 ) { startTimer2(); } // Envia un OK de comando recibido if( isPC ) pc.printf("OK\r\n"); else RS_232.printf("OK\r\n"); break; } case 'V': //Setear la velocidad de Posicionamiento { fq_posicion = value; // Envia un OK de comando recibido if( isPC ) pc.printf("OK\r\n"); else RS_232.printf("OK\r\n"); break; } // Generar un numero definido de pulsos a la velocidad de posicionamiento case 'P': { float pulsos = abs( value ); //Numero de pulsos a generar t_alto = (float)(pulsos / fq_posicion); //Tiempo que debe ser generado el tren de pulsos. bandera_inicio = 0; //En caso que haya estado yendo a HOME, cancelar //DEBUG //pc.printf("Tiempo en timer en seg = %f", t_alto); stopTimer2(); //Deten el tren de pulsos setPTO( fq_posicion ); //Nueva frecuencia de salida startTimer2(); //Inicia el tren de pulsos wait( t_alto ); //Espera hasta llegar a la posicion stopTimer2(); //Posicion alcanzada ALTO. // Envia un OK de comando recibido if( isPC ) pc.printf("OK\r\n"); else RS_232.printf("OK\r\n"); break; } // Generar un numero definido de MILES de pulsos a la velocidad de posicionamiento case 'M': { float pulsos = abs(value * 1000); //Numero de pulsos a generar t_alto = (float)(pulsos / fq_posicion); //Tiempo que debe ser generado el tren de pulsos. bandera_inicio = 0; //En caso que haya estado yendo a HOME, cancelar //DEBUG //pc.printf("Tiempo en timer en seg = %f", t_alto); stopTimer2(); //Deten el tren de pulsos setPTO( fq_posicion ); //Nueva frecuencia de salida startTimer2(); //Inicia el tren de pulsos wait( t_alto ); //Espera hasta llegar a la posicion stopTimer2(); //Posicion alcanzada ALTO. // Envia un OK de comando recibido if( isPC ) pc.printf("OK\r\n"); else RS_232.printf("OK\r\n"); break; } // Generar un numero definido de MILLONES pulsos a la velocidad de posicionamiento case 'N': { float pulsos = abs( value * 1000000 ); //Numero de pulsos a generar t_alto = (float)(pulsos / fq_posicion); //Tiempo que debe ser generado el tren de pulsos. bandera_inicio = 0; //En caso que haya estado yendo a HOME, cancelar //DEBUG //pc.printf("Tiempo en timer en seg = %f", t_alto); stopTimer2(); //Deten el tren de pulsos setPTO( fq_posicion ); //Nueva frecuencia de salida startTimer2(); //Inicia el tren de pulsos wait( t_alto ); //Espera hasta llegar a la posicion stopTimer2(); //Posicion alcanzada ALTO. // Envia un OK de comando recibido if( isPC ) pc.printf("OK\r\n"); else RS_232.printf("OK\r\n"); break; } case 'R': // Leer la velocidd del encoder en RPM's { if( isPC ) { pc.printf( "%u", encoder.CalculateRPM( encoder.GetVelocityCap(), 360) ); // ultima velocidad leida desde el encoder }else RS_232.printf( "%u",encoder.CalculateRPM( encoder.GetVelocityCap(), 360) ); break; } case 'Z': //Limpiar contador encoder encoder.Reset(QEI_RESET_POS); encoder.Reset(QEI_RESET_VEL); // Envia un OK de comando recibido if( isPC ) pc.printf("OK\r\n"); else RS_232.printf("OK\r\n"); break; case 'S': //Encender el Servo pin_son = value; bandera_inicio = 0; //En caso que haya estado yendo a HOME, cancelar // Envia un OK de comando recibido if( isPC ) pc.printf("OK\r\n"); else RS_232.printf("OK\r\n"); break; case 'I': //Ir al inicio del recorrido pin_dir = 1; //Mover hacia el motor bandera_inicio = 1; // Informar a ISR_Adv_motor() acerca del Homing setPTO( value ); // a la velocidad seteada // Envia un OK de comando recibido if( isPC ) pc.printf("OK\r\n"); else RS_232.printf("OK\r\n"); break; default: // EL COMANDO NO SE RECONOCE: No Aplica if( isPC ) pc.printf("NA\r\n"); else RS_232.printf("NA\r\n"); break; } } void setPTO( int freq ) { if( freq != 0 ) { LPC_TIM2->TC = 0x00; //Resetear Timer setMR2( getMRvalue( freq ) ); startTimer2(); }else{ stopTimer2(); LPC_TIM2->TC = 0x00; //Resetear Timer } } void ISR_Alarm() { pin_son = 0 ; stopTimer2(); aout = 0.5 ; if(isPC) pc.printf( "AL\r\n" ); //ALARMA! solo es AL para que //sea conciso con el modo ETH y funcione //bien en LabVIEW. else RS_232.printf( "AL\r\n" ); } /** @brief: Esta es la rutina que maneja las interrupciones * del sensor óptico, al recibir una ALARMA de proximidad al encoder */ void ISR_Alm_encoder() { if( isPC ) pc.printf("A3\r\n"); else RS_232.printf("A3\r\n"); } /** @brief: Esta es la rutina que maneja las interrupciones * del sensor óptico, al recibir una ALARMA de proximidad al motor */ void ISR_Alm_motor() { wait_us( 50 ); if ( limite_4 == 1) { if( isPC ) pc.printf("A0\r\n"); else RS_232.printf("A0\r\n"); } } /** @brief: Esta es la rutina que maneja las interrupciones * del sensor óptico, al recibir una advertencia de proximidad al encoder */ void ISR_Adv_encoder() { wait_ms( 50 ); if ( limite_2 == 1) { if( isPC ) pc.printf("A2\r\n"); else RS_232.printf("A2\r\n"); } } /** @brief: Esta es la rutina que maneja las interrupciones * del sensor óptico, al recibir una advertencia de proximidad al motor */ void ISR_Adv_motor() { if ( bandera_inicio == 1 ) { setPTO( 0 ); //detener el carro pin_dir = 0; //hacer que se aleje del motor stopTimer2(); //Deten el tren de pulsos setPTO( 20000 ); //Nueva frecuencia de salida startTimer2(); //Inicia el tren de pulsos wait_ms( 100 ); //Espera hasta llegar a la posicion stopTimer2(); //Posicion alcanzada ALTO. setPTO (0); // Detener el carro cuando este en posición valida wait_ms(100); //Encerar el contador de encoder y de velocidad encoder.Reset(QEI_RESET_POS); encoder.Reset(QEI_RESET_VEL); bandera_inicio = 0; //Limpiar la bandera // Envia un IN de proceso terminado if( isPC ) pc.printf("IN\r\n"); else RS_232.printf("IN\r\n"); } else{ if( isPC ) pc.printf("A1\r\n"); else RS_232.printf("A1\r\n"); } } int getMRvalue( int fout ) { int toRegister; toRegister = (24000000 /(fout*2.0) ) -1; return toRegister; } void setMR2( int newValue ) { LPC_TIM2->MR2 = newValue; // Las dos salidas son identicas LPC_TIM2->MR3 = newValue; // Para testear el programa. } void startTimer2() { // Arrancer el Timer 2 LPC_TIM2->TCR = 1; } void stopTimer2() { // Detener el Timer 2 LPC_TIM2->TCR = 0x2; } int getBaud() { int baudios = 115200; //Valor por defecto FILE *fp = fopen("/local/config.mbd", "r"); // Abre el archivo y lo guarda en fp if(!fp) // En caso de no encontrarse el archivo { printf("\nEl archivo /mbed/config.txt no puede ser abierto!\n"); printf("Cree un archivo de texto: config.mbd dentro de la unidad Mbed\n"); printf("que contenga las lineas:\n\n"); printf(" 1\n"); printf(" 2\n"); printf(" 3\n"); printf(" 4\n"); printf(" baudios: 115200\n"); printf("Cambie el valor de 115200 por la velocidad a la que desea transmitir:\n"); printf("luego reinicie el microcontrolador\n"); exit(1); } else { // Cadenas de caracteres desde el Archivo config.mbd char notstr [04]; // linea vacia char baud [40]; // valor en baudios // Leer linea a linea el archivo // cuatro primeras lineas no sirven fgets( notstr, 4, fp ); fgets( notstr, 4, fp ); fgets( notstr, 4, fp ); fgets( notstr, 4, fp ); fgets( baud, 40, fp ); fclose(fp); // Extraer los valores numericos sscanf( baud,"%*s %d",&baudios ); } return baudios; } // **** Funciones Liberia Ethernet ***** // void setPTO_eth( char * input, char * output ) { int freq = atoi( input ); if( freq != 0 ){ LPC_TIM2->TC = 0x00; // Resetear Timer setMR2( getMRvalue( freq ) ); // Cambiar frefuencia startTimer2(); // Iniciar Timer if( pin_alm == 0 ) { if ( limite_2 == 1 ) // Alarma muy cerca al encoder { sprintf( output,"A2\r\n" ); } if ( limite_3 == 1 ) // Alarma muy cerca al encoder { sprintf( output,"A1\r\n" ); } if ( limite_1 == 1 || limite_4 == 1 ) // ERROR DE POSICION { sprintf( output,"A0\r\n" ); } else sprintf( output,"OK\r\n" ); } else sprintf( output,"AL" ); }else{ stopTimer2(); LPC_TIM2->TC = 0x00; // Resetear Timer if( pin_alm == 0 ) { if ( limite_2 == 1 ) // Alarma muy cerca al encoder { sprintf( output,"A2\r\n" ); } if ( limite_3 == 1 ) // Alarma muy cerca al encoder { sprintf( output,"A1\r\n" ); } if ( limite_1 == 1 || limite_4 == 1 ) // ERROR DE POSICION { sprintf( output,"A0\r\n" ); } else sprintf( output,"OK\r\n" ); } else sprintf( output,"AL" ); } } void setANG_eth( char * input, char * output ) { long int pulsos = atol( input ); //Numero de pulsos a generar float pulsos_f = (float) pulsos; t_alto = pulsos_f / fq_posicion; //Tiempo que debe ser generado el tren de pulsos. stopTimer2(); //Deten el tren de pulsos setPTO( fq_posicion ); //Nueva frecuencia de salida startTimer2(); //Inicia el tren de pulsos wait( t_alto ); //Espera hasta llegar a la posicion stopTimer2(); //Posicion alcanzada ALTO. if( pin_alm == 0 ) { if ( limite_2 == 1 ) // Alarma muy cerca al encoder { sprintf( output,"A2\r\n" ); } if ( limite_3 == 1 ) // Alarma muy cerca al encoder { sprintf( output,"A1\r\n" ); } if ( limite_1 == 1 || limite_4 == 1 ) // ERROR DE POSICION { sprintf( output,"A0\r\n" ); } else sprintf( output,"OK\r\n" ); } else sprintf( output,"AL" ); } void setSPD_eth( char * input, char * output ) { fq_posicion = atoi( input ); // Esta funcion cambia la velocidad con la que se // posicionara el eje del motor en un angulo determinado if( pin_alm == 0 ) { if ( limite_2 == 1 ) // Alarma muy cerca al encoder { sprintf( output,"A2\r\n" ); } if ( limite_3 == 1 ) // Alarma muy cerca al encoder { sprintf( output,"A1\r\n" ); } if ( limite_1 == 1 || limite_4 == 1 ) // ERROR DE POSICION { sprintf( output,"A0\r\n" ); } else sprintf( output,"OK\r\n" ); } else sprintf( output,"AL" ); } void setAout_eth( char * input, char * output ) { int vout = atoi( input ); aout = (float)( vout + 10000 ) / 20000; if( pin_alm == 0 ) { if ( limite_2 == 1 ) // Alarma muy cerca al encoder { sprintf( output,"A2\r\n" ); } if ( limite_3 == 1 ) // Alarma muy cerca al encoder { sprintf( output,"A1\r\n" ); } if ( limite_1 == 1 || limite_4 == 1 ) // ERROR DE POSICION { sprintf( output,"A0\r\n" ); } else sprintf( output,"OK\r\n" ); } else sprintf( output,"AL" ); } void setDir_eth ( char * input, char * output ) { int value = atoi( input ); pin_dir = value; if( pin_alm == 0 ) { if ( limite_2 == 1 ) // Alarma muy cerca al encoder { sprintf( output,"A2\r\n" ); } if ( limite_3 == 1 ) // Alarma muy cerca al encoder { sprintf( output,"A1\r\n" ); } if ( limite_1 == 1 || limite_4 == 1 ) // ERROR DE POSICION { sprintf( output,"A0\r\n" ); } else sprintf( output,"OK\r\n" ); } else sprintf( output,"AL" ); } void setSON_eth ( char * input, char * output ) { int value = atoi( input ); pin_son = value; if( pin_alm == 0 ) { if ( limite_2 == 1 ) // Alarma muy cerca al encoder { sprintf( output,"A2\r\n" ); } if ( limite_3 == 1 ) // Alarma muy cerca al encoder { sprintf( output,"A1\r\n" ); } if ( limite_1 == 1 || limite_4 == 1 ) // ERROR DE POSICION { sprintf( output,"A0\r\n" ); } else sprintf( output,"OK\r\n" ); } else sprintf( output,"AL" ); } void getENC_eth( char * input, char * output ) { if( pin_alm == 0 ) { if ( limite_2 == 1 ) // Alarma muy cerca al encoder { sprintf( output,"A2\r\n" ); } if ( limite_3 == 1 ) // Alarma muy cerca al encoder { sprintf( output,"A1\r\n" ); } if ( limite_1 == 1 || limite_4 == 1 ) // ERROR DE POSICION { sprintf( output,"A0\r\n" ); } else sprintf( output,"OK\r\n" ); } else sprintf( output,"AL" ); } void setENC_eth( char * input, char * output ) { encoder.Reset(QEI_RESET_POS); encoder.Reset(QEI_RESET_VEL); if( pin_alm == 0 ) { if ( limite_2 == 1 ) // Alarma muy cerca al encoder { sprintf( output,"A2\r\n" ); } if ( limite_3 == 1 ) // Alarma muy cerca al encoder { sprintf( output,"A1\r\n" ); } if ( limite_1 == 1 || limite_4 == 1 ) // ERROR DE POSICION { sprintf( output,"A0\r\n" ); } else sprintf( output,"OK\r\n" ); } else sprintf( output,"AL" ); } void getRPM_eth( char * input, char * output ) { int rpm; rpm = encoder.CalculateRPM( encoder.GetVelocityCap(), 360); // ultima velocidad leida desde el encoder // numero de revoluciones por vuelta del encoder if( pin_alm == 0 ) { if ( limite_2 == 1 ) // Alarma muy cerca al encoder { sprintf( output,"A2\r\n" ); } if ( limite_3 == 1 ) // Alarma muy cerca al encoder { sprintf( output,"A1\r\n" ); } if ( limite_1 == 1 || limite_4 == 1 ) // ERROR DE POSICION { sprintf( output,"A0\r\n" ); } else sprintf( output,"OK\r\n" ); } else sprintf( output,"AL" ); } void setHOME_eth( char * input, char * output ) { int value = atoi( input ); pin_dir = 1; //Mover hacia el motor bandera_inicio = 1; // Informar a ISR_Adv_motor() acerca del Homing setPTO( value * 1000 ); // a la velocidad seteada en KiloHertzios if( pin_alm == 0 ) { if ( limite_2 == 1 ) // Alarma muy cerca al encoder { sprintf( output,"A2\r\n" ); } if ( limite_3 == 1 ) // Alarma muy cerca al encoder { if (bandera_inicio == 1) { sprintf( output,"IN\r\n" ); } sprintf( output,"A1\r\n" ); } if ( limite_1 == 1 || limite_4 == 1 ) // ERROR DE POSICION { sprintf( output,"A0\r\n" ); } else sprintf( output,"OK\r\n" ); } else sprintf( output,"AL" ); } void getALM_eth ( char * input, char * output ) { if( pin_alm == 0 ) { if ( limite_2 == 1 ) // Alarma muy cerca al encoder { sprintf( output,"A2\r\n" ); } if ( limite_3 == 1 ) // Alarma muy cerca al encoder { sprintf( output,"A1\r\n" ); } if ( limite_1 == 1 || limite_4 == 1 ) // ERROR DE POSICION { sprintf( output,"A0\r\n" ); } else sprintf( output,"OK\r\n" ); } else sprintf( output,"AL" ); } /* LEGACY FUNCTIONS * * El siguiente codigo no es utilizado por el * programa. Sin embargo pueden servir como * futuras referencias. */ void setMR3( int newValue ) { LPC_TIM2->MR3 = newValue; } void setPrescaler( int newValue) { LPC_TIM2->PR = newValue; } EthernetNetIf configurarEthernet() { //____________ *** ARCHIVO DE CONFIGURACION ***_______________________ // printf("\n *** CONFIGURACION ETHERNET DE MBED ***\n"); printf("Leyendo archivo de configuracion...\n\n"); FILE *fp = fopen("/local/config.txt", "r"); // Abre el archivo y lo guarda en fp if(!fp) // En caso de no encontrarse el archivo { printf("\nEl archivo /mbed/config.txt no puede ser abierto!\n"); exit(1); } else { // Cadenas de caracteres desde el Archivo config.txt char isDHCP [15]; //Modo Automatico o Manual char empty [2]; // Linea vacia char ip [40]; // Direccion IP char mask [40]; // Mascara de Subred char gate [40]; // Puerta de enlace char dns [40]; // Direccion DNS // Valores 'int' para agregar a la configuracion manual int DHCP; int n_ip[4]; int n_mask[4]; int n_gate[4]; int n_dns[4]; // Leer linea a linea el archivo fgets( isDHCP, 15, fp ); fgets( empty, 2, fp ); fgets( ip, 40, fp ); fgets( mask, 40, fp ); fgets( gate, 40, fp ); fgets( dns, 40, fp ); printf("Cerrando archivo...\n"); fclose(fp); // Extraer los valores numericos sscanf( isDHCP,"%*s %d",&DHCP ); sscanf( ip,"%*s %d.%d.%d.%d",&n_ip[0],&n_ip[1],&n_ip[2],&n_ip[3] ); sscanf( mask,"%*s %d.%d.%d.%d",&n_mask[0],&n_mask[1],&n_mask[2],&n_mask[3] ); sscanf( gate,"%*s %d.%d.%d.%d",&n_gate[0],&n_gate[1],&n_gate[2],&n_gate[3] ); sscanf( dns,"%*s %d.%d.%d.%d",&n_dns[0],&n_dns[1],&n_dns[2],&n_dns[3] ); if(DHCP) //En caso de modo DHCP { printf("\n Configurar red de manera automatica\n"); EthernetNetIf eth; //Crea la interfaz EthernetErr ethErr = eth.setup(); if( ethErr ) { printf( "Error %d en la configuracion\n", ethErr ); exit(1); } printf("Configuracion Correcta\n\n"); return eth; } else { sscanf( ip,"%*s %d.%d.%d.%d",&n_ip[0], &n_ip[1], &n_ip[2], &n_ip[3] ); sscanf( mask,"%*s %d.%d.%d.%d",&n_mask[0],&n_mask[1],&n_mask[2],&n_mask[3] ); sscanf( gate,"%*s %d.%d.%d.%d",&n_gate[0],&n_gate[1],&n_gate[2],&n_gate[3] ); sscanf( dns,"%*s %d.%d.%d.%d",&n_dns[0], &n_dns[1], &n_dns[2], &n_dns[3] ); printf(" %s %s %s %s %s\n " , isDHCP, ip, mask, gate, dns ); printf("\n Configurar red de manera manual\n"); EthernetNetIf eth( IpAddr( n_ip[0], n_ip[1], n_ip[2], n_ip[3]), //IP Address IpAddr( n_mask[0],n_mask[1],n_mask[2],n_mask[3]), //Network Mask IpAddr( n_gate[0],n_gate[1],n_gate[2],n_gate[3]), //Gateway IpAddr( n_dns[0], n_dns[1], n_dns[2], n_dns[3] ) //DNS ); EthernetErr ethErr = eth.setup(); if( ethErr ) { printf( "Error %d en la configuracion\n", ethErr ); exit(1); } printf("Configuracion Correcta\n\n"); return eth; } } EthernetNetIf eth; return eth; }