Compare commits
No commits in common. 'develop' and 'master' have entirely different histories.
@ -1,21 +0,0 @@
|
|||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2021 Bramble-Hands-Software (BraHaSoft)
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
@ -1,127 +1,41 @@
|
|||||||
|
# RPi_WS2812b_LED
|
||||||
|
|
||||||
|
#Raspberry Pi Project
|
||||||
|
#WS2812b - LED
|
||||||
|
#Python3
|
||||||
|
|
||||||
# tickerPi
|
Objective:
|
||||||
|
|
||||||
tickerPi is a Python Program to handle WS281X LED interactions on a Raspberry Pi
|
Be able to pass through data (text, designs, colors, patterns, etc) through GPIO on a Raspberry Pi, through to WS2812b LEDs.
|
||||||
* WS2812b has only been tested at this time
|
|
||||||
|
|
||||||
## Authors
|
Initial Challenges:
|
||||||
|
|
||||||
* **Justin Healy**
|
1 - Rasberry Pi doesn't have 1:1 libraries for Neopixel, so need to write programs to pass off to the Adafruit libraries (already installed)
|
||||||
* **Vin Presciutti**
|
|
||||||
|
|
||||||
## Requirements
|
2 - Current LEDs are in a "zigzag" configuration (because we can not use the 1:1 Neopixel Matrix Module), we have to take on the overhead to configure/define our LED matrix, then convert our data to that matrix
|
||||||
|
Example: LED Matrix numbered by: 8x8
|
||||||
|
|
||||||
1. Python 3 - As Python 2 support is no longer available
|
|
||||||
2. Python 3 PIP
|
|
||||||
3. Python SMBus
|
|
||||||
4. RPI.GPIO
|
|
||||||
5. Adafruit Blinka
|
|
||||||
6. Adafruit Neopixel
|
|
||||||
7. RPI WS281X Libraries
|
|
||||||
8. Adafruit PixelFramebuffer
|
|
||||||
|
|
||||||
## Installation
|
0 | 15 | 16 | 31 | 32 | 47 | 48 | 63 |
|
||||||
|
1 | 14 | 17 | 30 | 33 | 46 | 49 | 62 |
|
||||||
|
2 | 13 | 18 | 29 | 34 | 45 | 50 | 61 |
|
||||||
|
3 | 12 | 19 | 28 | 35 | 44 | 51 | 60 |
|
||||||
|
4 | 11 | 20 | 27 | 36 | 43 | 52 | 59 |
|
||||||
|
5 | 10 | 21 | 26 | 37 | 42 | 53 | 58 |
|
||||||
|
6 | 9 | 22 | 25 | 38 | 41 | 54 | 57 |
|
||||||
|
7 | 8 | 23 | 24 | 39 | 40 | 55 | 56 |
|
||||||
|
|
||||||
1. Standard Updates for Raspberry Pi:
|
vs
|
||||||
```
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get upgrade
|
|
||||||
sudo pip3 install --upgrade setuptools
|
|
||||||
```
|
|
||||||
* If this fails, try this and repeat step 1
|
|
||||||
```
|
|
||||||
sudo apt-get install python3-pip
|
|
||||||
```
|
|
||||||
* Recommended, but may not be required, setting your Python install to default with Python 3. There are multiple ways to do this, here's an example:
|
|
||||||
```
|
|
||||||
sudo apt-get install -y python3 git python3-pip
|
|
||||||
sudo update-alternatives --install /usr/bin/python python $(which python2) 1
|
|
||||||
sudo update-alternatives --install /usr/bin/python python $(which python3) 2
|
|
||||||
sudo update-alternatives --config python
|
|
||||||
```
|
|
||||||
2. Enabling I2C and SPI, which is only required to be done **once** for **each** Raspberry Pi:\
|
|
||||||
**Only Required if you are using multiple devices on your Raspberry Pi, if not, move to step 3**\
|
|
||||||
**Important:**
|
|
||||||
> If you are using a GPIO wiring setup for the LEDs that does not support I2C, you will not see anything show up for the LEDS.\
|
|
||||||
> Again, this is only for if you have **OTHER** devices you plan on hooking up to make sure they still show up under I2C
|
|
||||||
* Enabling I2C:
|
|
||||||
* From Command Line:
|
|
||||||
```
|
|
||||||
sudo apt-get install -y python-smbus
|
|
||||||
sudo apt-get install -y i2c-tools
|
|
||||||
sudo raspi-config
|
|
||||||
```
|
|
||||||
* Interfacing Options > I2C > Enable > Yes
|
|
||||||
> If you did not hit "finish" you can repeat these steps but change out the I2C for the SPI
|
|
||||||
* Enabling SPI:
|
|
||||||
* From Command Line:
|
|
||||||
```
|
|
||||||
sudo raspi-config
|
|
||||||
```
|
|
||||||
* Interfacing Options > SPI > Enable > Yes
|
|
||||||
* Click "Finish"
|
|
||||||
* Reboot your Raspberry Pi
|
|
||||||
```
|
|
||||||
sudo reboot
|
|
||||||
```
|
|
||||||
* Testing I2C and SPI after reboot:
|
|
||||||
* I2C Testing:
|
|
||||||
```
|
|
||||||
sudo i2cdetect -y 1
|
|
||||||
```
|
|
||||||
* If you do not get anything back from the above command, try seeing which I2C is being used under Dev:
|
|
||||||
```
|
|
||||||
ls /dev/i2c*
|
|
||||||
```
|
|
||||||
> Whichever number is after the "-" in "/dev/i2c-(X) is what you should replace the number in the command with
|
|
||||||
>> Example: /dev/i2c-3 = "sudo i2cdetect -y 3"
|
|
||||||
* SPI Testing:
|
|
||||||
```
|
|
||||||
ls -l /dev/spidev*
|
|
||||||
```
|
|
||||||
> This should return a device for each SPI bus (two)
|
|
||||||
3. Installing Python Support Libraries:
|
|
||||||
* GPIO - If not already installed:
|
|
||||||
```
|
|
||||||
sudo pip3 install RPI.GPIO
|
|
||||||
```
|
|
||||||
* Adafruit Blinka:
|
|
||||||
```
|
|
||||||
sudo pip3 install adafruit-blinka
|
|
||||||
```
|
|
||||||
* RPi WS281X and Neopixel:
|
|
||||||
```
|
|
||||||
sudo pip3 install rpi_ws281x adafruit-circuitpython-neopixel
|
|
||||||
sudo python3 -m pip install --force-reinstall adafruit-blinka
|
|
||||||
```
|
|
||||||
* PixelFramebuffer:
|
|
||||||
```
|
|
||||||
sudo pip3 install adafruit-circuitpython-pixel-framebuf
|
|
||||||
```
|
|
||||||
4. Changing Conflicting HDMI Settings:\
|
|
||||||
**Important:** Only do this if you are having issues with the LEDs, this is not always needed!\
|
|
||||||
```
|
|
||||||
sudo nano /boot/config.txt
|
|
||||||
```
|
|
||||||
* If it doesn't already exist, add:
|
|
||||||
```
|
|
||||||
hdmi_force_hotplug=1
|
|
||||||
hdmi_force_edid_audio=1
|
|
||||||
```
|
|
||||||
* Save and exit the file (ctrl + x > y)
|
|
||||||
* Reboot Raspberry Pi
|
|
||||||
```
|
|
||||||
sudo reboot
|
|
||||||
```
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
TBD
|
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
|
||||||
|
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8
|
||||||
|
16 | 17 | 18 | 19 | 20 | 21 | 22 | 23
|
||||||
|
31 | 30 | 29 | 28 | 27 | 26 | 25 | 24
|
||||||
|
32 | 33 | 34 | 35 | 36 | 37 | 38 | 39
|
||||||
|
47 | 46 | 45 | 44 | 43 | 42 | 41 | 40
|
||||||
|
48 | 49 | 50 | 51 | 52 | 53 | 54 | 55
|
||||||
|
63 | 62 | 61 | 60 | 59 | 58 | 57 | 56
|
||||||
|
|
||||||
## Contributing
|
3 - Read from a file > take the contents > convert to string > turn string into ASCII imagery > turn ASCII imagery into pixel grid matrix > convert matrix into zigzag matrix to send to Neopixel and throw it to the LED matrix. (piltest.py) already has this PoC up to the Matrix to zigzag.
|
||||||
TBD
|
|
||||||
|
|
||||||
## License
|
|
||||||
* [MIT](https://choosealicense.com/licenses/mit/)
|
|
||||||
> A copy of this can be found in the root directory of this project under "LICENSE"
|
|
||||||
|
|
||||||
|
4 - Figure out how to use Neopixel pass offs. (already solved and confirmed working)
|
@ -1,65 +0,0 @@
|
|||||||
#Created By: Justin Healy and Vin Presciutti || 2021
|
|
||||||
#Based off of work done by 2020 Melissa LeBlanc-Williams, written for Adafruit Industries, MIT
|
|
||||||
#!/usr/bin/python3
|
|
||||||
|
|
||||||
import board
|
|
||||||
import neopixel
|
|
||||||
from PIL import Image
|
|
||||||
from adafruit_pixel_framebuf import PixelFramebuffer
|
|
||||||
import time
|
|
||||||
import argparse
|
|
||||||
|
|
||||||
|
|
||||||
gpio_pin = board.D18
|
|
||||||
|
|
||||||
pixel_width = 8
|
|
||||||
scroll_width = pixel_width + 1
|
|
||||||
pixel_height = 16
|
|
||||||
scroll_height = pixel_height + 1
|
|
||||||
|
|
||||||
pixel_max = pixel_width * pixel_height - 1
|
|
||||||
|
|
||||||
led_message = "Jaki"
|
|
||||||
|
|
||||||
# Main program logic follows:
|
|
||||||
if __name__ == '__main__':
|
|
||||||
# Process arguments
|
|
||||||
parser = argparse.ArgumentParser()
|
|
||||||
parser.add_argument('-c', '--clear', action='store_true', help='clear the display on exit')
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
# Create NeoPixel object with appropriate configuration.
|
|
||||||
neo_pixel = neopixel.NeoPixel(gpio_pin, pixel_width * pixel_height, brightness=0.1, auto_write=False)
|
|
||||||
#Create PixelFramebuffer object with appropriate configuration.
|
|
||||||
pixel_framebuf = PixelFramebuffer(neo_pixel, pixel_width, pixel_height, reverse_x=True,alternating=True)
|
|
||||||
|
|
||||||
print ('Press Ctrl-C to quit.')
|
|
||||||
if not args.clear:
|
|
||||||
print('Use "-c" argument to clear LEDs on exit')
|
|
||||||
|
|
||||||
try:
|
|
||||||
|
|
||||||
while True:
|
|
||||||
led_message_len = len(led_message)
|
|
||||||
led_message_scroll_height = led_message_len * 16
|
|
||||||
for led_scroll in range(0, led_message_scroll_height , 1):
|
|
||||||
led_char_counter = 1
|
|
||||||
pixel_framebuf.fill(0x000000)
|
|
||||||
pixel_framebuf.display()
|
|
||||||
for led_char in led_message:
|
|
||||||
|
|
||||||
led_char_spacing = 8 * led_char_counter
|
|
||||||
led_char_pos = pixel_height - led_scroll + led_char_spacing
|
|
||||||
pixel_framebuf.text(led_char, 0, led_char_pos , 0x00FF00)
|
|
||||||
pixel_framebuf.display()
|
|
||||||
time.sleep
|
|
||||||
led_char_counter += 1
|
|
||||||
|
|
||||||
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
if args.clear:
|
|
||||||
neo_pixel.deinit()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Binary file not shown.
@ -0,0 +1,34 @@
|
|||||||
|
# SPDX-FileCopyrightText: 2020 Melissa LeBlanc-Williams, written for Adafruit Industries
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
#!/usr/bin/python3
|
||||||
|
"""
|
||||||
|
Be sure to check the learn guides for more usage information.
|
||||||
|
|
||||||
|
This example is for use on (Linux) computers that are using CPython with
|
||||||
|
Adafruit Blinka to support CircuitPython libraries. CircuitPython does
|
||||||
|
not support PIL/pillow (python imaging library)!
|
||||||
|
|
||||||
|
Author(s): Melissa LeBlanc-Williams for Adafruit Industries
|
||||||
|
"""
|
||||||
|
import board
|
||||||
|
import neopixel
|
||||||
|
from PIL import Image
|
||||||
|
from adafruit_pixel_framebuf import PixelFramebuffer
|
||||||
|
|
||||||
|
pixel_pin = board.D18
|
||||||
|
pixel_width = 8
|
||||||
|
pixel_height = 16
|
||||||
|
|
||||||
|
pixels = neopixel.NeoPixel(
|
||||||
|
pixel_pin, pixel_width * pixel_height, brightness=0.1, auto_write=False,
|
||||||
|
)
|
||||||
|
pixel_framebuf = PixelFramebuffer(pixels, pixel_width, pixel_height, reverse_x=True,alternating=True)
|
||||||
|
pixel_framebuf.fill(0x000000)
|
||||||
|
pixel_framebuf.display()
|
||||||
|
pixel_framebuf.text("H", 0, 0, 0x00FF00)
|
||||||
|
pixel_framebuf.display()
|
||||||
|
pixel_framebuf.text("i", 0, 8, 0x00FF00)
|
||||||
|
pixel_framebuf.display()
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1 @@
|
|||||||
|
Jaki is the best.
|
@ -0,0 +1,52 @@
|
|||||||
|
#Created by Justin Healy
|
||||||
|
#Based on logic from jsheperd from https://stackoverflow.com/a/27753869/190597
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
import string
|
||||||
|
from PIL import Image
|
||||||
|
from PIL import ImageFont
|
||||||
|
from PIL import ImageDraw
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
def char_to_pixels(text, path, fontsize):
|
||||||
|
|
||||||
|
font = ImageFont.truetype(path, fontsize)
|
||||||
|
w, h = font.getsize(text)
|
||||||
|
image = Image.new('L', (w, h), 1)
|
||||||
|
draw = ImageDraw.Draw(image)
|
||||||
|
draw.text((0, 0), text, font=font)
|
||||||
|
arr = np.asarray(image)
|
||||||
|
arr = np.where(arr, 0, 1)
|
||||||
|
arr = arr[(arr != 0).any(axis=1)]
|
||||||
|
return arr
|
||||||
|
|
||||||
|
def display(arr):
|
||||||
|
result = np.where(arr, '1', '0')
|
||||||
|
print("This gives an Array of Arrays, where reach contained Array is a row")
|
||||||
|
print(result)
|
||||||
|
print()
|
||||||
|
print('\n'.join([''.join(row) for row in result]))
|
||||||
|
|
||||||
|
#I have used static coding successfully, now to set this as more reusable declarations rather than hard coding.
|
||||||
|
#Single Source to change for everything
|
||||||
|
#Read from file?
|
||||||
|
fileName = "pilReadTest"
|
||||||
|
pullFile = open(fileName,"r")
|
||||||
|
someString = pullFile.read()
|
||||||
|
#Font Path?
|
||||||
|
fontPath = "fonts/FreeMonoBold.ttf"
|
||||||
|
#font Size?
|
||||||
|
fontSize = 12
|
||||||
|
#print("This was what was found in the File: "+str(someString))
|
||||||
|
#print()
|
||||||
|
#print("Now putting each letter of the found string through the PIL Image Module")
|
||||||
|
#print()
|
||||||
|
for c in someString:
|
||||||
|
arr = char_to_pixels(c,fontPath,fontSize)
|
||||||
|
print()
|
||||||
|
#This is the grid size results (w,h)
|
||||||
|
print(arr.shape)
|
||||||
|
print()
|
||||||
|
#print("This is the converted values of the AofAs, for each ROW in Result, the end product")
|
||||||
|
display(arr)
|
||||||
|
print()
|
Loading…
Reference in new issue