You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
//Pin connected to ST_CP of 74HC595
int latchPin = 8;
//Pin connected to SH_CP of 74HC595
int clockPin = 12;
////Pin connected to DS of 74HC595
int dataPin = 11;
if(mode == MODE_FREESTYLE) {
if(distanceIndexChanged || playButtonChanged || sharpButtonChanged || modeChanged || octaveChanged) {
// this is kind of gross. this is all the changes that should prompt us
// to reconsider the tone we're emitting now based on user input
updatePlayingToneFromEnvironment();
}
}
else if(mode == MODE_LOOP) {
if(distanceIndexChanged || playButtonChanged || sharpButtonChanged || loopChanged || octaveChanged) {
// similarly, any change that might cause us to change what note we're
// playing based on recorded tones + user input
updateRecordingTone(playButtonChanged, loopChanged);
}
}
}
void updateRecordedNote() {
samples[currentSampleIndex] = playing ? playingTone : -1;
if(currentSampleIndex == 0) {
// need to decide what to save for previous note
int previousNoteIndex = (currentLoopPosition - 1) % MAX_NOTES;
currentSong[previousNoteIndex] = determineSampledNoteValue();
}
}
int determineSampledNoteValue() {
// do a really dumb O(n^2) search through the array to
// find the first value with >= 50% representation.
int minSamples = NUM_SAMPLES_PER_NOTE / 2;
unsigned char encoder_A = digitalRead(rotaryPin1);
unsigned char encoder_B = digitalRead(rotaryPin2);
if((!encoder_A) && (encoder_A_prev)){
// A has gone from high to low
if(encoder_B) {
// B is high so clockwise
delta = 1;
}
else {
// B is low so counter-clockwise
delta = -1;
}
}
encoder_A_prev = encoder_A;
int index = (distance - MIN_DISTANCE) / NOTE_WIDTH;
index = index % NUM_NOTES;
// there is a segment at either edge of each note which must be debounced before it is accepted as a note change
if(distance < MIN_DISTANCE + index * NOTE_WIDTH + NOTE_BOUNDARY_WIDTH || distance > MIN_DISTANCE + (index + 1) * NOTE_WIDTH - NOTE_BOUNDARY_WIDTH) {
if(index != currentDistanceIndex) {
if(++consecutiveChangedNote >= NOTE_CHANGE_THRESHOLD) {
currentDistanceIndex = index;
}
}
}
else {
consecutiveChangedNote = 0;
currentDistanceIndex = index;
}
}
void shiftValue(int value) {
// take the latchPin low so
// the LEDs don't change while you're sending in bits:
digitalWrite(latchPin, LOW);
// shift out the bits:
shiftOut(dataPin, clockPin, MSBFIRST, value);
//take the latch pin high so the LEDs will light up:
digitalWrite(latchPin, HIGH);
}
void updateDistance() {
unsigned int uS = sonar.ping(); // Send ping, get ping time in microseconds (uS).
if(uS) {
currentDistance = uS;
}
}
Hi i have a proble with this code, it saids "" In function
timer0_toggle_count': (.text+0x0): multiple definition of
__vector_7' ""error compling to arduino uno
Please help
this is the code that im ussing
#include <NewPing.h>
#include <Tone.h>
///////////////////////////////////
// constants
#define trigPin 3
#define echoPin 4
#define speakerPin1 9
//#define speakerPin2 10
#define buttonPin 6
#define rotaryPin1 0
#define rotaryPin2 1
#define sharpPin 7
#define modePin 2
#define metronomeLightPin 5
//Pin connected to ST_CP of 74HC595
int latchPin = 8;
//Pin connected to SH_CP of 74HC595
int clockPin = 12;
////Pin connected to DS of 74HC595
int dataPin = 11;
const int NUM_OCTAVES = 6;
double scales[NUM_OCTAVES][8] = {
{65, 73, 82, 87, 98, 110, 123, 131},
{NOTE_C3, NOTE_D3, NOTE_E3, NOTE_F3, NOTE_G3, NOTE_A3, NOTE_B3, NOTE_C4},
{NOTE_C4, NOTE_D4, NOTE_E4, NOTE_F4, NOTE_G4, NOTE_A4, NOTE_B4, NOTE_C5},
{NOTE_C5, NOTE_D5, NOTE_E5, NOTE_F5, NOTE_G5, NOTE_A5, NOTE_B5, NOTE_C6},
{NOTE_C6, NOTE_D6, NOTE_E6, NOTE_F6, NOTE_G6, NOTE_A6, NOTE_B6, NOTE_C7},
{NOTE_C7, NOTE_D7, NOTE_E7, NOTE_F7, NOTE_G7, NOTE_A7, NOTE_B7, NOTE_C8}
};
double HALF_STEP_RATIO = 1.059463094359;
#define MAX_SENSOR_DISTANCE 200 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.
const int MODE_BUTTON_CHECK_FREQUENCY = 20; // ms
const int BUTTON_HOLD_MIN_LENGTH = 25;
///////////////////////////////////
// globals
NewPing sonar(trigPin, echoPin, MAX_SENSOR_DISTANCE); // NewPing setup of pins and maximum distance.
Tone notePlayer[2];
long currentDistance = 0;
double distanceCheckTimer[1] = {0};
double playButtonCheckTimer[1] = {0};
double sharpCheckTimer[1] = {0};
double loopTimer[1] = {0};
int playButtonPressed = 0;
boolean playing = false;
int playingTone;
int currentDistanceIndex;
int sharpPressed = 0;
boolean metronomeOn = false;
const boolean MODE_FREESTYLE = true;
const boolean MODE_LOOP = false;
boolean mode = MODE_FREESTYLE;
const boolean ROTARY_TEMPO = true;
const boolean ROTARY_OCTAVE = false;
boolean rotaryMode = ROTARY_OCTAVE;
int currentOctave = 1;
const int BUTTON_NO_CLICK = 0;
const int BUTTON_CLICKED = 1;
const int BUTTON_LONG_CLICKED = 2;
#define NUM_SAMPLES_PER_NOTE 16
#define MAX_NOTES 128
#define MIN_TEMPO 8
#define MAX_TEMPO 250
int currentTempo = 50; // length of eighth note, in ms
double samples[NUM_SAMPLES_PER_NOTE];
double currentSong[MAX_NOTES];
int currentSampleIndex = 0;
int currentLoopPosition = 0;
///////////////////////////////////
void setup() {
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(buttonPin, INPUT);
pinMode(sharpPin, INPUT);
pinMode(modePin, INPUT);
pinMode(rotaryPin1, INPUT);
pinMode(rotaryPin2, INPUT);
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(metronomeLightPin, OUTPUT);
notePlayer[0].begin(speakerPin1);
//notePlayer[1].begin(speakerPin2);
for(int i = 0; i < MAX_NOTES; i++) {
currentSong[i] = -1;
}
}
void loop() {
boolean playButtonChanged = updatePlayButtonState();
boolean sharpButtonChanged = updateSharpButtonState();
boolean distanceIndexChanged = updateCurrentDistanceIndex();
boolean loopChanged = updateLoopPosition();
int modeButtonState = getModeButtonState();
bool modeChanged = false;
if(modeButtonState == BUTTON_LONG_CLICKED) {
modeChanged = true;
// switch instrument mode (freestyle vs loop)
mode = (mode == MODE_FREESTYLE ? MODE_LOOP : MODE_FREESTYLE);
if(mode == MODE_FREESTYLE) {
rotaryMode = ROTARY_OCTAVE;
}
}
else if(mode == MODE_LOOP && modeButtonState == BUTTON_CLICKED) {
// in loop mode, switch rotary mode (change tempo vs change octave)
rotaryMode = (rotaryMode == ROTARY_OCTAVE ? ROTARY_TEMPO : ROTARY_OCTAVE);
}
if(mode == MODE_LOOP) {
tickMetronomeLight();
}
else {
disableMetronomeLight();
}
boolean octaveChanged = updateTempoOrOctave();
if(distanceIndexChanged) {
updateHighlightedTone(currentDistanceIndex);
}
if(mode == MODE_FREESTYLE) {
if(distanceIndexChanged || playButtonChanged || sharpButtonChanged || modeChanged || octaveChanged) {
// this is kind of gross. this is all the changes that should prompt us
// to reconsider the tone we're emitting now based on user input
updatePlayingToneFromEnvironment();
}
}
else if(mode == MODE_LOOP) {
if(distanceIndexChanged || playButtonChanged || sharpButtonChanged || loopChanged || octaveChanged) {
// similarly, any change that might cause us to change what note we're
// playing based on recorded tones + user input
updateRecordingTone(playButtonChanged, loopChanged);
}
}
}
///////////////////////////////////
boolean updatePlayButtonState() {
if(tick(11, playButtonCheckTimer)) {
int oldButton = playButtonPressed;
playButtonPressed = digitalRead(buttonPin);
return oldButton != playButtonPressed;
}
return false;
}
boolean updateSharpButtonState() {
if(tick(11, sharpCheckTimer)) {
int oldSharp = sharpPressed;
sharpPressed = digitalRead(sharpPin);
return oldSharp != sharpPressed;
}
return false;
}
boolean updateCurrentDistanceIndex() {
if(tick(40, distanceCheckTimer)) {
updateDistance();
int oldDistanceIndex = currentDistanceIndex;
updateIndexFromDistance(currentDistance);
return oldDistanceIndex != currentDistanceIndex;
}
return false;
}
void updateHighlightedTone(int distanceIndex) {
if(distanceIndex >= 0) {
noteLightOn(distanceIndex);
}
else if(distanceIndex < 0) {
noteLightOff();
}
}
void updatePlayingToneFromEnvironment() {
int newTone;
if(currentDistanceIndex == -1 || !playButtonPressed) {
newTone = -1;
}
else if(currentDistanceIndex >= 0) {
newTone = currentDistanceIndex >= 0 ? scales[currentOctave][currentDistanceIndex] : currentDistanceIndex;
if(sharpPressed) {
newTone = (int)((double)newTone * HALF_STEP_RATIO);
}
}
playTone(newTone);
}
void playTone(int newTone) {
if(newTone >= 0 && (!playing || newTone != playingTone)) {
notePlayer[0].play(newTone);
playing = true;
playingTone = newTone;
}
else if(newTone < 0 && playing) {
notePlayer[0].stop();
playing = false;
}
}
boolean updateLoopPosition() {
int sampleFreq = currentTempo / NUM_SAMPLES_PER_NOTE;
if(tick(sampleFreq, loopTimer)) {
currentSampleIndex++;
if(currentSampleIndex == NUM_SAMPLES_PER_NOTE) {
currentSampleIndex = 0;
currentLoopPosition = (currentLoopPosition + 1) % MAX_NOTES;
}
return true;
}
return false;
}
void updateRecordingTone(boolean playButtonChanged, boolean loopChanged) {
if(!playButtonPressed) {
if(loopChanged) {
int newTone = currentSong[currentLoopPosition];
playTone(newTone);
}
}
else {
updatePlayingToneFromEnvironment();
updateRecordedNote();
}
}
void updateRecordedNote() {
samples[currentSampleIndex] = playing ? playingTone : -1;
if(currentSampleIndex == 0) {
// need to decide what to save for previous note
int previousNoteIndex = (currentLoopPosition - 1) % MAX_NOTES;
currentSong[previousNoteIndex] = determineSampledNoteValue();
}
}
int determineSampledNoteValue() {
// do a really dumb O(n^2) search through the array to
// find the first value with >= 50% representation.
int minSamples = NUM_SAMPLES_PER_NOTE / 2;
for(int i = 0; i < NUM_SAMPLES_PER_NOTE; i++) {
int candidateValue = samples[i];
int count = 0;
for(int j = 0; j < NUM_SAMPLES_PER_NOTE; j++) {
if(abs(candidateValue - samples[j]) < 0.001) {
count++;
}
}
if(count >= minSamples) {
return candidateValue;
}
}
// if no candidate, record silence.
return -1;
}
void tickMetronomeLight() {
int currentNote = currentLoopPosition / 8;
boolean metronomeState = currentNote % 2;
if(metronomeState != metronomeOn) {
metronomeOn = !metronomeOn;
// if we are in tempo-set mode, make the metronome dim
// instead of completely off
int lowValue = (rotaryMode == ROTARY_TEMPO ? 40 : 0);
analogWrite(metronomeLightPin, metronomeOn ? 255 : lowValue);
}
}
void disableMetronomeLight() {
metronomeOn = false;
analogWrite(metronomeLightPin, 0);
}
///////////////////////////////////
// mostly copy-pasted
unsigned char encoder_A_prev;
boolean updateTempoOrOctave() {
int delta = 0;
unsigned char encoder_A = digitalRead(rotaryPin1);
unsigned char encoder_B = digitalRead(rotaryPin2);
if((!encoder_A) && (encoder_A_prev)){
// A has gone from high to low
if(encoder_B) {
// B is high so clockwise
delta = 1;
}
else {
// B is low so counter-clockwise
delta = -1;
}
}
encoder_A_prev = encoder_A;
if(delta != 0) {
if(rotaryMode == ROTARY_OCTAVE) {
int newOctave = currentOctave + delta;
if(newOctave >= 0 && newOctave < NUM_OCTAVES) {
currentOctave = newOctave;
return true;
}
}
else if(rotaryMode == ROTARY_TEMPO) {
// make size of tempo change proportional to current tempo
int tempoDelta = (int)(-4.0 * (double)currentTempo / 30.0 * (double)delta);
tempoDelta = 0 < tempoDelta && tempoDelta < 2 ? 2 : tempoDelta;
tempoDelta = 0 > tempoDelta && tempoDelta > -2 ? -2 : tempoDelta;
int newTempo = currentTempo + tempoDelta;
newTempo = newTempo < MIN_TEMPO ? MIN_TEMPO : newTempo;
newTempo = newTempo > MAX_TEMPO ? MAX_TEMPO : newTempo;
currentTempo = newTempo;
}
}
return false;
}
///////////////////////////////////
// determine state of mode change button
double modeButtonTimer[1] = {0};
boolean triggeredDoubleClick = false;
int clickLength = 0;
int getModeButtonState() {
if(tick(MODE_BUTTON_CHECK_FREQUENCY, modeButtonTimer)) {
int button_pushed = digitalRead(modePin);
if(button_pushed) {
clickLength++;
if(clickLength == BUTTON_HOLD_MIN_LENGTH) {
if(!triggeredDoubleClick) {
triggeredDoubleClick = true;
return BUTTON_LONG_CLICKED;
}
}
}
else if(!button_pushed) {
if(clickLength > 0) {
clickLength = 0;
if(!triggeredDoubleClick) {
return BUTTON_CLICKED;
}
}
triggeredDoubleClick = false;
}
}
return BUTTON_NO_CLICK;
}
///////////////////////////////////
// distance to index, with debouncing of out-of-range notes and note changes
const int MIN_DISTANCE = 300;
const int NUM_NOTES = 8; // c major for now
const double NOTE_WIDTH = 300.0;
const double NOTE_BOUNDARY_WIDTH = 50;
double MAX_DISTANCE = MIN_DISTANCE + NUM_NOTES * NOTE_WIDTH;
int consecutiveOutOfRange = 0;
const int OUT_OF_RANGE_THRESHOLD = 8;
int consecutiveChangedNote = 0;
const int NOTE_CHANGE_THRESHOLD = 9999;
void updateIndexFromDistance(unsigned int distance) {
if(distance < MIN_DISTANCE || distance > MAX_DISTANCE) {
if(++consecutiveOutOfRange > OUT_OF_RANGE_THRESHOLD) {
currentDistanceIndex = -1;
}
return;
}
else {
consecutiveOutOfRange = 0;
}
int index = (distance - MIN_DISTANCE) / NOTE_WIDTH;
index = index % NUM_NOTES;
// there is a segment at either edge of each note which must be debounced before it is accepted as a note change
if(distance < MIN_DISTANCE + index * NOTE_WIDTH + NOTE_BOUNDARY_WIDTH || distance > MIN_DISTANCE + (index + 1) * NOTE_WIDTH - NOTE_BOUNDARY_WIDTH) {
if(index != currentDistanceIndex) {
if(++consecutiveChangedNote >= NOTE_CHANGE_THRESHOLD) {
currentDistanceIndex = index;
}
}
}
else {
consecutiveChangedNote = 0;
currentDistanceIndex = index;
}
}
///////////////////////////////////
void noteLightOn(int index) {
index = 7 - index;
shiftValue(1 << index);
}
void noteLightOff() {
shiftValue(0);
}
void shiftValue(int value) {
// take the latchPin low so
// the LEDs don't change while you're sending in bits:
digitalWrite(latchPin, LOW);
// shift out the bits:
shiftOut(dataPin, clockPin, MSBFIRST, value);
//take the latch pin high so the LEDs will light up:
digitalWrite(latchPin, HIGH);
}
void updateDistance() {
unsigned int uS = sonar.ping(); // Send ping, get ping time in microseconds (uS).
if(uS) {
currentDistance = uS;
}
}
///////////////////////////////////
boolean tick(int delay, double timekeeper[1]){
unsigned long currentTime = millis();
if(currentTime >= (timekeeper[0] + delay)){
timekeeper[0] = currentTime;
return true;
}
else {
return 0;
}
}
The text was updated successfully, but these errors were encountered: