-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathDMX-MovingHead.ino
199 lines (168 loc) · 4.29 KB
/
DMX-MovingHead.ino
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
#include <DmxSimple.h>
#define CH_X_GROSS 1
#define CH_X_FINE 2
#define CH_Y_GROSS 3
#define CH_Y_FINE 4
#define CH_SPEED 5
#define CH_DIMMING 6
#define CH_STROBE 7
#define CH_LED_RED 8
#define CH_LED_GREEN 9
#define CH_LED_BLUE 10
#define CH_LED_WHITE 11
#define CH_RESET 13
#define X_FINE_STEPS_PER_GROSS_STEP 105
#define X_DEGREES_PER_GROSS_STEP (540 / 255.0)
#define X_WORLD_ZERO_IN_DEGREES 90
//TODO: check Y fine steps per gross
#define Y_FINE_STEPS_PER_GROSS_STEP 105
#define Y_DEGREES_PER_GROSS_STEP (180 / 205.0)
#define Y_WORLD_ZERO_IN_DEGREES 25
#define Y_FINE_TO_X_FINE_RATIO 33/11.75
#define MIN_X_GROSS 0
#define MAX_X_GROSS 85
#define MIN_Y_GROSS 0
#define MAX_Y_GROSS 131
void resetLamp() {
DmxSimple.write(CH_RESET,255);
delay(3000);
}
void setup() {
Serial.begin(115200);
DmxSimple.usePin(3);
//resetLamp();
lightsOn();
//while (true) {}
gotoXY(0,0);
delay(1500);
}
//
//int fromDegreesX(float degrees) {
// return round(degrees/);
//}
//
//int fromDegreesY(float degrees) {
// return round(degrees/);
//}
//
//int convertWorldDegreesX(float degrees) {
// return degrees + 90;
//}
//
//int convertWorldDegreesY(float degrees) {
// return degrees + 29;
//}
int xGross, xFine, yGross, yFine;
void setXGross(int x) {
xGross = x;
DmxSimple.write(CH_X_GROSS, xGross);
}
int getXGross() {
return xGross;
}
void setYGross(int y) {
yGross = y;
DmxSimple.write(CH_Y_GROSS, yGross);
}
int getYGross() {
return yGross;
}
void setXFine(int x) {
xFine = x;
DmxSimple.write(CH_X_FINE, xFine);
}
int getXFine() {
return xFine;
}
void setYFine(int y) {
yFine = y;
DmxSimple.write(CH_Y_FINE, yFine);
}
int getYFine() {
return yFine;
}
void moveIncremental(int x, int y) {
//TODO: take care of proper behavior when hitting the limits of gross motion.
int newXFine = (getXFine() + x) % X_FINE_STEPS_PER_GROSS_STEP;
int newXGross = getXGross() + (getXFine() + x) / X_FINE_STEPS_PER_GROSS_STEP;
while (newXFine<0) {
newXGross--;
newXFine+=X_FINE_STEPS_PER_GROSS_STEP;
}
int newYFine = (getYFine() + y) % Y_FINE_STEPS_PER_GROSS_STEP;
int newYGross = getYGross() + (getYFine() + y) / Y_FINE_STEPS_PER_GROSS_STEP;
while (newYFine<0) {
newYGross--;
newYFine+=Y_FINE_STEPS_PER_GROSS_STEP;
}
setXFine(newXFine);
setXGross(min(MAX_X_GROSS,max(MIN_X_GROSS,newXGross)));
setYFine(newYFine);
setYGross(min(MAX_Y_GROSS,max(MIN_Y_GROSS,newYGross)));
}
/**
* goto given coordinate (x,y) given in degrees in world coordinate system (where 0,0 is the lamp pointing straight ahead (y level with ground) at a -90 degree offset on X from home).
*/
void gotoXY(double x, double y) {
int xGross, xFine, yGross, yFine;
double xSteps = (X_WORLD_ZERO_IN_DEGREES - x) / X_DEGREES_PER_GROSS_STEP;
double ySteps = (Y_WORLD_ZERO_IN_DEGREES + y) / Y_DEGREES_PER_GROSS_STEP;
xGross = floor(xSteps);
xFine = (xSteps-xGross) * X_FINE_STEPS_PER_GROSS_STEP;
yGross = floor(ySteps);
yFine = (ySteps-yGross) * Y_FINE_STEPS_PER_GROSS_STEP;
Serial.print("Going to [");
Serial.print(x,2);
Serial.print(",");
Serial.print(y,2);
Serial.print("] : [");
Serial.print(xGross);
Serial.print(":");
Serial.print(xFine);
Serial.print(",");
Serial.print(yGross);
Serial.print(":");
Serial.print(yFine);
Serial.println("]");
setXGross(xGross);
setXFine(xFine);
setYGross(yGross);
setYFine(yFine);
}
void lightsOn() {
DmxSimple.write(6, 255);
DmxSimple.write(8, 255);
DmxSimple.write(9, 255);
DmxSimple.write(10, 255);
DmxSimple.write(11, 255);
}
void lightsOff() {
DmxSimple.write(6, 0);
}
String inString = ""; // string to hold input
void handleInput() {
while (Serial.available() > 0) {
int inChar = Serial.read();
inString += (char)inChar;
if (inChar == '\n') {
if ('c'==inString[0]) {
gotoXY(0,0);
} else if ('x'==inString[0]) {
int steps = inString.substring(1).toInt();
moveIncremental(steps, 0);
} else if ('y'==inString[0]) {
int steps = inString.substring(1).toInt();
moveIncremental(0, steps);
} else {
Serial.print(" Unknown command: '");
Serial.print(inString);
Serial.println("'");
}
// clear the string for new input:
inString = "";
}
}
}
void loop() {
handleInput();
}