Rad Silviu
Published

Ultrasonic range meter

In this tutorial, I will show you 2 types of ultrasonic range meters.

BeginnerFull instructions provided1 hour591
Ultrasonic range meter

Things used in this project

Hardware components

NodeMCU ESP8266 Breakout Board
NodeMCU ESP8266 Breakout Board
×1
Ultrasonic Sensor - HC-SR04 (Generic)
Ultrasonic Sensor - HC-SR04 (Generic)
×1
Shift Register- Parallel to Serial
Texas Instruments Shift Register- Parallel to Serial
×2
4 Digit 7 Segment Common Cathode Display
×1
Through Hole Resistor, 150 ohm
Through Hole Resistor, 150 ohm
×3

Story

Read more

Schematics

The no wifi ultrasonic range meter

Code

The no wifi ultrasonic range meter

C/C++
//declare the pins used by the shift registers
const int dataPin = D8;
const int latchPin = D7;
const int clockPin = D6;

//declare the pins used by the ultrasonic module
const int echoPin = D2; 
const int trigPin = D1;

//declare a byte variable to store the current digit active
byte digit;

//the next byte variable will tell us when the third digit
//is active, so the dot next to it will turn on
byte dot;

//declare an array of 4 int elements in which we will be
//storing the figures that are going to be displayed on each
//digit of the display
int digits[4];

//this variable will tells us which is the current digit
int currentDigit = 0;

//declare the exponential moving average
double ema = 0;

//function that will trigger every
//move the function to RAM using ICACHE_RAM_ATTR
void ICACHE_RAM_ATTR timer_function()
{
  //select the digit
  Digit(currentDigit);

  //if we are at the third digit, then modify the bit 
  //for the dor from 0 to 1
  if(currentDigit == 2)
      dot = 0b10000000;

  //display the number on the selected digit
  Number(digits[currentDigit]);
  
  //go to the next digit
  currentDigit++;

  //if we are at the last digit, then go to the first one
  if(currentDigit > 3)
     currentDigit = 0;

  //initialize this function again after 4 ms
  timer1_write(20000);
}

void setup()
{
  //set the pins used by the shift registers to output
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);

  //the trigger pin (transmitter) must be set as OUTPUT  
  pinMode(trigPin, OUTPUT); 

  //the echo pin (receiver) must be set as INPUT
  pinMode(echoPin, INPUT); 
  
  //initialize the timer every 4 ms
  //enable the timer with the divider TIM_DIV16 which
  //has a value of 5 ticks/microsecond
  timer1_attachInterrupt(timer_function);
  timer1_enable(TIM_DIV16, 0, 0);
  
  //divide the ticks by 5 and that is the value in microseconds
  timer1_write(20000);
}

void loop() 
{
  //calculate the distance
  calculate_distance();
}

void calculate_distance()
{
  //set the trigPin LOW in order to prepare for the next reading
  digitalWrite(trigPin, LOW);

  //delay for 2 microseconds
  delayMicroseconds(2);

  //generate a ultrasound for 10 microseconds then turn off the transmitter
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  //reads the echoPin, returns the sound wave travel time in microseconds
  long duration = pulseIn(echoPin, HIGH, 400*2/0.034);

  //using the formula shown in the guide, calculate the distance
  double distance = duration*0.034/2;

  //calculate the Exponential Moving Average
  double k = 2.0/(10+1);
  ema = distance*k + ema*(1-k);

  //multiply the ema by 10 to get also the first decimal
  int dist = (int)(ema*10);
  
  //if the modified distance is greater than 0, then extract the figures
  if(dist > 0)
  {
    digits[3] = dist%10;
    digits[2] = (dist/10)%10;
    digits[1] = (dist/100)%10;
    digits[0] = dist/1000;
  }

  //wait 50 ms before next reading
  delay(100);
}

//this function is used to select the digit to be turned on
void Digit(int x)
{
  //turn off all the digits and segments
  //because we use a common cathode display, to turn off the digits
  //we have to set them to HIGH 
  //15 written as 8 bits is B00001111 
  digitalWrite(latchPin, 0);
  shiftOut(dataPin, clockPin, MSBFIRST, 15);
  shiftOut(dataPin, clockPin, MSBFIRST, 0);
  digitalWrite(latchPin, 1);

  //reset the dot variable
  dot = 0;
  
  //the switch statement is used to select the right digit
  switch(x)
  {
  case 0: 
    //prepare to turn on only the first digit
    digit = 14; //B00001110
    //break is used to get out from the switch function
    break;
  case 1:
    //prepare to turn on only the second digit 
    digit = 13; //B00001101
    break;
  case 2: 
    //prepare to turn on only the third digit
    digit = 11; //B00001011
    break;
  default: 
    //prepare to turn on only the fourth digit
    digit = 7; //B00000111
    break;
  }
}

//this function is used to select a number to display
void Number(int x)
{
    //deppending on the value of x, using the switch statement
    //we are calling a specific function to display on the selected 
    //digit a number indicated by the name of the function
    switch(x)
    {
      default: 
        zero(); 
        break;
      case 1: 
        one(); 
        break;
      case 2: 
        two(); 
        break;
      case 3: 
        three(); 
        break;
      case 4: 
        four(); 
        break;
      case 5: 
        five(); 
        break;
      case 6: 
        six(); 
        break;
      case 7: 
        seven(); 
        break;
      case 8: 
        eight(); 
        break;
      case 9: 
        nine(); 
        break;
    }
}

//to make our code shorter and to have only one function for
//zero, one etc., we are going to use the bitwise OR operator
//to change the bit for the dot before sending it to the
//shift register
void zero()
{
  //display on the selected digit a "0"
  digitalWrite(latchPin, 0);
  shiftOut(dataPin, clockPin, MSBFIRST, digit);
  shiftOut(dataPin, clockPin, MSBFIRST, 0b00111111 | dot);
  digitalWrite(latchPin, 1);
}
 
void one()
{
  //display on the selected digit a "1"
  digitalWrite(latchPin, 0);
  shiftOut(dataPin, clockPin, MSBFIRST, digit);
  shiftOut(dataPin, clockPin, MSBFIRST, 0b00000110 | dot);
  digitalWrite(latchPin, 1);
}
 
void two()
{
  //display on the selected digit a "2"
  digitalWrite(latchPin, 0);
  shiftOut(dataPin, clockPin, MSBFIRST, digit);
  shiftOut(dataPin, clockPin, MSBFIRST, 0b01011011 | dot);
  digitalWrite(latchPin, 1);
}
 
void three()
{
  //display on the selected digit a "3"
  digitalWrite(latchPin, 0);
  shiftOut(dataPin, clockPin, MSBFIRST, digit);
  shiftOut(dataPin, clockPin, MSBFIRST, 0b01001111 | dot);
  digitalWrite(latchPin, 1);
}
 
void four()
{
  //display on the selected digit a "4"
  digitalWrite(latchPin, 0);
  shiftOut(dataPin, clockPin, MSBFIRST, digit);
  shiftOut(dataPin, clockPin, MSBFIRST, 0b01100110 | dot);
  digitalWrite(latchPin, 1);
}
 
void five()
{
  //display on the selected digit a "5"
  digitalWrite(latchPin, 0);
  shiftOut(dataPin, clockPin, MSBFIRST, digit);
  shiftOut(dataPin, clockPin, MSBFIRST, 0b01101101 | dot);
  digitalWrite(latchPin, 1);
}
 
void six()
{
  //display on the selected digit a "6"
  digitalWrite(latchPin, 0);
  shiftOut(dataPin, clockPin, MSBFIRST, digit);
  shiftOut(dataPin, clockPin, MSBFIRST, 0b01111101 | dot);
  digitalWrite(latchPin, 1);
}
 
void seven()
{
  //display on the selected digit a "7"
  digitalWrite(latchPin, 0);
  shiftOut(dataPin, clockPin, MSBFIRST, digit);
  shiftOut(dataPin, clockPin, MSBFIRST, 0b00000111 | dot);
  digitalWrite(latchPin, 1);
}
 
void eight()
{
  //display on the selected digit a "8"
  digitalWrite(latchPin, 0);
  shiftOut(dataPin, clockPin, MSBFIRST, digit);
  shiftOut(dataPin, clockPin, MSBFIRST, 0b01111111 | dot);
  digitalWrite(latchPin, 1);
}
 
void nine()
{
  //display on the selected digit a "9"
  digitalWrite(latchPin, 0);
  shiftOut(dataPin, clockPin, MSBFIRST, digit);
  shiftOut(dataPin, clockPin, MSBFIRST, 0b01101111 | dot);
  digitalWrite(latchPin, 1);
}

The wifi ultrasonic range meter

C/C++
#include <ESP8266WebServer.h>

const char* ssid = "Your wifi ssid ";
const char* password = "Your wifi password";

//declare the pins used by the module
const int echoPin = D5; 
const int trigPin = D3;

//declare 2 variables which help us later to calculate the distance
long duration;
double distance;

ESP8266WebServer server(80);

String page =
R"(
<html>  
  <head> 
    <script src='https://code.jquery.com/jquery-3.3.1.min.js'></script>
    <title>Plusivo</title> 
  </head> 

  <body> 
    <h2>Hello from Plusivo!</h2> 
    <table style='font-size:20px'>  
      <tr>  
        <td> 
          <div>Distance:  </div>
        </td>
        <td> 
          <div id='Distance'></div> 
        </td>
       </tr> 
    </table>  
  </body> 
  
  <script> 
   $(document).ready(function(){ 
     setInterval(refreshFunction,100); 
   });

   function refreshFunction(){ 
     $.get('/refresh', function(result){  
       $('#Distance').html(result);  
     }); 
   }      
  </script> 
</html> 
)";

void refresh()
{ 
  //create a char array
  char messageFinal[100];

  //put the distance value in buffer
  sprintf(messageFinal, "%.2f", distance);

  //send data to user
  server.send(200, "application/javascript", messageFinal);
}

//the htmlIndex() is called everytime somebody access the address
//of the board in the browser and sends back a message.
void htmlIndex() 
{
  //send the message to the user
  server.send(200, "text/html", page);
}

//connectToWiFi() is used to connect to the WiFi network
//using the SSID and PASSWORD variables created at the
//beginning of the code
void connectToWiFi()
{ 
  Serial.println("Connecting to the WiFi");
  //set the WiFi mode to WiFi_STA.
  //the WiFi_STA means that the board will act as a station,
  //similar to a smartphone or laptop
  WiFi.mode(WIFI_STA);

  //connect to the WiFi network using the ssid and password strings
  WiFi.begin(ssid, password);

  //below we check the status of the WiFi and wait until the
  //board is connected to the network
  Serial.println("Waiting for connection");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  //when the board is successfully connected to the network,
  //display the IP assigned to it in the serial manager.
  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
}

//setupServer() function is used to set up and organise
//the website
void setupServer()
{ 
  //the method "server.on()" is to call a function when
  //the user access the location
  //the default location is "/"
  server.on("/", htmlIndex);
  server.on("/refresh", refresh);
 
  //start the server
  server.begin();
  
  //print in serial manager that the HTTP server is started
  Serial.println("HTTP server started");
}

void setup() 
{
  //the trigger pin (transmitter) must be set as OUTPUT  
  pinMode(trigPin, OUTPUT); 

  //the echo pin (receiver) must be set as INPUT
  pinMode(echoPin, INPUT); 

  //start the Serial communication at 115200 bits/s
  Serial.begin(115200);
  
  //wait 1s so the serial communication has enough time to start
  delay(1000);

  //call the two functions used to connect to the wireless network
  //and setup the web server
  connectToWiFi();
  setupServer();
}
 
void loop() 
{
  //the method below is used to manage the incoming requests 
  //from the user
  server.handleClient();

  // Set the trigPin LOW in order to prepare for the next reading
  digitalWrite(trigPin, LOW);
  
  //delay for 2 microseconds
  delayMicroseconds(2);

  //generate a ultrasound for 10 microseconds then turn off the transmitter.
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  //reads the echoPin, returns the sound wave travel time in microseconds
  duration = pulseIn(echoPin, HIGH);

  //using the formula shown in the guide, calculate the distance
  distance = duration*0.034/2;
}

Credits

Rad Silviu
12 projects • 8 followers

Comments