-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cpp
More file actions
81 lines (74 loc) · 3.46 KB
/
main.cpp
File metadata and controls
81 lines (74 loc) · 3.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#include <string>
#include <vector>
#include <cmath>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
void set_interface_attribs(int fd, int speed) {
termios tty{};
if (tcgetattr(fd, &tty) != 0) return; // copying current settings from file descriptor in tty
cfsetospeed(&tty, speed); // output speed
cfsetispeed(&tty, speed); // input speed
tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // setting strong format size for frame
tty.c_iflag &= ~IGNBRK; // turning off ignoring disconnect
tty.c_lflag = 0; // disable echo and canonical mode
tty.c_oflag = 0; // turning off output processing
tty.c_cc[VMIN] = 0; // read doesn't block (return immediately)
tty.c_cc[VTIME] = 5; // timeout for reading 0.5s
tty.c_cflag |= (CLOCAL | CREAD); // ignoring other console lines and accepting for reading from port
tty.c_cflag &= ~(PARENB | PARODD); // turning off checking errors
tty.c_cflag &= ~CSTOPB; // using 1 stop bit
tty.c_cflag &= ~CRTSCTS; // turning off hardware management
tcsetattr(fd, TCSANOW, &tty); // apply right now
}
int main(int argc, char* argv[]) {
const char* port = "/dev/ttyUSB0"; // or your any other device which you can see with command 'lsusb'
int num_leds = 255; // default value ( i guess )
int speed_baud = B115200; // also default value
std::string mode = (argc > 1) ? (argv[1]) : "neon";
float speed_step = (argc > 2) ? std::stof(argv[2]) : 0.15f;
int fd = open(port, O_RDWR | O_NOCTTY | O_SYNC); // read and write access | ignore terminal control signals | sync output
set_interface_attribs(fd, speed_baud); // set port speed
float t = 0;
std::vector<unsigned char> header = {'A', 'd', 'a', 0x00, 0xFF, 0xAA}; // Adalight protocol frame header for 255 leds
while (true) {
std::vector<unsigned char> payload;
payload.reserve(num_leds * 3);
for (int i = 0; i < num_leds; ++i) { // frame generating
float r = 0, g = 0, b = 0;
if (mode == "rainbow") {
float hue = fmodf(t + i * 0.05f, 6.0f);
float x = 255.0f * (1.0f - fabsf(fmodf(hue, 2.0f) - 1.0f));
if (hue < 1.0f) { r = 255; g = x; b = 0; }
else if (hue < 2.0f) { r = x; g = 255; b = 0; }
else if (hue < 3.0f) { r = 0; g = 255; b = x; }
else if (hue < 4.0f) { r = 0; g = x; b = 255; }
else if (hue < 5.0f) { r = x; g = 0; b = 255; }
else { r = 255; g = 0; b = x; }
} else if (mode == "red") r = 255;
else if (mode == "blue") b = 255;
else if (mode == "green") g = 255;
else if (mode == "purple") r = 128, b = 255;
else if (mode == "yellow") r = 255, g = 255;
else if (mode == "orange") r = 255, g = 140;
else if (mode == "turquoise") g = 255, b = 215;
else if (mode == "neon") {
float wave = (sin(t + i * 0.1f) + 1.0f) / 2.0f;
r = 120 + 135 * sin(t * 0.5f + i * 0.05f) / 2.0f;
b = 255 * wave;
} else return 1;
payload.push_back(static_cast<unsigned char>(r));
payload.push_back(static_cast<unsigned char>(g));
payload.push_back(static_cast<unsigned char>(b));
}
ssize_t res;
res = write(fd, header.data(), header.size());
res = write(fd, payload.data(), payload.size());
(void)res;
t += speed_step;
if (t > 1000.0) t = 0.0f;
usleep(20000); // 20ms = 50 FPS
}
close(fd);
return 0;
}