#include // notes - http://www.phy.mtu.edu/~suits/notefreqs.html const float NOTEC3 = 130.81; const float NOTEC4 = 261.63; const float NOTED4 = 293.66; const float NOTEE4 = 329.63; const float NOTEG4 = 392; const float NOTEA4 = 440; const float NOTEB4 = 493.88; const float NOTEC5 = 523.25; const float NOTEG5 = 783.99; long startTime; const int ledPin = 5; const int switchPin = 7; const int spkrPin = 6; boolean switchState, prevState; // BEGIN SPI INTRO #define DATAOUT 11//MOSI #define DATAIN 12//MISO #define SPICLOCK 13//sck #define SLAVESELECT 10//ss for /LIS3LV02DQ, active low #define RTC_CHIPSELECT 9// chip select (ss/ce) for RTC, active high byte clr; // END SPI INTRO // BEGIN TOUCH VARIABLES const int touchPinA = 4; const int touchPinB = 2; int touchReferenceReading, touchReferenceDelta; // END TOUCH VARIABLES // BEGIN ACCELEROMETER VARIABLES long n, nStroke, strokeEntropyX = 0, strokeEntropyY = 0, strokeEntropyZ = 0, maxX, maxY, initialVectorX, initialVectorY; // # of samples collected long totalX = 0, totalY = 0, totalZ = 0; // sum of X readings long avgX, avgY, avgZ, calibX, calibY, calibZ, vectorX, vectorY, vectorZ; // average of X int x_val, y_val, z_val; byte x_val_l, x_val_h, y_val_l, y_val_h, z_val_l, z_val_h; const int nVectorBuffer = 5; long vectorBufferX[nVectorBuffer]; long vectorBufferY[nVectorBuffer]; boolean inStroke = false; const int motionThreshold = 30, entropyThreshold = 150, strokeThreshold = 500; long vBufXAvg, vBufYAvg; // END ACCELEROMETER VARIABLES void setup() { // BEGIN TOUCH SETUP touchReferenceReading = touchGetReading(); // ignore first one - was getting bogus values delay(100); touchReferenceReading = touchGetReading(); touchReferenceDelta = touchReferenceReading / 3; // END TOUCH SETUP // sound setup startTime = millis(); pinMode(ledPin, OUTPUT); pinMode(switchPin, INPUT); pinMode(spkrPin, OUTPUT); prevState = false; // accelerom setup char in_byte; clr = 0; in_byte = clr; Serial.begin(9600); // set direction of pins pinMode(DATAOUT, OUTPUT); pinMode(DATAIN, INPUT); pinMode(SPICLOCK,OUTPUT); pinMode(SLAVESELECT,OUTPUT); digitalWrite(SLAVESELECT,HIGH); //disable device pinMode(10, OUTPUT); // SPCR = 01010000 // Set the SPCR register to 01010000 //interrupt disabled,spi enabled,msb 1st,master,clk low when idle, //sample on leading edge of clk,system clock/4 rate SPCR = (1< motionThreshold) || (abs(vBufYAvg) > motionThreshold)) { inStroke = true; accelResetStroke(); initialVectorX = vBufXAvg; initialVectorY = vBufYAvg; // spkrBeep(spkrPin, NOTED4, 100); // Serial.println("STROKE START"); } } else { n++; nStroke++; totalX += x_val - calibX; totalY += y_val - calibY; totalZ += z_val - calibZ; strokeEntropyX += log(abs(vectorBufferX[nVectorBuffer - 1] - vectorBufferX[nVectorBuffer - 2])); strokeEntropyY += log(abs(vectorBufferY[nVectorBuffer - 1] - vectorBufferY[nVectorBuffer - 2])); if (abs(vBufXAvg) > abs(maxX)) { maxX = vBufXAvg; } if (abs(vBufYAvg) > abs(maxY)) { maxY = vBufYAvg; } /* if (nStroke % 10 == 0) { Serial.print("X: "); for (int d = 0; d < nVectorBuffer; d++) { Serial.print(vectorBufferX[d]); Serial.print(" "); } Serial.println(); Serial.print("Y: "); for (int d = 0; d < nVectorBuffer; d++) { Serial.print(vectorBufferY[d]); Serial.print(" "); } Serial.println(); /* Serial.println(vectorBufferX); Serial.println(vectorBufferY); } */ accelCloseStroke(); } /* multiple "strokes" here if (abs(x_val-calibX) < 100) { doSpkr(NOTEC5, 0.5, 50); } */ // delay(50); } } void accelCloseStroke() { if ( ((abs(maxX) > strokeThreshold) || (abs(maxY) > strokeThreshold)) /* && (((initialVectorX > 0) && (maxX > initialVectorX) || (initialVectorX < 0) && (maxX < initialVectorX)) || ((initialVectorY > 0) && (maxY > initialVectorY) || (initialVectorY < 0) && (maxY < initialVectorY))) */ // (abs(vBufXAvg) < motionThreshold) && (abs(vBufYAvg) < motionThreshold) // && (nStroke > 15) && ((abs(strokeEntropyX) > entropyThreshold) || (abs(strokeEntropyY) > entropyThreshold)) // && (abs(avgX) > motionThreshold) && (abs(avgY) > motionThreshold) ) { inStroke = false; spkrBeep(spkrPin, NOTEE4, 100); // Serial.println("STROKE END"); avgX = totalX / n; avgY = totalY / n; avgZ = totalZ / n; // Serial.println(); // DEBUG Serial.print(n); Serial.print(" "); Serial.print(nStroke); Serial.print(" "); Serial.print(avgX); Serial.print(" "); Serial.print(avgY); Serial.print(" "); Serial.print(maxX); Serial.print(" "); Serial.print(maxY); Serial.print(" "); Serial.print(strokeEntropyX); Serial.print(" "); Serial.print(strokeEntropyY); Serial.print(" "); Serial.print(vBufXAvg); Serial.print(" "); Serial.println(vBufYAvg); accelResetStroke(); delay(300); spkrBeep(spkrPin, NOTEG4, 100); } } void accelResetStroke() { totalX = 0; totalY = 0; totalZ = 0; nStroke = 0; strokeEntropyX = 0; strokeEntropyY = 0; maxX = 0; maxY = 0; for (int vBufNdx = 0; vBufNdx < nVectorBuffer; vBufNdx++) { vectorBufferX[vBufNdx] = 0; vectorBufferY[vBufNdx] = 0; } } // speaker code from http://www.ladyada.net/make/eshield/examples.html void spkrBeep(uint8_t pin, uint16_t freq, int32_t us) { int usdelay; usdelay = 500000 / freq; pinMode(pin, OUTPUT); us *= 1000; //in uS while (us > 0) { digitalWrite(pin, HIGH); delayMicroseconds(usdelay); digitalWrite(pin, LOW); delayMicroseconds(usdelay); us -= usdelay*2; } } // BEGIN SPI FUNCTIONS char spi_transfer(volatile char data) { /* Writing to the SPDR register begins an SPI transaction */ SPDR = data; /* Loop right here until the transaction is complete. the SPIF bit is the SPI Interrupt Flag. When interrupts are enabled, and the SPIE bit is set enabling SPI interrupts, this bit will set when the transaction is finished. */ while (!(SPSR & (1< touchReferenceDelta) { // Serial.println("true"); return true; } else { // Serial.println("false"); return false; } } int touchGetReading() { int count = 0; pinMode(touchPinA, OUTPUT); pinMode(touchPinB, OUTPUT); digitalWrite(touchPinA, LOW); digitalWrite(touchPinB, LOW); // while (digitalRead(touchPinA) != HIGH) { while ((PIND & B00010000) != B00010000) { count++; DDRD = B00010000; // pinMode(a, output) // DDRD &= !B00000100; // pinmode(b, input) PORTD |= B00010000; // write(a, high) /* DDRD = B00000100; PORTD &= !B00000100; */ /* pinMode(touchPinB, INPUT); pinMode(touchPinA, OUTPUT); digitalWrite(touchPinA, HIGH); */ pinMode(touchPinA, INPUT); pinMode(touchPinB, OUTPUT); digitalWrite(touchPinB, LOW); } return count; } // END TOUCH FUNCTIONS