Welcome to Hackster!
Hackster is a community dedicated to learning hardware, from beginner to pro. Join us, it's free!
C Forde
Published © CC BY-SA

Balanced Lighting

3D Printed monostatic ball based adjustable lamp with flower head, variable colour and intensity using a Plasma 2040 & RGBW Neopixels

IntermediateFull instructions providedOver 2 days70
Balanced Lighting

Things used in this project

Hardware components

Pimoroni Plasma 2040
Controller for WS2812/Neopixel and APA102/Dotstar addressable LED strip.
×1
Adafruit neopixel RGBW
×12
DFRobot Rotary Encoder EC11
360 degree rotary encoder module
×1
Capacitor 1000uF/6V3
×1
Resistor 470R/1W
×1
USB-C extension cable
×1

Software apps and online services

Thonny

Hand tools and fabrication machines

3D Printer (generic)
3D Printer (generic)

Story

Read more

Schematics

Circuit Schematic

All ellectrically connected elements

Code

blamp6.py

MicroPython
Code for light colour and intensity all controlled by an EC11 rotary encoder with a Plasma 2040.
Using Micropython V1.19
import machine
import utime
import plasma
from plasma import plasma2040

# define LED colour selection
NUM_COLOURS = 8 #none,red,orange,yellow,green,blue,indigo,violet,white
RGBW = [[0,0,0,0],[255,0,0,0],[255,140,0,0],[255,255,0,0],[0,255,0,0],[0,0,255,0],[75,0,130,0],[255,0,255,0],[0,0,0,255]]

# initialize LED's
NUM_LEDS = 12
led_strip = plasma.WS2812(NUM_LEDS, 0, 0, plasma2040.DAT, rgbw=True)
led_strip.start()

for i in range(NUM_LEDS): #switch off LED's if on
   led_strip.set_rgb(i, 0, 0, 0, 0)

button = 0              #push button value to enable colour or intensity
intensity = NUM_COLOURS #LED intensity divider
counter = 0             #value to select colour
status = False          #valid rotation flag
tdiff = 0               #rotation direction +1 or -1
phase_a = 0             #channel A level
phase_b = 0             #channel B level

def ENC_A_change(pin):
    global phase_a, ENC_A_status, phase_b, tdiff
    phase_a = ENC_A()
    phase_b = ENC_B()
    if phase_a == phase_b:
        tdiff = 1
    phase_a = ENC_A()
    ENC_compare()
    #utime.sleep_ms(5)

    return
 
def ENC_B_change(pin):
    global phase_b, ENC_B_status, phase_a, tdiff
    phase_b = ENC_B()
    phase_a = ENC_A()
    if phase_a == phase_b:
        tdiff = -1
    phase_b = ENC_B()
    ENC_compare()
    #utime.sleep_ms(5)
    
    return

def ENC_compare():
    global status
    status = True

    return

# assign pins for encoder and initialise IRQ and levels for EC11 rotary encoder
ENC_A = machine.Pin(26, machine.Pin.IN, machine.Pin.PULL_UP)
ENC_A.irq(trigger=machine.Pin.IRQ_RISING|machine.Pin.IRQ_FALLING, handler=ENC_A_change)
ENC_B = machine.Pin(27, machine.Pin.IN, machine.Pin.PULL_UP)
ENC_B.irq(trigger=machine.Pin.IRQ_RISING|machine.Pin.IRQ_FALLING, handler=ENC_B_change)
# assign pin for encoder switch
ENC_C = machine.Pin(28, machine.Pin.IN, machine.Pin.PULL_UP)

def isNeg(val): #determine numeric sign
    if val < 0: #negative
       return True 
    if val > 0: #positive
       return False 

def isButtonPushDown():
  if not(ENC_C.value()):
      utime.sleep_ms(5)
      if not(ENC_C.value()):
          return True
  else:
    return False

def LED_intensity():
 # change each RGB value by the same fraction to adjust brightness
 global intensity, NUM_COLOURS   
 
 led = [] #storage for new RGB values
 bright = (intensity/NUM_COLOURS) #fraction of brightness
  
 if bright > 0:
  for i in range(4):
   led.append(int((RGBW[counter][i])*bright))
 else:
  led=[0, 0, 0, 0] #LED's off
 
 for i in range(NUM_LEDS): 
     led_strip.set_rgb(i, led[0], led[1], led[2], led[3])
     utime.sleep_ms(5)
 
 return

while True:

 if isButtonPushDown():
  button += 1
  if button > 1:
      button = 0
  #print("button press", button)     
 else:
  if status:
   if button == 0: 
    #change the colours
    if isNeg(tdiff):
     counter -= 1
     if counter < 0:
       counter = 0
    if not(isNeg(tdiff)):
     counter += 1
     if counter > NUM_COLOURS:
       counter = NUM_COLOURS  
    for i in range(NUM_LEDS):
       led_strip.set_rgb(i, RGBW[counter][0], RGBW[counter][1], RGBW[counter][2], RGBW[counter][3])
    
    LED_intensity() #retain intensity change if previously updated
   
   else:
    #change the brightness
    if isNeg(tdiff):
     intensity -= 1
     if intensity < 0:
       intensity = 0
    if not(isNeg(tdiff)):
     intensity += 1
     if intensity > NUM_COLOURS:
       intensity = NUM_COLOURS  

    LED_intensity()
 
 status = False

 utime.sleep_ms(400)

Credits

C Forde
11 projects • 3 followers
Contact

Comments

Please log in or sign up to comment.