Add component photos to catalog
|
|
@ -13,28 +13,28 @@ Hver fysisk komponenttype får sit eget stabile id og en mappe med:
|
|||
|
||||
## Registrerede komponenter
|
||||
|
||||
| Komponent | Type | Interface | Produkt-id | Sketches |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| [LCD1602 med PCF8574T](lcd1602-i2c-pcf8574/README.md) | Output/display | I²C | – | [`lcd1602_i2c_demo`](../sketches/arduino-uno-r4-wifi/lcd1602_i2c_demo) |
|
||||
| [RGB LED](keyestudio-ks0032-rgb-led/README.md) | Output/lys | Digital/PWM | KS0032 | – |
|
||||
| [Mikrofon](keyestudio-ks0035-microphone/README.md) | Input/lyd | Analog | KS0035 | – |
|
||||
| [IR-modtager](keyestudio-ks0026-ir-receiver/README.md) | Input/IR | Digital | KS0026 | – |
|
||||
| [Analog temperatursensor](keyestudio-ks0033-thermistor/README.md) | Input/temperatur | Analog | KS0033 | – |
|
||||
| [DS18B20-temperatursensor](keyestudio-ks0023-ds18b20/README.md) | Input/temperatur | 1-Wire | KS0023 | – |
|
||||
| [Tiltsensor](keyestudio-ks0025-tilt/README.md) | Input/orientering | Digital | KS0025 | – |
|
||||
| [Aktiv buzzer](keyestudio-ks0018-active-buzzer/README.md) | Output/lyd | Digital | KS0018 | – |
|
||||
| [Laser-emitter](keyes-ke2054-laser-emitter/README.md) | Output/lys | Digital | KE2054 | – |
|
||||
| [Analog rotationssensor](keyestudio-ks0014-analog-rotation/README.md) | Input/position | Analog | KS0014 | – |
|
||||
| [Trykknap](keyestudio-ks0029-push-button/README.md) | Input/kontakt | Digital | KS0029 | – |
|
||||
| [IR-sender](keyestudio-ks0027-ir-transmitter/README.md) | Output/IR | Digital/PWM | KS0027 | – |
|
||||
| [Passiv buzzer](keyestudio-ks0019-passive-buzzer/README.md) | Output/lyd | Digital/tone | KS0019 | – |
|
||||
| [Knock-sensor](keyestudio-ks0024-knock/README.md) | Input/slag | Digital | KS0024 | – |
|
||||
| [Reed switch](keyestudio-ks0038-reed-switch/README.md) | Input/magnet | Digital | KS0038 | – |
|
||||
| [Pulssensor](keyestudio-ks0015-pulse-rate/README.md) | Input/optisk | Analog | KS0015 | – |
|
||||
| [Vibrationssensor](keyestudio-ks0037-vibration/README.md) | Input/vibration | Digital | KS0037 | – |
|
||||
| [Fotomodstandssensor](keyestudio-ks0028-photocell/README.md) | Input/lys | Analog | KS0028 | – |
|
||||
| [LM35-temperatursensor](keyestudio-ks0022-lm35/README.md) | Input/temperatur | Analog | KS0022 | – |
|
||||
| [Collision-/endestopsensor](keyestudio-ks0021-collision/README.md) | Input/kontakt | Digital | KS0021 | – |
|
||||
| Foto | Komponent | Type | Interface | Produkt-id | Sketches |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| – | [LCD1602 med PCF8574T](lcd1602-i2c-pcf8574/README.md) | Output/display | I²C | – | [`lcd1602_i2c_demo`](../sketches/arduino-uno-r4-wifi/lcd1602_i2c_demo) |
|
||||
| <img src="keyestudio-ks0032-rgb-led/thumbnail.webp" width="120" alt="RGB LED"> | [RGB LED](keyestudio-ks0032-rgb-led/README.md) | Output/lys | Digital/PWM | KS0032 | – |
|
||||
| <img src="keyestudio-ks0035-microphone/thumbnail.webp" width="120" alt="Mikrofon"> | [Mikrofon](keyestudio-ks0035-microphone/README.md) | Input/lyd | Analog | KS0035 | – |
|
||||
| <img src="keyestudio-ks0026-ir-receiver/thumbnail.webp" width="120" alt="IR-modtager"> | [IR-modtager](keyestudio-ks0026-ir-receiver/README.md) | Input/IR | Digital | KS0026 | – |
|
||||
| <img src="keyestudio-ks0033-thermistor/thumbnail.webp" width="120" alt="Analog temperatursensor"> | [Analog temperatursensor](keyestudio-ks0033-thermistor/README.md) | Input/temperatur | Analog | KS0033 | – |
|
||||
| <img src="keyestudio-ks0023-ds18b20/thumbnail.webp" width="120" alt="DS18B20-temperatursensor"> | [DS18B20-temperatursensor](keyestudio-ks0023-ds18b20/README.md) | Input/temperatur | 1-Wire | KS0023 | – |
|
||||
| <img src="keyestudio-ks0025-tilt/thumbnail.webp" width="120" alt="Tiltsensor"> | [Tiltsensor](keyestudio-ks0025-tilt/README.md) | Input/orientering | Digital | KS0025 | – |
|
||||
| <img src="keyestudio-ks0018-active-buzzer/thumbnail.webp" width="120" alt="Aktiv buzzer"> | [Aktiv buzzer](keyestudio-ks0018-active-buzzer/README.md) | Output/lyd | Digital | KS0018 | – |
|
||||
| <img src="keyes-ke2054-laser-emitter/thumbnail.webp" width="120" alt="Laser-emitter"> | [Laser-emitter](keyes-ke2054-laser-emitter/README.md) | Output/lys | Digital | KE2054 | – |
|
||||
| <img src="keyestudio-ks0014-analog-rotation/thumbnail.webp" width="120" alt="Analog rotationssensor"> | [Analog rotationssensor](keyestudio-ks0014-analog-rotation/README.md) | Input/position | Analog | KS0014 | – |
|
||||
| <img src="keyestudio-ks0029-push-button/thumbnail.webp" width="120" alt="Trykknap"> | [Trykknap](keyestudio-ks0029-push-button/README.md) | Input/kontakt | Digital | KS0029 | – |
|
||||
| <img src="keyestudio-ks0027-ir-transmitter/thumbnail.webp" width="120" alt="IR-sender"> | [IR-sender](keyestudio-ks0027-ir-transmitter/README.md) | Output/IR | Digital/PWM | KS0027 | – |
|
||||
| <img src="keyestudio-ks0019-passive-buzzer/thumbnail.webp" width="120" alt="Passiv buzzer"> | [Passiv buzzer](keyestudio-ks0019-passive-buzzer/README.md) | Output/lyd | Digital/tone | KS0019 | – |
|
||||
| <img src="keyestudio-ks0024-knock/thumbnail.webp" width="120" alt="Knock-sensor"> | [Knock-sensor](keyestudio-ks0024-knock/README.md) | Input/slag | Digital | KS0024 | – |
|
||||
| <img src="keyestudio-ks0038-reed-switch/thumbnail.webp" width="120" alt="Reed switch"> | [Reed switch](keyestudio-ks0038-reed-switch/README.md) | Input/magnet | Digital | KS0038 | – |
|
||||
| <img src="keyestudio-ks0015-pulse-rate/thumbnail.webp" width="120" alt="Pulssensor"> | [Pulssensor](keyestudio-ks0015-pulse-rate/README.md) | Input/optisk | Analog | KS0015 | – |
|
||||
| <img src="keyestudio-ks0037-vibration/thumbnail.webp" width="120" alt="Vibrationssensor"> | [Vibrationssensor](keyestudio-ks0037-vibration/README.md) | Input/vibration | Digital | KS0037 | – |
|
||||
| <img src="keyestudio-ks0028-photocell/thumbnail.webp" width="120" alt="Fotomodstandssensor"> | [Fotomodstandssensor](keyestudio-ks0028-photocell/README.md) | Input/lys | Analog | KS0028 | – |
|
||||
| <img src="keyestudio-ks0022-lm35/thumbnail.webp" width="120" alt="LM35-temperatursensor"> | [LM35-temperatursensor](keyestudio-ks0022-lm35/README.md) | Input/temperatur | Analog | KS0022 | – |
|
||||
| <img src="keyestudio-ks0021-collision/thumbnail.webp" width="120" alt="Collision-/endestopsensor"> | [Collision-/endestopsensor](keyestudio-ks0021-collision/README.md) | Input/kontakt | Digital | KS0021 | – |
|
||||
|
||||
## Navngivning
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
# Keyes KE2054 laser-emittermodul
|
||||
|
||||

|
||||
|
||||
## Identifikation
|
||||
|
||||
| Felt | Værdi |
|
||||
|
|
|
|||
BIN
components/keyes-ke2054-laser-emitter/image.webp
Normal file
|
After Width: | Height: | Size: 206 KiB |
BIN
components/keyes-ke2054-laser-emitter/thumbnail.webp
Normal file
|
After Width: | Height: | Size: 14 KiB |
|
|
@ -1,5 +1,7 @@
|
|||
# Keyestudio KS0014 analog rotationssensor
|
||||
|
||||

|
||||
|
||||
## Identifikation
|
||||
|
||||
| Felt | Værdi |
|
||||
|
|
|
|||
BIN
components/keyestudio-ks0014-analog-rotation/image.webp
Normal file
|
After Width: | Height: | Size: 222 KiB |
BIN
components/keyestudio-ks0014-analog-rotation/thumbnail.webp
Normal file
|
After Width: | Height: | Size: 14 KiB |
|
|
@ -1,5 +1,7 @@
|
|||
# Keyestudio KS0015 pulssensor
|
||||
|
||||

|
||||
|
||||
## Identifikation
|
||||
|
||||
| Felt | Værdi |
|
||||
|
|
|
|||
BIN
components/keyestudio-ks0015-pulse-rate/image.webp
Normal file
|
After Width: | Height: | Size: 225 KiB |
BIN
components/keyestudio-ks0015-pulse-rate/thumbnail.webp
Normal file
|
After Width: | Height: | Size: 14 KiB |
|
|
@ -1,5 +1,7 @@
|
|||
# Keyestudio KS0018 aktiv buzzer
|
||||
|
||||

|
||||
|
||||
## Identifikation
|
||||
|
||||
| Felt | Værdi |
|
||||
|
|
|
|||
BIN
components/keyestudio-ks0018-active-buzzer/image.webp
Normal file
|
After Width: | Height: | Size: 236 KiB |
BIN
components/keyestudio-ks0018-active-buzzer/thumbnail.webp
Normal file
|
After Width: | Height: | Size: 15 KiB |
|
|
@ -1,5 +1,7 @@
|
|||
# Keyestudio KS0019 passiv buzzer
|
||||
|
||||

|
||||
|
||||
## Identifikation
|
||||
|
||||
| Felt | Værdi |
|
||||
|
|
|
|||
BIN
components/keyestudio-ks0019-passive-buzzer/image.webp
Normal file
|
After Width: | Height: | Size: 253 KiB |
BIN
components/keyestudio-ks0019-passive-buzzer/thumbnail.webp
Normal file
|
After Width: | Height: | Size: 15 KiB |
|
|
@ -1,5 +1,7 @@
|
|||
# Keyestudio KS0021 collision-/endestopsensor
|
||||
|
||||

|
||||
|
||||
## Identifikation
|
||||
|
||||
| Felt | Værdi |
|
||||
|
|
|
|||
BIN
components/keyestudio-ks0021-collision/image.webp
Normal file
|
After Width: | Height: | Size: 227 KiB |
BIN
components/keyestudio-ks0021-collision/thumbnail.webp
Normal file
|
After Width: | Height: | Size: 13 KiB |
|
|
@ -1,5 +1,7 @@
|
|||
# Keyestudio KS0022 LM35-temperatursensor
|
||||
|
||||

|
||||
|
||||
## Identifikation
|
||||
|
||||
| Felt | Værdi |
|
||||
|
|
|
|||
BIN
components/keyestudio-ks0022-lm35/image.webp
Normal file
|
After Width: | Height: | Size: 270 KiB |
BIN
components/keyestudio-ks0022-lm35/thumbnail.webp
Normal file
|
After Width: | Height: | Size: 16 KiB |
|
|
@ -1,5 +1,7 @@
|
|||
# Keyestudio KS0023 DS18B20-temperatursensor
|
||||
|
||||

|
||||
|
||||
## Identifikation
|
||||
|
||||
| Felt | Værdi |
|
||||
|
|
|
|||
BIN
components/keyestudio-ks0023-ds18b20/image.webp
Normal file
|
After Width: | Height: | Size: 151 KiB |
BIN
components/keyestudio-ks0023-ds18b20/thumbnail.webp
Normal file
|
After Width: | Height: | Size: 14 KiB |
|
|
@ -1,5 +1,7 @@
|
|||
# Keyestudio KS0024 knock-sensor
|
||||
|
||||

|
||||
|
||||
## Identifikation
|
||||
|
||||
| Felt | Værdi |
|
||||
|
|
|
|||
BIN
components/keyestudio-ks0024-knock/image.webp
Normal file
|
After Width: | Height: | Size: 254 KiB |
BIN
components/keyestudio-ks0024-knock/thumbnail.webp
Normal file
|
After Width: | Height: | Size: 15 KiB |
|
|
@ -1,5 +1,7 @@
|
|||
# Keyestudio KS0025 digital tiltsensor
|
||||
|
||||

|
||||
|
||||
## Identifikation
|
||||
|
||||
| Felt | Værdi |
|
||||
|
|
|
|||
BIN
components/keyestudio-ks0025-tilt/image.webp
Normal file
|
After Width: | Height: | Size: 196 KiB |
BIN
components/keyestudio-ks0025-tilt/thumbnail.webp
Normal file
|
After Width: | Height: | Size: 14 KiB |
|
|
@ -1,5 +1,7 @@
|
|||
# Keyestudio KS0026 digital IR-modtager
|
||||
|
||||

|
||||
|
||||
## Identifikation
|
||||
|
||||
| Felt | Værdi |
|
||||
|
|
|
|||
BIN
components/keyestudio-ks0026-ir-receiver/image.webp
Normal file
|
After Width: | Height: | Size: 235 KiB |
BIN
components/keyestudio-ks0026-ir-receiver/thumbnail.webp
Normal file
|
After Width: | Height: | Size: 14 KiB |
|
|
@ -1,5 +1,7 @@
|
|||
# Keyestudio KS0027 digital IR-sender
|
||||
|
||||

|
||||
|
||||
## Identifikation
|
||||
|
||||
| Felt | Værdi |
|
||||
|
|
|
|||
BIN
components/keyestudio-ks0027-ir-transmitter/image.webp
Normal file
|
After Width: | Height: | Size: 243 KiB |
BIN
components/keyestudio-ks0027-ir-transmitter/thumbnail.webp
Normal file
|
After Width: | Height: | Size: 14 KiB |
|
|
@ -1,5 +1,7 @@
|
|||
# Keyestudio KS0028 fotomodstandssensor
|
||||
|
||||

|
||||
|
||||
## Identifikation
|
||||
|
||||
| Felt | Værdi |
|
||||
|
|
|
|||
BIN
components/keyestudio-ks0028-photocell/image.webp
Normal file
|
After Width: | Height: | Size: 219 KiB |
BIN
components/keyestudio-ks0028-photocell/thumbnail.webp
Normal file
|
After Width: | Height: | Size: 13 KiB |
|
|
@ -1,5 +1,7 @@
|
|||
# Keyestudio KS0029 trykknapmodul
|
||||
|
||||

|
||||
|
||||
## Identifikation
|
||||
|
||||
| Felt | Værdi |
|
||||
|
|
|
|||
BIN
components/keyestudio-ks0029-push-button/image.webp
Normal file
|
After Width: | Height: | Size: 216 KiB |
BIN
components/keyestudio-ks0029-push-button/thumbnail.webp
Normal file
|
After Width: | Height: | Size: 14 KiB |
|
|
@ -1,5 +1,7 @@
|
|||
# Keyestudio KS0032 RGB LED-modul
|
||||
|
||||

|
||||
|
||||
## Identifikation
|
||||
|
||||
| Felt | Værdi |
|
||||
|
|
|
|||
BIN
components/keyestudio-ks0032-rgb-led/image.webp
Normal file
|
After Width: | Height: | Size: 167 KiB |
BIN
components/keyestudio-ks0032-rgb-led/thumbnail.webp
Normal file
|
After Width: | Height: | Size: 11 KiB |
|
|
@ -1,5 +1,7 @@
|
|||
# Keyestudio KS0033 analog temperatursensor
|
||||
|
||||

|
||||
|
||||
## Identifikation
|
||||
|
||||
| Felt | Værdi |
|
||||
|
|
|
|||
BIN
components/keyestudio-ks0033-thermistor/image.webp
Normal file
|
After Width: | Height: | Size: 191 KiB |
BIN
components/keyestudio-ks0033-thermistor/thumbnail.webp
Normal file
|
After Width: | Height: | Size: 13 KiB |
|
|
@ -1,5 +1,7 @@
|
|||
# Keyestudio KS0035 mikrofonmodul
|
||||
|
||||

|
||||
|
||||
## Identifikation
|
||||
|
||||
| Felt | Værdi |
|
||||
|
|
|
|||
BIN
components/keyestudio-ks0035-microphone/image.webp
Normal file
|
After Width: | Height: | Size: 203 KiB |
BIN
components/keyestudio-ks0035-microphone/thumbnail.webp
Normal file
|
After Width: | Height: | Size: 13 KiB |
|
|
@ -1,5 +1,7 @@
|
|||
# Keyestudio KS0037 vibrationssensor
|
||||
|
||||

|
||||
|
||||
## Identifikation
|
||||
|
||||
| Felt | Værdi |
|
||||
|
|
|
|||
BIN
components/keyestudio-ks0037-vibration/image.webp
Normal file
|
After Width: | Height: | Size: 191 KiB |
BIN
components/keyestudio-ks0037-vibration/thumbnail.webp
Normal file
|
After Width: | Height: | Size: 15 KiB |
|
|
@ -1,5 +1,7 @@
|
|||
# Keyestudio KS0038 reed switch
|
||||
|
||||

|
||||
|
||||
## Identifikation
|
||||
|
||||
| Felt | Værdi |
|
||||
|
|
|
|||
BIN
components/keyestudio-ks0038-reed-switch/image.webp
Normal file
|
After Width: | Height: | Size: 196 KiB |
BIN
components/keyestudio-ks0038-reed-switch/thumbnail.webp
Normal file
|
After Width: | Height: | Size: 14 KiB |
88
scripts/process_component_images.py
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
"""Crop the photographed Keyes modules and create README-ready WebP assets."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
|
||||
import numpy as np
|
||||
from PIL import Image, ImageOps
|
||||
|
||||
|
||||
COMPONENTS_DIR = Path(__file__).resolve().parents[1] / "components"
|
||||
|
||||
PHOTOS = {
|
||||
"keyestudio-ks0037-vibration": "IMG_20261024_203426885_HDR.jpg",
|
||||
"keyestudio-ks0019-passive-buzzer": "IMG_20261024_203440803_HDR.jpg",
|
||||
"keyes-ke2054-laser-emitter": "IMG_20261024_203450304_HDR.jpg",
|
||||
"keyestudio-ks0033-thermistor": "IMG_20261024_203506743_HDR.jpg",
|
||||
"keyestudio-ks0024-knock": "IMG_20261024_203515354_HDR.jpg",
|
||||
"keyestudio-ks0028-photocell": "IMG_20261024_203524523_HDR.jpg",
|
||||
"keyestudio-ks0014-analog-rotation": "IMG_20261024_203538683_HDR.jpg",
|
||||
"keyestudio-ks0023-ds18b20": "IMG_20261024_203559430_BURST000_COVER.jpg",
|
||||
"keyestudio-ks0029-push-button": "IMG_20261024_203615490_HDR.jpg",
|
||||
"keyestudio-ks0038-reed-switch": "IMG_20261024_203624532_HDR.jpg",
|
||||
"keyestudio-ks0035-microphone": "IMG_20261024_203651498_HDR.jpg",
|
||||
"keyestudio-ks0025-tilt": "IMG_20261024_203705101_HDR.jpg",
|
||||
"keyestudio-ks0026-ir-receiver": "IMG_20261024_203723952_HDR.jpg",
|
||||
"keyestudio-ks0018-active-buzzer": "IMG_20261024_203734801_HDR.jpg",
|
||||
"keyestudio-ks0027-ir-transmitter": "IMG_20261024_203743461_HDR.jpg",
|
||||
"keyestudio-ks0015-pulse-rate": "IMG_20261024_203754423_HDR.jpg",
|
||||
"keyestudio-ks0022-lm35": "IMG_20261024_203804368_HDR.jpg",
|
||||
"keyestudio-ks0021-collision": "IMG_20261024_203811921_HDR.jpg",
|
||||
"keyestudio-ks0032-rgb-led": "IMG_20261024_203820913_HDR.jpg",
|
||||
}
|
||||
|
||||
|
||||
def crop_around_board(image: Image.Image) -> Image.Image:
|
||||
"""Find the red PCB, then retain generous room for protruding components."""
|
||||
pixels = np.asarray(image.convert("RGB"))
|
||||
red = pixels[:, :, 0].astype(np.int16)
|
||||
green = pixels[:, :, 1].astype(np.int16)
|
||||
blue = pixels[:, :, 2].astype(np.int16)
|
||||
mask = (red > 125) & (red > green * 1.35) & (red > blue * 1.20)
|
||||
ys, xs = np.nonzero(mask)
|
||||
if len(xs) < 10_000:
|
||||
raise RuntimeError("Could not locate the red PCB")
|
||||
|
||||
left, right = int(np.percentile(xs, 0.2)), int(np.percentile(xs, 99.8))
|
||||
top, bottom = int(np.percentile(ys, 0.2)), int(np.percentile(ys, 99.8))
|
||||
width, height = right - left, bottom - top
|
||||
pad_x, pad_y = int(width * 0.22), int(height * 0.18)
|
||||
box = (
|
||||
max(0, left - pad_x),
|
||||
max(0, top - pad_y),
|
||||
min(image.width, right + pad_x),
|
||||
min(image.height, bottom + pad_y),
|
||||
)
|
||||
return image.crop(box)
|
||||
|
||||
|
||||
def fit(image: Image.Image, max_size: tuple[int, int]) -> Image.Image:
|
||||
result = image.copy()
|
||||
result.thumbnail(max_size, Image.Resampling.LANCZOS)
|
||||
return result
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("source_dir", type=Path, help="Directory containing the source JPEGs")
|
||||
args = parser.parse_args()
|
||||
|
||||
for component, filename in PHOTOS.items():
|
||||
source = args.source_dir / filename
|
||||
destination = COMPONENTS_DIR / component
|
||||
with Image.open(source) as opened:
|
||||
image = ImageOps.exif_transpose(opened).convert("RGB")
|
||||
crop = crop_around_board(image)
|
||||
fit(crop, (1400, 1050)).save(
|
||||
destination / "image.webp", "WEBP", quality=90, method=6
|
||||
)
|
||||
fit(crop, (240, 180)).save(
|
||||
destination / "thumbnail.webp", "WEBP", quality=90, method=6
|
||||
)
|
||||
print(f"{component}: {filename}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||