/* * Mega-test for ME30 Mini-board * Written by Eric B. Wertz * Last updated Nov 16, 2009 * * The ME30 Mini-board layout * AnalogIn Pin 0 - potentiometer * Digital Pin 6 - RGB LED - blue, active high * Digital Pin 5 - RGB LED - green, active high * Digital Pin 3 - RGB LED - red, active high * Digital Pin 4 - speaker * Digital Pin 7 - momentary (N.O.) switch, active low * * This program demonstrates the following: * - serial output * - fade RGB LED up/down red, then green, then blue * - sampling for button presses * - read/determine full range of potentiometer (pot) values * - record & play some tones on the speaker */ const int ANALOG_IN_MIN=0, ANALOG_IN_MAX=1023; // 10-bit ADCs for input const int ANALOG_OUT_MIN=0, ANALOG_OUT_MAX=255; // 8-bit resolution PWM for output const int TWO_SECONDS = 2000 ; // # of milliseconds in 2 seconds const long USECS_PER_SEC = 1000000L; // # of microseconds per second // ANALOG pin assignments const int pinPot = 0; // DIGITAL pin assignments const int pinRGB_R = 3; const int pinRGB_G = 5; const int pinRGB_B = 6; const int pinSpeaker = 4; const int pinButton = 7; /* * Number of milliseconds to wait for a switch to stop bouncing before checking again. * The datasheet for this particular series of button says 5ms max. */ const int BUTTON_DEBOUNCE_DELAY = 7; /* * Number of milliseconds to light at one intensity level before changing. * Must be less than or equal to 655 to not overflow an "int" when multiplied * by 100 (percent). */ const unsigned int LED_STEP_PERIOD = 100; /* * 10 milliseconds to get a good refresh rate (100Hz) for plusing the LEDs. */ const unsigned int SWPWM_PERIOD = 10; const unsigned int POT_SAMPLING_DELAY=250; // only check pot value every 0.25sec const unsigned int FREQ_MIN=600, FREQ_MAX=2400; // use two octaves for output const unsigned int TONES_MAX=30; // maximum number of tones to store in array const unsigned int PLAYBACK_PERIOD=500; // msecs to playback tones /* * one-time initializations at start of program */ void setup() { Serial.begin(9600); // init serial connection to 9600bps pinMode(pinButton, INPUT); digitalWrite(pinButton, HIGH); // enable internal pull-up pinMode(pinSpeaker,OUTPUT); pinMode(pinRGB_R, OUTPUT); pinMode(pinRGB_B, OUTPUT); pinMode(pinRGB_G, OUTPUT); } /* Detect (software debounced) button press */ boolean isButtonDown(int pin) { if (digitalRead(pin) == HIGH) return false; delay(BUTTON_DEBOUNCE_DELAY); return (digitalRead(pin) == LOW); } /* Detect (software debounced) button release */ boolean isButtonUp(int pin) { if (digitalRead(pin) == LOW) return false; delay(BUTTON_DEBOUNCE_DELAY); return (digitalRead(pin) == HIGH); } void waitForPressAndRelease(int pin) { while (isButtonUp(pin)) ; while (isButtonDown(pin)) ; } /* * Use the hardware's PWM to shine the LED using a duty cycle that fades up-and-down. * Return indication of whether or not we were interrupted by a button press. */ boolean fadeLEDUsingHardware(byte ledpin, byte buttonpin, int duration) { boolean buttonPressed=false; for (int pct=10; !buttonPressed && (pct <= 100); pct += 10) { analogWrite(ledpin, (pct*ANALOG_OUT_MAX)/100); delay(duration); buttonPressed = isButtonDown(buttonpin); } for (int pct=100; !buttonPressed && (pct >= 0); pct -= 10) { analogWrite(ledpin, (pct*ANALOG_OUT_MAX)/100); delay(duration); buttonPressed = isButtonDown(buttonpin); } return buttonPressed; } /* * PWM at "percentOn" duty cycle in SWPWM_PERIOD millisecond chunks for "duration". */ boolean fadeLEDUsingSoftware(byte ledpin, byte buttonpin, int percentOn, int duration) { boolean buttonPressed = false; int partOfPeriodOn = (SWPWM_PERIOD*percentOn)/100; while (!buttonPressed && (duration >= SWPWM_PERIOD)) { digitalWrite(ledpin, HIGH); delay(partOfPeriodOn); digitalWrite(ledpin, LOW); delay(SWPWM_PERIOD-partOfPeriodOn); duration -= SWPWM_PERIOD; buttonPressed = isButtonDown(buttonpin); } /* do remaining fraction of SWPWM_PERIOD, if any */ if (!buttonPressed && (duration > 0)) { partOfPeriodOn = (duration*percentOn)/100; digitalWrite(ledpin, HIGH); delay(partOfPeriodOn); digitalWrite(ledpin, LOW); } return buttonPressed; } /* * Cycle through red then green then blue until the button is pressed. * Check to see if the button is depressed at every intensity step to be more responsive. */ void doLEDFades() { boolean buttonPressed=false; Serial.println("Time for some cosmic LED action. Press button when you've had enough."); while (!buttonPressed) { buttonPressed = fadeLEDUsingHardware(pinRGB_R, pinButton, LED_STEP_PERIOD); if (!buttonPressed) buttonPressed = fadeLEDUsingHardware(pinRGB_G, pinButton, LED_STEP_PERIOD); if (!buttonPressed) buttonPressed = fadeLEDUsingHardware(pinRGB_B, pinButton, LED_STEP_PERIOD); } while (isButtonDown(pinButton)) // wait for button to be released ; digitalWrite(pinRGB_R, LOW); digitalWrite(pinRGB_G, LOW); digitalWrite(pinRGB_B, LOW); Serial.println(); } void doPotSampling(byte ledPin, unsigned int *pPotMin, unsigned int *pPotMax) { unsigned int potValue, potMax=ANALOG_IN_MIN, potMin=ANALOG_IN_MAX; boolean changedBounds; Serial.println("Sweep the pot knob over its full range. Press button when done."); while (isButtonUp(pinButton)) { potValue = analogRead(pinPot); changedBounds = false; if (potValue > potMax) { potMax = potValue; changedBounds = true; } if (potValue < potMin) { potMin = potValue; changedBounds = true; } analogWrite(ledPin, map(potValue, ANALOG_IN_MIN, ANALOG_IN_MAX, ANALOG_OUT_MIN, ANALOG_OUT_MAX)); if (changedBounds) { Serial.print("min="); Serial.print (potMin); Serial.print(", max="); Serial.println(potMax); } delay(POT_SAMPLING_DELAY); // don't go crazy by sampling more than every 1/4 sec } while (isButtonDown(pinButton)) ; Serial.println(); *pPotMin = potMin; *pPotMax = potMax; digitalWrite(ledPin, LOW); } void playTone(int pin, int freq, int durationMSecs) { long duration = (long)durationMSecs * 1000L, fullPeriod = USECS_PER_SEC/freq, halfPeriod = fullPeriod/2, i; for (i=0; i TWO_SECONDS) done = true; else tones[tonenum++] = freq; } } while (!done); Serial.println(); return tonenum; } /* * Play back array of tones, half-period on and off (duty cycle 50%). */ void doPlayback(int pin, unsigned int numtones, unsigned int *tones, unsigned int playbackPeriod) { unsigned int i, halfPeriod=(playbackPeriod/2); Serial.print("Playing song consisting of "); Serial.print(numtones); Serial.println(" tones."); for (i=0; i