Änderungen

Aus Hackerspace Ffm
Wechseln zu: Navigation, Suche

Rundbunt Mini

13.166 Byte hinzugefügt, 15:07, 28. Dez. 2015
== Software ==
Arduino Projekt Download [[Datei:RundbuntMini_V1RundBuntMini_V2.zip]]
Die Software verwendet die Bibliotheken Flash und Bibliothek FastLED (statt Adafruits Neopixel Bibliothek, da diese keine so schönen Farbraumkonversationsroutinen besitzt). Eine Art Renderpipeline bringt die als HSV-Array[0..63] vorgerechneten Daten auf die Lampe, dabei werden die HSV-Werte in RGB-Werte umgerechnet, eine Gamma-Korrektur von 2.4 per Tabelle darauf geworfen und dann diese Daten in die richtige Reihenfolge für die LEDs gebracht (Zick-Zack und Offset-Korrektur). Der Einfachheit legt sich die Pixelfläche wie ein rechteckiges Blatt von vorne auf den Zylinder, hinten links unten ist Pixel 0, Pixel 7 ist hinten links oben, dann geht es bei Pixel 8 in der nächsten Spalte wieder etwas weniger hinten links unten weiter. Die Spalten laufen einmal von Mitte-Links-Hinten über Vorne-Mitte nach Mitte-Rechts-Hinten. Dadurch ist der Rand der 8x8 Pixelfläche auf der Rückseite der Lampe, die typischerweise mit den Potis nach vorne aufgestellt wird.
Die Potis werden etwas "entrauschst" und das erste Poti bestimmt die Animation:
1. # Lampe wird mit einer konstanten Farbe "angemalt", Farbe (Hue) und Sättigung (Saturation) können per Poti eingestellt werden. 2. # Linear wird ein laufender "Hue"-Wert (Regenbogen) von Pixel 0 bis Pixel 63 ausgegeben. Das eine Poti bestimmt die Schrittweite, das andere den Start-Wert der Farbe. Werden die Potis über die Hälfte gedreht, so werden diese Werte dynamisch verändert, Potiausschlag bestimmt die Änderungsgeschwindigkeit. Es ergeben sich sehr schöne Farbübergänge, die mal horizontal, mal vertikal, mal schräg, mal wild über die Lampe wabern.3. # Kaleidoskop: Der Quadrant links unten (4x4 Pixel) wird mit zufälligen Farben "bepixelt", wobei sich immer nur ein Pixel langsam in der Farbe verändert. Die untere Ecke wird an die drei verbleibenen Quadranten gespiegelt. Es ergibt sich ein symetrischer Farbeffekt. Über die Potis kann die Änderungsgeschwindigkeit und die Farbwahl eingestellt werden. Farbwahl: Weit nach links: viele dunkle Pixel, mittig: keine dunklen, keine weißen Pixel, weiter nach rechts: mehr Pixel, die auch weiß sind.4. # Plasmaeffekt: Der Klassiker, der Ausgangswert der Plasmasummenformel wird über ein Poti-Wert einstellbar verschieden stark in den Hue-Wert skaliert. Über das andere Poti kann die Änderungsgeschwindigkeit des Plasmaeffektes eingestellt werden.
== Bilder ==
== Materialliste ==
<big><big>{| class="wikitable sortable" style="text-align:rightleft" ! Anzahl !! Teil !! style="text-align:right" | Preis !! Kaufen bei
|-
| 1
| Tischleuchte BOXXX &Oslash; 10cm, H: 20 cm
| style="text-align:right" | 5,00
| XXL
|-
| 1 | Holzkern &Oslash; 2,5cm + Halbzeug| style="text-align:right" | 2,00
| Baumarkt
|-
| 1
| Neopixelstreifen mit 64 LEDs, 60 LEDs/m
| style="text-align:right" | 19,00
| Ebay
|-
| 1 | 3x Poti 10k (522-0439) + 3310Y von Bourns <br> 3x Potiknopf (Alu Design) (465-9814)| style="text-align:right" | 13,00
| RS-Online
|-
| 1
| Netzeil 5V, 2.5A (SNT 2500 5V) + Hohlbuchse 2.1mm (HEBL 21)
| style="text-align:right" | 13,00| Reichelt
|-
| 1
| Arduino Pro Mini
| style="text-align:right" | 3,00
| EBay
|-
| 1
| Kursgebühr für Nicht-Mitglieder
| style="text-align:right" | 20,00
| Hackerspace FFM
|-
|}
 
'''Summe Teile ohne Kursgebühr: 55,00 EUR'''
</big></big>
 
== Nachbau ==
=== Lampe zerlegen ===
<gallery widths=350px heights=250px perrow=2>
Datei:RundBuntMiniAufbauA01.jpg|Alles auspacken, Lampenschirm am besten noch in der Luftpolsterfolie belassen.
Datei:RundBuntMiniAufbauA02.jpg|Abdeckung am Boden abziehen. Je nach dem ob man steiler oder weniger steil zieht, geht es mehr oder weniger Rückstandfrei ab.
Datei:RundBuntMiniAufbauA03.jpg|Die Abdeckung kann ggf. später weiterverwendet werden.
Datei:RundBuntMiniAufbauA04.jpg|Zugentlastung fürs Kabel abschrauben und entfernen.
Datei:RundBuntMiniAufbauA05.jpg|Haltemutter für Lampensockel komplett abschrauben.
Datei:RundBuntMiniAufbauA06.jpg|Kabel durchknipsen
Datei:RundBuntMiniAufbauA07.jpg|Lampensockel öffnen (notfalls destruktiv - Kunststoffsockel wird nicht benötigt).
Datei:RundBuntMiniAufbauA08.jpg|Gewinde vorsichtig aus Lampensockel heraus schrauben - dieser wird später noch benötigt.
</gallery>
 
 
'''Überblick über die gewonnenen Teile:'''
 
[[Datei:RundBuntMiniAufbauA09.jpg|720px|Überblick über die gewonnenen Teile.]]
 
 
=== Lampensockel bohren ===
* Das Loch für das ehemalige 230V Kabel aufbohren auf 8mm
* Gegenüberliegend 3 Löcher 6mm für die Potis, die beiden äußeren 45° versetzt
 
<gallery widths=350px heights=250px perrow=2>
Datei:Rundbunt Anriss 3.jpg|Bohrungen - Plan
Datei:Rundbunt Anriss 1 IMAG2697.jpg|Behelfs-Parallel-Anriss mit 9 Volt Block und Bleistift :-)
Datei:Rundbunt Anriss 2 IMAG2697.jpg|Gebohrt
Datei:Rundbunt Anriss 4.jpg|Anfang der Verkabelung
</gallery>
 
 
 
=== Matrix auf Stab erstellen und löten ===
[[Datei:RundBuntMiniMatrix.png|So wird die Matrix gelötet.]]
 
 
 
=== Potis vorbereiten ===
[[Datei:RundBuntMiniPotis.png]]
 
 
[[Datei:Rundbunt Poti IMAG2697.jpg|240px]]
 
 
 
=== Alles zusammen bauen ===
[[Datei:Rundbunt_Mini_Bau2.png|720px]]
 
 
 
=== Firmware ===
Es wird die zusätzlich die Library [http://fastled.io/ FastLED] benötigt.
<pre>
/*
The MIT License (MIT)
 
Copyright (c) 2015, Lutz Lisseck (lutz. lisseck AT gmx. de)
 
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
 
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
 
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
 
// #define FORCE_SOFTWARE_SPI
// #define FORCE_SOFTWARE_PINS
 
#include "FastLED.h"
 
// How many leds are in the strip?
#define NUM_LEDS 64
 
// Data pin that led data will be written out over
#define DATA_PIN 6
 
// 5 lines with 8 pix shift in this situation
#define PIXSHIFT 40
 
#define GAMMA 2.4
const PROGMEM uint8_t gamma_table[] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,8,8,8,9,9,9,10,
10,10,11,11,11,12,12,13,13,14,14,14,15,15,16,16,17,17,18,18,19,19,20,20,21,22,22,23,23,24,24,25,26,26,27,28,28,29,30,30,31,32,32,33,
34,35,35,36,37,38,39,39,40,41,42,43,43,44,45,46,47,48,49,50,51,52,53,53,54,55,56,57,58,59,60,62,63,64,65,66,67,68,69,70,71,73,74,75,
76,77,78,80,81,82,83,85,86,87,88,90,91,92,94,95,96,98,99,100,102,103,105,106,108,109,111,112,114,115,117,118,120,121,123,124,126,127,
129,131,132,134,136,137,139,141,142,144,146,148,149,151,153,155,156,158,160,162,164,166,167,169,171,173,175,177,179,181,183,185,187,
189,191,193,195,197,199,201,203,205,207,210,212,214,216,218,220,223,225,227,229,232,234,236,239,241,243,246,248,250,253,255 };
 
// This is an array of leds. One item for each led in your strip.
CRGB leds[NUM_LEDS];
 
CHSV hsvbuf1[NUM_LEDS];
//CHSV hsvbuf2[NUM_LEDS];
CRGB rgbbuf1[NUM_LEDS];
 
// parameters from potis
int para[3];
 
// Auto animation here later...
void getPara(void) {
static int paraInt[3];
paraInt[0] = analogRead(A0);
paraInt[1] = analogRead(A1);
paraInt[2] = analogRead(A2);
if(abs(paraInt[0] - para[0]) > 2) para[0] = paraInt[0];
if(abs(paraInt[1] - para[1]) > 0) para[1] = paraInt[1];
if(abs(paraInt[2] - para[2]) > 0) para[2] = paraInt[2];
}
 
// This function sets up the ledsand tells the controller about them
void setup() {
Serial.begin(9600);
FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
Serial.print("Mem: "); Serial.println(availableMemory());
randomSeed(analogRead(A7)+analogRead(A1));
getPara();
for(uint8_t i=0; i<NUM_LEDS; i++) { leds[i] = CRGB::Black; hsvbuf1[i] = CHSV(0,0,0); }
FastLED.show();
delay(1000);
}
 
// Copy HSV to RGB, rearranged and show
void showHSV(const struct CHSV * phsv) {
CRGB *pLed;
pLed = &leds[PIXSHIFT];
for(uint8_t i=0; i<NUM_LEDS; i++) {
if((i+PIXSHIFT)==NUM_LEDS) pLed = &leds[0];
if(i & 8) {
hsv2rgb_rainbow(phsv[i], *pLed++);
} else {
hsv2rgb_rainbow(phsv[i^7], *pLed++);
}
}
FastLED.show();
}
 
// Copy HSV to RGB, rearranged, gamma-corrected and show
void showHSVg(const struct CHSV * phsv) {
CRGB *pLed;
pLed = &leds[PIXSHIFT];
for(uint8_t i=0; i<NUM_LEDS; i++) {
if((i+PIXSHIFT)==NUM_LEDS) pLed = &leds[0];
if(i & 8) {
hsv2rgb_rainbow(phsv[i], *pLed);
} else {
hsv2rgb_rainbow(phsv[i^7], *pLed);
}
pLed->r = pgm_read_byte_near(gamma_table + pLed->r);
pLed->g = pgm_read_byte_near(gamma_table + pLed->g);
pLed->b = pgm_read_byte_near(gamma_table + pLed->b);
pLed++;
}
FastLED.show();
}
 
// Copy RGB to RGB, rearranged and show
void showRGB(const struct CRGB * prgb) {
CRGB *pLed;
pLed = &leds[PIXSHIFT];
for(uint8_t i=0; i<NUM_LEDS; i++) {
if((i+PIXSHIFT)==NUM_LEDS) pLed = &leds[0];
if(i & 8) {
*pLed++ = prgb[i];
} else {
*pLed++ = prgb[i^7];
}
}
FastLED.show();
}
 
void rearrangeLeds(void) {
CRGB C, *pCa, *pCb;
for(uint8_t i=8; i < NUM_LEDS; i+=16) {
pCa = &leds[i]; pCb = &leds[i+7];
for(uint8_t j=0; j <= 3; j++) {
C = *pCa;
*pCa++ = *pCb;
*pCb-- = C;
//C = leds[i+j];
//leds[i+j] = leds[i+(7-j)];
//leds[i+(7-j)] = C;
}
}
}
 
 
void loop() {
#define AnimCount 4
int para0remain, para0main;
getPara();
para0main = (para[0]*AnimCount)/1024;
para0remain = map(para[0]%(1024/AnimCount),0,(1024/AnimCount)-1,0,255);
switch(para0main) {
case 0:
if(para0remain < 4) {
// turn all off
for(uint8_t i=0; i<NUM_LEDS; i++) { leds[i] = CRGB::Black; hsvbuf1[i] = CHSV(0,0,0); }
FastLED.show();
// optional: Power down stuff here...
}
else
{
// lightpainter to one color
CHSV hsv_col(para[2]/4,para[1]/4,min(255,para0remain+32));
for(uint8_t i=31; i>0; i--) {
hsvbuf1[i] = hsvbuf1[i-1];
}
hsvbuf1[0] = hsvbuf1[NUM_LEDS-1];
for(uint8_t i=NUM_LEDS-1; i>32; i--) {
hsvbuf1[i] = hsvbuf1[i-1];
}
hsvbuf1[32] = hsv_col;
showHSVg(hsvbuf1);
delay(30);
}
break;
case 1:
{
// Rainbow-Fill animation
static float p2_mover = 0.0;
static float hue_mover = 0.0;
int para1rem = para[1]%512;
p2_mover += pow(para1rem/511.0,4.0); if(p2_mover > 255.0) p2_mover = 0.0;
if(para[1] >= 512) para1rem = p2_mover;
int para2rem = para[2]%512;
hue_mover += pow(para2rem/511.0,4.0); if(hue_mover > 255.0) hue_mover = 0.0;
if(para[2] >= 512) para2rem = int(hue_mover);
CHSV hsv_col(para2rem,255,min(para0remain,255));
float hue_f = para2rem;
for(uint8_t i=0; i<NUM_LEDS; i++) {
hsv_col.h = int(hue_f);
hsvbuf1[i] = hsv_col;
hue_f += para1rem/8.0;
}
//Serial.println(int(hue_f));
showHSVg(hsvbuf1);
}
break;
case 2:
{
// =======================
// ==== kaleidoscope =====
// =======================
//for(uint8_t i=0; i<NUM_LEDS; i++) hsvbuf1[i].v = 0;
// light-up pixel in lower-left corner
static unsigned char pix_addr = 0;
static CHSV hsv_target;
static CHSV hsv_source;
static float step_part = 0.0;
uint8_t v_max = min(255,para0remain+32);
// target color adapted or not?
if(hsv_source != hsv_target) {
float old_step = step_part;
int do_step;
step_part += para[1]/64.0;
do_step = int(step_part - old_step);
step_part -= do_step;
if(step_part > 100.0) step_part -= 100.0;
// slowly (with do_step) adjust hsv to target
if(hsv_source.s < hsv_target.s) {
hsv_source.s = min((int)hsv_target.s, hsv_source.s + do_step);
} else {
hsv_source.s = max((int)hsv_target.s, hsv_source.s - do_step);
}
if(hsv_source.h < hsv_target.h) {
hsv_source.h = min((int)hsv_target.h, hsv_source.h + do_step);
} else {
hsv_source.h = max((int)hsv_target.h, hsv_source.h - do_step);
}
if(hsv_source.v < hsv_target.v) {
hsv_source.v = min((int)hsv_target.v, hsv_source.v + do_step);
} else {
hsv_source.v = max((int)hsv_target.v, hsv_source.v - do_step);
}
hsvbuf1[pix_addr] = hsv_source;
} else {
// choose new pixel and new color
pix_addr = random(32) & 0x1b; // limit to one quadrant
hsv_target.h = random(256);
hsv_target.s = (para[2]>=512)?((random(512)>(para[2]-512))?255:0):255;
hsv_target.v = (para[2]>=512)?v_max:((random(512)>(para[2]))?0:v_max);
hsv_source = hsvbuf1[pix_addr];
}
// big pixel hack
/*
hsvbuf1[12] = hsvbuf1[18];
hsvbuf1[17] = hsvbuf1[18];
hsvbuf1[9] = hsvbuf1[18];
hsvbuf1[11] = hsvbuf1[19];
hsvbuf1[25] = hsvbuf1[26];
hsvbuf1[8] = hsvbuf1[16];
hsvbuf1[2] = hsvbuf1[1];
*/
// clone pixels to other corners
for(uint8_t i=0;i<32;i++) {
if(i & 0x04) i+=4;
if(i != pix_addr) { hsvbuf1[i].v = hsvbuf1[i].v?v_max:0;}
hsvbuf1[(7-(i&0x03))|(i&0x18)] = hsvbuf1[i];
hsvbuf1[(56-(i&0x18))|(i&0x03)] = hsvbuf1[i];
hsvbuf1[(56-(i&0x18))|(7-(i&0x03))] = hsvbuf1[i];
}
showHSVg(hsvbuf1);
}
break;
case 3:
{
float v,cx,cy,t;
static int para1, para2;
if(abs(para1 - para[1]) > 4) para1 = para[1];
if(abs(para2 - para[2]) > 4) para2 = para[2];
t = millis()/(10000.0/pow(para1/511.0,4.0));
for(uint8_t x=0; x<8; x++) {
for(uint8_t y=0; y<8; y++) {
v = sin(x*0.2+t);
v += sin(0.2*(x*sin(t/2)+y*cos(t/3))+t);
cx = x - 3.5 + 5.0*sin(t/3.0);
cy = y - 3.5 + 5.0*cos(t/3.0);
v += sin(sqrt(0.2*(cx*cx+cy*cy)+0.0)+t);
hsvbuf1[x*8+y].h = v*para2;
hsvbuf1[x*8+y].s = 255;
hsvbuf1[x*8+y].v = min(255,para0remain+32);
}
}
 
showHSVg(hsvbuf1);
}
break;
case 4:
{
static float edge;
edge = para[1]/100.0;
for(uint8_t i=NUM_LEDS-1; i>7; i--) {
hsvbuf1[i] = hsvbuf1[i-8];
}
for(uint8_t i=0;i<=7;i++) {
hsvbuf1[i].s = (i>int(edge))?0:255;
if(int(edge) == i) hsvbuf1[i].s = int((edge-(i))*255.0);
hsvbuf1[i].h = 140;
hsvbuf1[i].v = min(255,para0remain+32);
}
showHSVg(hsvbuf1);
delay(100);
}
break;
default:
showHSV(hsvbuf1);
break;
}
}
 
int availableMemory()
{
int size = 1024;
byte *buf;
while ((buf = (byte *) malloc(--size)) == NULL);
free(buf);
return size;
}
 
</pre>
 
 
== Muster entwickeln ==
* [[Rundbunt Mini Emulator]] unter [https://processing.org/ Processing] zur Entwicklung neuer Muster auf dem Desktop.
* Weitere fertige Muster sind unter [[Rundbunt Mini Pattern]] zu finden.
 
== Weiterentwicklung ==
 
[[Rundbunt Mini WIFI]]
[[Kategorie:Projekte]]
688
Bearbeitungen