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
🏡 My Home Assistant Configs. Be sure to 🌟 my repo to follow the updates!

Home Assistant Configuration Here's my Home Assistant configuration. I have installed HA on a Lenovo ThinkCentre M93P Tiny with an Intel Dual-Core i5-

iLyas Bakouch 25 Dec 30, 2022
DIY split-flap display

The goal is to make a low-cost display that's easy to fabricate at home in small/single quantities (e.g. custom materials can be ordered from Ponoko or similar, and other hardware is generally availa

Scott Bezek 2.5k Jan 05, 2023
The robot is an autonomous small scale racing car using NVIDIA Jetson Nano.

The robot is an autonomous small scale racing car using NVIDIA Jetson Nano. This project utilizes deep learning neural network framework Keras/Tensorflow, together with computer vision library OpenCV

1 Dec 08, 2021
Ingeniamotion is a library that works over ingenialink and aims to simplify the interaction with Ingenia's drives.

Ingeniamotion Ingeniamotion is a library that works over ingenialink and aims to simplify the interaction with Ingenia's drives. Requirements Python 3

Ingenia Motion Control 7 Dec 15, 2022
Samples for robotics, node, python, and bash

RaspberryPi Robot Project Technologies: Render: intent Currently designed to act as programmable sentry.

Martin George 1 May 31, 2022
Software framework to enable agile robotic assembly applications.

ConnTact Software framework to enable agile robotic assembly applications. (Connect + Tactile) Overview Installation Development of framework was done

Southwest Research Institute Robotics 29 Dec 01, 2022
Implemented robot inverse kinematics.

robot_inverse_kinematics Project setup # put the package in the workspace $ cd ~/catkin_ws/ $ catkin_make $ source devel/setup.bash Description In thi

Jianming Han 2 Dec 08, 2022
CircuitPython Driver for Adafruit 24LC32 I2C EEPROM Breakout 32Kbit / 4 KB

Introduction CircuitPython driver for Adafruit 24LC32 I2C EEPROM Breakout Dependencies This driver depends on: Adafruit CircuitPython Bus Device Regis

foamyguy 0 Dec 20, 2021
Pinion — Nice-looking interactive diagrams for KiCAD PCBs

Pinion — Nice-looking interactive diagrams for KiCAD PCBs Pinion is a simple tool that allows you to make a nice-looking pinout diagrams for your PCBs

Jan Mrázek 297 Jan 06, 2023
ArduinoWaterHeaterIOT - IoT Probe of a solar PV water heating system - Arduino, Python, MQTT, MySQL

ArduinoWaterHeaterIOT IoT Probe of a solar PV water heating system - Arduino, Raspberry Pi, Python, MQTT, MySQL The Arduino sends the AC and DC watts

Jacques Fourie 1 Jan 11, 2022
Connect a TeslaMate instance to Home Assistant, using MQTT

TeslaBuddy Connect a TeslaMate instance to Home Assistant, using MQTT. It allows basic control of your Tesla vehicle via Home Assistant (currently, ju

4 May 23, 2022
A Raspberry Pi Pico powered Macro board, like a Streamdeck but cheaper and simpler.

Env-MCRO A Raspberry Pi Pico powered Macro board, like a Streamdeck but cheaper and simpler. (btw this image is a bit outdated, some of the silkscreen

EnviousData 68 Oct 14, 2022
An open source two key macro-pad modeled to look like a cartoony melting popsicle

macropopsicle An open source two key macro-pad modeled to look like a cartoony melting popsicle. Build instructions Parts List -1x Top case half (3D p

17 Aug 18, 2022
A simple Picobot project implemented in Python

Python-Picobot A simple Picobot project implemented in Python About Explanation This is my first programming project. Picobot use rules.txt file which

Shayan Shiravani 0 Apr 03, 2022
Repo for the esp32s2 version of the Wi-Fi Nugget

Repo for the esp32s2 version of the Wi-Fi Nugget

HakCat 30 Nov 05, 2022
Programmable Rainbow Redstone Computer

Programmable Rainbow Redstone Computer Table of contents What is it? Program flasher How to use it What is it? PRRC is Programmable Rainbow Redstone C

Fern H 2 Jun 07, 2022
A ESP32 project template with a web interface built in React

ESP AP Webserver demo.mp4 This is my experiment with "mobile app development" for the ESP32. The project consists of two parts, the ESP32 code and the

8 Dec 15, 2022
FHEM Connector for FHT Heating devices

home-assistant-fht from: https://github.com/Rsclub22 FHEM Connector for FHT Heating devices (connected via FHEM) Requires FHEM to work You can find FH

5 Dec 01, 2022
A modular sequencer based on Pi Pico & EuroPi

PicoSequencer A modular sequencer based on Pi Pico & EuroPi by Zeno Van Moerkerke / Keurslager Kurt For now it is 'only' a trigger sequencer, but I si

5 Oct 27, 2022
BoneIO is a compact IO controller for home automation.

Project description BoneIO is a compact IO controller for home automation. Main features of this controller are Compact size (27x11x6)cm - 15 DIN modu

Maciej Krasuski 120 Nov 30, 2022