Compare commits

...

78 Commits

Author SHA1 Message Date
frank 43d7a280bc Merge commit '37cf5a350' 2024-03-05 19:45:27 +00:00
git stash 37cf5a3500 WIP on main: ee13cdb clarify single player ending message 2024-03-05 19:43:12 +00:00
git stash 004c9b6a8a index on main: ee13cdb clarify single player ending message 2024-03-05 19:43:12 +00:00
ohsqueezy da0458e0a9 add canonical url to web page, take down mailman API while mailman is broken on the server 2024-03-05 14:42:46 -05:00
ohsqueezy 616aa93bc3 fix for issue of disappearing level select previews after hard reset 2024-01-18 19:41:42 -08:00
ohsqueezy ee13cdbdc6 clarify single player ending message 2024-01-10 21:24:00 -08:00
ohsqueezy 41fa64c553 - ending screen for versus battles
- add date to saved scores
- add file for tracking dnf runs
2024-01-10 21:11:45 -08:00
ohsqueezy 0b59b4fc29 sync seed and wait time separately from launch trigger 2024-01-10 17:30:37 -08:00
ohsqueezy 3c68333638 cancel blinds animation when quick starting level 2024-01-10 16:26:10 -08:00
ohsqueezy c4c8a1e79b sync wipe animation and wait for all peers to be at voted status before starting level 2024-01-10 16:13:44 -08:00
ohsqueezy 5745783e68 debug messages for random seeding, skip directly to screen wipe on level select when more than one player is playing 2024-01-10 15:30:47 -08:00
ohsqueezy e7846d4826 use level select vote messages to determine if peers are playing versus and sync random seed for level 2024-01-10 15:16:10 -08:00
ohsqueezy a085eaff6d use most recent score object to transfer time in milliseconds 2024-01-10 10:03:04 -08:00
ohsqueezy 01df4f350e remove peer list from checked in config 2024-01-09 23:44:11 -05:00
ohsqueezy 2fe057a351 - preliminary support for listening for messages, posting messages, and displaying status of network
- make title screen scores optimization optional
- add option to clear pop up messages queue when adding a message
2024-01-09 19:22:54 -08:00
ohsqueezy 9b9277bedb add screen to setup diagram 2023-12-22 01:20:50 -05:00
ohsqueezy 78b05b0bf9 update info about wiki in the README 2023-12-22 01:06:45 -05:00
ohsqueezy 5a78b3c6c1 add screenshot of level 1 for operator's manual 2023-12-22 01:02:08 -05:00
ohsqueezy 1f9ce78e42 more operator's manual images 2023-12-22 00:51:30 -05:00
ohsqueezy e61237f1a7 reorganize news on web page 2023-12-22 00:18:55 -05:00
ohsqueezy 33beb9df6f news section for web site 2023-12-21 23:49:40 -05:00
ohsqueezy 66043aa393 try all detected devices when auto detecting Arduino; restore the end function's behavior which kills serial threads before quitting 2023-10-13 14:58:26 -04:00
ohsqueezy d1fe534c9f mark event date as past 2023-08-07 14:35:19 -04:00
Blake Lee Andrews ef8f7bc5a8 backgrounds 2023-08-04 20:01:58 -04:00
ohsqueezy a05f42c257 add more kaomojis to fill screen 2023-08-04 18:51:30 -04:00
ohsqueezy 78689e1bb8 add reminder to update version to event checklist 2023-08-04 18:38:48 -04:00
ohsqueezy e17b29b1c1 add dates to calendar 2023-08-04 18:35:18 -04:00
Blake Lee Andrews 97880534ae new board assets
changed some tuning also
2023-07-26 19:15:04 -04:00
Blake Lee Andrews 28dcee741c Merge branch 'main' of https://open.shampoo.ooo/scrape/scrapeboard 2023-06-16 22:29:11 -04:00
Blake Lee Andrews c0095d7ced SCORES 2023-06-16 22:29:07 -04:00
ohsqueezy d828346fae fix qr boolean config, add builder's manual print-out to equipment list 2023-06-15 17:05:49 -04:00
ohsqueezy ef5ec4d313 Merge commit 'ce14753' 2023-06-14 17:28:19 -04:00
ohsqueezy ce14753668 add QR code to tony's shirt, add links for shop, wiki, and kofi to web page 2023-06-14 17:25:59 -04:00
ohsqueezy 129907c30a fix links and adjust wording 2023-05-17 16:06:42 -04:00
ohsqueezy 39de5967d1 replaced builder's manual file with links to the wiki in the README 2023-05-17 16:02:41 -04:00
ohsqueezy fdff973446 Merge branch 'main' of https://open.shampoo.ooo/scrape/scrapeboard 2023-05-16 17:50:25 -04:00
ohsqueezy 9249d6f83a more doc images for wiki 2023-05-16 17:50:05 -04:00
ohsqueezy a1ef890238 add PIL install step to windows docs 2023-04-28 15:17:46 -04:00
ohsqueezy bd585b92f4 fix link 2023-04-25 19:17:54 -04:00
ohsqueezy ea256e7ea1 fix link 2023-04-25 19:15:34 -04:00
ohsqueezy 3f674150b6 fix link 2023-04-25 19:11:53 -04:00
ohsqueezy 5fe4140523 fix relative links 2023-04-25 19:09:08 -04:00
ohsqueezy 58637344f0 fix anchor links 2023-04-25 19:04:28 -04:00
ohsqueezy 3c2a818028 fix anchor link 2023-04-25 18:59:36 -04:00
ohsqueezy 921689f655 fix link to board and platform photo 2023-04-25 18:36:44 -04:00
ohsqueezy 71186bf1cf fix link to electronics section 2023-04-25 18:33:59 -04:00
ohsqueezy c532f09388 remove table display from table of contents header 2023-04-25 18:32:46 -04:00
ohsqueezy a582bdd096 fix table of contents shortcode 2023-04-25 18:31:31 -04:00
ohsqueezy f9e1e967a0 fix readme links to manual 2023-04-25 18:30:03 -04:00
ohsqueezy 1618dacc4d update builder's manual 2023-04-25 18:28:02 -04:00
ohsqueezy b30391bdcc restore time lapse webp 2023-02-03 13:43:57 -05:00
ohsqueezy a0f7c9d3fc replace webp with webm and html tag 2023-02-03 13:37:16 -05:00
ohsqueezy 94dd058a70 rearrange history images in builder's manual 2023-02-02 19:30:33 -05:00
ohsqueezy 8a745a9617 change gif markdown to html 2023-02-02 19:27:30 -05:00
ohsqueezy 2bd04296cb added media to builder's manual 2023-02-02 18:50:11 -05:00
ohsqueezy 4b73638d48 fix image path 2023-01-30 14:01:05 -05:00
ohsqueezy aa2f599215 remove width attribute on image 2023-01-30 14:00:06 -05:00
ohsqueezy a5546a56e5 add image to builder's manual history with width attribute 2023-01-30 13:59:13 -05:00
ohsqueezy 3080f650d4 fix link to electronics section 2023-01-27 17:23:49 -05:00
ohsqueezy 941c320290 change rpi pins 2023-01-27 17:22:06 -05:00
ohsqueezy 6231711a3d added terminology to builder's manual 2023-01-27 16:51:03 -05:00
ohsqueezy 1ee97de9e1 combine kicad projects into single board, update builder manual supplies 2023-01-27 16:45:37 -05:00
ohsqueezy de8a227acf update credits 2023-01-25 21:08:53 -05:00
ohsqueezy a4f2feef0f add kicad pcb project files and readme 2023-01-25 20:07:33 -05:00
ohsqueezy 42bc7440c4 restore background scrolling 2023-01-25 16:52:12 -05:00
ohsqueezy 5faee7703c update PGFW repo url 2023-01-25 16:44:23 -05:00
ohsqueezy 34b9c30e0a clean up unused code and resources 2023-01-25 16:42:37 -05:00
ohsqueezy dcef09e613 change Arduino pins to 2, 3, 4, 5, remove old serial code, update builder's manual 2023-01-25 16:09:07 -05:00
ohsqueezy 4a076a72d0 update builder's manual supplies and instructions, add introduction 2023-01-20 19:40:10 -05:00
ohsqueezy d0cb0706a7 yellow pad 2023-01-02 16:21:57 -08:00
ohsqueezy 8cfa142d39 fix manual links again 2022-12-18 20:48:17 -05:00
ohsqueezy f35c3a1486 fix manual links 2022-12-18 20:47:27 -05:00
ohsqueezy 66d9eabfe5 Merge branch 'main' of https://git.nugget.fun/scrape/scrapeboard 2022-12-18 20:44:36 -05:00
ohsqueezy 263c131cdb remove boss clip 2022-12-18 20:42:59 -05:00
ohsqueezy 6b94fed42f add raspberry pi to readme 2022-12-18 20:41:08 -05:00
ohsqueezy 455630509b auto detect gpio library 2022-12-18 20:34:22 -05:00
ohsqueezy 21a856089d builder's manual 2022-12-18 20:09:06 -05:00
ohsqueezy 14772a45e6 test clipping on level screen 2022-12-03 14:42:50 -05:00
127 changed files with 270357 additions and 807 deletions

9
.gitignore vendored
View File

@ -16,3 +16,12 @@ pyvenv.cfg
lib/python*
stat/
www/scrapeboard_new.gif
*.backup
kicad/*/*-backups
scrapeboard_hat*.zip
_autosave-*
www/Scrapeboard_Cyber_Monday_auction.webp
www/Scrapeboard_Cyber_Monday_auction_long.webp
www/Scrapeboard_auction_flyer_with_stream.png
resource/scores.txt
resource/dnf.txt

2
.gitmodules vendored
View File

@ -1,3 +1,3 @@
[submodule "lib/pgfw"]
path = lib/pgfw
url = https://git.nugget.fun/nugget/pgfw
url = https://open.shampoo.ooo/shampoo/pgfw

View File

@ -3,7 +3,7 @@ Code
Original source code is released under the zlib license:
Copyright (c) 2021-22 Frank DeMarco, Blake Andrews, and Dr. Clement Shimizu <scrape@nugget.fun>
Copyright (c) Frank DeMarco, Blake Andrews, and Dr. Clement Shimizu <scrape@nugget.fun>
This software is provided 'as-is', without any express or implied warranty. In
no event will the authors be held liable for any damages arising from the use of
@ -23,8 +23,8 @@ the following restrictions:
3. This notice may not be removed or altered from any source distribution.
Assets
------
Assets and documents
--------------------
Art, sound, document, and schematic assets are released under CC BY 4.0 To view a copy of this
license, visit <http://creativecommons.org/licenses/by/4.0/>
Art, sound, documentation, manuals, and schematics are released under CC BY 4.0. To view a copy of this
license, visit <http://creativecommons.org/licenses/by/4.0/>.

569
NS.py
View File

@ -6,12 +6,18 @@
# the hardware. For more information on setting up and running the game, see
# README.md, or for the game in general, visit <https://scrape.nugget.fun/>.
#
# Full open source code is available at <https://git.nugget.fun/scrape/scrapeboard>.
# The code, assets, and hardware are released as open source. See <https://open.shampoo.ooo/scrape/scrapeboard>.
#
# This is the main file containing all the pygame code.
# This is the main file containing all the Pygame code.
import argparse, pathlib, operator, subprocess, sys, os, socket, select, time, random, datetime
# Auto-detect GPIO library
try:
import gpio
except ImportError:
pass
import argparse, pathlib, operator, subprocess, sys, os
from random import randint, choice, random
from math import pi
from copy import copy
from glob import iglob
@ -21,7 +27,7 @@ from time import sleep
from PIL import Image
import pygame
from pygame import Surface, Color, mixer
from pygame import Surface, mixer
from pygame.event import clear
from pygame.mixer import Sound
from pygame.image import load, fromstring
@ -70,16 +76,23 @@ class NS(Game, Animation):
class Score:
def __init__(self, milliseconds=None, level_index=None):
def __init__(self, milliseconds=None, level_index=None, date=None):
self.milliseconds = milliseconds
self.level_index = level_index
if date is None:
date = datetime.datetime.now()
self.date = date
@classmethod
def from_string(cls, line: str):
milliseconds, level_index = (int(field) for field in line.strip().split())
fields = line.strip().split()
milliseconds, level_index = (int(field) for field in fields[:2])
date = None
if len(fields) > 2:
date = datetime.datetime.fromisoformat(fields[2])
if level_index == -1:
level_index = None
return cls(milliseconds, level_index)
return cls(milliseconds, level_index, date)
@classmethod
def level(cls, milliseconds: int, level_index: int):
@ -116,7 +129,7 @@ class NS(Game, Animation):
serialized_level_index = -1
else:
serialized_level_index = self.level_index
return f"{self.milliseconds} {serialized_level_index}"
return f"{self.milliseconds} {serialized_level_index} {datetime.datetime.isoformat(self.date, 'T')}"
def __str__(self):
return self.formatted()
@ -138,6 +151,21 @@ class NS(Game, Animation):
else:
return self.level_index < other.level_index
class Peer:
"""
Scrapeboard game on the local area network. It is expected to be sending and receiving messages using socket
communication. It will be read and written to regularly in a separate thread.
"""
status = None
result = None
versus = False
level = None
seed = None
def __init__(self, address, port):
self.address = address
self.port = port
def __init__(self):
"""
Parse the command line, set config types, initialize the serial reader, subscribe to events, and initialize child objects.
@ -187,6 +215,18 @@ class NS(Game, Animation):
"cooldown-level-3", "first-combo-delay"
]
},
"network":
{
"int": ["port", "diagnostics-size", "join-time-limit"],
"bool": "diagnostics",
"path": "diagnostics-font",
"list": "peers"
},
"pop-up":
{
"int": ["size", "length"],
"bool": "center"
},
"input":
{
"bool": ["serial", "pi"]
@ -194,13 +234,15 @@ class NS(Game, Animation):
"display":
{
"float": "attract-gif-alpha",
"bool": ["effects", "alpha-effect-title"],
"path": "scores-font"
"bool": ["effects", "alpha-effect-title", "qr-static"],
"path": "scores-font",
"int": "scores-alpha"
},
"system":
{
"bool": ["minimize-load-time", "enable-level-select"],
"int": ["lives-boss-rush-mode", "lives-level-select-mode"]
"bool": ["minimize-load-time", "enable-level-select", "optimize-title-screen"],
"int": ["lives-boss-rush-mode", "lives-level-select-mode", "max-seed"],
"path": ["dnf-file", "scores-file"]
},
"pads":
{
@ -239,16 +281,14 @@ class NS(Game, Animation):
# init Pi
if self.pi_enabled():
import gpio
# Initialize GPIO interface
gpio.initialize_gpio()
# Launch a separate thread for reading the GPIO (and allowing its custom delays/sleeps). Use the daemon flag to force
# exit when the main thread is killed (by a sigterm from systemctl stop) (?).
self.gpio_kill = False
# exit automatically when the main thread is killed.
self.gpio_thread = Thread(target=self.read_gpio, daemon=True)
self.gpio_thread.start()
self.gpio_data = gpio.activity()
# init Arduino
elif self.serial_enabled():
@ -259,26 +299,38 @@ class NS(Game, Animation):
# If a list of serial ports was requested, print detected ports and exit.
if arguments.list_serial_ports:
for port in list_ports.comports():
print(f"Detected serial port: {port.device}")
if list_ports.comports():
for port in list_ports.comports():
print(f"Detected serial port: {port.device}")
else:
print("No serial ports detected")
exit()
# Open the port specified by the configuration or command line if it is found. If the specified port is not
# found, open the first found serial port. If no serial ports are found, raise an exception.
# found, iterate through the com ports, and try to open each. If no serial port can be opened, raise an
# exception.
requested_port = self.get_configuration("input", "arduino-port")
devices = [port.device for port in list_ports.comports()]
if requested_port in devices:
self.serial_reader = Serial(requested_port, timeout=.3)
elif devices:
self.serial_reader = Serial(devices[0], timeout=.3)
else:
raise SerialException("No serial port devices were detected. Use --no-serial for keyboard-only mode.")
self.serial_kill = False
if requested_port:
print(f"Could not connect with requested port {requested_port}. Searching for other ports.")
found = False
for device in devices:
try:
self.serial_reader = Serial(device, timeout=.3)
found = True
except SerialException:
print(f"Tried and failed to open connection with serial device {device}")
if not found:
raise SerialException("No usable serial port devices found. Use --no-serial for keyboard-only mode.")
print(f"Using serial device at port {self.serial_reader.port}")
self.serial_data = 0
self.reset_arduino()
# Launch a separate thread for reading serial data
self.serial_thread = Thread(target=self.read_serial)
self.serial_thread = Thread(target=self.read_serial, daemon=True)
self.serial_thread.start()
Animation.__init__(self, self)
@ -313,19 +365,43 @@ class NS(Game, Animation):
self.most_recent_score = None
# Add existing scores to the list from file
with open(self.get_resource("scores"), "rt") as score_file:
for line in score_file:
if line.strip():
self.scores.append(NS.Score.from_string(line))
path = self.get_configuration("system", "scores-file")
if os.path.exists(path):
with open(path, "rt") as score_file:
for line in score_file:
if line.strip():
self.scores.append(NS.Score.from_string(line))
# Draw the score sprites
self.title.draw_scores()
# Initialize key input buffering
self.last_press = get_ticks()
# Initialize pop-up
self.register(self.close_pop_up)
self.reset()
self.pop_up_font = pygame.font.Font(self.get_resource(Dialogue.FONT_PATH), 12)
self.pop_up_font = pygame.font.Font(self.get_resource(Dialogue.FONT_PATH), self.get_configuration("pop-up", "size"))
self.pop_up_text = ""
# Initialize networking. Include self as a peer located at "localhost".
self.server = socket.create_server(("", self.get_configuration("network", "port")))
self.peers = {"localhost": NS.Peer("localhost", self.get_configuration("network", "port"))}
self.peers["localhost"].versus = True
print(f"Added peer 'localhost'")
if self.get_configuration("network", "peers"):
for peer in self.get_configuration("network", "peers"):
# Store peers in a dictionary where the key is the peer address
self.peers[peer] = NS.Peer(peer, self.get_configuration("network", "port"))
print(f"Added peer '{peer}'")
# Launch separate threads for listing and posting to peers
self.listen_thread = Thread(target=self.listen_to_peers, daemon=True)
self.listen_thread.start()
self.post_thread = Thread(target=self.post_to_peers, daemon=True)
self.post_thread.start()
self.reset()
# Clear events queue
clear()
def pi_enabled(self):
@ -338,11 +414,11 @@ class NS(Game, Animation):
"""
Test all connections of GPIO input pins.
"""
while not self.gpio_kill:
while True:
self.gpio_data = gpio.activity()
def read_serial(self):
while not self.serial_kill:
while True:
name = self.get_configuration("input", "arduino-port")
try:
transmission = self.serial_reader.readline().strip()
@ -377,12 +453,6 @@ class NS(Game, Animation):
self.serial_reader.dtr = False
self.serial_reader.reset_input_buffer()
self.serial_reader.dtr = True
def end(self, evt):
if evt.type == QUIT or self.delegate.compare(evt, "quit"):
self.serial_kill = True
self.gpio_kill = True
Game.end(self, evt)
def apply_serial(self):
for ii, light in enumerate(self.platform.lights):
@ -403,6 +473,107 @@ class NS(Game, Animation):
if self.gpio_data[light_id]:
self.idle_elapsed = 0
def post_to_peers(self):
"""
Update peers with current status every 1/2 second.
"""
while True:
# Determine this game's status
if self.title.active:
status = "title"
message = status
elif self.level_select.active and self.level_select.level_index_selected is None:
status = "level select"
message = status
elif self.level_select.active and not self.level_select.level_launched:
status = "voted"
level = self.level_select.level_index_selected
self.peers["localhost"].level = level
message = f"{status} {level} {self.peers['localhost'].seed}"
elif self.level_select.active or not self.boss.battle_finished:
status = "playing"
level = self.level_select.level_index_selected
self.peers["localhost"].level = level
message = f"{status} {level}"
elif self.boss.player_defeated:
status = "lost"
self.peers["localhost"].result = None
message = status
else:
status = "complete"
result = self.most_recent_score.milliseconds
self.peers["localhost"].result = result
message = f"{status} {result}"
self.peers["localhost"].status = status
# Connect and send status message to each peer. If sending fails, pass and wait until the next iteration.
for peer in self.peers.values():
if peer.address != "localhost":
try:
socket.create_connection((peer.address, peer.port)).send(str.encode(message))
except:
pass
# Send status every 1/2 second
time.sleep(0.5)
def listen_to_peers(self):
"""
Update peer statuses by processing incoming messages on the socket server.
"""
while True:
# Use the server to receive messages. Update peer statuses as the messages come in.
read_list, write_list, except_list = select.select([self.server], [], [], 0.5)
# When there is no read list, there are no messages to accept.
if (len(read_list) > 0):
incoming = self.server.accept()
peer = self.peers[incoming[1][0]]
# All messages are less than 64 characters
message = incoming[0].recv(64).decode()
if message.startswith("title") or message.startswith("level select"):
peer.versus = False
if message.startswith("complete"):
try:
peer.result = int(message.split()[-1])
peer.status = "complete"
except:
# Improperly formatted message received
pass
elif message.startswith("playing"):
try:
peer.level = int(message.split()[-1])
peer.status = "playing"
except:
pass
elif message.startswith("voted"):
try:
status, level, seed = message.split()
peer.level = int(level)
peer.seed = int(seed)
peer.status = status
except:
pass
else:
peer.status = message
def count_players(self):
"""
@return count of peers committed to a match with this peer
"""
count = 0
for peer in self.peers.values():
count += peer.versus
return count
def count_lobby(self):
"""
@return count of peers at the level select screen
"""
count = 0
for peer in self.peers.values():
count += peer.status == "level select" or peer.status == "voted"
return count
def reset(self, leave_wipe_running=False):
self.idle_elapsed = 0
self.suppressing_input = False
@ -455,20 +626,29 @@ class NS(Game, Animation):
self.reset()
elif event.key == K_a:
self.reset_arduino()
elif event.type == KEYDOWN and event.key == K_n and pygame.key.get_mods() & (pygame.KMOD_CTRL | pygame.KMOD_SHIFT):
# Toggle visibility of network diagnostics menu
state = self.get_configuration("network", "diagnostics")
self.configuration.set("network", "diagnostics", not state)
self.pop_up(f"Network diagnostics visible: {not state}")
self.last_press = get_ticks()
else:
if self.get_delegate().compare(event, "reset-game"):
self.reset()
def pop_up(self, text):
def pop_up(self, text, clear=False):
"""
Trigger a pop up message that displays for a certain amount of time before being closed automatically. Adds a line of
text to a variable that contains all pop up messages in case there is a previously sent message that needs to continue
being displayed.
@param text message to display
@param clear if True, delete any existing messages
"""
self.pop_up_text += f"{text}\n"
if not clear:
self.pop_up_text += f"{text}\n"
else:
self.pop_up_text = f"{text}\n"
self.halt(self.close_pop_up)
self.play(self.close_pop_up, play_once=True, delay=3000)
@ -493,10 +673,16 @@ class NS(Game, Animation):
score = NS.Score.level(milliseconds, level_index)
self.scores.append(score)
self.most_recent_score = score
with open(self.get_resource("scores"), "wt") as score_file:
for score in sorted(self.scores):
if not score.blank():
score_file.write(f"{score.serialize()}\n")
# Write scores to file
try:
with open(self.get_configuration("system", "scores-file"), "wt") as score_file:
for score in sorted(self.scores):
if not score.blank():
score_file.write(f"{score.serialize()}\n")
except:
print("Error saving scores")
self.title.draw_scores()
def update(self):
@ -511,7 +697,7 @@ class NS(Game, Animation):
elif self.serial_enabled():
# Translate the most recent serial data, being provided by serial/serial2/serial2.ino, into pad states
# Translate the most recent serial data, being provided by serial/serial.ino, into pad states
self.apply_serial()
# Handle auto reset of the Arduino for stablizing serial data
@ -535,20 +721,61 @@ class NS(Game, Animation):
self.chemtrails.update()
self.boss.update_dialogue()
self.wipe.update()
# Draw the pop up text line by line if there is any
pop_up_y = 0
for line in self.pop_up_text.split("\n"):
if line:
surface = self.pop_up_font.render(line, False, (0, 0, 0), (255, 255, 255))
self.get_display_surface().blit(surface, (0, pop_up_y))
pop_up_y += surface.get_height()
# Draw pop up text line by line
if self.pop_up_text:
width = 0
height = 0
for line in self.pop_up_text.split("\n"):
if line:
line_width, line_height = self.pop_up_font.size(line)
if line_width > width:
width = line_width
height += line_height
full_surface = pygame.Surface((width, height))
x = 0
y = 0
for line in self.pop_up_text.split("\n"):
if line:
surface = self.pop_up_font.render(
line, True, pygame.Color(self.get_configuration("pop-up", "foreground")),
pygame.Color(self.get_configuration("pop-up", "background")))
full_surface.blit(surface, (x, y))
y += surface.get_height()
if y > 0:
sprite = Sprite(self)
sprite.add_frame(full_surface)
sprite.set_alpha(200)
if self.get_configuration("pop-up", "center"):
sprite.location.center = self.get_display_surface().get_rect().center
sprite.update()
# Draw network diagnostics
if self.get_configuration("network", "diagnostics"):
y = self.get_display_surface().get_rect().bottom
font = pygame.font.Font(self.get_configuration("network", "diagnostics-font"),
self.get_configuration("network", "diagnostics-size"))
for peer in self.peers.values():
surface = font.render(
f"{peer.address} {peer.status} [PvP {peer.versus}, lvl {peer.level}, result {peer.result}]",
True, (255, 255, 255), (0, 0, 0))
surface.set_alpha(200)
y -= surface.get_height()
self.get_display_surface().blit(surface, (0, y))
surface = font.render(f"players: {self.count_players()} lobby: {self.count_lobby()}", True, (255, 255, 255), (0, 0, 0))
surface.set_alpha(200)
y -= surface.get_height()
self.get_display_surface().blit(surface, (0, y))
# Reset the game when idle
self.idle_elapsed += self.time_filter.get_last_frame_duration()
if self.idle_elapsed >= self.IDLE_TIMEOUT:
self.reset()
def end(self, event):
"""
Extend the parent end method to try adding a permanent quit feature in case there is a Raspbian Lite systemd autostart service running
Extend the parent end method to try adding a permanent quit feature in case there is a Raspbian Lite systemd autostart
service running
"""
if event.type == QUIT or self.delegate.compare(event, "quit"):
if self.confirming_quit or not self.get_configuration("input", "confirm-quit"):
@ -560,6 +787,8 @@ class NS(Game, Animation):
print("Killing with permanent stop sent to systemd scrapeboard service")
except:
print("No scrapeboard system service detected, so permanent quit either failed or was unnecessary")
# Call parent to complete quit
super().end(event)
@ -573,7 +802,7 @@ class LevelSelect(Animation):
def __init__(self, parent):
Animation.__init__(self, parent)
self.subscribe(self.respond, KEYDOWN)
self.register(self.timeout)
self.register(self.timeout, self.force_launch)
y = 250
indent = 10
dsr = self.get_display_surface().get_rect()
@ -599,9 +828,9 @@ class LevelSelect(Animation):
self.previews = []
font = pygame.font.Font(self.get_resource(Dialogue.FONT_PATH), 18)
padding = 4
for level_index, text in enumerate(("NORMAL", "ADVANCED", "EXPERT")):
for level_index, text in enumerate(("1 KOOL", "2 ALIEN", "3 GOTH")):
self.previews.append(Sprite(self, 100))
text = font.render(text, True, (255, 255, 255))
text = font.render(text, True, (0, 0, 0))
text = pygame.transform.rotate(text, 90)
text_rect = text.get_rect()
text_rect.midleft = preview_rect.midleft
@ -617,7 +846,7 @@ class LevelSelect(Animation):
for hue in range(0, 360, 8):
frame = pygame.Surface(preview_rect.size)
color = Color(0, 0, 0)
color.hsla = hue, 100, 50, 100
color.hsla = hue, 100, 75, 100
frame.fill(color)
frame.blit(text, text_rect)
frame.blit(environment, environment_rect)
@ -625,8 +854,10 @@ class LevelSelect(Animation):
self.previews[-1].add_frame(frame)
self.previews[-1].location.midbottom = self.platforms[level_index].view.location.centerx, \
self.platforms[level_index].view.location.top - 12
self.reset()
def activate(self):
self.reset()
self.active = True
for platform in self.platforms:
platform.activate()
@ -636,17 +867,23 @@ class LevelSelect(Animation):
self.active = False
for platform in self.platforms:
platform.deactivate()
def reset(self):
self.deactivate()
self.level_index_selected = None
self.level_launched = False
self.launch_forced = False
self.zoom = 1.0
self.grow_sound_channel = None
for level_index in range(3):
self.platforms[level_index].view.halt(self.platforms[level_index].view.wipe_out)
self.previews[level_index].halt(self.previews[level_index].wipe_out)
self.platforms[level_index].view.reset()
self.previews[level_index].reset()
self.platforms[level_index].view.unhide()
self.previews[level_index].unhide()
self.halt()
def reset(self):
self.deactivate()
def respond(self, event):
"""
Respond to CTRL + key presses to launch a level or toggle level select mode
@ -687,6 +924,9 @@ class LevelSelect(Animation):
"""
self.get_game().wipe.start(self.get_game().reset, leave_wipe_running=True)
def force_launch(self):
self.launch_forced = True
def update(self):
if self.active:
Animation.update(self)
@ -698,17 +938,31 @@ class LevelSelect(Animation):
for level_index, platform in enumerate(self.platforms):
if platform.get_glowing_edge() == self.get_game().platform.get_edge_pressed():
if self.get_game().platform.press_elapsed > self.get_configuration("time", "level-select-press-length"):
# This will cause the level to launch
# This will cause a vote to be cast to peers if there are any. If there are others in the lobby,
# the game will wait for other votes to be cast or the lobby to clear. Otherwise, the level will
# launch.
self.level_index_selected = level_index
if self.grow_sound_channel is not None:
self.grow_sound_channel.stop()
self.grow_sound_channel = None
self.get_game().peers["localhost"].seed = random.randint(0, self.get_configuration("system", "max-seed"))
self.seed = self.get_game().peers['localhost'].seed
print(f"Set seed to {self.seed}")
self.play(self.force_launch, delay=self.get_configuration("network", "join-time-limit"))
# Wipe away other levels and zoom selected
for level_index in range(3):
if level_index != self.level_index_selected:
self.platforms[level_index].view.play(self.platforms[level_index].view.wipe_out)
self.previews[level_index].play(self.previews[level_index].wipe_out, interval=100)
self.get_audio().play_sfx("complete_pattern_3")
self.players_counted = 1
break
else:
if self.grow_sound_channel is None:
self.grow_sound_channel = self.get_audio().play_sfx("grow", -1, x=platform.view.location.centerx)
# Draw a growing ring around the currently pressed level
angle = self.get_game().platform.press_elapsed / self.get_configuration("time", "level-select-press-length") * 2 * pi
angle = self.get_game().platform.press_elapsed / \
self.get_configuration("time", "level-select-press-length") * 2 * pi
diameter = self.previews[level_index].location.height + 21
rect = pygame.Rect(0, 0, diameter, diameter)
rect.center = self.previews[level_index].location.center
@ -717,15 +971,49 @@ class LevelSelect(Animation):
if offset < angle:
pygame.draw.arc(self.get_display_surface(), (255, 255, 255), rect, offset, angle, 14)
offset += .01
if self.level_index_selected is not None:
# Launch the level
for level_index in range(3):
if level_index != self.level_index_selected:
self.platforms[level_index].view.play(self.platforms[level_index].view.wipe_out)
self.previews[level_index].play(self.previews[level_index].wipe_out, interval=100)
self.get_audio().play_sfx("complete_pattern_3")
# Check if peers are still deciding
elif not self.level_launched:
# Sync seed and wait time with players who have voted for the same level
for peer in self.get_game().peers.values():
if peer.address != "localhost" and peer.status == "voted" and peer.level == self.level_index_selected:
peer.versus = True
if self.get_game().count_players() > self.players_counted:
self.players_counted += 1
self.seed = (self.seed + peer.seed) % self.get_configuration("system", "max-seed")
self.halt(self.force_launch)
self.play(self.force_launch, delay=self.get_configuration("network", "join-time-limit"))
# Launch if time is up, the lobby is empty, or everyone present has voted
if all(peer.status != "level select" or peer.status == "voted" for peer in self.get_game().peers.values()) or \
self.launch_forced:
print(f"Seeding generator with {self.seed}")
random.seed(self.seed)
self.halt(self.force_launch)
self.get_game().pop_up("", clear=True)
self.level_launched = True
self.opponents_at_launch = [peer for peer in self.get_game().peers.values() if peer.versus]
if len(self.opponents_at_launch) > 1:
for level_index in range(3):
if level_index != self.level_index_selected:
self.platforms[level_index].view.halt()
self.previews[level_index].halt()
self.get_game().wipe.start(self.launch_selected_index)
# Update displayed wait message
else:
remaining = self.accounts[self.force_launch].delay
if remaining < self.get_configuration("network", "join-time-limit") - 500:
self.get_game().pop_up(
f"Waiting {remaining // 1000 + 1}s for players to join", clear=True)
# Second half of launch animation
elif not self.get_game().wipe.is_playing() and any(preview.is_hidden() for preview in self.previews):
# Final animation before game will launch, launch is attached to the animation and will be triggered automatically
self.get_game().wipe.start(self.launch_selected_index)
for platform in self.platforms:
platform.update()
if self.level_index_selected is not None:
@ -894,6 +1182,22 @@ class Tony(Sprite):
self.location.centerx = dsr.centerx
self.board.location.centerx = self.location.centerx
# Add a QR code to the t-shirt
self.qr = Sprite(self)
frame = pygame.image.load(self.get_resource("qr/qr.png"))
frame = pygame.transform.smoothscale(frame, (165, 141))
self.qr.add_frame(frame)
self.qr.location.midtop = 410, 103
self.qr_text = Sprite(self, [6000, 1500, 1500, 1500, 1500])
if self.get_configuration("display", "qr-static"):
frames = load_frames(self.get_resource("qr/qr_text_static.png"), transparency=True)
else:
frames = load_frames(self.get_resource("qr/"), query="qr_text_[0-9].png", transparency=True)
for ii, frame in enumerate(frames):
frames[ii] = pygame.transform.smoothscale(frame, (165, int(165 / frame.get_width() * frame.get_height())))
self.qr_text.add_frames(frames)
self.qr_text.location.midtop = self.qr.location.midbottom
def set_frameset(self, name):
Sprite.set_frameset(self, name)
self.get_current_frameset().reset()
@ -910,7 +1214,7 @@ class Tony(Sprite):
Sprite.shift_frame(self)
frameset = self.get_current_frameset()
if frameset.name == "board" and frameset.current_index == 1:
self.get_audio().play_sfx(choice(self.taunts))
self.get_audio().play_sfx(random.choice(self.taunts))
def update(self):
"""
@ -922,11 +1226,17 @@ class Tony(Sprite):
save = self.get_display_surface()
intermediate_surface = Surface(self.location.size, SRCALPHA)
self.display_surface = intermediate_surface
self.qr.display_surface = intermediate_surface
self.qr_text.display_surface = intermediate_surface
location_save = self.location.copy()
self.location.topleft = 0, 0
self.qr.location.centerx = self.location.centerx + 10
self.qr_text.location.midtop = self.qr.location.midbottom
# Do a regular Sprite animation update
Sprite.update(self)
self.qr.update()
self.qr_text.update()
# Blend the effect frame with the sprite frame
if not self.get_configuration("system", "minimize-load-time"):
@ -1001,9 +1311,9 @@ class Video(Sprite):
def shift_frame(self):
Sprite.shift_frame(self)
if random() < self.next_video_chance:
if random.random() < self.next_video_chance:
while True:
selection = choice(range(0, len(self.gif_frames_scaled)))
selection = random.choice(range(0, len(self.gif_frames_scaled)))
if selection != self.gif_index:
self.gif_index = selection
self.load_selection()
@ -1034,16 +1344,16 @@ class Logo(Sprite):
for x in range(0, dsr.w + self.location.w, self.location.w):
if x != 0 or y != 0:
self.add_location((x, y))
self.background = pygame.surface.Surface(self.get_display_surface().get_size())
self.display_surface = self.background
Sprite.update(self)
self.display_surface = self.get_screen()
def update(self):
"""
Draw the background, disable parent update (performance hack)
"""
self.get_display_surface().blit(self.background, (0, 0))
self.move(-1, 1)
if self.location.right < 0:
self.move(self.location.w)
if self.location.top > 0:
self.move(dy=-self.location.h)
Sprite.update(self)
class Title(Animation):
@ -1051,11 +1361,10 @@ class Title(Animation):
Handles displaying and drawing the title screen. It draws the high scores, creates and updates an attract mode video pop-up, tracks
the player's moves and checks if they are doing the start game pattern, and updates the background logo and giant Tony sprite.
Notes
-----
Title.draw_scores is a slow method, so the scores should only be drawn when a score is added.
* It should be directed to draw scores when a new score is added (and only then), and it will store the score surfaces and only blit
them once when activated (unless the scores are updated). This way it only blits that section of the screen once.
If the game is configured to optimize on the title screen, the scores will only be blit when Title.activate is called. Otherwise,
they will blit every update.
"""
# Sequence of moves the player must do to start the game
@ -1068,6 +1377,7 @@ class Title(Animation):
@param parent GameChild object that will connect this GameChild object to the overall tree and root Game object
"""
Animation.__init__(self, parent)
self.active = False
# Set up attract mode pop-up
self.angle = pi / 8
@ -1103,14 +1413,17 @@ class Title(Animation):
self.get_game().tony.set_frameset("static")
self.get_audio().play_bgm("title")
# Blit the scores
for sprite in self.score_sprites:
sprite.update()
# Optimization for only drawing part of the title screen
if self.get_configuration("system", "optimize-title-screen"):
# Optimize by setting a clip that excludes the area where the scores are drawn
self.get_display_surface().set_clip(
(self.score_sprites[0].location.right, 0, self.score_sprites[1].location.left - self.score_sprites[0].location.right,
self.get_display_surface().get_height()))
# Blit the scores
for sprite in self.score_sprites:
sprite.update()
# Optimize by setting a clip that excludes the area where the scores are drawn
self.get_display_surface().set_clip(
(self.score_sprites[0].location.right, 0, self.score_sprites[1].location.left - self.score_sprites[0].location.right,
self.get_display_surface().get_height()))
def deactivate(self):
self.active = False
@ -1196,9 +1509,9 @@ class Title(Animation):
def draw_scores(self):
"""
Create two columns, one for each side of the screen. Draw as many scores as can fit along each column, in order from best to worst, separating
them evenly into categories: normal, advanced, and expert. Save the columns as sprites. Note that this doesn't support non-level select mode
anymore.
Create two columns, one for each side of the screen. Draw as many scores as can fit along each column, in order from
best to worst, separating them evenly into categories: normal, advanced, and expert. Save the columns as sprites. Note
that this doesn't support non-level select mode anymore.
"""
ds = self.get_display_surface()
self.score_indicator = None
@ -1248,6 +1561,10 @@ class Title(Animation):
y += self.draw_score_to_column(score, right_column, (x, y), rank)
right_column_sprite.add_frame(right_column)
right_column_sprite.location.topleft = x, 0
if not self.get_configuration("system", "optimize-title-screen") and self.get_configuration("display", "scores-alpha") < 255:
alpha = self.get_configuration("display", "scores-alpha")
left_column.set_alpha(alpha)
right_column.set_alpha(alpha)
self.score_sprites = [left_column_sprite, right_column_sprite]
def show_video(self):
@ -1288,6 +1605,11 @@ class Title(Animation):
self.get_audio().play_sfx("land_0")
self.get_game().tony.update()
# Draw the scores unless optimized out
if not self.get_configuration("system", "optimize-title-screen"):
for sprite in self.score_sprites:
sprite.update()
# Bounce the GIF around the screen
if self.video.location.right > dsr.right or self.video.location.left < dsr.left:
self.angle = reflect_angle(self.angle, 0)
@ -2298,6 +2620,7 @@ class Boss(Animation):
animations that control attacks, effects, and dialog.
"""
Animation.__init__(self, parent)
self.battle_finished = False
# Set up sprites with boil, hit, and intro animations
self.boss_sprites = []
self.boss_sprite_arms = []
@ -2499,6 +2822,7 @@ class Boss(Animation):
def brandish(self):
self.queue = []
platform = self.get_game().platform
choice = random.choice
if self.level_index == 0:
if self.health.amount > 90:
first = choice(platform.get_steps_from_edge(self.last_attack))
@ -2651,7 +2975,7 @@ class Boss(Animation):
length = 8
while len(self.queue) < length:
while True:
orientation = randint(0, 5)
orientation = random.randint(0, 5)
if (not self.queue and orientation != self.last_attack) or \
(len(self.queue) > 0 and orientation != self.queue[-1]):
self.queue.append(orientation)
@ -2668,7 +2992,7 @@ class Boss(Animation):
def choose_new_edge(self, edges):
while True:
edge = choice(edges)
edge = random.choice(edges)
if edge != self.last_attack:
return edge
@ -2694,6 +3018,14 @@ class Boss(Animation):
self.level_sprite().set_frameset("normal")
self.play(self.flash_player_damage)
self.get_game().chemtrails.set_frameset("hurt")
# Record a play to the DNF file for analytics
try:
with open(self.get_configuration("system", "dnf-file"), "at") as dnf_file:
dnf_file.write(f"{self.time_elapsed} {self.level_index} {datetime.datetime.isoformat(datetime.datetime.now(), 'T')}\n")
except:
print("Error saving DNF run to file")
self.player_defeated = not win
self.kills += not win
self.play(self.show_end_dialogue, delay=3000, play_once=True)
@ -2823,7 +3155,8 @@ class Boss(Animation):
def level_sprite(self, level_index=None):
"""
Return the boss sprite associated with this the given level index. If level index is not given, use the value in `self.level_index`.
Return the boss sprite associated with this the given level index. If level index is not given, use the value in
`self.level_index`.
@param level_index index of the level of the requested sprite
"""
@ -3259,7 +3592,7 @@ class Ending(Animation):
self.deactivate()
self.halt()
self.text_index = 0
self.angle = choice((pi / 4, 3 * pi / 4, 5 * pi / 4, 7 * pi / 4))
self.angle = random.choice((pi / 4, 3 * pi / 4, 5 * pi / 4, 7 * pi / 4))
self.slime_bag.reset()
def deactivate(self):
@ -3273,18 +3606,18 @@ class Ending(Animation):
foreground = get_boxed_surface(
self.time_font.render(str(self.get_game().most_recent_score), False, (180, 150, 20), (255, 255, 255)).convert_alpha(),
background=(255, 255, 255), padding=(38, 0))
if self.rank() % 100 // 10 != 1:
if self.rank() % 10 == 1:
if self.rank()[0] % 100 // 10 != 1:
if self.rank()[0] % 10 == 1:
ordinal = "ST"
elif self.rank() % 10 == 2:
elif self.rank()[0] % 10 == 2:
ordinal = "ND"
elif self.rank() % 10 == 3:
elif self.rank()[0] % 10 == 3:
ordinal = "RD"
else:
ordinal = "TH"
else:
ordinal = "TH"
rank = self.rank_font.render(f"{self.rank()}{ordinal}", False, (180, 150, 20), (255, 255, 255))
rank = self.rank_font.render(f"{self.rank()[0]}{ordinal}", False, (180, 150, 20), (255, 255, 255))
rank = pygame.transform.rotate(rank, 90)
rank_rect = rank.get_rect()
rank_rect.midleft = foreground.get_rect().midleft
@ -3305,19 +3638,43 @@ class Ending(Animation):
def rank(self):
"""
Get the rank of the currently displaying score
@return the rank of the currently displaying score as a tuple: (rank, total)
"""
rank = 0
for score in sorted([score for score in self.get_game().scores if score.level_index == self.defeated_level_index]):
level_scores = [score for score in self.get_game().scores if score.level_index == self.defeated_level_index and not score.blank()]
for score in sorted(level_scores):
rank += 1
if score == self.get_game().most_recent_score:
break
return rank
return rank, len(level_scores)
def start(self):
dialogue = self.get_game().dialogue
if self.get_configuration("system", "enable-level-select"):
text = f"You vanquished my goon and got the #{self.rank()} rank! Well done, slime bag.\n"
# Create a message for versus mode
if len(self.get_game().level_select.opponents_at_launch) > 1:
# Check if any peers had a faster time
rank = 1
for peer in self.get_game().level_select.opponents_at_launch:
if peer.address != "localhost" and not peer.status == "playing" and peer.result is not None and \
peer.result < self.get_game().most_recent_score.milliseconds:
rank += 1
if rank == 1:
text = (f"Congratulations on winning the battle and getting #{self.rank()[0]} out of {self.rank()[1]} overall!\n"
"Well done, slime bag. ")
else:
total = len(self.get_game().level_select.opponents_at_launch)
text = (f"You were #{rank} out of {total} in the battle, but you vanquished my goon and finished\n"
f"#{self.rank()[0]} out of {self.rank()[1]} overall! Well done, slime bag. ")
# Create a message for single-player mode
else:
text = (f"You vanquished my goon and got the #{self.rank()[0]} rank out of {self.rank()[1]} overall!\n"
"Well done, slime bag.")
if self.defeated_level_index == 2:
dialogue.set_name("Tony")
text += "You made your father proud today. I love you child."

View File

@ -5,37 +5,50 @@ Scrapeboard
So, you think you can skateboard, but can you scrapeboard, you slime bag? Scrapeboard is a DDR inspired alt control game that uses a real skateboard deck instead of your feet. Do you have the moves to skate through a gauntlet of goons all the way to Tony Hawk?
Wiki
----
This README file is for setting up and using the code repository. For more general information on how to [operate](../../../wiki/Operators-manual) or [build](../../../wiki/Builders-manual) Scrapeboard, see the [wiki](../../../wiki).
Controller
----------
The controller must be provided by the user, whether it's a standard Scrapeboard mat and board, a custom interface built by the user, or keyboard input. The hardware requirement for [serial mode](#Serial) is an [Arduino][] or Arduino-equivalent device that can run the [serial program][]. For [keyboard mode](#Keys), no special hardware is required, although a gamepad or [Makey Makey][] could be used to create a custom controller that sends key presses.
The standard controller is a custom platform combined with a modified skatedeck, seen in the above GIF. It can be built using the instructions in the [builder's manual](../../../wiki/Builders-manual) and attached to an Arduino. Custom interfaces can be created using an Arduino or Raspberry Pi.
We are working on an Instructable with details on how to create a standard Scrapeboard mat, board, and circuit! For now, feel free to set up the software and experiment with your own Makey Makey or Arduino interface.
There is also keyboard support built-in. It is meant for testing, but the game can be played with it.
Software
--------
### *See the [software chapter](../../../wiki/Software) of the [Builder's Manual](../../../wiki/Builders-manual) for more detailed instructions*
The software requires Python, [Pygame][], and a custom Python game framework [PGFW][]. The Python version should be 3.9 or higher. The Pygame version should be 1.9.6 or higher. PGFW is a submodule of this repository, so it can be cloned simultaneously using the `--recursive` flag. Python and Pygame can be installed on any operating system, including Windows, OS X, and Linux.
Installing Python will usually install Python's package manager PIP as well. PIP can be used to install Pygame by running the following from your terminal (for example, PowerShell on Windows)
Installing Python will usually install Python's package manager PIP as well. PIP can be used to install Pygame by running the following from your terminal (for example, PowerShell on Windows).
pip install pygame
Once you have Python and Pygame installed, run the following to download Scrapeboard and PGFW
git clone --recursive https://git.nugget.fun/scrape/scrapeboard
git clone --recursive https://open.shampoo.ooo/scrape/scrapeboard
If you have an Arduino prepared, run this to start the game
If you have an Arduino connected with the circuit and program prepared, run this to start the game. If the Arduino is not prepared yet, see below.
./OPEN-GAME
python OPEN-GAME
Otherwise run the game in keyboard mode like this
If you are using a Raspberry Pi, run this instead. The Pi should have a circuit installed to its GPIO pins. See below for details.
./OPEN-GAME --no-serial
python OPEN-GAME --pi
To run the game in keyboard mode anytime, use the following
python OPEN-GAME --no-serial
Serial
------
### *See the [electronics chapter](../../../wiki/Electronics) of the [Builder's Manual](../../../wiki/Builders-manual) for more detailed instructions*
To run the game using the custom skateboard and metal pads, the Arduino attached to the pads must be plugged into USB, and the [pyserial][] package must be installed on the computer.
If you have Python Package Installer, you can run this to install pyserial:
@ -46,6 +59,13 @@ The Arduino must be loaded with the [serial program][] and connected to USB. The
If you don't have the board, pad and Arduino, you can test the game using keyboard-only mode.
Raspberry Pi
------------
Raspberry Pi GPIO input is also supported. See the [Raspberry Pi chapter](../../../wiki/Raspberry-Pi) of the manual for how to install Scrapeboard on a Raspberry Pi. Once the circuit is in place, the game will be able to detect GPIO input. Run with the `--pi` flag to activate Raspberry Pi mode.
./OPEN-GAME --pi
Keys
----
@ -78,23 +98,16 @@ Options
The full list of configurable values is in the [config file][]. There are also command line flags that can override config values. Use the help flag to see the possible values:
./OPEN-GAME -h
python OPEN-GAME -h
The `--minimize-load-time` flag can be useful when testing because it sacrifices some effects to load the game quickly.
License
-------
Original Scrapeboard code is released without restriction on copying, modifying, or selling, under the zlib license. Art, sound, text, and schematic assets are released under CC BY 4.0. This means users are free to use Scrapeboard in any context, including modding it and even selling mods or creating a closed source version. Use of the assets requires attribution is given to Scrapeboard for the original assets, and if source is distributed, the zlib license must be included as the license for the original code.
Original Scrapeboard code is released without restriction on copying, modifying, or selling, under the zlib license. Art, sound, text, and schematic assets are released under CC BY 4.0. Users are licensed to modify Scrapeboard and even sell their modifications. Scrapeboard code and assets can be used in other projects, even closed source ones. Use of the assets requires attribution is given to Scrapeboard for the original assets. If the source is distributed, the zlib license must be included as the license for the original code. The full license is in [LICENSE.txt][].
PGFW is included under its zlib license. Python, Pygame, and Arduino all have their own licenses, but they are not distributed with this project.
See [LICENSE.txt][]
Contact
-------
Email us at scrape (at) nugget (dot) fun
PGFW is included under [its zlib license](https://open.shampoo.ooo/shampoo/pgfw/LICENSE.txt).
Donations
---------
@ -103,11 +116,17 @@ Send us a donation through [Ko-fi](https://ko-fi.com/scrapeboard)!
[![Donate at Ko-fi](https://storage.ko-fi.com/cdn/kofi3.png?v=3)](https://ko-fi.com/Z8Z7FX41L)
Contact
-------
More information is available [at the website](https://scrape.nugget.fun). Email us at scrape (at) nugget (dot) fun.
[Pygame]: https://pygame.org
[Makey Makey]: https://makeymakey.com
[serial program]: serial/serial2/serial2.ino
[serial program]: serial/serial.ino
[pyserial]: https://pypi.org/project/pyserial/
[Arduino]: https://arduino.cc
[config file]: config
[LICENSE.txt]: LICENSE.txt
[PGFW]: https://git.nugget.fun/nugget/pgfw
[PGFW]: https://open.shampoo.ooo/shampoo/pgfw
[Raspberry Pi]: https://www.raspberrypi.org/

42
config
View File

@ -22,14 +22,16 @@ data-exclude = local/, *.pyc, .git*, README, build/, dist/, *.egg-info, *.py, MA
[display]
caption = Scrapeboard
show-framerate = yes
show-framerate = no
framerate-position = 600, 0
dimensions = 800, 450
fullscreen = no
attract-gif-alpha = 1.0
effects = True
alpha-effect-title = False
alpha-effect-title = True
scores-font = BPmono.ttf
scores-alpha = 230
qr-static = False
[system]
# will force set display->effects to off
@ -37,6 +39,26 @@ minimize-load-time = no
enable-level-select = yes
lives-boss-rush-mode = 3
lives-level-select-mode = 1
optimize-title-screen = no
max-seed = 2147483647
dnf-file = resource/dnf.txt
scores-file = resource/scores.txt
[network]
peers =
port = 8080
delimeter = |
join-time-limit = 5999
diagnostics = no
diagnostics-font = resource/BPmono.ttf
diagnostics-size = 15
[pop-up]
size = 22
length = 3000
foreground = #ffffff
background = #000000
center = yes
[boss]
damage-per-hit-level-1 = 6.0
@ -61,8 +83,8 @@ volume = 1.0
[input]
buffer = 0
arduino-port = /dev/ttyACM0
serial = no
arduino-port = COM6
serial = yes
pi = no
confirm-quit = no
@ -80,8 +102,8 @@ attract-gif-length = 10000
attract-board-length = 3600
attract-reset-countdown = 30000
level-select-reset-countdown = 30000
level-select-press-length = 2000
ending-timeout = 22000
level-select-press-length = 1500
ending-timeout = 7500
lizard-hurt-length = 2000
[bgm]
@ -92,8 +114,8 @@ level_2 = bgm/level_2.ogg, .65
end = bgm/end.ogg, .65
[pads]
nw_color = #00FF88
ne_color = #FF88FF
se_color = #2222FF
sw_color = #FF2222
nw_color = #FF88FF
ne_color = #E4B80C
se_color = #FF2222
sw_color = #2222FF
center_y = 376

View File

@ -1,47 +0,0 @@
[setup]
license = Public Domain
title = Scrapeboard
url = http://shampoo.ooo/games/esb
version = 0.2.3
init-script = OPEN-GAME
additional-packages = lib
data-exclude = local/, *.pyc, .git*, README, build/, dist/, *.egg-info, *.py, MANIFEST*, PKG-INFO, *.pyc, *.swp, *~, changelog, scrapeboard, OPEN-GAME, lib
[display]
caption = Scrapeboard
show-framerate = False
dimensions = 640, 480
fullscreen = False
attract-gif-alpha = 0.95
[mouse]
visible = False
[keys]
quit = K_ESCAPE
up = K_u
[audio]
sfx-volume = 0.8
panel-enabled = True
volume = 1.0
[input]
buffer = 0
arduino-port = /dev/ttyACM1
serial = True
[time]
timer-max-time = 10000
timer-start-time = 7000
timer-addition = 1000
sword-delay = 300
attract-gif-length = 10000
attract-board-length = 3600
[bgm]
title = resource/bgm/title.ogg, 1.00
level_0 = /home/frank/storage/audio/bgm/bat-tree-habitat-key/level-0.wav, 1.00
level_1 = /home/frank/storage/audio/bgm/esp-hadouken/Cube-Levers.ogg, 1.00
level_2 = /home/frank/storage/audio/bgm/esp-hadouken/Bog.ogg, 1.00
end = /home/frank/storage/audio/bgm/odoboe/odoboe-2.wav, 1.00

View File

@ -0,0 +1,63 @@
Scrapeboard events checklist
============================
This is a list to look over while packing and before leaving for an event. For some events, some of these supplies may be unnecessary. For example, if the event uses a TV monitor, the projector wouldn't be necessary.
Basics
------
* Platform: four metal/wood panels with attached wires
* Skatedeck with attached metal pads
* Arduino
* Arduino USB cable
* Laptop that can run Scrapeboard
* Power for laptop
* HDMI cable
* PCB
* Male-to-male PCB pin adapter (usually in the Arudino already)
* Mini flat-head screwdriver
* HDMI Projector
* Projector screen
* Regular flat-head screwdriver
* Regular phillips-head screwdriver
* Pliers
* Mailing list clipboard
* Builder's manual print-out
* Remember to pull the latest version from the main branch of the Git repository
Raspberry Pi
------------
The Raspberry Pi is the preferred way to run the game, but it's more untested than using a laptop and Arduino. Ideally, bring both the Arudino + laptop version and the Raspberry Pi one.
* Raspberry Pi with Scrapeboard pre-installed and set to auto launch
* Raspberry Pi power adapter
* Micro-HDMI to HDMI cable
* PCB
* Mini phillips-head screwdriver
* USB keyboard
Sound
-----
The projector's speaker can be used for audio, but when not using a projector, a bluetooth speaker should be included.
* Bluetooth speaker with AUX input
* AUX cable
* USB charger for speaker
Merch
-----
* T-shirts
* Stickers
* Square credit card reader phone adapter
Extras
------
* Backup platform
* Backup skatedeck
* Extra resistors
* Extra speaker wire
* Knife

BIN
doc/img/End_screen.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 KiB

BIN
doc/img/Level_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

BIN
doc/img/Level_select.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 216 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 MiB

BIN
doc/img/Scrapeboard_underside.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 KiB

BIN
doc/img/Title_screen.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 KiB

BIN
doc/img/clasps.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 390 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 313 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 221 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 MiB

BIN
doc/img/metal_plate_outline.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

BIN
doc/img/metal_strip.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

BIN
doc/img/outer_screw_routing.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

BIN
doc/img/raspi-config.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 KiB

BIN
doc/img/stripped_wire_endings.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

BIN
doc/img/wood_panels_14in.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

17
gpio.py
View File

@ -2,16 +2,19 @@
#
# It requires custom hardware to play but can be tested in keyboard mode without
# the hardware. For more information on setting up and running the game, see
# README.md, or for the game in general, visit <https://scrape.nugget.fun/>.
# README.md. For information on the game in general, see <https://scrape.nugget.fun/>.
#
# Full open source code is available at <https://git.nugget.fun/scrape/scrapeboard>.
#
# This module can be imported and used to check on the status of connections between four GPIO
# inputs on the Raspberry Pi for detecting the pads in Scrapeboard.
#
# When run as a script, it prints connections detected between the input GPIO pins.
# It can also be run as a diagnostic script, in which case it prints connections detected between
# the input GPIO pins. Use the `-h` flag to print the options.
#
# Original algorithm by Dr. Clement Shimizu is translated from Arduino code in serial2.ino
# $ python3 gpio.py -h
#
# Original algorithm by Dr. Clement Shimizu is taken from his Arduino code in serial/serial.ino
import time, itertools, argparse
import RPi.GPIO as GPIO
@ -19,10 +22,10 @@ import RPi.GPIO as GPIO
# These represent the game pads and the GPIO pins they're connected to
LNW, LNE, LSE, LSW = range(4)
pins = {
LNW: 17,
LNE: 27,
LSE: 22,
LSW: 23
LNW: 26,
LNE: 19,
LSE: 13,
LSW: 6
}
def initialize_gpio():

View File

@ -1,20 +0,0 @@
import argparse, pygame, pathlib, os
from lib.pgfw.pgfw import extension
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("input_path", type=pathlib.Path)
parser.add_argument("output_path", type=pathlib.Path)
parser.add_argument("shift", type=int)
arguments = parser.parse_args()
pygame.display.set_mode((200, 100))
pygame.init()
for root, dirs, files in os.walk(arguments.input_path):
for name in files:
if name.endswith(".png"):
input_file_path = os.path.join(root, name)
shifted = extension.get_hue_shifted_surface(pygame.image.load(input_file_path).convert_alpha(), arguments.shift)
output_file_path = pathlib.Path(input_file_path.replace(str(arguments.input_path), str(arguments.output_path)))
os.makedirs(output_file_path.parent, exist_ok=True)
pygame.image.save(shifted, str(output_file_path))
print(f"saved hue shifted {input_file_path} to {output_file_path}")

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

14
kicad/README.md Normal file
View File

@ -0,0 +1,14 @@
KiCad PCB project files
=======================
This folder contains a [KiCad 7](https://kicad.org) project for printing a circuit board that can attach to Raspberry Pi or Arduino. KiCad 7 software is required for viewing and editing. The necessary footprint, symbol, and 3D model files are included. Local paths have been set to include these folders, so the projects should be able to load everything automatically, but they have not been tested on other installations of KiCad.
This PCB can be printed and used to connect the wires from the four metal plates to either an Arduino or a Raspberry Pi.
Originally made by Evan Kahn and modified by Frank DeMarco. Alien goon logo is by Blake Andrews. The boards and project files are released under the zlib license, so they are licensed to be used for any purpose. See [LICENSE.txt](../LICENSE.txt) for details.
![Scrapeboard Raspberry Pi hat](../www/pcb_hats/scrapeboard_hat_top_and_bottom_annotated.png)
![Scrapeboard Arduino UNO hat](../www/pcb_hats/scrapeboard_hat_top_and_bottom_annotated.png)
![Scrapeboard Arduino UNO hat](../www/KiCad_GUI_screen.png)

View File

@ -0,0 +1,57 @@
(footprint "PinHeader_1x04_P2.54mm_Vertical" (version 20221018) (generator pcbnew)
(layer "F.Cu")
(descr "Through hole straight pin header, 1x04, 2.54mm pitch, single row")
(tags "Through hole pin header THT 1x04 2.54mm single row")
(attr through_hole)
(fp_text reference "REF**" (at 0 -2.33) (layer "F.SilkS")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp d559e78f-9137-43bf-9f69-165532415fcf)
)
(fp_text value "PinHeader_1x04_P2.54mm_Vertical" (at 0 9.95) (layer "F.Fab")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp 348f53c9-f22c-45ad-a1c8-50113d0805cb)
)
(fp_text user "${REFERENCE}" (at 0 3.81 90) (layer "F.Fab")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp 6a275956-06fa-47ad-92b1-820393d36d11)
)
(fp_line (start -1.33 -1.33) (end 0 -1.33)
(stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp decb3ddc-c833-429d-8c0e-63b5aa24bff4))
(fp_line (start -1.33 0) (end -1.33 -1.33)
(stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 3842b227-6544-43a1-85fa-56835b085379))
(fp_line (start -1.33 1.27) (end -1.33 8.95)
(stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp e60cdaf9-8c35-4a4f-a87a-cc0c4ae2445b))
(fp_line (start -1.33 1.27) (end 1.33 1.27)
(stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 6e06f040-0623-46ed-af8e-13eea2bd173d))
(fp_line (start -1.33 8.95) (end 1.33 8.95)
(stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 48f5f3f1-daeb-4966-b655-9849658074ad))
(fp_line (start 1.33 1.27) (end 1.33 8.95)
(stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 31936b74-58c0-41b0-9174-96592b7c2da3))
(fp_line (start -1.8 -1.8) (end -1.8 9.4)
(stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp c81c6ee0-4441-4de7-807f-c30b3d1aa088))
(fp_line (start -1.8 9.4) (end 1.8 9.4)
(stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 9743eb14-e958-45a4-83eb-310dcdb26e62))
(fp_line (start 1.8 -1.8) (end -1.8 -1.8)
(stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp eef21155-0819-4e22-84e8-f17b0bc291da))
(fp_line (start 1.8 9.4) (end 1.8 -1.8)
(stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 22b486a5-f3c3-447d-83fc-e0bf37a5d122))
(fp_line (start -1.27 -0.635) (end -0.635 -1.27)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp f23b7a6c-84ee-4e57-bc43-363743bbba33))
(fp_line (start -1.27 8.89) (end -1.27 -0.635)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 91ac591b-23aa-41f6-a831-190c665c7dd1))
(fp_line (start -0.635 -1.27) (end 1.27 -1.27)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 036fb27e-aac9-4db3-afab-9f568eb24cb5))
(fp_line (start 1.27 -1.27) (end 1.27 8.89)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp a0f55beb-3ffe-43fe-b95d-6e9857ff1b99))
(fp_line (start 1.27 8.89) (end -1.27 8.89)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 110fb385-fb0b-4fa5-817c-9563606ec082))
(pad "1" thru_hole rect (at 0 0) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") (tstamp 154cd23f-521c-47b4-b321-b81bccc55300))
(pad "2" thru_hole oval (at 0 2.54) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") (tstamp 73467b20-058f-45e4-ac84-184d62db7dc8))
(pad "3" thru_hole oval (at 0 5.08) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") (tstamp 70affaf9-cf8f-4cfc-b9e7-c80a572e37b4))
(pad "4" thru_hole oval (at 0 7.62) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") (tstamp 7773fc0b-045f-44e0-9512-f82000fc06b7))
(model "../3dmodels/Connector_PinHeader_2.54mm.3dshapes/PinHeader_1x04_P2.54mm_Vertical.wrl"
(offset (xyz 0 0 0))
(scale (xyz 1 1 1))
(rotate (xyz 0 0 0))
)
)

View File

@ -0,0 +1,43 @@
(footprint "PinSocket_1x04_P2.54mm_Vertical" (version 20211014) (generator pcbnew)
(layer "F.Cu")
(tedit 5A19A429)
(descr "Through hole straight socket strip, 1x04, 2.54mm pitch, single row (from Kicad 4.0.7), script generated")
(tags "Through hole socket strip THT 1x04 2.54mm single row")
(attr through_hole)
(fp_text reference "REF**" (at 0 -2.77) (layer "F.SilkS")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp f2b54470-c210-48e0-af04-601bc8f080b6)
)
(fp_text value "PinSocket_1x04_P2.54mm_Vertical" (at 0 10.39) (layer "F.Fab")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp d53e0302-0db9-4055-a945-e949bb69a01a)
)
(fp_text user "${REFERENCE}" (at 0 3.81 90) (layer "F.Fab")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp 12818457-a928-4a58-a768-32818fc42d8d)
)
(fp_line (start 0 -1.33) (end 1.33 -1.33) (layer "F.SilkS") (width 0.12) (tstamp 0b0caae4-3516-4e1d-8c34-db4d96d41b69))
(fp_line (start 1.33 -1.33) (end 1.33 0) (layer "F.SilkS") (width 0.12) (tstamp 1bbfb789-b903-4d94-a84c-27c31d6ddb87))
(fp_line (start -1.33 1.27) (end -1.33 8.95) (layer "F.SilkS") (width 0.12) (tstamp 257cdb19-4025-4fa7-9a74-b2d22e8ba58d))
(fp_line (start -1.33 1.27) (end 1.33 1.27) (layer "F.SilkS") (width 0.12) (tstamp 7046adf6-9740-4d25-b205-d1fffb82b005))
(fp_line (start 1.33 1.27) (end 1.33 8.95) (layer "F.SilkS") (width 0.12) (tstamp c8cf58ba-8863-4630-be56-78a2eb8d55bd))
(fp_line (start -1.33 8.95) (end 1.33 8.95) (layer "F.SilkS") (width 0.12) (tstamp d1e4446c-7a25-4f49-846a-5ec9b3ac753a))
(fp_line (start -1.8 9.4) (end -1.8 -1.8) (layer "F.CrtYd") (width 0.05) (tstamp 59f28584-bc37-4ee4-9d8d-83313332dd22))
(fp_line (start 1.75 -1.8) (end 1.75 9.4) (layer "F.CrtYd") (width 0.05) (tstamp 63d51db6-ac13-4c8e-a47e-37785e50651f))
(fp_line (start -1.8 -1.8) (end 1.75 -1.8) (layer "F.CrtYd") (width 0.05) (tstamp 7fbbaabf-f9c9-4c65-84ac-eb48bbb94306))
(fp_line (start 1.75 9.4) (end -1.8 9.4) (layer "F.CrtYd") (width 0.05) (tstamp f7f34377-dc94-4e23-abc2-c9ec3682eb39))
(fp_line (start 0.635 -1.27) (end 1.27 -0.635) (layer "F.Fab") (width 0.1) (tstamp 4488ae3b-6026-4638-a2e4-db8d518174db))
(fp_line (start 1.27 -0.635) (end 1.27 8.89) (layer "F.Fab") (width 0.1) (tstamp 71b610dc-6482-4490-9131-865e7f856685))
(fp_line (start -1.27 8.89) (end -1.27 -1.27) (layer "F.Fab") (width 0.1) (tstamp 7949220b-fca3-49a1-9b4c-fac10faf8d69))
(fp_line (start -1.27 -1.27) (end 0.635 -1.27) (layer "F.Fab") (width 0.1) (tstamp 7c45869b-ce5d-4b65-9c7c-2e902cfe9d0a))
(fp_line (start 1.27 8.89) (end -1.27 8.89) (layer "F.Fab") (width 0.1) (tstamp f97fc5e6-8b3e-4567-9586-3ebba4b86f3f))
(pad "1" thru_hole rect (at 0 0) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp 2e08a263-3e07-43ef-b8ac-536cb45b6165))
(pad "2" thru_hole oval (at 0 2.54) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp 21d635ce-212a-436e-8900-6f95ebc71c55))
(pad "3" thru_hole oval (at 0 5.08) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp 4eed0372-d89a-4fec-bea1-b5660297ac7d))
(pad "4" thru_hole oval (at 0 7.62) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp 1f92a149-11c2-4b9c-9f4d-d30f134bf31d))
(model "${KICAD6_3DMODEL_DIR}/Connector_PinSocket_2.54mm.3dshapes/PinSocket_1x04_P2.54mm_Vertical.wrl"
(offset (xyz 0 0 0))
(scale (xyz 1 1 1))
(rotate (xyz 0 0 0))
)
)

View File

@ -0,0 +1,63 @@
(footprint "PinSocket_2x03_P2.54mm_Vertical" (version 20221018) (generator pcbnew)
(layer "F.Cu")
(descr "Through hole straight socket strip, 2x03, 2.54mm pitch, double cols (from Kicad 4.0.7), script generated")
(tags "Through hole socket strip THT 2x03 2.54mm double row")
(attr through_hole)
(fp_text reference "REF**" (at -1.27 -2.77) (layer "F.SilkS")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp 547f6058-d0f8-4b17-9eea-3335399ee2c3)
)
(fp_text value "PinSocket_2x03_P2.54mm_Vertical" (at -1.27 7.85) (layer "F.Fab")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp e73ef684-f822-425e-9f87-e46d26e33de1)
)
(fp_text user "${REFERENCE}" (at -1.27 2.54 90) (layer "F.Fab")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp b21bfe37-8cf6-472a-8277-d897f75677af)
)
(fp_line (start -3.87 -1.33) (end -3.87 6.41)
(stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 8dba4dae-6ee7-41f7-89af-5eae2b9e24d5))
(fp_line (start -3.87 -1.33) (end -1.27 -1.33)
(stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp bd6823a8-eecf-4e7d-a82a-861ce2f958a1))
(fp_line (start -3.87 6.41) (end 1.33 6.41)
(stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 3fe1ebdd-418a-49ec-9b1a-7fd025aa8474))
(fp_line (start -1.27 -1.33) (end -1.27 1.27)
(stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp be73fec0-a41c-479e-9ca5-41e528e60fd7))
(fp_line (start -1.27 1.27) (end 1.33 1.27)
(stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 494e1600-1f0d-4a93-9da6-23d025d75462))
(fp_line (start 0 -1.33) (end 1.33 -1.33)
(stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 91e2d6b4-f2ba-48a8-8abf-6d5a87305bd7))
(fp_line (start 1.33 -1.33) (end 1.33 0)
(stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp f10b8cfb-68c6-4d3d-9601-86c90e4e064a))
(fp_line (start 1.33 1.27) (end 1.33 6.41)
(stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 9d00c9b1-8ed2-41a8-a4d4-84c0935b9a2e))
(fp_line (start -4.34 -1.8) (end 1.76 -1.8)
(stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 2fed7008-a1b8-4949-ad06-dfccf8306a57))
(fp_line (start -4.34 6.85) (end -4.34 -1.8)
(stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp c593c6bd-791a-4447-b384-7d62cd512ff7))
(fp_line (start 1.76 -1.8) (end 1.76 6.85)
(stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp e242fa4e-f2ef-4372-9f5b-a4d3ecf2c6a6))
(fp_line (start 1.76 6.85) (end -4.34 6.85)
(stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 78e3d90c-43b7-4836-b83d-3d53d086928b))
(fp_line (start -3.81 -1.27) (end 0.27 -1.27)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 7e29cd35-3f2a-48c9-acc8-d014a5110b8d))
(fp_line (start -3.81 6.35) (end -3.81 -1.27)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 781febbd-90b2-44d9-83bb-b1d2479a435f))
(fp_line (start 0.27 -1.27) (end 1.27 -0.27)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp b16ab704-c191-447a-be88-e92f6fe58e2c))
(fp_line (start 1.27 -0.27) (end 1.27 6.35)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 06a63ecb-6558-417d-a55c-2bf4413510cb))
(fp_line (start 1.27 6.35) (end -3.81 6.35)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 2550f46f-d775-4a46-85aa-2c06289b6e41))
(pad "1" thru_hole rect (at 0 0) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") (tstamp d9b0de11-74c8-4d77-86fa-70a51d432852))
(pad "2" thru_hole oval (at -2.54 0) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") (tstamp 5efdc2f3-947f-47e4-be12-376e85cabe90))
(pad "3" thru_hole oval (at 0 2.54) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") (tstamp 1755c143-7bd3-42a1-8a6e-adbfe4768968))
(pad "4" thru_hole oval (at -2.54 2.54) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") (tstamp a6077d29-b32a-4586-9b87-15ca964f7122))
(pad "5" thru_hole oval (at 0 5.08) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") (tstamp b712a23c-c57a-4596-844a-f582681a8672))
(pad "6" thru_hole oval (at -2.54 5.08) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") (tstamp f98507ce-23ea-4ae8-b05f-5fb546e4dd3f))
(model "../3dmodels/Connector_PinSocket_2.54mm.3dshapes/PinSocket_2x03_P2.54mm_Vertical.wrl"
(offset (xyz 0 0 0))
(scale (xyz 1 1 1))
(rotate (xyz 0 0 0))
)
)

View File

@ -0,0 +1,49 @@
(footprint "R_Axial_DIN0204_L3.6mm_D1.6mm_P5.08mm_Horizontal" (version 20221018) (generator pcbnew)
(layer "F.Cu")
(descr "Resistor, Axial_DIN0204 series, Axial, Horizontal, pin pitch=5.08mm, 0.167W, length*diameter=3.6*1.6mm^2, http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf")
(tags "Resistor Axial_DIN0204 series Axial Horizontal pin pitch 5.08mm 0.167W length 3.6mm diameter 1.6mm")
(attr through_hole)
(fp_text reference "REF**" (at 2.54 -1.92) (layer "F.SilkS")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp ebea55fe-536f-4927-aa8d-6fcdfd78ce7a)
)
(fp_text value "R_Axial_DIN0204_L3.6mm_D1.6mm_P5.08mm_Horizontal" (at 2.54 1.92) (layer "F.Fab")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp d0bf7ffd-3c91-431f-a80b-0a79f3746de9)
)
(fp_text user "${REFERENCE}" (at 2.54 0) (layer "F.Fab")
(effects (font (size 0.72 0.72) (thickness 0.108)))
(tstamp 41964bac-5517-4835-9a75-1e78fb8fdbf3)
)
(fp_line (start 0.62 -0.92) (end 4.46 -0.92)
(stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 7838ef45-07ba-4309-a2ca-7e8d9db957fa))
(fp_line (start 0.62 0.92) (end 4.46 0.92)
(stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 5b5ee5a6-78cb-4a95-921d-77e05f111e1d))
(fp_line (start -0.95 -1.05) (end -0.95 1.05)
(stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 326374a9-11e2-4ed4-9096-41c432bf783b))
(fp_line (start -0.95 1.05) (end 6.03 1.05)
(stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp d71fb886-2b0d-4954-9f5d-9dc732799255))
(fp_line (start 6.03 -1.05) (end -0.95 -1.05)
(stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp ebc18cf3-a0eb-4813-aa40-a8538219d5d5))
(fp_line (start 6.03 1.05) (end 6.03 -1.05)
(stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 3f192b22-7424-4689-b8c9-4082a2577f5c))
(fp_line (start 0 0) (end 0.74 0)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 4d20b271-141d-4c9c-a5f4-2ad87473b03b))
(fp_line (start 0.74 -0.8) (end 0.74 0.8)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 9dedcc7f-88be-491b-b7ea-281efff1ff70))
(fp_line (start 0.74 0.8) (end 4.34 0.8)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp b10178b3-9c6b-452e-9ac1-4c96c0d98a15))
(fp_line (start 4.34 -0.8) (end 0.74 -0.8)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp c0f03172-0d98-467c-9df6-8d41589d8644))
(fp_line (start 4.34 0.8) (end 4.34 -0.8)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 470bc31e-9d3d-492f-9108-2e8867078dba))
(fp_line (start 5.08 0) (end 4.34 0)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp dcc0313f-4fed-4546-96b4-431fce0eeeec))
(pad "1" thru_hole circle (at 0 0) (size 1.4 1.4) (drill 0.7) (layers "*.Cu" "*.Mask") (tstamp a4046359-6457-425d-a49b-248934349aed))
(pad "2" thru_hole oval (at 5.08 0) (size 1.4 1.4) (drill 0.7) (layers "*.Cu" "*.Mask") (tstamp cc3d7c9b-0586-4d33-b6fd-733dca88e64b))
(model "../3dmodels/Resistor_THT.3dshapes/R_Axial_DIN0204_L3.6mm_D1.6mm_P5.08mm_Horizontal.wrl"
(offset (xyz 0 0 0))
(scale (xyz 1 1 1))
(rotate (xyz 0 0 0))
)
)

View File

@ -0,0 +1,133 @@
(footprint "TerminalBlock_Phoenix_MKDS-1,5-4_1x04_P5.00mm_Horizontal" (version 20221018) (generator pcbnew)
(layer "F.Cu")
(descr "Terminal Block Phoenix MKDS-1,5-4, 4 pins, pitch 5mm, size 20x9.8mm^2, drill diamater 1.3mm, pad diameter 2.6mm, see http://www.farnell.com/datasheets/100425.pdf, script-generated using https://github.com/pointhi/kicad-footprint-generator/scripts/TerminalBlock_Phoenix")
(tags "THT Terminal Block Phoenix MKDS-1,5-4 pitch 5mm size 20x9.8mm^2 drill 1.3mm pad 2.6mm")
(attr through_hole)
(fp_text reference "REF**" (at 7.5 -6.26) (layer "F.SilkS")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp a21e8700-241b-400e-83fb-fadb2d4c102d)
)
(fp_text value "TerminalBlock_Phoenix_MKDS-1,5-4_1x04_P5.00mm_Horizontal" (at 7.5 5.66) (layer "F.Fab")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp de4143e3-1566-40dc-9690-7491c66e0405)
)
(fp_text user "${REFERENCE}" (at 7.5 3.2) (layer "F.Fab")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp 56e24b71-ec18-4ed3-afae-35ca33a2b246)
)
(fp_line (start -2.8 4.16) (end -2.8 4.9)
(stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp d4c0e6f5-e415-4c25-a64b-e3286aa5b23d))
(fp_line (start -2.8 4.9) (end -2.3 4.9)
(stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 8e974080-6df8-4af1-85c0-f90c9b8bd2b6))
(fp_line (start -2.56 -5.261) (end -2.56 4.66)
(stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp d4e760ee-1684-4f4e-81cc-08c17225f771))
(fp_line (start -2.56 -5.261) (end 17.561 -5.261)
(stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 92feddb0-12ce-4382-9a81-301b3776452d))
(fp_line (start -2.56 -2.301) (end 17.561 -2.301)
(stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 7c6aaba1-d40c-4c8b-99cf-fe6b024df4ba))
(fp_line (start -2.56 2.6) (end 17.561 2.6)
(stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp e692a87c-964a-4222-aaf6-84deb6ef7d53))
(fp_line (start -2.56 4.1) (end 17.561 4.1)
(stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 4ba88744-45ca-4487-a0e1-8b232a8ae0ac))
(fp_line (start -2.56 4.66) (end 17.561 4.66)
(stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 7ae7bceb-2af8-4bbc-9f7a-738f07bea61b))
(fp_line (start 3.773 1.023) (end 3.726 1.069)
(stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 4d819a18-dd2a-4355-a1aa-a0e05780d58a))
(fp_line (start 3.966 1.239) (end 3.931 1.274)
(stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 31417d65-a94a-40cf-b830-1f8f06988481))
(fp_line (start 6.07 -1.275) (end 6.035 -1.239)
(stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 68ba6865-d06e-4dd1-9086-8a8c604145ea))
(fp_line (start 6.275 -1.069) (end 6.228 -1.023)
(stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 5791149e-f802-4b60-9383-f082bb19f4e3))
(fp_line (start 8.773 1.023) (end 8.726 1.069)
(stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 2358fd56-5b56-4f33-b933-0f5e71778831))
(fp_line (start 8.966 1.239) (end 8.931 1.274)
(stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 0df73792-2d3a-4abb-9786-a7b9f1c0b5e5))
(fp_line (start 11.07 -1.275) (end 11.035 -1.239)
(stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 759605aa-4ad5-41ad-b7c1-0f9fc6fd2f62))
(fp_line (start 11.275 -1.069) (end 11.228 -1.023)
(stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 486a7108-3b6c-490e-9119-5aacbecfa75f))
(fp_line (start 13.773 1.023) (end 13.726 1.069)
(stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp ae0d4f5e-65f2-46ec-a122-3d11a253b453))
(fp_line (start 13.966 1.239) (end 13.931 1.274)
(stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 42b35d34-46c7-4410-a4b3-091caf4d3f19))
(fp_line (start 16.07 -1.275) (end 16.035 -1.239)
(stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 15c0758b-f306-45b5-8d01-14a8db926dd7))
(fp_line (start 16.275 -1.069) (end 16.228 -1.023)
(stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 9b14171e-c21e-498a-8233-50819d357e0b))
(fp_line (start 17.561 -5.261) (end 17.561 4.66)
(stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp eb198d0c-7a5c-4f81-837e-76c8212f4040))
(fp_arc (start -1.535427 0.683042) (mid -1.680501 -0.000524) (end -1.535 -0.684)
(stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp f8ed04b9-622d-4130-ba0c-e4f187b5b8a4))
(fp_arc (start -0.683042 -1.535427) (mid 0.000524 -1.680501) (end 0.684 -1.535)
(stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 198fdd75-8403-4c63-924e-148c9394b9d7))
(fp_arc (start 0.028805 1.680253) (mid -0.335551 1.646659) (end -0.684 1.535)
(stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 9a6be24a-1d2d-4a11-a93d-771673f88bac))
(fp_arc (start 0.683318 1.534756) (mid 0.349292 1.643288) (end 0 1.68)
(stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 48aa4a68-fa93-4263-8b29-af35c8910190))
(fp_arc (start 1.535427 -0.683042) (mid 1.680501 0.000524) (end 1.535 0.684)
(stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 44939052-2f80-4be5-bb65-435fd966c3cb))
(fp_circle (center 5 0) (end 6.68 0)
(stroke (width 0.12) (type solid)) (fill none) (layer "F.SilkS") (tstamp 81094710-f8b5-4eee-9c62-b9cc8d864112))
(fp_circle (center 10 0) (end 11.68 0)
(stroke (width 0.12) (type solid)) (fill none) (layer "F.SilkS") (tstamp f7c06156-93b3-48bb-97b3-066c9ee981f1))
(fp_circle (center 15 0) (end 16.68 0)
(stroke (width 0.12) (type solid)) (fill none) (layer "F.SilkS") (tstamp 485fde80-1e36-4bf2-b4ec-a24930286064))
(fp_line (start -3 -5.71) (end -3 5.1)
(stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 511a7274-e689-46a1-b431-1606a0baad24))
(fp_line (start -3 5.1) (end 18 5.1)
(stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp b2c91f91-0022-48a5-a9e8-09d1f1b132f0))
(fp_line (start 18 -5.71) (end -3 -5.71)
(stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 5e92a9a6-94a7-4bbd-9db2-6fcc9e62a1f1))
(fp_line (start 18 5.1) (end 18 -5.71)
(stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 4c32cf34-3934-4215-b035-e6983e2f8e45))
(fp_line (start -2.5 -5.2) (end 17.5 -5.2)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 8af2bd48-29b1-4512-9e88-e397b5f81a7f))
(fp_line (start -2.5 -2.3) (end 17.5 -2.3)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 10c68a37-927f-444c-9361-3820dcb39299))
(fp_line (start -2.5 2.6) (end 17.5 2.6)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp c47bd299-e3fa-4a21-a123-ebdf5d70eef8))
(fp_line (start -2.5 4.1) (end -2.5 -5.2)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 716ee938-647e-4a4f-8135-4e2e27f6850b))
(fp_line (start -2.5 4.1) (end 17.5 4.1)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 58dffd43-8365-4dfe-9744-9f59cbf6c610))
(fp_line (start -2 4.6) (end -2.5 4.1)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp ee917058-4132-4021-9c45-300db29cdcbc))
(fp_line (start 0.955 -1.138) (end -1.138 0.955)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 52efb189-4b3d-440f-8062-66049cf989e7))
(fp_line (start 1.138 -0.955) (end -0.955 1.138)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 88a81e11-86ee-4d13-94fb-ab01ad4b251e))
(fp_line (start 5.955 -1.138) (end 3.863 0.955)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp c53a5d42-c505-4178-b07e-dea74a6c0521))
(fp_line (start 6.138 -0.955) (end 4.046 1.138)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 436754bc-d636-46e2-ae3d-09c3660b0c82))
(fp_line (start 10.955 -1.138) (end 8.863 0.955)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 9fb03865-778a-4ae5-9611-b443ee37e5d9))
(fp_line (start 11.138 -0.955) (end 9.046 1.138)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp b258cc7e-24b9-4d4b-a095-a2259180295d))
(fp_line (start 15.955 -1.138) (end 13.863 0.955)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 47e26b55-5971-4469-bb28-c55c2c868cb1))
(fp_line (start 16.138 -0.955) (end 14.046 1.138)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 13cc8dd9-74c8-4222-affa-2a4e8006eb08))
(fp_line (start 17.5 -5.2) (end 17.5 4.6)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp ded0f7c3-8929-498f-b016-eb53fb0bbde5))
(fp_line (start 17.5 4.6) (end -2 4.6)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 67c31ba9-f69f-4828-adf5-7d0d9746a585))
(fp_circle (center 0 0) (end 1.5 0)
(stroke (width 0.1) (type solid)) (fill none) (layer "F.Fab") (tstamp c5b83e75-e018-466a-99e4-e8119ecc75dd))
(fp_circle (center 5 0) (end 6.5 0)
(stroke (width 0.1) (type solid)) (fill none) (layer "F.Fab") (tstamp d9e19c94-bfad-4eee-90be-c6e460ee9cf5))
(fp_circle (center 10 0) (end 11.5 0)
(stroke (width 0.1) (type solid)) (fill none) (layer "F.Fab") (tstamp 90c37f53-8ffa-4ebe-9a8c-4b924f310093))
(fp_circle (center 15 0) (end 16.5 0)
(stroke (width 0.1) (type solid)) (fill none) (layer "F.Fab") (tstamp 097537d6-8842-4c97-bfd2-e1c88cf37777))
(pad "1" thru_hole rect (at 0 0) (size 2.6 2.6) (drill 1.3) (layers "*.Cu" "*.Mask") (tstamp 21d2cab0-828f-4396-b3aa-dcd78386c0bf))
(pad "2" thru_hole circle (at 5 0) (size 2.6 2.6) (drill 1.3) (layers "*.Cu" "*.Mask") (tstamp cb39843e-e04f-4101-9146-b9f08ca26d6c))
(pad "3" thru_hole circle (at 10 0) (size 2.6 2.6) (drill 1.3) (layers "*.Cu" "*.Mask") (tstamp 05259832-ed60-4eb7-bab6-477bb172ee86))
(pad "4" thru_hole circle (at 15 0) (size 2.6 2.6) (drill 1.3) (layers "*.Cu" "*.Mask") (tstamp 43d8a773-2c4a-4143-8007-31330a485ad8))
(model "../3dmodels/TerminalBlock_Phoenix.3dshapes/TerminalBlock_Phoenix_MKDS-1,5-4_1x04_P5.00mm_Horizontal.wrl"
(offset (xyz 0 0 0))
(scale (xyz 1 1 1))
(rotate (xyz 0 0 0))
)
)

View File

@ -0,0 +1,15 @@
3349543420202
Connector_PinSocket_2.54mm
PinSocket_1x04_P2.54mm_Vertical
Through hole straight socket strip, 1x04, 2.54mm pitch, single row (from Kicad 4.0.7), script generated
Through hole socket strip THT 1x04 2.54mm single row
0
4
4
Connector_PinSocket_2.54mm
PinSocket_2x03_P2.54mm_Vertical
Through hole straight socket strip, 2x03, 2.54mm pitch, double cols (from Kicad 4.0.7), script generated
Through hole socket strip THT 2x03 2.54mm double row
0
6
6

View File

@ -0,0 +1,7 @@
(fp_lib_table
(lib (name "Connector_PinHeader_2.54mm")(type "KiCad")(uri "${KIPRJMOD}/../footprints/Connector_PinHeader_2.54mm.pretty")(options "")(descr ""))
(lib (name "Connector_PinSocket_2.54mm")(type "KiCad")(uri "${KIPRJMOD}/../footprints/Connector_PinSocket_2.54mm.pretty")(options "")(descr ""))
(lib (name "Resistor_THT")(type "KiCad")(uri "${KIPRJMOD}/../footprints/Resistor_THT.pretty")(options "")(descr ""))
(lib (name "scrapeboard_footprint_library")(type "KiCad")(uri "${KIPRJMOD}/../footprints/scrapeboard_footprint_library.pretty")(options "")(descr ""))
(lib (name "TerminalBlock_Phoenix")(type "KiCad")(uri "${KIPRJMOD}/../footprints/TerminalBlock_Phoenix.pretty")(options "")(descr ""))
)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,77 @@
{
"board": {
"active_layer": 0,
"active_layer_preset": "All Layers",
"auto_track_width": true,
"hidden_netclasses": [],
"hidden_nets": [],
"high_contrast_mode": 0,
"net_color_mode": 1,
"opacity": {
"images": 0.6,
"pads": 1.0,
"tracks": 1.0,
"vias": 1.0,
"zones": 0.6
},
"selection_filter": {
"dimensions": true,
"footprints": true,
"graphics": true,
"keepouts": true,
"lockedItems": true,
"otherItems": true,
"pads": true,
"text": true,
"tracks": true,
"vias": true,
"zones": true
},
"visible_items": [
0,
1,
2,
3,
4,
5,
8,
9,
10,
11,
12,
13,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
32,
33,
34,
35,
36,
39,
40
],
"visible_layers": "fffffff_ffffffff",
"zone_display_mode": 0
},
"meta": {
"filename": "scrapeboard_hat.kicad_prl",
"version": 3
},
"project": {
"files": []
}
}

View File

@ -0,0 +1,489 @@
{
"board": {
"3dviewports": [],
"design_settings": {
"defaults": {
"board_outline_line_width": 0.09999999999999999,
"copper_line_width": 0.19999999999999998,
"copper_text_italic": false,
"copper_text_size_h": 1.5,
"copper_text_size_v": 1.5,
"copper_text_thickness": 0.3,
"copper_text_upright": false,
"courtyard_line_width": 0.049999999999999996,
"dimension_precision": 4,
"dimension_units": 3,
"dimensions": {
"arrow_length": 1270000,
"extension_offset": 500000,
"keep_text_aligned": true,
"suppress_zeroes": false,
"text_position": 0,
"units_format": 1
},
"fab_line_width": 0.09999999999999999,
"fab_text_italic": false,
"fab_text_size_h": 1.0,
"fab_text_size_v": 1.0,
"fab_text_thickness": 0.15,
"fab_text_upright": false,
"other_line_width": 0.15,
"other_text_italic": false,
"other_text_size_h": 1.0,
"other_text_size_v": 1.0,
"other_text_thickness": 0.15,
"other_text_upright": false,
"pads": {
"drill": 0.762,
"height": 1.524,
"width": 1.524
},
"silk_line_width": 0.15,
"silk_text_italic": false,
"silk_text_size_h": 1.0,
"silk_text_size_v": 1.0,
"silk_text_thickness": 0.15,
"silk_text_upright": false,
"zones": {
"min_clearance": 0.508
}
},
"diff_pair_dimensions": [
{
"gap": 0.0,
"via_gap": 0.0,
"width": 0.0
}
],
"drc_exclusions": [],
"meta": {
"version": 2
},
"rule_severities": {
"annular_width": "error",
"clearance": "error",
"connection_width": "warning",
"copper_edge_clearance": "error",
"copper_sliver": "warning",
"courtyards_overlap": "error",
"diff_pair_gap_out_of_range": "error",
"diff_pair_uncoupled_length_too_long": "error",
"drill_out_of_range": "error",
"duplicate_footprints": "warning",
"extra_footprint": "warning",
"footprint": "error",
"footprint_type_mismatch": "warning",
"hole_clearance": "error",
"hole_near_hole": "error",
"invalid_outline": "error",
"isolated_copper": "warning",
"item_on_disabled_layer": "error",
"items_not_allowed": "error",
"length_out_of_range": "error",
"lib_footprint_issues": "warning",
"lib_footprint_mismatch": "warning",
"malformed_courtyard": "error",
"microvia_drill_out_of_range": "error",
"missing_courtyard": "ignore",
"missing_footprint": "warning",
"net_conflict": "warning",
"npth_inside_courtyard": "warning",
"padstack": "warning",
"pth_inside_courtyard": "warning",
"shorting_items": "error",
"silk_edge_clearance": "warning",
"silk_over_copper": "warning",
"silk_overlap": "warning",
"skew_out_of_range": "error",
"solder_mask_bridge": "error",
"starved_thermal": "error",
"text_height": "warning",
"text_thickness": "warning",
"through_hole_pad_without_hole": "error",
"too_many_vias": "error",
"track_dangling": "warning",
"track_width": "error",
"tracks_crossing": "error",
"unconnected_items": "error",
"unresolved_variable": "error",
"via_dangling": "warning",
"zones_intersect": "error"
},
"rules": {
"max_error": 0.005,
"min_clearance": 0.0,
"min_connection": 0.0,
"min_copper_edge_clearance": 0.0,
"min_hole_clearance": 0.25,
"min_hole_to_hole": 0.25,
"min_microvia_diameter": 0.19999999999999998,
"min_microvia_drill": 0.09999999999999999,
"min_resolved_spokes": 2,
"min_silk_clearance": 0.0,
"min_text_height": 0.7999999999999999,
"min_text_thickness": 0.12,
"min_through_hole_diameter": 0.3,
"min_track_width": 0.19999999999999998,
"min_via_annular_width": 0.049999999999999996,
"min_via_diameter": 0.39999999999999997,
"solder_mask_clearance": 0.0,
"solder_mask_min_width": 0.0,
"solder_mask_to_copper_clearance": 0.0,
"use_height_for_length_calcs": true
},
"teardrop_options": [
{
"td_allow_use_two_tracks": true,
"td_curve_segcount": 5,
"td_on_pad_in_zone": false,
"td_onpadsmd": true,
"td_onroundshapesonly": false,
"td_ontrackend": false,
"td_onviapad": true
}
],
"teardrop_parameters": [
{
"td_curve_segcount": 0,
"td_height_ratio": 1.0,
"td_length_ratio": 0.5,
"td_maxheight": 2.0,
"td_maxlen": 1.0,
"td_target_name": "td_round_shape",
"td_width_to_size_filter_ratio": 0.9
},
{
"td_curve_segcount": 0,
"td_height_ratio": 1.0,
"td_length_ratio": 0.5,
"td_maxheight": 2.0,
"td_maxlen": 1.0,
"td_target_name": "td_rect_shape",
"td_width_to_size_filter_ratio": 0.9
},
{
"td_curve_segcount": 0,
"td_height_ratio": 1.0,
"td_length_ratio": 0.5,
"td_maxheight": 2.0,
"td_maxlen": 1.0,
"td_target_name": "td_track_end",
"td_width_to_size_filter_ratio": 0.9
}
],
"track_widths": [
0.0
],
"via_dimensions": [
{
"diameter": 0.0,
"drill": 0.0
}
],
"zones_allow_external_fillets": false
},
"layer_presets": [],
"viewports": []
},
"boards": [],
"cvpcb": {
"equivalence_files": []
},
"erc": {
"erc_exclusions": [],
"meta": {
"version": 0
},
"pin_map": [
[
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
2,
0,
1,
0,
0,
1,
0,
2,
2,
2,
2
],
[
0,
0,
0,
0,
0,
0,
1,
0,
1,
0,
1,
2
],
[
0,
1,
0,
0,
0,
0,
1,
1,
2,
1,
1,
2
],
[
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
2
],
[
1,
1,
1,
1,
1,
0,
1,
1,
1,
1,
1,
2
],
[
0,
0,
0,
1,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
2,
1,
2,
0,
0,
1,
0,
2,
2,
2,
2
],
[
0,
2,
0,
1,
0,
0,
1,
0,
2,
0,
0,
2
],
[
0,
2,
1,
1,
0,
0,
1,
0,
2,
0,
0,
2
],
[
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2
]
],
"rule_severities": {
"bus_definition_conflict": "error",
"bus_entry_needed": "error",
"bus_to_bus_conflict": "error",
"bus_to_net_conflict": "error",
"conflicting_netclasses": "error",
"different_unit_footprint": "error",
"different_unit_net": "error",
"duplicate_reference": "error",
"duplicate_sheet_names": "error",
"endpoint_off_grid": "warning",
"extra_units": "error",
"global_label_dangling": "warning",
"hier_label_mismatch": "error",
"label_dangling": "error",
"lib_symbol_issues": "warning",
"missing_bidi_pin": "warning",
"missing_input_pin": "warning",
"missing_power_pin": "error",
"missing_unit": "warning",
"multiple_net_names": "warning",
"net_not_bus_member": "warning",
"no_connect_connected": "warning",
"no_connect_dangling": "warning",
"pin_not_connected": "error",
"pin_not_driven": "error",
"pin_to_pin": "warning",
"power_pin_not_driven": "error",
"similar_labels": "warning",
"simulation_model_issue": "error",
"unannotated": "error",
"unit_value_mismatch": "error",
"unresolved_variable": "error",
"wire_dangling": "error"
}
},
"libraries": {
"pinned_footprint_libs": [],
"pinned_symbol_libs": []
},
"meta": {
"filename": "scrapeboardhat_uno.kicad_pro",
"version": 1
},
"net_settings": {
"classes": [
{
"bus_width": 12,
"clearance": 0.2,
"diff_pair_gap": 0.25,
"diff_pair_via_gap": 0.25,
"diff_pair_width": 0.2,
"line_style": 0,
"microvia_diameter": 0.3,
"microvia_drill": 0.1,
"name": "Default",
"pcb_color": "rgba(0, 0, 0, 0.000)",
"schematic_color": "rgba(0, 0, 0, 0.000)",
"track_width": 0.25,
"via_diameter": 0.8,
"via_drill": 0.4,
"wire_width": 6
}
],
"meta": {
"version": 3
},
"net_colors": null,
"netclass_assignments": null,
"netclass_patterns": []
},
"pcbnew": {
"last_paths": {
"gencad": "",
"idf": "",
"netlist": "",
"specctra_dsn": "",
"step": "",
"vrml": ""
},
"page_layout_descr_file": ""
},
"schematic": {
"annotate_start_num": 0,
"drawing": {
"dashed_lines_dash_length_ratio": 12.0,
"dashed_lines_gap_length_ratio": 3.0,
"default_line_thickness": 6.0,
"default_text_size": 50.0,
"field_names": [],
"intersheets_ref_own_page": false,
"intersheets_ref_prefix": "",
"intersheets_ref_short": false,
"intersheets_ref_show": false,
"intersheets_ref_suffix": "",
"junction_size_choice": 3,
"label_size_ratio": 0.375,
"pin_symbol_size": 25.0,
"text_offset_ratio": 0.15
},
"legacy_lib_dir": "",
"legacy_lib_list": [],
"meta": {
"version": 1
},
"net_format_name": "",
"page_layout_descr_file": "",
"plot_directory": "",
"spice_adjust_passive_values": false,
"spice_external_command": "spice \"%I\"",
"spice_save_all_currents": false,
"spice_save_all_voltages": false,
"subpart_first_id": 65,
"subpart_id_separator": 0
},
"sheets": [
[
"195130d0-ebea-4258-8e5e-5259bc202c76",
""
]
],
"text_variables": {}
}

View File

@ -0,0 +1,449 @@
(kicad_sch (version 20221206) (generator eeschema)
(uuid 195130d0-ebea-4258-8e5e-5259bc202c76)
(paper "A4")
(lib_symbols
(symbol "Connector:Screw_Terminal_01x04" (pin_names (offset 1.016) hide) (in_bom yes) (on_board yes)
(property "Reference" "J" (at 0 5.08 0)
(effects (font (size 1.27 1.27)))
)
(property "Value" "Screw_Terminal_01x04" (at 0 -7.62 0)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" "" (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_keywords" "screw terminal" (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_description" "Generic screw terminal, single row, 01x04, script generated (kicad-library-utils/schlib/autogen/connector/)" (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_fp_filters" "TerminalBlock*:*" (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(symbol "Screw_Terminal_01x04_1_1"
(rectangle (start -1.27 3.81) (end 1.27 -6.35)
(stroke (width 0.254) (type default))
(fill (type background))
)
(circle (center 0 -5.08) (radius 0.635)
(stroke (width 0.1524) (type default))
(fill (type none))
)
(circle (center 0 -2.54) (radius 0.635)
(stroke (width 0.1524) (type default))
(fill (type none))
)
(polyline
(pts
(xy -0.5334 -4.7498)
(xy 0.3302 -5.588)
)
(stroke (width 0.1524) (type default))
(fill (type none))
)
(polyline
(pts
(xy -0.5334 -2.2098)
(xy 0.3302 -3.048)
)
(stroke (width 0.1524) (type default))
(fill (type none))
)
(polyline
(pts
(xy -0.5334 0.3302)
(xy 0.3302 -0.508)
)
(stroke (width 0.1524) (type default))
(fill (type none))
)
(polyline
(pts
(xy -0.5334 2.8702)
(xy 0.3302 2.032)
)
(stroke (width 0.1524) (type default))
(fill (type none))
)
(polyline
(pts
(xy -0.3556 -4.572)
(xy 0.508 -5.4102)
)
(stroke (width 0.1524) (type default))
(fill (type none))
)
(polyline
(pts
(xy -0.3556 -2.032)
(xy 0.508 -2.8702)
)
(stroke (width 0.1524) (type default))
(fill (type none))
)
(polyline
(pts
(xy -0.3556 0.508)
(xy 0.508 -0.3302)
)
(stroke (width 0.1524) (type default))
(fill (type none))
)
(polyline
(pts
(xy -0.3556 3.048)
(xy 0.508 2.2098)
)
(stroke (width 0.1524) (type default))
(fill (type none))
)
(circle (center 0 0) (radius 0.635)
(stroke (width 0.1524) (type default))
(fill (type none))
)
(circle (center 0 2.54) (radius 0.635)
(stroke (width 0.1524) (type default))
(fill (type none))
)
(pin passive line (at -5.08 2.54 0) (length 3.81)
(name "Pin_1" (effects (font (size 1.27 1.27))))
(number "1" (effects (font (size 1.27 1.27))))
)
(pin passive line (at -5.08 0 0) (length 3.81)
(name "Pin_2" (effects (font (size 1.27 1.27))))
(number "2" (effects (font (size 1.27 1.27))))
)
(pin passive line (at -5.08 -2.54 0) (length 3.81)
(name "Pin_3" (effects (font (size 1.27 1.27))))
(number "3" (effects (font (size 1.27 1.27))))
)
(pin passive line (at -5.08 -5.08 0) (length 3.81)
(name "Pin_4" (effects (font (size 1.27 1.27))))
(number "4" (effects (font (size 1.27 1.27))))
)
)
)
(symbol "Connector_Generic:Conn_01x04" (pin_names (offset 1.016) hide) (in_bom yes) (on_board yes)
(property "Reference" "J" (at 0 5.08 0)
(effects (font (size 1.27 1.27)))
)
(property "Value" "Conn_01x04" (at 0 -7.62 0)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" "" (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_keywords" "connector" (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_description" "Generic connector, single row, 01x04, script generated (kicad-library-utils/schlib/autogen/connector/)" (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_fp_filters" "Connector*:*_1x??_*" (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(symbol "Conn_01x04_1_1"
(rectangle (start -1.27 -4.953) (end 0 -5.207)
(stroke (width 0.1524) (type default))
(fill (type none))
)
(rectangle (start -1.27 -2.413) (end 0 -2.667)
(stroke (width 0.1524) (type default))
(fill (type none))
)
(rectangle (start -1.27 0.127) (end 0 -0.127)
(stroke (width 0.1524) (type default))
(fill (type none))
)
(rectangle (start -1.27 2.667) (end 0 2.413)
(stroke (width 0.1524) (type default))
(fill (type none))
)
(rectangle (start -1.27 3.81) (end 1.27 -6.35)
(stroke (width 0.254) (type default))
(fill (type background))
)
(pin passive line (at -5.08 2.54 0) (length 3.81)
(name "Pin_1" (effects (font (size 1.27 1.27))))
(number "1" (effects (font (size 1.27 1.27))))
)
(pin passive line (at -5.08 0 0) (length 3.81)
(name "Pin_2" (effects (font (size 1.27 1.27))))
(number "2" (effects (font (size 1.27 1.27))))
)
(pin passive line (at -5.08 -2.54 0) (length 3.81)
(name "Pin_3" (effects (font (size 1.27 1.27))))
(number "3" (effects (font (size 1.27 1.27))))
)
(pin passive line (at -5.08 -5.08 0) (length 3.81)
(name "Pin_4" (effects (font (size 1.27 1.27))))
(number "4" (effects (font (size 1.27 1.27))))
)
)
)
(symbol "Device:R" (pin_numbers hide) (pin_names (offset 0)) (in_bom yes) (on_board yes)
(property "Reference" "R" (at 2.032 0 90)
(effects (font (size 1.27 1.27)))
)
(property "Value" "R" (at 0 0 90)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" "" (at -1.778 0 90)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_keywords" "R res resistor" (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_description" "Resistor" (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_fp_filters" "R_*" (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(symbol "R_0_1"
(rectangle (start -1.016 -2.54) (end 1.016 2.54)
(stroke (width 0.254) (type default))
(fill (type none))
)
)
(symbol "R_1_1"
(pin passive line (at 0 3.81 270) (length 1.27)
(name "~" (effects (font (size 1.27 1.27))))
(number "1" (effects (font (size 1.27 1.27))))
)
(pin passive line (at 0 -3.81 90) (length 1.27)
(name "~" (effects (font (size 1.27 1.27))))
(number "2" (effects (font (size 1.27 1.27))))
)
)
)
)
(wire (pts (xy 128.27 87.63) (xy 133.35 87.63))
(stroke (width 0) (type default))
(uuid 42d05a19-f4dc-402d-aeff-f23947d74f14)
)
(wire (pts (xy 128.27 80.01) (xy 133.35 80.01))
(stroke (width 0) (type default))
(uuid 9f33ca07-d471-4296-8415-4f0477da0f66)
)
(wire (pts (xy 113.03 87.63) (xy 120.65 87.63))
(stroke (width 0) (type default))
(uuid aaad9ee8-fb49-4134-aae4-c2176209f148)
)
(wire (pts (xy 128.27 82.55) (xy 133.35 82.55))
(stroke (width 0) (type default))
(uuid dbba668a-a10e-4c23-b338-13b92cb499e8)
)
(wire (pts (xy 113.03 80.01) (xy 120.65 80.01))
(stroke (width 0) (type default))
(uuid e5015bf5-37de-40d3-a024-e35edb77fe4c)
)
(wire (pts (xy 113.03 82.55) (xy 120.65 82.55))
(stroke (width 0) (type default))
(uuid f399897a-b451-41c0-b517-803099b32c72)
)
(wire (pts (xy 128.27 85.09) (xy 133.35 85.09))
(stroke (width 0) (type default))
(uuid f5c37a3a-68c5-4892-8914-2eb6482c66b4)
)
(wire (pts (xy 113.03 85.09) (xy 120.65 85.09))
(stroke (width 0) (type default))
(uuid f7226f80-a25f-4965-868a-cb97db855a28)
)
(label "PIN3" (at 114.3 82.55 0) (fields_autoplaced)
(effects (font (size 1.27 1.27)) (justify left bottom))
(uuid 28ccf20f-4834-451d-a5ce-45a3958ef774)
)
(label "PIN4" (at 114.3 85.09 0) (fields_autoplaced)
(effects (font (size 1.27 1.27)) (justify left bottom))
(uuid 3e1d6fe7-2b7c-4cc1-ac2f-bb83f1e814d2)
)
(label "PIN2" (at 114.3 80.01 0) (fields_autoplaced)
(effects (font (size 1.27 1.27)) (justify left bottom))
(uuid 93a6a7d8-62d2-4b9e-8fc6-5bf2ac146a19)
)
(label "PIN5" (at 114.3 87.63 0) (fields_autoplaced)
(effects (font (size 1.27 1.27)) (justify left bottom))
(uuid fbda4e07-87f8-4ddc-81e1-b860c91df8cf)
)
(symbol (lib_id "Device:R") (at 124.46 82.55 270) (unit 1)
(in_bom yes) (on_board yes) (dnp no)
(uuid 0111c824-1332-4ce4-9b62-513acee8652a)
(property "Reference" "R6" (at 124.46 77.47 90)
(effects (font (size 1.27 1.27)) hide)
)
(property "Value" "4.7K" (at 124.46 82.55 90)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" "Resistor_THT:R_Axial_DIN0204_L3.6mm_D1.6mm_P5.08mm_Horizontal" (at 124.46 80.772 90)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (at 124.46 82.55 0)
(effects (font (size 1.27 1.27)) hide)
)
(pin "1" (uuid d12e2229-a5c0-48ec-ba08-441621a20e93))
(pin "2" (uuid 3f0c725a-d800-4a87-afa6-69f72aea0964))
(instances
(project "scrapeboard_hat"
(path "/195130d0-ebea-4258-8e5e-5259bc202c76"
(reference "R6") (unit 1)
)
)
)
)
(symbol (lib_id "Device:R") (at 124.46 80.01 270) (unit 1)
(in_bom yes) (on_board yes) (dnp no)
(uuid 692ab5a4-bfca-4d07-af0a-e1d873fc6777)
(property "Reference" "R7" (at 124.46 74.93 90)
(effects (font (size 1.27 1.27)) hide)
)
(property "Value" "4.7K" (at 124.46 80.01 90)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" "Resistor_THT:R_Axial_DIN0204_L3.6mm_D1.6mm_P5.08mm_Horizontal" (at 124.46 78.232 90)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (at 124.46 80.01 0)
(effects (font (size 1.27 1.27)) hide)
)
(pin "1" (uuid 78a58fc8-b241-4b18-8b27-0d199ed43511))
(pin "2" (uuid 93062795-9550-42a6-a88d-1d44884f946c))
(instances
(project "scrapeboard_hat"
(path "/195130d0-ebea-4258-8e5e-5259bc202c76"
(reference "R7") (unit 1)
)
)
)
)
(symbol (lib_id "Connector_Generic:Conn_01x04") (at 107.95 85.09 180) (unit 1)
(in_bom yes) (on_board yes) (dnp no)
(uuid b61ae372-5cc8-455a-b68f-975e70a349db)
(property "Reference" "J3" (at 105.41 84.455 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Value" "PI_OR_ARDUINO_HEADER" (at 105.41 81.915 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Footprint" "Connector_PinSocket_2.54mm:PinSocket_1x04_P2.54mm_Vertical" (at 107.95 85.09 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (at 107.95 85.09 0)
(effects (font (size 1.27 1.27)) hide)
)
(pin "1" (uuid 347254f3-79ae-4acf-bc54-1becda7db6b5))
(pin "2" (uuid 4312d4d0-0062-4173-9e48-deefe1183f1e))
(pin "3" (uuid 88bd6f1c-8e3c-47a2-84f6-6a39f3def2cd))
(pin "4" (uuid a8ea1197-d7b6-4942-a74c-bfd494007c00))
(instances
(project "scrapeboard_hat"
(path "/195130d0-ebea-4258-8e5e-5259bc202c76"
(reference "J3") (unit 1)
)
)
)
)
(symbol (lib_id "Connector:Screw_Terminal_01x04") (at 138.43 82.55 0) (unit 1)
(in_bom yes) (on_board yes) (dnp no)
(uuid c9618a6f-1090-4906-9c99-a03e0182a2bd)
(property "Reference" "J1" (at 140.97 83.185 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Value" "Screw_Terminal_01x04" (at 140.97 85.725 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Footprint" "TerminalBlock_Phoenix:TerminalBlock_Phoenix_MKDS-1,5-4_1x04_P5.00mm_Horizontal" (at 138.43 82.55 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (at 138.43 82.55 0)
(effects (font (size 1.27 1.27)) hide)
)
(pin "1" (uuid e6b2c076-9102-4267-90f9-43bef0a9e5c4))
(pin "2" (uuid 423a7ac8-3525-4440-a620-8aeb96cea13d))
(pin "3" (uuid b41cb0d4-6631-45ce-a5b2-d92e3fb5a26d))
(pin "4" (uuid dc7e9a66-e758-4c49-aeca-db026d2b3b43))
(instances
(project "scrapeboard_hat"
(path "/195130d0-ebea-4258-8e5e-5259bc202c76"
(reference "J1") (unit 1)
)
)
)
)
(symbol (lib_id "Device:R") (at 124.46 87.63 270) (unit 1)
(in_bom yes) (on_board yes) (dnp no)
(uuid e1aaf9d1-3988-433f-8a79-2a9a6e0691a1)
(property "Reference" "R4" (at 124.46 82.55 90)
(effects (font (size 1.27 1.27)) hide)
)
(property "Value" "4.7K" (at 124.46 87.63 90)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" "Resistor_THT:R_Axial_DIN0204_L3.6mm_D1.6mm_P5.08mm_Horizontal" (at 124.46 85.852 90)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (at 124.46 87.63 0)
(effects (font (size 1.27 1.27)) hide)
)
(pin "1" (uuid 595d08ce-3b5d-47ea-9731-1caa456175f4))
(pin "2" (uuid c168884a-66b2-4a05-94cf-a1657c7e462d))
(instances
(project "scrapeboard_hat"
(path "/195130d0-ebea-4258-8e5e-5259bc202c76"
(reference "R4") (unit 1)
)
)
)
)
(symbol (lib_id "Device:R") (at 124.46 85.09 270) (unit 1)
(in_bom yes) (on_board yes) (dnp no)
(uuid f90bc9d3-bcde-459d-92d9-f6c2f8dbb148)
(property "Reference" "R5" (at 124.46 80.01 90)
(effects (font (size 1.27 1.27)) hide)
)
(property "Value" "4.7K" (at 124.46 85.09 90)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" "Resistor_THT:R_Axial_DIN0204_L3.6mm_D1.6mm_P5.08mm_Horizontal" (at 124.46 83.312 90)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (at 124.46 85.09 0)
(effects (font (size 1.27 1.27)) hide)
)
(pin "1" (uuid ffefd996-31e2-40ec-b2da-432fe4d868ed))
(pin "2" (uuid 0741004a-8d4b-4e72-96a2-f7a12be493ac))
(instances
(project "scrapeboard_hat"
(path "/195130d0-ebea-4258-8e5e-5259bc202c76"
(reference "R5") (unit 1)
)
)
)
)
(sheet_instances
(path "/" (page "1"))
)
)

View File

@ -0,0 +1,5 @@
(sym_lib_table
(lib (name "Connector")(type "KiCad")(uri "${KIPRJMOD}/../symbols/Connector.kicad_sym")(options "")(descr ""))
(lib (name "Connector_Generic")(type "KiCad")(uri "${KIPRJMOD}/../symbols/Connector_Generic.kicad_sym")(options "")(descr ""))
(lib (name "Device")(type "KiCad")(uri "${KIPRJMOD}/../symbols/Device.kicad_sym")(options "")(descr ""))
)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

75254
kicad/symbols/Device.kicad_sym Normal file

File diff suppressed because it is too large Load Diff

@ -1 +1 @@
Subproject commit d00e434c633f8ca45ab4fd1fb56e19d876027a1d
Subproject commit 2bbdc9a7028dd86c8a2f06a74403ffc5a1fe6d44

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,38 +0,0 @@
import pyaudio
import wave
CHUNK = 1024
FORMAT = pyaudio.paInt32
CHANNELS = 2
RATE = 44100
RECORD_SECONDS = 5
WAVE_OUTPUT_FILENAME = "output.wav"
p = pyaudio.PyAudio()
stream = p.open(format=FORMAT,
channels=CHANNELS,
rate=RATE,
input=True,
frames_per_buffer=CHUNK)
print("* recording")
frames = []
for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
data = stream.read(CHUNK)
frames.append(data)
print("* done recording")
stream.stop_stream()
stream.close()
p.terminate()
wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(RATE)
wf.writeframes(b''.join(frames))
wf.close()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 610 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 402 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 740 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

BIN
resource/qr/qr.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

BIN
resource/qr/qr_text_0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

BIN
resource/qr/qr_text_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

BIN
resource/qr/qr_text_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Some files were not shown because too many files have changed in this diff Show More