Autor Tema: submarino RC // un sueño de toda la vida  (Leído 8265 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado japifer_22

  • PIC18
  • ****
  • Mensajes: 405
submarino RC // un sueño de toda la vida
« en: 27 de Abril de 2010, 12:12:25 »
Hola gente otra vez, bueno estoy aquí porque hace un tiempo atrás que empecé con este tema de mi primer submarino RC, el cual avía dejado votado hasta ahora.
La idea de este submarino es hacer que tengas las características idénticas o casi idénticas a un submarino real.
Yo empecé hace como 6 meses atrás la construcción de él, pero solo el aspecto mecánico, (el cual mostrare fotos) y creo yo ahora que he terminado esto y me toca ponerle la electrónica, es por eso que acudo acá para debatir cual sería lo más apropiado para este mismo. El modelo que estoy asiendo tengo la duda si controlarlo mediante un PC por cable ó por control remoto, el cual tengo varios pero el designado seria uno de 4 canales hitec attack-4.
La ventaja de controlarlo por cable es que no tengo que estar preocupado que lo allá sumergido mucho por perdida de seña. Además que el modelo según yo debería sumergiré a una profundidad máxima de unos 25 mts sin problemas.
Por otra parte por medio del control RC me brinda una mayor maniobrabilidad del modelo, pero con la desventaja que estaría limitado a una profundidad de unos 2 a 3 mts de profundidad y con el peligro que se pierda la señal de emisor.
Además de esto tengo que controlar varias cosas:
1-Lastre principal: en este tengo que manejar 4 cosas por lo mínimo las cuales son:
 *-electro válvula de ingreso de agua
*-  bomba de agua para llenar el lastre principal
*- bomba de agua para sacar el agua del lastre principal
*- medidor de nivel de agua al interior del lastre principal
2-lastres de estabilización: en este son 2 lastres a pistón el cual se encarga de mantener siempre el submarino en una posición horizontal
3-sensor que me indique la posición del submarino ya sea vertical o horizontal
4- control del motor de propulsión (este con inversión de giro mas una aceleración de 0 a 100%)
5- control del estabilizador
6- control del timón
Mm bueno creo que no se me queda nada, como verán es un proyecto ambicioso, pero muy lindo.
y bueno reitero que me gustaría que me orienten  con respecto a la electrónica y si quieren en lo mecánico si es que se me ha escapado algo.
En otro post pongo las fotos para que vean como me está quedando esto.

Desconectado Miquel_S

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1251
Re: submarino RC // un sueño de toda la vida
« Respuesta #1 en: 27 de Abril de 2010, 12:33:38 »
Hola japifer_22, sin duda un proyecto de envergadura,  porque creeme para empezar no es facil meter todo esto en un tubo que pueda soportar la presion del agua sin que entre y lo fastidie todo.
Seguire atentamente el proyecto te lo aseguro.

 Saludos

 Miquel_S
Todos somos muy ignorantes. Lo que ocurre es que no todos ignoramos las mismas cosas.

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: submarino RC // un sueño de toda la vida
« Respuesta #2 en: 27 de Abril de 2010, 13:37:20 »
Hola.

Suena muy interesante. Creo que seria mejor hacerlo por RF no? queda mejor ... respecto a los temores, pues .. se podría hacer que cuando el receptor pierda señal, inmediatamente suba ... de esa manera no pierdes lo hecho  :mrgreen:

Lo del agua si que es un lío, pero con unos buenos empaques y a presión de tonillo, creo que se puede lograr impermeabilizarlo.

Saludos
El papel lo aguanta todo

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: submarino RC // un sueño de toda la vida
« Respuesta #3 en: 27 de Abril de 2010, 13:48:29 »
Efectivamente, cuando pierdas la señal RF, mételo en un ciclo de emersión y con una alarma que pite para facilitar su localización.

A ver si nos enseñas las fotos.

Desconectado japifer_22

  • PIC18
  • ****
  • Mensajes: 405
Re: submarino RC // un sueño de toda la vida
« Respuesta #4 en: 27 de Abril de 2010, 17:48:32 »
hola aqui estan las fotos de la parte interior del submarino.
















Desconectado japifer_22

  • PIC18
  • ****
  • Mensajes: 405
Re: submarino RC // un sueño de toda la vida
« Respuesta #5 en: 27 de Abril de 2010, 22:52:43 »
hola pensando en lo que me dijeron, decidí que lo voy a hacer mediante RF la maniobrabilidad del submarino, pero como quiero usar un radio que tiene solo 4 canales, lo que pensé es ponerle al receptor un pic para tomar estos 4 canales del receptor y aumentar los canales del receptor. esto se me ocurre asiendo qué los 2 joystikc del emisor (las 2 palancas) sacar 4 canales para servos (bueno esto es lo que hace el receptor ),pero también usar los 4 strick del control, como 4 canales más del emisor/receptor. ósea dejar estos en su limite máximo, y cuando se deje a mínimo me genera un pulso en alguna de las salidas del pic, para activar algún elemento. para mi caso estaba viendo que con los 4 canales ya casi tengo todo (esto el control del submarino nada mas, el resto de la lógica es interna del submarino) solo me faltaría 1 más para activar la reversa del modelo , y esto lo quiero hacer mediante un strick del control. ósea mi primer joystick es para controlar el timón y el elevador, y el segundo joystick es para controlar la inmersión del modelo más la propulsión, pero esta ultima al estar en el límite inferior la palanca se para el motor de propulsión y sí se mueve el strick a su lado opuesto activa la reversa del motor de propulsión (este strick es el mismo que controla la aceleración).
saludos!


Desconectado japifer_22

  • PIC18
  • ****
  • Mensajes: 405
Re: submarino RC // un sueño de toda la vida
« Respuesta #7 en: 28 de Abril de 2010, 18:07:48 »
hola nocturno, gracias pero ya lo avia visto, de todas formas alguna duda que tenga la pongo aca y ademas voy a ir poniendo los avances que haga. saludos que esten bien.

Desconectado japifer_22

  • PIC18
  • ****
  • Mensajes: 405
Re: submarino RC // un sueño de toda la vida
« Respuesta #8 en: 16 de Mayo de 2010, 18:20:04 »
hola otra vez, les comento que tengo lista la electrónica, pero ahora quiero más.
vamos por partes dijo jack el destripador.
la electrónica que he elaborado en base al pic 16f877a, controla lo siguiente:

1- controla la propulsión del submarino, por medio de uno de los joystick del control RC (TX), ósea toma la señal de receptor RC, y controla el avance o el retroceso del submarino, el avance lo hago por medio del joystick, del canal 3 del servo y el retroceso lo hago por medio de su strick con una señal de PWM de 20KHz, conectado a un puente H.

2-controla 2 lastre a pistón, los cuales están encargado de la estabilización del submarino.
al encender el submarino el programa lleva a estos 2 lastres a pistón hasta su final de recorrido, esto para llenar las mangueras de agua y sacar el aire que pudieran quedar en estas, luego regresan al 50% de su recorrido, para luego verificar si esta en equilibrio el submarino, (esto lo hago por medio de un péndulo conectado a un potenciómetro) si no está en equilibrio se mueven los lastres hasta dejar en equilibrio el submarino (siempre se mueven en sentido contrario, ósea uno saca el agua y el otro ingresa agua (recordar que estaban en un principio al 50% cada lastre)). esto de igual forma van conectado a puentes H.

3-el lastre principal lo controla un servo que está sujeto a su receptor, en conjunto con la electroválvula.

4- el timón y el estabilizador está controlado de igual forma por el receptor y 2 servos.

pero ahora quiero más. porque quiero controlar el lastre principal con el pic y no con el receptor, es por esto que quiero enviar otra señal del receptor al pic, pero en esta no sé como detectarla, pensaba en hacerlo por medio de la interrupción RB, ósea controlar la propulsión y la inmersión con el pic, pero esto activado con las señales del control RC al receptor, y este al pic, porque aparte de querer controlar la inmersión quiero ponerle un sistema de seguridad por si se me va la señal del receptor, asiendo que el pic tome control del submarino y lo saque a flote. pero el problema que tengo es que estoy teniendo problemas con los timer, que son los que me cuentan el tiempo en alto de esta señal. e visto los ejemplos que a puesto REDPIC en el hilo midiendo un puso parte 1, 2 y 3. donde en este saque una parte para medir la señal del receptor que comanda la propulsión, pero como digo ahora tengo problemas para medir 2 señales del receptor.

Código: [Seleccionar]
#include <16F877a.h>
#device adc=10      // Conversión con 10 bits
#FUSES NOWDT, HS, NOPUT, NOPROTECT, BROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=4000000)
#define use_portd_lcd TRUE //definir portb lcd
#include<lcd.c> //libreria manejo lcd de 20x4 modificada por suky para el puerto D
#use standard_io(A)
#use standard_io(C)
#use standard_io(E)

////////////////////////////////////////////////////////////////////////////////////
//
// Defines de funciones
//
////////////////////////////////////////////////////////////////////////////////////

void lastre_piston(void);
void inclinasion_submaniro(void);


////////////////////////////////////////////////////////////////////////////////////
//
// Defines y Constantes
//
////////////////////////////////////////////////////////////////////////////////////


float const uSxTick = 0.1;                  // Microsegundos por Tick de TMR1 a 4 Mhz

////////////////////////////////////////////////////////////////////////////////////
//
// Variables en RAM
//
////////////////////////////////////////////////////////////////////////////////////

int1  flagToggleFlanco=0;                   // Flag para cambiar de flanco
int16 t1=0x00,t2=0x00,tt=0x00;              // Variables para guardar estados de ...
float st=0.0;                               // TMR1 en cada flanco y hacer la resta
int1  flagHayDatos=0;                       // Flag para indicar que ya hay datos de ..
                                            // dos flancos (de subida y bajada)
int1  flagHayTransmitir=0;                  // Flag para indicar que hay datos para ...
                                            // Transmitir al PC.
int16 a;                                    //variables para el PWM
float b;
int k=0,m=0;

float const uSxTick1 = 0.1;                  // Microsegundos por Tick de TMR1 a 4 Mhz
int1  flagToggleFlanco1=0;                   // Flag para cambiar de flanco
int1  flagHayDatos1=0;                       // Flag para indicar que ya hay datos de ..                                           // dos flancos (de subida y bajada)
int1  flagHayTransmitir1=0;                  // Flag para indicar que hay datos para ...
int16 t11=0x00,t21=0x00,tt1=0x00;              // Variables para guardar estados de ...
float st1=0.0;                               // TMR1 en cada flanco y hacer la resta
int  estado_portb_anterior=0;
int  estado_portb_actual=0;
int1 hay_flanco_de_bajada=0;                                         
////////////////////////////////////////////////////////////////////////////////////
//
// Interrupción por Externa por Cambio de Flanco en RB0
//
////////////////////////////////////////////////////////////////////////////////////

#int_ext
void handle_ext_int(){

   if(flagToggleFlanco==0){                 // He recibido Flanco de Subida
     
      t1=get_timer1();                      // Guardo en t1 el valor de TMR1 al Flanco de Subida
      ext_int_edge(0,H_TO_L);               // Configuro para capturar siguiente flanco de Bajada
      flagToggleFlanco=1;                   // Indico que el siguiente flanco será de Bajada

   } else {                                 // He recibido Flanco de Bajada

      t2=get_timer1();                      // Guardo en t2 el valor de TMR1 al Flanco de Bajada
      ext_int_edge(0,L_TO_H);               // Configuro para capturar siguiente flanco de subida
      flagToggleFlanco=0;                   // Indico que el siguiente flanco será de Subida
      set_timer1(0);                        // Reinicio TMR1
      if(flagHayDatos==0){                  // Si los datos anteriores han sido procesados ...
         flagHayDatos=1;                    // Indico que ya hay nuevos datos de flancos para calcular
      }
   }
}

////////////////////////////////////////////////////////////////////////////////////
//
// Interrupción por Externa por Cambio de Flanco en RB4
//
////////////////////////////////////////////////////////////////////////////////////

#int_rb
void handle_rb_int(){

  estado_portb_actual=input_b();
  if ((!bit_test(estado_portb_anterior,4))&&(bit_test(estado_portb_actual,4)))
  {
    hay_flanco_de_bajada=0;
  }
 
  if(hay_flanco_de_bajada!=0){             // He recibido Flanco de Subida
     t11=get_timer2();                      // Guardo en t1 el valor de TMR2 al Flanco de Subida
  } else {                                 // He recibido Flanco de Bajada
     t21=get_timer2();                      // Guardo en t2 el valor de TMR2 al Flanco de Bajada
     set_timer1(0);                        // Reinicio TMR2
     if(flagHayDatos1==0){                  // Si los datos anteriores han sido procesados ...
        flagHayDatos1=1;                    // Indico que ya hay nuevos datos de flancos para calcular
     }
  }
}

void main() {
 
  lcd_init();                             //inicializa lcd

    ////////////////////////////////////////// INICIALIZACIONES GENERALES

   delay_ms(333);                           // Espero a que todo se estabilice e ...
   disable_interrupts(global);              // Inicializo el Micro y ...
   disable_interrupts(int_timer1);          // deshabilitando todo lo no necesario ...
   disable_interrupts(int_timer2);          // deshabilitando todo lo no necesario ...   
   disable_interrupts(int_ext);
   disable_interrupts(int_rb);   
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
   setup_timer_2(T2_DISABLED,0,1);
   delay_ms(333);

   /////////////////////////////////////////// INICIALIZACIONES PERTINENTES A LA APLICACION
   
                                           
   ext_int_edge(0,L_TO_H);                  // Configuro captura de 1er flanco de subida
   flagToggleFlanco = 0;                    // inicializo el Flag para cambiar de flanco

   set_tris_b(0b00010011);                  // Habilito como entrada RB7 para interrupción RB
   enable_interrupts(int_rb);
   enable_interrupts(int_ext);
   enable_interrupts(global);

   setup_ccp1(CCP_PWM);                     //ccp1 modo PWM
   setup_timer_2(T2_DIV_BY_1, 49, 1);

  // Configuramos entradas analogicas:
   setup_adc_ports(AN0);
   setup_adc(ADC_CLOCK_INTERNAL);
  // Tomamos las medidas
  set_adc_channel(0);
   
   output_low(PIN_C3);
   output_low(PIN_C4);
  // lastre_piston();
   
   a=20;   // punto medio del duty de 10 bits
   set_pwm1_duty(a);//duty cycle con una variable para variar el PWM

   do {
   if(k==1 && m==1){
   inclinasion_submaniro();
   }
   
      if(flagHayDatos==1){                  // Detecto que ya hay datos de flancos ...
         if(t2 > t1){                       // Compruebo que estoy en la misma vuelta de TMR1
            tt = t2 - t1;                   // Calculo en Tick's de TMR1 el tiempo entre flancos
            st = uSxTick * tt;              // Calculo en uS el tiempo.
            flagHayTransmitir=1;            // Indico que tengo nuevo valor para transmitir
         }
         flagHayDatos=0;                    // Indico que ya han sido procesados los datos.
      }
     
      if(flagHayDatos1==1){                  // Detecto que ya hay datos de flancos ...
         if(t21 > t11){                       // Compruebo que estoy en la misma vuelta de TMR1
            tt1 = t21 - t11;                   // Calculo en Tick's de TMR1 el tiempo entre flancos
            st1 = uSxTick1 * tt1;              // Calculo en uS el tiempo.
            flagHayTransmitir1=1;            // Indico que tengo nuevo valor para transmitir
         }
         flagHayDatos1=0;                    // Indico que ya han sido procesados los datos.
      }     
     

      set_pwm1_duty(a);//duty cycle con una variable para variar el PWM
     
   /////////////////////////////////////////// COMANDO PARA VARIAR EL PWM
   b=a;
   lcd_gotoxy(1,1);
   printf(lcd_putc,"PWM=%f",b);
   lcd_gotoxy(1,2);
   printf(lcd_putc,"Ticks =%3.1fuS",st);

   if(st>=107.4 && st<=174){
   output_high(PIN_C3);
   a=((175-st)*2.96)+1;
   }
   else{
   output_low(PIN_C3);
        }
   
   if(st>=180 && st<=196.8){
   output_high(PIN_C4);
   a=((st-180)*(198/16))+1;
   }
   else{
   output_low(PIN_C4);
   }     

////////////////////////////////////////////////////////////////////////////////////
// control de inmercion submarino comandado por receptor
////////////////////////////////////////////////////////////////////////////////////
   if(st1>=107.4 && st1<=174){
   output_high(PIN_A4);
   }
   else{
   output_low(PIN_A4);
        }   
   } while (TRUE);                     //...CICLO INFINITO...........
}

////////////////////////////////////////////////////////////////////////////////////
//
// Funcion para poner lastres a piston a su 50% de su recorrido
//
////////////////////////////////////////////////////////////////////////////////////

void lastre_piston(void){           

////////////////////////////////////////////////////////////////////////////////////
//
// Variables en RAM
//
////////////////////////////////////////////////////////////////////////////////////
int h=0,i=0,z=0,x=0;
float g=0,j=0;

while(TRUE){

////////////////////////////////////////////////////////////////////////////////////
// Control lastre 1
////////////////////////////////////////////////////////////////////////////////////

if(input(PIN_E1) && h==0){                          //detecta que no este a su 100% el recorrido del piston
                          output_high(PIN_B6);      //activo la reversa del piston para dejarlo al 100% del recorrido (puente H)
                          output_low(PIN_B7);       //desactivo el avance del piston para que retroceda (puente H)
}
else if(!input(PIN_E1) && h==0){                    //detecta que el piston esta al 100% del recorrido...
                                g=2292;             //pulsos que generado al 100% del recorrido por C0
                                h=1;                //vandera para poner el piston al 50% de su recorrido
                                output_low(PIN_B6); //desactivo la reversa del piston (puente H)
                                output_low(PIN_B7); //desactivo el avance del piston (puente H)
                                delay_ms(100);      //tiempo de espera antes de poner el piston al 50%
}
if(h==1 && g>1146){                                 //detecta que el piston todavia es mayor al 50% de su recorrido
                   output_low(PIN_B6);              //desactivo la reversa del piston (puente H)
                   output_high(PIN_B7);             //activo el avance del piston para dejarlo al 50% (puente H)
if(!input(PIN_C0)){                                 //contador de pusos invalidos y tiempo presionado el boton
                   z++;                             //contador de revotes                                       
                  }
else{                                               //se solto el boton de conteo
if(z>0){ g=g-1;                                     //decremento g para saver cuando llega al 50% (1146) el piston
        z=0;
        }
}

}
else if(h==1 && g<=1146){                           //detecta que el piston esta al 50% y desactiva el puente H
                         output_low(PIN_B6);        //desactivo la reversa del piston (puente H)
                         output_low(PIN_B7);        //desactivo el avance del piston (puente H)
                         k=1;                       //vandera que indica que el lastre esta a 50%
}
   lcd_gotoxy(1,1);
   printf(lcd_putc,"M1 %f  %i",g,h);
   
////////////////////////////////////////////////////////////////////////////////////
// Control lastre 2
////////////////////////////////////////////////////////////////////////////////////

if(input(PIN_B1) && i==0){                          //detecta que no este a su 100% el recorrido del piston
                          output_high(PIN_B2);      //activo la reversa del piston para dejarlo al 100% del recorrido (puente H) 
                          output_low(PIN_B3);       //desactivo el avance del piston para que retroceda (puente H)
}
else if(!input(PIN_B1) && i==0){                    //detecta que el piston esta al 100% del recorrido...
                                j=2256;             //pulsos que generado al 100% del recorrido por B4
                                i=1;                //vandera para poner el piston al 50% de su recorrido
                                output_low(PIN_B2); //desactivo la reversa del piston (puente H)
                                output_low(PIN_B3); //desactivo el avance del piston (puente H)
                                delay_ms(100);      //tiempo de espera antes de poner el piston al 50%
}
if(i==1 && j>1128){                                 //detecta que el piston todavia es mayor al 50% de su recorrido
                   output_low(PIN_B2);              //desactivo la reversa del piston (puente H)
                   output_high(PIN_B3);             //activo el avance del piston para dejarlo al 50% (puente H)
if(!input(PIN_E0)){                                 //contador de posicion del piston
                   x++;                             //contador de revotes                                       
                  }
else{                                               //se solto el boton de conteo
if(x>0){ j=j-1;                                     //decremento j para saver cuando llega al 50% (1146) el piston
        x=0;
        }
}
}
else if(i==1 && j<=1128){                           //detecta que el piston esta al 50% y desactiva el puente H
                         output_low(PIN_B2);        //desactivo la reversa del piston (puente H)
                         output_low(PIN_B3);        //desactivo el avance del piston (puente H)
                         m=1;                       //vandera que indica que el lastre esta al 50%
}
   lcd_gotoxy(1,2);
   printf(lcd_putc,"M2 %f  %i",j,i);
   
if(k==1 && m==1){
                 break;
}
}}

////////////////////////////////////////////////////////////////////////////////////
//
// Funcion para dejar el submarino equilibrado
//
////////////////////////////////////////////////////////////////////////////////////

void inclinasion_submaniro(void){

int16 Valor;       // para 10 bits
float  resolucion= 5.0/1024.0;      // Conversión con 10 bits 
float inclinacion=0;
int p;
for(p=0;;p++){

  Valor=read_adc();//almacena el valor de medicion
  inclinacion= valor * resolucion; //convierte de resolucion de 10bit a numeros
  lcd_gotoxy(1,1);
  printf(lcd_putc,"%f voltios", inclinacion );
 
if(inclinacion>=2.49 && inclinacion<=2.51){
                     output_low(PIN_B2);
                     output_low(PIN_B3);
                     output_low(PIN_B6);
                     output_low(PIN_B7);
                     k=0;m=0;
                     break;   
}
else{
     if(inclinacion>2.51){
                        output_low(PIN_B2);
                        output_high(PIN_B3);
                        output_high(PIN_B6);
                        output_low(PIN_B7);                         
}
else if(inclinacion<2.49){
                        output_high(PIN_B2);
                        output_low(PIN_B3);
                        output_low(PIN_B6);
                        output_high(PIN_B7);
}
}
}}