0% found this document useful (0 votes)
18 views

MEC8063 Tutorial 3 Sensors

Uploaded by

yulin lin
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
18 views

MEC8063 Tutorial 3 Sensors

Uploaded by

yulin lin
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 25

MEC8063 Introduction to Mechatronics Design

Tutorial 3 – Sensors

Objective: This tutorial is to gain experience in connecting sensor systems to the Arduino and examining various
options for receiving the data. It also highlights the importance of calibrating sensors.

Reading: It is best to read pages 31 – 74 of “Mechatronics : electronic control systems in mechanical and
electrical engineering” by W. Bolton before commencing this tutorial.

1. Introduction

There are a multitude of sensors available ranging in performance and price. Some of these sensors are basic and
require additional electronics whilst others come as ready to use systems. For this tutorial, we will only consider 4
sensors. Although this is a limited range in terms of sensing options (a more comprehensive list can be found in
the recommended reading for this tutorial), the examples chosen demonstrate the typical range of connection
options available. The tutorial will cover digital input, analogue input, pulse width (timing) and comms.

The sensors used in the simulation aspects of this tutorial will not be exactly the same as the sensors described in
the practical work however connectivity and functionality are the same. Note that in some cases the simulations
run slow and when changing the sensor values the program may take a little time to react. For each of the
following exercises, build a new circuit for each sensor. Ultimately, you will need to connect several sensors at the
same time but for now, it is best to see how each one works and what types of connection pins are needed.

2. Simulation tutorials

2.1. Microswitch (digital input example)

Open Tinkercad and connect a Pushbutton to the Arduino as shown in figure 1. Although a breadboard is not
essential for these simple circuits, it is worth starting to use one from the outset to connect components as it
makes it easier to track your wiring (see Appendix 1 for how breadboards are arranged). This would also be the
practical way of connecting your circuits if you were to build it. Using the example program Button shown in
figure 2 (this can be found in the examples on the Arduino IDE), run the simulation. You should hopefully see the
internal LED (labelled L on the Arduino) turn on when the pushbutton is pressed (to push the virtual pushbutton
place the mouse cursor over the pushbutton and hold down the left mouse button, you should see a slight change
in the shadow of the pushbutton when it is pressed).

Figure 1: A simple pushbutton circuit.

John Hedley, School of Engineering, 2024. Page 1


MEC8063 Introduction to Mechatronics Design

/* Button
created 2005 by DojoDave
modified 30 Aug 2011 by Tom Igoe
http://www.arduino.cc/en/Tutorial/Button
*/

// constants won't change. They're used here to set pin numbers:


const int buttonPin = 2; // the number of the pushbutton pin
const int ledPin = 13; // the number of the LED pin

// variables will change:


int buttonState = 0; // variable for reading the pushbutton status

void setup()
{
// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT);
}

void loop()
{
// read the state of the pushbutton value:
buttonState = digitalRead(buttonPin);

// check if the pushbutton is pressed. If it is, the buttonState is HIGH:


if (buttonState == HIGH)
{
// turn LED on:
digitalWrite(ledPin, HIGH);
}
else
{
// turn LED off:
digitalWrite(ledPin, LOW);
}
}

Figure 2: The Arduino example program Button (found in Examples – Digital – Button).

The problem is that the LED remains on regardless of whether the button is pressed. This is because the output
voltage (your connection to pin 2) is floating, we do not know what voltage it is when the button is released. To
check this voltage, we can connect a multimeter (set to measure V) as shown in figure 3.

John Hedley, School of Engineering, 2024. Page 2


MEC8063 Introduction to Mechatronics Design

Figure 3: Measuring the floating voltage (albeit it is not floating once you try to take this measurement).

When we run the program, you should see the voltage changes from 5V when the button is pressed to around
50mV when released (and the LED goes out) – suddenly the circuit is working. What you have actually done by
using the multimeter is that in addition to measuring the voltage, you have added a pull-down resistor to the
circuit (the multimeter has an internal resistance of around 1 MΩ and so we have effectively connected pin 2 to
ground via a high resistance). We shall complete the circuit correctly and add an appropriate pull-down resistor (a
value of 4.7 kΩ connected between pin 2 and GND) as shown in figure 4. The circuit should now work as
expected.

Figure 4: Pushbutton with pulldown resistor.

You can invert this operation (light goes off when button is pressed) by using a pullup resistor as shown in figure
5. The floating voltage is now held high with the resistor connected to the 5V supply and shorted to ground when
the button is pressed. Also note the appropriate use of wire colouring, although the wire colour has no effect on
the circuit it allows you (and anyone else) to clearly see the difference between circuits shown in figure 4 and 5.
An alternative to figure 5 is to remove the pullup resistor and use the alternative software option (utilising the
internal pullup resistor in the Arduino) by changing the pinMode command to:

pinMode(buttonPin, INPUT_PULLUP);

John Hedley, School of Engineering, 2024. Page 3


MEC8063 Introduction to Mechatronics Design

Figure 5: Pushbutton with pullup resistor.

Another issue with real mechanical switches is ‘bounce’. This is where the switch makes intermittent contact
upon closing before it finally comes to a rest in the closed position. This can be problematic if you are counting
the number of times the switch is closed. To resolve this, you should use a debounce option, this can be done
electronically with an appropriate circuit or in the software where you write the code so that if the switch
changes state, there is a delay before it is read again. An example of this is shown in the Arduino Examples –
Digital – Debounce program (alternatively see https://www.arduino.cc/en/Tutorial/BuiltInExamples/Debounce).

The code we have used to read the state of the microswitch is known as ‘polling’, we are asking the pin for its
condition. The alternative approach is for the microswitch to effective ‘tell’ the Arduino that its state has changed.
This is known as an ‘interrupt’ and the Arduino knows exactly when the switch has changed, as opposed to polling
where the Arduino has to waiting for the part of the code to read. Thus if timing is critical, for example the
microswitch is used as part of a car’s bumper and indicates a collision has occurred, the car must immediately
stop and therefore an interrupt should be used. We will learn more about interrupts when we discuss motors.

2.2. Temperature sensor (analogue input example)

A range of sensors have an analogue voltage as an output, in this circuit will use the TMP36 temperature sensor
(the datasheet for this can be found at https://www.analog.com/media/en/technical-documentation/data-
sheets/TMP35_36_37.pdf ). Connect up the circuit as shown in figure 6 carefully noting the pin designations of
Power, Vout and GND of the sensor. Then program the Arduino to digitise an analogue voltage presented on pin
A0 (using the program from tutorial 1, figure 11). Run the simulation and try altering the value of the temperature
sensor using its slider input, you should see corresponding change in the value printed over the serial port of the
Arduino from 20 to 358.

Figure 6: Connecting the TMP36 temperature sensor to the Arduino.

John Hedley, School of Engineering, 2024. Page 4


MEC8063 Introduction to Mechatronics Design

The Arduino has a 0V – 5V input range on its 10-bit digitiser corresponding to values of between 0 and 1023. We
are therefore not using the maximum range of this digitiser. At this point it is a good idea to connect up a
multimeter to the output of the TMP36 sensor to check its output. You will see it has a minimum value of 99.9mV
(i.e. 1023 x 0.0999 / 5 = 20) to a maximum of 1.75V (i.e. 1023 x 1.75 / 5 = 358). We could amplifier the output of
the TMP to 5V thereby giving us better resolution in our measurement but for the purposes of this module, this
output will suffice.

As an exercise, try altering the program to give a warning light if the temperature exceeds a certain value, for
example illuminate the internal LED if the digitised value exceeds 300. This value should be stored in a #define
statement at the start of the program so it can be easily changed if you need to. It is important to realise what a
value from a computer physically corresponds to in the real world – from the datasheet, try to estimate what
temperature a digitised value of 300 corresponds to (see Discussions 1 in Appendix 2).

2.3. Light sensor (alternative analogue input example)

A light sensor is another example of an output we would wish to digitise to give us a range of values. Some light
sensors output a voltage corresponding to light level, others (as with many sensors) give a corresponding
electrical change. Consider the Ambient Light Sensor (a phototransistor) supplied on Tinkercad. The output of this
sensor is a resistance change that we must convert to a corresponding voltage. Consider figure 7 in which we
have two resistors connected across a supply voltage, VS, of 5V.

Figure 7: A potential divider circuit can be used to convert a resistance change into a voltage change. Here R1 is 1
kΩ and R2 is 4 kΩ with 5V being supplied by an Arduino.

Using Ohm’s Law, V=IR, we can calculate the current through these resistors and knowing this current, we can
therefore work out the voltage drop across R2 and thus the voltage Vout:

𝑅𝑅2
𝑉𝑉𝑜𝑜𝑜𝑜𝑜𝑜 = � � 𝑉𝑉
𝑅𝑅1 + 𝑅𝑅2 𝑆𝑆

If we change one of the resistor values, this gives a corresponding change on the output voltage.

The phototransistor is essentially an analogue (resistive) switch controlled by the amount of incoming light.
Therefore (similar to our digital switch) we need a pulldown transistor to fix its voltage when the switch is fully
closed and to control the voltage level when the switch is partially open. Figure 8 shows how to connect our
phototransistor to the Arduino taking careful note that the collector is connected to the 5V supply and the
emitter connected to ground via the resistor. By knowing the phototransistors properties, we could pick a suitable
value for the resistor however as we do not have this information in this case, you can experimentally determine
an appropriate value by trying different values. Figure 9 shows various resistor values and the corresponding

John Hedley, School of Engineering, 2024. Page 5


MEC8063 Introduction to Mechatronics Design

output from the phototransistor (as measured on the Arduino) for a range of input (sensor slider) values. Which
resistor value do you think is most suitable (see Discussions 2 in the appendix)?

Figure 8: Phototransistor with pulldown resistor.

1200 1 kohm 2 kohm 3 kohm 10 kohm

1000
Digitised value

800

600

400

200

0
0 20 40 60 80 100
Relative light intensity (%)

Figure 9: Phototransistor output for various pulldown resistor values. Note solid lines show interpolated values
between the circular data points and do not necessarily correspond to actual sensor values.

Using your digitisation program from section 2.2 (TMP36 sensor), run the simulation and check your output
values for a range on input settings. In this case, rather than the LED being a warning light, you can use it as
effectively automatic headlights if the light level falls below a certain value.

If we consider the automatic headlights scenario, there are two minor problems with our initial solution. Firstly
what if the light level is exactly on the cut-off value. Due to noise in the reading (which although not evident in a
simulation would happen in practice) when the light is at this cut-off level, you will find the LED will be continually
switching on and off as the readings fluctuate around this value. To overcome this, we need to add hysteresis into
the system, as shown in figure 10. If you set the light to come on after it has fallen below a certain value, say
LIGHTS_ON, and switches off when the value has increased above a certain value, say LIGHTS_OFF, where
LIGHTS_ON < LIGHTS_OFF, then (providing you choose appropriate values), this should ensure steady operation.
Write a program to incorporate this feature and check your solution by slowing changing the slider position across
these two values.

John Hedley, School of Engineering, 2024. Page 6


MEC8063 Introduction to Mechatronics Design

Figure 10: Adding hysteresis to the automatic headlights. The value at which the lights change to a HIGH or LOW
state depends of whether the light level is increasing or decreasing.

The second issue is intermittent light levels, for example when driving past trees. Even with the hysteresis
incorporated, this may still pose a problem. The simple solution to this is to incorporate a delay so when the lights
switch on or off, they will remain in this state for a minimum amount of time regardless of sensor input. This is
the same scenario as the debounce option for the mechanical switch in section 2.1.

2.4. Ultrasonic sensor (timing)

Ultrasonic sensors work by sending out a sound wave and measuring the time it takes to register the echo. In
principle any wavelength of sound will work although anything within the audible range would be irritating hence
the use of ultrasound, sound beyond the human hearing range.

For Tinkercad we have a couple of options for simulating the ultrasonic sensors. The Ping sensor has 3
connections and uses the same pin to trigger (initiate) and sense the returned signal. The HC-SR04 has a separate
trigger pin. Connect up the Ping sensor as shown in figure 11 and use the example code for the Ping sensor given
in figure 12 (copied from the Arduino IDE examples).

Figure 11: The Ping ultrasonic rangefinder.

John Hedley, School of Engineering, 2024. Page 7


MEC8063 Introduction to Mechatronics Design

/*
Ping))) Sensor
created 3 Nov 2008 by David A. Mellis
modified 30 Aug 2011 by Tom Igoe
http://www.arduino.cc/en/Tutorial/Ping
*/

// this constant won't change. It's the pin number of the sensor's output:
const int pingPin = 7;

void setup()
{
// initialize serial communication:
Serial.begin(9600);
}

void loop()
{
// establish variables for duration of the ping, and the distance result in inches and centimeters:
long duration, cm;

// The PING))) is triggered by a HIGH pulse of 2 or more microseconds.


// Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
pinMode(pingPin, OUTPUT);
digitalWrite(pingPin, LOW);
delayMicroseconds(2);
digitalWrite(pingPin, HIGH);
delayMicroseconds(5);
digitalWrite(pingPin, LOW);

// The same pin is used to read the signal from the PING))): a HIGH pulse whose duration is the
// time (in microseconds) from the sending of the ping to the reception of its echo off of an object.
pinMode(pingPin, INPUT);
duration = pulseIn(pingPin, HIGH);

// convert the time into a distance


cm = microsecondsToCentimeters(duration);

Serial.print(cm);
Serial.print("cm");
Serial.println();

delay(100);
}

long microsecondsToCentimeters(long microseconds)


{
// The speed of sound is 340 m/s or 29 microseconds per centimeter. The ping travels out and back,
// so to find the distance of the object we take half of the distance travelled.
return microseconds / 29 / 2;
}

Figure 12: Modified version of the Arduino example program Ping (Examples – Sensors – Ping).

On running the simulation and clicking on the sensor, you will see a schematic range for the sensor. Moving the
target circle effective places an object in front of the sensor and the returned signal indicates the distance to this
‘object’. What happens when this object is placed outside of the sensor’s range (either too short, too long or too
far to one side) – what value is reported back? When using sensors you should calibrate them and be aware of
their limitations, your control program should then act accordingly in these scenarios. Remember if the signal
contains interference then it could report back a false reading – how do you account for this? See Discussions 3 in
the appendix for possible solutions to these issues.

John Hedley, School of Engineering, 2024. Page 8


MEC8063 Introduction to Mechatronics Design

Also note that the serial printing appears more slowly the further the object is away. The is because the pulseIn
command is a blocking function and the program is held at this point (the rest of the code is being blocked from
executing) until the signal is returned from the sensor. Ideally you want to reduce the use of blocking functions as
much as possible.

The other ultrasonic sensor available in the simulation is the HC-SR04, this is equivalent to many of the ultrasonic
sensors we have in the electronics lab such as the TruSens HC-SR504. Find the datasheet for the TruSens HC-
SR504 (https://static.rapidonline.com/pdf/74-1109_v1.pdf, a copy of this is available in Canvas – Modules -
Datasheets) and connect up the circuit given in the datasheet (this has been reproduced in figure 13). Copy the
example program code given in the datasheet and try running the program (note the “ and ” characters in the
Serial.println(“Out of range”) and Serial.println(“ cm”) commands do not copy and paste correctly from the
datasheet to the simulation so these will need correcting before the program will run).

Figure 13: Using the HC-SR04 ultrasonic sensor with warning LEDs.

Both programs are excessively long as they convert the reading to a human readable form of cm. This is not
necessary at this point as we do not need to read the actual value, we only want the program to respond to a
certain distance (i.e. duration for the echo). Remove any excessive code by changing the code to use duration
instead of distance. This will speed up the program. Note that is it worth putting comments in to explain what is
happening, i.e.

// a duration of 232 microseconds corresponds to a distance of 4cm

If(duration<232)

{

}

Finally try calibrating one of these sensors. Using the readings given on the screen, record range against duration
and plot this up in an Excel file. You can add a linear Trendline by right clicking on the data points in Excel, display
the resulting equation on the plot as shown in figure 14. Be sure to save the Excel file as we will be using it in next
week’s tutorial.

John Hedley, School of Engineering, 2024. Page 9


MEC8063 Introduction to Mechatronics Design

Figure 14: Calibration of the HC-SR04 ultrasonic sensor. Data points shown as red circles, best linear line fit
shown.

2.5. IMU (comms)

Data from a sensor can sometimes be transmitted as a message using one of the standard communications
protocols. Sometimes the data sent back from a sensor can be complex (consisting of a string of data) and
therefore this option for relaying the information is the only choice.

The IMU sensor used in this tutorial demonstrates 2 principles: receiving data via a communications channel (in
this case I2C) and the need for calibration (up to this point data sheets provide a reasonable level of calibration,
this is definitely not the case for a magnetometer). The IMU we will use in the practical work (the Popolu
MinIMU-9 v5) is quite a complex sensor giving 9 readings for acceleration, rotation and magnetic field strength
along/around the x,y and z axes. There is nothing similar in the simulation to mimic this sensor so we will build an
equivalent circuit.

We will simulate a 2 degree of freedom magnetometer (measuring field strength in the x and y direction) lying
perfectly horizontal. For the x-axis, when we align the x-axis to the magnetic field we would expect a maximum
value (or a negative maximum if it was aligned in exactly the opposite direction) and a zero value if it was
perpendicular to it. This would be the same case for the y-axis magnetometer. Therefore if we rotate our sensor
through 360 degrees, we would expect the x and y readings to trace out cosine and sine functions respectively.
Thus if we plot x values against y values we would expect to see a circle centred at the origin (with the reasonable
assumption that the sensitivity of each magnetometer is the same). However in most cases we will get a hard iron
error (which offsets this circle) and usually to a lesser extent a soft iron error (which causes the circle to turn into
an ellipse shape). More on this can be found at: https://www.fierceelectronics.com/components/compensating-
for-tilt-hard-iron-and-soft-iron-effects . For our work (as is commonly the case), we will assume only the hard iron
error is significant.

We will build our simplified magnetometer out of a potentiometer. Unfortunately, the potentiometer does not
turn a full 360 degrees so we have to infer compass headings as shown in figure 15a. Construct the circuit shown
in figure 15b and use the program code given in figure 16. It is simply a digitisation of a potentiometer with the
reading scaled to represent a heading of between 0° and 360°. The corresponding value for the x and y
magnetometers are calculated and scaled/offset accordingly by using user defined values at the start of the
program. The values calculated for the magnetometer are shown on the serial monitor. Try running the

John Hedley, School of Engineering, 2024. Page 10


MEC8063 Introduction to Mechatronics Design

simulation and copy and paste the values shown into an Excel worksheet (you will need to copy and paste into
Notepad and then recopy and use Import Wizard with a comma as deliminator to import into Excel). Insert an xy
plot using the magnetometer x and y values, you should see something similar to the plot shown in figure 17.
From this plot you can now work out the hard iron compensation (which should correspond to the values in the
Arduino program). As a final exercise, get a friend to set the potentiometer to a random direction (or alternative
close your eyes and do it). By only using the x and y magnetometer readings, can you determine the heading? Be
sure to save the Excel file as we will be using it in next week’s tutorial.

(a) (b)

Figure 15: (a) A potentiometer is used to set compass headings. (b) Imitating a magnetometer with a
potentiometer arrangement.

John Hedley, School of Engineering, 2024. Page 11


MEC8063 Introduction to Mechatronics Design

// 2DOF Magnetometer simulator

#define PI 3.14159
#define potPin A0
// Constants for magnetometer - set as required
#define X_OFFSET 300
#define Y_OFFSET 200
#define X_SENS 1000
#define Y_SENS 1000
#define NOISE 50

// Other variables
long magX = 0;
long magY = 0;
int potentiometer = 0;
int heading = 0;

void setup()
{
// Open serial port for checking values, remove when not requiring debugging
Serial.begin(9600);
}

void loop()
{
setheading();
calcvalues();
printvalues();
delay(100);
}

void setheading()
{
// To replicate the compass, take the potentiometer reading and convert to a heading
// 0 deg -> 360 deg over pot rotation
potentiometer = analogRead(A0);
heading = potentiometer*360.0/1023.0;
}

void calcvalues()
{
// Trigonometry used to calculate equivalent magnetometer values for
// given heading, values scaled and offset at user's discretion
magX = cos(heading*PI/180)*X_SENS + X_OFFSET + random(-NOISE,NOISE);
magY = sin(heading*PI/180)*Y_SENS + Y_OFFSET + random(-NOISE,NOISE);
}

void printvalues()
{
Serial.print(magX);
Serial.print(" , ");
Serial.println(magY);
}

Figure 16: Arduino code to mimic a magnetometer in Tinkercad. A potentiometer is used to set compass heading.

John Hedley, School of Engineering, 2024. Page 12


MEC8063 Introduction to Mechatronics Design

Figure 17: Calibration of the magnetometer, various levels of noise are shown. Due to the limited number of data
points displayed on the serial monitor in Tinkercad, each data set shown consists of 5 scans.

Now that you have practised analysing magnetometer readings, we want to convert this circuit into a sensor that
you can potentially use in your assignment. We will try to approximately replicate the Popolu MinIMU-9 v5 by
setting it up with I2C communications and appropriate pin connections. The circuit required is shown in figure 18
and consists of the Arduino replicating the magnetometer sensor and the main Arduino which would be your
controller. The circuit is arranged to mimic the actually connections needed, for example the controller Arduino
has to supply the power to the sensor for it to work. Following the circuit in figures 19 and 20 are the program
codes for each Arduino.

The programs will seem very confusing to those not familiar with Arduino programming. Do not worry about this
for now (we will discuss I2C communication more towards the end of the module at which point you may wish to
revisit this code). The code has been written so that all you need to do is use the readmagnetometer() function to
retrieve the simulated magnetometer values. It is best to set the offset and noise parameters to zero whilst
testing to ensure the program is working but these should be set back to a realistic value (offset 100-500, noise
20-50) when using the magnetometer for sensing.

Note: The actual Popolu IMU sensor is slightly different to program as all the required commands to retrieve the
data are provided for you (as demonstrated in the example programs for this sensor, you will see this in the
practical exercises).

Currently the master Arduino prints out the magnetometer readings. Try altering this program to instead print
out the compass heading indicated on the potentiometer. Run this simulation for various levels of noise to see
how consistent your compass readings are for a fixed potentiometer value.

John Hedley, School of Engineering, 2024. Page 13


MEC8063 Introduction to Mechatronics Design

Figure 18: Circuit to simulate magnetometer as a slave device.

John Hedley, School of Engineering, 2024. Page 14


MEC8063 Introduction to Mechatronics Design

// 2DOF Magnetometer simulator with I2C


// J Hedley 25/09/20
// Controller master device

#include <Wire.h>

long X_mag = 0;
long Y_mag = 0;

void setup()
{
// Open communication channels
Serial.begin(9600);
Wire.begin();
}

void loop()
{
// Simply program to read value and display
readmagnetometer();
Serial.print(X_mag);
Serial.print(" , ");
Serial.println(Y_mag);
delay(200);
}

void readmagnetometer()
{
long magX_B1;
long magX_B2;
long magY_B1;
long magY_B2;

// Ask for 4 bytes of data from the magnetometer


Wire.requestFrom(30,4);
while(Wire.available())
{
magX_B1 = Wire.read();
magX_B2 = Wire.read();
magY_B1 = Wire.read();
magY_B2 = Wire.read();
}

// Convert bytes to numerical values


X_mag = magX_B1*256 + magX_B2 - 32768;
Y_mag = magY_B1*256 + magY_B2 - 32768;
}

Figure 19: Master Arduino program code for the magnetometer simulation.

John Hedley, School of Engineering, 2024. Page 15


MEC8063 Introduction to Mechatronics Design

// 2DOF Magnetometer simulator with I2C


// J Hedley 25/09/20
// Magnetometer slave device

#include <Wire.h>

#define PI 3.14159
#define potPin A0

// Constants for magnetometer - set as required


// Transmission limited from -32768 to +32767 (2 bytes)
#define X_OFFSET 300
#define Y_OFFSET 200
#define X_SENS 1000
#define Y_SENS 1000
#define NOISE 50

// Other variables
int potentiometer = 0;
int heading = 0;

void setup()
{
Serial.begin(9600);
Wire.begin(30); // set magnetometer address as 30
Wire.onRequest(transmitvalues); // function to read and send values
}

void loop()
{
delay(100);
}

void transmitvalues()
{
// To replicate the compass, take the potentiometer
// reading and convert to a heading
// 0 deg -> 360 deg over pot rotation
int potentiometer = analogRead(A0);
int heading = potentiometer*360.0/1023.0;

// Trigonometry used to calculate equivalent magnetometer values for


// given heading, values scaled and offset at user's discretion
long magX = cos(heading*PI/180)*X_SENS + X_OFFSET + random(-NOISE,NOISE);
long magY = sin(heading*PI/180)*Y_SENS + Y_OFFSET + random(-NOISE,NOISE);

// Ensure values are positive


magX += 32768;
magY += 32768;

// Convert each number to 2 bytes


int magX_B1 = magX/256;
int magX_B2 = magX%256;
int magY_B1 = magY/256;
int magY_B2 = magY%256;

// Transmit values
Wire.write(magX_B1);
Wire.write(magX_B2);
Wire.write(magY_B1);
Wire.write(magY_B2);
}

Figure 20: Slave Arduino program code for the magnetometer simulation.

John Hedley, School of Engineering, 2024. Page 16


MEC8063 Introduction to Mechatronics Design

3. Practical exercises

In prior lab practicals, you learnt the basics on how to use the equipment and connect up the Arduino. In this
practical, you will repeat some of the simulation exercises done in this tutorial but using real hardware. As the
Arduino community provides a lot more resources than what is available on Tinkercad, in some cases we can take
shortcuts to achieve our objectives (as you will see when you work through the exercises). However you will also
notice that sometimes your circuits do not operate as intended, maybe due to a loose wire or a burnt out chip. If
this happens, try using the available hardware (DVM, oscilloscope, etc) to identify where the problem is. Of
course the staff (who have a lot more experience with this) will help but being able to overcome these problems
for yourself is a key skill in such design work.

In these exercises, you will gain experience in connecting sensor systems to the Arduino and experience the issues
of real hardware. For each of the following exercises, it is best to disconnect the sensor before moving onto the
next exercise. Multiple sensors should only be connected when you are familiar with the procedure.

IMPORTANT NOTE: It is possible to plug the sensors into breadboards, this allows for easy wiring. However they
can be very difficult to remove and the risk is that you will bend or snap the connection pins. For this lab
session, please connect jumper cables to the sensor pins which (although lead to untidy wiring) will be a lot
easier to remove at the end of the session. These jumper cables can then be connected into the breadboard if
you wish.

3.1. Microswitch (digital input)

The lever microswitch (CamdenBoss CSM40580A) is simply a switch that closes a contact, in this case a long
cantilever arm allows the switch to be mechanical compliant thereby enabling closure under a small contact
force. Connect up the circuit as shown in figure 21 and program the Arduino to switch on the internal LED if the
switch closes.

Figure 21: Arduino Uno connected to a microswitch.

3.2. Light sensor (analogue input)

When using components (such as sensors) for the first time, it is easiest to try them already mounted on what is
called a breakout board. This has all the necessary electronic components included making them very simple to
use. The downside is that this will be significantly more cost (around 10-100 times more expensive) than building
the equivalent system for yourself so they are not viable for when you are wanting to mass produce a product.

John Hedley, School of Engineering, 2024. Page 17


MEC8063 Introduction to Mechatronics Design

For this demonstration we will use a light sensor breakout board. The Adafruit ALS-PT19 is a light sensor mounted
on a small PCB board with associated electronics. You simply connect it via its terminals as shown in figure 22,
note there is no need for a pulldown resistor (as there was in the Tinkercad tutorials) as this is included on the
breakout board. Try taking light intensity readings, stream your values over the serial port and display the values
on your Arduino IDE serial monitor). What are the typical range of values for this sensor (when covered and when
illuminated)? Program the Arduino to switch on the internal LED (to mimic automatic headlights) for appropriate
illumination levels.

Figure 22: Connection of the ALS-PT19 light sensor to an Arduino Uno.

3.3. Ultrasonic sensor (timing)

You have a wide choice of sensors to measure distance, the main ones being IR sensors and ultrasonic sensors
(both are available in the electronics workshop). The advantage of the latter is that most surfaces give a good
reflection to this energy (compared to light based sensors which would struggle to measure glass surfaces for
example) and that the beam angle is relatively large (so they are good that knowing something is there although
they cannot spatially resolve its size).

These attributes make it ideal for use in today’s cars to measure proximity of objects close to the car (for example
when reversing into a parking space). There are a wide range of these ultrasonic sensors ranging from single
membrane (sound is emitted and detected from the same membrane) to dual membrane (one membrane is used
to send out the signal whilst the second waits to measure the echo). In all cases, the sensors work by sending an
initialisation pulse (i.e. start the measurement), there is a small dead time (corresponding to minimum
measurable distance) and then a HIGH signal is activated until an echo is detected at which point the signal goes
LOW. The length of time the signal is HIGH (which is measured by our Arduino pulseIn command) is proportional
to distance.

3.3.1. Exercise (note this may form part of the assignment so take a copy of the screenshot)

Connect a TruSens HC-SR504 to an Arduino and program the Arduino to send duration measurements over the
serial monitor. Produce a calibration curve (similar to figure 14) for this sensor – how does it compare to the
calibration curve from the tutorials? You will probably find that the data points are a little more scattered (due to
measurement uncertainty in the actual distance to the object) and that the gradient of the linear fit is different
(as the velocity of sound depends on atmospheric conditions). Does the intercept go through the origin – if not
why? You can also determine beam width by moving an object perpendicularly in front of the sensor and seeing
at what positions it is detectable. Take a screenshot of the screen showing ultrasonic values being streamed over
the Serial Monitor and a plot of your ultrasonic sensor calibration (fitted with a straight line, display the equation
of this straight line on the plot similar to figure 14). Remember to display all group member names.

John Hedley, School of Engineering, 2024. Page 18


MEC8063 Introduction to Mechatronics Design

3.4. IMU

For this tutorial, we will look to use a 9 degree of freedom Popolu inertial measurement unit MinIMU-9 v5, details
of the board can be found at https://www.pololu.com/product/2738. Although the basic principles are similar to
the IMU tutorial previous discussed in this tutorial, programming will be easier as we can utilise the supplied
example programs to extract the required data.

The nice feature of this sensor (and with many sensor breakout boards available today) is that it comes with a
library of commands that can be easily used. The first task is to install this library on the PC so that the Arduino
IDE has access to it. In the Arduino IDE, click on Sketch – Include Library and see if LSM6 and LIS3MDL are listed. If
they are present then someone has previously installed them. If they are not present, you will need to click on
Manage Libraries and following the instructions given on the Popolu webpage link, see figure 23. Note that now
there are several of these libraries, find the ones by Popolu.

Figure 23: Screenshots from https://github.com/pololu/lsm6-arduino and https://github.com/pololu/lis3mdl-


arduino on installing the MinIMU-9 v5 libraries. Note that there are several similar libraries available, in this case
use the ones by Popolu (the breakout board manufacturer).

We will briefly review communication protocols for this device (more on this is given in tutorial 6). For I2C
communication, we require 2 communication lines, denoted as SCL (clock) and SDA (data). The clock line informs
the device on the transmission speed whilst the data line contains the message to be transmitted. In I2C
communications, these 2 lines connect all devices and so the master (in our case the Arduino controlling the
communications) must have a way to identify each of the connected devices (known as slaves). Therefore each
slave device must have a unique identifier associated with it (known as a slave address). This can be programmed
but for our case (and in most cases of supplied devices), this slave address is set as shown in figure 24. You will
notice that we have 2 slave address associated with this board, this is because the board contains 2 sensors (a
combined gyro/accelerometer together with a magnetometer).

John Hedley, School of Engineering, 2024. Page 19


MEC8063 Introduction to Mechatronics Design

Figure 24: Addresses for the sensor chips.

Once the 2 libraries are installed you will be able to load example programs (under File – Examples) to see how to
access the data from the sensors. Figure 25 shows the appropriate wiring to the Arduino Uno. You will notice in
the example programs that at the start is an #include file to load the relevant header (.h) files for each sensor
thereby allowing for simple programming to read the data through the imu.read() and mag.read() commands. The
#include <Wire.h> is required to allow for I2C communication.

Figure 25: Connection of the IMU sensor with the Arduino Uno.

Once you have the sensor connected and are streaming the data, check that you are measuring the acceleration
due to gravity (you will need to note the board axes shown in figure 25 with respect to how you have orientated
the sensor with respect to the ground). Try rotating the sensor and note how this measurement of gravity
changes to another axis of the sensor.

Now try calibrating the magnetometer. Produce the circular calibration curve (as done in figure 17) by rotating
the sensor through 360° and plotting the resulting data in Excel. Using this calibration, try rotating the sensor to
some random orientation and see if (by using the values) you can calculate what the compass heading is. Try to
confirm your result by another independent method (for example a compass app on your smartphone).

4. Summary

This concludes the Arduino sensor tutorial. The exercises have given you a taste for the options available, more
sensors are available in the simulator and in the electronics workshop which you may wish to investigate. When
choosing a sensor, you will always need to look at the datasheet to see what connections are required and it is
also a good idea to pick sensors with support (i.e. Arduino example files, etc).

John Hedley, School of Engineering, 2024. Page 20


MEC8063 Introduction to Mechatronics Design

Appendix 1: Electronics

A1.1. Introduction

When prototyping electronics, the tendency is to just pick whatever wire is available and see if appropriate
connections work. Although this is convenient when you are exploring how to get your electronics working, when
it comes to your final build wiring tends to be poorly labelled and prone to becoming disconnected due to
entanglement with other objects. The following sections outline methods and good practice to make your wiring
more robust and allow for easier diagnosing of problems.

A1.2. Solderless breadboard

The solderless breadboard is a convenient way to connect up chip packages without the need of fabricating a PCB,
an image of the one used in this module is shown in figure A1. They offer simple plug in and use functionality
without the requirement of soldering. The downside to this is that connections are not robustly held in place and
so care should be taken not to disrupt the wiring. These breadboards commonly have rails running along the long
side of the board (usually used as power rails, i.e. 5V and ground) and shorter rails running across the board,
typically in runs of 5. Figure 1a highlights which pins are connected together. An example of wiring a uni-polar 8
pin op amp chip is shown in figure 1b and highlights appropriate use of the breadboard.

(a) (b)

Figure A1: (a) A solderless breadboard. (b) An example of wire connections using a solderless breadboard. Notice
that the chip is mounted across the central recess (gap in breadboard) to prevent the pins shorting. For ease of
construction use single strand wire for creating a circuit on breadboard. Always look at the datasheet for pin
assignments on components (such as op amps, etc).

A1.3. Wiring

Colour coding of wires makes diagnostics much easier. For example, if all wires were black and a wire came loose,
it would be difficult to know from which connection it became detached from. However, if you colour code it so,
for example, all green wires were earth connections then if a green wire became loose, you would know where it
should be connected to. There are no hard rules on what colours to use but using the defined convention makes it
easier for other people (i.e. the demonstrators) to help you if something is not working. Typically:

John Hedley, School of Engineering, 2024. Page 21


MEC8063 Introduction to Mechatronics Design

• Red: Positive voltage supply


• Black: Negative voltage supply (when only positive voltage supplies are needed, this side of the voltage
supply is connected to ground)
• Green: Earth connection

If many wire connections are required, ribbon cables can be used with their distinct colouring allowing for easy
tracking of each wire. For longer cables, it is good practice to put a label on each end of the cable highlighting
what it is being used for. Molex connectors, see for example https://www.rapidonline.com/molex-22-27-2121-12-
way-2-54mm-kk-straight-header-22-0852, are a useful way to keep your wiring organised. You will be able to
make up any length of connector you wish although you will need to reposition the pins so they plug into your
Arduino / breadboard. Molex connectors are available from the electronics workshop.

Note: Here we are talking about your own basic electronic circuits. For any commercial electrical wiring (for
example plugs and sockets in your house), you must follow the correct cable colouring.

When you have wire pairs carrying large currents, for example the two power connections to a motor, the current
in these lines can produce a significant magnetic field which will disrupt (i.e. introduce noise) to the rest of your
electronics. To minimise this effect, these wires should be twisted together (known as a twisted pair), this can be
seen on the power cable attached to motors. In this arrangement, the magnetic field produced in the first wire is
cancelled by the opposite magnetic field produced by the return current in the second wire.

IMPORTANT NOTE: Please do not cut any of the specific cables supplied, for example the motor cables, sensor
cables, etc. Although these may be too long, they provide convenient connections. You are, of course, welcome
to make up your own cables of appropriate length.

A1.4. Resistor colour coding

Resistor values are often indicated with colour codes. Practically all leaded resistors with a power rating up to one
watt are marked with colour bands. The colour code is given by several bands. Together they specify the
resistance value, the tolerance and sometimes the reliability or failure rate. The number of bands varies from
three to six. As a minimum, two bands indicate the resistance value and one band serves as multiplier. The chart
below shows how to determine the resistance and tolerance for resistors. The table can also be used to specify
the colour of the bands when the values are known. There are lots of options for web based apps to calculated
resistor values, for example https://www.allaboutcircuits.com/tools/resistor-color-code-calculator/ .

John Hedley, School of Engineering, 2024. Page 22


MEC8063 Introduction to Mechatronics Design

Figure A2: Colour coding for resistors (image taken from www.resistorguide.com).

John Hedley, School of Engineering, 2024. Page 23


MEC8063 Introduction to Mechatronics Design

Appendix 2 : Discussions

1) A digitised value of 300 corresponds to an input around 1.47V however this is with using a 5V supply. Figure 6
of the TMP36 data sheet (reproduced below in figure A3) uses a 3V supply and therefore we need to work out the
equivalent measured voltage if this was the supply: 1.47x3/5 = 0.88V. This corresponds to a temperature of
around 35°C. You will also see from the datasheet that there are a lot more circuit options for these sensors
depending on the application, we will go into more detail about alternative circuits in the stage 4 module
Mechatronics and Robotics (for those taking this module). The good news for those who do not like electronics is
that a multitude of third party companies produce breakout boards (essentially these circuits already built for
you) so the sensors are simple to use, you will see this in some of the practical exercises.

Figure A3: Calibration plot for TMP36 sensor (taken from TMP36 datasheet).

2) There is no definitive answer to this. 2kΩ gives a good linear response over the full input range of the Arduino
so this (or something around this value) would generally be the most appropriate. However if light levels never
exceeded 20% (for example your sensor only operates at night) then the 10kΩ gives you the best resolution for
that scenario.

3) The PING sensors appears to have a range from 2cm to 336cm. Outside of this range then the sensor just
reports back a value of 336cm. So what does a value of 336cm mean – is it at maximum range, is it beyond
maximum range, it is closer than 2cm, is it at the side of the sensors field of view? A reading of 336cm could be
any of these scenarios and so should it be ignored – you cannot ignore it as no reading means you do not know if
any objects are present. What you need to do is have enough sensors to cover your range of interest so you may
need multiple ultrasonic sensors to cover a wider field of view and pick another type of sensor for close object
detection, for example a microswitch to detect anything very close. That way if all sensors detect no objects then
you can be confident an object is not in close proximity (assuming the sensors are working that is). Of course, you
could always set your ultrasonic sensor 2cm into your sensor housing so 2cm then effectively corresponds to zero
distance.

4) When calibrating the magnetometer in section 2.5, it was assumed that the distortions were in the same fixed
coordinate system as the magnetometer. So for example if you are using this in a petrol engine car with a steel

John Hedley, School of Engineering, 2024. Page 24


MEC8063 Introduction to Mechatronics Design

frame then although this gives an error, this can be calibrated out as the car always rotates in the same frame of
reference as the magnetometer. However anything external to the car, for example a building, is in a different
coordinate frame (it does not rotate with the car) and so it is impossible to calibrate out this error.

Note: You have to be in close proximity to the steel for this to have an effect so generally buildings will not affect a
magnetometer inside a car although a robot moving through a building would have this problem. Notice that I
have specified a petrol engine car compared to an electric car as electric motors will generate a varying magnetic
field which could be problematic to the sensor readings.

John Hedley, School of Engineering, 2024. Page 25

You might also like