Introduction to Sensor Technology Week Three Adam Taylor tayloral@tcd.ie

Preview:

Citation preview

Introduction to Sensor Technology

Week Three

Adam Taylor tayloral@tcd.ie

Last Week

• Introduction to Arduino Microcontrolller

• Digital Input and Output

• Building a pushbutton circuit

Class Outline

• Analog Input and Output

• Manipulating Values

Week 3.1 Analog Output

Pulse Width Modulation

• When working with digital input and output we saw that voltage values were specified as HIGH or LOW (0v or 5v).

• Microcontrollers can’t produce a varying voltage, they can only produce this high or low.

• To create a varying output voltage, we ‘fake’ an analog voltage using a technique known as pulsewidth modulation.

Pulsewidth modulation

• Think back to the first code you wrote which blinked an LED:

• If the LED is off and on (HIGH and LOW) for the same increment of time (i.e. 5ms) with no delay the LED would appear to be at 50% of its usual brightness.

• If we were to alternate the time so that the LED was off for 2.5ms and on for 7.5ms, the result would be an LED which appeared to glow at 25% of its usual brightness.

Pulsewidth Modulation

•The pulse with is usually a very small increment of time in the range of microseconds or milliseconds

analogWrite(pin, value)

• This instruction changes the PWM rate on one of the analog out pins. In week one we saw that pins 3, 5, 6, 9, 10 and 11 of the digital pins can be reconfigured as analog output pins using the analogWrite() instruction.

• analogWrite() takes two arguments – the pin no. and a value between 0 and 255. This value represents the scale between 0 and 5v output voltage.

• i.e. analogWrite (9, 128); //Dim an LED on pin 9 to 50%

Fading an LED using analogWrite()

• Build a simple circuit on your breadboard.• You will need two wires, a 220 ohm resistorand an LED.• The positive side of the LED should beconnected to digital pin 9 on the arduino,which will be reconfigured for analog input.• the negative side of the LED will be connectedto a 220 ohm resistor in turn connected to theGND on the Arduino.

Class Exercise One

• Using a for loop, write a code that gradually fades your LED in and out.

• Hints:

• The value applied to your analogue pin analogueWrite(pin, Value) should gradually increment with each iteration of a loop and then gradually de-increment.

• You will need a loop to increment the value applied to your pin and another to de-increment the value.

• Remember that instructions in arduino are executed instantaneously – in order to be able to see your light fade in and out – you are going to need to add a short delay between each new increment/de-increment. If not, the LED will change from dim to bright so fast you wont be able to register it. Delay(10); should be enough but you can experiment.

• In this exercise we are using PWM withanalogWrite() to vary the brightness of ourLED.

• We use a for loop to move through the valuesfrom 0 – 255 (0% – 100% brightness)

• Every 10ms ‘i’ increments by 1 and our LEDgets progressively brighter. When it is at 100%or 255 we move downwards from 255 to 0again. The PWN value of the analog pin isspecified as the loop counter ‘i’.

W.3.3 Analog Input

• analogRead(pin): Reads the voltage applied to an analog input pin and returns a number between 0 and 1023 that represents the voltages between 0v and 5v.

• i.e. Val = analogRead(0); // reads analog input 0 into val

Analog Input

• We use analogRead() to read in values from a richsensor.

• Variable resistors such as Light Dependent resistors(LDRs), thermoresistors, tilt switches andpotentiometers can be used to read in analoginformation.

Class Exercise 2A: using a potentiometer for analog input

• A potentiometer is a simple knob that provides a variableresistance, which we can read into an arduino board as an analog value. In this example, the value controls the rate at which the LED blinks.

• You will need an LED connected to pin 13 of the arduino• A potentiometer connected to pin 2

• The potentiometer has three connections which will be connected to the arduino board:• The first goes to ground (either of the outer wires)• The second of the outer wires goes to 5 volts• The centre wire goes to our analog input pin (in this case pin 2)

/* Analogue InputThis code demonstrates analogue input by readingan analogue sensor on analog pin 2 andturning on and off an LED connected to digital pin 13.The amount of time the LED will be on and off dependson the value obtained by AnalogRead().The circuit:- Potentiometer attached to analog input 0- centre pin of the potentiometer to the analog pin- One side pin to groundthe other pin to 5vLed to pin 13 */

int sensorPin = 2; // select the input pin for the potentiometerint ledPin = 13; // select the pin for the LEDint sensorValue = 0; // variable to store the// value coming from the sensorvoid setup() {pinMode(ledPin, OUTPUT);pinMode(sensorPin, INPUT);}void loop() {sensorValue = analogRead(sensorPin);digitalWrite(ledPin, HIGH);delay(sensorValue);digitalWrite(ledPin, LOW);delay(sensorValue);}

•We initialise/declare the pins for thepotentiometer and the LED.

• We create a variable to store the value coming from the pot.

•We read in a value from the potusing analogRead and store it in the variable called ‘sensorValue’.

• ‘SensorValue’ specifies the delay for the blinking LED.

The code step by step:

Class Exercise Two:

• Run the code using a Pot and then a Light dependent resistor (LDR).

• This implements the same circuit as the pushbutton switch circuit used in weeks two and three.

• You will need a 10k resistor, three wires and an LDR.

Week 3.4: Make a pressure sensor:

Make a pressure sensor:

• Conductive foam (comes as packaging with some electronics or available to buy cheap from radionics)

• Two wires stripped at the ends

• Tinfoil

• Insulation tape

Make a pressure sensor:

• Conductive foam can be used to make a pressure sensor: As you apply pressure to the foam, its electrical resistance decreases. You can use this property to sense pressure, force and impact.

• Wrap your wires in individual squares of tinfoil and place on either side of the conductive foam. Tape the components together to make a square.

• As the foam is squeezed, the resistance drops and the voltage flowing through the circuit increases.

• Test your values out in Arduino using analogRead()

Make a pressure sensor:

The pressure sensor is wired the same as a pushbutton with a 10k pull down resistor to ground. However, the input pin should go to an analog input rather than a digital input pin.

W.3.5. Manipulating values

• It is important to know how to change the ranges of our values so that they are meaningful to whatever we are controlling

• There are a number of different mathematical functions which can be used to constrain, scale or map values.

• constrain(x, a, b)

• Returns the value of x constrained between a and b. If x is less than a, it will just return a and if x is greater than b, it will just return b.

• Example: val = constrain(analogRead(0), 0 , 255); // reject values bigger than 255

• map(value, fromLow, fromHigh, toLow, toHigh)

• Maps an incoming range to a new range. This is very useful when processing values from analog sensors.

• Example:• val = map(analogRead(0), 0, 1023, 0, 255); //

maps the value of analog 0 to a value between 0 and 255

Arithmetic Operators

• / and * and % operators• Its also possible to scale a value using multiplication and

division.• i.e. 0 – 1023/4 is 0 – 255.val = analogRead(0);analogWrite (LED, val/4); Reads in a values from analogRead and divides it by four.• Modulo %• Returns the remainder of a division• i.e. 7 % 2 = 1

Class Exercise 4:

Exercise: Using a pot and an LED, build your owndimmer switch.• We have seen two examples: one that usesanalogRead() and one that uses analogWrite().• To make a dimmer switch we need to use bothanalogRead() and analogWrite().• Referring to the code in out analog Input and analogOutput examples, try and build a program that reads ina value from a dimmer switch and applies/maps this tothe PWM value of your analog output.

W.5.2.3. Ping)) Sensor (Ultrasonic Range Finder)

• Parallax’s PING)) ultrasonic sensor is a method of distance measurement. This sensor is used to perform measurements between moving or stationary objects. The PING sensor measures distance using sonar; an ultrasonic pulse is transmitted from the unit and distance-to-target is determined by measuring the time required for the echo return. Output from the PING)) sensor is a variable-width pulse that corresponds to the distance to the target.

W.5.2.3. Ping)) Sensor (Ultrasonic Range Finder)

PING))• Parallax’s PING)) ultrasonic sensor is a method of distance

measurement. This sensor is used to perform measurements between moving or stationary objects. The PING sensor measures distance using sonar; an ultrasonic pulse is transmitted from the unit and distance-to-target is determined by measuring the time required for the echo return.

• Output from the PING)) sensor is a variable-width pulse that corresponds to the distance to the target.

• Interfacing to the Arduino is very straight forward: a single (shared) I/O pin is used to trigger the Ping sensor and ‘listen’ for the echo return pulse. The pulse hits off the nearest object in range and returns the distance between the object and the sensor.

W.5.2.3. Ping)) Sensor (Ultrasonic Range Finder)

• PING)) Code Explained:

• This sketch reads a PING))) ultrasonic rangefinder and returns the distance to the closest object in range. To do this, it sends a pulse to the sensor to initiate a reading, then listens for a pulse to return. The length of the returning pulse is proportional to the distance of the object from the sensor.

• long duration, inches, cm;

W.5.2.3. Ping)) Sensor (Ultrasonic Range Finder)

• Established variables for duration, and values in inches and cm. The PING)) is triggered by a HIGH pulse of 2 or more microseconds. This sends a low pulse first to ensure a clear HIGH signal.

pinMode(pingPin, OUTPUT);digitalWrite(pingPin, LOW);delayMicroseconds(2);digitalWrite(pingPin, HIGH);delayMicroseconds(5);digitalWrite(pingPin, LOW);

W.5.2.3. Ping)) Sensor (Ultrasonic Range Finder)

• This same pin is used to read the returning 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. Where pingPin was an OUTPUT, we now specify it as an INPUT.

• pinMode(pingPin, INPUT);• duration = pulseIn(pingPin, HIGH);

PulseIn()

PulseIn() reads a pulse (either HIGH or LOW) on a pin. If the value is HIGH, pulseIn() waits for the pin to go HIGH, starts timing, then waits for the pin to go LOW and stops timing. It then returns the length of the pulse in microseconds. PulseIn() gives up and returns 0 if no pulse starts within a specified time out.

PulseIn()

The syntax is as follows:

pulseIn(pin, value) pulseIn(pin, value, timeout) • pin: the number of the pin on which you want to read the

pulse. (int)• value: type of pulse to read: either HIGH or LOW. (int)• timeout (optional): the number of microseconds to wait

for the pulse to start; default is one second (unsigned long)

PulseIn()

• PulseIn() returns the length of the pulse (in microseconds) or 0 if no pulse started before the timeout (unsigned long).

• pinMode(pingPin, INPUT);• duration = pulseIn(pingPin, HIGH);

W.5.2.3. Ping)) Sensor (Ultrasonic Range Finder)

• We read the value of the returning HIGH pulse and set that as the duration. The program contains two extra functions that convert distance as a function of time to centimetres and inches using arithmetic expressions.

• The program prints the result of these equations to the serial port.

Serial.print(inches);Serial.print("in, ");Serial.print(cm);Serial.print("cm");Serial.println();

delay(100);

5.2.4. PIR Sensor

The PIR sensor detects motion up to 20ft away by using a Fresnel lens and infrared-sensitive element to detect changing patterns of passive infrared emitted by objects in its vicinity. Its ideal for motion-activated systems. This sensor detects motion in a range of 20ft and returns a logical high if motion is sensed.

5.2.4. PIR Sensor

5.2.4. PIR Sensor

5.2.4. PIR Sensor

PIR Example One Explained

• This example involves sensor calibration. It prints this calibration to the serial port, but really all this example entails is a 30 second delay. It uses the same principle as the state change example looked at in week two.

5.2.4. PIR Sensor

if(digitalRead(pirPin) == HIGH){ digitalWrite(ledPin, HIGH); if(lockLow){ lockLow = false; Serial.println("---");Serial.print("motion detected at ");Serial.print(millis()/1000);Serial.println(" sec"); delay(50);

• We initialise a Boolean variable Locklow and initialise it to TRUE at the start of the program. The PIR goes HIGH if movement is detected. We turn on an LED and set locklow to false and print the number of milliseconds elapsed when motion detected.

5.2.4. PIR Sensor

if(digitalRead(pirPin) == LOW){ digitalWrite(ledPin, LOW); //the led visualizes the

sensors output pin state if(takeLowTime){lowIn = millis(); //save the time of the transition

from high to LOWtakeLowTime = false; //make sure this is only done

at the start of a LOW phase }

5.2.4. PIR Sensor

• You may remember from the state change example in week two that there are four possible conditions in a state change:

• Previously HIGH and Currently HIGH: Still on• Previously LOW and Currently HIGH: Just turned on• Previously HIGH and Currently LOW: Just turned off• Previously LOW and Currently LOW: Still off

5.2.4. PIR Sensor

• We’re watching out for the third condition – the moment the sensor goes from HIGH to LOW. We’re going to store the moment that this happens, we store it in a variable called lowIn.

PIR sensors may periodically go low from time to time even while movement is detected. This program is designed to ignore LOW periods which are shorter than a given period of time: 5,000 ms. As specified by the variable

long unsigned int pause = 5000;

5.2.4. PIR Sensor

if(!lockLow && millis() - lowIn > pause)

• This condition says that is lockLow is true and if the value in millis() - lowIn is greater than 5 seconds then we can safely say that there is no longer motion present at the sensor. We print the time that motion ended at.

5.2.6. PIR Sensor: Example Two

• This code can be used to give a (not very precise) reading of location in a space. If the left Sensor is fired the object is far left, if the right is fired the object if right and if both are fired simultaneously it is possible that the object is somewhere in the middle. Its more accurate to do this kind of motion tracking using a camera and frame differencing algorithms – there’s lots of code online for this if you’re interested.

• This code is very straightforward, but its potentially a foundation for a more interesting program. It could be used to trigger video projections based on somebody’s position in a room for example.

Sharp Proximity Sensor

Sharp Code Explained

• This code takes the incoming range between 0 and 1023 reflecting a variable voltage depending on the proximity of an object and maps it to distance in centimetres. The distance is printed to the serial port. If you just wanted to values from 0 – 1023 you could read it like any other analog sensor.

5.3. Smoothing and Calibration

With complicated sensors its useful to know how to smooth erratic values and how to calibrate erratic sensors.

5.3. Smoothing and Calibration

• Calibration Code Explained

• This example demonstrates one technique for calibrating sensor input. The sensor readings during the first five minutes of the sketch execution define the minimum and maximum of expected values attached to the sensor pin.

5.3. Smoothing and Calibration

• Initially, you set the minimum high and listen for anything lower, saving it as the new minimum. Likewise, you set the maximum low and listen for anything higher as the new maximum.

int sensorMin = 1023; // minimum sensor value int sensorMax = 0; // maximum sensor value

5.3. Smoothing and Calibration

• The minimum and maximum values are switched at the start. Our minimum is 1023 and max is 0.

while (millis() < 5000) { sensorValue = analogRead(sensorPin);

5.3. Smoothing and Calibration

• Millis() records the amount of time elapsed since the arduino started. In the first five seconds, while millis() is less than 50000 ms, we read the value from the analog sensor.

if (sensorValue > sensorMax) { sensorMax = sensorValue; }

5.3. Smoothing and Calibration

• We record the maximum sensor value, listening for anything above zero. This value becomes the new maximum. We do the same for the minimum value, listening for values that are less than 1023 and setting the new minimum.

if (sensorValue < sensorMin) { sensorMin = sensorValue; }

5.3. Smoothing and Calibration

• After the five second calibration period has elapsed we read the sensor value and apply the calibration to the reading. We map the values recorded in calibration between 0 and 255. We constrain the sensor in case we sense a value that’s outside the range seen during calibration.

sensorValue = map(sensorValue, sensorMin, sensorMax, 0, 255);

sensorValue = constrain(sensorValue, 0, 255);

5.3. Smoothing and Calibration

Recommended