Adding code for Pi Video Synth
Adding Blinka code, Processing code and two .png files for the Raspberry Pi Video Synth Learn Guide
This commit is contained in:
parent
94464e609a
commit
382a10081f
4 changed files with 402 additions and 0 deletions
141
Raspberry_Pi_Video_Synth/BlinkaRaspberryPiVideoSynth.py
Normal file
141
Raspberry_Pi_Video_Synth/BlinkaRaspberryPiVideoSynth.py
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
# SPDX-FileCopyrightText: 2022 Liz Clark for Adafruit Industries
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
import socket
|
||||
import time
|
||||
import board
|
||||
import simpleio
|
||||
import adafruit_vl53l4cd
|
||||
from adafruit_seesaw import seesaw, rotaryio, neopixel
|
||||
from adafruit_seesaw.analoginput import AnalogInput
|
||||
|
||||
# VL53L4CD setup
|
||||
vl53 = adafruit_vl53l4cd.VL53L4CD(board.I2C())
|
||||
|
||||
# rotary encoder setup
|
||||
encoder = seesaw.Seesaw(board.I2C(), addr=0x36)
|
||||
encoder.pin_mode(24, encoder.INPUT_PULLUP)
|
||||
rot_encoder = rotaryio.IncrementalEncoder(encoder)
|
||||
|
||||
# neoslider setup - analog slide pot and neopixel
|
||||
# 0x30 = red control
|
||||
# 0x31 = green control
|
||||
# 0x32 = blue control
|
||||
red_slider = seesaw.Seesaw(board.I2C(), 0x30)
|
||||
red_pot = AnalogInput(red_slider, 18)
|
||||
r_pix = neopixel.NeoPixel(red_slider, 14, 4)
|
||||
|
||||
g_slider = seesaw.Seesaw(board.I2C(), 0x31)
|
||||
green_pot = AnalogInput(g_slider, 18)
|
||||
g_pix = neopixel.NeoPixel(g_slider, 14, 4)
|
||||
|
||||
b_slider = seesaw.Seesaw(board.I2C(), 0x32)
|
||||
blue_pot = AnalogInput(b_slider, 18)
|
||||
b_pix = neopixel.NeoPixel(b_slider, 14, 4)
|
||||
|
||||
# rotary encoder position tracker
|
||||
last_position = 0
|
||||
|
||||
# neoslider position trackers
|
||||
last_r = 0
|
||||
last_g = 0
|
||||
last_b = 0
|
||||
|
||||
# VL53L4CD value tracker
|
||||
last_flight = 0
|
||||
|
||||
# rotary encoder index
|
||||
x = 0
|
||||
|
||||
# VL53L4CD start-up
|
||||
vl53.inter_measurement = 0
|
||||
vl53.timing_budget = 200
|
||||
|
||||
vl53.start_ranging()
|
||||
|
||||
# HTTP socket setup
|
||||
s = socket.socket()
|
||||
print("socket check")
|
||||
|
||||
port = 12345
|
||||
|
||||
s.bind(('', port))
|
||||
print("socket binded to %s" %(port))
|
||||
|
||||
s.listen(1)
|
||||
print("listening")
|
||||
|
||||
time.sleep(10)
|
||||
|
||||
c, addr = s.accept()
|
||||
print('got connected', addr)
|
||||
|
||||
while True:
|
||||
# rotary encoder position read
|
||||
position = -rot_encoder.position
|
||||
|
||||
# VL53L4CD distance read
|
||||
flight = vl53.distance
|
||||
|
||||
# mapping neosliders to use 0-255 range for RGB values in Processing
|
||||
r_mapped = simpleio.map_range(red_pot.value, 0, 1023, 0, 255)
|
||||
g_mapped = simpleio.map_range(green_pot.value, 0, 1023, 0, 255)
|
||||
b_mapped = simpleio.map_range(blue_pot.value, 0, 1023, 0, 255)
|
||||
|
||||
# converting neoslider data to integers
|
||||
r_pot = int(r_mapped)
|
||||
g_pot = int(g_mapped)
|
||||
b_pot = int(b_mapped)
|
||||
|
||||
# rotary encoder position check
|
||||
if position != last_position:
|
||||
# rotary encoder is ranged to 0-3
|
||||
if position > last_position:
|
||||
x = (x + 1) % 4
|
||||
if position < last_position:
|
||||
x = (x - 1) % 4
|
||||
# send rotary encoder value over socket
|
||||
# identifying string is "enc"
|
||||
c.send(str.encode(' '.join(["enc", str(x)])))
|
||||
# reset last_position
|
||||
last_position = position
|
||||
# sliders only update data for changes >15 to avoid flooding socket
|
||||
# red neoslider position check
|
||||
if abs(r_pot - last_r) > 15:
|
||||
# send red neoslider data over socket
|
||||
# identifying string is "red"
|
||||
c.send(str.encode(' '.join(["red", str(r_pot)])))
|
||||
# reset last_r
|
||||
last_r = r_pot
|
||||
# green neoslider position check
|
||||
if abs(g_pot - last_g) > 15:
|
||||
# send green neoslider data over socket
|
||||
# identifying string is "green"
|
||||
c.send(str.encode(' '.join(["green", str(g_pot)])))
|
||||
# reset last_g
|
||||
last_g = g_pot
|
||||
# blue neoslider position check
|
||||
if abs(b_pot - last_b) > 15:
|
||||
# send blue neoslider data over socket
|
||||
# identifying string is "blue"
|
||||
c.send(str.encode(' '.join(["blue", str(b_pot)])))
|
||||
# reset last_b
|
||||
last_b = b_pot
|
||||
# VL53L4CD value check
|
||||
if abs(flight - last_flight) > 2:
|
||||
# setting max value of 45
|
||||
if flight > 45:
|
||||
flight = 45
|
||||
# send VL53L4CD data over socket
|
||||
# identifying string is "flight"
|
||||
c.send(str.encode(' '.join(["flight", str(flight)])))
|
||||
# reset last_flight
|
||||
last_flight = flight
|
||||
# set neopixels on neosliders to match background color of Processing animations
|
||||
r_pix.fill((r_pot, g_pot, b_pot))
|
||||
g_pix.fill((r_pot, g_pot, b_pot))
|
||||
b_pix.fill((r_pot, g_pot, b_pot))
|
||||
# reset the VL53L4CD
|
||||
vl53.clear_interrupt()
|
||||
|
||||
261
Raspberry_Pi_Video_Synth/ProcessingRaspberryPiVideoSynth.pde
Normal file
261
Raspberry_Pi_Video_Synth/ProcessingRaspberryPiVideoSynth.pde
Normal file
|
|
@ -0,0 +1,261 @@
|
|||
// SPDX-FileCopyrightText: 2022 Liz Clark for Adafruit Industries
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
// Processing library for Networking
|
||||
// make sure that you have the library installed!
|
||||
import processing.net.*;
|
||||
|
||||
// HTTP client
|
||||
Client myClient;
|
||||
|
||||
// variables for receiving data from Blinka socket
|
||||
int index;
|
||||
String inString;
|
||||
|
||||
// holding the red, green, blue data
|
||||
String[] r;
|
||||
String[] g;
|
||||
String[] b;
|
||||
int red;
|
||||
int green;
|
||||
int blue;
|
||||
|
||||
// holding the VL53L4CD data
|
||||
String[] f;
|
||||
int flight;
|
||||
|
||||
// cat and pizza images
|
||||
//emojis are from the OpenMoji emoji library (https://openmoji.org/)
|
||||
PImage cat_img;
|
||||
PImage pizza_img;
|
||||
|
||||
// colors for Circles animation
|
||||
color c_red = color(255, 0, 0);
|
||||
color c_green = color(0, 255, 0);
|
||||
color c_blue = color(0, 0, 255);
|
||||
color c_yellow = color(255, 125, 0);
|
||||
color c_aqua = color(0, 125, 255);
|
||||
color c_purple = color(255, 0, 255);
|
||||
|
||||
IntList colors;
|
||||
|
||||
// float for Cube animation
|
||||
float i = 0.0;
|
||||
|
||||
// variables for Circles animation
|
||||
int rad = 60;
|
||||
float xpos, ypos;
|
||||
|
||||
float xspeed = 2.8;
|
||||
float yspeed = 10;
|
||||
|
||||
int xdirection = 1;
|
||||
int ydirection = 1;
|
||||
|
||||
// variables for pizzaCat animation
|
||||
float pizza_speed = 20;
|
||||
float cat_speed = 30;
|
||||
|
||||
float pizza_pos, cat_pos;
|
||||
|
||||
int img_w = 10;
|
||||
|
||||
int pizza_dir = 1;
|
||||
int cat_dir = 1;
|
||||
int num_cats;
|
||||
|
||||
// variables for dancingTriangles animation
|
||||
int x1;
|
||||
int y1;
|
||||
int x2;
|
||||
int y2;
|
||||
int x3;
|
||||
int y3;
|
||||
|
||||
void setup()
|
||||
{
|
||||
// setting animations to run fullscreen with P3D
|
||||
fullScreen(P3D);
|
||||
// RGB color mode with value range of 0-255
|
||||
colorMode(RGB, 255);
|
||||
ellipseMode(RADIUS);
|
||||
// setting xpos and ypos in center
|
||||
xpos = width/2;
|
||||
ypos = height/2;
|
||||
|
||||
// creating array of colors
|
||||
// this is used for the Circles animation
|
||||
colors = new IntList();
|
||||
colors.append(c_red);
|
||||
colors.append(c_yellow);
|
||||
colors.append(c_green);
|
||||
colors.append(c_aqua);
|
||||
colors.append(c_blue);
|
||||
colors.append(c_purple);
|
||||
|
||||
// loading the cat and pizza images
|
||||
cat_img = loadImage("cat.png");
|
||||
pizza_img = loadImage("pizza.png");
|
||||
|
||||
// connecting to socket to communicate with Blinka script
|
||||
myClient = new Client(this, "127.0.0.1", 12345);
|
||||
|
||||
}
|
||||
|
||||
// void draw() is the loop in Processing
|
||||
void draw()
|
||||
{
|
||||
//if data is coming in over the socket...
|
||||
if (myClient.available() > 0) {
|
||||
//string data is stored in inString
|
||||
inString = myClient.readString();
|
||||
//if the string begins with 'enc'
|
||||
//aka is a msg from the rotary encoder...
|
||||
if (inString.startsWith("enc")) {
|
||||
// the encoder pos is stored in index
|
||||
String[] q = splitTokens(inString);
|
||||
index = int(q[1]);
|
||||
}
|
||||
//if the string begins with 'red'
|
||||
//aka is from the red neoslider
|
||||
if (inString.startsWith("red")) {
|
||||
//the red value is stored in red
|
||||
String[] r = splitTokens(inString);
|
||||
red = int(r[1]);
|
||||
}
|
||||
//if the string begins with 'green'
|
||||
//aka is from the green neoslider
|
||||
if (inString.startsWith("green")) {
|
||||
// the green value is stored in green
|
||||
String[] g = splitTokens(inString);
|
||||
green = int(g[1]);
|
||||
}
|
||||
//if the string begins with 'blue'
|
||||
//aka is from the blue neoslider
|
||||
if (inString.startsWith("blue")) {
|
||||
//the blue value is stored in blue
|
||||
String[] b = splitTokens(inString);
|
||||
blue = int(b[1]);
|
||||
}
|
||||
//if the string begins with flight
|
||||
//aka is from the VL53L4CD
|
||||
if (inString.startsWith("flight")) {
|
||||
//the time of flight value is stored in flight
|
||||
String[] f = splitTokens(inString);
|
||||
flight = int(f[1]);
|
||||
}
|
||||
}
|
||||
//the encoder's position corresponds with which animation plays
|
||||
if (index == 0) {
|
||||
circles();
|
||||
}
|
||||
|
||||
if (index == 1) {
|
||||
cube();
|
||||
}
|
||||
if (index == 2) {
|
||||
dancingTriangles();
|
||||
}
|
||||
if (index == 3) {
|
||||
pizzaCat();
|
||||
}
|
||||
}
|
||||
|
||||
//the Circles animation
|
||||
//colorful circles randomly appear in the middle of the screen
|
||||
//background color is affected by the sliders
|
||||
//the circles' size is affected by the VL53L4CD
|
||||
void circles() {
|
||||
background(red, green, blue);
|
||||
strokeWeight(1);
|
||||
|
||||
ypos = ypos + ( yspeed * ydirection );
|
||||
|
||||
if (ypos > height-rad || ypos < rad) {
|
||||
ydirection *= +1;
|
||||
}
|
||||
|
||||
int size = int(map(flight, 0, 45, 300, 25));
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
for (int z = 0; z < 6; z++) {
|
||||
fill(colors.get(z));
|
||||
circle(width/2, random(ypos), random(size));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//the Cube animation
|
||||
//a 3D cube spins in the center of the screen
|
||||
//background color is affected by the sliders
|
||||
//the speed of the spinning cube is affected by the VL53L4CD
|
||||
void cube() {
|
||||
strokeWeight(5);
|
||||
|
||||
float speed = map(flight, 0, 45, 10, 0.1);
|
||||
|
||||
background(red, green, blue);
|
||||
translate(width/2, height/2, 0);
|
||||
|
||||
i = i + speed;
|
||||
if (i > 180) {
|
||||
i = 0.0;
|
||||
}
|
||||
rotateY(radians(i));
|
||||
noFill();
|
||||
box(500);
|
||||
}
|
||||
|
||||
//the Pizza Cat animation
|
||||
//pizza and cat face emojis go back and forth across the screen
|
||||
//emojis are from the OpenMoji emoji library (https://openmoji.org/)
|
||||
//the background color is affected by the sliders
|
||||
//the speed of the cat emojis are affected by the V53L4CD
|
||||
void pizzaCat() {
|
||||
background(red, green, blue);
|
||||
int num_cats = int(map(flight, 0, 45, 65, 15));
|
||||
|
||||
pizza_pos = pizza_pos + ( pizza_speed * pizza_dir );
|
||||
cat_pos = cat_pos + ( num_cats * cat_dir );
|
||||
|
||||
if (pizza_pos + img_w > width || pizza_pos < img_w) {
|
||||
pizza_dir *= -1;
|
||||
}
|
||||
if (cat_pos + img_w > height || cat_pos < img_w) {
|
||||
cat_dir *= -1;
|
||||
}
|
||||
|
||||
for (int p = 0; p < 25; p++) {
|
||||
image(cat_img, pizza_pos-10, cat_pos*p);
|
||||
image(pizza_img, pizza_pos*p, cat_pos+10);
|
||||
}
|
||||
}
|
||||
|
||||
// the dancingTriangles animation
|
||||
// triangles are randomly generated in the center of the screen
|
||||
//the background is affected by the sliders
|
||||
// the speed of new triangles being added are affected by the V53L4CD
|
||||
void dancingTriangles() {
|
||||
int speed = int(map(flight, 0, 45, 25, 100));
|
||||
|
||||
background(red, green, blue);
|
||||
strokeWeight(30);
|
||||
|
||||
for (int w = 800; w < 1000; w ++) {
|
||||
for (int h = 1100; h < 1500; h++) {
|
||||
|
||||
x1 = int(random(h));
|
||||
y1 = int(random(w));
|
||||
|
||||
x2 = int(random(h));
|
||||
y2 = int(random(w));
|
||||
|
||||
x3 = int(random(h));
|
||||
y3 = int(random(w));
|
||||
}
|
||||
}
|
||||
noFill();
|
||||
triangle(x1, y1, x2, y2, x3, y3);
|
||||
delay(speed);
|
||||
}
|
||||
BIN
Raspberry_Pi_Video_Synth/cat.png
Normal file
BIN
Raspberry_Pi_Video_Synth/cat.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
BIN
Raspberry_Pi_Video_Synth/pizza.png
Normal file
BIN
Raspberry_Pi_Video_Synth/pizza.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
Loading…
Reference in a new issue