sensor ultrasónico Arduino

1

Estoy intentando leer un sensor ultrasónico HC-SR04 al mismo tiempo que se ejecutan un par de servos. Tener un servo en funcionamiento está arruinando el tiempo del método pulseIn ().

La medición de la distancia será correcta para distancias pequeñas (hasta 24 cm o menos), pero cualquier cosa más grande a veces se lee incorrectamente. Si un servidor no está conectado a D2 o D3, el sensor de distancia funciona bien. ¿Cómo puedo conseguir que ambos jueguen juntos? ¿Tal vez una biblioteca que no dependa de los mismos temporizadores que un servidor en D2 y D3? Esto está en un Mega.

// read the distance sensor
// returns: distance in inches. -1 means out of range
float ReadDistance(int trigPin, int echoPin)
{
  long duration;
  float distance;
  digitalWrite(trigPin, LOW);  // Added this line
  delayMicroseconds(2); // Added this line

  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10); // Added this line
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  distance = (duration/2.0) / 29.1 / 2.54;
  if (distance >= 200 || distance <= 0)
    return -1.0;
  else
    return distance;
}
    
pregunta BrianK

1 respuesta

6

Si examinamos el código fuente para pulseIn podemos ver que no utiliza ninguno de los temporizadores. La función pulseIn se repite hasta que el pulso finaliza y luego convierte los ciclos de reloj en microsegundos.

La causa de su problema podría ser interrupciones cuando los servos están activos. En algún lugar en el medio de su medición, en la función pulseIn, ocurre una interrupción que permite que el código servo subyacente administre la posición / movimiento del servo. Sin embargo, esto significa que el ancho del pulso (consulte línea 59 ) no se actualiza mientras se ejecuta el código de interrupción. Por lo tanto, obtienes resultados que son muy pequeños.

Esto parece coincidir perfectamente con su descripción de pequeños pulsos que leen correctamente (es menos probable que se interrumpan con otro código) y con pulsos más largos que leen incorrectamente.

Esto es para lo que está el modo de "captura" en la mayoría de los módulos de temporizador de microcontroladores. Inicia el temporizador en el modo de captura, lo deja para ejecutarse en segundo plano y luego utiliza el valor cuando termina. Esto no puede interrumpirse porque es una función de hardware que se ejecuta en segundo plano.

Es posible que desee leer en esta Appmelote de Atmel (su caso de uso es mucho más simple, pero el appnote hace un buen trabajo de explicación). Si no hay un código Arduino para realizar la medición, tendrá que usar los temporizadores directamente, suponiendo que esto sea compatible con el código servo. Lea este esta página web para ver cómo hacerlo, consulte, por ejemplo, el registro ICR1.

    
respondido por el David

Lea otras preguntas en las etiquetas