Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
Nächste Überarbeitung | Vorhergehende Überarbeitung | ||
project:alma [28.06.2014 21:38] – angelegt schmofu | project:alma [28.12.2015 23:42] (aktuell) – aktualisiert schmofu | ||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
====== ALMA – Aldi Led MAtrix | ====== ALMA – Aldi Led MAtrix | ||
+ | Die LED-Matrix steht derzeit im Erdgeschoss des Raums. Sie ist an die MediaBox angeschlossen. | ||
- | Anschluss: Mini-USB\\ | + | Man kann sie mit Animationen bespielen. Hierzu wird der [[https:// |
- | Das Display | + | |
+ | Zum Testen könnte man beispielsweise folgendes asuführen: | ||
+ | while true ; do python animations/ | ||
+ | |||
+ | :!: Die RGB-Werte Blau-Rot-Grün (also anders als bei mit der Lightwall). | ||
+ | |||
+ | |||
+ | ===== Details ===== | ||
+ | |||
+ | Die 8 x 12 RGB-Pixel LED Matrix basiert auf den digital LED Streifen, die es dereinzt bei Feinkost-Albrecht, | ||
+ | |||
+ | Ein passendes 12 V Netzteil liegt neben der Matrix. Neben dem Regal (Spiegel) steht eine noch nicht passend zugeschnitte Abdeckplatte aus oparkem Kunststoff. | ||
+ | |||
+ | An ALMA hängt ein kleiner USB Controller. (MicroUSB Kabel mitbringen.) Dieser | ||
Zeile 14: | Zeile 28: | ||
{{: | {{: | ||
{{: | {{: | ||
+ | |||
+ | |||
+ | ===== Beispielcode ===== | ||
+ | |||
+ | Das folgende Programm demonstriert die Benutzung der Matrix mit einem MacOS X bzw. Linux Rechner. Wer weitere Fragen dazu hat kann einfach Jochen/ | ||
+ | |||
+ | <file c host_ctrl.c> | ||
+ | /* | ||
+ | * Copyright (c) 2013 Jochen Kunz. | ||
+ | * All rights reserved. | ||
+ | * | ||
+ | * Redistribution and use in source and binary forms, with or without | ||
+ | * modification, | ||
+ | * are met: | ||
+ | * 1. Redistributions of source code must retain the above copyright | ||
+ | | ||
+ | * 2. Redistributions in binary form must reproduce the above copyright | ||
+ | | ||
+ | | ||
+ | * | ||
+ | * THIS SOFTWARE IS PROVIDED BY JOCHEN KUNZ | ||
+ | * ``AS IS'' | ||
+ | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
+ | * PURPOSE ARE DISCLAIMED. | ||
+ | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
+ | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
+ | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
+ | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
+ | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
+ | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
+ | * POSSIBILITY OF SUCH DAMAGE. | ||
+ | */ | ||
+ | |||
+ | |||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | |||
+ | // Gesammtanzahl der Pixel. | ||
+ | // 1 x 5 m Streifen = 50 | ||
+ | // 2 x 5 m Streifen hinereinander = 100 | ||
+ | # | ||
+ | |||
+ | typedef struct { | ||
+ | uint16_t h; | ||
+ | uint8_t s; | ||
+ | uint8_t v; | ||
+ | } hsv_t; | ||
+ | |||
+ | |||
+ | /* | ||
+ | primitive Geradeausimplementierung in Fixkomma nach: | ||
+ | https:// | ||
+ | h = [0..1535] = [0..(256 * 6 - 1)] | ||
+ | s, v = [0..255] | ||
+ | */ | ||
+ | void | ||
+ | hsv2rgb( uint16_t h, uint8_t s, uint8_t v, uint8_t *r, uint8_t *g, uint8_t *b) { | ||
+ | assert( h < (255 * 6)); | ||
+ | assert( s <= 255); | ||
+ | assert( v <= 255); | ||
+ | v = (v * v) / 255; // Gammakorrektur, | ||
+ | uint8_t hi = h / 255; | ||
+ | uint8_t f = h - hi * 255; | ||
+ | uint8_t p = (v * (255 - s)) / 255; | ||
+ | uint8_t q = (v * (255 - (s * f) / 255)) / 255; | ||
+ | uint8_t t = (v * (255 - (s * (255 - f)) / 255)) / 255; | ||
+ | switch (hi) { | ||
+ | case 0: | ||
+ | case 6: | ||
+ | *r = v; | ||
+ | *g = t; | ||
+ | *b = p; | ||
+ | break; | ||
+ | case 1: | ||
+ | *r = q; | ||
+ | *g = v; | ||
+ | *b = p; | ||
+ | break; | ||
+ | case 2: | ||
+ | *r = p; | ||
+ | *g = v; | ||
+ | *b = t; | ||
+ | break; | ||
+ | case 3: | ||
+ | *r = p; | ||
+ | *g = q; | ||
+ | *b = v; | ||
+ | break; | ||
+ | case 4: | ||
+ | *r = t; | ||
+ | *g = p; | ||
+ | *b = v; | ||
+ | break; | ||
+ | case 5: | ||
+ | *r = v; | ||
+ | *g = p; | ||
+ | *b = q; | ||
+ | break; | ||
+ | }; | ||
+ | } | ||
+ | |||
+ | |||
+ | int | ||
+ | write_rgb_buf( int port_fd, uint8_t buf[], size_t buf_len) { | ||
+ | int retval = write( port_fd, buf, buf_len); | ||
+ | if (retval < 0) { | ||
+ | perror( " | ||
+ | return -1; | ||
+ | } | ||
+ | if (retval != buf_len) { | ||
+ | printf( "Short write(2) to port, retval=%d", | ||
+ | return -1; | ||
+ | } | ||
+ | return 0; | ||
+ | } | ||
+ | |||
+ | |||
+ | void | ||
+ | schnarch( int sec, int msec) { | ||
+ | struct timespec ts; | ||
+ | ts.tv_sec = sec + msec / 256000000; | ||
+ | ts.tv_nsec = (msec * 256000) % 256000000; | ||
+ | while (nanosleep( &ts, &ts) != 0) {}; | ||
+ | } | ||
+ | |||
+ | |||
+ | // Farbfolge WS2801: rot, grün, blau | ||
+ | // Farbfolge TM1829: blau, rot, grün | ||
+ | void | ||
+ | convert_buf( hsv_t hsv_buf[], size_t hsv_buf_len, | ||
+ | memset( rgb_buf, 0, rgb_buf_len); | ||
+ | for (int idx = 0; idx + 2 < rgb_buf_len; | ||
+ | hsv2rgb( | ||
+ | hsv_buf[ (idx / 3) % hsv_buf_len].h, | ||
+ | hsv_buf[ (idx / 3) % hsv_buf_len].s, | ||
+ | hsv_buf[ (idx / 3) % hsv_buf_len].v, | ||
+ | & | ||
+ | } | ||
+ | } | ||
+ | |||
+ | |||
+ | int | ||
+ | write_hsv_buf( int port_fd, hsv_t hsv_buf[], size_t hsv_buf_len) { | ||
+ | uint8_t rgb_buf[ 512]; | ||
+ | convert_buf( hsv_buf, hsv_buf_len, | ||
+ | return write_rgb_buf( port_fd, rgb_buf, sizeof( rgb_buf)); | ||
+ | } | ||
+ | |||
+ | |||
+ | void | ||
+ | usage( void) { | ||
+ | fprintf( stderr, " | ||
+ | " | ||
+ | " | ||
+ | "-0: short for \"-h 0 -s 0 -v 0\" | ||
+ | } | ||
+ | |||
+ | |||
+ | int | ||
+ | main( int argc, char* const argv[]) { | ||
+ | const char* port_fn = "/ | ||
+ | hsv_t hsv; | ||
+ | hsv.h = 0; | ||
+ | hsv.s = 0; | ||
+ | hsv.v = 0; | ||
+ | bool zero = false; | ||
+ | int opt; | ||
+ | while ((opt = getopt( argc, argv, " | ||
+ | switch (opt) { | ||
+ | case ' | ||
+ | port_fn = optarg; | ||
+ | break; | ||
+ | case ' | ||
+ | zero = true; | ||
+ | break; | ||
+ | case ' | ||
+ | zero = true; | ||
+ | hsv.h = atoi( optarg); | ||
+ | break; | ||
+ | case ' | ||
+ | zero = true; | ||
+ | hsv.s = atoi( optarg); | ||
+ | break; | ||
+ | case ' | ||
+ | zero = true; | ||
+ | hsv.v = atoi( optarg); | ||
+ | break; | ||
+ | default: | ||
+ | usage(); | ||
+ | return EXIT_FAILURE; | ||
+ | } | ||
+ | } | ||
+ | int port_fd = open( port_fn, O_RDWR | O_NONBLOCK | O_CLOEXEC); | ||
+ | if (port_fd < 0) { | ||
+ | perror( " | ||
+ | return EXIT_FAILURE; | ||
+ | } | ||
+ | if (isatty( port_fd) <= 0 ) { | ||
+ | perror( " | ||
+ | return EXIT_FAILURE; | ||
+ | } | ||
+ | struct termios tio; | ||
+ | if (tcgetattr( port_fd, &tio) < 0) { | ||
+ | perror( " | ||
+ | return EXIT_FAILURE; | ||
+ | } | ||
+ | tio.c_iflag &= ~ICANON; | ||
+ | tio.c_oflag = 0; | ||
+ | tio.c_lflag = 0; | ||
+ | tio.c_cflag = (CS8 | CREAD | CLOCAL); | ||
+ | tio.c_cc[VMIN] = 1; | ||
+ | tio.c_cc[VTIME] = 0; | ||
+ | cfsetispeed( &tio, B9600); | ||
+ | cfsetospeed( &tio, B9600); | ||
+ | if (tcsetattr( port_fd, TCSANOW, &tio) < 0) { | ||
+ | perror( "Error setting termis" | ||
+ | exit( EXIT_FAILURE); | ||
+ | } | ||
+ | int retval = fcntl( port_fd, F_GETFL, 0); | ||
+ | if (retval < 0) { | ||
+ | perror( " | ||
+ | return EXIT_FAILURE; | ||
+ | } | ||
+ | |||
+ | retval &= ~O_NONBLOCK; | ||
+ | retval = fcntl( port_fd, F_SETFL, retval); | ||
+ | if (retval < 0) { | ||
+ | perror( " | ||
+ | return EXIT_FAILURE; | ||
+ | } | ||
+ | hsv_t hsv_buf[ PIXEL_LEN]; | ||
+ | if (zero) { | ||
+ | if (write_hsv_buf( port_fd, &hsv, 1) < 0) { | ||
+ | return EXIT_FAILURE; | ||
+ | } | ||
+ | return EXIT_SUCCESS; | ||
+ | } | ||
+ | |||
+ | for (int loops = 0; loops < 2560; ++loops) { | ||
+ | memset( hsv_buf, 0, sizeof( hsv_buf)); | ||
+ | for (int idx = 0; idx < PIXEL_LEN; ++idx) { | ||
+ | /* | ||
+ | hsv_buf[ idx].h = ((idx + loops) % 12) * ((6 * 255 - 1) / 12); | ||
+ | hsv_buf[ idx].s = 255; | ||
+ | hsv_buf[ idx].v = 255; | ||
+ | */ | ||
+ | // | ||
+ | hsv_buf[ idx].h = ((idx + loops) % PIXEL_LEN) * ((6 * 255 - 1) / PIXEL_LEN); | ||
+ | hsv_buf[ idx].s = 255; | ||
+ | // | ||
+ | hsv_buf[ idx].v = 255; | ||
+ | // | ||
+ | } | ||
+ | if (write_hsv_buf( port_fd, hsv_buf, PIXEL_LEN) < 0) { | ||
+ | return EXIT_FAILURE; | ||
+ | } | ||
+ | // | ||
+ | } | ||
+ | return EXIT_SUCCESS; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ==== Metadaten ==== | ||
+ | ---- dataentry projekt ---- | ||
+ | name : ALMA | ||
+ | contact | ||
+ | tags_tags | ||
+ | type : projekt | ||
+ | subtype | ||
+ | sticky_hidden : no | ||
+ | ---- | ||
+ | |||
+ |