Ultrasonic Sensor

From Pinguino-Wiki
Jump to: navigation, search
Language: English  • Español


Contents

Ultrasonic sensor HC-SR04

This is an example for measuring a distance to an obstacle with the ultrasonic sensor HC-SR04. The sensor needs an operational voltage of 5V, draws 15mA of current and you will need a level shifter if you work with an 3.3V PIC (for example a PIC32-Pinguino-220). (More to come...)

Wiring

(thumbnail)
Photo of the sensor with named pins


Bidirectional Level Shifter

(thumbnail)
Schematic of a bidirectional level shifter with 2N7000

Operation

TODO

Code for 8 bit PICs

/*----------------------------------------------------- 
File:        hc-sr04_p8.pde
Author:      Edermar Dominguez <Edermar_12[_at_]hotmail.com>
Date:        31 Jan 2013
Changes by:  Oliver Göpferich <pinguplus[_at_]live.de>
Date:        Sat Mar 22 09:47:36 2014
Description: Measure the distance to an obstacle using
             the Ultrasonic sensor HC-SRC04
PIC:         PIC18F25k50
Should also work with any other 8 bit PIC18F
-----------------------------------------------------*/
 
int trig = 3;
int echo = 4;
unsigned long pulse;
float distance;
 
void setup() {
    Serial.begin(9600);
    pinMode (USERLED,OUTPUT);
 
    pinMode (echo,INPUT);      // Declare the echo pin as INPUT
    pinMode (trig,OUTPUT);     // Declare the trigger pin as OUTPUT
 
    digitalWrite(USERLED,LOW);
    }
 
 
// I'm using my own pulseIn() function, because builtin pulseIn()
// provides to high values with the 25k50
 
unsigned long myPulseIn(unsigned char pin, unsigned char state, unsigned long timeout)
{
	unsigned long width = 0; // keep initialization out of time critical area
 
	// convert the timeout from microseconds to a number of times through
	unsigned long numloops = 0;
	unsigned long maxloops = timeout / 10; //We have a microsecond by 10 loops (mean).
 
 
	// wait for any previous pulse to end
	while (digitalRead(pin) == state) {
		if (numloops++ == maxloops) {
			return 0;
    }
  }
 
	// wait for the pulse to start
	while (digitalRead(pin) != state)
		if (numloops++ == maxloops) {
			return 0;
    }
 
	// wait for the pulse to stop
	while (digitalRead(pin) == state) {
		width++;
  }
 
	//There will be some error introduced by the interrupt handlers.
	//At last loop, each interaction have 12us + 60us from digitalRead() instructions
 
   //return width * 12 + 60;
 
   return width * 9;
}
 
 
void medirdistance() {
    // set the trigger for 2 ms low
    digitalWrite(trig, LOW);
    delayMicroseconds(2);
 
    // Set the trigger for 15 ms high (minimum 10 ms)
    digitalWrite(trig, HIGH);
    delayMicroseconds(15);
 
    // Set the trigger low. This starts the measuring procedure.
    digitalWrite(trig, LOW);
 
    // Measure the length of the input signal
    pulse = myPulseIn(echo, HIGH, 3000);
 
    // The speed of sound is 29 cm/second (/29). The ultrasonic pulse travels
    // the distance to the obstacle and back (/2).
    distance = (float)(((pulse)/29.0/2.0));
 
    Serial.printf("Puls: %d\r\n", pulse);
    Serial.printf("distance: %f cm\r\n", distance);
 
    toggle(USERLED);
 
    // Just wait for a second
    delay(1000);
}
 
 
void loop() {
    //run repeatedly:
    medirdistance();
}

Code for 32 bit PICs

/*----------------------------------------------------- 
File:        hc-sr04_p32.pde
Author:      Edermar Dominguez <Edermar_12[_at_]hotmail.com>
Date:        31 Jan 2013
Changed by:  Oliver Göpferich <pinguplus[_at_]live.de>
Date:        Sat Mar 22 09:47:36 2014
Description: Measure the distance to an obstacle using
             the Ultrasonic sensor HC-SRC04
Board:       Pic32-Pinguino-220
Should also work with other PIC32MX
-----------------------------------------------------*/
 
#define UARTPORT UART2
#define UARTSPEED 19200
 
u32 baudrate;
int trig = 3;
int echo = 4;
unsigned long pulse;
float distance;
 
void setup() {
    // With a PIC32MX220 CDC will not work because of to low flash memory
    // That's why I'm using UART
    baudrate = UARTSPEED; 	// 300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, until Sys. Clock / 4
    SerialP32MX.configure(UARTPORT, UART_ENABLE, UART_RX_TX_ENABLED,	baudrate);
    pinMode (USERLED,OUTPUT);
 
    pinMode (echo,INPUT);      // Declare the echo pin as INPUT
    pinMode (trig,OUTPUT);     // Declare the trigger pin as OUTPUT
 
    digitalWrite(USERLED,LOW);
    }
 
 
// I'm using my own pulseIn() function, because builtin pulseIn() for p32
// didn't work for me
 
unsigned long myPulseIn(unsigned char pin, unsigned char state, unsigned long timeout)
{
	unsigned long width = 0; // keep initialization out of time critical area
 
	// convert the timeout from microseconds to a number of times through
	unsigned long numloops = 0;
  unsigned long maxloops = timeout;
 
	// wait for any previous pulse to end
	while (digitalRead(pin) == state) {
		if (numloops++ == maxloops) {
			return 0;
    }
  }
 
	// wait for the pulse to start
	while (digitalRead(pin) != state)
		if (numloops++ == maxloops) {
			return 0;
    }
 
	// wait for the pulse to stop
	while (digitalRead(pin) == state) {
		width++;
  }
 
	//There will be some error introduced by the interrupt handlers.
	//At last loop, each interaction have 12us + 60us from digitalRead() instructions
	//return width * 12 + 60;
 
   #if defined (PIC32_PINGUINO_220) || defined (PINGUINO32MX220) || defined (PINGUINO32MX250)
   return width;
   #elif defined (PIC32_PINGUINO) || defined(PIC32_PINGUINO_OTG) || defined (PIC32_PINGUINO_MICRO) || defined (PIC32_PINGUINO_T795)
   return width * 2;
   #else
   return width;
   #endif
}
 
 
void medirdistance() {
    // set the trigger for 2 ms low
    digitalWrite(trig, LOW);
    delayMicroseconds(2);
 
    // Set the trigger for 15 ms high (minimum 10 ms)
    digitalWrite(trig, HIGH);
    delayMicroseconds(15);
 
    // Set the trigger low. This starts the measuring procedure.
    digitalWrite(trig, LOW);
 
    // Measure the length of the input signal
    pulse = myPulseIn(echo, HIGH, 10000);
 
    // The speed of sound is 29 cm/second (/29). The ultrasonic pulse travels
    // the distance to the obstacle and back (/2).
    distance = (float)(((pulse)/29.0/2.0));
 
    SerialP32MX.printf(UARTPORT, "Puls: %d\r\n", pulse);
    SerialP32MX.printf(UARTPORT, "distance: %f cm\r\n", distance);
 
    toggle(USERLED);
 
    delay(1000); 
}
 
 
void loop() {
    //run repeatedly:
    medirdistance();
}
Personal tools