Nama
A textile interface for controlling generative audiovisual output.
Components and supplies
Arduino LilyPad Main Board
SparkFun Triple Axis Accelerometer Breakout - ADXL335
Apps and platforms
Arduino IDE
Project description
Code
Processing Code
java
A sample code of how to link the Instrument to Processing, with a simple visualization software.
1////////////////////////////////////////////////////////////////////////////////////////////// 2// Nama Project v1.0 3// Instrument data receiver. 4// ------------------------------------------------------------------------------------------- 5// All codes created by Luiz Zanotello on May/2012. 6// Under Creative Commons License: CC BY-NC-SA 3.0. 7// More information at: http://www.viraseres.com/nama 8////////////////////////////////////////////////////////////////////////////////////////////// 9 10// General configuration 11int baudRate = 115200; //Baud rate 12int serialPort = 0; //Serial port 13boolean isPrinting = true; //Print to post? 14 15// Libraries 16import processing.serial.*; 17import processing.opengl.*; 18 19////////////////////////////////////////////////////////////////////////////////////////////// 20 21void setup() { 22 size(1200, 600, OPENGL); 23 beginSerial(); 24 setupFonts(); 25 smooth(); 26} 27 28void draw() { 29 background(230, 230, 212); 30 visualizeData(); 31 if (isPrinting==true) { 32 printValues(); 33 } 34} 35 36void printValues() { 37 println("AC NAME / RAW / FILTERED / DIFFERENCE / FILTERED DIFFERENCE"); 38 println("A1(z): "+acData[1][0]+" / "+acData[1][1]+" / "+acData[1][2]+" / "+acData[1][3]); 39 println("A2(z): "+acData[2][0]+" / "+acData[2][1]+" / "+acData[2][2]+" / "+acData[2][3]); 40 println("A3(z): "+acData[3][0]+" / "+acData[3][1]+" / "+acData[3][2]+" / "+acData[3][3]); 41 println("A4(z): "+acData[4][0]+" / "+acData[4][1]+" / "+acData[4][2]+" / "+acData[4][3]); 42 println("A5(x): "+acData[5][0]+" / "+acData[5][1]+" / "+acData[5][2]+" / "+acData[5][3]); 43 println("A5(y): "+acData[6][0]+" / "+acData[6][1]+" / "+acData[6][2]+" / "+acData[6][3]); 44 println("AV(z): "+acData[0][0]+" / "+acData[0][1]+" / "+acData[0][2]+" / "+acData[0][3]); 45 println(); 46} 47 48////////////////////////////////////////////////////////////////////////////////////////////// 49// Kalman Filter Class. 50// Created by Interactive Matter. 51// (http://github.com/interactive-matter/Processing/tree/master/lis302dl_kalman) 52// ------------------------------------------------------------------------------------------- 53////////////////////////////////////////////////////////////////////////////////////////////// 54 55public class KalmanFilter { 56 private float q; 57 private float r; 58 private float x; 59 private float p; 60 private float k; 61 public KalmanFilter(float q, float r, float p, float initial_value) { 62 this.q=q; 63 this.r=r; 64 this.p=p; 65 this.x=initial_value; 66 } 67 public float addSample(float measurement) { 68 //omit x=x 69 p=p+q; 70 k=p/(p+r); 71 x= x + k*(measurement-x); 72 p=(1-k)*p; 73 return x; 74 } 75 public String toString() { 76 return "KalmanFilter with p="+p+", k="+k; 77 } 78 public float getQ() { 79 return q; 80 } 81 public float getR() { 82 return r; 83 } 84 public float getP() { 85 return p; 86 } 87 public float getK() { 88 return k; 89 } 90} 91 92////////////////////////////////////////////////////////////////////////////////////////////// 93// Serial communication and configuration to the Lilypad accelerometer soft circuit. 94// ------------------------------------------------------------------------------------------- 95////////////////////////////////////////////////////////////////////////////////////////////// 96 97// Use the following variables to calibrate the readings from the accelerometers. 98// Change the "low" and "high" values of each accelerometer 99// according to the average lowest and highest values received. 100 101int a1lowZ = 307; 102int a1highZ = 759; 103int a2lowZ = 294; 104int a2highZ = 727; 105int a3lowZ = 281; 106int a3highZ = 711; 107int a4lowZ = 286; 108int a4highZ = 717; 109int a5lowX = 303; 110int a5highX = 769; 111int a5lowY = 298; 112int a5highY = 747; 113 114////////////////////////////////////////////////////////////////////////////////////////////// 115 116// Mapping variables 117Serial myPort; 118float acData[][] = new float[7][4]; // [raw, filt, dif, dif filt] [average z, 1, 2, 3, 4, 5x, 5y, 5z] 119float acDataOld[] = new float[7]; // used for calculating the differences 120float newValue, newValueFiltered, masterAverage, newDif, rawDif; //mapping 121 122// Kalman filter instances 123// q(process noise), r(sensor noise), p(estimated error), initial_value 124 125KalmanFilter filterDif0 = new KalmanFilter(0.1, 16, 0.1, 1); 126KalmanFilter filterDif1 = new KalmanFilter(0.1, 16, 0.1, 1); 127KalmanFilter filterDif2 = new KalmanFilter(0.1, 16, 0.1, 1); 128KalmanFilter filterDif3 = new KalmanFilter(0.1, 16, 0.1, 1); 129KalmanFilter filterDif4 = new KalmanFilter(0.1, 16, 0.1, 1); 130KalmanFilter filterDif5 = new KalmanFilter(0.1, 16, 0.1, 1); 131KalmanFilter filterDif6 = new KalmanFilter(0.1, 16, 0.1, 1); 132KalmanFilter filterDif7 = new KalmanFilter(0.1, 16, 0.1, 1); 133KalmanFilter filterA1 = new KalmanFilter(0.5, 256, 100, 510); 134KalmanFilter filterA2 = new KalmanFilter(0.5, 256, 100, 510); 135KalmanFilter filterA3 = new KalmanFilter(0.5, 256, 100, 510); 136KalmanFilter filterA4 = new KalmanFilter(0.5, 256, 100, 510); 137KalmanFilter filterA5X = new KalmanFilter(0.5, 256, 100, 510); 138KalmanFilter filterA5Y = new KalmanFilter(0.5, 256, 100, 510); 139KalmanFilter filterMaster = new KalmanFilter(0.5, 256, 100, 510); 140 141////////////////////////////////////////////////////////////////////////////////////////////// 142 143// Serial Event 144void beginSerial() { 145 myPort = new Serial(this, Serial.list()[serialPort], baudRate); 146 myPort.bufferUntil(10); 147} 148 149// Map Data 150void serialEvent(Serial p) { 151 String inString; 152 try { 153 inString = (myPort.readString()); 154 if (inString != null) { 155 String[] listSt = split(inString, ','); 156 if (listSt.length == 7) { 157 masterAverage = 0; 158 159 ////////////////////// 160 // Accelerometer 1 - Z 161 newValue = float(listSt[1]); 162 if (Float.isNaN(newValue)) { 163 newValue = acData[1][0]; 164 } 165 acData[1][0] = newValue; 166 masterAverage = masterAverage+newValue; 167 newValueFiltered = constrain(map(filterA1.addSample(newValue), a1lowZ, a1highZ, 0.01, 1.0), 0.001, 2.0); 168 if (Float.isNaN(newValueFiltered)) { 169 newValueFiltered = acData[1][1]; 170 } 171 acData[1][1] = newValueFiltered; 172 173 ////////////////////// 174 // Accelerometer 2 - Z 175 newValue = float(listSt[2]); 176 if (Float.isNaN(newValue)) { 177 newValue = acData[2][0]; 178 } 179 acData[2][0] = newValue; 180 masterAverage = masterAverage+newValue; 181 newValueFiltered = constrain(map(filterA2.addSample(newValue), a2lowZ, a2highZ, 0.01, 1.0), 0.001, 2.0); 182 if (Float.isNaN(newValueFiltered)) { 183 newValueFiltered = acData[2][1]; 184 } 185 acData[2][1] = newValueFiltered; 186 187 ////////////////////// 188 // Accelerometer 3 - Z 189 newValue = float(listSt[3]); 190 if (Float.isNaN(newValue)) { 191 newValue = acData[3][0]; 192 } 193 acData[3][0] = newValue; 194 masterAverage = masterAverage+newValue; 195 newValueFiltered = constrain(map(filterA3.addSample(newValue), a3lowZ, a3highZ, 0.01, 1.0), 0.001, 2.0); 196 if (Float.isNaN(newValueFiltered)) { 197 newValueFiltered = acData[3][1]; 198 } 199 acData[3][1] = newValueFiltered; 200 201 ////////////////////// 202 // Accelerometer 4 - Z 203 newValue = float(listSt[4]); 204 if (Float.isNaN(newValue)) { 205 newValue = acData[4][0]; 206 } 207 acData[4][0] = newValue; 208 masterAverage = masterAverage+newValue; 209 newValueFiltered = constrain(map(filterA4.addSample(newValue), a4lowZ, a4highZ, 0.01, 1.0), 0.001, 2.0); 210 if (Float.isNaN(newValueFiltered)) { 211 newValueFiltered = acData[4][1]; 212 } 213 acData[4][1] = newValueFiltered; 214 215 ////////////////////// 216 // Accelerometer C - X 217 newValue = float(listSt[5]); 218 if (Float.isNaN(newValue)) { 219 newValue = acData[5][0]; 220 } 221 acData[5][0] = newValue; 222 newValueFiltered = constrain(map(filterA5X.addSample(newValue), a5lowX, a5highX, 0.01, 1.0), 0.001, 2.0); 223 if (Float.isNaN(newValueFiltered)) { 224 newValueFiltered = acData[5][1]; 225 } 226 acData[5][1] = newValueFiltered; 227 228 ////////////////////// 229 // Accelerometer C - Y 230 newValue = float(listSt[6]); 231 if (Float.isNaN(newValue)) { 232 newValue =acData[6][0]; 233 } 234 acData[6][0] = newValue; 235 newValueFiltered = constrain(map(filterA5Y.addSample(newValue), a5lowY, a5highY, 0.01, 1.0), 0.001, 2.0); 236 if (Float.isNaN(newValueFiltered)) { 237 newValueFiltered = acData[6][1]; 238 } 239 acData[6][1] = newValueFiltered; 240 241 ////////////////////// 242 // Master average calc 243 newValue = masterAverage/4; 244 if (Float.isNaN(newValue)) { 245 newValue = acData[0][0]; 246 } 247 acData[0][0] = newValue; 248 newValueFiltered = constrain(map(filterMaster.addSample(newValue), (a4lowZ+a3lowZ+a2lowZ+a1lowZ)*0.25, (a4highZ+a3highZ+a2highZ+a1highZ)*0.25, 0.01, 1.0), 0.001, 2.0); 249 if (Float.isNaN(newValueFiltered)) { 250 newValueFiltered = acData[0][1]; 251 } 252 acData[0][1] = newValueFiltered; 253 setDifferences(); 254 } 255 } 256 } 257 catch(Exception e) { 258 println(e); 259 } 260} 261 262// Set differences 263void setDifferences() { 264 for (int i=0;i<acData.length;i++) { 265 acData[i][2] = acData[i][1]-acDataOld[i]; 266 if (i==0) { 267 acData[i][3] = filterDif0.addSample(acData[i][2]); 268 } 269 if (i==1) { 270 acData[i][3] = filterDif1.addSample(acData[i][2]); 271 } 272 if (i==2) { 273 acData[i][3] = filterDif2.addSample(acData[i][2]); 274 } 275 if (i==3) { 276 acData[i][3] = filterDif3.addSample(acData[i][2]); 277 } 278 if (i==4) { 279 acData[i][3] = filterDif4.addSample(acData[i][2]); 280 } 281 if (i==5) { 282 acData[i][3] = filterDif5.addSample(acData[i][2]); 283 } 284 if (i==6) { 285 acData[i][3] = filterDif6.addSample(acData[i][2]); 286 } 287 if (Float.isNaN(acData[i][3])) { 288 acData[i][3] = acDataOld[i]; 289 } 290 if (acData[i][3]<0.0001) { 291 acData[i][3]=0; 292 } 293 if (acData[i][2]<0.0001) { 294 acData[i][2]=0; 295 } 296 acDataOld[i] = acData[i][1]; 297 } 298} 299 300////////////////////////////////////////////////////////////////////////////////////////////// 301// Graphical visualization of the interface data. 302// ------------------------------------------------------------------------------------------- 303////////////////////////////////////////////////////////////////////////////////////////////// 304 305// Config 306int interfaceDimensionX = 128; 307int interfaceDimensionY = 134; 308 309// Mapping variables 310PFont titleFont, contentFont, copyrightFont; 311float goPoint[][] = new float[5][3]; 312float baseX, baseY; 313 314void setupFonts() { 315 titleFont = loadFont("ArialNarrow-23.vlw"); 316 contentFont = loadFont("Courier-15.vlw"); 317 copyrightFont = loadFont("Courier-9.vlw"); 318} 319 320void visualizeData() { 321 // Bg 322 fill(35, 41, 44); 323 rect(-2, -2, 380, height+4); 324 325 // Base position of text 326 baseX = 60; 327 baseY = 214; 328 329 // Title 330 textFont(titleFont); 331 fill(230, 230, 212); 332 text("Nama Instrument v1.0", baseX-6, baseY-60); 333 textFont(contentFont); 334 fill(230, 230, 212); 335 text("", baseX-6, baseY-28); 336 textFont(copyrightFont); 337 text("ACC: RAW FILTER DIF DIF+FILTER", baseX-6, baseY); 338 339 // 1 340 baseY = baseY+34; 341 textFont(titleFont); 342 fill(215, 102, 124); 343 text("A1z: ", baseX-6, baseY); 344 fill(230, 230, 212); 345 textFont(contentFont); 346 text(int(acData[1][0]), baseX+48, baseY-3); 347 text("", baseX+79, baseY-3); 348 text(acData[1][1], baseX+84, baseY-3); 349 text("", baseX+142, baseY-3); 350 text(acData[1][2], baseX+147, baseY-3); 351 text("", baseX+205, baseY-3); 352 text(acData[1][3], baseX+210, baseY-3); 353 354 // 2 355 baseY = baseY+34; 356 textFont(titleFont); 357 fill(215, 181, 102); 358 text("A2z: ", baseX-6, baseY); 359 fill(230, 230, 212); 360 textFont(contentFont); 361 text(int(acData[2][0]), baseX+48, baseY-3); 362 text("", baseX+79, baseY-3); 363 text(acData[2][1], baseX+84, baseY-3); 364 text("", baseX+142, baseY-3); 365 text(acData[2][2], baseX+147, baseY-3); 366 text("", baseX+205, baseY-3); 367 text(acData[2][3], baseX+210, baseY-3); 368 369 // 3 370 baseY = baseY+34; 371 textFont(titleFont); 372 fill(102, 215, 161); 373 text("A3z: ", baseX-6, baseY); 374 fill(230, 230, 212); 375 textFont(contentFont); 376 text(int(acData[3][0]), baseX+48, baseY-3); 377 text("", baseX+79, baseY-3); 378 text(acData[3][1], baseX+84, baseY-3); 379 text("", baseX+142, baseY-3); 380 text(acData[3][2], baseX+147, baseY-3); 381 text("", baseX+205, baseY-3); 382 text(acData[3][3], baseX+210, baseY-3); 383 384 // 4 385 baseY = baseY+34; 386 textFont(titleFont); 387 fill(102, 130, 215); 388 text("A4z: ", baseX-6, baseY); 389 fill(230, 230, 212); 390 textFont(contentFont); 391 text(int(acData[4][0]), baseX+48, baseY-3); 392 text("", baseX+79, baseY-3); 393 text(acData[4][1], baseX+84, baseY-3); 394 text("", baseX+142, baseY-3); 395 text(acData[4][2], baseX+147, baseY-3); 396 text("", baseX+205, baseY-3); 397 text(acData[4][3], baseX+210, baseY-3); 398 399 // 5x 400 baseY = baseY+34; 401 textFont(titleFont); 402 fill(139, 137, 127); 403 text("A5x: ", baseX-6, baseY); 404 fill(230, 230, 212); 405 textFont(contentFont); 406 text(int(acData[5][0]), baseX+48, baseY-3); 407 text("", baseX+79, baseY-3); 408 text(acData[5][1], baseX+84, baseY-3); 409 text("", baseX+142, baseY-3); 410 text(acData[5][2], baseX+147, baseY-3); 411 text("", baseX+205, baseY-3); 412 text(acData[5][3], baseX+210, baseY-3); 413 414 // 5y 415 baseY = baseY+34; 416 textFont(titleFont); 417 fill(139, 137, 127); 418 text("A5y: ", baseX-6, baseY); 419 fill(230, 230, 212); 420 textFont(contentFont); 421 text(int(acData[6][0]), baseX+48, baseY-3); 422 text("", baseX+79, baseY-3); 423 text(acData[6][1], baseX+84, baseY-3); 424 text("", baseX+142, baseY-3); 425 text(acData[6][2], baseX+147, baseY-3); 426 text("", baseX+205, baseY-3); 427 text(acData[6][3], baseX+210, baseY-3); 428 429 // separador 430 baseY = baseY+34; 431 textFont(contentFont); 432 fill(230, 230, 212); 433 text("", baseX-6, baseY-3); 434 435 // Average 436 baseY = baseY+34; 437 textFont(titleFont); 438 fill(230, 230, 212); 439 text("AVz: ", baseX-6, baseY); 440 fill(230, 230, 212); 441 textFont(contentFont); 442 text(int(acData[0][0]), baseX+48, baseY-3); 443 text("", baseX+79, baseY-3); 444 text(acData[0][1], baseX+84, baseY-3); 445 text("", baseX+142, baseY-3); 446 text(acData[0][2], baseX+147, baseY-3); 447 text("", baseX+205, baseY-3); 448 text(acData[0][3], baseX+210, baseY-3); 449 450 // Credits 451 textFont(copyrightFont); 452 fill(35, 41, 44); 453 text("created by luiz gustavo zanotello at jun/2012", width-233, height-30); 454 text("http://www.viraseres.com/nama", width-154, height-20); 455 text("under CC BY-NC-SA 3.0", width-114, height-10); 456 457 //////////////////////////////////////////////////////////////////////////////////////////// 458 // Graph 459 noStroke(); 460 fill(255); 461 baseX = width-width/3+map(acData[5][1], 0, 1, -1, 1)*100; 462 baseY = height/2+map(acData[6][1], 0, 1, -1, 1)*100+map(acData[0][1], 0, 1, -1, 1)*50; 463 translate(baseX, baseY, map(acData[0][1], 0, 1, 50, -100)); 464 perspective(); 465 rotateX(radians(acData[5][1]*360)); 466 rotateY(radians(acData[6][1]*360)); 467 rotateZ(radians(acData[0][1]*360)); 468 directionalLight(120, 120, 120, 0, -1, -1); 469 ambientLight(230, 230, 230); 470 471 // 4 472 fill(142-(acData[2][3]*255*100), 170-(acData[2][3]*255*100), 255-(acData[2][3]*255*100), 90+(acData[4][3]*255*100)); 473 goPoint[4][0] = 0-interfaceDimensionX+map(acData[4][1], 0, 1, -100, 100); 474 goPoint[4][1] = interfaceDimensionY/2+map(acData[4][1], 0, 1, -100, 100); 475 goPoint[4][2] = map(acData[4][1], 0, 1, -400, 400); 476 pushMatrix(); 477 translate(goPoint[4][0], goPoint[4][1], goPoint[4][2]); 478 sphere(6); 479 popMatrix(); 480 481 // 3 482 fill(142-(acData[1][3]*255*100), 255-(acData[1][3]*255*100), 201-(acData[1][3]*255*100), 90+(acData[4][3]*255*100)); 483 goPoint[3][0] = 0-interfaceDimensionX+map(acData[3][1], 0, 1, -100, 100); 484 goPoint[3][1] = 0-interfaceDimensionY/2+map(acData[3][1], 0, 1, -100, 100); 485 goPoint[3][2] = map(acData[3][1], 0, 1, -400, 400); 486 pushMatrix(); 487 translate(goPoint[3][0], goPoint[3][1], goPoint[3][2]); 488 sphere(6); 489 popMatrix(); 490 491 // 2 492 fill(255-(acData[3][3]*255*100), 221-(acData[3][3]*255*100), 142-(acData[3][3]*255*100), 90+(acData[4][3]*255*100)); 493 goPoint[2][0] = interfaceDimensionX+map(acData[2][1], 0, 1, -100, 100); 494 goPoint[2][1] = 0-interfaceDimensionY/2+map(acData[2][1], 0, 1, -100, 100); 495 goPoint[2][2] = map(acData[2][1], 0, 1, -400, 400); 496 pushMatrix(); 497 translate(goPoint[2][0], goPoint[2][1], goPoint[2][2]); 498 sphere(6); 499 popMatrix(); 500 501 // 1 502 fill(255-(acData[4][3]*255*100), 142-(acData[4][3]*255*100), 164-(acData[4][3]*255*100), 90+(acData[4][3]*255*100)); 503 goPoint[1][0] = interfaceDimensionX+map(acData[1][1], 0, 1, -100, 100); 504 goPoint[1][1] = interfaceDimensionY/2+map(acData[1][1], 0, 1, -100, 100); 505 goPoint[1][2] = map(acData[1][1], 0, 1, -400, 400); 506 pushMatrix(); 507 translate(goPoint[1][0], goPoint[1][1], goPoint[1][2]); 508 sphere(6); 509 popMatrix(); 510 511 // C 512 fill(179-(acData[5][3]*255*100)-(acData[6][3]*255*100), 177-(acData[5][3]*255*100)-(acData[6][3]*255*100), 167-(acData[5][3]*255*100)-(acData[6][3]*255*100), 90+(acData[5][3]*255*100)+(acData[6][3]*255*100)); 513 goPoint[0][0] = map(acData[5][1], 0, 1, -400, 400); 514 goPoint[0][1] = map(acData[6][1], 0, 1, -400, 400); 515 goPoint[0][2] = map(acData[0][1], 0, 1, -100, 100); 516 pushMatrix(); 517 translate(goPoint[0][0], goPoint[0][1], goPoint[0][2]); 518 sphere(6); 519 popMatrix(); 520 521 // Lines 522 stroke(255); 523 line(goPoint[0][0], goPoint[0][1], goPoint[0][2], goPoint[1][0], goPoint[1][1], goPoint[1][2]); 524 line(goPoint[0][0], goPoint[0][1], goPoint[0][2], goPoint[2][0], goPoint[2][1], goPoint[2][2]); 525 line(goPoint[0][0], goPoint[0][1], goPoint[0][2], goPoint[3][0], goPoint[3][1], goPoint[3][2]); 526 line(goPoint[0][0], goPoint[0][1], goPoint[0][2], goPoint[4][0], goPoint[4][1], goPoint[4][2]); 527 line(goPoint[1][0], goPoint[1][1], goPoint[1][2], goPoint[2][0], goPoint[2][1], goPoint[2][2]); 528 line(goPoint[1][0], goPoint[1][1], goPoint[1][2], goPoint[3][0], goPoint[3][1], goPoint[3][2]); 529 line(goPoint[1][0], goPoint[1][1], goPoint[1][2], goPoint[4][0], goPoint[4][1], goPoint[4][2]); 530 line(goPoint[2][0], goPoint[2][1], goPoint[2][2], goPoint[3][0], goPoint[3][1], goPoint[3][2]); 531 line(goPoint[2][0], goPoint[2][1], goPoint[2][2], goPoint[4][0], goPoint[4][1], goPoint[4][2]); 532 line(goPoint[3][0], goPoint[3][1], goPoint[3][2], goPoint[4][0], goPoint[4][1], goPoint[4][2]); 533}
Arduino Code
arduino
1/////////////////////////////////////////////////////////////// 2// Nama Project v1.0 3// Instrument Arduino code. 4// ------------------------------------------------------------ 5// Created by Luiz Zanotello on May/2012. 6// Under Creative Commons License: CC BY-NC-SA 3.0. 7// More information at: http://www.viraseres.com/nama 8/////////////////////////////////////////////////////////////// 9 10//Accelerometer 1 (z) - bottom right 11//////////////////////////////////// 12const int a1pinV = 6; //output current pin 13const int a1pinZ = A0; //data pin 14 15//Accelerometer 2 (z) - top right 16///////////////////////////////// 17const int a2pinV = 7; //output current pi 18const int a2pinZ = A1; //data pin 19 20//Central accelerometer (x/y) 21///////////////////////////// 22const int aCpinV = 8; //output current pi 23const int aCpinX = A2; //data pin 24const int aCpinY = A3; //data pin 25//Accelerometer 3 (z) - top left 26//////////////////////////////// 27const int a3pinV = 2; //output current pi 28const int a3pinZ = A4; //data pin 29 30//Accelerometer 4 (z) - bottom left 31/////////////////////////////////// 32const int a4pinV = 3; //output current pi 33const int a4pinZ = A5; //data pin 34 35//////////////////////////////////////////////////////// 36 37void setup() 38{ 39 //Begin serial transmition: 40 Serial.begin(115200); 41 //Set output pins (+ current): 42 pinMode(a1pinV, OUTPUT); 43 digitalWrite(a1pinV, HIGH); 44 pinMode(a2pinV, OUTPUT); 45 digitalWrite(a2pinV, HIGH); 46 pinMode(aCpinV, OUTPUT); 47 digitalWrite(aCpinV, HIGH); 48 pinMode(a3pinV, OUTPUT); 49 digitalWrite(a3pinV, HIGH); 50 pinMode(a4pinV, OUTPUT); 51 digitalWrite(a4pinV, HIGH); 52} 53 54//////////////////////////////////////////////////////// 55 56void loop() 57{ 58 // Printing analog data received from accelerometers 59 Serial.println(); 60 Serial.print(5); // Number of accelerometers 61 Serial.print(','); 62 Serial.print(analogRead(a1pinZ)); // Accelerometer 1 reading (z) 63 Serial.print(','); 64 Serial.print(analogRead(a2pinZ)); // Accelerometer 2 reading (z) 65 Serial.print(','); 66 Serial.print(analogRead(a3pinZ)); // Accelerometer 3 reading (z) 67 Serial.print(','); 68 Serial.print(analogRead(a4pinZ)); // Accelerometer 4 reading (z) 69 Serial.print(','); 70 Serial.print(analogRead(aCpinX)); // Central accelerometer reading (x) 71 Serial.print(','); 72 Serial.print(analogRead(aCpinY)); // Central accelerometer reading (y) 73 Serial.print(tranG); 74 delay(10); 75} 76 77//////////////////////////////////////////////////////// 78
Processing Code
java
A sample code of how to link the Instrument to Processing, with a simple visualization software.
1////////////////////////////////////////////////////////////////////////////////////////////// 2// 3 Nama Project v1.0 4// Instrument data receiver. 5// ------------------------------------------------------------------------------------------- 6// 7 All codes created by Luiz Zanotello on May/2012. 8// Under Creative Commons License: 9 CC BY-NC-SA 3.0. 10// More information at: http://www.viraseres.com/nama 11////////////////////////////////////////////////////////////////////////////////////////////// 12 13// 14 General configuration 15int baudRate = 115200; //Baud rate 16int serialPort = 17 0; //Serial port 18boolean isPrinting = true; //Print to post? 19 20// Libraries 21import 22 processing.serial.*; 23import processing.opengl.*; 24 25////////////////////////////////////////////////////////////////////////////////////////////// 26 27void 28 setup() { 29 size(1200, 600, OPENGL); 30 beginSerial(); 31 setupFonts(); 32 33 smooth(); 34} 35 36void draw() { 37 background(230, 230, 212); 38 visualizeData(); 39 40 if (isPrinting==true) { 41 printValues(); 42 } 43} 44 45void printValues() 46 { 47 println("AC NAME / RAW / FILTERED / DIFFERENCE / FILTERED DIFFERENCE"); 48 49 println("A1(z): "+acData[1][0]+" / "+acData[1][1]+" / "+acData[1][2]+" 50 / "+acData[1][3]); 51 println("A2(z): "+acData[2][0]+" / "+acData[2][1]+" 52 / "+acData[2][2]+" / "+acData[2][3]); 53 println("A3(z): "+acData[3][0]+" 54 / "+acData[3][1]+" / "+acData[3][2]+" / "+acData[3][3]); 55 println("A4(z): 56 "+acData[4][0]+" / "+acData[4][1]+" / "+acData[4][2]+" / "+acData[4][3]); 57 58 println("A5(x): "+acData[5][0]+" / "+acData[5][1]+" / "+acData[5][2]+" 59 / "+acData[5][3]); 60 println("A5(y): "+acData[6][0]+" / "+acData[6][1]+" 61 / "+acData[6][2]+" / "+acData[6][3]); 62 println("AV(z): "+acData[0][0]+" 63 / "+acData[0][1]+" / "+acData[0][2]+" / "+acData[0][3]); 64 println(); 65} 66 67////////////////////////////////////////////////////////////////////////////////////////////// 68// 69 Kalman Filter Class. 70// Created by Interactive Matter. 71// (http://github.com/interactive-matter/Processing/tree/master/lis302dl_kalman) 72// 73 ------------------------------------------------------------------------------------------- 74////////////////////////////////////////////////////////////////////////////////////////////// 75 76public 77 class KalmanFilter { 78 private float q; 79 private float r; 80 private float 81 x; 82 private float p; 83 private float k; 84 public KalmanFilter(float q, 85 float r, float p, float initial_value) { 86 this.q=q; 87 this.r=r; 88 this.p=p; 89 90 this.x=initial_value; 91 } 92 public float addSample(float measurement) 93 { 94 //omit x=x 95 p=p+q; 96 k=p/(p+r); 97 x= x + k*(measurement-x); 98 99 p=(1-k)*p; 100 return x; 101 } 102 public String toString() { 103 return 104 "KalmanFilter with p="+p+", k="+k; 105 } 106 public float getQ() { 107 return 108 q; 109 } 110 public float getR() { 111 return r; 112 } 113 public float getP() 114 { 115 return p; 116 } 117 public float getK() { 118 return k; 119 } 120} 121 122////////////////////////////////////////////////////////////////////////////////////////////// 123// 124 Serial communication and configuration to the Lilypad accelerometer soft circuit. 125// 126 ------------------------------------------------------------------------------------------- 127////////////////////////////////////////////////////////////////////////////////////////////// 128 129// 130 Use the following variables to calibrate the readings from the accelerometers. 131// 132 Change the "low" and "high" values of each accelerometer 133// according to 134 the average lowest and highest values received. 135 136int a1lowZ = 307; 137int 138 a1highZ = 759; 139int a2lowZ = 294; 140int a2highZ = 727; 141int a3lowZ = 281; 142int 143 a3highZ = 711; 144int a4lowZ = 286; 145int a4highZ = 717; 146int a5lowX = 303; 147int 148 a5highX = 769; 149int a5lowY = 298; 150int a5highY = 747; 151 152////////////////////////////////////////////////////////////////////////////////////////////// 153 154// 155 Mapping variables 156Serial myPort; 157float acData[][] = new float[7][4]; // [raw, 158 filt, dif, dif filt] [average z, 1, 2, 3, 4, 5x, 5y, 5z] 159float acDataOld[] = 160 new float[7]; // used for calculating the differences 161float newValue, newValueFiltered, 162 masterAverage, newDif, rawDif; //mapping 163 164// Kalman filter instances 165// 166 q(process noise), r(sensor noise), p(estimated error), initial_value 167 168KalmanFilter 169 filterDif0 = new KalmanFilter(0.1, 16, 0.1, 1); 170KalmanFilter filterDif1 = new 171 KalmanFilter(0.1, 16, 0.1, 1); 172KalmanFilter filterDif2 = new KalmanFilter(0.1, 173 16, 0.1, 1); 174KalmanFilter filterDif3 = new KalmanFilter(0.1, 16, 0.1, 1); 175KalmanFilter 176 filterDif4 = new KalmanFilter(0.1, 16, 0.1, 1); 177KalmanFilter filterDif5 = new 178 KalmanFilter(0.1, 16, 0.1, 1); 179KalmanFilter filterDif6 = new KalmanFilter(0.1, 180 16, 0.1, 1); 181KalmanFilter filterDif7 = new KalmanFilter(0.1, 16, 0.1, 1); 182KalmanFilter 183 filterA1 = new KalmanFilter(0.5, 256, 100, 510); 184KalmanFilter filterA2 = new 185 KalmanFilter(0.5, 256, 100, 510); 186KalmanFilter filterA3 = new KalmanFilter(0.5, 187 256, 100, 510); 188KalmanFilter filterA4 = new KalmanFilter(0.5, 256, 100, 510); 189KalmanFilter 190 filterA5X = new KalmanFilter(0.5, 256, 100, 510); 191KalmanFilter filterA5Y = new 192 KalmanFilter(0.5, 256, 100, 510); 193KalmanFilter filterMaster = new KalmanFilter(0.5, 194 256, 100, 510); 195 196////////////////////////////////////////////////////////////////////////////////////////////// 197 198// 199 Serial Event 200void beginSerial() { 201 myPort = new Serial(this, Serial.list()[serialPort], 202 baudRate); 203 myPort.bufferUntil(10); 204} 205 206// Map Data 207void serialEvent(Serial 208 p) { 209 String inString; 210 try { 211 inString = (myPort.readString()); 212 213 if (inString != null) { 214 String[] listSt = split(inString, ','); 215 216 if (listSt.length == 7) { 217 masterAverage = 0; 218 219 ////////////////////// 220 221 // Accelerometer 1 - Z 222 newValue = float(listSt[1]); 223 if 224 (Float.isNaN(newValue)) { 225 newValue = acData[1][0]; 226 } 227 228 acData[1][0] = newValue; 229 masterAverage = masterAverage+newValue; 230 231 newValueFiltered = constrain(map(filterA1.addSample(newValue), a1lowZ, a1highZ, 232 0.01, 1.0), 0.001, 2.0); 233 if (Float.isNaN(newValueFiltered)) { 234 newValueFiltered 235 = acData[1][1]; 236 } 237 acData[1][1] = newValueFiltered; 238 239 240 ////////////////////// 241 // Accelerometer 2 - Z 242 newValue 243 = float(listSt[2]); 244 if (Float.isNaN(newValue)) { 245 newValue 246 = acData[2][0]; 247 } 248 acData[2][0] = newValue; 249 masterAverage 250 = masterAverage+newValue; 251 newValueFiltered = constrain(map(filterA2.addSample(newValue), 252 a2lowZ, a2highZ, 0.01, 1.0), 0.001, 2.0); 253 if (Float.isNaN(newValueFiltered)) 254 { 255 newValueFiltered = acData[2][1]; 256 } 257 acData[2][1] 258 = newValueFiltered; 259 260 ////////////////////// 261 // Accelerometer 262 3 - Z 263 newValue = float(listSt[3]); 264 if (Float.isNaN(newValue)) 265 { 266 newValue = acData[3][0]; 267 } 268 acData[3][0] = newValue; 269 270 masterAverage = masterAverage+newValue; 271 newValueFiltered = constrain(map(filterA3.addSample(newValue), 272 a3lowZ, a3highZ, 0.01, 1.0), 0.001, 2.0); 273 if (Float.isNaN(newValueFiltered)) 274 { 275 newValueFiltered = acData[3][1]; 276 } 277 acData[3][1] 278 = newValueFiltered; 279 280 ////////////////////// 281 // Accelerometer 282 4 - Z 283 newValue = float(listSt[4]); 284 if (Float.isNaN(newValue)) 285 { 286 newValue = acData[4][0]; 287 } 288 acData[4][0] = newValue; 289 290 masterAverage = masterAverage+newValue; 291 newValueFiltered = constrain(map(filterA4.addSample(newValue), 292 a4lowZ, a4highZ, 0.01, 1.0), 0.001, 2.0); 293 if (Float.isNaN(newValueFiltered)) 294 { 295 newValueFiltered = acData[4][1]; 296 } 297 acData[4][1] 298 = newValueFiltered; 299 300 ////////////////////// 301 // Accelerometer 302 C - X 303 newValue = float(listSt[5]); 304 if (Float.isNaN(newValue)) 305 { 306 newValue = acData[5][0]; 307 } 308 acData[5][0] = newValue; 309 310 newValueFiltered = constrain(map(filterA5X.addSample(newValue), a5lowX, 311 a5highX, 0.01, 1.0), 0.001, 2.0); 312 if (Float.isNaN(newValueFiltered)) 313 { 314 newValueFiltered = acData[5][1]; 315 } 316 acData[5][1] 317 = newValueFiltered; 318 319 ////////////////////// 320 // Accelerometer 321 C - Y 322 newValue = float(listSt[6]); 323 if (Float.isNaN(newValue)) 324 { 325 newValue =acData[6][0]; 326 } 327 acData[6][0] = newValue; 328 329 newValueFiltered = constrain(map(filterA5Y.addSample(newValue), a5lowY, 330 a5highY, 0.01, 1.0), 0.001, 2.0); 331 if (Float.isNaN(newValueFiltered)) 332 { 333 newValueFiltered = acData[6][1]; 334 } 335 acData[6][1] 336 = newValueFiltered; 337 338 ////////////////////// 339 // Master average 340 calc 341 newValue = masterAverage/4; 342 if (Float.isNaN(newValue)) 343 { 344 newValue = acData[0][0]; 345 } 346 acData[0][0] = newValue; 347 348 newValueFiltered = constrain(map(filterMaster.addSample(newValue), (a4lowZ+a3lowZ+a2lowZ+a1lowZ)*0.25, 349 (a4highZ+a3highZ+a2highZ+a1highZ)*0.25, 0.01, 1.0), 0.001, 2.0); 350 if (Float.isNaN(newValueFiltered)) 351 { 352 newValueFiltered = acData[0][1]; 353 } 354 acData[0][1] 355 = newValueFiltered; 356 setDifferences(); 357 } 358 } 359 } 360 361 catch(Exception e) { 362 println(e); 363 } 364} 365 366// Set differences 367void 368 setDifferences() { 369 for (int i=0;i<acData.length;i++) { 370 acData[i][2] 371 = acData[i][1]-acDataOld[i]; 372 if (i==0) { 373 acData[i][3] = filterDif0.addSample(acData[i][2]); 374 375 } 376 if (i==1) { 377 acData[i][3] = filterDif1.addSample(acData[i][2]); 378 379 } 380 if (i==2) { 381 acData[i][3] = filterDif2.addSample(acData[i][2]); 382 383 } 384 if (i==3) { 385 acData[i][3] = filterDif3.addSample(acData[i][2]); 386 387 } 388 if (i==4) { 389 acData[i][3] = filterDif4.addSample(acData[i][2]); 390 391 } 392 if (i==5) { 393 acData[i][3] = filterDif5.addSample(acData[i][2]); 394 395 } 396 if (i==6) { 397 acData[i][3] = filterDif6.addSample(acData[i][2]); 398 399 } 400 if (Float.isNaN(acData[i][3])) { 401 acData[i][3] = acDataOld[i]; 402 403 } 404 if (acData[i][3]<0.0001) { 405 acData[i][3]=0; 406 } 407 if 408 (acData[i][2]<0.0001) { 409 acData[i][2]=0; 410 } 411 acDataOld[i] = 412 acData[i][1]; 413 } 414} 415 416////////////////////////////////////////////////////////////////////////////////////////////// 417// 418 Graphical visualization of the interface data. 419// ------------------------------------------------------------------------------------------- 420////////////////////////////////////////////////////////////////////////////////////////////// 421 422// 423 Config 424int interfaceDimensionX = 128; 425int interfaceDimensionY = 134; 426 427// 428 Mapping variables 429PFont titleFont, contentFont, copyrightFont; 430float goPoint[][] 431 = new float[5][3]; 432float baseX, baseY; 433 434void setupFonts() { 435 titleFont 436 = loadFont("ArialNarrow-23.vlw"); 437 contentFont = loadFont("Courier-15.vlw"); 438 439 copyrightFont = loadFont("Courier-9.vlw"); 440} 441 442void visualizeData() 443 { 444 // Bg 445 fill(35, 41, 44); 446 rect(-2, -2, 380, height+4); 447 448 449 // Base position of text 450 baseX = 60; 451 baseY = 214; 452 453 // Title 454 455 textFont(titleFont); 456 fill(230, 230, 212); 457 text("Nama Instrument v1.0", 458 baseX-6, baseY-60); 459 textFont(contentFont); 460 fill(230, 230, 212); 461 text("", 462 baseX-6, baseY-28); 463 textFont(copyrightFont); 464 text("ACC: RAW FILTER 465 DIF DIF+FILTER", baseX-6, baseY); 466 467 // 1 468 baseY = baseY+34; 469 470 textFont(titleFont); 471 fill(215, 102, 124); 472 text("A1z: ", baseX-6, baseY); 473 474 fill(230, 230, 212); 475 textFont(contentFont); 476 text(int(acData[1][0]), 477 baseX+48, baseY-3); 478 text("", baseX+79, baseY-3); 479 text(acData[1][1], 480 baseX+84, baseY-3); 481 text("", baseX+142, baseY-3); 482 text(acData[1][2], 483 baseX+147, baseY-3); 484 text("", baseX+205, baseY-3); 485 text(acData[1][3], 486 baseX+210, baseY-3); 487 488 // 2 489 baseY = baseY+34; 490 textFont(titleFont); 491 492 fill(215, 181, 102); 493 text("A2z: ", baseX-6, baseY); 494 fill(230, 230, 495 212); 496 textFont(contentFont); 497 text(int(acData[2][0]), baseX+48, baseY-3); 498 499 text("", baseX+79, baseY-3); 500 text(acData[2][1], baseX+84, baseY-3); 501 502 text("", baseX+142, baseY-3); 503 text(acData[2][2], baseX+147, baseY-3); 504 505 text("", baseX+205, baseY-3); 506 text(acData[2][3], baseX+210, baseY-3); 507 508 509 // 3 510 baseY = baseY+34; 511 textFont(titleFont); 512 fill(102, 215, 161); 513 514 text("A3z: ", baseX-6, baseY); 515 fill(230, 230, 212); 516 textFont(contentFont); 517 518 text(int(acData[3][0]), baseX+48, baseY-3); 519 text("", baseX+79, baseY-3); 520 521 text(acData[3][1], baseX+84, baseY-3); 522 text("", baseX+142, baseY-3); 523 524 text(acData[3][2], baseX+147, baseY-3); 525 text("", baseX+205, baseY-3); 526 527 text(acData[3][3], baseX+210, baseY-3); 528 529 // 4 530 baseY = baseY+34; 531 532 textFont(titleFont); 533 fill(102, 130, 215); 534 text("A4z: ", baseX-6, baseY); 535 536 fill(230, 230, 212); 537 textFont(contentFont); 538 text(int(acData[4][0]), 539 baseX+48, baseY-3); 540 text("", baseX+79, baseY-3); 541 text(acData[4][1], 542 baseX+84, baseY-3); 543 text("", baseX+142, baseY-3); 544 text(acData[4][2], 545 baseX+147, baseY-3); 546 text("", baseX+205, baseY-3); 547 text(acData[4][3], 548 baseX+210, baseY-3); 549 550 // 5x 551 baseY = baseY+34; 552 textFont(titleFont); 553 554 fill(139, 137, 127); 555 text("A5x: ", baseX-6, baseY); 556 fill(230, 230, 557 212); 558 textFont(contentFont); 559 text(int(acData[5][0]), baseX+48, baseY-3); 560 561 text("", baseX+79, baseY-3); 562 text(acData[5][1], baseX+84, baseY-3); 563 564 text("", baseX+142, baseY-3); 565 text(acData[5][2], baseX+147, baseY-3); 566 567 text("", baseX+205, baseY-3); 568 text(acData[5][3], baseX+210, baseY-3); 569 570 571 // 5y 572 baseY = baseY+34; 573 textFont(titleFont); 574 fill(139, 137, 127); 575 576 text("A5y: ", baseX-6, baseY); 577 fill(230, 230, 212); 578 textFont(contentFont); 579 580 text(int(acData[6][0]), baseX+48, baseY-3); 581 text("", baseX+79, baseY-3); 582 583 text(acData[6][1], baseX+84, baseY-3); 584 text("", baseX+142, baseY-3); 585 586 text(acData[6][2], baseX+147, baseY-3); 587 text("", baseX+205, baseY-3); 588 589 text(acData[6][3], baseX+210, baseY-3); 590 591 // separador 592 baseY = baseY+34; 593 594 textFont(contentFont); 595 fill(230, 230, 212); 596 text("", baseX-6, baseY-3); 597 598 599 // Average 600 baseY = baseY+34; 601 textFont(titleFont); 602 fill(230, 230, 603 212); 604 text("AVz: ", baseX-6, baseY); 605 fill(230, 230, 212); 606 textFont(contentFont); 607 608 text(int(acData[0][0]), baseX+48, baseY-3); 609 text("", baseX+79, baseY-3); 610 611 text(acData[0][1], baseX+84, baseY-3); 612 text("", baseX+142, baseY-3); 613 614 text(acData[0][2], baseX+147, baseY-3); 615 text("", baseX+205, baseY-3); 616 617 text(acData[0][3], baseX+210, baseY-3); 618 619 // Credits 620 textFont(copyrightFont); 621 622 fill(35, 41, 44); 623 text("created by luiz gustavo zanotello at jun/2012", 624 width-233, height-30); 625 text("http://www.viraseres.com/nama", width-154, height-20); 626 627 text("under CC BY-NC-SA 3.0", width-114, height-10); 628 629 //////////////////////////////////////////////////////////////////////////////////////////// 630 631 // Graph 632 noStroke(); 633 fill(255); 634 baseX = width-width/3+map(acData[5][1], 635 0, 1, -1, 1)*100; 636 baseY = height/2+map(acData[6][1], 0, 1, -1, 1)*100+map(acData[0][1], 637 0, 1, -1, 1)*50; 638 translate(baseX, baseY, map(acData[0][1], 0, 1, 50, -100)); 639 640 perspective(); 641 rotateX(radians(acData[5][1]*360)); 642 rotateY(radians(acData[6][1]*360)); 643 644 rotateZ(radians(acData[0][1]*360)); 645 directionalLight(120, 120, 120, 0, -1, 646 -1); 647 ambientLight(230, 230, 230); 648 649 // 4 650 fill(142-(acData[2][3]*255*100), 651 170-(acData[2][3]*255*100), 255-(acData[2][3]*255*100), 90+(acData[4][3]*255*100)); 652 653 goPoint[4][0] = 0-interfaceDimensionX+map(acData[4][1], 0, 1, -100, 100); 654 655 goPoint[4][1] = interfaceDimensionY/2+map(acData[4][1], 0, 1, -100, 100); 656 657 goPoint[4][2] = map(acData[4][1], 0, 1, -400, 400); 658 pushMatrix(); 659 translate(goPoint[4][0], 660 goPoint[4][1], goPoint[4][2]); 661 sphere(6); 662 popMatrix(); 663 664 // 3 665 666 fill(142-(acData[1][3]*255*100), 255-(acData[1][3]*255*100), 201-(acData[1][3]*255*100), 667 90+(acData[4][3]*255*100)); 668 goPoint[3][0] = 0-interfaceDimensionX+map(acData[3][1], 669 0, 1, -100, 100); 670 goPoint[3][1] = 0-interfaceDimensionY/2+map(acData[3][1], 671 0, 1, -100, 100); 672 goPoint[3][2] = map(acData[3][1], 0, 1, -400, 400); 673 pushMatrix(); 674 675 translate(goPoint[3][0], goPoint[3][1], goPoint[3][2]); 676 sphere(6); 677 popMatrix(); 678 679 680 // 2 681 fill(255-(acData[3][3]*255*100), 221-(acData[3][3]*255*100), 142-(acData[3][3]*255*100), 682 90+(acData[4][3]*255*100)); 683 goPoint[2][0] = interfaceDimensionX+map(acData[2][1], 684 0, 1, -100, 100); 685 goPoint[2][1] = 0-interfaceDimensionY/2+map(acData[2][1], 686 0, 1, -100, 100); 687 goPoint[2][2] = map(acData[2][1], 0, 1, -400, 400); 688 pushMatrix(); 689 690 translate(goPoint[2][0], goPoint[2][1], goPoint[2][2]); 691 sphere(6); 692 popMatrix(); 693 694 695 // 1 696 fill(255-(acData[4][3]*255*100), 142-(acData[4][3]*255*100), 164-(acData[4][3]*255*100), 697 90+(acData[4][3]*255*100)); 698 goPoint[1][0] = interfaceDimensionX+map(acData[1][1], 699 0, 1, -100, 100); 700 goPoint[1][1] = interfaceDimensionY/2+map(acData[1][1], 0, 701 1, -100, 100); 702 goPoint[1][2] = map(acData[1][1], 0, 1, -400, 400); 703 pushMatrix(); 704 705 translate(goPoint[1][0], goPoint[1][1], goPoint[1][2]); 706 sphere(6); 707 popMatrix(); 708 709 710 // C 711 fill(179-(acData[5][3]*255*100)-(acData[6][3]*255*100), 177-(acData[5][3]*255*100)-(acData[6][3]*255*100), 712 167-(acData[5][3]*255*100)-(acData[6][3]*255*100), 90+(acData[5][3]*255*100)+(acData[6][3]*255*100)); 713 714 goPoint[0][0] = map(acData[5][1], 0, 1, -400, 400); 715 goPoint[0][1] = map(acData[6][1], 716 0, 1, -400, 400); 717 goPoint[0][2] = map(acData[0][1], 0, 1, -100, 100); 718 pushMatrix(); 719 720 translate(goPoint[0][0], goPoint[0][1], goPoint[0][2]); 721 sphere(6); 722 popMatrix(); 723 724 725 // Lines 726 stroke(255); 727 line(goPoint[0][0], goPoint[0][1], goPoint[0][2], 728 goPoint[1][0], goPoint[1][1], goPoint[1][2]); 729 line(goPoint[0][0], goPoint[0][1], 730 goPoint[0][2], goPoint[2][0], goPoint[2][1], goPoint[2][2]); 731 line(goPoint[0][0], 732 goPoint[0][1], goPoint[0][2], goPoint[3][0], goPoint[3][1], goPoint[3][2]); 733 734 line(goPoint[0][0], goPoint[0][1], goPoint[0][2], goPoint[4][0], goPoint[4][1], 735 goPoint[4][2]); 736 line(goPoint[1][0], goPoint[1][1], goPoint[1][2], goPoint[2][0], 737 goPoint[2][1], goPoint[2][2]); 738 line(goPoint[1][0], goPoint[1][1], goPoint[1][2], 739 goPoint[3][0], goPoint[3][1], goPoint[3][2]); 740 line(goPoint[1][0], goPoint[1][1], 741 goPoint[1][2], goPoint[4][0], goPoint[4][1], goPoint[4][2]); 742 line(goPoint[2][0], 743 goPoint[2][1], goPoint[2][2], goPoint[3][0], goPoint[3][1], goPoint[3][2]); 744 745 line(goPoint[2][0], goPoint[2][1], goPoint[2][2], goPoint[4][0], goPoint[4][1], 746 goPoint[4][2]); 747 line(goPoint[3][0], goPoint[3][1], goPoint[3][2], goPoint[4][0], 748 goPoint[4][1], goPoint[4][2]); 749}
Arduino Code
arduino
1/////////////////////////////////////////////////////////////// 2// 3 Nama Project v1.0 4// Instrument Arduino code. 5// ------------------------------------------------------------ 6// 7 Created by Luiz Zanotello on May/2012. 8// Under Creative Commons License: CC 9 BY-NC-SA 3.0. 10// More information at: http://www.viraseres.com/nama 11/////////////////////////////////////////////////////////////// 12 13//Accelerometer 14 1 (z) - bottom right 15//////////////////////////////////// 16const int a1pinV 17 = 6; //output current pin 18const int a1pinZ = A0; //data pin 19 20//Accelerometer 21 2 (z) - top right 22///////////////////////////////// 23const int a2pinV = 7; 24 //output current pi 25const int a2pinZ = A1; //data pin 26 27//Central accelerometer 28 (x/y) 29///////////////////////////// 30const int aCpinV = 8; //output current 31 pi 32const int aCpinX = A2; //data pin 33const int aCpinY = A3; //data pin 34//Accelerometer 35 3 (z) - top left 36//////////////////////////////// 37const int a3pinV = 2; //output 38 current pi 39const int a3pinZ = A4; //data pin 40 41//Accelerometer 4 (z) - bottom 42 left 43/////////////////////////////////// 44const int a4pinV = 3; //output current 45 pi 46const int a4pinZ = A5; //data pin 47 48//////////////////////////////////////////////////////// 49 50void 51 setup() 52{ 53 //Begin serial transmition: 54 Serial.begin(115200); 55 //Set 56 output pins (+ current): 57 pinMode(a1pinV, OUTPUT); 58 digitalWrite(a1pinV, 59 HIGH); 60 pinMode(a2pinV, OUTPUT); 61 digitalWrite(a2pinV, HIGH); 62 pinMode(aCpinV, 63 OUTPUT); 64 digitalWrite(aCpinV, HIGH); 65 pinMode(a3pinV, OUTPUT); 66 digitalWrite(a3pinV, 67 HIGH); 68 pinMode(a4pinV, OUTPUT); 69 digitalWrite(a4pinV, HIGH); 70} 71 72//////////////////////////////////////////////////////// 73 74void 75 loop() 76{ 77 // Printing analog data received from accelerometers 78 Serial.println(); 79 80 Serial.print(5); // Number of accelerometers 81 Serial.print(','); 82 Serial.print(analogRead(a1pinZ)); 83 // Accelerometer 1 reading (z) 84 Serial.print(','); 85 Serial.print(analogRead(a2pinZ)); 86 // Accelerometer 2 reading (z) 87 Serial.print(','); 88 Serial.print(analogRead(a3pinZ)); 89 // Accelerometer 3 reading (z) 90 Serial.print(','); 91 Serial.print(analogRead(a4pinZ)); 92 // Accelerometer 4 reading (z) 93 Serial.print(','); 94 Serial.print(analogRead(aCpinX)); 95 // Central accelerometer reading (x) 96 Serial.print(','); 97 Serial.print(analogRead(aCpinY)); 98 // Central accelerometer reading (y) 99 Serial.print(tranG); 100 delay(10); 101} 102 103//////////////////////////////////////////////////////// 104
Downloadable files
Materials and components
Materials and components
Design
How to sew the components
Design
Fritzing Schematic
Fritzing Schematic
Materials and components
Materials and components
Fritzing Schematic
Fritzing Schematic
Design
How to sew the components
Design
Comments