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:
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:
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.
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.
And finally, I checked with my own satshakit. I used PD5 and PD6 as trigger and echo. The sensor was working as expected.
You can find some information on the accuracy of sensor datasheet.
A code example can be found here.
Due to the measurement principle, the sensor is not as precise in close proximity.
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.
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.
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.
From checking the serial, I checked that everything works as expected.
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.
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.
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); }