test

main.cpp

Committer:
dapi08
Date:
2020-05-27
Revision:
3:55227f9877e0
Parent:
2:82fdfeec5799
Child:
4:7564d0ffd595

File content as of revision 3:55227f9877e0:

#include "declaraciones.h"
#include "EthernetInterface.h"
#include "gps.h"

#define IP         "192.168.1.247"
#define GATEWAY    "192.168.1.1"
#define MASK       "255.255.255.0"

 
// Network interface
EthernetInterface net;


//GPS gps(PC_10, PC_11, PF_8);

// CANALES DE COMUNICACION
Serial pc(SERIAL_TX, SERIAL_RX, 115200);
Serial serGPS(PC_10, PC_11, 9600);
RawSerial serSERVO(PC_12, PD_2, 115200);
Serial serRS485(PD_5, PD_6, 115200);

// SALIDAS PARA LEDS
DigitalOut led1(LED1, 0);               //LED1
DigitalOut led2(LED2, 0);
DigitalOut led3(LED3, 0);

// SALIDAS DE CONTROL COMUNICACIONES
DigitalOut RS485_DIR(PE_3, 0);          //DIR RS485 a RX
DigitalOut RS485_OE(PF_7, 0);           //OE RS485 a tri-state

// SALIDAS PARA CONTROL DEL SERVO
DigitalOut control_PWR_servo(PF_9, 1);  // Alimentacion del inverter para 220V del servo
DigitalOut SERVO_ON(PG_1, 0);           // Salida de control ON del servo (J7-2)
DigitalOut SERVO_CLR_COUNT(PG_0, 0);    // Salida de control CLR_COUNT del servo (J7-1)
DigitalOut SERVO_ALARM_CLR(PF_0, 0);    // Salida de control ALARM_CLR del servo (J7-4)
DigitalOut SERVO_CONTROL_MODE(PC_6, 0); // Salida de control CONTROL_MODE del servo (J7-3)
DigitalOut SERVO_INC_POS(PB_10, 0);     // Salida de control INC_POS del servo (J1-2)
DigitalOut SERVO_DEC_POS(PB_11, 0);     // Salida de control DEC_POS del servo (J1-3)
DigitalOut SERVO_AUX_OUT(PA_15, 0);     // Salida de control AUX_OUT del servo (J7-10)

// ENTRADAS DE ESTADO DEL SERVO
DigitalIn SERVO_RDY_IN(PF_13);          //Entrada desde SERVO_RDY, 1=activa;
DigitalIn SERVO_AL_IN(PE_9);            //Entrada desde SERVO_AL, 1=activa;
DigitalIn SERVO_POS_IN(PE_11);          //Entrada desde SERVO_POS, 1=activa;
DigitalIn SERVO_TORQ_L_IN(PF_14);       //Entrada desde SERVO_TORQ_L, 1=activa;
DigitalIn SERVO_Z_SPEED_IN(PE_13);      //Entrada desde SERVO_Z_SPEED, 1=activa;
DigitalIn SRV_D_VEL(PF_2);              //Entrada desde SERVO signo nivel de velocidad 1=positivo
DigitalIn SRV_D_TRQ(PF_1);              //Entrada desde SERVO signo nivel de torque 1=positivo

// ENTRADAS DEL SELECTOR
DigitalIn SEL0(PC_8);                   //Selector 1 = BABOR/ESTRIBOR, ON(0)=BABOR OFF(1)=ESTRIBOR
DigitalIn SEL1(PC_9);                   //Selector 2
DigitalIn SEL2(PG_2);                   //Selector 3
DigitalIn SEL3(PG_3);                   //Selector 4

// SALIDAS PWM
PwmOut SRV_C_TRQ_P(PD_13);              // Salida PWM para control del torque POSITIVO del SERVO
PwmOut SRV_C_TRQ_N(PA_0);               // Salida PWM para control del torque NEGATIVO del SERVO

// ENTRADAS ANALOGICAS
AnalogIn SRV_VEL(PA_3);                 // Entrada analogica de VELOCIDAD del servo
AnalogIn SRV_TRQ(PC_0);                 // Entrada analogica de TORQUE del servo


// ENTRADAS GENERALES
DigitalIn pulsador(PC_13);              //Pulsador de usuario, 1=pulsado;



// VARIABLES DE SISTEMA
volatile unsigned long tiempo_ms = 0;
volatile bool f_ms = false;             // se pone en cada interrupcion de ms


long t_ult_recepcion;   // guarda tiempo ultima recepción
byte nMando;            // numero de mando 0=babor 1=estribor
int servo;              // servo recibido en ultima comunicacion
volatile float latitud;
volatile float longitud;
volatile long fecha_hora;
volatile int n_satelites;
volatile float HDOP;
volatile int rumbo;
volatile int velocidad;  // MNPH
volatile int timon_babor;
volatile int timon_estribor;
volatile enEstadoDireccion estado_direccion;
volatile byte EstadoAnteriorServo;       //Guarda estado anterior del servo para salir de piloto-automatico o rumbo
volatile byte estado_otro_servo;         // Estado del otro servo
volatile int retardoActualizacion;       // para no visualizar estado durante este tiempo en ms
volatile bool act_display;               // flag para actualizar display
volatile bool trama_estado_valida;
volatile bool trama_posicion_valida;

// VARIABLE CONTROL SERVO
enEstadoServo estado_servo;
int16_t velocidad_servo;
int16_t torque_servo;
long desviacion_servo;
volatile int pos_actual_servo = 0;
volatile int pos_objetivo_servo = 0;
volatile unsigned long tempo_espera = 0;

int torque_max;                 // torque máximo calculado
int out_torque = TORQUE_MINIMO; // nivel de torque de TORQUE_MINIMO a TORQUE_MAXIMO

int cons_timon_babor = 0;       // consigna % de timon babor bajado
int cons_timon_estribor =  0;   // consigna % de timon estribor bajado

float diferencia_rumbo = 0.0;   // Diferencia al Rumbo deseado

st_datos_servo datos_servo;       // ESTRUCTURA DE VARIABLES DE ESTADO DEL SERVO DE DIRECCION
st_datos_GPS datos_GPS;           // ESTRUCTURA DE DATOS DE ESTADO DEL GPS


// VARIABLES CONFIGURACION DESDE ORDENADOR
int cfg_hora = 7200;  // Suma dos horas a UTC


// VARIABLES GENERALES
float ana_velocidad = 0.0;
float ana_torque = 0.0;
bool newtime = false;
ntp_packet in_data;         // para recibir fecha y hora del servidor

// VARIABLES DE COMUNICACION RS485
volatile bool f_rs485_busy = false;             // comunicacion ocupada
volatile bool recibidoEstadoServo = false;      //Si ha recibido estado del otro servo se pone a true para sincronizacion


// TIMERS
Timer timer;
Ticker millis;          // Interrupcion para cuenta de milisegundos
Ticker tickRS485us;     // Interrupcion de 100us para com rs485
Timer timerRS485;       // Timer para sincronizacion por rs485 de los mandos







// RUTINAS

// CUENTA MILISEGUNDOS DESDE RESET
void cuenta_ms() {
    tiempo_ms++;
    posicion_servo();        // AJUSTA POSICION SERVO SI ES NECESARIO
    f_ms = true;             // se pone en cada interrupcion de ms
}




/*
/////////////////////////////////////////////////////////
// PROCESA RECEPCION DESDE SERIAL SERVO
void onSerialServo(void){  // Procesa recepcion SERVO

    while (serSERVO.readable()) {
        char c = serSERVO.getc();
//        pc.putc(c);
    }
}
*/





#define FACTOR_INC_RUMBO_BABOR    0.015
#define FACTOR_INC_RUMBO_ESTRIBOR 0.015

// PARA SIMULACION
// Pocesa rumbo_GPS, llamada cada 250ms
void  procesa_rumbo_GPS(void){

    datos_servo.rumbo -= datos_servo.timon_babor * FACTOR_INC_RUMBO_BABOR;
    datos_servo.rumbo += datos_servo.timon_estribor * FACTOR_INC_RUMBO_ESTRIBOR;
    //    datos_servo.rumbo = flimit_decimales(datos_servo.rumbo, 2);
    if(datos_servo.rumbo>360.0){
        datos_servo.rumbo -= 360.0;
    }
    else if(datos_servo.rumbo<0.0){
        datos_servo.rumbo += 360.0;
    }
}



/////////////////////////////////////////////////////////
// PROGRAMA PRINCIPAL 
int main() {
int nc=0; 
char out_buffer_2[50];
static int posicion_mando_old = 0;


    // Bring up the ethernet interface
    pc.printf("\r\n\r\n");
    pc.printf("RESET\r\n\r\n");
    pc.printf("PROGRAMA CONTROL SERVO V0.1\r\n");
    pc.printf("CONTROL DE SERVO DE ");
    if(SEL0.read()==0)  // Si es servo de babor = 0
        pc.printf("BABOR\r\n");
    else
        pc.printf("ESTRIBOR\r\n");
    


    // Open Ethernet connection
    int c=0;
    do{
        net.disconnect();
        wait(2.0);     // espera de 1s
        int j = net.set_network(IP, MASK, GATEWAY);
        printf("set IP status: %i\r\n", j);

        c=net.connect();
        if(0 != c) {
            printf("Error connecting\r\n");
    //        return -1;
        }
    }while(c != 0);
 
    // Show the network address
    const char *ip = net.get_ip_address();
    printf("IP address is: %s\r\n", ip ? ip : "No IP");

    Thread t; // can pass in the stack size here if you run out of memory
    t.start(&udp_main);

     
    // Inicializa datos_servo ESTRUCTURA DE VARIABLES DE ESTADO DEL SERVO DE DIRECCION
    datos_servo.n_servo = SEL0.read();
    datos_servo.estado = 0;
    datos_servo.latitud = 0.0;
    datos_servo.longitud = 0.0;
    datos_servo.fecha_hora = 0;
    datos_servo.velocidad = 0.0;          // MNPH
    datos_servo.rumbo = 0.0;
    datos_servo.ch_radio = 0;
    datos_servo.trim_timon_bab = 0;
    datos_servo.trim_trans_bab = 6;
    datos_servo.trim_timon_estr = 0;
    datos_servo.trim_trans_estr = 6;
    datos_servo.timon_babor = 0;          // %de timon babor bajado, para 100% 5s, 1% = 50ms
    datos_servo.timon_estribor = 0;       // %de timon estribor bajado, para 100% 5s
    datos_servo.rumbo_fijado = 0.0;       // Rumbo fijado al pulsar botón para RUMBO FIJO
    datos_servo.rumbo_piloto_auto = 0.0;  // Rumbo fijado por piloto automático
    
    // Set handler to be called when UDP socket event occurrs.
    // sock.attach(&onUDPSocketEvent);

    timer.start();
    millis.attach(&cuenta_ms, 0.001);               // the address of the function to be attached (cuenta_ms) and the interval (1 miliseconds)
    tickRS485us.attach(&SerialTxRS485, 0.0001);     // Interrupcion de 100us para comunicaciones por RS485 con mando
    timerRS485.start();                             // Timer para sincronizacion desde recepcion del otro control servo

    led1 = led2 = led3 =1;
    wait(0.5);
    led1 = led2 = led3 =0;

//    serSERVO.attach(&onSerialServo);  // Interrupcion de serial Servo
//    serRS485.attach(&onSerialRxRS485, RxIrq);  // Interrupcion de RX serial RS485 (MANDOS)
//    serRS485.attach(&onSerialTxRS485, Serial::TxIrq);  // Interrupcion de TX serial RS485 (MANDOS)

    serGPS.attach(&onSerialGPS);      // Interrupcion de serial GPS

    RS485_OE = 1;   // habilita conversor 3.3V a 5V para RS485

/*
    SRV_C_TRQ_P.period(0.001f);          // 1 kHz or 1 ms
    SRV_C_TRQ_N.period(0.001f);          // 1 kHz or 1 ms
    SRV_C_TRQ_P=0;
    SRV_C_TRQ_N=0;
*/

    SERVO_ON = 1;       // Pone servo en ON
   
//    uint8_t i=0;

//    SetDateTime(2020, 4, 25, 10, 00, 0);   // Actualiza hora del RTC
//    ShowDateTime();
    
    while(1){
        
        while(f_ms!=true);     // espera interrupcion de 1 ms
        f_ms = false;

        procesaGPS();          // Comprueba trama pendiente de GPS y la procesa

        if(datos_servo.estado == DIR_MASTER || datos_servo.estado == DIR_REPOSO)
            datos_servo.posicion_mando = desviacion_servo;
        else
            datos_servo.posicion_mando = pos_objetivo_servo;  // PARA PILOTO AUTOMATICO
        
        if(datos_servo.posicion_mando != posicion_mando_old){ // Si cambia la posicion del mando envia trama
            if(abs(desviacion_servo) >= 50 && datos_servo.estado == DIR_REPOSO && estado_otro_servo == DIR_REPOSO){
                datos_servo.estado = DIR_MASTER;
            }
        
            if(datos_servo.estado == DIR_MASTER || datos_servo.estado == DIR_RUMBO || datos_servo.estado == DIR_PILOTO)
                envia_posicion_mando(datos_servo.posicion_mando);
            posicion_mando_old = datos_servo.posicion_mando;
        }
            
        // PROCESA CADA SEGUNDO
        if(((tiempo_ms+500)%1000)==0){     // Envia cada segundo

//            getTime();

//            SetDateTime(2020, 4, 25, 10, 00, 0);   // Actualiza hora del RTC
//            ShowDateTime();
//            pc.printf("tiempo_ms:%d\r\n", tiempo_ms);
            
//                pc.printf("RDY:%u AL:%u POS:%u TORQ_L:%u Z_SPEED:%u \r\n", SERVO_RDY_IN.read(), SERVO_AL_IN.read(), SERVO_POS_IN.read(), SERVO_TORQ_L_IN.read(), SERVO_Z_SPEED_IN.read());
//            pc.printf("velocidad:%3.3f torque:%3.3f fix:%d satelites:%s\r\n", ana_velocidad, ana_torque, gps.have_fix, gps.NmeaGpsData.NmeaSatelliteTracked);

//            procesa_servo();                       // lee estado del servo, procesa torque y actualiza
//            envia_posicion_mando(datos_servo.posicion_mando);

//            printf("tiempo_ms=%d pos_objetivo_servo=%d SEL0=%d ESTADO=%d\r\n", tiempo_ms, pos_objetivo_servo, SEL0.read(), datos_servo.estado);
        }

/*
        //PROCESO CADA 10ms
        if((tiempo_ms%10) == 0){
            ana_velocidad = SRV_VEL.read(); // 1.0=VCC, lee entradas analogicas
            ana_torque = SRV_TRQ.read();
            SRV_C_TRQ_P.pulsewidth(ana_velocidad*0.001f);   // Ajusta PWM de salida DAC
            SRV_C_TRQ_N.pulsewidth(ana_torque*0.001f);
        }
*/
        //PROCESO CADA 100ms
        if((tiempo_ms%100) == 0){
//            procesa_rumbo_GPS();            // SIMULA RUMBO SEGUN TIMON PARA GPS
//            procesa_posicion_timones();   // Pocesa activación y posición timones, llamada cada 100ms
        }

        //PROCESO CADA 250ms
        if((tiempo_ms%250) == 0){
            procesa_servo();                // lee estado del servo, procesa torque y actualiza
            procesa_posicion_timones();     // Pocesa activación y posición timones, llamada cada 250ms
            actualiza_timones();            // ACTUALIZA TIMONES
            procesa_rumbo_GPS();            // SIMULA RUMBO SEGUN TIMON PARA GPS
        }

        if(recibidoEstadoServo==true){            //Si ha recibido estado del otro servo está a true para sincronizacion
            if(timerRS485.read_ms()>=110){
                envia_estado_mando();
                recibidoEstadoServo = false;
                timerRS485.reset();
            }
        }
        else{
            int espera = (SEL0.read()==0)? 240 :260;
            if(timerRS485.read_ms()>=espera){      // Si es servo de babor = 240ms, estribor = 260ms, evita colision
                envia_estado_mando();
                timerRS485.reset();
            }
        }

//        control_PWR_servo =  (pulsador.read() == 1)?0:1;
        control_PWR_servo = 0;  // encendido
        
        // PROCESO CADA 10 SEGUNDOS         
        if((tiempo_ms%10000)==0){

/*
            if(pos_objetivo_servo == 0){
                pos_objetivo_servo = 200;
                escribe_parametro_servo(0, 13, TORQUE_MAXIMO);
                }
            else if(pos_objetivo_servo == 200){
                pos_objetivo_servo = -200;
                escribe_parametro_servo(0, 13, TORQUE_MAXIMO);
                }
            else if(pos_objetivo_servo == -200){
                pos_objetivo_servo = 0;
                escribe_parametro_servo(0, 13, TORQUE_MINIMO);
                }
 //           printf("\r\n\r\npos_objetivo_servo=%d\r\n\r\n",pos_objetivo_servo);
 */
        }

//        Thread::wait(10000);
    }

    return 0;
}