Week 13 - Input devices

Menu

Input devices

Input devices are basically all sorts of sensor components, measuring motion, sound, light, temperature, distances, acceleration and many more. In my case, I will look specifically into different technologies to measure distances which will then be integrated into my final project as a collision avoidance sensor. I am planning to look into three different technologies:

  1. Ultrasonic: measure a distance by sound
  2. Infrared: measure by means of infrared light
  3. TOF: time of fight sensor

I will do the prototyping with an Arduino Uno first and use my modified Satshakit which created in Week 10 - output devices. The design files are also available in the Download section.

So here is the tasks for Week 13:

Programming devices

Ultrasonic sensor - HC-SR04:

I have used ultrasonic sensors before. In this case, I used some piece of code from instructables and modified it according to my needs. The data sheet can be found here. The accuracy is around 3 mm for a distance from 2 cm to 400 cm. If the area is too small reflections might cause inaccuracies. The same is true if more than one sensor is being used and signal are overlapping.

image UltrasonicSensorArduino HC-SR04 ultrasonic sensor
image UltrasonicWiring Wiring of ultrasonic sensor

The code:

/*
HC-SR04 Ping distance sensor]
VCC to arduino 5v GND to arduino GND
Echo to Arduino pin 13 Trig to Arduino pin 12
*/
#define trigPin 13
#define echoPin 12


void setup() {
  Serial.begin (9600);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
}

void loop() {
  // Trigger signal
  long duration, distance;
  digitalWrite(trigPin, LOW); 
  delayMicroseconds(2); 
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  // Return signal
  duration = pulseIn(echoPin, HIGH); // wait for the pin to go high
  distance = (duration/2) / 29.1; // way there and back, speed of sound: 29.1 cm/microsecond

  // Serial monitor - up to 200 cm range
  if (distance >= 200 || distance <= 0){
    Serial.println("Out of range");
  }
  else {
    Serial.print(distance);
    Serial.println(" cm");
  }
  delay(500);
} 

Now that the code is working, I can transfer it to the Satshakit.

image UltrasonicWorks The sensor works

And finally, I checked with my own satshakit. I used PD5 and PD6 as trigger and echo. The sensor was working as expected.

image Satshakit_Ultrasonic Ultrasonic sensor connected to the Satshakit
image UltrasonicSatshakitWorking Ultrasonic sensor works as expected

Infrared sensor - Sharp 2Y0A21

You can find some information on the accuracy of sensor datasheet.

  1. Distance measuring range : 10 to 80 cm
  2. Analog output type
  3. Package size : 29.5×13×13.5 mm
  4. Consumption current : Typ. 30 mA
  5. Supply voltage : 4.5 to 5.5 V

A code example can be found here.

image InfraredSensorConnected Sharp 2Y0A21 infrared sensor
image InfraredSensor Wiring of infrared sensor

Due to the measurement principle, the sensor is not as precise in close proximity.

image SensitivityInfraredSensor accuracy of the infrared sensor

The sensor data can be read with a simple analogRead command. To come from analog data to a distance, I wanted to do simple calibration measuring distance and reading the analog values from the serial monitor.

image CalibrationInfrared Calibration infrared: reading actual distance
image CalibrationInfraredAnalogData Calibration infrared: reading analog values

Here are the values read I read from the ruler and the sensor, as well as the -calculated- reciprocal analog reading:

Analog value [-] 1/Analog read [-] Distance [cm]
630 0.0015873 5
557 0.00179533 8
440 0.00227273 10
380 0.00263158 12
318 0.00314465 15
245 0.00408163 20

As the data sheet implied a antiproportional correlation, I drew a linear regression from the reciprocal analog reading. The resulting line had an inclination of 5026 [Analog Reading*cm], the intercept can be neglected. Dividing this value by the actual reading gives a rather accurate value for the distance for small distances.

image CalibrationGraph_analog Calibration infrared: Analog data
image CalibrationGraph_1DividedByAnalog Calibration infrared: 1 / Analog data

The code:

//collects data from an analog sensor

int sensorpin = 3;                 // analog pin used to connect the sharp sensor
int val = 0;                 // variable to store the values from sensor(initially zero)

void setup()
{
  Serial.begin(9600);               // starts the serial monitor
}

void loop()
{
  val = analogRead(sensorpin);    // reads the value of the sharp sensor
  val = 5026/val;                 // Conversion from analogReading to cm
  Serial.println(val);            // prints the value of the sensor to the serial monitor
  
  delay(400);                     // wait for this much time before printing next value
}

Finally, I tested the design on my board. I used A1 as my input pin which is Arduino pin A0.

image InfraredSatshakit Data pin connection Satshakit
image InfraredSatshakitWiring Data pin connection Satshakit

From checking the serial, I checked that everything works as expected.

Satshakit test infrared sensor

TOF - time of flight sensor

I also tested the VL53L0X which claims to be the world smallest time-of-flight (TOF) sensor. You can download the data sheet here.

In the image, I'm using a web application to read the data. I will describe this further Week 16 but as the sensor is writing serial data, you can simply use the serial monitor to display the readings.

image SensorTestJavaScript VL53L0Xconnected

Connecting the sensor to I2C discovered something I had not considered upfront. As I have some dedicated ports for the stepper motor driver socket which include the native I2C ports. So later on, I will have to use software I2C ports.

image PortsI2C Ports layout on the Satshakit
image PortsBoardView Ports in Board View

Connections of the sensor to the Arduino:

The code:

#include "Adafruit_VL53L0X.h"

Adafruit_VL53L0X lox = Adafruit_VL53L0X();

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

  // wait until serial port opens for native USB devices
  while (! Serial) {
    delay(1);
  }
  
  //Serial.println("Adafruit VL53L0X test");
  if (!lox.begin()) {
    Serial.println(F("Failed to boot VL53L0X"));
    while(1);
  }
  // power 
  //Serial.println(F("VL53L0X API Simple Ranging example\n\n")); 
}


void loop() {
  VL53L0X_RangingMeasurementData_t measure;
    
  //Serial.print("Reading a measurement... ");
  lox.rangingTest(&measure, false); // pass in 'true' to get debug data printout!

  if (measure.RangeStatus != 4) {  // phase failures have incorrect data
    //Serial.print("Distance (mm): "); Serial.println(measure.RangeMilliMeter);
    Serial.println(measure.RangeMilliMeter);
  } else {
    //Serial.println(" out of range ");
    Serial.println("2000");     // Default for "out of range"
  }
    
  delay(100);
}

Download files