Controlling fireworks with micropython

Overview

Controlling-fireworks-with-micropython

How the code works


line 1-4

from machine import Pin, I2C
import ds1307
from time import localtime, mktime, sleep

We first import all the necessary libraries. Here is an explanation of the time.mktime() function from the Micropython docs. from Micropython docs:

time.mktime()

This is inverse function of localtime. It’s argument is a full 8-tuple which expresses a time as per localtime. It returns an integer which is the number of seconds since Jan 1, 2000.

The ds1307 is a library used to interface with RTC module. Find it here..


line 6-20

#rtc i2c pins
sda_pin = 26
scl_pin = 27

#pins for 7seg display
digits = (9, 8, 7, 6) #dig 1 2 3 4
segments = (11, 12, 16, 14, 17, 10, 13) # A B C D E F G, dp at Pin 15

#pins to activate relays
rel1 = 18
rel2 = 19

#rtc i2c setup
i2c = I2C(1, sda=Pin(sda_pin), scl=Pin(scl_pin))
ds = ds1307.DS1307(i2c)

We create variables for our circuit configuration. And then initiate the I2C and create a ds1307 class.


line 22-33

#segments values for displaying numbers  
num = {"-": (0,0,0,0,0,0,0),
       "0": (1,1,1,1,1,1,0),
       "1": (0,1,1,0,0,0,0),
       "2": (1,1,0,1,1,0,1),
       "3": (1,1,1,1,0,0,1),
       "4": (0,1,1,0,0,1,1),
       "5": (1,0,1,1,0,1,1),
       "6": (1,0,1,1,1,1,1),
       "7": (1,1,1,0,0,0,0),
       "8": (1,1,1,1,1,1,1),
       "9": (1,1,1,1,0,1,1)}

The tuples store the states (0=OFF, 1=ON) of the LED segments in order order to display each digit. NB: "-" is a blank character which keeps all segments off.


line 35-48

Pin(rel1, mode=Pin.OUT, value=0)
Pin(rel2, mode=Pin.OUT, value=0)

def init():
    #initiate digit pins at HIGH
    for digit in digits:
        Pin(digit, Pin.OUT)
        Pin(digit).on()
    
    #initiate segment pins at LOW
    for seg in segments:
        Pin(digit, Pin.OUT)
        Pin(digit).off()
init()

Relay pins begin as OFF. The init() function takes the display off. For the display to be off, the digit pins should be ON while the segments should be GND.


line 50

deadline = (2022, 1, 2, 17, 41, 0, 0, 0)  #time to countdown to

This value can be changed to a desired date and/or time. It is the target time for the countdown, and it is the 8-tuple time format used in micropython:

(year, month, mday, hour, minute, second, weekday, yearday) ... The format of the entries in the 8-tuple are:

year includes the century (for example 2014).

month is 1-12

mday is 1-31

hour is 0-23

minute is 0-59

second is 0-59

weekday is 0-6 for Mon-Sun

yearday is 1-366


The subsequent code runs inside of a while True loop


line 54

current = localtime() #current = ds.datetime() for RTC

#time difference between the two events/moments in seconds
diff = mktime(deadline) - mktime(current)

First of all, we get the current time either from port when the board is connected, time.localtime(), or from the RTC, ds.datetime().

When we pass the deadline or the current variables into local.mktime(), we get the time, in seconds since the epoch (info about local.mktime() at the top) Mathemetically, by subtracting time-since-epoch of both deadline and current, we get the time difference between deadline and current, hence time to go until its the deadline.


line 59-62

#convert seconds to hours, minutes, seconds
hours, minutes = divmod(diff,3600)
minutes, seconds = divmod(minutes,60)
seconds = int(seconds)

Since the time is in seconds, we have to convert it to total Hours, Minutes, and Seconds. To that, we have to

  1. find the total hours in `diff` by dividing the value by the number seconds in an hour, 3600 seconds. The remainder from this division will give total minutes then seconds
  2. dividing on the remainder with 60 (number of seconds in a minute) gives total minutes. The remainder from this division is the seconds

So how divmod works is that you pass two parameters, the dividend followed by the divisor and the functions returns a tuple: first item is the quotient then the second item is the remainder. Divisor-Dividend-Quotient explained

In this line seconds = int(seconds), we take only the integer of the previous seconds variable, discarding everything behind the decimal point.


line 63-67

#choosing between seconds countdown and HH:MM countdown
if (hours == 0) and (minutes <=1):
    s = f"--{seconds:02d}" 
else:
    s = f"{hours:02d}{minutes:02d}" 

Before the countdown time goes below a minute, the time is displayed as hours and minutes (HHMM), and when it is under a minute, we display seconds (--SS).


line 69-74

for digit in range(4):
    for seg in range(7):
        Pin(segments[seg], mode=Pin.OUT, value=num[str(s[digit])][seg])
    Pin(digits[digit], mode=Pin.OUT, value=0)
    sleep(0.001)
    Pin(digits[digit], mode=Pin.OUT, value=1)
for digit in range(4):
    for seg in range(7):

These loop through every segment of every digit.

Let us break this Pin(segments[seg], mode=Pin.OUT, value=num[str(s[digit])][seg]) down:

  1. `segments[seg]`- The pin number of the segment to be addressed is selected from the `segments` array by using the current counter value as the index.
  2. `mode=Pin.OUT`- The pin is to be an output
  3. `value=num[str(s[digit])][seg]`
      Example, let me explain it with our value of `s` representing 2 hours 30 min: `s = "0230"`
    • `str(s[digit])`-from `s`, we set the position of the digit to handle, indexed by `digit` counter from outer loop. We convert this value to string.
    • `>>> On first run of the loop we will have "0"`
    • `num[str(s[digit])]`-the string we found, we use it as a key to look up the `num` dictionary in order to get the tuple with LED state valus that represent different digits.
    • `>>> For a key of "0", we have the value (1,1,1,1,1,1,0)`
    • `num[str(s[digit])][seg]`-we index the tuple with the current value of seg counter. And the tuple item we get at whatever index will be either 1(ON) or 0(OFF) to define the state of the respective segment.
    • `>>>If seg is equal to 3, then we get a 1 which we assign to the value parameter to turn the segment ON.`
    the loop runs 7 times to appropriately, turn on the 7 segments that make up a digit.

In this line Pin(digits[digit], mode=Pin.OUT, value=0), digits[digit] indexes digits tuple to get the pin number of the digit to control. We set the pin to OFF (or GND) in order to bring the digit on. So these 3 lines Pin(digits[digit], mode=Pin.OUT, value=0), ``sleep(0.001), and Pin(digits[digit], mode=Pin.OUT, value=1)` control the display to show a single digit at a time, and then bring it off before showing another digit individually. The digits on the display appear as if they are all displayed simaltenously instead of individually. This is because thecycle of displaying the digits individually occurs very fast, it runs over each digit in 1 millisecond or 0.001 seconds.


line 76-80

if s == "--00":
    Pin(rel1, mode=Pin.OUT, value=1)
    sleep(2)
    Pin(rel2, mode=Pin.OUT, value=1)
    quit

if we have reached the end of our countdown, i.e time left to deadline is 0, or s is "--00", we turn ON the pins where relays are connected. This sets alight the fireworks. We then quit the whileloop.


line 81 We run the init() function to turn the display off.


To do

  • Documet code
  • Document circuit
  • Explain how the display works
  • Explain the maling of electronic igniters
Owner
Montso Mokake
Python: Micropython, Microcontrollers, MachineLearning.
Montso Mokake
HomeAssistant - Polyaire AirTouch 4 Integration

HomeAssistant - Polyaire AirTouch 4 Integration Custom integration to add an AirTouch 4 AC Controller Installation: Copy contents of custom_components

7 Aug 05, 2022
Code reimplementation of some papers published in SAIL-Lab

SAIL SAIL-Lab统一代码库 Motivation 创建这个项目的动机最早来源于实验室组内成员相互Debug代码的时候遇到的麻烦。

Jianwen Chen 8 Nov 15, 2022
Raspberry Pi Power Button - Wake/Power Off/Restart(Double Press)

Control Raspberry pi with physically attached button. Wake, Power Off, and Restart (Double Press) . Python3 script runs as a service with easy installation.

Stas Yakobov 16 Oct 22, 2022
Isaac Gym Environments for Legged Robots

Isaac Gym Environments for Legged Robots This repository provides the environment used to train ANYmal (and other robots) to walk on rough terrain usi

Robotic Systems Lab - Legged Robotics at ETH Zürich 372 Jan 08, 2023
Testing out some (stolen) DMA code for RP2040 Micropython

RP2040_micropython_dma testing out some (stolen) DMA code for RP2040 Micropython. Heavy inspiration and some code from https://iosoft.blog/2021/10/26/

2 Dec 29, 2022
EuroPi: A reprogrammable Eurorack project based on the Raspberry Pi Pico

EuroPi The EuroPi is a fully user reprogrammable module based on the Raspberry Pi Pico, which allows users to process inputs and controls to produce o

Allen Synthesis 218 Jan 01, 2023
Hardware: CTWingSKIT_BC28 Development Toolkit

IoT Portal Monitor Tools hardware: CTWingSKIT_BC28 Development Toolkit serial port driver: ST-LINK hardware development environment: Keli 5 MDK IoT pl

Fengming Zhang 1 Nov 07, 2021
Rasberry Pie GPIO memory game. Press the corresponding key to the lit LED.

RPie-keyboard-game Rasberry Pie GPIO memory game. Press the corresponding key to the lit LED. Randem LED (general output) is lit up on rasberrypi rand

Shawn Dowling 1 Oct 24, 2021
It is a program that displays the current temperature of the GPU and CPU in real time and stores the temperature history.

HWLogger It is a program that displays the current temperature of the GPU and CPU in real time and stores the temperature history. Sample Usage Run HW

Xeros 0 Apr 05, 2022
This is a collection of python modules that interact with the Ryze Tello drone.

This is a collection of python modules that interact with the Ryze Tello drone.

DJI-SDK 1.2k Jan 03, 2023
Doughskript interpreter for converting simple command sequences into executable Arduino C++ code.

Doughskript interpreter for converting simple command sequences into executable Arduino C++ code.

Svjatoslav 2 Jan 11, 2022
🎃 Some spooky code samples to hack yourself a pumpkin 👻

🎃 Tech Or Treat 👻 It's spooky season for those who celebrate Halloween, and to get in the spirit (spirit - get it? 👻 ) we thought it would be fun t

Jim Bennett 5 Feb 07, 2022
The main aim of this project is to avoid the accidents in shredding ( Waste Recycling Industry )

shredder-Machine-Hand-Safety The main aim of this project is to avoid the accidents in shredding ( Waste Recycling Industry ) . The Basic function of

Shubham Chaudhari 1 Nov 15, 2021
A simple Python script for toggling Philips Hue Lights by clapping

LightsClap A simple Python script for toggling Philips Hue Lights by clapping Usage pip3 install -r requirements.txt python3 main.py and press the Ent

Flux Industries 2 Nov 16, 2021
Python application, displaying currently played track from Spotify on OLED display connected via I2C

RaspberryPi Spotify OLED Display This application will display currently played track on SSD1306 OLED display connected to RaspberryPi. Displayed stuf

Wojciech Olech 2 Dec 30, 2021
Switch predictor for Home Assistant with AppDeamon

Home Assistant AppDeamon - Event predictor WORK IN PROGRESS - CURRENTLY NOT COMPLETE AND NOT WORK This is an idea under development (when I have free

37 Dec 17, 2022
Smart Tech Automation Remote via Kinematics Gesture control for IoT devices

STARK Smart Tech Automation Remote via Kinematics Gesture control for IoT devices View Demo · Report Bug · Request Feature Table of Contents About The

Juseong (Joe) Kim 1 Jan 29, 2022
Simple Weather Check base on Hefeng api, Work on raspberry Pi

Simple Weather Check base on Hefeng api, Work on raspberry Pi

Retr0mous 28 Sep 17, 2022
emhass: Energy Management for Home Assistant

emhass EMHASS: Energy Management for Home Assistant Context This module was conceived as an energy management optimization tool for residential electr

David 70 Dec 24, 2022
Python code written to utilize the Korlan usb2can hardware to send and receive data over the can-bus on a 2008 Nissan 350z

nissan_ecu_hacking Python code written to utilize the Korlan usb2can hardware to send and receive data over the can-bus on a 2008 Nissan 350z My goal

Liam Goss 11 Sep 24, 2022