powered by TinkerSpace.in
Join free
TinkerPy Tutorial ๐Ÿ“˜ Part 2 ยท Coder ยท Chapter 23 of 24

Distance, Colour, Gesture & Pulse Sensors

Measure distance with a laser, let your robot see colours, switch a lamp with a wave of your hand and watch your own heartbeat blink on an LED. Four amazing I2C sensors, one line of code each!

๐Ÿ“–Key words

VL53L0X

A laser distance sensor. It times how long its tiny, invisible, eye-safe laser light takes to bounce back: 3 cm to about 2 m. import vl53l0x.

TCS34725

A colour sensor with its own white light. It names the colour in front of it and gives its red, green and blue amounts. import tcs34725.

APDS-9960

A gesture sensor: it sees hand swipes (up, down, left, right), how near a hand is โ€” and colours too. import apds9960.

Pulse oximeter

A MAX30100 or MAX30102 module that shines light into a fingertip to find the heart rate and SpOโ‚‚ (oxygen in the blood). A learning project, not a medical device.

RGB value

A number from 0 to 255 for how much red, green or blue the sensor sees. The strongest colour is always 255.

๐ŸŽฌSee it work

Name that colour

The sensor shows its R, G and B numbers. Tap the colour name you think color_name() gives.

Laser ruler

Drag the object closer to the laser sensor and watch laser_distance() and the beeper.

๐Ÿง How it works

Laser distance (VL53L0X)

  • d = laser_distance() gives centimetres, from 3 to about 200. 999 means nothing is in range.
  • It is more exact than the ultrasonic sensor (TinkerPy Coder chapter 3) and works on soft things like cloth and curtains that swallow sound.
  • Check for 999 before you use the number, or your โ€œtoo closeโ€ code may get confused.

Colour (TCS34725 or APDS-9960)

  • color_name() gives a colour to compare in quotes: "red" "orange" "yellow" "green" "blue" "purple" "pink" "white" "black". Store it: c = color_name(), then if c == "red":
  • color_red(), color_green(), color_blue() give 0โ€“255; color_brightness() gives 0โ€“100 (small = dark).
  • Hold the colour 1โ€“2 cm from the sensor. Lighting changes colours, so first show the numbers for your own cards on the OLED.
  • The VL53L0X and the TCS34725 both use address 0x29: never both on one board. For laser + colour, use an APDS-9960 for the colour.

Gestures (APDS-9960)

  • gesture() gives "up", "down", "left" or "right" โ€” swipe a hand 5โ€“10 cm above the sensor. It gives None when there is no new swipe.
  • Each swipe is there for one pass of loop:, so store it first: g = gesture(), then check g with if / elif.
  • proximity(): 0 (far) to 100 (very close), for about 10 cm.

Pulse oximeter (learning only)

  • finger_detected() is 1 while a finger is on the sensor. Rest it gently โ€” no pressing, no moving.
  • heart_rate(): beats a minute; spo2(): oxygen in % (usually 95โ€“100). Both are 0 until a few beats are measured.
  • heart_beat() is 1 for one loop at every beat โ€” blink or beep with your heart.
  • This is a science project, not a medical device. Never use it to decide anything about someoneโ€™s health โ€” that is a doctorโ€™s job.
  • All four sensors use o7 (SDA) and o8 (SCL) and need board firmware 2.27 or newer, on Mega and Mini.

๐Ÿ’ปCode

# Add the libraries you need
import oled_display
import buzzer
import vl53l0x

# Give your pins easy-to-remember names
o1 = set_name("beeper")

# ===== Laser ruler =====

# This code block executes only once
setup:
    oled_begin()  # starts the OLED
    o7 = set_function(SDA)  # cannot be changed
    o8 = set_function(SCL)  # cannot be changed
    beeper = set_output(buzzer)
    oled_write(1, center, small, bold, "Laser ruler")  # write "Laser ruler" on OLED line 1 (small bold, centred)

# This code block executes forever
loop:
    d = laser_distance()  # cm, 999 = nothing in range
    if d == 999:  # when d == 999
        oled_write(2, center, large, bold, "--")  # write "--" on OLED line 2 (large bold, centred)
    else:  # otherwise
        oled_write(2, center, large, bold, d + " cm")  # write the value of d + " cm" on OLED line 2 (large bold, centred)
    if d < 10:  # when d < 10
        beeper = ON  # turn beeper ON
    else:  # otherwise
        beeper = OFF  # turn beeper OFF
    wait(200)  # pause here for 200 milliseconds before continuing

A laser ruler on the OLED. It shows -- when nothing is in range (999) and beeps when something is closer than 10 cm.

# Add the libraries you need
import oled_display
import servo
import tcs34725

# Give your pins easy-to-remember names
o1 = set_name("arm")

# ===== Colour-sorting arm =====

# This code block executes only once
setup:
    oled_begin()  # starts the OLED
    o7 = set_function(SDA)  # cannot be changed
    o8 = set_function(SCL)  # cannot be changed
    arm = set_output(servo, 90)

# This code block executes forever
loop:
    oled_write(1, left, small, regular, "R " + color_red())  # write "R " + color_red() on OLED line 1 (small, from the left)
    oled_write(2, left, small, regular, "G " + color_green())  # write "G " + color_green() on OLED line 2 (small, from the left)
    oled_write(3, left, small, regular, "B " + color_blue())  # write "B " + color_blue() on OLED line 3 (small, from the left)
    oled_write(4, left, small, regular, "Light " + color_brightness())  # write "Light " + color_brightness() on OLED line 4 (small, from the left)
    c = color_name()  # the colour it sees, as a colour name
    if c == "red":  # when c == "red"
        servo_write_angle(arm, 30)  # point the arm at the red box
    elif c == "green":  # otherwise, when c == "green"
        servo_write_angle(arm, 90)  # the green box
    elif c == "blue":  # otherwise, when c == "blue"
        servo_write_angle(arm, 150)  # the blue box
    wait(300)  # pause here for 300 milliseconds before continuing

A colour-sorting arm: the OLED shows R, G, B and brightness, and a servo points to the red, green or blue box. Test your own coloured cards first and change the angles to match your boxes.

# Add the libraries you need
import buzzer
import apds9960

# Give your pins easy-to-remember names
o1 = set_name("lamp")
o2 = set_name("beeper")

# ===== Wave-to-switch lamp =====

# This code block executes only once
setup:
    lamp = set_output(led)
    beeper = set_output(buzzer)
    o7 = set_function(SDA)  # cannot be changed
    o8 = set_function(SCL)  # cannot be changed
    level = 0  # set level to 0

# This code block executes forever
loop:
    g = gesture()  # up, down, left, right โ€” or None
    if g == "up":  # when g == "up"
        level = 100  # set level to 100
    elif g == "down":  # otherwise, when g == "down"
        level = 0  # set level to 0
    elif g == "right" and level <= 80:  # otherwise, when g == "right" and level <= 80
        level = level + 20  # set level to level + 20
    elif g == "left" and level >= 20:  # otherwise, when g == "left" and level >= 20
        level = level - 20  # set level to level - 20
    lamp = pwm(level)  # set lamp to level
    if proximity() > 90:  # when proximity() > 90
        beeper = ON  # a hand is very close
    else:  # otherwise
        beeper = OFF  # turn beeper OFF

Wave to switch a lamp: swipe up for full brightness, down for off, right and left for brighter and dimmer in steps of 20. A hand very close to the sensor sounds the beeper.

# Add the libraries you need
import oled_display
import pulse_oximeter

# Give your pins easy-to-remember names
o1 = set_name("heart_led")

# ===== Heartbeat display (learning only) =====

# This code block executes only once
setup:
    oled_begin()  # starts the OLED
    o7 = set_function(SDA)  # cannot be changed
    o8 = set_function(SCL)  # cannot be changed
    heart_led = set_output(led)

# This code block executes forever
loop:
    if finger_detected() == 0:  # when finger_detected() == 0
        oled_write(1, center, small, bold, "Rest a finger")  # write "Rest a finger" on OLED line 1 (small bold, centred)
        oled_clear_line(2)  # clear line 2 of the OLED
        oled_clear_line(3)  # clear line 3 of the OLED
    else:  # otherwise
        oled_write(1, center, small, bold, "Keep still")  # write "Keep still" on OLED line 1 (small bold, centred)
        oled_write(2, left, small, regular, "Heart " + heart_rate() + " per min")  # write "Heart " + heart_rate() + " per min" on OLED line 2 (small, from the left)
        oled_write(3, left, small, regular, "SpO2 " + spo2() + " %")  # write "SpO2 " + spo2() + " %" on OLED line 3 (small, from the left)
    if heart_beat() == 1:  # when heart_beat() == 1
        heart_led = ON  # turn heart_led ON
        wait(100)  # pause here for 100 milliseconds before continuing
        heart_led = OFF  # turn heart_led OFF

A heartbeat display: it asks for a finger, then shows the heart rate and SpO2, and the LED blinks with every beat. A learning project only, not a medical device.

Open TinkerPy Code

๐ŸŽ‰Fun examples

๐ŸฌSweet sorter

Feed coloured sweets or beads past the colour sensor and let a servo flick each colour into its own cup.

๐Ÿช„Magic wand lamp

Wave your hand like a magician over the APDS-9960 and the lamp obeys โ€” no switch touched.

๐Ÿ’“Heartbeat before and after

Measure your heart rate sitting quietly, then after 20 jumping jacks. Exercise makes the heart beat faster!

๐ŸŒWhere itโ€™s used

๐Ÿ› ๏ธProject ideas

Colour-sorting robot

Put the colour sensor at the front of a robot car. It drives along, stops at a coloured card and turns left for red and right for blue. Show the colour on the OLED.

๐Ÿงฐ You need: robot car with TinkerPy board, TCS34725 colour sensor, OLED, coloured cards
Wave-to-switch lamp

Use the APDS-9960 to switch and dim an LED lamp with swipes. Add a beep for every swipe and show the brightness level on the OLED.

๐Ÿงฐ You need: TinkerPy board, APDS-9960, LED, buzzer, OLED

โญPoints to remember

  1. laser_distance() gives cm from 3 to about 200; 999 = nothing in range.
  2. The VL53L0X and TCS34725 share address 0x29 โ€” use only one of them.
  3. color_name() gives red, orange, yellow, green, blue, purple, pink, white or black.
  4. Store it first: c = color_name(), then compare c == "red".
  5. color_red(), color_green(), color_blue() give 0โ€“255; the strongest is 255.
  6. color_brightness() gives 0โ€“100; hold the colour 1โ€“2 cm away.
  7. gesture() gives up, down, left, right โ€” or None.
  8. A swipe lasts one pass of loop: โ€” store it in g.
  9. proximity() goes from 0 (far) to 100 (very close).
  10. finger_detected() is 1 while a finger rests on the pulse sensor.
  11. heart_rate() and spo2() are 0 until a few beats are measured.
  12. heart_beat() is 1 for one loop at every beat.
  13. The pulse oximeter is for learning, never for medical decisions.
  14. All four sensors use o7/o8 and need board firmware 2.27.
๐Ÿคฏ
Did you know?

The VL53L0X measures distance by timing light. Light travels about 30 cm in one billionth of a second, so the chip measures times far shorter than a blink of an eye.

โ“Mini quiz

๐Ÿ”‘
Log in to try the mini quiz

5 quick questions to check yourself โ€” free with your TinkerPy account.

Log in