Offline
Newbie
Karma: 0
Posts: 12
|
 |
« on: April 09, 2011, 03:08:19 pm » |
Hola, me llamo Samuel, y siempre me ha gustado la electrónica, estas navidades me regalaron una placa Arduino, y he estado haciendo algunos ejemplos de los que vienen, pero otros como no tenía los aparatos, los he intentado entender. Bueno, el caso es que mi padre me compró un sensor para emitir y un receptor de ultrasonidos. Y la idea de mi padre es ver si podemos usarlos para medir la velocidad del aire y así aprender algo mas. Después de un mes he conseguido enviar una señal de cuarenta kilohercios por el transmisor en forma de trenes (vamos enviamos unos pulsos a esa frecuencia, paramos un tiempo y volvemos a enviar ) y mi padre hizo el circuito para que a partir del receptor obtengamos esos trenes de pulsos transformados en una señal cuadrada de 5 v para leerla.
Bueno, lo que a mi me interesa es saber como puedo calcular el tiempo entre que enviamos la señal y la recibimos. He intentado con lo que viene en los tutoriales del pulseIn, pero me dice todo el rato por la pantalla 0 0 0 0 . No se si se puede hacer de otra forma.
Bueno en resumen lo que quiero saber es como puedo calcular el tiempo entre que envío un tren de pulsos hasta que recibo un tren de pulsos.
¿Alguna idea?
Gracias por las respuestas. Ya he leido el manual básico, pero no veo nada que me sirva para medir ese tiempo.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Edison Member
Karma: 22
Posts: 1373
|
 |
« Reply #1 on: April 09, 2011, 04:36:37 pm » |
La semana que viene tengo que montar un medidor de distancia por ultrasonidos (que luego ya veremos que acaba saliendo) directamente con los sensores, sin preprocesado (como me parece que lo estás haciendo tú), así que si no tienes mucha prisa iré subiendo el código a GitHub según lo vaya haciendo.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 12
|
 |
« Reply #2 on: April 09, 2011, 05:39:46 pm » |
No tenemos prisa, además yo he terminado los exámenes hace poco. Así que voy a probar a ratos por las tardes a ver si me sale algo. Dice mi padre que tengo que aprender a pensar las diferentes soluciones.
Por cierto que es eso de GitHub?
Nosotros lo que estamos haciendo es hasta ahora mirar en un osciloscopio la señal que nos aparece en el receptor. Todavía no la hemos metido en el arduino. Y la señal que le metemos en el emisor la estamos haciendo con la orden pwn() y delays en el pin 9. No se mucho de eso, pero estuve buscando en internet y encontré un código para modificar no se que registros del timer(que no acabo de entender del todo que son) y que así nos saliera la señal de 40 khz.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Edison Member
Karma: 22
Posts: 1373
|
 |
« Reply #3 on: April 09, 2011, 06:18:19 pm » |
Mientras tanto puede que te interese este post, donde han hecho algo similar: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1295749011GitHub así rápido es una página donde subir el código de cualquier cosa que hayas hecho y que cualquier persona pueda tener acceso a el.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 12
|
 |
« Reply #4 on: April 11, 2011, 05:31:32 am » |
Bueno, he intentado utilizar la instrucción pulsein para medir tiempos, y en ausencia de viento cada vez me marca una cosa, puede que sea por el circuito externo. no lo se: void setup() {
pinMode(2,INPUT); pinMode(9, OUTPUT); Serial.begin(9600); //codigo para el pwm de los pines 9 y 10 en este caso 40 khz //Fórmula: Fpwm(KHz) = 16000KHz [clock de la arduino] / (2 * N //* ICR1) TCCR1A = 0x00; //con esto lo que hacemos es ajustar el timer en uno de los modos de //generacióndel pwm PWM, "Phase and Frequency Correct"
TCCR1B = 0x11; // esto setea el //"prescaler" (N), de la siguiente manera: // TCCR1B=0x11 --> //N=1; TCCR1B=0x12 -->N=8; TCCR1B=0x13 -->N=64, etc. // N, el famoso "prescaler"o divisor, es un divisor del reloj de la Arduino (16MHz) ICR1 = 200; // ICR1 es el valor //máximo del analogWrite, lo que le llaman el "TOP" del analogWrite
} void loop() { unsigned long x ;
digitalWrite(9,LOW); analogWrite(9,100); delayMicroseconds(475);// digitalWrite(9,LOW); x = pulseIn(2, HIGH);
Serial.print("duracion a lvl alto "); Serial.println(x,DEC);
delay(10000);
}
Los tiempos que me da son: 684, 709, ....
|
|
|
|
« Last Edit: April 11, 2011, 05:51:11 am by kiki1996 »
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 12
|
 |
« Reply #5 on: April 11, 2011, 05:50:02 am » |
Este es otro programa que tampoco me funciona: void setup() {
pinMode(2,INPUT); pinMode(9, OUTPUT); Serial.begin(9600);
//codigo para el pwm de los pines 9 y 10 en este caso 40 khz //Fórmula: Fpwm(KHz) = 16000KHz [clock de la arduino] / (2 * N //* ICR1) TCCR1A = 0x00; //con esto lo que hacemos es ajustar el timer en uno de los modos de //generacióndel pwm PWM, "Phase and Frequency Correct"
TCCR1B = 0x11; // esto setea el //"prescaler" (N), de la siguiente manera: // TCCR1B=0x11 --> //N=1; TCCR1B=0x12 -->N=8; TCCR1B=0x13 -->N=64, etc. // N, el famoso "prescaler"o divisor, es un divisor del reloj de la Arduino (16MHz) ICR1 = 200; // ICR1 es el valor //máximo del analogWrite, lo que le llaman el "TOP" del analogWrite
} void loop() { unsigned long x ; unsigned long y ; unsigned long z ;
digitalWrite(9,LOW); analogWrite(9,100); delayMicroseconds(475);// digitalWrite(9,LOW); x = pulseIn(2, HIGH);
Serial.println("duracion a lvl alto "); Serial.println(x,DEC);
delay(3000);
analogWrite(9,100); delayMicroseconds(475);// digitalWrite(9,LOW); delayMicroseconds(1975); digitalWrite(9,HIGH);
y = pulseIn(2, LOW);
Serial.println("duracion a lvl bajo "); Serial.println(y,DEC); delay (3000);
z = x + y ;
Serial.println("periodo de la señal"); Serial.println (z, DEC); delay(10000);
}
|
|
|
|
« Last Edit: April 11, 2011, 05:53:02 am by kiki1996 »
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 12
|
 |
« Reply #6 on: April 11, 2011, 07:22:25 am » |
Lo que quiero hacer es enviar con arduino un tren de pulsos a un sensor ultrasónico, a una distancia de 1 metro se encuentra un receptor de ultrasonidos, que recogerá dicha señal. Esta señal será transformada en una señal cuadrada para que vuelva a arduino y la lea.
Necesito medir el tiempo entre que me envía la señal y la recivo, pero no veo ninguna orden que me deje. Por ello he pensado que podría medir la frecuencia de una señal enviada al receptor.
Pero tengo el problema de que al tener que generar la señal con el mismo arduino, no soy capaz a medir esa frecuencia en una entrada. Ya que parece que las órdenes pulseIn() me bloquean el programa.O me miden lo que les da la gana.
Pero lo ideal sería algo para contar tiempo desde que pongo a lvl alto una entrada, hasta que vuelve a estar a lvl alto.
En resumen, ¿Se pueden activar contadores de tiempo con arduino? ¿Como?
uso la entrada 9 para generar la señal, y la 2 para recibir lo que recojo del receptor.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 12
|
 |
« Reply #7 on: April 11, 2011, 01:47:19 pm » |
Ahora que lo pienso,¿quizá no sería posible medir el tiempo en este caso con la función micros? No se, a ver si mañana me sale algo. El principal problema que tengo es que necesito conocer el tiempo, o la frecuencia, o lo que sea de la señal que recibo y compararla con la enviada. Si estuviera enviando la señal con otro dispositivo que no fuera arduino lo vería mas fácilXD Pero bueno, estoy aprendiendo. De hecho cada día cuando vuelvo del instituto estoy un par de horas mirándolo. 
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 12
|
 |
« Reply #8 on: April 12, 2011, 06:37:47 am » |
Bueno, nuevos avances, he conseguido medir el tiempo entre 2 trenes de pulsos. El problema es que todavía no se para que me puede servir  Ya que creo que necesitaría saber el tiempo entre emisión y recepción. Pero bueno este programilla me ha ayudado a entender un poco el concepto de medidas de tiempos en microsegundos, que la verdad me esperaba que fuera mas fácil hacer esto con arduino void setup() { pinMode(2,INPUT); pinMode(9, OUTPUT); Serial.begin(9600); //codigo para el pwm de los pines 9 y 10 en este caso 40 khz //Fórmula: Fpwm(KHz) = 16000KHz [clock de la arduino] / (2 * N //* ICR1) TCCR1A = 0x00; //con esto lo que hacemos es ajustar el timer en uno de los modos de //generacióndel pwm PWM, "Phase and Frequency Correct" TCCR1B = 0x11; // esto setea el //"prescaler" (N), de la siguiente manera: // TCCR1B=0x11 --> //N=1; TCCR1B=0x12 -->N=8; TCCR1B=0x13 -->N=64, etc. // N, el famoso "prescaler"o divisor, es un divisor del reloj de la Arduino (16MHz) ICR1 = 200; // ICR1 es el valor //máximo del analogWrite, lo que le llaman el "TOP" del analogWrite } void loop() { unsigned long x; unsigned long y; unsigned long z; unsigned long u; analogWrite(9,100); delayMicroseconds(475); digitalWrite(9,LOW); delayMicroseconds(475); analogWrite(9,100); delayMicroseconds(475); digitalWrite(9,LOW); while(digitalRead(2) == LOW); // se ejecuta contunuamente hasta que la expresión sea falsa vamos hasta que tenga 1 en la entrada 2 x = micros(); // Por lo que me medirá en micros justo el tiempo antes de que se ponga a lvl alto while(digitalRead(2) == HIGH); y = micros(); while( digitalRead(2)== LOW); u = micros(); z=u-x ; Serial.println(" tiempo entre los 2 pulsos"); Serial.println(z,DEC); delay(10000); }
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 12
|
 |
« Reply #9 on: April 12, 2011, 06:38:30 am » |
Y sigo investigando: 
|
|
|
|
|
Logged
|
|
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 12
|
 |
« Reply #11 on: April 12, 2011, 08:29:38 am » |
Gracias, aunque en este caso lo estamos haciendo todo desde cero  Bueno, al lío he conseguido hacer el programa Bien por mi que me mide el tiempo que me tarda un pulso en llegar. Al final me parece una chorrada, solo cuando he decidido dejar de intentar usar la función pulseIN() me ha salido:  void setup() { pinMode(2,INPUT); pinMode(9, OUTPUT); Serial.begin(9600); //codigo para el pwm de los pines 9 y 10 en este caso 40 khz //Fórmula: Fpwm(KHz) = 16000KHz [clock de la arduino] / (2 * N //* ICR1) TCCR1A = 0x00; //con esto lo que hacemos es ajustar el timer en uno de los modos de //generacióndel pwm PWM, "Phase and Frequency Correct" TCCR1B = 0x11; // esto setea el //"prescaler" (N), de la siguiente manera: // TCCR1B=0x11 --> //N=1; TCCR1B=0x12 -->N=8; TCCR1B=0x13 -->N=64, etc. // N, el famoso "prescaler"o divisor, es un divisor del reloj de la Arduino (16MHz) ICR1 = 200; // ICR1 es el valor //máximo del analogWrite, lo que le llaman el "TOP" del analogWrite } void loop() { unsigned long x; unsigned long y; unsigned long z; unsigned long u; x = micros();// tomo el tiempo inicial antes de enviar el pulso analogWrite(9,100); delayMicroseconds(475); digitalWrite(9,LOW); while(digitalRead(2) == LOW); // se ejecuta contunuamente hasta que la expresión sea falsa vamos hasta que tenga 1 en la entrada 2 y = micros(); // Por lo que me medirá en micros justo el tiempo antes de que se ponga a lvl alto z=y-x ; Serial.println(" tiempo entre la salida y la llegada "); Serial.println(z,DEC); delay(10000); } Igual hay alguna variable que sobra, pero bueno. Ya las utilizaré mas adelante Bueno he hecho un montón de medidas, si pongo el transmisor separado del receptor 1 metro obtengo aprox una medida de la velocidad del sonido de 360 m/s jajajaja Continuaré con las investigaciones : 
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 12
|
 |
« Reply #12 on: April 14, 2011, 03:57:28 am » |
Bueno, he estado realizando medidas y aproximadamente debería realizar una corrección en la medida de la velocidad del viento de - 3%. De la medida obtenida con arduino.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 12
|
 |
« Reply #13 on: April 14, 2011, 07:26:21 am » |
A continuación muestro el programa que he realizado para tomar medidas de las velocidades del sonido, con la corrección. void setup() {
pinMode(2,INPUT); pinMode(9, OUTPUT); Serial.begin(9600);
//codigo para el pwm de los pines 9 y 10 en este caso 40 khz //Fórmula: Fpwm(KHz) = 16000KHz [clock de la arduino] / (2 * N //* ICR1) TCCR1A = 0x00; //con esto lo que hacemos es ajustar el timer en uno de los modos de //generacióndel pwm PWM, "Phase and Frequency Correct"
TCCR1B = 0x11; // esto setea el //"prescaler" (N), de la siguiente manera: // TCCR1B=0x11 --> //N=1; TCCR1B=0x12 -->N=8; TCCR1B=0x13 -->N=64, etc. // N, el famoso "prescaler"o divisor, es un divisor del reloj de la Arduino (16MHz) ICR1 = 200; // ICR1 es el valor //máximo del analogWrite, lo que le llaman el "TOP" del analogWrite
} void loop() { unsigned long x; unsigned long y; unsigned long z; unsigned long u = 0;// Pongo la suma de 10 medidas a 0 antes de cada bucle for (int i=0; i < 10; i++){ //inicializo el contador de toma de 10 medidas x = micros();// tomo el tiempo inicial antes de enviar el pulso analogWrite(9,100); delayMicroseconds(475); digitalWrite(9,LOW);// envío el tren de pulsos while(digitalRead(2) == LOW); // se ejecuta continuamente hasta que la expresión sea falsa vamos //hasta que tenga 1 en la entrada 2. Es decir un lvl alto. y = micros(); // Por lo que me tomara la medida en microsegundos justo el tiempo antes de que se // ponga a lvl alto
z=y-x ; // con esta operación obtengo la diferencia de tiempos entre la señal enviada y la recibida u += z; // equivalente a la expresión u = u + z. Voy sumando las 10 medidas. delay(5); }
u /= 10; // equivalente a la expresión u = u / 10; Por lo que tendría en u la media de los tiempos // en microsegundos
u -= 492; // equivalente a la expresión u = u - 492; Le resto el retardo electrónico. // ahora tendré el tiempo de vuelo en u u = 1000000/u; // obtengo en u la velocidad en m/s sin corrección
u = u * 98 / 100; // ahora estaría haciendo una corrección del 2% en la velocidad del sonido. // tendría la velocidad del sonido en ese momento.
Serial.println(" velocidad del sonido"); Serial.println(u,DEC);
delay(10000); }
|
|
|
|
|
Logged
|
|
|
|
|
|