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.
#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);
}
}
}}