forked from hanabusa-lab/polyzome
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathrain0.ino
More file actions
257 lines (222 loc) · 6.74 KB
/
rain0.ino
File metadata and controls
257 lines (222 loc) · 6.74 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
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
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <Conceptinetics.h>
#define _USE_MATH_DEFINES
#define DMX_MASTER_CHANNELS 32 //DMXで使うチャンネル数
#define RXEN_PIN 2 //不明
#define MAX_LIGHT_VOLUME 125 //ライトの最大ボリューム
//DMXコントローラのインスタンス
DMX_Master dmx_master ( DMX_MASTER_CHANNELS, RXEN_PIN );
char BUF[256]; //シリアル出力文字列用バッファー
//ライトボリューム 0から1の間の調整にします。
float gLightVolume = 0;
//初期設定
void setup() {
//DMXの初期化
dmx_master.enable ();
dmx_master.setChannelRange ( 1, DMX_MASTER_CHANNELS, MAX_LIGHT_VOLUME);
//シリアル通信の初期化
Serial.begin(9600);
clearAll();
}
//ライトボリュームの設定
//volume:値(0〜1までの少数)
void setLightVolume(float volume){
gLightVolume = volume;
}
//点の描画
//x,y:描画する位置(0〜4)
void drawPoint(int x, int y){
if(x<0 || 4<x || y<0 || 4<y){
sprintf(BUF, "Input value is out of range %d %d", x, y);
Serial.println(BUF);
}
int ch = 6+x+5*y;
int val = int(gLightVolume*MAX_LIGHT_VOLUME);
sprintf(BUF, "drawPoint x[%d] y[%d] ch[%d] val[%d]", x, y, ch, val);
Serial.println(BUF);
dmx_master.setChannelValue(ch, val);
}
//円の描画
//x, y:中心
//radius:半径
//fillFg:円の内側を塗りつぶす場合(true), 塗りつぶさない場合(false)
// example : (中心座標(x, y) = (2, 2), 半径r = 2, 塗りつぶし = on)
// int x=2;
// int y=2;
// float radius=2;
// bool fillFg=true;
void drawCircle(int x, int y, float radius, bool fillFg){
float dist;
//x, yを起点にして、radiusの範囲を走査して、半径の内側に入っているかを確認する
for(int i=x-radius/2; i<x+radius/2; i++){
for(int j=y-radius/2; j<y+radius/2; j++){
dist = (i-x)*(i-x)+(i-y)*(i-y);
if(dist <= radius*radius){
drawPoint(i, j);
}
}
}
}
//四角の描画
//x, y:中心
//四角:半径
//fillFg:四角の内側を塗りつぶす場合(true), 塗りつぶさない場合(false)
void drawBox(int x, int y, float radius, bool fillFg){
float dist;
//中を埋める場合
if(fillFg){
for(int i=x-radius/2; i<x+radius/2; i++){
for(int j=y-radius/2; j<y+radius/2; j++){
drawPoint(i, j);
}
}
}else{
//中を埋めない場合
for(int i=x-radius/2; i<x+radius/2; i++){
drawPoint(i, y-radius/2);
drawPoint(i, y+radius/2);
}
for(int i=y-radius/2; i<y+radius/2; i++){
drawPoint(x-radius/2, i);
drawPoint(y+radius/2, i);
}
}
}
//線の描画
//sPosX:開始点X
//sPosY:開始点Y
//ePosX:終了点X
//ePosY:終了点Y
void drawLine(int sPosX, int sPosY, int ePosX, int ePosY){
//スタートよりもエンドの方が値が大きいこと
if(sPosX< ePosX || sPosY< ePosY){
sprintf(BUF, "Input value is wrong %d %d %d %d", sPosX, sPosY, ePosX, ePosY);
Serial.println(BUF);
}
//まずは、直線だけを描画
if(sPosX == ePosX){
for(int i=sPosY; i<=ePosY; i++){
drawPoint(sPosX, i);
}
}else if(sPosY == ePosY){
for(int i=sPosX; i<=ePosX; i++){
drawPoint(i, sPosY);
}
}else{
Serial.println("drawLine. not supported");
}
}
//全部クリアする
void clearAll(){
for(int i=1; i<=30; i++){
dmx_master.setChannelValue(i, 0);
}
}
//平面を全て消す
void clearPlaneAll(){
for(int i=6; i<=30; i++){
dmx_master.setChannelValue(i, 0);
}
}
//高さ方向を全て消す
void clearHeightAll(){
for(int i=1; i<=5; i++){
dmx_master.setChannelValue(i, 0);
}
}
//高さ方向のライトの点灯位置の指定
//height:変更する高さ(0〜4)
//fg: ONの場合(true), OFFの場合(false)
void setLightHeight(int height, bool fg){
dmx_master.setChannelValue(height+1, fg ? MAX_LIGHT_VOLUME : 0);
}
//高さ方向のライトの点灯位置の指定(複数指定)
//height:変更する高さ.要素が4つの配列で指定する
//ex. 全部クリア:height=[0,0,0,0,0]
// 全部点灯:height=[1,1,1,1,1]
// 1段目だけ点灯:height=[1,0,0,0]
void setLightHeights(int *height){
for(int i=0; i<5; i++){
// dmx_master.setChannelValue(i+1, (height[0]==1) ? MAX_LIGHT_VOLUME : 0);
dmx_master.setChannelValue(i+1, (height[i]==1) ? MAX_LIGHT_VOLUME : 0);
}
}
//テスト1(1段目のライトを、個別に光らせる)
void test1(){
//ライトボリューム調整
setLightVolume(1);
//光らせる高さの指定
setLightHeight(0, true);
for(int i=0; i<5; i++){
for(int j=0; j<5; j++){
drawPoint(i,j);
delay(100);
clearPlaneAll();
}
}
}
//テスト2(平面は、順に光らせる。高さ方向は、ランダムでON/OFFを切り替える)
void test2(){
//ライトボリューム調整
setLightVolume(1);
for(int i=0; i<5; i++){
for(int j=0; j<5; j++){
//光らせる高さの指定
setLightHeight(0, random(0,2)==1 ? true : false);
setLightHeight(1, random(0,2)==1 ? true : false);
setLightHeight(2, random(0,2)==1 ? true : false);
setLightHeight(3, random(0,2)==1 ? true : false);
setLightHeight(4, random(0,2)==1 ? true : false);
//点で描画する
drawPoint(i,j);
delay(100);
clearPlaneAll();
}
}
}
//上に上がっていく雨の表現を行う
//起点を複数指定できる。
//場所に応じて平面の光の大きさを変えることができる。
//関数で一つの光が上に上がっていくまでとする
void perform_uprain(){
//起点の場所を決める
int vpos[2] = {2,2};
int hpos = 0; //hposは、0〜4
//光の高さをを変えていく
for(int i=0; i<5; i++){
//場所に応じて、光の大きさを変える.未対応
sprintf(BUF, "height %d", i);
Serial.println(BUF);
setLightHeight(i, true);
setLightVolume(1);
drawCircle(vpos[0], vpos[1], 1, true);
delay(100);
clearAll();
}
}
/*
** HANLER TEMPLETE **
** 関数名 : handler_<自分の名前>
** 引数 : デフォルト値はなし。自分用に作るのはあり(作った場合はここに要説明)。
** 戻り値 : void
** 関数の機能 : <説明> loopでこの関数呼び出すだけでみんなの処理がまとまるようにしたい。
** 作者: 関数作った人
** 日付: 関数作った日
*/
// void handler_name(voids)
// {
// ここにloop内で行いたい処理を書き込む
// }
//メインループ
void loop()
{ setLightVolume(0.1);
//実行するものに対して、コメントを外す。そのうち、シリアル経由でパソコンから切り替えられるようにする。
for (int i=0;i<5;i++)
{drawPoint(i,4);
setLightHeight(1, true);delay(500);
setLightHeight(1, false);delay(500);
clearAll();
}
}