CSE: Cycle Pitch

This sketch plays an intermittent tone in loop(), raising the pitch each time it gets a pin change interrupt. When it gets to the top of the octave, it starts over.

// cycle_pitch - cycle the pitch on button press

int oj_rc     =   9;  // pin D9 drives right channel
int pb_top    =  11;  // pin D11 is the top button

int dur_delay = 500;  // duration of delay (ms)
int dur_tone  = 500;  // duration of tone  (ms)

// Define an (approximately :-) tempered scale.
int scale[] = {
     392, 415, 440, 466, 494, 523,
  //   G   Ab    A   Bb    B    C
     554, 587, 622, 659, 698, 740  };
  //  Db    D   Eb    E    F   Gb

int scale_ndx =   0;  // Start at the beginning.

volatile boolean pressed = false;

ISR (PCINT0_vect) {
  pressed = true;
}

void setup() {
  pinMode(pb_top, INPUT);
  digitalWrite(pb_top, HIGH);
  pinMode(oj_rc, OUTPUT);

  PCMSK0 |= bit (PCINT3);  // interrupt for D11
  PCIFR  |= bit (PCIF0);   // clear interrupts
  PCICR  |= bit (PCIE0);   // enable interrupts
}

void loop() {
  if (pressed) {  // pressed in last iteration
    scale_ndx = (scale_ndx + 1) % 12;  // cycle
    pressed   = false;
  }

  tone(oj_rc, scale[scale_ndx], dur_tone);
  delay(dur_tone + dur_delay);
}

//SYSIN DD DUMMY

Discussion

Careful Reader will notice that we aren't doing any sort of debouncing. Instead, we accept one or more button presses as a single press. We're also fudging the (A440) pitch scale a bit, rounding the frequencies from the "official" values.


This wiki page is maintained by Rich Morin, an independent consultant specializing in software design, development, and documentation. Please feel free to email comments, inquiries, suggestions, etc!

Topic revision: r13 - 05 Mar 2016, RichMorin
This site is powered by Foswiki Copyright © by the contributing authors. All material on this wiki is the property of the contributing authors.
Foswiki version v2.1.6, Release Foswiki-2.1.6, Plugin API version 2.4
Ideas, requests, problems regarding CFCL Wiki? Send us email