Category Archives: Arduino

Using the ultrasound sensor HC SR04

My first foray into Ardunio programming is to implement a robot based upon the Arduino Motor shield and some sensors – starting with the HC SR04.

In this case I want a sensor that will tell me the distance from objects, so hopefully the robot will not go around smashing into walls etc. This is where the HC SR04 comes in.

The HC SR04 has four pins. We simply connect the VCC pin to the 5V pin on the Arduino, the GND to the Arduino’s ground pin and then we’re left with two other pins.

The trigger and echo pins are digital pins, the idea being we send a 10 microsecond pulse to the trigger pin and the module will send back (via the echo pin) a value whose duration we can use to calculate the distance “pinged”. But we don’t just read the digital pin, we instead use the pulseIn function.

I’m indebted to others who have kindly supplied information on how to program this sensor, I’ve added references at the bottom of this post. I’m writing this post simply to detail the steps and code I successfully used to get this working. The referenced posts are definitely the best posts for full information on this sensor, hardware connections and code.

Here’s a simple C++ class (header and source) for handling this sensor

#ifndef _ULTRASOUND_h
#define _ULTRASOUND_h

#if defined(ARDUINO) && ARDUINO >= 100
   #include "Arduino.h"
#else
   #include "WProgram.h"
#endif

class Ultrasound
{
private:
	int triggerPin;
	int echoPin;

public:

	void init(int tiggerPin, int echoPin);
	long ping();
};

#endif

and the corresponding source

#include "Ultrasound.h"

void Ultrasound::init(int triggerPin, int echoPin)
{
   this->triggerPin = triggerPin;
   this->echoPin = echoPin;

   pinMode(triggerPin, OUTPUT);
   pinMode(echoPin, INPUT);
}

long Ultrasound::ping()
{
   digitalWrite(triggerPin, LOW);
   delayMicroseconds(2);
   digitalWrite(triggerPin, HIGH);
   delayMicroseconds(10);
   digitalWrite(triggerPin, LOW);

   long duration = pulseIn(echoPin, HIGH);
   long distance = (duration / 2) / 29.1;
   // >= 200 or <= 0 are error values, or out of range
   return distance >= 200 || distance <= 0 ? -1 : distance;
}

References

Ultrasonic Ranging Module HC – SR04
Simple Arduino and HC-SR04 Example
Complete Guide for Ultrasonic Sensor HC-SR04

Getting started with the Arduino

Let’s get started with some basics using the Arduino.

Note: I am using the Arduino Uno, so references to the specification of the Arduino should be taken as specific to the Uno.

The Arduino is programmed using C/C++ and includes libraries which make programming simple and programming the Arduino even simpler. Arduino programs are known as sketches.

My aim in this post in not to repeat everything in the excellent Arduino documentation but to just show code snippets (Arduino sketches) to simply demonstrate the principles of getting started programming the Arduino.

The Basics

Whether using the Arduino IDE/application or the Visual Micro for Visual Studio (or any other editor) and Arduino application requires at the bare minimum a setup function and a loop function, which are simply written as

void setup()
{
   // your setup goes here 
}

void loop()
{
   // your code goes here 
}

The setup as the name suggests, is used to initialize variables or set pin modes (discussed later) etc. The Arduino calls the setup and then the loop.

An Arduino is single threaded, the loop is where we add our “main” code. Of course we can create further functions that are called from the loop. Just remember when the loop function exits, the Arduino will call the function again and so on.

Input/Output

The Arduino microcontroller has digital input/outputs and analog input pins. There are no analog output pins but we can simulate such output using PWM.

Digital pins

Digital pins can be configured as either inputs or outputs. Digital pins 1 to 13 are available for input/output with digital pins marked with the tilde ~ on the Uno being pins capable of PWM and therefore simulating analog output.

By default, digital pins are inputs, but within the setup we can change them to outputs. Let’s take a look at how we do this

const int inputPin = 1;
const int outputPin = 3;

void setup()
{
   pinMode(inputPin, INPUT); // setting a digital pin for INPUT
   pinMode(outputPin, OUTPUT); // setting a digital pin for OUTPUT
}

Once the pins have been setup for I/O we need a way to read/write data from/to those pins.

Note: I will discuss using digital pins for PWM in the Analog section

Let’s look at the code to read and write to the digital pins

int value;

void loop()
{
   value = digitalRead(inputPin);
   digitalWrite(outputPin, value);
}

Digital values are HIGH and LOW (think ON and OFF), so a digitalRead will return either HIGH or LOW and likewise the digitalWrite can write a HIGH or LOW.

One thing to note is that when the pins are used for input they’re in a “high impedance state”, for us programmers this basically means that small changes can change the pin from LOW to HIGH or vice versa, and more importantly it means that if they have nothng connected to them and we’re reading their state we will get random changes in the pin state as they pick up “noise”. See Arduino General Purpose Input & Output (GPIO) Pins Explained for more on this subject.

Analog

As stated previous, there are no analog output pins, but we can use the digital pins as output pins and using PWM simulate analog output.

First off let’s take a look at the Arduino Uno and you’ll see 6 Analog input pins, marked A0 to A5. To read from the analog pins we simple use the analogRead method, for example

int value;

void setup()
{
   value = analogRead(0);
}

Analog input voltages range from 0 to 5V which results in an integer value from 0 to 1023. However when outputting analog values we can only write values 0 to 255.

We can use the map function to scale the values from input to output if we need to, i.e.

int value = map(inputValue, 0, 1023, 0, 255); 

As mentioned, we cannot write analog data to analog pins but we can write data to digital PWM pins. The Arduino library kindly gives us a function analogWrite which handles everything for us, we just need to specify one of the PWM pins for output, for example

const int outputPin = 3;

void setup()
{
   pinMode(outputPin, OUTPUT);
}

int value = 0;

void loop()
{
   if (value > 255)
      value = 0;

   analogWrite(outputPin, value++);
   delay(1000);
}

Serial I/O

We can use the UART via the Serial functions to communicate with other devices, for example intercommunication between the Arduino and a connected PC.

In such a case you might use the Serial functions to write debug information and within the Arduino IDE you can monitor the connected COM port and view the debug output.

To setup and use the Serial port we can use the following code (from the Arduino)

void setup()
{
   Serial.begin(9600);
}

void loop()
{
   if (value > 255)
      value = 0;

   Serial.println(value);
   value++;

   delay(1000);
}

With the above code, if we view the output in the serial port monitor we’ll simply see the value variable slowly (with a 1 second delay between each iteration) increase until it reaches 1024 and then it’s reset to 0.

So, we can output to the COM port but the Arduino can also read input from the COM port and thus we can create two way communications between the Arduino and another device.

For example

const int outputPin = 3;

void setup()
{
   Serial.begin(57600);
}

int value = 0;

void loop()
{
   if (Serial.available() > 0)
   {
      value = Serial.parseInt();
      if (value < 0)
         value = 0;
   }
   Serial.println(value);

   analogWrite(outputPin, value);
}

In the above code we use the parseInt method instead of the read method. The parseInt method simply takes the input and converts to an integer, so for example if using the serial port monitor within the Arduino IDE, sending 0 will result in the ASCII value (or 49) being received by the Arduino – parseInt converts this to an integer for us.

References

There are many excellent resources on the Arduino, some of which I have referenced for this post, others I will add here because they may be of use.

The Arduino Uno
Introduction to the Arduino Board
Arduino Quick Reference
Arduino Uno Schematic