Módulo HC-SR04 (ultrasonidos) sin la función pulseIn()

Hola,

Estoy tratando de implementar dos módulos HC-SR04 controlados mediante el protocolo I2C con la ayuda de un módulo PCF8574 y todo ello gestionado por mi Arduino MEGA. La cuestión es, que como ya he comprobado, no se puede emplear la función pulseIn() ya que interrumpe el código y por ello la comunicación.

¿Conocéis algún método para programar los módulos HC-SR04 sin la función pulseIn()?

Pd. No adjunto el código porque tengo un batiburrillo de códigos sin funcionar.
Pd2. Tampoco me sirve la opción de conectarlos directamente al Arduino, ya que es para un trabajode la universidad y nos obligan a emplear comunicación serie.

¡Gracias!

2 módulos HC-SR04 que requieren 4 pines, controlados por I2C o sea por 2 pines generandote un monton de problemas de programación con que objetivo si es que además usas un micro que tiene 54 pines I/O.

Sinceramente no se entiende la razón?
Si me dijeras que usas un ATtiny ahi te comprendo o un ESP01, también.
Buscalos y entederás porque hago mi comentario.

De todos modos eres libre de hacer lo que gustes.

Esperaré tu respuesta.

EDITO: como se hace lo que quieres hacer. Pues los pines del PCF8574 pueden programarse como entrada o salida.
Si además el PCF8574 tiene una IRQ disponible.
Acá tienes un buen tutorial que puede guiarte en cómo hacerlo link

Ya, me he dado cuenta que me he metido en un pequeño lio. Pero al tratarse de un trabajo para la universidad lo he de hacer así. Además, empleo este material porque lo tenia por casa, salvo el PCF8574 que lo he comprado pensando que si me serviría. (error mío)

El proyecto en si consiste, de manera teórica, en un asistente de aparcamiento para el coche. Donde el Arduino estará en el salpicadero del coche (controlando mas cosas) y los HC-SR04 y el PCF8574 en la parte de detrás.

Bien, acá tienes un tutorial que usa la interrupción.

// Function interrupt
void keyPressedOnPCF8574();
 
// Set i2c address
PCF8574 pcf8574(0x39, ARDUINO_UNO_INTERRUPT_PIN, keyPressedOnPCF8574);

Remember you can’t use Serial or Wire on interrupt function.

The better way is to set only a variable to read on loop:

La mejor manera es setear solo una variable para que sea leída en el loop.

void keyPressedOnPCF8574(){
    // Interrupt called (No Serial no read no wire in this function, and DEBUG disabled on PCF library)
     keyPressed = true;
}

Muchas gracias por el tutorial, le echaré un vistazo y a ver si me sirve para mi proyecto.

Una idea, así "en el aire" y sin consultar la documentación (todavía).
Podrías memorizar en una variable el valor de micros() inmediatamente mandas el pulso y desde la rutina de servicio de interrupción en otra variable almacenas el valor de micros() en el momento que se produce la misma.
Luego haces los calculos (es una simple resta entre ambas variables) para conocer el ancho del pulso.
Recuerda tener en cuenta el tiempo que tarda la transferecia I2C para descontarlo del valor que obtienes.

Obviamente tienes que leer sobre como manejar interrupciones, pero no es nada terrible tampoco.

Saludos

Si, he mirado por encima lo que me ha enviado el usuario surbyte y habla sobre eso, interrupciones. Tendré que informarme bien porque no tengo ni idea (no suelo programar en texto estructurado).
Respecto a tu idea, si, debería de funcionar. En otros códigos que he visto he intuido que hacen algo parecido, pero hay tantas funciones y procesos que no entiendo que no he sabido hacerle "ingeniería inversa" para aplicarlo a mi proyecto. Tocará sacar papel y boli y empezar a tomar apuntes :smiley:

Si te las arreglas con el inglés (igual siempre está don Google para ayudar) te recomiendo este artículo sobre interrupciones de Nick Gammond.

Saludos

Hola,

Quería dar las gracias a todos los participantes del hilo, al final he conseguido solucionarlo y emplear los módulos HC-SR04 sin la función pulseIn(). Ahora me tocara implementar toda la comunicación I2C, pero eso es otro tema.

Aquí dejo el código por si alguien tuviese el mismo problema:

int trig = 3;
int echo = 2;
volatile uint32_t t, tH, tL, pulseWidth = 0;
int distance;

void setup() {
  pinMode(trig, OUTPUT);
  pinMode(echo, INPUT);

  attachInterrupt(digitalPinToInterrupt(echo), interruption, CHANGE);
  
  Serial.begin(9600);
}

void loop() { 
  digitalWrite(trig, LOW);
  delayMicroseconds(2);

  digitalWrite(trig, HIGH);
  delayMicroseconds(10);
  digitalWrite(trig, LOW);
  
  distance = pulseWidth*0.034/2;
  Serial.println(distance);
  pulseWidth = 0;

  delay(500);
}

void interruption() {
  t = micros();

  if ( digitalRead(echo) == HIGH){
    tH = t;  
  } 
  else {
    tL = t;
    pulseWidth = (tL-tH);  
  }
}

A ver, la lectura de un módulo HC-SR04 esta documentada por toda la web.
He visto muy pocos ejemplos en los que alguien usa pulsein. Pensé que el problema era hacerlo con el PCF8574 no leer un sensor ultrasónico propiamente dicho.

Si vas a seguir con consultas deja abierto el hilo.

A ver, la lectura de un módulo HC-SR04 esta documentada por toda la web.
He visto muy pocos ejemplos en los que alguien usa pulsein. Pensé que el problema era hacerlo con el PCF8574 no leer un sensor ultrasónico propiamente dicho.

Si vas a seguir con consultas por el tema I2C deja el hilo abierto.
Mis links justamente eran para que lo resolvieras de esa forma y no la que has mostrado en el post#8.

Coincido con @surbyte, esa solución es para un sensor conectado directamente al arduino, no te va a servir cuando lo conectes por i2c.

Saludos

@surbyte Si, la intención es hacerlo con el módulo PCF8574, pero en mi caso todos los ejemplos que encontraba para trabajar con el HC-SR04 eran con pulseIn(), así que necesitaba alguna solución alternativa. Ahora que ya tengo claro como funcionan las interrupciones me pongo a implementarlo con I2C y actualizaré con el resultado final.

Mira un consejo, cuando busques algo en español siempre referencia a Luis Llamas. Todo lo que el publica es excelente.
Asi que si ves pulseIn en la web de Luis Llamas me dices. De todas formas te estas iniciando con Arduino y es normal que lo que encuentres lo tomes como la verdad.
Para mi un sensor ultrasónico se lee con NewPing Library

Verás que en lugar de usar pulsein usa micros() pero si dispone usa de los timers del microcontrolador. Es mas avanzado pero no consume tiempo del microcontrolador
De hecho tiene un ejemplo con 15 sensores ultrasónicos.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.