miliamperios.com

Bootstrap Framework 3.3.6

Más de una docena de componentes reutilizables construidos para proporcionar iconografía, menús desplegables, grupos de entrada, navegación, alertas, y mucho más ...

Todo lo relacionado con el estudio, diseño y funcionamiento de circuitos y componentes electrónicos relacionados con el radio control. Fundado el 4 de Octubre del 2006.

Moderador: Moderadores

Avatar de Usuario
Por Blandi
#898116
Es un proyecto que hace tiempo que tengo en mente, y poco a poco se va cociendo en mi cabeza, pero como de electrónica estaba y estoy bastante pez para este proyecto, lo he ido dejando, pero últimamente me he puesto con los PIC's con ganas y ya vamos teniendo resultados.
Pues bien, la idea es hacer un "parato" que usando un solo canal de la emisora se puedan controlar ocho interruptores, se pueden controlar mas, se supone que si la emisora es de 1024 pasos son diez los bits controlables, pero para dar un margen de seguridad prefiero empezar con ocho, dejando los dos bits de menos peso para un margen de error, además la idea es sustituir el potenciómetro del canal por ocho interruptores. (esto parece mas complicado de lo que es, aunque es mas complicado de lo que parece) :mrgreen:
Al grano, lo primero que he hecho es un sistema que al conectarlo al canal del servo me saque en tiempo real, en microsegundos, la duración del pulso de control, vamos! para los que sabeis mas que yo, el dutty cycle, y ¿por que?, porque si futaba dice una cosa y hi-tech otra, yo quiero saber exactamente la duración de ese pulso en mi emisora, no se si me explico, además como soy yo el que va a interpretar ese pulso, quiero saber como lo interpreto, no sé si me explico, creo que no. :cry:
Bueno, el caso es que el programa está terminado y funcionando, en el "PIC simulator IDE" funciona perfectamente y al pasarlo a la placa tambien, con un pulsador doy un pequeño toque y me pone en pantalla los microsegundos que está pulsado, pero ahora no sé como conectarlo al receptor, me explico, sí, el cable blanco, pero el problema es que no sé que componentes necesito intercalar entre el RB0 del pic y la señal de un canal.
Bueno, si alguien sabe como conectarlo gracias de antemano, y si a alguien le interesa, mi intención es hacerlo libre, si quereis os pongo el código, pero hasta que funcione de todo casi es tontería.
Además este primer programa es para testear las emisoras, el que se supone útil es el que saldrá despues.
Avatar de Usuario
Por dedalo1111
#898167
Hola, en principio no necesitarías nada siempre y cuando ambos circuitos estén alimentados a la misma tensión. La salida del receptor (cable blanco) es una señal digital L=0V y H=+5V.

Posiblemente lo que te falta es que has de unir los negativos de ambos circuitos para "nivelar" los voltajes y que el 0 sea el mismo en ambos circuitos (receptor y PIC).

Una cosa que se hace para protección anti-burradas, se suele colocar en tu entrada a RB0 (por ejemplo) una resistencia al positivo de TU circuito (10..100k) y la entrada se hace interclando un diodo con el cátodo a RB0. De esta forma el H lo pones tú con la resistencia y solo aceptas que un circuito externo "baje a 0" la señal...

Un término intermedio, menos conservador (y menos componentes), es poner una resistencia a negativo de forma que si el cable queda "al aire" no haga de antena y te vuelva loco el circuito.

Si no me he explicado bien o necesitas más datos.... ya sabes :wink:

Salu2

PD. Ten en cuenta que estás en un entorno "límpio" de desarrollo, pero en el avión todo son "parásitos e interferencias"...
Avatar de Usuario
Por dedalo1111
#898177
Hace poco, por si te sirve, publicaron en este hilo un post de un interruptor canal servo discreto que hace por hardware algo parecido a tu proyecto.

Solo que usa una red R/C para determinar el tiempo en que muestrea el ancho del pulso y activar desactivar.... mismo principio pero solo un canal en vez de tus ocho.

Salu2
Avatar de Usuario
Por Blandi
#898204
dedalo1111 escribió: Una cosa que se hace para protección anti-burradas, se suele colocar en tu entrada a RB0 (por ejemplo) una resistencia al positivo de TU circuito (10..100k) y la entrada se hace interclando un diodo con el cátodo a RB0. De esta forma el H lo pones tú con la resistencia y solo aceptas que un circuito externo "baje a 0" la señal...
hummm, a esto me refería, vale!, creo que te he entendido, de RB0 saco una resistencia de 10 o 100k y de esa resistencia por un lado la conecto directamente a positivo y por otro con un diodo imagino que un 4001 a la señal de manera que cuando esté a uno bloquee y así pase la corriente de la resistencia a RBO y cuando la señal esté a cero absorba la corriente de positivo y la resistencia impida el paso de corriente a RB0. ¿es así?, es que si lo conecto directamente ni caso.
Por cierto la alimentación estoy usando la misma, los 5v que tengo en la placa la aprovecho para el receptor, o debería dejar solo las masas unidas y alimentar el positivo diferente?
Gracias por la ayuda.
Avatar de Usuario
Por dedalo1111
#898314
Vamos por partes que decía Jack el destripador... :D fíjate en el esquema del interruptor simple:
Imagen

La entrada "RX in" como ves no necesita de "nada especial" para recibir la señal del receptor. Cuando acoplas señales de circuitos, no necesitas hacer nada especial salvo casos concretos (las salidas de tipo "colector abierto", que no es el caso del receptor). El único "pero" de ese circuito, es que si no se conecta al receptor se puede volver "loco" con esa entrada "al aire", pero conectado es perfectamente estable.

Imagen
Ahora mismo dices que tienes en RB0 con una resistencia a positivo y que con un pulsador lo "bajas a cero" y te funciona ¿correcto?... pues quita la resistencia y pon el cable blanco "ya-ta" :wink: Si tienes un osciloscopio, deberías poder ver la señal (hay unos para PC que usan la tarjeta de sonido :wink: ). Con un polímetro deberías poder ver por lo menos que hay +5V (aprox. al ser una señal de pulso te oscilará la medida :? )

Las resistencias a positivo o negativo (se llaman pullup / pulldown) y sirven para cuando una entrada se queda "al aire" forzar que mantenga en H o L (Caso del pulsador)

----------------------

Imagen
Los circuitos de salida de los IC's (como el receptor) generan los niveles H/L por lo que tu entrada no está "al aire" sino forzada en H/L por el circuito de salida (¿ves que hay dos transistores en la salida del ejemplo? 414-416, uno fija el H y el otro el L en la entrada 415).

---------
Imagen
¿Cuando usar lo que te he contado con el diodo? Cuando diseñas un circuito "de uso general" y quieres protegerlo contra "accidentes". Pero ahora mismo, insisto, no necesitas hacer nada especial (en este ejemplo, de paso usan el diodo para "mostrar la señal"). Otra cosa, 1N4001 es un diodo de 1A... con un 1N4148 "de señal" es jarto bastante y más rápido :wink: .

NOTA: NO se te ocurra hacer esto con la señal del receptor, con una resistencia de 330 ohm le pedirías unos 10mA al circuito de salida del receptor y lo fries. Se puede hacer con 10K..100K que dan para "polarizar" una entrada, pero no para un LED ¿ok? :roll:

----------

- Circuito y receptor alimentados misma fuente +5V y 0V --> OK (no es necesario separarlos, te lo comenté porque "supuse" :roll: que lo tenías con su batería aparte).

- Señal del receptor directamente a RB0 --> OK. (si quieres, una resistencia pull-up de 100K, nada más)

---------

Ya sabes todo lo básico para conectar circuitos, RB0 "debería" leer la señal del receptor... casi lo que te recomiendo es que te montes lo del osciloscopio-PC y "veas" la señal que hay realmente.

Piensa quizás que el problema te pueda venir por otro lado... la señal es un "tren de pulsos", si estás disparando una interrupción ¿no se te estarán "solapando" los disparos?

Salu2
Avatar de Usuario
Por Blandi
#899224
OK, ya funciona, estaba probando con la wfly-09 y por si las moscas he cambiado a la f6exap que de momento nunca me dio problemas.(la wfly aún no la he probado bien)

Le he puesto una resistencia pull-up de 10k (la que tenía a mano) y ahora funciona.
En el canal 6 que es en el que voy a intentar hacer el parato me da una lectura con 140% de EPA de un mínimo de 920us y máximo de 2120us, entonces tenemos un margen de 1200us que varían linealmente según varía el potenciómetro del canal 6.
Ahora hay que conseguir que con 8 potenciómetros podamos "emular" el comportamiento de ese potenciómetros.
La idea es que en el 1º interruptor se conecte una resistencia de la mitad del valor total del potenciómetro o a +5 o a masa, en el segundo 1/4 del valor total,en el tercero 1/8 de ese valor...
y así hasta los 8 interruptores.
De ese modo cuando conectamos el 1º interruptor, el valor en binario de 10bits en el receptor siempre será:"1xxxxxxxxx", y si lo desconectamos siempre "0xxxxxxxxx",no sé si me explico.
El problema de esto es que el valor de las resistencias es muy crítico, porque una ligera variación nos puede chafar todo, aunque siempre empezará a dar por saco por el bit de menos peso, y dependiendo de la precisión que consigamos con las resistencias podremos utilizar cuatro cinco seis... interruptores.

Gracias por el aporte, de todas maneras tendré que probar tambien con la wfly que hoy no la tengo a mano.
Avatar de Usuario
Por dedalo1111
#899234
Me alegro!!! Utilizar resistencias es bastante delicado, las "normales" de carbón son muy dependientes de la temperatura. Puedes mejorar la precisión /estabilidad con resistencias de película metálica.

De todas formas, ya te anticipo que conseguir la resolución de 1024bits es muy ambicioso.

El valor del ancho de pulso puede variar ligeramente según fabricantes, quizás no estaría mal que previeras algún ajuste de "cero".

En esta web hay mucha info de servos, quizás saques alguna idea de los catálogos: http://servocity.com
Imagen

Hay unos chips de Maxim que son "potenciómetros digitales", esto es que llevan la resistencias incorporadas y la electrónica para añadir-quitar valor (a ver si te lo localizo). Con eso además de simplificar tu circuito, seguramente ganes estabilidad.

Otra idea para "fase II" podría ser la de medir la temperatura del circuito y aplicar alguna compensación... pero eso ya llegará.
Avatar de Usuario
Por dedalo1111
#899239
Otra idea para que lo vayas pensando (es más intrusiva en la emisora), el potenciómetro al fin y al cabo lo que hace es un "divisor de tensión" para aplicar un voltaje entre 0-5V (habría que asegurarse del rango). Para eso hay una cosa que se llama "conversores D/A" (digital/analógico) y hay PIC's que lo traen incorporado.

De un plumazo, te quitas problemas de componentes externos, precisión y estabilidad.

Salu2
Avatar de Usuario
Por xerex
#899341
hola, 1024 bits no es imposible, ya que utilizando los temporizadores de los pics puedes obtenerlo correctamente, deteccion por interrupcion de flanco de subida y de bajada, siempre que la frecuencia del PIC sea suficientemente alta, para poder medir al menos 1 microsegundo.

Pasate por http://www.todopic.com.ar (foros) alli tienes mucha informacion de como utilizar los perifericos.

Te dejo como detecto yo los cambios para 3 niveles con un canal del receptor de un proyecto que tengo casi terminado. este detecta la duracion del pulso y asigna a una variable un valor para mostrar una determianda pagina en un OSD. Por cierto, para que no tengas problemas con las señales del receptor a la entrada de captura del CCP, pon un OPAM en configuracion de comparador a un nivel por ejemplo de 2.5V (suficiente para la tecnologia del PIC) y alimentado a los 5v del PIC. Espero pueda servirte de ejemplo para los 1024bits.

//Funcion para medir el tiempo del canal del RX para mostrar pagina.
#define resolucion_ccp 0.2 //en us
#define T_max 2100 //Duracion maxima del pulso en us
#define T_min 900 //Duracion minima del pulso en us

int CCP=0; //variable para poner interrupcion por flanco en alto o en bajo
int16 aux_rise, aux_fall, rise, fall, pulse_width,aux_ccp; //variables de captura de datos de Timer 1
int last_pagina[15]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int pagina_index=0;

#int_CCP1
void CCP1_isr(void)
{
aux_ccp=get_timer1();
if (CCP == 0)
{
aux_rise = aux_ccp;
setup_ccp1(CCP_CAPTURE_FE); // Flanco de Bajada
CCP = !CCP;
}
else
{
aux_fall = aux_ccp; //pulse width
setup_ccp1(CCP_CAPTURE_RE); // Flanco de subida
CCP = !CCP;
rise=aux_rise;
fall=aux_fall;
}
}
/*****************************************************************************/
/* esta funcion da 3 valores distintos conforme a la señal PPM que llega por
el CCP, se calcula de la diferencia de los valores T_max y T_min */

int pagina (void)
{
float aux_pagina;
float time;
int aux,i,cero=0,uno=0,dos=0;

pulse_width= fall - rise;
aux_pagina = pulse_width * resolucion_ccp;
//printf ("ccp %4.0f\n\r",aux_pagina);
time= T_max - T_min;
if ((aux_pagina >= (T_min))&&(aux_pagina <= ((time/3)+T_min)))
aux=0; //Pantalla de retorno a casa.
else if ((aux_pagina >= ((time/3)+T_min))&&(aux_pagina<=((time*2/3)+T_min)))
aux=1; //Pantalla con informacion basica
else if ((aux_pagina >= ((time*2/3)+T_min))&&(aux_pagina <= (time+T_min)))
aux=2; //Pantalla en blanco
else //si se sale de estos valores asignamos la pagina con todos los datos.
aux=0;
pagina_index++;
if (pagina_index == 15)
pagina_index=0;
last_pagina[pagina_index]=aux;
for (i=0;i<15;i++)
{
if (last_pagina == 0)
cero++;
else if (last_pagina == 1)
uno++;
else if (last_pagina == 2)
dos++;
}

if ((cero >= uno)&&(cero>=dos))
return(0);
else if (uno >=dos)
return (1);
else
return (2);
}
Avatar de Usuario
Por dedalo1111
#899353
Hola Xerex, no digo imposible :wink: ... la parte "ambiciosa" es conseguir la suficiente precisión en el lado "emisora" para que asigne exactamente el tiempo de impulso que deseamos junto con todas las tolerancias de componentes + variaciones por temperatura, etc.

Si pudieramos darle a la emisora el valor digital a transmitir sería otra cosa (hasta donde sé, en una FF6ex no y menos un interfaz "universal"), pero el planteamiento de Blandi es "simular el potenciómetro del canal" y esa es la parte "imprecisa" para 1024bits. Medir el ancho del impulso es "relativamente fácil" :lol:

Salu2
Avatar de Usuario
Por xerex
#899783
buenas,

Puedes utilizar la misma filosofia del headtrack para FPV, se lee un sensor (o valor) y se emite en ppm a traves del cable trainer de la emisora, es algo bastante sencillo de hacer y con una buena temporizacion puedes alcanzar esa precision en canales que por lo general no se usan (revisate los post relaccionados en http://www.aeromodelismovirtual.com), como puede ser el 7 u el 8, con esto no dependes de los valores de la emisora, sino de la temporizacion y modulacion de un circuito conectado a la emisora a traves, como te he dicho, el conector de trainer.

Espero os sirva de ayuda, os dejo algo de codigo que hice en su dia (con el giroscopo creo que no funcionaba correctamente porque necesitaba mas velocidad para calcular con mas precision el angulo de giro, al utilizar la integral rectangular o trapezoidal de la señal discreta... creo recordar...)para simular un headtrack sin brujula, pero con giroscopo para calcular el giro de la cabeza, la funcion esencial es la del timer 2 que es la que genera el tren de pulsos PPM en los canales 6 y 7 de la emisora.

// PIC16F876A
#include "Y:\headtrack\headtrack.h"
#include "y:\headtrack\lib_int_eeprom.c"
#include "float.h"
#include <stdlib.h>

// Definicion de posiciones de memoria para los valores de calibracion
// Canales ADC
#define canal_giro 0
#define canal_incl 1
// Pendientes
#define D_ANGULO1 0X00
#define D_ANGULO2 0X02
#define D_INCLINACION1 0X04
#define D_INCLINACION2 0X06
// Ceros
#define D_CANGULO 0X08
#define D_CINCLINACION 0X0A
// Factor de multiplicacion-division
#define factor 1000000
// recorrido servo en us
#define lim_sup_servo 2500
#define lim_inf_servo 300
// Frecuencia de oscilacion del led T_led*20ms
#define T_led 50
// Numero de cuentas con las que se realizara el filtrado software
#define max_filtrado 1
// Periodo de muestreo (en segundos)
#define muestreo 0.02
//define sensisibilidad del gyro (en milivoltios) mV/º/s
#define sensibilidad 0.67
// definde el angulo maximo de variacion
#define max_angulo 180
//Define el numero maximo de cuentas del ADC
#define adc 1024

//variables para calculo angulo de movimiento
int16 gyro[2]; // Lecturas del ADC



signed int16 c_angulo=0,c_inclinacion=0,aux;
float p_inclinacion,aux2;
int16 inclinacion1,inclinacion2,angulo,inclinacion;
int i=0;
int led=0;
int16 aux3;
int16 aux4;
//Valores de calibracion por defecto
#rom 0x2100 = {0xA7,0x02,0x89,0x01,0xB0,0x02,0x7F,0x010,0x18,0x00,0x17,0x00,0xFF,0xFF,0xFF,0xFF}
#rom 0x21E8 = {'H','e','a','d','T','r','a','c','k',' ','b','y',' ','X','e','R','e','X',' ','V','2','.','0'}


int calcula_angulo (void) //devuelve la variacion de angulo del giroscopo
{
float rectangulo,triangulo,area,MSB;
int angle;

MSB= 5/adc; //5000 milivoltios entre cuentas de ADC valor del escalon

// Calculando area inferior rectangulo
rectangulo = (gyro[0]*muestreo)*MSB; //area del rectangulo

//Calculando area superior triangulo
triangulo = (((gyro[0]-gyro[1])/muestreo)/2)*MSB; //area del triangulo

//calculando area total
area = rectangulo + triangulo;

//calculando angulo de variacion mV/s / mV/º/s
angle = area/sensibilidad;

return (angle);
}
/**************************************************************************/
void cero (void)
{
//giroscopo
c_angulo = (max_angulo * (((lim_sup_servo-lim_inf_servo)/2) - angulo))/(lim_sup_servo-lim_inf_servo);

// Inclinacion
set_adc_channel(canal_incl); // recogemos valor inclinacion
delay_ms(10);
c_inclinacion = read_adc(ADC_START_AND_READ)-512;

write_int16_eeprom(D_CANGULO, c_angulo);
write_int16_eeprom(D_CINCLINACION, c_inclinacion);

//señal de que hemos hecho 0
output_bit(pin_a2,1);
delay_ms(100);
output_bit(pin_a2,0);
}
/**************************************************************************/
void channell(void)
{
output_bit(Pin_A5,0);
delay_us(400);
output_bit(Pin_A5,1);
delay_us(900);
output_bit(Pin_A5,0);
}
/**************************************************************************/
void parpadea (int i)
{

output_bit(pin_a2,1);
delay_ms(i);
output_bit(pin_a2,0);
delay_ms(i);
output_bit(pin_a2,1);

}
/**************************************************************************/
void calibracion(void)
{

disable_interrupts (GLOBAL);

//Calibracion punto 1 de inclinacion
parpadea(500);

while(input(Pin_a3));
output_bit(pin_a2,0);
set_adc_channel(canal_incl);
delay_ms(10);
inclinacion1 = read_adc(ADC_START_AND_READ);
delay_ms(1000);

//Calibracion punto 2 de inclinacion
parpadea(500);

while(input(Pin_a3));
output_bit(pin_a2,0);
set_adc_channel(canal_incl);
delay_ms(10);
inclinacion2 = read_adc(ADC_START_AND_READ);
delay_ms(1000);

//Preparacion para guardar la pendiente de inclinacion
if (inclinacion1 < inclinacion2)
{
aux = inclinacion1;
inclinacion1 =inclinacion2;
inclinacion2 = aux;
}
write_int16_eeprom(D_INCLINACION1, inclinacion1);
write_int16_eeprom(D_INCLINACION2, inclinacion2);
while(1) //proceso de calibracion terminado hay que apagar.
{
parpadea(200);
}
}
/**************************************************************************/
void restaura_cal(void)
{
//restaurando giroscopo
c_angulo = read_int16_eeprom(D_CANGULO);
//restaurando inclinacion
inclinAcion1 = read_int16_eeprom(D_INCLINACION1);
inclinacion2 = read_int16_eeprom(D_INCLINACION2);
p_inclinacion = ((((lim_sup_servo - lim_inf_servo) * factor)/(inclinacion1-inclinacion2)));
c_inclinacion = read_int16_eeprom(D_CINCLINACION) ;
}
/**************************************************************************/
#int_RDA //comunicaciones con exterior
RDA_isr()
{

}
/**************************************************************************/
#int_TIMER2 //Pulsos de salida
void TIMER2_isr(void)
{
int x;
// recogiendo valor del giroscopo
gyro[0]=gyro[1];
set_adc_channel(canal_giro); // recogemos valor inclinacion
delay_us(500);
gyro[1] = read_adc(ADC_START_AND_READ);
//secuencia de temporizacion para Slave emisora PPM
for (x=0;x<5;x++)
channell();
//Canal 6: EJE X DEL INCLINOMETRO
delay_us(400);
output_bit(Pin_A5,1);
delay_us(angulo);
output_bit(Pin_A5,0);
//Canal 7: EJE Y DEL INCLINOMETRO
delay_us(400);
output_bit(Pin_A5,1);
delay_us(inclinacion);
output_bit(Pin_A5,0);
//Pulso de sincronizacion
delay_us(350);
output_bit(Pin_A5,1);

if (i>T_led)
{
i=0;
led= !led;
output_bit(pin_a2,led);
}
else
i++;
}
/**************************************************************************/
void main()
{
int cal;
int16 filtro_angulo[max_filtrado];
int16 filtro_inclinacion[max_filtrado];
int32 valor_filtrado;

setup_adc_ports(AN0_AN1_AN3);
setup_adc(ADC_OFF);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DIV_BY_16,249,10);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
enable_interrupts(INT_RDA);
enable_interrupts(INT_TIMER2);
enable_interrupts(GLOBAL);

if (!input(Pin_A3)) //hemos pulsado en arranque calibracion?
{
while (!input(Pin_A3)); // esperamos a soltar el boton
calibracion();
}
enable_interrupts(GLOBAL);
restaura_cal();
for (cal=0;cal<max_filtrado;cal++)
{
filtro_angulo[cal]=0;
filtro_inclinacion[cal]=0;
}
// TODO: USER CODE!!
while (1)
{
delay_ms(10);
if (!input(pin_a3))/// si pulsamos boton entramos en cero
{
cal=0;
while(!cal) // esperamos a dejar de pulsar el boton
{
delay_ms(100);
cal = input(pin_A3);
}
cero(); //hacemos cero
}
// Giroscopo
aux = angulo + (((lim_sup_servo-lim_inf_servo)/(max_angulo/2))* (calcula_angulo() + c_angulo));

for (cal=0;cal<max_filtrado;cal++)
{
filtro_angulo[cal]=filtro_angulo[cal+1];
valor_filtrado = filtro_angulo[cal] + valor_filtrado;
}
filtro_angulo[max_filtrado-1]=aux;
valor_filtrado= (valor_filtrado + filtro_inclinacion[max_filtrado-1])/ max_filtrado;

if (valor_filtrado > lim_sup_servo)
angulo = lim_sup_servo;
else if (valor_filtrado < lim_inf_servo)
angulo = lim_inf_servo ;
else
angulo = valor_filtrado;

// inclinacion
set_adc_channel(canal_incl);
delay_us(100);
aux4 = read_adc() - (c_inclinacion + inclinacion2);
aux2= (aux4 * p_inclinacion);
aux3= aux2/factor;
aux = lim_inf_servo+aux3;

for (cal=0;cal<max_filtrado;cal++)
{
filtro_inclinacion[cal]=filtro_inclinacion[cal+1];
valor_filtrado = filtro_inclinacion[cal] + valor_filtrado;
}
filtro_inclinacion[max_filtrado-1]=aux;
valor_filtrado= (valor_filtrado + filtro_inclinacion[max_filtrado-1])/ max_filtrado;

if (valor_filtrado > lim_sup_servo)
inclinacion = lim_sup_servo;
else if (valor_filtrado < lim_inf_servo)
inclinacion = lim_inf_servo ;
else
inclinacion = valor_filtrado;
}

}

Saludos.
Avatar de Usuario
Por xerex
#899993
Veamos señores, un poco de tecnica para el trainer:

La señal de trainer se puede utilizar como bien habeis visto, para controlar en paralelo con la emisora (el menos en las emisoras de gama media, yo lo tengo probado en una FF)) los canales que le digamos.

La señal ppm envia los pulsos de cada canal separados por un "espacio" de 400 us, fijate en la funcion channell:

void channell(void)
{
output_bit(Pin_A5,0);
delay_us(400);
output_bit(Pin_A5,1);
delay_us(900);
output_bit(Pin_A5,0);
}

Esta esta metida dentro de un bucle for que hace que tengamos un tren de 5 pulsos que son LOS 5 PRIMEROS CANALES de la emisora, pero esto solo es para meter de alguna manera los siguientes canales que son el 6 y el 7 (donde va la informacion de los sensores en mi caso), fijaros en la interrupcion Timer2, lo que hace es enviar la secuencia de los 7 canales, en la emisora FF9 (donde se ha probado) puedes eliminar los canales que quieras y añadir los de la entrada de trainer ;)


#int_TIMER2 //Pulsos de salida
void TIMER2_isr(void)
{
int x;
// recogiendo valor del giroscopo
gyro[0]=gyro[1];
set_adc_channel(canal_giro); // recogemos valor inclinacion
delay_us(500);
gyro[1] = read_adc(ADC_START_AND_READ);
//secuencia de temporizacion para Slave emisora PPM
for (x=0;x<5;x++)
channell();
//Canal 6: EJE X DEL INCLINOMETRO
delay_us(400);
output_bit(Pin_A5,1);
delay_us(angulo);
output_bit(Pin_A5,0);
//Canal 7: EJE Y DEL INCLINOMETRO
delay_us(400);
output_bit(Pin_A5,1);
delay_us(inclinacion);
output_bit(Pin_A5,0);
//Pulso de sincronizacion
delay_us(350);
output_bit(Pin_A5,1);

if (i>T_led)
{
i=0;
led= !led;
output_bit(pin_a2,led);
}
else
i++;
}

Con esto ya puedes insertar la informacion que quieras y emitirla junto con los controles al avion :), programando correctamente la emisora, claro.

Por cierto, hay dos tipos de señal PPM, la positiva y la negativa, osea la que funciona con informacion en pulso en alto y la que funciona con la informacion de pulsos por bajo, Futaba, utiliza PPM positiva.

Espero os hayais aclarado.

Saludos y Feliz navidad.
Avatar de Usuario
Por dedalo1111
#899998
A ver si te he entendido bien, lees la señal actual de los canales y compones el tren completo de señal con la lectura obtenida donde has reemplazando los valores para los canales a modificar.

¿correcto?

Salu2 y felices fiestas tambien!
Avatar de Usuario
Por xerex
#900029
sactamente :), tienes que componer la señal completa PPM con el numero de canales que se necesitan, luego el filtrado se hace por programacion en la emisora.

Por eso con la interrupcion del timer, se envian 7 canales, pero solo en los dos ultimos, el 6 y el 7 envian la informacion que yo necesito.

Saludos!
Avatar de Usuario
Por Blandi
#900408
Bueno, bueno, se despista uno dos días y en vez de un aporte me encuentro una revelación!
Desde luego que sip, no se me hubiera ocurrido que esto se podía hacer así, pero ahora mismo quemo las resistencias y los conversores y me pongo a este sistema.
Gracias, solo tengo el problema de que en cuanto me encuentro un "Void" me entra una alergia del quince, y es que de momento solo programo en asm, supongo que algún día habrá que ponerse con el "C" :oops:
Avatar de Usuario
Por dedalo1111
#900414
Jajjajajja, la siguiente revelación es que C es "asm recubierto" :roll:

output_bit(Pin_A5,0); => PUSH Pin_A5: PUSH 0: CALL output_bin;

De todas formas lo importante es la idea, el codigo de Xerex son solo trozos "parciales" de cosas que ha echo, pero no te vale de copy-paste 8)

Salu2
Avatar de Usuario
Por xerex
#900624
Blandi escribió:Bueno, bueno, se despista uno dos días y en vez de un aporte me encuentro una revelación!
Desde luego que sip, no se me hubiera ocurrido que esto se podía hacer así, pero ahora mismo quemo las resistencias y los conversores y me pongo a este sistema.
Gracias, solo tengo el problema de que en cuanto me encuentro un "Void" me entra una alergia del quince, y es que de momento solo programo en asm, supongo que algún día habrá que ponerse con el "C" :oops:

Vaya por dios... ASM que tiempos..... pasate al C se te dara mejor ;) y ademas pasate por el hilo que te ha puesto Juan, un poco extenso pero..... interesante, aunque solo he leido el primero comentario de acristobal para hacer 3 canales todo nada de un canal proporcional....

Si tuviera tiempo y una caña........ snif!

Saludos!
Avatar de Usuario
Por xerex
#901046
juan ruiz escribió:Xerex te pido disculpas si te he molestado por poner ese link.

Puedo poner este que ya existe y hace muchos años yo lo tube puesto en mi emisora para barcos.


http://es.willyfogg.com/p60414021/ROBBE ... DECODER+8/


Saludos

No Juan!!! no me mal interpretes es perfecto el link, lo hubiera puesto yo si lo hubiera leido en aeromodelismo virtual!!! :) llevo un tiempo desconectado de la pagina de aeromodelismovirtual.... y siempre es bueno tener noticias de alli.

Lo unico, que supongo que lo habran tenido en cuenta y tendran que resolver, es que a veces puedes tener "ruidos", eso mismo lo tengo yo hecho para cambiar de pagina en el OSD y tuve que poner algun tipo de filtrado... si no recuerdo mal, poniendo 3 niveles que correspondian a 3 paginas del OSD.... es complicadillo y mas poniendo 256 niveles para 8 canales....

Saludos!!!
Por fbforos
#903743
Buenas,

El tener 8 interruptores en un canal no es complejo. el problema es para que sirven 8 interruptores en un canal si solo puedes seleccionar uno cada vez. Lo realmente interesante sería el poder utilizar los 8 canales simultaneamente y esto si que no es posible. Si quisiesemos utilizar los 8 canales todo o nada simultaneamente necesitariamos 64 estados posibles, no es imposible pero bastante complejo.

En el foro de aeromodelismovirtual en el link que os puso juan se va a hacer un sistema de 3 interuptores con 3 posiciones cada uno. Estará basado en el arduino y creo que en un tiempo llegará a buen puerto.
Avatar de Usuario
Por dedalo1111
#903811
Hola y feliz año a todos. Me gusta esa frase de :D
lo hicimos... porque no se podía.
fbforos, ¿de donde sacas 64 estados? ¿y como llegas a la conclusion de que no es posible? 8 bits a mi dan 256 estados y en el peor de los casos... ¿que nos impide serializar los bit? :wink: se podrían mandar 8 u 80, tan solo es cuestión de latencia el multiplexar la información.

La idea de Blandi es:
Bit 0-7: (8 bits, 256 estados ). El rango de pulso entre -90º y +90º es de 1800useg, luego 1800/256=7,03useg. Midiendo la longitud del pulso sabe que valor hay (en decimal) y en binario son los ocho interruptores.

00100110= 38x7,03= 267 useg (+600 de -90º)
10000001= 129x7,03= 906,87 useg
10001001= 137x7,03= 963,11 useg

¡¡Dale caña Blandi, que dicen que no se puede!!! :twisted: :twisted: :twisted:
Por fbforos
#904022
fbforos, ¿de donde sacas 64 estados?
No me digas que no te has dado cuenta, de hacer los calculos con 6 bits únicamente.

Lo que no se de donde sacas +90 -90 en la emisora. En los servos sin problema pero has tratado de generar ese pulso en la emisora y que funcione recibiendolo correctamente en el receptor?

Yo si lo intente. Ahora te dejo que lo pruebes.

El decodificar la señal es muy fácil una tabla ancho de pulso y byte correspondiente
lo hicimos... porque no se podía.
Para mí los milagros son en la puerta de al lado
Avatar de Usuario
Por dedalo1111
#904047
Ufff, fbforos... entras muy "tenso" y sentenciando las afirmaciones, en fin... a mi me gusta más el trato de mejor rollo :?

Ya conocía que no todas las emisoras admiten +/-90º. En cualquier caso eso no altera el principio de funcionamiento que Blandi propone, si fuera con +/-60º o +/-45º sigue siendo igual de válido. Viendo lo que alcanza se determina el rango "util" y la precisión alcanzable, que pueden no ser 8 bit... pero para eso se inventó la multiplexión o dejarlo en 7, 6, o <5 bits.

Estoy de acuerdo contigo, que una vez obtenido el ancho de pulso es facil decodificarlo (incluso sin tabla) el propio valor binario del ancho de pulso / unidad_pulso son los bit de estado de los interruptores (una vez restado el ancho minimo de -90,-60, o -45º).

Lo de los milagros, ya no entro... respeto las creencias personales de cada uno.

En fin, en mi ánimo nunca ha estado el molestar y si tienes opiniones constructivas, por mi parte, bienvenidas.

Un saludo
Por fbforos
#904063
No me mal interpretes, aunque parezca lo contrario ni molestas, ni tampoco estoy tenso, son puntos de vista distintos. Y lo de los milagros viene a cuento de lo imposible

Pero es que yo no conozco ninguna emisora que te permita +-90º , puede que alguna graupner, o jr pero no transmitiendo en PPM. Puede ser que exista pero no la conozco.
Si lo dejamos en 7 6 o 5 bits ya no son 8 interuptores. Si dejamos 5 interuptores ya son 32 rangos esto es mucho mas fácil y si son 6, 64 puede ser pero implica riesgo

El propio valor binario del ancho de pulso creo que no nos vale, deberíamos de dar una tolerancia al pulso leido ¿no? estaría fatal que se nos encendiese algo que no deseamos por unos usegundos mas o menos debidos a un cambio en la temperatura o la humedad.

Multiplexar un canal de una trama PPM es posible por supuesto. Pero ya tienes que meter un pulso de sincronismo y un CRC al final del envio para estar seguro de que lo que transmites y recibes es correcto. Cuando manejas un servo us arriba o abajo no pasa nada ya que es cuestión de corregir el vuelo, pero imaginate que a alguien se le ocurre conectar un paracaidas a un interruptor y este se abre por un salto en el pulso. No es imposible pero para mi creo que es un poco complejo y lento para el fin que tenemos. Aunque un reto es un reto y si lo conseguimos nos escoramos un poco más ( Lo digo por las medallas). :mrgreen:

Nuestro proyecto es un poco menos ambicioso, 3 canales de 3 posiciones cada uno 27 rangos en total + o -. si tomamos 1000us que es el rango estándar de nuestras emisoras tenemos 35,5 us por posición, que no está mal del todo.

Y por favor no me mal interpretes, si hay algo que no te gusta o no te cuadra me lo dices y no es que sea categorico yo soy el primero que me equivoco :oops:

¡Elija que Addons deben funcionar, utilice sólo lo que realmente necesita!