Compare commits
17 Commits
Author | SHA1 | Date |
---|---|---|
jhealy | acb4ea8f56 | 4 years ago |
jhealy | 9a7bb116bf | 4 years ago |
jhealy | 42a0bc722d | 4 years ago |
jhealy | eb728f3ddb | 4 years ago |
jhealy | 62b91f103e | 4 years ago |
jhealy | 6dc51746ea | 4 years ago |
jhealy | 91dc76caa4 | 4 years ago |
jhealy | 3915a5f317 | 4 years ago |
jhealy | aed3274bdf | 4 years ago |
jhealy | 36ffcb5d77 | 4 years ago |
jhealy | 4e78ca7d24 | 4 years ago |
jhealy | 7733a922b6 | 4 years ago |
jhealy | b96dde47ef | 4 years ago |
jhealy | a71079c86f | 4 years ago |
jhealy | b421b016b5 | 4 years ago |
jhealy | 3a83768c0c | 4 years ago |
jhealy | 0b2e28795a | 4 years ago |
@ -0,0 +1,21 @@
|
||||
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,41 +1,127 @@
|
||||
# RPi_WS2812b_LED
|
||||
|
||||
#Raspberry Pi Project
|
||||
#WS2812b - LED
|
||||
#Python3
|
||||
|
||||
Objective:
|
||||
# tickerPi
|
||||
|
||||
Be able to pass through data (text, designs, colors, patterns, etc) through GPIO on a Raspberry Pi, through to WS2812b LEDs.
|
||||
tickerPi is a Python Program to handle WS281X LED interactions on a Raspberry Pi
|
||||
* WS2812b has only been tested at this time
|
||||
|
||||
## Authors
|
||||
|
||||
Initial Challenges:
|
||||
* **Justin Healy**
|
||||
* **Vin Presciutti**
|
||||
|
||||
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)
|
||||
## 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:
|
||||
```
|
||||
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
|
||||
|
||||
vs
|
||||
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
|
||||
TBD
|
||||
|
||||
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.
|
||||
## 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)
|
@ -0,0 +1,65 @@
|
||||
#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.
@ -1,34 +0,0 @@
|
||||
# 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()
|
||||
|
||||
|
||||
|
@ -1 +0,0 @@
|
||||
Jaki is the best.
|
@ -1,52 +0,0 @@
|
||||
#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