¿Puedo hacer un failsafe con un Pic16f84 para mi auto R/C?

Tengo un auto a explosión, el enlace de radio frecuencia no tiene failsafe..

failsafe es cuando el receptor pierde la señal del transmisor, entonces el servo va a una posición indicada.. la mas comun es Frenar.


ahora bien... mi receptor tiene 2 canales.. y usa la trama ppm..

habrá alguna persona que me explique.. si esto se podrida hacer con el pic16f84

o.. pic16f819 --> pwm y oscilador interno


básicamentehasta donde tengo entendido.. hay que sensar que los pulsos que recibe el servo sean validos.. que son de 1ms a 2ms..
 
el enlace de radio frecuencia no tiene failsafe..

failsafe es cuando el receptor pierde la señal del transmisor,
amigo por mas pic que le metas si no ay señal (se pierde la señal)no va a funcionar,
primero prueba el canal de rf o el radio-enlace si funciona bien
 
el-rey-julien: no estoy tratando de inventar algo .. ademas tampoco necesito inventar una señal cuando esta se perdió...

lo que necesito hacer no es ningún invento.. es algo muy simple.. lo que pasa es que recién me inicio con los pic.. y bueno.. quería preguntar.. si alguien sabia...


para el realmente quiera saber lo que es..

ML --> failsafe rc -- un costo aproximado .. de 30u$s

el pic.. lo consigo por 3 pesos..

saludos
 
Se puede hacer, pero es algo complicado, especialmente si no tienes conocimientos de electronica, lo primero es averiguar si el control remoto siempre esta enviando informacion al carro, si esto es correcto entonces se puede hacer de 2 maneras, la primera es monitorear el nivel de intensidad de la señal RF que llega a tu carro, pasado cierto nivel se considera que el carro esta fuera del alcance permitido y el PIC lo que tiene que hacer es desactivar el circuito de monitoreo, y poner los servos en frenado, o incluso puede ordenar un giro de 180° al vehiculo para tratar de localizar de nuevo la señal y despues frenarlo

la segunda opcion es esperar el ultimo comando y activar un contador de tiempo, si el vehiculo no recibe un nuevo comando despues de cierto tiempo (unos segundos) entonces el PIC ordena frenar el vehiculo

exactamente como depende mucho de la circuiteria electronica que estes usando en tu carro de control remoto, por eso solo te doy el procedimiento de como se podria hacer....

Saludos...
 
entonces entendí mal
,haber lo quieres hacer es un programa para que el autito cuando pierda señal de algún modo retroceda o frene asta encontrar la señal nuevamente ?es eso??
bueno hagamoslo
primero subir el esquema del autito y del control remoto
segundo elegir pic
tercero a trabajar
saludos y disculpas ,entendí cualquier cosa
 
Bueno, no nos compliquemos tanto. Agarra el pic mas chico que puedas conseguir, preferentemente que tenga oscilador interno para hacer aun mas chico el circuito. (ej: 12F675)

Lo intercalas entre tu receptor y el servo, toma la alimentacion 5v desde la misma alimentacion al servo y el cable señal lo pones en una entrada, y otro pin como salida al servo.

Si tenes acceso a osciloscopio verifica si la señal a los servos es de pulsos de 5v o de 3v (radios mas nuevas). Tambien verifica la frecuencia de tu señal (el ancho de pulso varia, te interesa la frecuencia).

Segun esto: http://es.wikipedia.org/wiki/Servomotor_de_modelismo

Tu frecuencia tiene un periodo de 200ms. Programa el pic de la siguiente forma (vamos a lo simple primero):

1)- Monitoreas el estado de la entrada y reflejas a la salida lo mismo... funcionamiento normal.
2)- Cuando tengas X ciclos de 200ms SIN pulso, o determinas de alguna forma pulsos erraticos, entonces llevas forzadamente el servo a la posicion, digamos, de pulsos de 1ms (0 grados).

Habria que ver que es lo que sucede en la señal cuando perdiste el alcance, si es que deja de emitir pulsos, ya sea en estado alto o bajo... o puede ser tambien que obtengas pulsos erraticos.

Para pulsos erraticos se me ocurre que podes almacenar unos 10 pulsos atras en el tiempo, y verificar que entre ellos haya una relacion mas o menos logica, subiendo o bajando: p1 < p2 < p3 < p4.... o p1 > p2 > p3 > p4.... Si no cumplen con esta relacion podes estar recibiendo pulsos erraticos. (considera el servo "quieto" o sea, todos los pulsos iguales, como algo valido).

Resumiento:
1)- Replicar la entrada en la salida.
2)- Temporizar los pulsos recibidos.
3)- Analizarlos y actuar en consecuencia.

Para replicar podes usar interrupciones, tambien te servira para temporizar.
Para temporizar, usa el TMR0, a valores de interrupcion redondos como por ej: 1 o 4 microsegundos.
Para analizar, usa un vector de X cantidad de pulsos previos.

Te recomiendo programar en C.
 
Gracias a todos por las propuestas muy interesantes.. practicamente lo que necesitaba era esto.. que me den pistas desde donde partir..

la verdad que esto abarca muchos temas a la vez.. pero en fin...
gracias POR moverlo al lugar correspondiente y disculpas por donde lo puse..

Explico un poco como funciona el tema de la perdia de la señal en los equipos de radio convencionales..

hay radios.. en donde el receptor del equipo trae de fabrica por normas de seguridad.. un dispositivo que se llama failsafe. (Esta embebido en el receptor..)
y hay radios que no lo traen..

ahora para que sirve: la mayoria de los radios que no tienen este dispositivo de seguridad.. al salirse del alcance.. perder el vinculo rf, los servos comienzan a chatear.. es decir hacen movimientos erraticos.. lo que si es un auto.. seguro choca contra algo.. y si es un avion.. seguro se entierra por algun lado..

yo tengo 3 equipos de radio.. los cuales 2 de ellos que son de aviones tienen este dispositivo..
cuando el avion queda sin mando, sea interferecia, demasiado lejos, etc.. los servos.. toman una determinada posicion.. , tanto acelerador, timom, elevador.. etc y esto asegura de cierta forma que el avion.. al momento de perder la señal.. si va a fondo apuntado para el sur... no lo tenga que ir a buscar a usa., sino que queda regulando y pega a vuelta..

esto.. en los autos a radio control es muy importante.. porque si pasa algo raro. .el auto tiene que frenar instantaneamente..antes de que se lleve algo puesto... no necesito que vuelva hasta donde este yo.. ni que pegue unos esquivones tampoco jajja..

yo proponia el pic16f84 porque.. es el que estoy empezando a usar.. con el c compiler.. tengo mucha facilidad para la programacion.. pero no tengo ni media idea de como se mueve un servo desde c :eek: en fin seguro qUE algo debe haber por ahi..




seaarg ----> muy clara tu explicacion.. pero.. justamente me puse con el proteus a ver como se usa el timer 0... y un par de servos.. si me dieras una mano.. con esto.. te lo agradeceria muchisimo....


gracias a todos...
 
Última edición por un moderador:
Empecemos por lo primero, que compilador usas? yo conozco CCS C. No seria necesario que sepas mover servos, sino replicar la señal de entrada. Veamos:

Asumiento PIN_A0 como la entrada desde el receptor y PIN_A1 como la salida al servo

do {
restart_wdt();
if (input(PIN_A0)) {
output_high(PIN_A1);
} else {
output_low(PIN_A1);
}

} while(TRUE);

Con esto haces que el micro replique la señal recibida.

Despues:

#int_tmr0
void tmr0_interrupt(void) {

}

Con esto declaras la interrupcion (en realidad CCS C tiene un armador de proyectos donde te declara solo este tipo de codigos)

El timer0 genera una interrupcion cuando se desborda el mismo. va contando de 0 a 255 cada 1us (a 4mhz)

El IDE de CSS te permite configurarlo para que desborde en unos determinados tiempos, por ejemplo 1us, 4us,etc.etc.

Si me tocara a mi hacerlo, yo haria todo por interrupciones, de la siguiente forma:
1)- Usar interrupcion de cambio de estado del pin de entrada. Poner la salida en lo que corresponda.
2)- Al activar esta interrupcion, activar el timer0 (ponerlo a cero y habilitar su interrupcion)
3)- Cuando el timer0 desborda, aumentar un contador (y resetearlo de nuevo)
4)- Cuando hay cambio de estado del pin de entrada nuevamente (o sea, el flanco bajo) parar el timer0, leer su valor y calcular el tiempo transcurrido con la entrada en estado alto haciendo: (tmr0_contador * tiempotmr0) + ultima lectura tmr0
5)- Pongo ese valor en un vector. Cuando tengo X valores en vector empiezo a desviar a una rutina de analisis de los datos obtenidos (que se ejecutara de ahora en mas todas las veces).

Sobre tu pregunta en particular, el TMR0: una de las formas de utilizarlo es por medio de interrupciones, como te explique mas arriba. Se configura a traves de setup_timer0 (ojo con el watchdog)
 
muy clarito!!! fenomeno...

entonces voy a empezar a ver como hago.. lo que detallas...

antes pregunto::: restart_wdt(); para que sirve esto?

y

Se configura a traves de setup_timer0 (ojo con el watchdog) :S yo siempre desactivo el WDT

muchas gracias seaarg
 
Última edición:
sirve para reiniciar el wdt, para que no se active. Se pone en los ciclos generalmente y a criterio del programador. Y ya que es un failsafe te recomiendo rotundamente que uses el wdt :)

En un codigo totalmente pensado, calculado, etc. no deberia ser necesario el uso del wdt, pero somos humanos y a veces hay algo que no consideramos que pueda colgar el micro. Ahi nos salva el wdt.

Te cuento una experiencia? Tengo un planeador con motor electrico, que en su momento le pude poner una radio de 2 canales solamente. Entonces con un micro me fabrique un 3r canal "virtual" para control de motor que respondia a cierta secuencia de un canal fisico para encender y apagar el motor.

No use WDT, era mi primer proyecto de PIC. Termino con el avion cayendo a todo motor desde 100 mts. de altura, por suerte se rompio muy poco. (el motor no sirvio mas jeje)

La falla? el micro entro en un bucle no controlado y no pude apagar nunca el motor. En tierra funcionaba pero en el uso en aire no. Les paso hasta a los muchachos que envian cohetes a la luna asi que nadie se salva jeje. (buscar cohete+integer+overflow)
 
Muchas gracias por el dato... para tenerlo en cuenta entonces...!!! yo tengo 2 planeadores. .pero esos estan protegidos..

el tema es del auto.. que si bien.. tiene 2 ch y alcanse de sobra.. es como que a 300mts no se ve.. y sigue teniendo vinculo sin problemas mas que la señal esta en 2.4 ghz es poco probable qUE lo interfieran.. pero.. bueno.. la idea era jugar con los pic.. y de paso.. aprender un poco-.--


muchas gracias por la explicacion... ahi estuve haciendo unas pruebas en proteus.. con un servo un codigo.. ( el que me pasaste.. ) y todo funciona ok.. por lo menos hace relay de la señal que le entra... por un pin en otro pin.. el tema es que no se como puedo generar este tipo de señal.. con proteus.. tenes idea?

te adjunto una imagen... no logro generar señales entre 1ms y 2 ms... :S
 

Adjuntos

  • fs [].JPG
    fs [].JPG
    32.1 KB · Visitas: 20
Última edición por un moderador:
bueno, no tiene nada que ver con proteus sino programacion:

do {
output_high(PIN_A1);
delay_us(2000);
output_low(PIN_A1);
delay_ms(198);
} while(TRUE);

Eso te genera un pulso alto de 2ms sobre un periodo total de 200ms.

PD: No sabia que proteus tenia servos, que bueno!
 
Excelente.. lo tuyo seaarg-... ya me diste toda la materia prima.. jajaja muchas gracias.. y si... proteus tiene servos.. ahi en la imagen que te adjunte sale un hitec.. 311-- es un standard..

probe lo que me pasaste y anda perfecto..

al principio no lo veia tan claro.. pero despues de probarlo me dejaste mudo..


te hago una consulta mas.. ---

en tu codigo...

do {
output_high(PIN_A1);
delay_us(2000); //pone el sevo al maximo
output_low(PIN_A1);
delay_ms(198); // lo pone al maximo cada 200 ms
} while(TRUE);

la pregunta es: son 198 ms.. porque se le restan los 2000us del pulso que envie antes?

osea que si quiero poner el servo en el medio.. .deberia hacer..

do {
output_high(PIN_A1);
delay_us(1500); //pone el sevo a la mitad, 0° .. ya que 1ms son -90° y 2ms +90° output_low(PIN_A1);
delay_ms(198.5); // lo pone a la mitad cada 200 ms
} while(TRUE);


es correcto?=????


un abrazo hermano!
 
Exacto, ahora: lamentablemente no podes trabajar con punto decimal ahi por lo tanto vas a tener que hacer una rutina que te fabrique el retardo "restante" para el ciclo completo

delay_us(198500) no podes porque: time - a variable 0-65535(int16) or a constant 0-65535

Lo que SI podes hacer es el delay 2, 3, 4 veces, las que te hagan falta. Es re facil pero te la dejo a vos para que la pienses ;) jeje

Pista: Si tenes un periodo de 200ms de los cuales usas 2ms como maximo en estado alto... el resto se arma con delays fijos sumados, y esos 1-2 ms son variables.

Ah! en el pic real, usa si o si cristal. (no veo si es un F84 u otro). Cuando usas oscilador interno el mismo tiene una tolerancia. Eso nunca es bueno en aplicaciones temporizadas. Ojo con que capacitores le pones al cristal. Yo no le pondria asi trabaja en la F fundamental pero en todos lados recomiendan ponerlos.

Proba esto (sale la señal por RB1)

y date una vuelta por aca https://www.forosdeelectronica.com/...hos-mplab-proyecto-completo-20784/index8.html en el segundo post.

Una vez que tengas todo mas o menos funcionando, lo que haria yo seria revisar la lista de conversion C - ASM que te genera CCS y con ella ajustar los delays para obtener los tiempos exactos. Programando en C perdemos por ahi la nocion de que las llamadas y retornos de funcion nos usan 2 ciclos, etc.

Código:
#use fast_io(A)
#define  OUT_SERVO   PIN_B1
#int_TIMER0
void  TIMER0_isr(void) {

}
void init(void) {
   set_tris_a(0b11111111);
   set_tris_b(0b11111111);
   output_a(0x00);
   output_b(0x00);

   setup_wdt(WDT_18MS);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_4); // Overflow cada 1ms

   restart_wdt();
//   enable_interrupts(INT_TIMER0);
//   enable_interrupts(GLOBAL);
}

void main() {
   unsigned int16 tiempoalto;
   unsigned int1  direccion;
   
   init();
   
   tiempoalto = 1500;
   direccion = 1;
   
   do {
   
      output_high(OUT_SERVO);
      delay_us(tiempoalto);
      output_low(OUT_SERVO);
      delay_us(2000 - tiempoalto);
      delay_ms(198);
      
      if (direccion == 1) {
         tiempoalto = tiempoalto + 50;
      } else {
         tiempoalto = tiempoalto - 50;
      }
      if (tiempoalto == 2000) direccion = 0;
      if (tiempoalto == 1000) direccion = 1;
   
   } while(TRUE);
}
 
Última edición:
sos un groso.. loco... ya me pongo a hacer las pruebas.. y entiendo lo que me decis ;) el pic si es un 16f84 con cristal de 4mhz.. y capacitores de 27pf

muchas gracias por toda la data... muy educativo!!!


posta te debo una cerveza.. jajaj


saludos!
 
Por mas que pienso.. no logro comprender como sensar los datos de entrada de la señal.. :S hice hasta aqui.. segun lo que me explicaste vos.. pero.. hay cosas qUE no tengo claras.. desde las set_tris, use_fast_io(), no lo entiendo loco.. tampoco entiendo lo de que hace overflow cada 1ms.. lo que si.. es que cuando habilito la interrupcion global.. el servo vibra.. porque se deforma la señal.. si le podes pegar una revisada a esto.. aqui te adjunto todo.. simulacion y codigo..


gracias loco

y te adjunto lo que necesito hacer..


nada mas.. qUE solo para un canal.. y con el pic16f84...

la idea es aprender + entender.. no cargar el programa ya generado sobre un diseño ya generado..

 

Adjuntos

  • FailSafe.rar
    36.1 KB · Visitas: 10
Última edición por un moderador:
Bueno, no puedo cargar tu simulacion porque tengo una version mas vieja de proteus.

Te fijaste en la ayuda de CCS? ahi te explica que set_tris_x lo que hace es configurar los puertos fisicos del pic, que bits de entrada y cuales de salida.

use_fast_io es una declaracion que le dice al compilador que los puertos quedaran como vos los configures. Sino el mismo genera codigo para hacerlos automaticamente de entrada o de salida depende la operacion que hagas. (Ademas de tardar mas para hacer I/O, perdes un poco el control de eso).

Para entender lo del overflow, deberias buscar algun tutorial sobre temporizaciones con tmr0 por medio de interrupciones.

Basicamente, cada instruccion ejecutada, el pic incrementa el registro del tmr0, que es de 8 bits. Si habilitas la interrupcion, cuando el mismo desborde (pasa de 255 a 0) se genera una interrupcion.

Usando eso y el prescaler del timer, tenes una temporizacion exacta que te sirve para correr un trozo de codigo cada x tiempo.

Los servos te vibran porque no tenes en cuenta en tu programa, que al habilitar la interrupcion, cada cierto tiempo se hace una bifurcacion de codigo que te consume como minimo unos 4 ciclos de reloj (sumados al codigo que implementes en la interrupcion en si). Me parece un exceso que por 4us de variacion se queje pero anda a saber.
 
Bueno gracias por los comentarios.. lo que pasa es que te señalo la vibracion.. porque.. en un servo es importante eso.. fijate en el video que puse.. no se vibran.. quizas en la simulacion vibran en la vida real no...

en fin voy a ponerme a leer.. a ver a que llego..

muchas gracias como siempre por responderme..


saludos!! abrazo loco

y muchas gracias una vez mas
 
Bueno despues de intentar un par de veces(largas) + la ayuda de seaarg.. te digo q no lo puedo creer que me salio... jaja


esto es lo que yo necesitaba...


en fin ahora viene la prueba fisica pero.. no me asusta porque.. hasta aqui todo lo que simule anduvo..


te adjunto unas imagenes..


basicamente..

hace relay por un pin de la señal del receptor.. como quedamos.. y cuando no hay señal.. (promedio 20ms -- cantidad de puslos recibidos)

enciende un led.. y mueve el servo a una posicion preestablecida.. en mi codigo...


dejo las imagenes de como se ve en el osciloscopio virtual..


lo interesante no son tanto las imagene.. si queres te paso el codigo.. y lo probas.. o lo simulas.. al que le interese..
 

Adjuntos

  • FS.JPG
    FS.JPG
    74.7 KB · Visitas: 11
  • FS Activado.JPG
    FS Activado.JPG
    69.6 KB · Visitas: 11
  • relay_señal.JPG
    relay_señal.JPG
    69.9 KB · Visitas: 8
Atrás
Arriba