/* * Capacitive Turbulence Demo * by Connor Nishijima * For 16MHz or higher AVR systems like the ATMEGA, or ATTINY with an external (>= 16MHz) clock! * * No license of any kind, do as you please with it! */ const int numReadings = 50; // the number of readings used for averaging int readings[numReadings]; // the readings from the analog input int readIndex = 0; // the index of the current reading float total = 0; // the running total float average = 0; // the average int inputPin = A3; // readings are from A3 int lastMax = 0; // last maximum value seen int maxVal = 0; // maximum value this interval int maxI = 0; // index in max readings const int maxReadingsN = 100; // number of max readings int maxReadings[maxReadingsN]; // max readings array int maxChange = 0; // change of maxVal this interval int lastMaxChange = 0; // change of maxVal last interval void setup() { Serial.begin(250000); // Fast serial speed to reduce lag analogReference(INTERNAL); // AREF of 1v1 makes for higher sensitivity for (int thisReading = 0; thisReading < numReadings; thisReading++) { // initialize averaging array readings[thisReading] = 0; } } void loop() { long now = millis(); // The time in mS since boot takeReading(); // EVERY mS if (now % 10 == 0) { // EVERY 10 mS sendReading(); // Print to Serial and write PWM value to Pin 3. } while (millis() == now) { // WAIT UNTIL NEXT MILLISECOND } } void takeReading() { float a = getAverage(analogRead(inputPin)); // Get moving average value of A3. getMax(a); // See if this reading is the maximum value received in this interval int change = maxVal - lastMax; // calculate change from one interval to the next if (change < 0) { change *= -1; // get the absolute value of the change } if (change > 1) { // if any change if (change > maxChange) { maxChange = change; // if this is the new max, make it so. } } lastMax = maxVal; } void sendReading() { int output = 0; if (maxChange > 0) { // if any change lastMaxChange = maxChange; output = maxChange; } else { // if no change, print last change value to remove jitter in output output = lastMaxChange; } maxChange = 0; if (output < 900) { // This skips a huge burst of change when the Arduino boots Serial.println(output); // Send turbulence value to Serial port. analogWrite(3, constrain(output, 1, 254)); // Write turbulence value to PWM on Pin 3. Use pulseIn() with an Pin Change Interrupt on another Arduino to decode this easily. // The value is never 0 or 255 to keep PWM pulsing for the external interrupt of the other board. } } void getMax(int reading) { // Adds readings to an array to calculate the maxVal per interval maxReadings[maxI] = reading; maxI++; if (maxI > maxReadingsN) { maxI = 0; maxVal = 0; int i = 0; while (i < maxReadingsN) { if (maxReadings[i] > maxVal) { maxVal = maxReadings[i]; } i++; } } } float getAverage(int reading) { // This is used for smoothing of the data received from A3. // subtract the last reading: total = total - readings[readIndex]; // read from the sensor: readings[readIndex] = reading; // add the reading to the total: total = total + readings[readIndex]; // advance to the next position in the array: readIndex = readIndex + 1; // if we're at the end of the array... if (readIndex >= numReadings) { // ...wrap around to the beginning: readIndex = 0; } // calculate the average: average = total / numReadings; return average; }