ChristmasTown is a simple CircuitPython application to manage the lights in a decorative Christmas Town holiday scene. It is written in CircuitPython and uses a Raspberry Pi Pico WH RP2040 board with RGB NeoPixels to control the lights.
The Welcome to CircuitPython tutorial will help you get your Raspberry Pi Pico loaded with CircuitPython and interacting with the serial console. I'm not using the Mu Editor because I've been learning to program in other IDEs. If you're like me then you'll want to pay close attention to the "Connecting to the Serial Console" section. I strongly recommend clicking on the links for "Using Something Else" so you can get the correct syntax to connect to the serial console (in my case that was "Advanced Serial Console for Mac").
I also found the "Wooden NeoPixel Xmas Tree" tutorial by Liz Clark to be very helpful in brainstorming how I could engineer the project for the NeoPixels to align with each building in the town.
First, import the time and random modules to assist in managing the lights along with the board and neopixel libraries.
import random import time import board import neopixel
The main function instantiates the building and neopixel objects. It uses two for loops to iterate over the ChristmasTown objects turning the neopixel LEDs on and off in a random order for a random period of time. You'll want to rename the different ChristmasTown objects to whatever decorative buildings you have in your ChristmasTown. The application uses the time module to manage execution of these shifts on a randomized periodicity and it uses the random module to generate the random order for the building activity and the random time intervals.
def main(): '''Instantiate all the buildings in Christmas Town''' grand_house = ChristmasTown("Grand House") clock_tower = ChristmasTown("Clock Tower") tavern = ChristmasTown("Tavern") coffee_shop = ChristmasTown("Coffee Shop") church = ChristmasTown("Church") surf_shop = ChristmasTown("Surf Shop") pet_shop = ChristmasTown("Pet Shop") '''Instantiate and setup the neopixel LEDs''' # Update this to match the number of NeoPixel LEDs connected to your board. num_pixels = 30 pixels = neopixel.NeoPixel(board.GP0, num_pixels) pixels.brightness = 0.5 '''Manage the town lights''' # introduce an infinite loop while True: # iterate over all the ChristmasTown building objects for i in ChristmasTown.town_list: # set all the light timers in the buildings i.set_on_timer(ChristmasTown.rand_int_generator()) i.set_off_timer(ChristmasTown.off_func(i.get_on_timer())) # print statements to check the results print(f'{i.get_building()} is in a state of {i.get_bldg_state()}') print(f'{i.get_building()} is on for {i.get_on_timer()} min') print(f'{i.get_building()} is off for {i.get_off_timer()} min\n') for i in range(len(ChristmasTown.town_list)): # randomly select which building to turn the lights on index_value = random_int() print("Index value: ", index_value) # turn the lights on for the length of the on timer ChristmasTown.town_list[index_value].set_bldg_state(True) print(f"{ChristmasTown.town_list[index_value].get_building()} state is: {ChristmasTown.town_list[index_value].get_bldg_state()}") pixels[index_value] = (255, 0, 0) pixels.show() time.sleep(ChristmasTown.town_list[index_value].get_on_timer()) for i in range(len(ChristmasTown.town_list)): # randomly select which building to turn the lights off index_value = random_int() print("Index value: ", index_value) # turn the lights off for the length of the off timer ChristmasTown.town_list[index_value].set_bldg_state(False) print(f"{ChristmasTown.town_list[index_value].get_building()} state is: {ChristmasTown.town_list[index_value].get_bldg_state()}") pixels[index_value] = (0, 0, 0) pixels.show() time.sleep(ChristmasTown.town_list[index_value].get_off_timer()) def random_int(): return random.randint(0, len(ChristmasTown.town_list) - 1)
The application uses a ChristmasTown class to manage the individual buildings and stores each building object in a list called town_list. The class instance methods initialize the building the objects, get and set the building State between True/False, get and set the on/off timer for the lights, and generate a random integer.
class ChristmasTown(object): '''Christmas Town class creates the attributes and actions in the towns buildings''' town_list = [] # initialize a new building in the town def __init__(self, building): self.town_list.append(self) self.__building = building self.__bldg_state = False def __str__(self): return self.__building def set_building(self, building): self.__building = building def get_building(self): return self.__building def set_on_timer(self, on_timer): self.__on_timer = on_timer def get_on_timer(self): return self.__on_timer def set_off_timer(self, off_timer): self.__off_timer = off_timer def get_off_timer(self): return self.__off_timer def set_bldg_state(self, bldg_state): self.__bldg_state = bldg_state def get_bldg_state(self): return self.__bldg_state def rand_int_generator(): return random.randint(1, 59) def off_func(building_timer): return 60 - building_timer
Finally, call the main function.
if __name__ == '__main__': main()