/* Thingamagoop 2 Arduino code By Dr. Bleep Nov 2009 See bleeplabs.com for more info Update April 2012: This code is the first thing I made in Arduino and looks it. If you're wanting to make noise, check out the code for the NEBULOPHONE http://bleeplabs.com/wp/wp-content/uploads/2010/04/Nebulophone_D01.zip. */ int pcellPin = 3; // Photocell analog in int ModePot = 5; // top right pot int LedPot = 4; // nottom left pot int outPin = 9; //PWM out to analog digital switch taht feed VCO int LedPin = 11; //BLIBKYBLIBKY BLINK. To 120 ohm resistor then LEDacle int pcellval; // Raw photocell value int mval; // Photocell value + MATHMATICS int note; // more maths int modeA; // modified ModePot values int modeAC; int mode; // Raw ModePot valus int interval1; // values for timers long prev1; long prev2; long prev3; int i=0; // variables for mode int r; int j=1; // Variable for LEDacle long ledrate; // Modified LedPot values long ledrateC; long ledpotval; int majscale[32]={ 238,224,200,178,159,150,133,119,112,100,89,79,75,67,59,56,50,45,40,37,33,30,28,25,22,20,19,17,15,14,13,11}; // voltage values for output to VCO. The VOC is pretty much linear but cnages with the voltage supplied. These were derived simply my //hooking the VCO up to a tuner ant trying to hit the steps of a major scale long random1; long random2; void setup (){ randomSeed(analogRead(4)); //Hey analog pin 4, what's going on. Cool, give me a random number KTHXBI //Serial.begin(9600); TCCR1B = B00000001; TCCR2B = B00000001; //Turns of the prescaler off PWM outputs on 9 and 11. Easy way smootgh the output. } void loop(){ //Serial.print(random1);Serial.print(" : ");Serial.println(mval); //Serial.print(ledpotval); Serial.print(" : "); Serial.println(ledrateC); if (millis() - prev3 > 4 ) { // Only read all the analog ins every 4ms. If you constanly read it will be a little messy. prev3 = millis(); ledpotval = analogRead(LedPot); //read, read, read. mode = analogRead(ModePot); pcellval = analogRead(pcellPin); mval = (map(pcellval, 256, 1000, 32 , 0)); // Controls the high and low range of the photcell. TO CHAnGE : make this a logarithmic mapping mval = constrain (mval,0,32); //keeps the value between 0 and 32 note = majscale[mval]; //and uses it to get one of the note voltages } // DIGITAL MODES // E - Sample and hold "Thingamagoop sounds beter autotuuuuuuuned" if (mode <255){ //where the mode happens on the pot TCCR1B = B00000001; //resets the prescaler to off since some modes chage it modeA = map(mode, 0, 254, 5, 133); //maps the pot to chage the lenght of notes while in the "E" mode. modeAC = constrain (modeA, 5,133); if (millis() - prev1 > modeAC ) { prev1 = millis(); analogWrite(outPin, majscale[mval]); } } // A - Arpegio 1 "Robot Wasteland" if (mode >=256 && mode<510){ //where the mode happens on the pot TCCR1B = B00000001; //resets the prescaler to off since some modes chage it modeA = map(mode, 256, 510, 500, 1); //maps the pot to chage the arpegio speed while in the "A" mode. modeAC = constrain (modeA, 1,500); if (millis() - prev1 > modeAC ) { //the arpegio code. Counts up i to 3 then back to 0 prev1 = millis(); i++; analogWrite(outPin, majscale[mval+i]); //Plays the note the photocell is at, then 1 up, then 2 up, then 3, then back. if (i>3){ i=0; } } } // B - Arpegio 2 "Pac Madness" if (mode >=510 && mode<767){ //where the mode happens on the pot TCCR1B = B00000001; //resets the prescaler to off since some modes chage it. modeA = map(mode, 510, 767, 120, 1); //maps the pot to chage the arpegio speed while in the "B" mode. modeAC = constrain (modeA, 1,120); if (millis() - prev1 > modeAC ) { //the arpegio code. Counts up i to 8 then back to 0 prev1 = millis(); i++; if (i<3){ //plays a sequence of notes based on the mval. off, down 3, at the mval, off, up three, off repeat. analogWrite(outPin, 0); } if (i==3){ analogWrite(outPin, majscale[mval-3]); } if (i==4){ analogWrite(outPin, majscale[mval]); } if (i>4 && i<7){ analogWrite(outPin, 0); } if (i==7){ analogWrite(outPin, majscale[mval+3]); } if (i==8){ i=0; analogWrite(outPin, majscale[mval+1]); } } } // X - Noise is the future if (mode >=767 && mode<831){ //where the mode happens on the pot TCCR1B = B00000001; //resets the prescaler to off since some modes chage it. mval = (map(pcellval, 256, 1000, 0 , 255)); //Instead of using the maval with the majscale voltages, use it to chage the maximu random nimber. random1 = random(mval); // This makes the photocell controll the filter of the sound rather than the pitch prev1 = millis(); if (millis() - prev1 > 30 ) { // slows the output down a bit analogWrite(outPin, random1); } } if (mode >=831 && mode<895){ //This mode juast chages between two values TCCR1B = B00000001; //resets the prescaler to off since some modes chage it. mval = (map(pcellval, 256, 1000, 0 , 255)); //Same as the last random1 = random(mval); analogWrite(outPin, random1); } // z - Bit Crushinator if (mode >=895 && mode<959){ //where the mode happens on the pot TCCR1B = B0000010; //I told you! This mode changes the prescaler of the output to the vco to /8, creating a bit crush effect if (millis() - prev1 > 50 ) { prev1 = millis(); analogWrite(outPin, majscale[mval]); } } if (mode >=959){ //where the mode happens on the pot TCCR1B = B0000011; //This mode has two parts. In the secon half the prescaler is changed to /32. if (millis() - prev1 > 50 ) { prev1 = millis(); analogWrite(outPin, majscale[mval]); } } // LEDacle //Random "The synthesizer is thinking" if (ledpotval >=1021) //Same idea as the digital mode pot. Differnt zones do differnt things. { analogWrite(LedPin, 255); //If it's all the way to the right the LED is just on. //digitalWrite(12, HIGH); } else if (ledpotval >512 && ledpotval <1020){ //The right half of the pot is the random waveform. ledrate = map(ledpotval, 513, 1021, 200 , 1); //maps the pot to chage the rate while in the "random" mode. ledrateC = constrain(ledrate, 1,200); if (millis() - prev2 > ledrateC) { //This is a random walk instead of a random noise like the "X" digital mode. //It randomly selects from a set of actions. This gives it a more musical, rather than white noise, sound. prev2 = millis(); analogWrite(LedPin, r); //Make with the blink. random2 = random(6); //Random nuimber from 0-6 if (random2 <2){ //go down 32 r-=32; } if (random2 == 2){ //up 32 r+=32; } if (random2 == 3){ //up 64 r+=64; } if (random2 == 4){ //reset to 128 r=128; } if (random2 >= 5){ //reset to 0 r=0; } } } // Ramp - "ACHTUNG" if (ledpotval <=512){ //The left half of the pot is the random waveform. ledrate = map(ledpotval, 0, 512, 35000 , 1); //maps the pot to chage the rate while in the "ramp" mode. ledrateC = constrain(ledrate, 1,35000); if (micros() - prev2 > ledrateC) { //increas j by 20 untill it hits 240 and reset. Easy! prev2 = micros(); if (j>0){ j+=20; analogWrite(LedPin, j); } if (j>=240){ j=10; //analogWrite(led2Pin, j); } } } //;Serial.print(" : ");Serial.println(random2); // Serial.print(pcellval);Serial.print(" : ");Serial.println(mval); } /* Things to change. Increse resolution of outputs without adding digital noise or a sepaerta chip. */