Theremin con fotocellule

Buongiorno a tutti, ho creato un theremin con una fotocellula con questo codice:

//pin definitions
#define PHONES 9   // headphones connected to digital pin 9
#define PHOTOCELL 0 //photocell analog in pin 0

//variable definitions
long val = 0;        //stores raw value from photocell
long maxread = 0;    //maximum value from calibration phase
long minread = 1000;  // minimum value from calibration phase
double f = 0;         // frequency of sound
double normf = 0;    // normalized frequency 
double logf = 0;      // logarithm of normalized frequency
int ilogf = 0;        // rounded logarithm
int i = 0;            // loop dummy variable
double factor = 0;    // scaling factor for calibration
double shift = 0;     // shift for calibration
long maxfreq = 1048;  // maximum desired frequency after calibration
long minfreq = 131;   // minimum desired frequency after calibration


//magic numbers that make the intervals sound pleasing
double gap = 1.148698355;  //ratio of consecutive notes (pentatonic)
                             // it's the 5th root of 2
//double gap = 1.059463094;  //ratio of consecutive notes (chromatic)
                              // its the 12th root of 2

                              
void setup()
{
  pinMode(PHONES, OUTPUT);    // sets the digital pin as output

// calibration loop to determine a rasonable range of light levels (minread to maxread)
// and map that to frequencies between minfreq and maxfreq
  for (i = 0; i< 500; i++) {  // calibration loop runs for 5 seconds
    val = analogRead(PHOTOCELL);   // read photocell 
    tone(PHONES, val);          // play raw tone to guide calibration
    if (val > maxread) {        // as the values climb, store the largest
      maxread = val;
    }
    if (val < minread) {        // as the values drop, store the smallest
      minread = val;
    }  
    delay(10);                  // reasonable delay
  } 
  
  //Now we use the calibration to calculate scale and shift parameters
  factor = (double)(maxfreq - minfreq) / (double)(maxread - minread); // scale parameter
  //it's like a slope
  
  shift = factor * minread - minfreq;  //shift parameter: it's like an offset
}

void loop()
{
  val = analogRead(PHOTOCELL);   // read photocell 
  f = factor * val - shift;     // this linearly maps the frequency to
                                // a value between minfreq and maxfreq
                                // according to the calibration result
  
  normf = f / (double) minfreq;  // Dividing an exponential function by the min value
  logf = log(normf) / log(gap); // allows us to take the log (base gap) and the result 
  ilogf = round(logf);           // is the number of notes above the lowest, once we round it.
  f = minfreq * pow(gap,ilogf);  // we better "unlog" it.
  
  
  tone(PHONES, f);              // this produces the tone signal
  
}

Volevo poi aggiungere delle nuove fotocellule ma ho dei grossi problemi con il codice ho provato a farlo così ma da un sacco di errori. Scusate ma sono alle prime armi.

// Optical Theramin

//pin definitions
#define PHONES 9   // headphones connected to digital pin 9
#define PHOTOCELL 0 //photocell analog in pin 0
#define PHOTOCEL 1
//variable definitions
long val = 0; //stores raw value from photocell
long val1 = 0; 
long maxread = 0;    //maximum value from calibration phase
long maxread1 = 0; 
long minread = 1000;  // minimum value from calibration phase
long minread1 = 1000;
double f = 0;         // frequency of sound
double f1 = 0; 
double normf = 0;    // normalized frequency 
double normf1 = 0;
double logf = 0;      // logarithm of normalized frequency
double logf1 = 0; 
int ilogf = 0;        // rounded logarithm
int ilogf1 = 0;
int i = 0;            // loop dummy variable
int i1 = 0
double factor = 0;    // scaling factor for calibration
double factor1 = 0;
double shift = 0;     // shift for calibration
double shift1 = 0;
long maxfreq = 1048;  // maximum desired frequency after calibration
long maxfreq1 = 1048
long minfreq = 131;   // minimum desired frequency after calibration
long minfreq1 = 131; 


//magic numbers that make the intervals sound pleasing
double gap = 1.148698355;  //ratio of consecutive notes (pentatonic)
                             // it's the 5th root of 2
//double gap = 1.059463094;  //ratio of consecutive notes (chromatic)
                              // its the 12th root of 2
double gap1 = 1.148698355;
                              
void setup()
{
  pinMode(PHONES, OUTPUT);    // sets the digital pin as output

// calibration loop to determine a rasonable range of light levels (minread to maxread)
// and map that to frequencies between minfreq and maxfreq
  for (i = 0; i< 500; i++) {  // calibration loop runs for 5 seconds
    val = analogRead(PHOTOCELL);   // read photocell 
    
    tone(PHONES, val);          // play raw tone to guide calibration
    if (val > maxread) {        // as the values climb, store the largest
      maxread = val;
    }
    if (val < minread) {        // as the values drop, store the smallest
      minread = val;
    }  
    delay(10);                  // reasonable delay
    
     val1 = analogRead(PHOTOCEL);
     
        
    tone(PHONES, val1);          // play raw tone to guide calibration
    if (val1 > maxread1) {        // as the values climb, store the largest
      maxread1 = val1;
    }
    if (val1 < minread1) {        // as the values drop, store the smallest
      minread1 = val1;
    }  
    delay(10);                  // reasonable delay
    
  } 
  
  //Now we use the calibration to calculate scale and shift parameters
  factor = (double)(maxfreq - minfreq) / (double)(maxread - minread); // scale parameter
  //it's like a slope
  
   factor1 = (double)(maxfreq1 - minfreq1) / (double)(maxread1 - minread1); // scale parameter
  
  shift = factor * minread - minfreq;  //shift parameter: it's like an offset
   shift1 = factor1 * minread1 - minfreq1;  //shift parameter: it's like an offset
}

void loop()
{
  val = analogRead(PHOTOCELL);   // read photocell 
  f = factor * val - shift;     // this linearly maps the frequency to
                                // a value between minfreq and maxfreq
                                // according to the calibration result
  
  normf = f / (double) minfreq;  // Dividing an exponential function by the min value
  logf = log(normf) / log(gap); // allows us to take the log (base gap) and the result 
  ilogf = round(logf);           // is the number of notes above the lowest, once we round it.
  f = minfreq * pow(gap,ilogf);  // we better "unlog" it.
  
  
  val = analogRead(PHOTOCELL);   // read photocell 
  f = factor * val - shift;     // this linearly maps the frequency to
                                // a value between minfreq and maxfreq
                                // according to the calibration result
  
  normf1 = f1 / (double) minfreq1;  // Dividing an exponential function by the min value
  logf1 = log(normf1) / log(gap1); // allows us to take the log (base gap) and the result 
  ilogf1 = round(logf1);           // is the number of notes above the lowest, once we round it.
  f1 = minfreq1 * pow(gap1,ilogf1);
  
  tone(PHONES, f,f1);              // this produces the tone signal
  
}

FKZ8TXGH7430QRB.MEDIUM.jpg

Mancano semplicemente tutti i ; terminatori di riga.
--> codebender

Ho rinominato le fotocellule in A e B.

Grazie mille, il problema è che funziona un solo sensore, nel codice ho aggiunto un'altra uscita per avere l'effetto stereo

 //pin definitions
#define PHONES 9
#define PHONESB 8	// headphones connected to digital pin 9
#define PHOTOCELLA A0 		//photocell analog in pin 0
#define PHOTOCELLB A1

//variable definitions
long valA = 0;				 //stores raw value from photocell
long valB = 0;
long maxreadA = 0;		    //maximum value from calibration phase
long maxreadB = 0;
long minreadA = 1000;  // minimum value from calibration phase
long minreadB = 1000;

double fA = 0;         // frequency of sound
double fB = 0;
double normfA = 0;    // normalized frequency
double normfB = 0;
double logfA = 0;      // logarithm of normalized frequency
double logfB = 0;
int ilogfA = 0;        // rounded logarithm
int ilogfB = 0;

double factorA = 0;    // scaling factor for calibration
double factorB = 0;
double shiftA = 0;     // shift for calibration
double shiftB = 0;
long maxfreqA = 1048;  // maximum desired frequency after calibration
long maxfreqB = 1048;
long minfreqA = 131;   // minimum desired frequency after calibration
long minfreqB = 131;


//magic numbers that make the intervals sound pleasing
double gapA = 1.148698355;  //ratio of consecutive notes (pentatonic)
// it's the 5th root of 2
double gapB = 1.148698355;	//ratio of consecutive notes (chromatic)
// its the 12th root of 2


void setup()
{
	pinMode(PHONES, OUTPUT);    // sets the digital pin as output
        pinMode(PHONESB, OUTPUT);
// calibration loop to determine a rasonable range of light levels (minread to maxread)
// and map that to frequencies between minfreq and maxfreq
	for (int i = 0; i < 500; i++)   // calibration loop runs for 5 seconds
	{
		valA = analogRead(PHOTOCELLA);   // read photocell
		tone(PHONES, valA);          // play raw tone to guide calibration
		
		if (valA > maxreadA)          // as the values climb, store the largest
		{
			maxreadA = valA;
		}
		
		if (valA < minreadA)          // as the values drop, store the smallest
		{
			minreadA = valA;
		}
		delay(10);

		valB = analogRead(PHOTOCELLB);
		tone(PHONESB, valB);          // play raw tone to guide calibration
		
		if (valB > maxreadB)          // as the values climb, store the largest
		{
			maxreadB = valB;
		}
		
		if (valB < minreadB)          // as the values drop, store the smallest
		{
			minreadB = valB;
		}
		delay(10);                  // reasonable delay

	}
	noTone(PHONES);
        noTone(PHONESB);

	//Now we use the calibration to calculate scale and shift parameters
	factorA = (double)(maxfreqA - minfreqA) / (double)(maxreadA - minreadA); // scale parameter
	//it's like a slope

	factorB = (double)(maxfreqB - minfreqB) / (double)(maxreadB - minreadB); // scale parameter

	shiftA = factorA * minreadA - minfreqA;		//shift parameter: it's like an offset
	shiftB = factorB * minreadB - minfreqB;		//shift parameter: it's like an offset
}

void loop()
{
	valA = analogRead(PHOTOCELLA);				// read photocell
	valB = analogRead(PHOTOCELLB);      		// read photocell

	fA = factorA * valA - shiftA;   			// this linearly maps the frequency to
	// a value between minfreq and maxfreq
	// according to the calibration result
	normfA = fA / (double) minfreqA;			// Dividing an exponential function by the min value
	logfA = log(normfA) / log(gapA); 			// allows us to take the log (base gap) and the result
	ilogfA = round(logfA);           			// is the number of notes above the lowest, once we round it.
	fA = minfreqA * pow(gapA, ilogfA); 			// we better "unlog" it.

	fB = factorB * valB - shiftB;   			// this linearly maps the frequency to
	// a value between minfreq and maxfreq
	// according to the calibration result
	normfB = fB / (double) minfreqB;			// Dividing an exponential function by the min value
	logfB = log(normfB) / log(gapB);			// allows us to take the log (base gap) and the result
	ilogfB = round(logfB);						// is the number of notes above the lowest, once we round it.
	fB = minfreqB * pow(gapB, ilogfB);

	tone(PHONES, fA);
tone(PHONESB,fB); }

Il problema è che funziona sempre un solo sensore quello collegato al pin 0 Non riesco a capire come fare per far funzionare tutti e due, se poi non è stereo non è importante mi interessa che funzionino tutti e due.
Grazie mille sei stato gentilissimo!! =)

Se usi la funziona tone con

tone(PHONE, fA, fB);

fA è la frequenza del tono, mentre fB è la durata.
Il problema è che con quel tipo di sensori la risposta non è lineare. Inoltre dovresti aggiungere un LCD o il monitor seriale per verificare le operazioni di taratura.
Cosi alla cieca è difficile regolare lo strumento e attendersi dei buoni risultati, perché non sai che dati sta elaborando Arduino.

Grazie mille, io sono proprio all'inizio e mi incasino parecchio, non sapesti consigliarmi come fare? Magari con un altro tipo di codice. Grazie mille e scusa per le tante domande.

in questo molto più semplice il risultato è sempre lo stesso, suona sempre una cassa. Non so proprio come fare.

int speakerPinA = 8;
int speakerPinB = 9;
int photocellPinA = 0;
int photocellPinB = 1;
 
void setup()
{
}
 
void loop()
{
  int readingA = analogRead(photocellPinA);
  int pitchA = 100 + readingA / 8;
  tone(speakerPinA, pitchA);
  
  int readingB = analogRead(photocellPinB);
  int pitchB = 200 + readingB / 4;
  tone(speakerPinB, pitchB);
}

http://arduino.cc/en/reference/tone:
NOTE: if you want to play different pitches on multiple pins, you need to call noTone() on one pin before calling tone() on the next pin.

Sostanzialmente è difficile creare più toni perché devi fermare il precedente.

Quindi con quel codice creare più toni è impossibile?

Ciao a tutti, volevo chiedere se c'era qualcuno che sapeva spiegarmi come fare, sono settimane che provo ma non so come fare =( Spero che qualcuno mi aiuti

E' possibile, come indica questo video:

Purtroppo l'autore non indica come ha fatto, ma probabilmente usa la tecnica di accendere il 1° tone, spegnerlo, accendere il secondo tone spegnerlo, accendere il terzo tone e ripartire da capo.

La velocità del loop da l'illusione che i 3 toni siano contemporanei.

NOTE: if you want to play different pitches on multiple pins, you need to call noTone() on one pin before calling tone() on the next pin.

Quindi devo riuscire a bloccare una prima che inizia l'altra... il problema è come XD

#define speakerPinA  8
#define speakerPinB  9
#define photocellPinA  A0
#define photocellPinB  A1

unsigned int pitchA = 0; 
unsigned int pitchB = 0; 
unsigned long durata = 100;     // 100ms 
 
void setup() {
}

void loop() {
  pitchA = analogRead(photocellPinA) / 8 + 100;
  pitchB = analogRead(photocellPinB) / 4 + 200;
  tone(speakerPinA, pitchA, durata);
  noTone(speakerPinA);
  tone(speakerPinB, pitchB, durata);
  noTone(speakerPinB);
}

Grazie, mille per la risposta. Non ho ancora avuto modo di provare. Volevo chiedere se in questo modo potevo fare lo stesso procedimento con altre fotocellule, magari in modo da creare un theremin con 5 sensori.
Grazie mille

Teoricamente non esiste un limite ai toni generabili, ma tutto dipende dalla variabile durata che ho impostato a 100ms.

Più sono i toni e minore dovrà essere la durata per ottenere l'illusione della polifonia.

Ciao, purtroppo funziona sempre solo la prima fotocellula, sono disperato XD

Ciao a tutti, non avete dei consigli? Tutto quello fatto non funziona. Non riesco a creare un theremin con piú di una fotocellula. Non sapreste consigliarmi magari un progetto già fatto? Per me è importante riuscire a fare questa cosa. Grazie mille a tutti e buone feste

Per cominciare facci vedere lo schema utilizzato: l'errore potrebbe essere hardware.

Pubblica il codice che stai usando ora e lo schema dei collegamenti e, se puoi, anche una foto degli stessi

//pin definitions
#define PHONES 9
#define PHONESB 8	// headphones connected to digital pin 9
#define PHOTOCELLA A0 		//photocell analog in pin 0
#define PHOTOCELLB A1

//variable definitions
long valA = 0;				 //stores raw value from photocell
long valB = 0;
long maxreadA = 0;		    //maximum value from calibration phase
long maxreadB = 0;
long minreadA = 1000;  // minimum value from calibration phase
long minreadB = 1000;

double fA = 0;         // frequency of sound
double fB = 0;
double normfA = 0;    // normalized frequency
double normfB = 0;
double logfA = 0;      // logarithm of normalized frequency
double logfB = 0;
int ilogfA = 0;        // rounded logarithm
int ilogfB = 0;

double factorA = 0;    // scaling factor for calibration
double factorB = 0;
double shiftA = 0;     // shift for calibration
double shiftB = 0;
long maxfreqA = 1048;  // maximum desired frequency after calibration
long maxfreqB = 1048;
long minfreqA = 131;   // minimum desired frequency after calibration
long minfreqB = 131;


//magic numbers that make the intervals sound pleasing
double gapA = 1.148698355;  //ratio of consecutive notes (pentatonic)
// it's the 5th root of 2
double gapB = 1.148698355;	//ratio of consecutive notes (chromatic)
// its the 12th root of 2


void setup()
{
	pinMode(PHONES, OUTPUT);    // sets the digital pin as output
        pinMode(PHONESB, OUTPUT);
// calibration loop to determine a rasonable range of light levels (minread to maxread)
// and map that to frequencies between minfreq and maxfreq
	for (int i = 0; i < 500; i++)   // calibration loop runs for 5 seconds
	{
		valA = analogRead(PHOTOCELLA);   // read photocell
		tone(PHONES, valA);          // play raw tone to guide calibration
		
		if (valA > maxreadA)          // as the values climb, store the largest
		{
			maxreadA = valA;
		}
		
		if (valA < minreadA)          // as the values drop, store the smallest
		{
			minreadA = valA;
		}
		delay(10);

		valB = analogRead(PHOTOCELLB);
		tone(PHONESB, valB);          // play raw tone to guide calibration
		
		if (valB > maxreadB)          // as the values climb, store the largest
		{
			maxreadB = valB;
		}
		
		if (valB < minreadB)          // as the values drop, store the smallest
		{
			minreadB = valB;
		}
		delay(10);                  // reasonable delay

	}
	noTone(PHONES);
        noTone(PHONESB);

	//Now we use the calibration to calculate scale and shift parameters
	factorA = (double)(maxfreqA - minfreqA) / (double)(maxreadA - minreadA); // scale parameter
	//it's like a slope

	factorB = (double)(maxfreqB - minfreqB) / (double)(maxreadB - minreadB); // scale parameter

	shiftA = factorA * minreadA - minfreqA;		//shift parameter: it's like an offset
	shiftB = factorB * minreadB - minfreqB;		//shift parameter: it's like an offset
}

void loop()
{
	valA = analogRead(PHOTOCELLA);				// read photocell
	valB = analogRead(PHOTOCELLB);      		// read photocell

	fA = factorA * valA - shiftA;   			// this linearly maps the frequency to
	// a value between minfreq and maxfreq
	// according to the calibration result
	normfA = fA / (double) minfreqA;			// Dividing an exponential function by the min value
	logfA = log(normfA) / log(gapA); 			// allows us to take the log (base gap) and the result
	ilogfA = round(logfA);           			// is the number of notes above the lowest, once we round it.
	fA = minfreqA * pow(gapA, ilogfA); 			// we better "unlog" it.

	fB = factorB * valB - shiftB;   			// this linearly maps the frequency to
	// a value between minfreq and maxfreq
	// according to the calibration result
	normfB = fB / (double) minfreqB;			// Dividing an exponential function by the min value
	logfB = log(normfB) / log(gapB);			// allows us to take the log (base gap) and the result
	ilogfB = round(logfB);						// is the number of notes above the lowest, once we round it.
	fB = minfreqB * pow(gapB, ilogfB);

	tone(PHONES, fA);
tone(PHONESB,fB); }

e questo, ma nessuno dei due va

#define speakerPinA  8
#define speakerPinB  9
#define photocellPinA  A0
#define photocellPinB  A1

unsigned int pitchA = 0; 
unsigned int pitchB = 0; 
unsigned long durata = 100;     // 100ms 
 
void setup() {
}

void loop() {
  pitchA = analogRead(photocellPinA) / 8 + 100;
  pitchB = analogRead(photocellPinB) / 4 + 200;
  tone(speakerPinA, pitchA, durata);
  noTone(speakerPinA);
  tone(speakerPinB, pitchB, durata);
  noTone(speakerPinB);
}