Skip to content

Commit 9d58271

Browse files
committed
Init
0 parents  commit 9d58271

File tree

11 files changed

+145
-0
lines changed

11 files changed

+145
-0
lines changed

.vscode/arduino.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"sketch": "sketch.ino",
3+
"board": "arduino:avr:uno",
4+
"port": "/dev/cu.usbmodem1441"
5+
}

.vscode/c_cpp_properties.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"configurations": [
3+
{
4+
"name": "Mac",
5+
"includePath": [
6+
"/Applications/Arduino.app/Contents/Java/tools/**",
7+
"/Applications/Arduino.app/Contents/Java/hardware/arduino/avr/**"
8+
],
9+
"forcedInclude": [
10+
"/Applications/Arduino.app/Contents/Java/hardware/arduino/avr/cores/arduino/Arduino.h"
11+
],
12+
"macFrameworkPath": [
13+
"/System/Library/Frameworks",
14+
"/Library/Frameworks"
15+
],
16+
"intelliSenseMode": "clang-x64",
17+
"compilerPath": "/usr/bin/clang",
18+
"cStandard": "c11",
19+
"cppStandard": "c++17"
20+
}
21+
],
22+
"version": 4
23+
}

.vscode/settings.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"files.associations": {
3+
"cstddef": "cpp"
4+
},
5+
"python.pythonPath": "/usr/local/bin/python3"
6+
}

README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Arduino Fan Display
2+
## Prototype lol
3+
4+
DIY device I made using an Arduino Uno and some free time. Device was resurrected with brand new refactored firmware (a lot of time passed from the moment this device was originally created).
5+
6+
sketch.ino - Arduino Sketch. outputArray contains binary image to be displayed.
7+
img2bin.py - Python Script. Converts image to the outputArray format.
8+
9+
Each LED owns his own bit in int value (1led=1; 2led=2; 3led=4 e.t.c.). Sum of active bits is the value of vertical line to be displayed in one time unit.
10+
Phototransistor checks for the new lap and triggers the controller using interrupts.
11+
12+
* Proof that this one actually works:
13+
![Oops. Image was here](https://github.com/DV1X3R/fan-display/raw/master/img/demo.gif)
14+
15+
* Photo
16+
![Oops. Image was here](https://github.com/DV1X3R/fan-display/raw/master/img/photo.jpg)
17+
18+
* Schema
19+
![Oops. Image was here](https://github.com/DV1X3R/fan-display/raw/master/img/schema.jpg)

img/demo.gif

3.81 MB
Loading

img/nudes.png

4.81 KB
Loading

img/photo.jpg

72.7 KB
Loading

img/schema.jpg

21.5 KB
Loading

img/schema.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<mxfile userAgent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/7.9.5 Chrome/58.0.3029.110 Electron/1.7.5 Safari/537.36" version="9.1.2" editor="www.draw.io" type="device"><diagram name="Page-1" id="7e0a89b8-554c-2b80-1dc8-d5c74ca68de4">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</diagram></mxfile>

img2bin.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import sys
2+
from pathlib import Path
3+
from PIL import Image
4+
5+
if len(sys.argv) > 1:
6+
path = sys.argv[1]
7+
else:
8+
path = str(Path.home()) + "/Sourcetree/fan-display/img/nudes.png"
9+
10+
im = Image.open(path)
11+
px = im.load()
12+
13+
print("Image Size: " + str(im.size))
14+
15+
lines = []
16+
for w in range(0, im.size[0]):
17+
line = 0
18+
for h in range(0, im.size[1]):
19+
line += 1 << h if px[w, h][0] == 0 else 0
20+
lines.append(line)
21+
22+
print("Array: " + str(lines))

sketch.ino

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
const byte TR = 2; // Phototransistor pin
2+
const byte LEDS[8] = {10, 9, 8, 7, 6, 5, 4, 3}; //{3, 4, 5, 6, 7, 8, 9, 10}; // LED pins
3+
4+
// Nudes
5+
byte outputArray[100] = {255, 1, 2, 4, 8, 16, 32, 64, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 73, 73, 73, 50, 0, 0, 127, 73, 73, 73, 0, 0, 127, 7, 28, 112, 127, 0, 0, 127, 65, 65, 62, 0, 0, 0, 0, 0, 127, 7, 28, 112, 127, 0, 0, 127, 64, 64, 127, 0, 0, 127, 65, 65, 62, 0, 0, 127, 73, 73, 73, 0, 0, 6, 73, 73, 73, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 64, 32, 16, 8, 4, 2, 1, 255};
6+
// Test
7+
//byte outputArray[100] = {129, 66, 36, 24, 24, 36, 66, 129, 66, 36, 24, 24, 36, 66, 129, 4, 4, 20, 20, 84, 80, 80, 64, 64, 64, 64, 0, 0, 0, 0, 0, 255, 9, 9, 9, 9, 0, 0, 126, 129, 129, 129, 129, 126, 0, 3, 14, 56, 96, 192, 96, 56, 14, 3, 0, 0, 0, 0, 0, 254, 130, 186, 170, 162, 190, 128, 255, 0, 0, 0, 0, 0, 0, 0, 64, 64, 64, 64, 80, 80, 84, 20, 20, 4, 4, 129, 66, 36, 24, 24, 36, 66, 129, 66, 36, 24, 24, 36, 66, 129};
8+
9+
const unsigned long interruptLapBounceMcs = 50000; // prevent fake interrupts; 0,05s = 1200 RPM MAX; Larger bounce -> Lower Speed
10+
const byte extraStepsOffset = 5; // offset to display last array element
11+
12+
volatile bool rotateLap = false;
13+
volatile unsigned long outputIndex = 0;
14+
volatile unsigned long timePerStep = 0;
15+
volatile unsigned long nextStepTime = 0;
16+
volatile unsigned long prevLapStartTime = 0;
17+
18+
void lap()
19+
{
20+
unsigned long itMicros = micros();
21+
if (itMicros - prevLapStartTime > interruptLapBounceMcs)
22+
{
23+
outputIndex = 0; // reset output index
24+
rotateLap = true; // trigger rotation
25+
unsigned long lapTime = itMicros - prevLapStartTime; // calculate previous lap time
26+
timePerStep = lapTime / (sizeof(outputArray) + extraStepsOffset); // one step time = (lap / (128 + delta)
27+
prevLapStartTime = itMicros; // recotd new lap start time
28+
nextStepTime = itMicros + timePerStep; // set next step time
29+
}
30+
}
31+
32+
void rotate()
33+
{
34+
byte tmp = outputArray[0];
35+
for (int i = 0; i < sizeof(outputArray) - 1; i++)
36+
outputArray[i] = outputArray[i + 1];
37+
outputArray[sizeof(outputArray) - 1] = tmp;
38+
}
39+
40+
void setup()
41+
{
42+
pinMode(TR, INPUT); // phototransistor init
43+
attachInterrupt(digitalPinToInterrupt(TR), lap, RISING); // phototransistor (new lap checker) interrupt
44+
45+
for (int i = 0; i < sizeof(LEDS); i++)
46+
pinMode(LEDS[i], OUTPUT); // leds init
47+
48+
//for (int i = 0; i < sizeof(outputArray); i++)
49+
//outputArray[i] = i + 1;
50+
}
51+
52+
void loop()
53+
{
54+
unsigned long loopMicros = micros();
55+
if ((loopMicros >= nextStepTime) && (outputIndex < sizeof(outputArray) - 1))
56+
{ // current outputArray step update
57+
nextStepTime = loopMicros + timePerStep;
58+
outputIndex++;
59+
}
60+
61+
if (rotateLap)
62+
{ // text rotation
63+
rotate();
64+
rotateLap = false;
65+
}
66+
67+
for (int i = 0; i < sizeof(LEDS); i++) // output cycle
68+
digitalWrite(LEDS[i], ((1 << i) & outputArray[outputIndex]) != 0);
69+
}

0 commit comments

Comments
 (0)