Sound2Light auf RGB(W)-LED-Leisten
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ws2801.c 2.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. /*
  2. * vim: sw=2 ts=2 expandtab
  3. *
  4. * THE PIZZA-WARE LICENSE" (derived from "THE BEER-WARE LICENCE"):
  5. * <cfr34k@tkolb.de> wrote this file. As long as you retain this notice you can
  6. * do whatever you want with this stuff. If we meet some day, and you think
  7. * this stuff is worth it, you can buy me a pizza in return. - Thomas Kolb
  8. */
  9. #include <sys/types.h>
  10. #include <sys/socket.h>
  11. #include <netdb.h>
  12. #include <unistd.h>
  13. #include <string.h>
  14. #include <stdio.h>
  15. #include "ws2801.h"
  16. #define SET_COLOR 0
  17. #define FADE_COLOR 1
  18. #define ADD_COLOR 2
  19. #define SET_FADESTEP 3
  20. struct WS2801Packet {
  21. uint8_t metadata;
  22. uint8_t data[3];
  23. };
  24. int ws2801_socket = -1;
  25. struct WS2801Packet packetQueue[50];
  26. int queueIndex = 0;
  27. // creates the socket needed for steering the LED strip
  28. int ws2801_init(const char *host, unsigned short port) {
  29. struct addrinfo hints;
  30. struct addrinfo *result;
  31. char portstr[6];
  32. memset(&hints, 0, sizeof(struct addrinfo));
  33. hints.ai_family = AF_UNSPEC;
  34. hints.ai_socktype = SOCK_DGRAM;
  35. hints.ai_flags = 0;
  36. hints.ai_protocol = 0;
  37. sprintf(portstr, "%u", port);
  38. if(getaddrinfo(host, portstr, &hints, &result) != 0) {
  39. perror("getaddrinfo() failed");
  40. return 1;
  41. }
  42. ws2801_socket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
  43. if (ws2801_socket == -1) {
  44. perror("socket() failed");
  45. freeaddrinfo(result);
  46. return 2;
  47. }
  48. if (connect(ws2801_socket, result->ai_addr, result->ai_addrlen) == -1) {
  49. perror("connect() failed");
  50. freeaddrinfo(result);
  51. return 3;
  52. }
  53. freeaddrinfo(result);
  54. return 0;
  55. }
  56. void ws2801_set_color(uint8_t module, uint8_t r, uint8_t g, uint8_t b) {
  57. packetQueue[queueIndex].metadata = (SET_COLOR << 6) | (module & 0x3F);
  58. packetQueue[queueIndex].data[0] = r;
  59. packetQueue[queueIndex].data[1] = g;
  60. packetQueue[queueIndex].data[2] = b;
  61. queueIndex++;
  62. }
  63. void ws2801_fade_color(uint8_t module, uint8_t r, uint8_t g, uint8_t b) {
  64. packetQueue[queueIndex].metadata = (FADE_COLOR << 6) | (module & 0x3F);
  65. packetQueue[queueIndex].data[0] = r;
  66. packetQueue[queueIndex].data[1] = g;
  67. packetQueue[queueIndex].data[2] = b;
  68. queueIndex++;
  69. }
  70. void ws2801_add_color(uint8_t module, uint8_t r, uint8_t g, uint8_t b) {
  71. packetQueue[queueIndex].metadata = (ADD_COLOR << 6) | (module & 0x3F);
  72. packetQueue[queueIndex].data[0] = r;
  73. packetQueue[queueIndex].data[1] = g;
  74. packetQueue[queueIndex].data[2] = b;
  75. queueIndex++;
  76. }
  77. void ws2801_set_fadestep(uint8_t fadestep) {
  78. packetQueue[queueIndex].metadata = (SET_FADESTEP << 6);
  79. packetQueue[queueIndex].data[0] = fadestep;
  80. queueIndex++;
  81. }
  82. int ws2801_commit(void) {
  83. if(send(ws2801_socket, packetQueue, queueIndex * sizeof(struct WS2801Packet), 0) == -1) {
  84. return 1;
  85. }
  86. queueIndex = 0;
  87. return 0;
  88. }
  89. void ws2801_shutdown() {
  90. close(ws2801_socket);
  91. }