DIY Clap Reactive Night Lamp

by carbonmk in Circuits > Raspberry Pi

1157 Views, 0 Favorites, 0 Comments

DIY Clap Reactive Night Lamp

IMG_9817.jpeg
DIY Clap Light Demonstration

This project is a DIY soft-light lamp that also plays a selection of relaxing ambient noises to help fall asleep. Additionally, it has an option to set alarm if you need an alarm for the mornings. For easy convenience, the lights are toggled on and off by a clap or really any loud enough noise. The calming sounds are toggled on and off with a tap of the copper tape on our laminated piece of paper. 

The lights are coded to be the color of warm-white, a yellow-white that is great for nighttime and early morning since it has limited blue light, which is better for your eyes. Calming sounds found help provide a relaxing atmosphere when you are trying to fall asleep. 

Supplies

Electronics:

- 2 Microcontrollers (I used the CPB and Pico W), or one microcontroller if you have an external mic for the Pico W.

- An LED strip that can be connected to the CPB. Here I am using 2, .5 meter 30 LED strips.

- A Speaker that has an audio plug.

- 2 Alligator to pin clips

- 5 Alligator to alligator clips

- 7 Pin wires

- Stemma QT plug with pins on the end

- An Adafruit MPR121

- An Adafruit microSD SPI reader (pins already soldered on).

- An SD card (32 gigabytes or less)

- 2 USB cables (to power the microcontrollers)

- 2 Battery packs (or one if you have 2 USB slots for power, which I do)

Other materials:

- A hollow lamp, so that the components can be placed in the base, with only the speaker being out (the speaker can also go inside the lamp if you want dampened sound). 

- Some tape or adhesive

- Copper tape

- Laminated paper for your sound selections

- SD Card reader for your computer

Wire the CPB

IMG_9814.jpeg

1-    Take one LED strip and connect the white alligator clip to A1 (or any other signal connection). 

2-    Connect the red alligator clip to any power connection.

3-    Connect the black alligator clip to any ground connection.

4-    Take the second LED strip and connect the white alligator clip to A6 (or any other signal connection). 

5-    Connect the red alligator clip to any power connection.

6-    Connect the black alligator clip to any ground connection.

7-    Connect the CPB to the power module you have.

This will ensure a properly connected CPB. This will be the controller for the lights, which will be activated by a clap.

Wiring the Speaker to the Pico W

IMG_9805.jpeg

1-    Take one of the alligator to pin clips and connect the pin to any ground on the Pico.

2-    Connect the alligator clip to the base of the audio jack cable. 

3-    Take the other alligator to pin clips and connect the pin to GP15 on the Pico. 

4-    Connect the alligator clip to the tip of the audio jack cable.

5-    If applicable, make sure to turn on the speaker.

The speaker will play the sounds from your selected ones, here being a mix of nature sounds.

Wiring the Adafruit MPR121 to the Pico W

IMG_9807.jpeg

1-    Plug the Stemma QT wire into the MPR121.

2-    The yellow wire is SCL which is connected to GP5 on the Pico.

3-    The blue wire is SDA and is connected to GP4 on the Pico.

4-    The red wire is power which is connected to 3.3 Volts out, not VBUS!

5-    The black wire is ground which is connected to any ground on the Pico W.

6-    For each sound and its corresponding touch pad, use an alligator-to-alligator clip to connect the pad on the MPR121 to the copper tape on your sound sheet. 

The final step will allow you to tap on a piece of the copper tape for the sound to play rather than the actual MPR121 itself. It is not necessary to do this, as you can just touch the actual MPR121 itself.

Wiring the Adafruit SD Card Reader to the Pico W

IMG_9808.jpeg
IMG_9809.jpeg

1-    Using the SD card reader for your computer, make a new folder on the SD card and load any sounds you want into that folder. Make sure to remember the name of the folder as this will be the path for your sounds in the code.

2-    If applicable, make sure to solder the pins onto your Adafruit SD card reader.

3-    Take a pin-to-pin wire and connect it to 3.3 Volts on the Pico W and the 3V slot on the SD Card reader.

4-    Using another pin-to-pin wire, connect it to any ground on the Pico W and the ground slot on the SD card reader.

5-    Connect a pin-to-pin wire to GP10, which is SCK, to CLK slot on the SD Card reader.

6-    Connect a pin-to-pin wire to GP11, which is SI or TX, to the “DO SO” slot on the SD card reader.

7-    Connect a pin-to-pin wire to GP12, which is SO or RX, to the “CMD SI” slot on the SD card reader.

8-    Connect a pin-to-pin wire to GP13, which is CS, to the “DE CS” slot on the SD card reader.

9-    Finally, insert the SD card into the slot, you will hear a click when the SD Card is properly inserted. 

10- Plug the Pico W into your power source. 

Assembling the Lamp

IMG_9816.jpeg

1-    Carefully place the CPB in the center of the lamp, perhaps where the lightbulb should be. 

2-    Using your adhesive of choice, stick the LED strips to the inside of the lamp shade. Make sure it is secure and stable. 

3-    This is an optional step: you can wrap the LED in some sort of parchment or tissue paper to diffuse the light. 

4-    Open the bottom part of the lamp to get a better view of the hollow inside.

5-    Place the Pico W inside the hollow lamp, making sure the wires to the paper and the speaker have a place to easily be placed outside.

6-    Make sure the power to your power source is on.

7-    Enjoy your night lamp!

Code for the Project

Here I attached the code for each microcontroller. Additionally I have pasted the code for each below:

CPB:

#CPB Part of the code

import time, neopixel, board #import our necessary libraries

from adafruit_circuitplayground import cp


#set up both neopixel strips

strip_pin1 = board.A1

strip_pin2 = board.A6

strip_num_of_lights = 30

strip1 = neopixel.NeoPixel(strip_pin1, strip_num_of_lights, brightness = 0.1, auto_write = True)

strip2 = neopixel.NeoPixel(strip_pin2, strip_num_of_lights, brightness = 0.1, auto_write = True)


#defind our color

WARM_WHITE = (255, 175,25)


#have a variable so we can toggle the lights on and off

lights_on = False


# the main loop

while True:

  if lights_on: # Turn the strips this color

    strip1.fill((255, 175,25))

    strip2.fill((255, 175,25))

    if cp.loud_sound(sound_threshold=550): # if a noise is detected that surpoases the threshold and the lights are on, then turn them off

      lights_on = False

      time.sleep(0.5)

  else: # turn the strips off

    strip1.fill((0,0,0))

    strip2.fill((0,0,0))

    if cp.loud_sound(sound_threshold=550): # if a noise is detected that surpoases the threshold and the lights are off, then turn them on

      lights_on = True

      time.sleep(0.5)

Pico W code:

#Night Light Pico W Code

#import the necessary libraries for our build

import time, board, mount_sd, busio

import os, time, ssl, wifi, socketpool, adafruit_requests

import rtc, circuitpython_schedule as schedule


#set up audio with imports and where your speaker is connected to

from audiocore import WaveFile

from audiomp3 import MP3Decoder

from audiopwmio import PWMAudioOut as AudioOut

audio = AudioOut(board.GP15)


#from here down is optional

#set alarm time

alarm = ["15:44"]

path2 = "/sd/alarm/"


#set up alarm function:

def play_alarm(filename):

  with open(path2 + filename, "rb") as wave_file:

    wave = WaveFile(wave_file)

    audio.play(wave)

    while audio.playing:

      pass


#set up clock

clock = rtc.RTC()


# log into wifi nextwork using the data in settings.toml

wifi.radio.connect(os.getenv("WIFI_SSID"), os.getenv("WIFI_PASSWORD"))

print("Connected to WiFi")


# sockets set up an endpoint for communication as a resuable 'pool'

pool = socketpool.SocketPool(wifi.radio)

# create an object so that a request for web data can be made

requests = adafruit_requests.Session(pool, ssl.create_default_context())


#get an api callable url

url = "https://worldtimeapi.org/api/timezone/"

timezone = "America/New_York"

url = url + timezone


#a resuable function to reliably get time from the internet

def get_time():

  print(f"Accessing url: \n{url}")

  response = requests.get(url)


  #convert response into json

  json = response.json()

  # parse out values we want

  unixtime = json['unixtime']

  raw_offest = json["raw_offset"]


  #create local time in seconds

  location_time = unixtime + raw_offest


  #turn seconds into time components

  current_time = time.localtime(location_time)


  #format and print time and date

  printable_time = f"{current_time.tm_hour:d}:{current_time.tm_min:02d}:{current_time.tm_sec:02d}"

  printable_date = f"{current_time.tm_mon:d}/{current_time.tm_mday:d}/{current_time.tm_year:02d}"

  print(f"printable_time: {printable_time}")

  print(f"printable_date: {printable_date}")


  #set the rtc with the component time in current_time

  clock_datetime = time.struct_time(current_time)


# make your job, here it is just simply playing the alarm

def job():

  play_alarm("calmAlarm.wav")

  print("WAKE UP AND SMELL DA COFFEE")


#call get_time() once, first, to get the time from the web

get_time()


#schedule the jobs, set our alarm for 7 AM every day

schedule.every().day.at("07:00").do(job)

print("scheduled alarm at: 07:00")


schedule.every().day.at("00:00").do(get_time)# update time at midnight each day


# above this comment is the optional code for the alarm


#Set up mpr121

import adafruit_mpr121

from adafruit_debouncer import Button


#set up i2c object

i2c = board.STEMMA_I2C()

touch_pad = adafruit_mpr121.MPR121(i2c)

pads = []

for t_pad in touch_pad:

  pads.append(Button(t_pad, value_when_pressed=True))


#a seperate path than the alarm sound, so the alarm cannot be triggered by the touchpads

path1 = "/sd/sleeps/"

is_playing = False


#our sound files on the SD card

sleep = ["beachsegulls.wav", "birdsforest.wav", "calmocean.wav", "calmRain.wav", "rainforest.wav"]


def play_sound(filename, num):

  with open(path1 + filename, "rb") as wave_file:

    wave = WaveFile(wave_file)

    audio.play(wave, loop=True) # loop the sounds so we have it play all night

    while audio.playing:

      pads[num].update()

      if pads[num].pressed:

        print(num)

        audio.stop()

      else:

        pass


while True: # the main loop where we have our pads, make sure we update their value.

  for i in range(len(pads)):

    pads[i].update()

    if pads[i].pressed: # if a touch pad is pressed, print which pad we just touched then play the sound corresponding to the touch pad

      print(i)

      play_sound(sleep[i], i)