Hola AngelGris, antes que todo, gracias por la preocupación.
Bueno te comento todo. Me estoy asiendo un submarino a RC, el cual lo quiero controlar con un control futaba attack 4, de 4 canales.
A todo esto yo = practico el oficio del aeromodelismo. Pero mi avión me lo diseñe yo y lo controlo con otro control remoto Hitec, y estoy yendo al club de aeromodelismo de concepción chile. Bueno esto es harina de otro costal. XD
En mi submarino quiero controlar varias cosas, las cuales son timón esto para un canal, elevador para otro canal, inmersión otro canal y propulsión otro canal de mi receptor.
Pero el punto es que para la inmersión necesito activar varias cosas, 2 bombas de agua, más una electroválvula, como también chequear el nivel de mi lastre principal. Pero como quiero usar una palanca de mi control para hacer esto, lo que pretendo es mediante el PWM que genera el receptor hacer que se vallan activando las cosas, es por esto que quiero medir este PWM, además en este punto quiero poner un sistema de protección fail safe, para cuando se pierda esta señal PWM mi pic tome el mando del submarino y haga que emerja el mismo, pero esto es para un canal de mi receptor.
Ahora el canal 3 de mi receptor lo uso para controlar la propulsión de mi submarino (a todo esto mi control lo tengo en configuración modo 2) tanto de avance como de retroceso, el avance lo hago mediante una palanca del emisor, esto en todo su recorrido, y el retroceso lo hago mediante el Trim de ese mismo canal, como lo hago preguntaras. Bueno el Trim lo dejo en la posición mínima todo el tiempo que hago el avance del submarino, esto me genera un PWM con un siclo de trabajo de 107.4 a 174us, bueno no estoy seguro de esto, y no estoy en la casa para ver estos valores, pero como digo con el Trim al mínimo, y cuando mi submarino se detiene la palanca del emisor me genera un siclo de trabajo de 174us creo, y ahora al aumentar el trim aumenta este ciclo de trabajo a unos 195us creó igual, el cual me sirve este rango para darle la reversa a mi submarino con el rango de 175 a 195us. Ahora este control de propulsión lo hago por medio del pin B0 de mi pic acudiendo con su interrupción externa, pero mido este PWM con un timer1, además para controlar el motor de propulsión lo hago mediante una PWM que la saco del CCP1 del pic igual.
Por esto solo me queda CCP2 en conjunto con el timer0, para poder medir la señal proveniente de mi receptor para controlar la inmersión del submarino. Pero en este punto tengo problemas con los timer. o en realidad no sé bien como medir la segunda señal.
Bueno de todas formas aquí dejo el código de lo que tengo:
#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 16X2 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;
////////////////////////////////////////////////////////////////////////////////////
//
// 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
}
}
}
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_ext);
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
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.
}
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);
}
}
}}