Initial commit

This commit is contained in:
s3lph 2019-04-18 23:02:20 +02:00
commit 90d306ebb2
16 changed files with 38373 additions and 0 deletions

6
.gitignore vendored Normal file
View file

@ -0,0 +1,6 @@
*.pyc
**/__pycache__
**/venv
**/.idea
*~

View file

@ -0,0 +1,233 @@
#include <NeoPixelBus.h>
#define DOUBLE_SIDE 0
#define DOUBLE_SIDE_MIRROR 0
#define IMAGE_HEIGHT (7)
#define IMAGE_WIDTH (48)
#define N_ROT_SLICES (48)
#define WS_PIN (8)
#define WS_VCC (9)
#define WS_GND (7)
#define HALL_PIN (2)
static const RgbColor off(0,0,0);
#if DOUBLE_SIDE
#define WS_PIXEL_COUNT (2*IMAGE_HEIGHT)
#else
#define WS_PIXEL_COUNT (IMAGE_HEIGHT)
#endif
#define IMAGE_FAIRYDUST
//#define IMAGE_CYBER
#ifdef IMAGE_CYBER
#define SKEW_RATE (0)
static const __restrict__ RgbColor PALETTE[] = {
RgbColor(0,0,0), // black
RgbColor(20,20,0) // yellow
};
static const __restrict__ uint8_t IMAGE[IMAGE_WIDTH][IMAGE_HEIGHT] = {
{1,1,1,1,1,1,1},
{1,1,1,1,1,1,1},
{1,1,1,1,1,1,1},
{1,1,1,1,1,1,1},
{1,1,1,1,1,1,1},
{1,1,1,1,1,1,1},
{1,1,1,1,1,1,1},
{1,1,1,1,1,1,1},
{1,1,1,1,1,1,1},
{1,1,1,1,1,1,1},
{1,1,1,1,1,1,1},
{1,1,1,1,1,1,1},
{1,1,1,1,1,1,1},
{1,1,1,1,1,1,1},
{1,1,0,1,0,0,1},
{1,0,1,0,1,1,1},
{1,0,0,0,0,0,1},
{1,1,1,1,1,1,1},
{1,0,1,0,1,0,1},
{1,0,1,0,1,0,1},
{1,0,0,0,0,0,1},
{1,1,1,1,1,1,1},
{1,1,0,1,0,1,1},
{1,0,1,0,1,0,1},
{1,0,0,0,0,0,1},
{1,1,1,1,1,1,1},
{1,0,0,1,1,1,1},
{1,1,1,0,0,0,1},
{1,0,0,1,1,1,1},
{1,1,1,1,1,1,1},
{1,0,1,1,1,0,1},
{1,0,1,1,1,0,1},
{1,1,0,0,0,1,1},
{1,1,1,1,1,1,1},
{1,1,1,1,1,1,1},
{1,1,1,1,1,1,1},
{1,1,1,1,1,1,1},
{1,1,1,1,1,1,1},
{1,1,1,1,1,1,1},
{1,1,1,1,1,1,1},
{1,1,1,1,1,1,1},
{1,1,1,1,1,1,1},
{1,1,1,1,1,1,1},
{1,1,1,1,1,1,1},
{1,1,1,1,1,1,1},
{1,1,1,1,1,1,1},
{1,1,1,1,1,1,1},
{1,1,1,1,1,1,1}
};
#elif defined(IMAGE_FAIRYDUST)
#define SKEW_RATE (100)
static const RgbColor PALETTE[] = {
RgbColor(0,0,0), // black
RgbColor(0,128,0), // green
RgbColor(255,180,0), // orange
RgbColor(255,0,0) // red
};
static const __restrict__ uint8_t IMAGE[IMAGE_WIDTH][IMAGE_HEIGHT] = {
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,1,0,0,0},
{0,0,1,2,1,0,0},
{0,1,2,1,1,1,0},
{0,1,2,1,1,1,0},
{1,2,2,2,1,1,1},
{1,2,2,2,1,1,1},
{0,1,2,1,1,1,0},
{0,1,2,1,1,1,0},
{0,0,1,2,1,0,0},
{0,1,0,1,0,1,0},
{1,1,0,3,0,1,1},
{1,1,3,3,3,1,1},
{1,0,3,3,3,0,1},
{0,0,0,3,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0}
};
#endif
static NeoPixelBus<NeoGrbFeature, Neo800KbpsMethod> ws2812(WS_PIXEL_COUNT, WS_PIN);
static volatile uint32_t last_hall = 0UL;
static volatile uint32_t last_hall_diff = 1000UL;
#if SKEW_RATE
static uint16_t skew = 0U;
static uint32_t last_skew = 0UL;
#endif
void update_hall_timestamp() {
uint32_t now = millis();
last_hall_diff = now - last_hall;
last_hall = now;
}
void setup() {
// Setup output pins
pinMode(WS_PIN, OUTPUT);
pinMode(HALL_PIN, INPUT);
// Setup power supply for WS2812 strip
// (Yes, I know I shouldn't supply power from the Arduino I/O pins,
// but I'm running the LEDs at a fraction of their max power draw)
pinMode(WS_VCC, OUTPUT);
pinMode(WS_GND, OUTPUT);
digitalWrite(WS_VCC, HIGH);
digitalWrite(WS_GND, LOW);
// Setup WS2812 strup
ws2812.Begin();
ws2812.Show();
// Setup hall sensor interrupt
attachInterrupt(
digitalPinToInterrupt(HALL_PIN),
update_hall_timestamp,
FALLING
);
}
void loop() {
// Get the current time
uint32_t now = millis();
// Turn the LEDs off if no sensor input was received for 3s
if ((now - last_hall) > 3000UL) {
for (size_t i = 0; i < IMAGE_HEIGHT; ++i) {
ws2812.SetPixelColor(i, off);
#if DOUBLE_SIDE
ws2812.SetPixelColor(IMAGE_HEIGHT + i, off);
#endif
}
ws2812.Show();
// Only re-check after a second
delay(1000);
return;
}
// Get the slice to show at the current time, based on the time between the last two sensor events
uint16_t slice = (uint16_t) (((now - last_hall) * N_ROT_SLICES / last_hall_diff) % N_ROT_SLICES);
#if SKEW_RATE
// Increment the skew offset when it's time for the next skew step
if (now - last_skew > SKEW_RATE) {
skew = (skew + 1) % N_ROT_SLICES;
last_skew = now;
}
// Add the current skew offset to the slice index
slice = (uint16_t) ((slice + skew) % N_ROT_SLICES);
#endif
// Display the current slice (row) of the image
for (size_t i = 0; i < IMAGE_HEIGHT; ++i) {
ws2812.SetPixelColor(i, PALETTE[IMAGE[slice][i]]);
#if DOUBLE_SIDE
#if DOUBLE_SIDE_MIRROR
ws2812.SetPixelColor(IMAGE_HEIGHT+i, PALETTE[IMAGE[N_ROT_SLICES-slice][i]]);
#else
ws2812.SetPixelColor(IMAGE_HEIGHT+i, PALETTE[IMAGE[slice][i]]);
#endif
#endif
}
ws2812.Show();
}

53
openscad/arduino_isp.scad Normal file
View file

@ -0,0 +1,53 @@
module arduino_nano() {
union() {
// PCB
cube([18,44,2]);
// ISP Header
translate([5.25,0,-2]) {
cube([7.5,10,12]);
}
// USB Header
translate([5.15,36.4,0]) {
cube([7.7,9,6]);
}
}
}
module arduino_isp_header_holder(t, r) {
translate(t) {
rotate(r) {
difference() {
union() {
translate([-2,-4,-2]) {
cube([22,7,14]);
}
translate([3.75,3,2]) {
cube([10.5,5,2]);
}
translate([-2,3,3.75]) {
cube([22,5,8.25]);
}
rotate(r) {
translate(-t) {
children();
}
}
}
#arduino_nano();
translate([2.1,-1.25,4]) {
union() {
// ISP Female Header
cube([13.8,7.5,9]);
// Notch
translate([4.3,-1.6,0]) {
cube([5.2,8.1,9]);
}
}
}
}
}
}
}
arduino_isp_header_holder();

898
openscad/arduino_isp.stl Normal file
View file

@ -0,0 +1,898 @@
solid OpenSCAD_Model
facet normal -1 0 0
outer loop
vertex 18 0 0
vertex 18 3 2
vertex 18 3 0
endloop
endfacet
facet normal -1 -0 0
outer loop
vertex 18 3 2
vertex 18 0 0
vertex 18 0 2
endloop
endfacet
facet normal 0 0 -1
outer loop
vertex 18 0 2
vertex 14.25 3 2
vertex 18 3 2
endloop
endfacet
facet normal 0 0 -1
outer loop
vertex 12.75 0 2
vertex 14.25 3 2
vertex 18 0 2
endloop
endfacet
facet normal 0 0 -1
outer loop
vertex 12.75 8 2
vertex 14.25 3 2
vertex 12.75 0 2
endloop
endfacet
facet normal 0 0 -1
outer loop
vertex 14.25 3 2
vertex 12.75 8 2
vertex 14.25 8 2
endloop
endfacet
facet normal 0 0 -1
outer loop
vertex 5.25 0 2
vertex 3.75 3 2
vertex 5.25 8 2
endloop
endfacet
facet normal 0 0 -1
outer loop
vertex 0 0 2
vertex 3.75 3 2
vertex 5.25 0 2
endloop
endfacet
facet normal -0 0 -1
outer loop
vertex 3.75 3 2
vertex 0 0 2
vertex 0 3 2
endloop
endfacet
facet normal -0 0 -1
outer loop
vertex 5.25 8 2
vertex 3.75 3 2
vertex 3.75 8 2
endloop
endfacet
facet normal -0 0 1
outer loop
vertex 12.75 3 0
vertex 18 0 0
vertex 18 3 0
endloop
endfacet
facet normal 0 0 1
outer loop
vertex 18 0 0
vertex 12.75 3 0
vertex 12.75 0 0
endloop
endfacet
facet normal -0 0 1
outer loop
vertex 0 3 0
vertex 5.25 0 0
vertex 5.25 3 0
endloop
endfacet
facet normal 0 0 1
outer loop
vertex 5.25 0 0
vertex 0 3 0
vertex 0 0 0
endloop
endfacet
facet normal 1 -0 0
outer loop
vertex 0 0 2
vertex 0 3 0
vertex 0 3 2
endloop
endfacet
facet normal 1 0 0
outer loop
vertex 0 3 0
vertex 0 0 2
vertex 0 0 0
endloop
endfacet
facet normal 0 1 -0
outer loop
vertex 12.75 0 -2
vertex 5.25 0 0
vertex 12.75 0 0
endloop
endfacet
facet normal 0 1 0
outer loop
vertex 5.25 0 0
vertex 12.75 0 -2
vertex 5.25 0 -2
endloop
endfacet
facet normal 0 1 0
outer loop
vertex 12.75 0 0
vertex 12.75 0 2
vertex 18 0 2
endloop
endfacet
facet normal 0 1 0
outer loop
vertex 12.75 0 2
vertex 12.75 0 0
vertex 5.25 0 2
endloop
endfacet
facet normal 0 1 0
outer loop
vertex 12.75 0 0
vertex 18 0 2
vertex 18 0 0
endloop
endfacet
facet normal 0 1 0
outer loop
vertex 5.25 0 0
vertex 5.25 0 2
vertex 12.75 0 0
endloop
endfacet
facet normal 0 1 0
outer loop
vertex 5.25 0 2
vertex 5.25 0 0
vertex 0 0 2
endloop
endfacet
facet normal 0 1 0
outer loop
vertex 0 0 2
vertex 5.25 0 0
vertex 0 0 0
endloop
endfacet
facet normal 0 1 -0
outer loop
vertex 12.75 0 2
vertex 5.25 0 4
vertex 12.75 0 4
endloop
endfacet
facet normal 0 1 0
outer loop
vertex 5.25 0 4
vertex 12.75 0 2
vertex 5.25 0 2
endloop
endfacet
facet normal -1 0 0
outer loop
vertex 12.75 0 -2
vertex 12.75 3 0
vertex 12.75 3 -2
endloop
endfacet
facet normal -1 -0 0
outer loop
vertex 12.75 3 0
vertex 12.75 0 -2
vertex 12.75 0 0
endloop
endfacet
facet normal -1 0 0
outer loop
vertex 12.75 8 2
vertex 12.75 6.25 4
vertex 12.75 8 10
endloop
endfacet
facet normal -1 0 0
outer loop
vertex 12.75 0 2
vertex 12.75 6.25 4
vertex 12.75 8 2
endloop
endfacet
facet normal -1 -0 0
outer loop
vertex 12.75 6.25 4
vertex 12.75 0 2
vertex 12.75 0 4
endloop
endfacet
facet normal -1 -0 0
outer loop
vertex 12.75 8 10
vertex 12.75 6.25 4
vertex 12.75 6.25 10
endloop
endfacet
facet normal 0 0 -1
outer loop
vertex 5.25 6.25 10
vertex 12.75 8 10
vertex 12.75 6.25 10
endloop
endfacet
facet normal -0 0 -1
outer loop
vertex 12.75 8 10
vertex 5.25 6.25 10
vertex 5.25 8 10
endloop
endfacet
facet normal 0 0 -1
outer loop
vertex 20 -4 -2
vertex 12.75 0 -2
vertex 20 3 -2
endloop
endfacet
facet normal 0 0 -1
outer loop
vertex 20 -4 -2
vertex 5.25 0 -2
vertex 12.75 0 -2
endloop
endfacet
facet normal 0 0 -1
outer loop
vertex -2 -4 -2
vertex 5.25 0 -2
vertex 20 -4 -2
endloop
endfacet
facet normal 0 0 -1
outer loop
vertex -2 3 -2
vertex 5.25 0 -2
vertex -2 -4 -2
endloop
endfacet
facet normal 0 0 -1
outer loop
vertex 5.25 0 -2
vertex -2 3 -2
vertex 5.25 3 -2
endloop
endfacet
facet normal -0 0 -1
outer loop
vertex 20 3 -2
vertex 12.75 0 -2
vertex 12.75 3 -2
endloop
endfacet
facet normal 1 -0 0
outer loop
vertex 5.25 0 0
vertex 5.25 3 -2
vertex 5.25 3 0
endloop
endfacet
facet normal 1 0 0
outer loop
vertex 5.25 3 -2
vertex 5.25 0 0
vertex 5.25 0 -2
endloop
endfacet
facet normal 1 0 0
outer loop
vertex 5.25 6.25 4
vertex 5.25 8 10
vertex 5.25 6.25 10
endloop
endfacet
facet normal 1 0 0
outer loop
vertex 5.25 8 10
vertex 5.25 6.25 4
vertex 5.25 8 2
endloop
endfacet
facet normal 1 0 0
outer loop
vertex 5.25 0 2
vertex 5.25 6.25 4
vertex 5.25 0 4
endloop
endfacet
facet normal 1 0 0
outer loop
vertex 5.25 6.25 4
vertex 5.25 0 2
vertex 5.25 8 2
endloop
endfacet
facet normal -1 0 0
outer loop
vertex 15.9 -1.25 4
vertex 15.9 6.25 12
vertex 15.9 6.25 4
endloop
endfacet
facet normal -1 -0 0
outer loop
vertex 15.9 6.25 12
vertex 15.9 -1.25 4
vertex 15.9 -1.25 12
endloop
endfacet
facet normal 0 0 1
outer loop
vertex 5.25 6.25 4
vertex 2.1 6.25 4
vertex 5.25 0 4
endloop
endfacet
facet normal 0 0 1
outer loop
vertex 12.75 0 4
vertex 15.9 6.25 4
vertex 12.75 6.25 4
endloop
endfacet
facet normal 0 0 1
outer loop
vertex 15.9 6.25 4
vertex 12.75 0 4
vertex 15.9 -1.25 4
endloop
endfacet
facet normal 0 0 1
outer loop
vertex 12.75 0 4
vertex 11.6 -1.25 4
vertex 15.9 -1.25 4
endloop
endfacet
facet normal 0 0 1
outer loop
vertex 11.6 -1.25 4
vertex 6.4 -1.25 4
vertex 11.6 -2.85 4
endloop
endfacet
facet normal 0 0 1
outer loop
vertex 12.75 0 4
vertex 6.4 -1.25 4
vertex 11.6 -1.25 4
endloop
endfacet
facet normal -0 0 1
outer loop
vertex 5.25 0 4
vertex 6.4 -1.25 4
vertex 12.75 0 4
endloop
endfacet
facet normal 0 0 1
outer loop
vertex 5.25 0 4
vertex 2.1 -1.25 4
vertex 6.4 -1.25 4
endloop
endfacet
facet normal 0 0 1
outer loop
vertex 2.1 -1.25 4
vertex 5.25 0 4
vertex 2.1 6.25 4
endloop
endfacet
facet normal 0 0 1
outer loop
vertex 11.6 -2.85 4
vertex 6.4 -1.25 4
vertex 6.4 -2.85 4
endloop
endfacet
facet normal 1 -0 0
outer loop
vertex 2.1 -1.25 12
vertex 2.1 6.25 4
vertex 2.1 6.25 12
endloop
endfacet
facet normal 1 0 0
outer loop
vertex 2.1 6.25 4
vertex 2.1 -1.25 12
vertex 2.1 -1.25 4
endloop
endfacet
facet normal 0 -1 0
outer loop
vertex 2.1 6.25 12
vertex 5.25 6.25 10
vertex 15.9 6.25 12
endloop
endfacet
facet normal 0 -1 0
outer loop
vertex 2.1 6.25 4
vertex 5.25 6.25 10
vertex 2.1 6.25 12
endloop
endfacet
facet normal 0 -1 -0
outer loop
vertex 5.25 6.25 10
vertex 2.1 6.25 4
vertex 5.25 6.25 4
endloop
endfacet
facet normal 0 -1 0
outer loop
vertex 12.75 6.25 10
vertex 15.9 6.25 12
vertex 5.25 6.25 10
endloop
endfacet
facet normal 0 -1 0
outer loop
vertex 15.9 6.25 4
vertex 12.75 6.25 10
vertex 12.75 6.25 4
endloop
endfacet
facet normal 0 -1 0
outer loop
vertex 12.75 6.25 10
vertex 15.9 6.25 4
vertex 15.9 6.25 12
endloop
endfacet
facet normal 0 1 -0
outer loop
vertex 6.4 -1.25 4
vertex 2.1 -1.25 12
vertex 6.4 -1.25 12
endloop
endfacet
facet normal 0 1 0
outer loop
vertex 2.1 -1.25 12
vertex 6.4 -1.25 4
vertex 2.1 -1.25 4
endloop
endfacet
facet normal 0 1 -0
outer loop
vertex 15.9 -1.25 4
vertex 11.6 -1.25 12
vertex 15.9 -1.25 12
endloop
endfacet
facet normal 0 1 0
outer loop
vertex 11.6 -1.25 12
vertex 15.9 -1.25 4
vertex 11.6 -1.25 4
endloop
endfacet
facet normal -1 0 0
outer loop
vertex 11.6 -2.85 4
vertex 11.6 -1.25 12
vertex 11.6 -1.25 4
endloop
endfacet
facet normal -1 -0 0
outer loop
vertex 11.6 -1.25 12
vertex 11.6 -2.85 4
vertex 11.6 -2.85 12
endloop
endfacet
facet normal 1 -0 0
outer loop
vertex 6.4 -2.85 12
vertex 6.4 -1.25 4
vertex 6.4 -1.25 12
endloop
endfacet
facet normal 1 0 0
outer loop
vertex 6.4 -1.25 4
vertex 6.4 -2.85 12
vertex 6.4 -2.85 4
endloop
endfacet
facet normal 0 1 -0
outer loop
vertex 11.6 -2.85 4
vertex 6.4 -2.85 12
vertex 11.6 -2.85 12
endloop
endfacet
facet normal 0 1 0
outer loop
vertex 6.4 -2.85 12
vertex 11.6 -2.85 4
vertex 6.4 -2.85 4
endloop
endfacet
facet normal 1 0 0
outer loop
vertex 20 8 12
vertex 20 3 3.75
vertex 20 8 3.75
endloop
endfacet
facet normal 1 -0 0
outer loop
vertex 20 -4 12
vertex 20 3 3.75
vertex 20 8 12
endloop
endfacet
facet normal 1 0 0
outer loop
vertex 20 -4 -2
vertex 20 3 3.75
vertex 20 -4 12
endloop
endfacet
facet normal 1 0 0
outer loop
vertex 20 3 3.75
vertex 20 -4 -2
vertex 20 3 -2
endloop
endfacet
facet normal 0 0 1
outer loop
vertex 6.4 -1.25 12
vertex 2.1 -1.25 12
vertex 6.4 -2.85 12
endloop
endfacet
facet normal 0 0 1
outer loop
vertex 15.9 -1.25 12
vertex 20 8 12
vertex 15.9 6.25 12
endloop
endfacet
facet normal 0 0 1
outer loop
vertex 20 8 12
vertex 2.1 6.25 12
vertex 15.9 6.25 12
endloop
endfacet
facet normal 0 0 1
outer loop
vertex 2.1 6.25 12
vertex -2 8 12
vertex 2.1 -1.25 12
endloop
endfacet
facet normal -0 0 1
outer loop
vertex -2 8 12
vertex 2.1 6.25 12
vertex 20 8 12
endloop
endfacet
facet normal 0 0 1
outer loop
vertex 20 8 12
vertex 15.9 -1.25 12
vertex 20 -4 12
endloop
endfacet
facet normal 0 0 1
outer loop
vertex 11.6 -2.85 12
vertex 15.9 -1.25 12
vertex 11.6 -1.25 12
endloop
endfacet
facet normal 0 0 1
outer loop
vertex 15.9 -1.25 12
vertex 11.6 -2.85 12
vertex 20 -4 12
endloop
endfacet
facet normal -0 0 1
outer loop
vertex 6.4 -2.85 12
vertex 20 -4 12
vertex 11.6 -2.85 12
endloop
endfacet
facet normal 0 0 1
outer loop
vertex 6.4 -2.85 12
vertex -2 -4 12
vertex 20 -4 12
endloop
endfacet
facet normal 0 0 1
outer loop
vertex 2.1 -1.25 12
vertex -2 -4 12
vertex 6.4 -2.85 12
endloop
endfacet
facet normal 0 0 1
outer loop
vertex -2 -4 12
vertex 2.1 -1.25 12
vertex -2 8 12
endloop
endfacet
facet normal -1 0 0
outer loop
vertex -2 3 -2
vertex -2 -4 -2
vertex -2 3 3.75
endloop
endfacet
facet normal -1 0 0
outer loop
vertex -2 3 3.75
vertex -2 8 12
vertex -2 8 3.75
endloop
endfacet
facet normal -1 0 0
outer loop
vertex -2 -4 12
vertex -2 3 3.75
vertex -2 -4 -2
endloop
endfacet
facet normal -1 0 0
outer loop
vertex -2 3 3.75
vertex -2 -4 12
vertex -2 8 12
endloop
endfacet
facet normal 0 1 0
outer loop
vertex 20 3 3.75
vertex 18 3 2
vertex 14.25 3 3.75
endloop
endfacet
facet normal 0 1 0
outer loop
vertex 20 3 3.75
vertex 18 3 0
vertex 18 3 2
endloop
endfacet
facet normal 0 1 -0
outer loop
vertex 20 3 -2
vertex 18 3 0
vertex 20 3 3.75
endloop
endfacet
facet normal 0 1 0
outer loop
vertex 12.75 3 -2
vertex 18 3 0
vertex 20 3 -2
endloop
endfacet
facet normal 0 1 0
outer loop
vertex 18 3 0
vertex 12.75 3 -2
vertex 12.75 3 0
endloop
endfacet
facet normal 0 1 0
outer loop
vertex 14.25 3 3.75
vertex 18 3 2
vertex 14.25 3 2
endloop
endfacet
facet normal 0 1 0
outer loop
vertex 5.25 3 0
vertex 5.25 3 -2
vertex 0 3 0
endloop
endfacet
facet normal 0 1 0
outer loop
vertex 0 3 2
vertex 3.75 3 3.75
vertex 3.75 3 2
endloop
endfacet
facet normal 0 1 0
outer loop
vertex 3.75 3 3.75
vertex 0 3 2
vertex -2 3 3.75
endloop
endfacet
facet normal 0 1 -0
outer loop
vertex 0 3 0
vertex -2 3 3.75
vertex 0 3 2
endloop
endfacet
facet normal 0 1 0
outer loop
vertex 0 3 0
vertex -2 3 -2
vertex -2 3 3.75
endloop
endfacet
facet normal 0 1 0
outer loop
vertex -2 3 -2
vertex 0 3 0
vertex 5.25 3 -2
endloop
endfacet
facet normal 0 -1 0
outer loop
vertex -2 -4 -2
vertex 20 -4 12
vertex -2 -4 12
endloop
endfacet
facet normal 0 -1 -0
outer loop
vertex 20 -4 12
vertex -2 -4 -2
vertex 20 -4 -2
endloop
endfacet
facet normal 1 -0 0
outer loop
vertex 14.25 3 3.75
vertex 14.25 8 2
vertex 14.25 8 3.75
endloop
endfacet
facet normal 1 0 0
outer loop
vertex 14.25 8 2
vertex 14.25 3 3.75
vertex 14.25 3 2
endloop
endfacet
facet normal -1 0 0
outer loop
vertex 3.75 3 2
vertex 3.75 8 3.75
vertex 3.75 8 2
endloop
endfacet
facet normal -1 -0 0
outer loop
vertex 3.75 8 3.75
vertex 3.75 3 2
vertex 3.75 3 3.75
endloop
endfacet
facet normal 0 1 -0
outer loop
vertex 5.25 8 2
vertex 3.75 8 3.75
vertex 5.25 8 10
endloop
endfacet
facet normal 0 1 0
outer loop
vertex 3.75 8 3.75
vertex 5.25 8 2
vertex 3.75 8 2
endloop
endfacet
facet normal 0 1 0
outer loop
vertex 20 8 12
vertex 12.75 8 10
vertex -2 8 12
endloop
endfacet
facet normal 0 1 -0
outer loop
vertex 20 8 3.75
vertex 12.75 8 10
vertex 20 8 12
endloop
endfacet
facet normal 0 1 -0
outer loop
vertex 14.25 8 3.75
vertex 12.75 8 10
vertex 20 8 3.75
endloop
endfacet
facet normal 0 1 0
outer loop
vertex 12.75 8 2
vertex 14.25 8 3.75
vertex 14.25 8 2
endloop
endfacet
facet normal 0 1 0
outer loop
vertex 14.25 8 3.75
vertex 12.75 8 2
vertex 12.75 8 10
endloop
endfacet
facet normal 0 1 -0
outer loop
vertex 5.25 8 10
vertex -2 8 12
vertex 12.75 8 10
endloop
endfacet
facet normal 0 1 0
outer loop
vertex -2 8 3.75
vertex 5.25 8 10
vertex 3.75 8 3.75
endloop
endfacet
facet normal 0 1 0
outer loop
vertex 5.25 8 10
vertex -2 8 3.75
vertex -2 8 12
endloop
endfacet
facet normal 0 0 -1
outer loop
vertex 14.25 3 3.75
vertex 20 8 3.75
vertex 20 3 3.75
endloop
endfacet
facet normal -0 0 -1
outer loop
vertex 20 8 3.75
vertex 14.25 3 3.75
vertex 14.25 8 3.75
endloop
endfacet
facet normal 0 0 -1
outer loop
vertex -2 3 3.75
vertex 3.75 8 3.75
vertex 3.75 3 3.75
endloop
endfacet
facet normal -0 0 -1
outer loop
vertex 3.75 8 3.75
vertex -2 3 3.75
vertex -2 8 3.75
endloop
endfacet
endsolid OpenSCAD_Model

View file

@ -0,0 +1,358 @@
use <arduino_isp.scad>
$fn=50;
H=24.16;
function _sagitta_r(y, x) = (y*y)/(8*x) + (x/2);
module sagitta(y, x, h) {
r = _sagitta_r(y, x);
translate([-(r-y/2),-2*r,0]) {
difference() {
translate([r,r+x,0]) {
cylinder(h=h, r=r);
}
translate([0,0,-1]) {
cube([2*r, 2*r, h+2]);
}
}
}
}
module p(w) {
union() {
difference() {
cube([w,40,15]);
rotate([0,0,44]) {
translate([0,0,-1]) {
cube([100,100,17]);
}
}
translate([w,0,0]) {
rotate([0,0,20]) {
translate([0,0,-1]) {
cube([100,100,17]);
}
}
}
}
scale([1,-1,1]) {
sagitta(w, 4, 15);
}
}
}
module erode() {
difference() {
cube([100,100,100]);
minkowski() {
difference() {
cube([100,100,100]);
children(0);
}
children(1);
}
}
}
module wall() {
difference() {
minkowski() {
cylinder(r=8, h=.1);
p(44);
}
translate([0,0,-5]) {
scale([1,1,2]) {
translate([-30,-30,-30]) {
erode() {
translate([30, 30, 30]) {
minkowski() {
cylinder(r=8, h=2);
p(44);
}
}
cylinder(r=2, h=2);
}
}
}
}
}
}
module case() {
union() {
scale([1,1,1.6]) {
wall();
}
scale([1,1,.1]) {
minkowski() {
cylinder(r1=10, h=.1);
p(44);
}
}
translate([0,0,H-1.5]) {
scale([1,1,.1]) {
minkowski() {
cylinder(r=10, h=.1);
p(44);
}
}
}
}
}
module fullcase() {
difference() {
union() {
case();
translate([14.5, -9, 1.5]) {
cube([16, 12, 3]);
}
translate([-3,-2,0]) {
cylinder(r=4,h=H);
}
translate([47,-2,0]) {
cylinder(r=4,h=H);
}
// Arduino holders
translate([1, 1, 0]) {
rotate([0,0,44]) {
cube([5,5,6]);
}
}
translate([1, 1, H-5]) {
rotate([0,0,44]) {
cube([5,5,6]);
}
}
translate([32, 31, 0]) {
rotate([0,0,44]) {
cube([5,5,6]);
}
}
translate([32, 31, H-5]) {
rotate([0,0,44]) {
cube([5,5,6]);
}
}
// Schmitt trigger holders
translate([44, 0, 0]) {
rotate([0,0,20]) {
cube([6,25,6]);
}
}
translate([44, 0, H-5]) {
rotate([0,0,20]) {
cube([6,25,6]);
}
}
}
translate([20, -6, -2]) {
cube([5, 4, 5]);
}
translate([16.5, -7, 1.5]) {
cube([12, 8, 5]);
}
translate([-3,-2,-1]) {
cylinder(r=1.5,h=H+2);
}
translate([47,-2,-1]) {
cylinder(r=1.5,h=H+2);
}
// Arduino nano cutout
#translate([0,5,3]) {
rotate([0,0,-46]) {
cube([2,44,18]);
}
}
//Schmitt trigger board cutout
#translate([44,4,2]) {
rotate([0,0,20]) {
cube([2,20,20]);
}
}
// Various holes
translate([8,0,-1]) {
cylinder(r=5, h=H+2);
}
translate([37,0,-1]) {
cylinder(r=5, h=H+2);
}
translate([25,14,-1]) {
cylinder(r=8, h=H+2);
}
}
}
module two_halves() {
intersection() {
fullcase();
translate([-30,-30,0]) {
cube([100,100,H/2]);
}
}
intersection() {
translate([-80,0,H]) {
rotate([180,0,0]) {
fullcase();
}
}
translate([-100,-70,0]) {
cube([100,100,H/2]);
}
}
}
module double_case() {
difference() {
union() {
case();
translate([73,20,0]) {
rotate([0,0,72]) {
case();
}
}
//bottom connect outer
translate([50,-3,0]) {
rotate([0,0,35]) {
cube([30,40,1.5]);
}
}
//bottom connect inner
translate([50,24,0]) {
rotate([0,0,45]) {
cube([30,20,1.5]);
}
}
//bottom extrude short edge
translate([46,60,0]) {
rotate([0,0,2]) {
cube([45,30,1.5]);
}
}
//bottom extrude long edge
translate([-3,-5,0]) {
rotate([0,0,44]) {
cube([40,30,1.5]);
}
}
//top connect outer
translate([50,-3,H-1.5]) {
rotate([0,0,35]) {
cube([30,40,1.5]);
}
}
//top connect inner
translate([50,24,H-1.5]) {
rotate([0,0,45]) {
cube([30,20,1.5]);
}
}
//top extrude short edge
translate([46,60,H-1.5]) {
rotate([0,0,2]) {
cube([45,30,1.5]);
}
}
//top extrude long edge
translate([-3,-5,H-1.5]) {
rotate([0,0,44]) {
cube([40,30,1.5]);
}
}
}
//connect cutout
translate([45,5,1.5]) {
rotate([0,0,40]) {
cube([35,25,H-3]);
}
}
}
}
module double_full_case_halves() {
intersection() {
double_case();
translate([-30,-30,0]) {
cube([150,150,H/2]);
}
}
translate([40,40,0]) {
intersection() {
translate([-90,0,H]) {
rotate([180,0,90]) {
double_case();
}
}
translate([-110,-30,0]) {
cube([150,150,H/2]);
}
}
}
}
//fullcase();
//two_halves();
arduino_isp_header_holder(r=[0,180,-46],t=[12,-6.5,12]) {
difference() {
union() {
double_full_case_halves();
// Schmitt trigger holders
translate([44, -6, 0]) {
rotate([0,0,20]) {
cube([6,6,8]);
}
}
translate([38, 11, 0]) {
rotate([0,0,20]) {
cube([6,6,8]);
}
}
// Battery holder
translate([81, 31, 0]) {
rotate([0,0,27]) {
cube([5,30,20]);
}
}
// Sensor PCB enclosure
translate([20.5, -1, 1.5]) {
cube([16, 12, 3]);
}
}
// LED cable hole
translate([25,-9,-1]) {
cube([7,7,5]);
}
//Schmitt trigger board cutout
translate([45,-4,5]) {
rotate([0,0,20]) {
cube([2,20,20]);
}
}
// Sensor hole
translate([26, 2, -2]) {
cube([5, 4, 5]);
}
translate([22.5, 1, 1.5]) {
cube([12, 8, 5]);
}
// Power button hole
translate([80, 50, -1]) {
rotate([0,0,27]) {
cube([6,12,5]);
}
}
}
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,100 @@
#include <NeoPixelBus.h>
#define DOUBLE_SIDE 0
#define N_ROT_SLICES (48)
#define WS_PIN (8)
#define WS_VCC (9)
#define WS_GND (7)
#define HALL_PIN (2)
#include "image.h"
static const RgbColor off(0,0,0);
#if DOUBLE_SIDE
#define WS_PIXEL_COUNT (2*IMAGE_HEIGHT)
#else
#define WS_PIXEL_COUNT (IMAGE_HEIGHT)
#endif
static NeoPixelBus<NeoGrbFeature, Neo800KbpsMethod> ws2812(WS_PIXEL_COUNT, WS_PIN);
static volatile uint32_t last_hall = 0UL;
static volatile uint32_t last_hall_diff = 1000UL;
#if SKEW_RATE
static uint16_t skew = 0U;
static uint32_t last_skew = 0UL;
#endif
void update_hall_timestamp() {
uint32_t now = millis();
last_hall_diff = now - last_hall;
last_hall = now;
}
void setup() {
// Setup output pins
pinMode(WS_PIN, OUTPUT);
pinMode(HALL_PIN, INPUT);
// Setup power supply for WS2812 strip
// (Yes, I know I shouldn't supply power from the Arduino I/O pins,
// but I'm running the LEDs at a fraction of their max power draw)
pinMode(WS_VCC, OUTPUT);
pinMode(WS_GND, OUTPUT);
digitalWrite(WS_VCC, HIGH);
digitalWrite(WS_GND, LOW);
// Setup WS2812 strup
ws2812.Begin();
ws2812.Show();
// Setup hall sensor interrupt
attachInterrupt(
digitalPinToInterrupt(HALL_PIN),
update_hall_timestamp,
FALLING
);
}
void loop() {
// Get the current time
uint32_t now = millis();
// Turn the LEDs off if no sensor input was received for 3s
if ((now - last_hall) > 3000UL) {
for (size_t i = 0; i < IMAGE_HEIGHT; ++i) {
ws2812.SetPixelColor(i, off);
#if DOUBLE_SIDE
ws2812.SetPixelColor(IMAGE_HEIGHT + i, off);
#endif
}
ws2812.Show();
// Only re-check after a second
delay(1000);
return;
}
// Get the slice to show at the current time, based on the time between the last two sensor events
uint16_t slice = (uint16_t) (((now - last_hall) * N_ROT_SLICES / last_hall_diff) % N_ROT_SLICES);
#if SKEW_RATE
// Increment the skew offset when it's time for the next skew step
if (now - last_skew > SKEW_RATE) {
skew = (skew + 1) % N_ROT_SLICES;
last_skew = now;
}
// Add the current skew offset to the slice index
slice = (uint16_t) ((slice + skew) % N_ROT_SLICES);
#endif
// Display the current slice (row) of the image
for (size_t i = 0; i < IMAGE_HEIGHT; ++i) {
ws2812.SetPixelColor(i, PALETTE[IMAGE[slice][i]]);
#if DOUBLE_SIDE
#if DOUBLE_SIDE_MIRROR
ws2812.SetPixelColor(IMAGE_HEIGHT+i, PALETTE[IMAGE[N_ROT_SLICES-slice][i]]);
#else
ws2812.SetPixelColor(IMAGE_HEIGHT+i, PALETTE[IMAGE[slice][i]]);
#endif
#endif
}
ws2812.Show();
}

119
wheelgen/cyber.h Normal file
View file

@ -0,0 +1,119 @@
#ifndef _WHEELGEN_OUTPUT_H_
#define _WHEELGEN_OUTPUT_H_
#define IMAGE_HEIGHT (7)
#define IMAGE_WIDTH (100)
#define SKEW_RATE (0)
#define DOUBLE_SIDE_MIRROR (0)
static const RgbColor PALETTE[] = {
RgbColor(0,0,0), // background
RgbColor(20,20,0) // foreground
};
static const __restrict__ uint8_t IMAGE[IMAGE_WIDTH][IMAGE_HEIGHT] = {
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,1,1,1,0,0},
{0,1,0,0,0,1,0},
{0,1,0,0,0,1,0},
{0,0,0,0,0,0,0},
{0,0,0,0,1,1,0},
{0,1,1,1,0,0,0},
{0,0,0,0,1,1,0},
{0,0,0,0,0,0,0},
{0,1,1,1,1,1,0},
{0,1,0,1,0,1,0},
{0,0,1,0,1,0,0},
{0,0,0,0,0,0,0},
{0,1,1,1,1,1,0},
{0,1,0,1,0,1,0},
{0,1,0,1,0,1,0},
{0,0,0,0,0,0,0},
{0,1,1,1,1,1,0},
{0,0,0,1,0,1,0},
{0,1,1,0,1,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0}
};
#endif // _WHEELGEN_OUTPUT_H_

67
wheelgen/image.h Normal file
View file

@ -0,0 +1,67 @@
#ifndef _WHEELGEN_OUTPUT_H_
#define _WHEELGEN_OUTPUT_H_
#define IMAGE_HEIGHT (7)
#define IMAGE_WIDTH (48)
#define SKEW_RATE (100)
#define DOUBLE_SIDE_MIRROR (0)
static const RgbColor PALETTE[] = {
RgbColor(0,0,0), // background
RgbColor(255,255,0) // foreground
};
static const __restrict__ uint8_t IMAGE[IMAGE_WIDTH][IMAGE_HEIGHT] = {
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{1,0,0,0,1,1,0},
{0,1,0,1,0,0,1},
{0,0,1,1,0,0,1},
{0,0,0,1,0,0,1},
{1,1,1,1,1,1,1},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{1,0,0,0,0,0,1},
{1,0,0,1,0,0,1},
{1,0,0,1,0,0,1},
{1,0,0,1,0,0,1},
{1,1,1,1,1,1,1},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,1,1,0,1,1,0},
{1,0,0,1,0,0,1},
{1,0,0,1,0,0,1},
{1,1,1,1,1,1,1},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,1,1,1},
{0,0,0,1,0,0,0},
{1,1,1,0,0,0,0},
{0,0,0,1,0,0,0},
{0,0,0,0,1,1,1},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{1,0,0,0,0,0,1},
{1,0,0,0,0,0,1},
{1,0,0,0,0,0,1},
{0,1,0,0,0,1,0},
{0,0,1,1,1,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0}
};
#endif // _WHEELGEN_OUTPUT_H_

13
wheelgen/setup.py Normal file
View file

@ -0,0 +1,13 @@
from setuptools import setup, find_packages
from wheelgen import __version__
setup(
name='wheelgen',
version=__version__,
packages=find_packages(),
author='s3lph',
license='MIT',
install_requires=['Pillow']
)

View file

@ -0,0 +1,2 @@
__version__ = '0.1'

View file

@ -0,0 +1,77 @@
from typing import List
import argparse
from character import Character
from codegen import generate_wheel_header
from flash import arduino_upload
def render_text(text: List[str], fontsize: int) -> List[List[int]]:
rendered: List[List[int]] = list()
joined: str = ' '.join(text)
for char in joined:
rendered.extend(Character.get_character(char, fontsize))
rendered.append([0] * fontsize)
return rendered
def pad_text(text: List[List[int]], pad: int, mode: str = 'center') -> List[List[int]]:
i = 0
while len(text) < pad:
if mode == 'left' or (mode == 'center' and i % 2 == 0):
text.insert(0, [0, 0, 0, 0, 0, 0, 0])
else:
text.append([0, 0, 0, 0, 0, 0, 0])
i += 1
return text
def main():
parser = argparse.ArgumentParser(description='wheelgen')
parser.add_argument('-o', '--output',
help='File to write to, or - for stdout', type=str, required=True)
parser.add_argument('-f', '--foreground',
help='Foreground color, in HTML notation, without leading pound sign', default='ffffff')
parser.add_argument('-b', '--background',
help='Background color, in HTML notation, without leading pound sign', default='000000')
parser.add_argument('-m', '--mirror',
help='Mirror the resulting image horizontally', action='store_true', default=False)
parser.add_argument('-u', '--upside-down',
help='Mirror the resulting image vertically', action='store_true', default=False)
parser.add_argument('-p', '--pad-width',
help='Width to pad up to', type=int, default=0)
parser.add_argument('-a', '--pad-mode',
help='Padding mode', type=str, choices=['center', 'left', 'right'], default='center')
parser.add_argument('-s', '--skew-rate',
help='Skew rate (time in ms between two steps of rotating the image)', type=int, default=0)
parser.add_argument('-d', '--doubleside-mirror',
help='Mirror the image on the second side when displaying on both sides of the wheel',
action='store_true', default=False)
parser.add_argument('-5', help='Use a 5px high font', action='store_const', dest='fontsize', const=5, default=5)
parser.add_argument('-7', help='Use a 7px high font', action='store_const', dest='fontsize', const=7)
parser.add_argument('-S', '--sketch',
help='Arduino sketch to build and flash including the generated header', type=str)
parser.add_argument('text',
help='The text to render', type=str, nargs='+')
args: argparse.Namespace = parser.parse_args()
fg_color = int(args.foreground[0:2], 16), int(args.foreground[2:4], 16), int(args.foreground[4:6], 16)
bg_color = int(args.background[0:2], 16), int(args.background[2:4], 16), int(args.background[4:6], 16)
skew_rate: int = args.skew_rate
text_image: List[List[int]] = pad_text(render_text(args.text, args.fontsize), args.pad_width, args.pad_mode)
rendered: str = generate_wheel_header(text_image, fg_color, bg_color,
mirror=(args.mirror, args.upside_down),
skew=skew_rate,
doubleside_mirror=args.doubleside_mirror)
if args.output == '-':
print(rendered)
else:
with open(args.output, 'w') as f:
f.write(rendered)
if args.sketch is not None:
arduino_upload(args.sketch, args.output)
if __name__ == '__main__':
main()

View file

@ -0,0 +1,467 @@
from typing import List
from enum import Enum
class _5Character(Enum):
A = [
[0,0,0,0,0,0,0],
[0,1,1,1,1,0,0],
[0,0,0,1,0,1,0],
[0,1,1,1,1,0,0],
]
B = [
[0,0,0,0,0,0,0],
[0,1,1,1,1,1,0],
[0,1,0,1,0,1,0],
[0,0,1,0,1,0,0],
]
C = [
[0,0,0,0,0,0,0],
[0,0,1,1,1,0,0],
[0,1,0,0,0,1,0],
[0,1,0,0,0,1,0],
]
D = [
[0,0,0,0,0,0,0],
[0,1,1,1,1,1,0],
[0,1,0,0,0,1,0],
[0,0,1,1,1,0,0],
]
E = [
[0,0,0,0,0,0,0],
[0,1,1,1,1,1,0],
[0,1,0,1,0,1,0],
[0,1,0,1,0,1,0],
]
F = [
[0,0,0,0,0,0,0],
[0,1,1,1,1,1,0],
[0,0,0,1,0,1,0],
[0,0,0,1,0,1,0],
]
G = [
[0,0,0,0,0,0,0],
[0,0,1,1,1,0,0],
[0,1,0,0,0,1,0],
[0,0,1,1,0,1,0],
]
H = [
[0,0,0,0,0,0,0],
[0,1,1,1,1,1,0],
[0,0,0,1,0,0,0],
[0,1,1,1,1,1,0],
]
I = [
[0,0,0,0,0,0,0],
[0,1,0,0,0,1,0],
[0,1,1,1,1,1,0],
[0,1,0,0,0,1,0],
]
J = [
[0,0,0,0,0,0,0],
[0,0,1,0,0,1,0],
[0,1,0,0,0,1,0],
[0,0,1,1,1,1,0],
]
K = [
[0,0,0,0,0,0,0],
[0,1,1,1,1,1,0],
[0,0,1,1,1,0,0],
[0,1,0,0,0,1,0],
]
L = [
[0,0,0,0,0,0,0],
[0,1,1,1,1,1,0],
[0,1,0,0,0,0,0],
[0,1,0,0,0,0,0],
]
M = [
[0,0,0,0,0,0,0],
[0,1,1,1,1,1,0],
[0,0,0,0,1,0,0],
[0,1,1,1,1,1,0],
]
N = [
[0,0,0,0,0,0,0],
[0,1,1,1,1,1,0],
[0,0,0,0,1,0,0],
[0,1,1,1,1,1,0],
]
O = [
[0,0,0,0,0,0,0],
[0,0,1,1,1,0,0],
[0,1,0,0,0,1,0],
[0,0,1,1,1,0,0],
]
P = [
[0,0,0,0,0,0,0],
[0,1,1,1,1,1,0],
[0,0,0,1,0,1,0],
[0,0,0,0,1,0,0],
]
Q = [
[0,0,0,0,0,0,0],
[0,0,1,1,1,0,0],
[0,1,1,0,0,1,0],
[0,1,1,1,1,0,0],
]
R = [
[0,0,0,0,0,0,0],
[0,1,1,1,1,1,0],
[0,0,0,1,0,1,0],
[0,1,1,0,1,0,0],
]
S = [
[0,0,0,0,0,0,0],
[0,1,0,0,1,0,0],
[0,1,0,1,0,1,0],
[0,0,1,0,1,1,0],
]
T = [
[0,0,0,0,0,0,0],
[0,0,0,0,0,1,0],
[0,1,1,1,1,1,0],
[0,0,0,0,0,1,0],
]
U = [
[0,0,0,0,0,0,0],
[0,0,1,1,1,1,0],
[0,1,0,0,0,0,0],
[0,0,1,1,1,1,0],
]
V = [
[0,0,0,0,0,0,0],
[0,0,0,1,1,1,0],
[0,1,1,0,0,0,0],
[0,0,0,1,1,1,0],
]
W = [
[0,0,0,0,0,0,0],
[0,1,1,1,1,1,0],
[0,0,1,0,0,0,0],
[0,1,1,1,1,1,0],
]
X = [
[0,0,0,0,0,0,0],
[0,1,1,0,1,1,0],
[0,0,0,1,0,0,0],
[0,1,1,0,1,1,0],
]
Y = [
[0,0,0,0,0,0,0],
[0,0,0,0,1,1,0],
[0,1,1,1,0,0,0],
[0,0,0,0,1,1,0],
]
Z = [
[0,0,0,0,0,0,0],
[0,1,1,0,0,1,0],
[0,1,0,1,0,1,0],
[0,1,0,0,1,1,0],
]
_ = [
[0,0,0,0,0,0,0],
[0,1,0,0,0,0,0],
[0,1,0,0,0,0,0],
[0,1,0,0,0,0,0],
]
SPACE = [
[0,0,0,0,0,0,0],
[0,0,0,0,0,0,0],
]
@staticmethod
def get_character(char: str) -> List[List[int]]:
if char == ' ':
return _5Character.SPACE.value
else:
return _5Character[char].value
class _7Character(Enum):
A = [
[0,0,0,0,0,0,0],
[1,1,1,1,1,0,0],
[0,0,1,0,0,1,0],
[0,0,1,0,0,0,1],
[0,0,1,0,0,1,0],
[1,1,1,1,1,0,0],
]
B = [
[0,0,0,0,0,0,0],
[1,1,1,1,1,1,1],
[1,0,0,1,0,0,1],
[1,0,0,1,0,0,1],
[0,1,1,0,1,1,0],
[0,0,0,0,0,0,0],
]
C = [
[0,0,0,0,0,0,0],
[0,0,1,1,1,0,0],
[0,1,0,0,0,1,0],
[1,0,0,0,0,0,1],
[1,0,0,0,0,0,1],
[1,0,0,0,0,0,1],
]
D = [
[0,0,0,0,0,0,0],
[1,1,1,1,1,1,1],
[1,0,0,0,0,0,1],
[1,0,0,0,0,0,1],
[0,1,0,0,0,1,0],
[0,0,1,1,1,0,0],
]
E = [
[0,0,0,0,0,0,0],
[1,1,1,1,1,1,1],
[1,0,0,1,0,0,1],
[1,0,0,1,0,0,1],
[1,0,0,1,0,0,1],
[1,0,0,0,0,0,1],
]
F = [
[0,0,0,0,0,0,0],
[1,1,1,1,1,1,1],
[0,0,0,1,0,0,1],
[0,0,0,1,0,0,1],
[0,0,0,1,0,0,1],
[0,0,0,0,0,0,1],
]
G = [
[0,0,0,0,0,0,0],
[0,1,1,1,1,1,0],
[1,0,0,0,0,0,1],
[1,0,0,1,0,0,1],
[0,1,0,1,0,0,1],
[1,1,1,1,0,0,1],
]
H = [
[0,0,0,0,0,0,0],
[1,1,1,1,1,1,1],
[0,0,0,1,0,0,0],
[0,0,0,1,0,0,0],
[0,0,0,1,0,0,0],
[1,1,1,1,1,1,1],
]
I = [
[0,0,0,0,0,0,0],
[1,0,0,0,0,0,1],
[1,1,1,1,1,1,1],
[1,0,0,0,0,0,1],
]
J = [
[0,0,0,0,0,0,0],
[0,1,1,0,0,0,1],
[1,0,0,0,0,0,1],
[1,0,0,0,0,0,1],
[1,0,0,0,0,0,1],
[0,1,1,1,1,1,1],
]
K = [
[0,0,0,0,0,0,0],
[1,1,1,1,1,1,1],
[0,0,0,1,0,0,0],
[0,0,1,0,1,0,0],
[0,1,0,0,0,1,0],
[1,0,0,0,0,0,1],
]
L = [
[0,0,0,0,0,0,0],
[1,1,1,1,1,1,1],
[1,0,0,0,0,0,0],
[1,0,0,0,0,0,0],
[1,0,0,0,0,0,0],
[1,0,0,0,0,0,0],
]
M = [
[0,0,0,0,0,0,0],
[1,1,1,1,1,1,1],
[0,0,0,0,1,0,0],
[0,0,0,1,0,0,0],
[0,0,0,0,1,0,0],
[1,1,1,1,1,1,1],
]
N = [
[0,0,0,0,0,0,0],
[1,1,1,1,1,1,1],
[0,0,0,0,1,0,0],
[0,0,0,1,0,0,0],
[0,0,1,0,0,0,0],
[1,1,1,1,1,1,1],
]
O = [
[0,0,0,0,0,0,0],
[0,1,1,1,1,1,0],
[1,0,0,0,0,0,1],
[1,0,0,0,0,0,1],
[1,0,0,0,0,0,1],
[0,1,1,1,1,1,0],
]
P = [
[0,0,0,0,0,0,0],
[1,1,1,1,1,1,1],
[0,0,0,1,0,0,1],
[0,0,0,1,0,0,1],
[0,0,0,1,0,0,1],
[0,0,0,0,1,1,0],
]
Q = [
[0,0,0,0,0,0,0],
[0,1,1,1,1,1,0],
[1,0,0,0,0,0,1],
[1,0,1,0,0,0,1],
[0,1,0,0,0,0,1],
[1,0,1,1,1,1,0],
]
R = [
[0,0,0,0,0,0,0],
[1,1,1,1,1,1,1],
[0,0,0,1,0,0,1],
[0,0,1,1,0,0,1],
[0,1,0,1,0,0,1],
[1,0,0,0,1,1,0],
]
S = [
[0,0,0,0,0,0,0],
[1,0,0,0,1,1,0],
[1,0,0,1,0,0,1],
[1,0,0,1,0,0,1],
[1,0,0,1,0,0,1],
[0,1,1,0,0,0,1],
]
T = [
[0,0,0,0,0,0,0],
[0,0,0,0,0,0,1],
[0,0,0,0,0,0,1],
[1,1,1,1,1,1,1],
[0,0,0,0,0,0,1],
[0,0,0,0,0,0,1],
]
U = [
[0,0,0,0,0,0,0],
[0,0,1,1,1,1,1],
[0,1,0,0,0,0,0],
[1,0,0,0,0,0,0],
[0,1,0,0,0,0,0],
[0,0,1,1,1,1,1],
]
V = [
[0,0,0,0,0,0,0],
[0,0,0,0,1,1,1],
[0,0,1,1,0,0,0],
[1,1,0,0,0,0,0],
[0,0,1,1,0,0,0],
[0,0,0,0,1,1,1],
]
W = [
[0,0,0,0,0,0,0],
[1,1,1,1,1,1,1],
[0,0,1,0,0,0,0],
[0,0,0,1,0,0,0],
[0,0,1,0,0,0,0],
[1,1,1,1,1,1,1],
]
X = [
[0,0,0,0,0,0,0],
[1,1,0,0,0,1,1],
[0,0,1,0,1,0,0],
[0,0,0,1,0,0,0],
[0,0,1,0,1,0,0],
[1,1,0,0,0,1,1],
]
Y = [
[0,0,0,0,0,0,0],
[0,0,0,0,1,1,1],
[0,0,0,1,0,0,0],
[1,1,1,0,0,0,0],
[0,0,0,1,0,0,0],
[0,0,0,0,1,1,1],
]
Z = [
[0,0,0,0,0,0,0],
[1,1,0,0,0,0,1],
[1,0,1,0,0,0,1],
[1,0,0,1,0,0,1],
[1,0,0,0,1,0,1],
[1,0,0,0,0,1,1],
]
SPACE = [
[0,0,0,0,0,0,0],
[0,0,0,0,0,0,0],
[0,0,0,0,0,0,0]
]
@staticmethod
def get_character(char: str) -> List[List[int]]:
if char == ' ':
return _7Character.SPACE.value
else:
return _7Character[char].value
class Character:
@staticmethod
def get_character(char: str, fontsize: int) -> List[List[int]]:
if fontsize == 5:
return _5Character.get_character(char)
elif fontsize == 7:
return _7Character.get_character(char)
raise ValueError(fontsize)

View file

@ -0,0 +1,45 @@
from typing import List, Tuple
def generate_wheel_header(text: List[List[int]],
fg: Tuple[int, int, int],
bg: Tuple[int, int, int],
mirror: Tuple[bool, bool],
skew: int = 0,
doubleside_mirror: bool = False) -> str:
if mirror[0]:
text = list(reversed(text))
if mirror[1]:
text = [list(reversed(row)) for row in text]
image_width = len(text)
image_height = len(text[0])
imgarray = str(text)\
.replace(', ', ',')\
.replace('[', '\n [')\
.replace(']]', ']\n]')\
.replace('[', '{')\
.replace(']', '}')\
.strip()
rendered: str = f'''
#ifndef _WHEELGEN_OUTPUT_H_
#define _WHEELGEN_OUTPUT_H_
#define IMAGE_HEIGHT ({image_height})
#define IMAGE_WIDTH ({image_width})
#define SKEW_RATE ({skew})
#define DOUBLE_SIDE_MIRROR ({1 if doubleside_mirror else 0})
static const RgbColor PALETTE[] = {{
RgbColor({bg[0]},{bg[1]},{bg[2]}), // background
RgbColor({fg[0]},{fg[1]},{fg[2]}) // foreground
}};
static const __restrict__ uint8_t IMAGE[IMAGE_WIDTH][IMAGE_HEIGHT] = {imgarray};
#endif // _WHEELGEN_OUTPUT_H_
'''
return rendered

View file

@ -0,0 +1,21 @@
import os
import subprocess
def arduino_upload(sketch_file_path: str,
header_file_path: str):
sketch_abs_path: str = os.path.abspath(sketch_file_path)
header_dir_path: str = os.path.dirname(os.path.abspath(header_file_path))
process = subprocess.Popen(executable='/bin/bash',
args=[
'arduino ' +
'--upload ' +
'--useprogrammer ' +
'--nouploadport ' +
'--board ' + 'archlinux-arduino:avr:nano:cpu=atmega328 ' +
'--pref ' + f"compiler.c.extra_flags='-I{header_dir_path}' " +
'--pref ' + f"compiler.cpp.extra_flags='-I{header_dir_path}' " +
sketch_abs_path
],
shell=True)
process.wait()