Autor Tema: Pic 16f628a y Sensor Ultrasonico HC-SR04  (Leído 12904 veces)

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

Desconectado JohnElectron

  • PIC10
  • *
  • Mensajes: 3
Pic 16f628a y Sensor Ultrasonico HC-SR04
« en: 05 de Febrero de 2015, 15:45:08 »
Hola a TODOS! les comento soy novato en la programacion de pics y debo abordar un programa usando el compilador CCS para poder programar en c el pic 16f628a, lo que debo hacer basicamente es un programa que mediante la ultilizacion del sensor ultrasonico HC-SR04 a una distancia aprox 1.10m que detecte un obstaculo mande una alerta ej: encendido de un led. Tengo el programa hecho pero no encuentro el error por el cual no funciona. Espero que alguien pueda ayudarme! Gracias y Saludos.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Pic 16f628a y Sensor Ultrasonico HC-SR04
« Respuesta #1 en: 05 de Febrero de 2015, 15:58:37 »
Seria ideal que pusieras el codigo para que alguien lo pueda ver y detectar si existe algun error, sino se hace complejo el saber que puede estar pasando

Desconectado JohnElectron

  • PIC10
  • *
  • Mensajes: 3
Re: Pic 16f628a y Sensor Ultrasonico HC-SR04
« Respuesta #2 en: 05 de Febrero de 2015, 16:56:14 »
Sisi tal cual.. el programa es este :
//sensor de ultrasonido HC-SR04
#include <16f628a.h>
#fuses xt
#fuses wdt
#fuses noprotect
#fuses noput
#fuses nobrownout
#fuses nolvp

#use delay(clock=4000000)              //cristal de 4Mz
#define vibrador pin_b0
#define trig pin_b1
#define echo pin_b2

int16 distancia(void){
int16 tiempo=0, distancia;
int nNumero=0;
//pulso de disparo:
output_high(trig);
delay_us(50);
output_low(trig);
//espera flanco de subida por el pin echo
while(echo==0);
//comienza a contar centimetros hasta que pin echo sea cero
while(echo==1){   
if (nNumero == 0){
tiempo++;
if(tiempo==0){
nNumero = 1;
tiempo = 10000;
}
delay_us(58);
}
//demora de seguridad y retorna con el valor de centimetros contados
delay_ms(50);
distancia=tiempo*0.017;
RETURN (tiempo);

}
void main() 

int16 dist_cm=0;

set_tris_b(0b00000100);
 output_low(vibrador);
 
 while(true){
 
 dist_cm=distancia();
 
if(dist_cm<=110) {

output_high(vibrador);
delay_ms(2000);
output_low(vibrador);
delay_ms(1000);
}
}
}   
Nose si hay un error de llaves o un problema en la declaracion de los fusibles.. cuestion que nose que podria ser..

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Pic 16f628a y Sensor Ultrasonico HC-SR04
« Respuesta #3 en: 05 de Febrero de 2015, 18:09:26 »
No mire muy bien el programa, pero a simple vista me parece una mala manera de medir el tiempo del echo que da el sensor.

Aca hay un codigo usando el CCP de los PICs.
http://www.todopic.com.ar/foros/index.php?topic=42732.msg354265#msg354265

Desconectado JohnElectron

  • PIC10
  • *
  • Mensajes: 3
Re: Pic 16f628a y Sensor Ultrasonico HC-SR04
« Respuesta #4 en: 05 de Febrero de 2015, 20:49:35 »
Gracias! Por lo que veo trabaja con el timer del micro.. quisiera saber el error y porque esa seria una mala manera de medir el tiempo de echo, hice un codigo utilizando el timer pero nose si esta bien. Este es el codigo :

#include<16f628a.h>
#fuses xt
#fuses wdt
#fuses noprotect
#fuses noput
#fuses nobrownout
#fuses nolvp


#use delay(clock=4000000)              //cristal de 4Mz
#define vibrador pin_b0
#define trig pin_b1
#define echo pin_b2
#use standard_io(b) 


float distancia(void) 
{
int16 distancia, tiempo;

output_high(trig);  //ponemos en alto el trigg

delay_us(50);   // aplicamos-enviamos un pulso de 20us 

output_low(trig);   // ponemos en bajo el pin trig

while(echo==0);    //se queda preguntando por el inicio del eco

set_timer1(0);   //iniciamos el timer

while(echo==1);

tiempo=get_timer1();

delay_ms(50);              //espero 50ms para una nueva medida

distancia=(tiempo*0.017); //calculo la distancia que es proporcional al tiempo

return distancia;
}

void main()

float dist_cm=0;

setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);//configuro el timer1
 
 while(true){
 
 dist_cm=distancia();
 
if(dist_cm<=110) {

output_high(vibrador);
delay_ms(1000);
output_low(vibrador);
delay_ms(3000);

}
}
}   
Quiero trabajar con el oscilador interno del pic de 4MHZ, temo que algun fusible pueda estar mal declarado o mal usado el timer..

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Pic 16f628a y Sensor Ultrasonico HC-SR04
« Respuesta #5 en: 05 de Febrero de 2015, 23:38:02 »
Citar
Gracias! Por lo que veo trabaja con el timer del micro.. quisiera saber el error y porque esa seria una mala manera de medir el tiempo de echo,

Es exactamente a lo que voy. Una instruccion en ASM generalmente se realiza en un ciclo, si quisiera saber bien el tiempo que paso deberia contar cada instruccion de ASM, sumarlas y eso me daria el tiempo.

Tu metodo a contar no cuenta exactamente eso... sino que esta contando una cierta cantidad de instrucciones

Código: [Seleccionar]
while(echo==1){  
if (nNumero == 0){
tiempo++;
if(tiempo==0){
nNumero = 1;
tiempo = 10000;
}

Pasado a ASM seria y siendo generoso seria algo parecido a instrucciones:

Código: [Seleccionar]
loop:
 MOVF nNumero
 BTFSS STATUS,Z
 INCF   Tiempo  ; Asumo que tiempo es de 8 bits maximo sino aca serian muchas mas instrucciones
 BTFSS STATUS,Z
 GOTO fin
 MOVLW 0x01
 MOVWF nNumero
 MOVLW 0xFF    ; Aca puede haber mas..... por si su pera los 8 bits
 MOVWF Tiempo

fin:
 MOVF echo
 SUBLW 0x01
 BTFSC STATUS,Z
 GOTO loop
 

A lo que quiero llegar que lo que vos contas como "tiempo"  es una cantidad aleatoria de instrucciones ( digo aleatoria por que el compilador es quien decide como se pasa a ASM ), y cada 1 de tiempo significa varios ciclos de maquina, con lo cual no podes estar seguro jamas que cuadno sume 1 paso realmente un tiempo exacto.

Ahora el codigo que te pase usa el modulo Capture/Compare/PWM, este modulo usa el timer.
Entonces como podemos medir el pulso?

Podemos usar una interrupcion por flanco ( como tiene el RB0 del 628 ), entonces activas la interrupcion en flanco de subida, entra a la interrupcion y pones a 0 el timer, cambias el flanco a bajada. Cuando entre nuevamente guardas el valor del timer en una variable. Entonces el contenido del timer SI tiene una relacion directa con los ciclos de reloj (Ej: Osc 20Mhz sin prescaler, el timer suma 1 cada 0.2us). Por ende podes saber exactamente el tiempo transcurrido (podes llegar a tener un pequeño error pero no es significante como lo que podes obtener con tu codigo).

En el link que te pase hace exactamente eso nomas que utiliza el modulo CCP para generar la interrupcion y no la interrupcion del puerto RB0. La unica diferencia entre usar la interrupcion por flanco o por el modulo CCP, es que al ocurrir el evento de bajada, el valor se termina copiando a un registro del modulo CCP, es por eso que ves que no se copia el valor del timer en la interrupcion.
Otra de las cosas a tener en cuenta es que si observas el codigo, la muestra (el valor del timer ) se limita.. en ese ejemplo a 3000, si es mayor se considera fuera de rango, el valor de "fuera de rango" se lo das vos para evitar algunos falsos positivos.

Solo 3 cosas mas:

- no es necesario que calcules la distancia en centimetros si no la vas a mostrar en un display/lcd o algo por el estilo, podes simplemente hacer la "comparacion" con el valor obtenido del timer de esa forma ahorras muchos ciclos que estaria intentando multiplicar por un numero con coma.
- tenes que tener en cuenta que el timer puede rebalsar, y puede que en algun momento esto te de un valor que es erroneo.
- podes hacerlo como lo hiciste, es decir sin interrupciones, aunque podrias tener al micro haciendo otra cosa y no esperando un evento. Es por eso el uso de las interrupciones, pero con lo que intentas hacer basta y sobra. Tene en cuenta el punto de arriba

Citar
Quiero trabajar con el oscilador interno del pic de 4MHZ, temo que algun fusible pueda estar mal declarado o mal usado el timer..

#fuses xt
Es para un cristal de 4Mhz o menos

#fuses INTRC_IO
Oscilador interno y OSC1/OSC2 como I/O

Con reloj a 4mhz
1 ciclo = 4/4Mhz = 1us

como el preescaler esta en 1(T1_DIV_BY_1) cada 1 que sume significa que transcurrio 1us
el timer1 es de 16 bits, por lo tanto lo maximo que puede contar con ese preescaler es de 65,5ms

Si ese tiempo (tendras que traducirlo a cm y ver si es suficiente) es poco podrias aumentar el preescaler disminuyendo la precision o usar un contador de cuantas veces el temporizador rebalsa.
« Última modificación: 05 de Febrero de 2015, 23:50:04 por KILLERJC »

Desconectado danielauzc

  • PIC10
  • *
  • Mensajes: 1
Re: Pic 16f628a y Sensor Ultrasonico HC-SR04
« Respuesta #6 en: 25 de Marzo de 2015, 21:39:32 »
buenas si puede responderme esta pregunta es urgente me pueden ayudar con esto trabajare con el Pic 16f628a   
 como se puede decrementar me mandaron un circuito que cuente desde 25 a 85 y retorne a 55 y vuelva a su valor inicial?? me lo mandaron a programar en pic y no se como hacer que retorne

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Pic 16f628a y Sensor Ultrasonico HC-SR04
« Respuesta #7 en: 25 de Marzo de 2015, 22:08:58 »
Deberias haber abierto un tema nuevo, segun en que lenguaje lo programes:

Aca para C:
http://www.todopic.com.ar/foros/index.php?board=4.0

Aca en ASM:
http://www.todopic.com.ar/foros/index.php?board=3.0


De todas formas deberias de explicar como es que funciona ese contador. tanto en ASM como en C son faciles de implementar
Y no me queda claro como es que cuenta. Va de 25 a 85, luego pasa a 55 y vuelve a contar hasta 85 y luego a donde vuelve ? a 25 o 55 de nuevo ?


 

anything