Guido De SantisErik Welsh
Published

Laser-activated theremin

Buzzer activated by a VL53l0x TOF sensor that plays a music scale

BeginnerWork in progress16 hours129
Laser-activated theremin

Things used in this project

Hardware components

Gikfun 12x12x7.3 mm Tact Tactile Push Button Momentary SMD PCB Switch with Cap for Arduino (Pack of 25pcs) AE1027
×1
Onyehn 3pcs VL53L0X Time-of-Flight (ToF) Laser Ranging Sensor Breakout 940nm GY-VL53L0XV2 Laser Distance Module I2C IIC
×1
Resistor 220 ohm
Resistor 220 ohm
×1
PocketBeagle
BeagleBoard.org PocketBeagle
×1
Jumper wires (generic)
Jumper wires (generic)
×1
Buzzer
Buzzer
×1

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)
Breadboard, 400 Pin
Breadboard, 400 Pin

Story

Read more

Code

Laser_themenin

Python
# -*- coding: utf-8 -*-
"""
--------------------------------------------------------------------------
Laser_themenin
--------------------------------------------------------------------------
License:   
Copyright 2021-2023 Guido De Santis

Based on library from

Copyright 2018 Nicholas Lester

Redistribution and use in source and binary forms, with or without 
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this 
list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice, 
this list of conditions and the following disclaimer in the documentation 
and/or other materials provided with the distribution.

3. Neither the name of the copyright holder nor the names of its contributors 
may be used to endorse or promote products derived from this software without 
specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------
This file provides an interface to a PWM controllered buzzer.
  - Ex:  https://www.adafruit.com/product/1536


APIs:
  - Buzzer(pin)
    - play(frequency, length=1.0, stop=False)
      - Plays the frequency for the length of time

    - stop(length=0.0)
      - Stop the buzzer (will cause breaks between tones)
      
    - cleanup()
      - Stop the buzzer and clean up the PWM

"""
import time

import board
import busio




# ------------------------------------------------------------------------
# Global variables
# ------------------------------------------------------------------------


# ------------------------------------------------------------------------
# Main Tasks
# ------------------------------------------------------------------------
 


class Buzzer():
    pin       = None
    
    def __init__(self, pin):
        self.pin = pin
 
        # NOTE:  No other setup required
 
    # End def
    
    
    def play(self, frequency, length=1.0, stop=False):
        """ Plays the frequency for the length of time.
            frequency - Value in Hz or None for no tone
            length    - Time in seconds (default 1.0 seconds)
            stop      - Stop the buzzer (will cause breaks between tones)
        """
        if frequency is not None:
            PWM.start(self.pin, 50, frequency,0)
            print("Playing {0}".format(frequency))
             
        time.sleep(length)
        
        if (stop):
            self.stop()
        
    # End def

    
    def stop(self, length=0.0):
        """ Stops the buzzer (will cause breaks between tones)
            length    - Time in seconds (default 0.0 seconds)
        """
        PWM.stop(self.pin)

        time.sleep(length)
        
    # End def

    
    def cleanup(self):
        """Stops the buzzer and cleans up the PWM.
             *** This function must be called during hardware cleanup ***
        """
        self.stop()
        PWM.cleanup()
    # End def
    
# End class

# ------------------------------------------------------------------------
# Main script
# ------------------------------------------------------------------------

if __name__ == '__main__':

    import adafruit_vl53l0x
    import Adafruit_BBIO.PWM as PWM

    # Initialize I2C bus and sensor.
    i2c = busio.I2C(board.SCL, board.SDA)
    vl53 = adafruit_vl53l0x.VL53L0X(i2c)
    buzzer = Buzzer("P2_1")
    
    # Optionally adjust the measurement timing budget to change speed and accuracy.
    # See the example here for more details:
    #   https://github.com/pololu/vl53l0x-arduino/blob/master/examples/Single/Single.ino
    # For example a higher speed but less accurate timing budget of 20ms:
    # vl53.measurement_timing_budget = 20000
    # Or a slower but more accurate timing budget of 200ms:
    # vl53.measurement_timing_budget = 200000
    # The default timing budget is 33ms, a good compromise of speed and accuracy.
    
    # Main loop will read the range and print it every second.
        
    while True:
        range_value = vl53.range
        print("Range: {0}mm".format(range_value))
            
        if 260 < range_value < 300:
            buzzer.play(493, 1.0, True)  # Play 440Hz for 1 second when range is less than 800 mm
        elif 220 < range_value < 260:
            buzzer.play(440, 1.0, True)
        elif 180 < range_value < 220:
            buzzer.play(392, 1.0, True)
        elif 140 < range_value < 180:
            buzzer.play(349, 1.0, True)
        elif 100 < range_value < 140:
            buzzer.play(329, 1.0, True)
        elif 60 < range_value < 100:
            buzzer.play(293, 1.0, True)
        elif 0 < range_value < 60:
            buzzer.play(261, 1.0, True)
                       
        else:
            buzzer.stop()
            
        time.sleep(1.0)

    buzzer.cleanup()

Credits

Guido De Santis
1 project • 0 followers
Contact
Erik Welsh
33 projects • 18 followers
Contact
Thanks to Erik Welsh.

Comments

Please log in or sign up to comment.