====== light-synth ======
* Porteur du projet : fenshu [[:user:resonance|resonance]]
* Date : 09/07/2017/ - ...
* Licence : [[http://creativecommons.org/licenses/by-sa/3.0/legalcode|CC-by-sa-3.0]]
* Description : synthé qui marche avec la lumiere
* Fichiers sources : voir plus bas pour les codes , design : {{ :projets:light-synth:lightsynthdesign.ai |}}
* Lien : //mettre un lien//
{{tag>esadmm lumiere, son, arduino, puredata}}
===== Note d'intention =====
Synthé qui marche avec la lumiere :
Plusieurs pistes sont possible, notamment en changeant les fréquences des pwm avec library Tone et Mozzi
{{projets:light-synth:accueil:instrument_lumiere_minuscule.jpg?800|light-synth}}
===== Codes =====
Voici quelques codes pas mal... Certains utilisent les libraries Tone et Mozzi pour transformer l'arduino en petit synthé !
On capte le son emis en lumiere par des leds, via un panneau solaire.
Ca donne ceci :
{{youtube>nbi2d_UTToQ?large}}
//Le troisieme synth de la video est l'exemple de la librarie mozzi : Sensor/lighttemperature...//
==== Boite a rythme a led ====
On fait clignoter 3 led a la noire, croche triolet, et on controle le temp avec un potentiometre et une photoresistance...
++++ Le code |
// 3 led a jouant a la noire, croche et triolet
// un potentiometre 10k en A0 : controle le tempo général...
// une photo resistance en A1 : controle un effet de delay
#define led1 5
#define led2 9
#define led3 10
#define factor 6 //factor for pwm tone !
unsigned long previousMillis[3]; //[x] = number of leds
void setup() {
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
Serial.begin(9600);
}
void loop() {
int sensorValue = analogRead(A0);
sensorValue = map(sensorValue, 0, 1023, 0, 2000);
if(sensorValue > 1990) {
sensorValue == 10000;
}
int sensorValueB = analogRead(A1);
sensorValueB = map(sensorValueB, 0, 1023, 1023, 0);
if(sensorValueB > 800) {
BlinkLedSimple(led1, sensorValue, 0,sensorValueB); //BlinkLed( which led, interval, one of the stored prevMillis
BlinkLedSimple(led2, sensorValue/3, 1,sensorValueB); //last parameters must be different for each led
BlinkLedSimple(led3, sensorValue/2, 2,sensorValueB);
}
if(sensorValueB > 400 && sensorValueB < 800 ) {
BlinkLed(led1, sensorValue, 0,sensorValueB); //BlinkLed( which led, interval, one of the stored prevMillis
BlinkLed(led2, sensorValue/3, 1,sensorValueB); //last parameters must be different for each led
BlinkLed(led3, sensorValue/2, 2,sensorValueB);
}
if(sensorValueB < 400) {
BlinkLedSuper(led1, sensorValue, 0,sensorValueB); //BlinkLed( which led, interval, one of the stored prevMillis
BlinkLedSuper(led2, sensorValue/3, 1,sensorValueB); //last parameters must be different for each led
BlinkLedSuper(led3, sensorValue/2, 2,sensorValueB);
}
Serial.print("potentiometre");
Serial.println(sensorValue);
Serial.print("ldr");
Serial.println(sensorValueB);
delay(1);
}
///Simple blink
void BlinkLedSimple (int led, int interval, int array, int pwm){
if (((long)millis() - previousMillis[array]) >= interval){
previousMillis[array]= millis(); //stores the millis value in the selected array
digitalWrite(led, !digitalRead(led)); //changes led state
}}
///delayyyy blink
void BlinkLed (int led, int interval, int array, int pwm){
if (((long)millis() - previousMillis[array]) >= interval){
previousMillis[array]= millis(); //stores the millis value in the selected array
digitalWrite(led, !digitalRead(led)); //changes led state
delay (pwm/factor);
digitalWrite(led, !digitalRead(led)); //changes led state
delay (pwm/factor);
digitalWrite(led, !digitalRead(led)); //changes led state
}
}
///super delayyyy blink
void BlinkLedSuper (int led, int interval, int array, int pwm){
if (((long)millis() - previousMillis[array]) >= interval){
previousMillis[array]= millis(); //stores the millis value in the selected array
digitalWrite(led, !digitalRead(led)); //changes led state
delay (pwm/factor);
digitalWrite(led, !digitalRead(led)); //changes led state
delay (pwm/factor);
digitalWrite(led, !digitalRead(led)); //changes led state
delay (pwm/factor);
digitalWrite(led, !digitalRead(led)); //changes led state
delay (pwm/factor);
digitalWrite(led, !digitalRead(led)); //changes led state
delay (pwm/factor);
digitalWrite(led, !digitalRead(led)); //changes led state
delay (pwm/factor);
digitalWrite(led, !digitalRead(led)); //changes led state
delay (pwm/factor);
digitalWrite(led, !digitalRead(led)); //changes led state
delay (pwm/factor);
digitalWrite(led, !digitalRead(led)); //changes led state
}
}
++++
==== Synth fm avec 5 potentiomètres avec MOZZI ====
On controle un synthe fm avec 5 potards,
le son passe par la led en pin 9...
++++ Le code |
/*
Use 5 Analogic inputs to control fm synth (A0 - ... - A4 )
Output Pin 9 - led ...
*/
#include
#include // oscillator
#include // table for Oscils to play
#include
#include // maps unpredictable inputs to a range
// int freqVal;
// desired carrier frequency max and min, for AutoMap
const int MIN_CARRIER_FREQ = 22;
const int MAX_CARRIER_FREQ = 440;
const int MIN = 1;
const int MAX = 10;
const int MIN_2 = 1;
const int MAX_2 = 15;
// desired intensity max and min, for AutoMap, note they're inverted for reverse dynamics
const int MIN_INTENSITY = 700;
const int MAX_INTENSITY = 10;
// desired mod speed max and min, for AutoMap, note they're inverted for reverse dynamics
const int MIN_MOD_SPEED = 10000;
const int MAX_MOD_SPEED = 1;
AutoMap kMapCarrierFreq(0,1023,MIN_CARRIER_FREQ,MAX_CARRIER_FREQ);
AutoMap kMapIntensity(0,1023,MIN_INTENSITY,MAX_INTENSITY);
AutoMap kMapModSpeed(0,1023,MIN_MOD_SPEED,MAX_MOD_SPEED);
AutoMap mapThis(0,1023,MIN,MAX);
AutoMap mapThisToo(0,1023,MIN_2,MAX_2);
const int KNOB_PIN = 0; // set the input for the knob to analog pin 0
const int LDR1_PIN=1; // set the analog input for fm_intensity to pin 1
const int LDR2_PIN=2; // set the analog input for mod rate to pin 2
const int LDR3_PIN=3;
const int LDR4_PIN=4;
Oscil aCarrier(COS2048_DATA);
Oscil aModulator(COS2048_DATA);
Oscil kIntensityMod(COS2048_DATA);
int mod_ratio = 5; // brightness (harmonics)
long fm_intensity; // carries control info from updateControl to updateAudio
// smoothing for intensity to remove clicks on transitions
float smoothness = 0.95f;
Smooth aSmoothIntensity(smoothness);
void setup(){
Serial.begin(115200); // set up the Serial output so we can look at the light level
startMozzi(); // :))
}
void updateControl(){
// freqVal = map(LDR3_PIN, 0, 1023, 1, 100);
int freqVal = mozziAnalogRead(LDR3_PIN); // value is 0-1023
int FRQ = mapThis(freqVal);
int knob2 = mozziAnalogRead(LDR4_PIN); // value is 0-1023
int knob2Val = mapThis(knob2);
// read the knob
int knob_value = mozziAnalogRead(KNOB_PIN); // value is 0-1023
// map the knob to carrier frequency
int carrier_freq = kMapCarrierFreq(knob_value);
//calculate the modulation frequency to stay in ratio
int mod_freq = carrier_freq * mod_ratio * FRQ;
// set the FM oscillator frequencies
aCarrier.setFreq(carrier_freq);
aModulator.setFreq(mod_freq);
// read the light dependent resistor on the width Analog input pin
int LDR1_value= mozziAnalogRead(LDR1_PIN); // value is 0-1023
// print the value to the Serial monitor for debugging
int LDR1_calibrated = kMapIntensity(LDR1_value);
// calculate the fm_intensity
fm_intensity = ((long)LDR1_calibrated * knob2Val * (kIntensityMod.next()+128))>>8; // shift back to range after 8 bit multiply
// read the light dependent resistor on the speed Analog input pin
int LDR2_value= mozziAnalogRead(LDR2_PIN); // value is 0-1023
Serial.print("LDR0 = ");
Serial.print(knob_value);
Serial.print("\t"); // prints a tab
Serial.print("LDR1 = ");
Serial.print(LDR1_value);
Serial.print("\t"); // prints a tab
Serial.print("LDR2 = ");
Serial.print(LDR2_value);
Serial.print("\t"); // prints a tab
Serial.print("LDR3 = ");
Serial.print(freqVal);
Serial.print("\t"); // prints a tab
Serial.print("LDR4 = ");
Serial.print(knob2);
Serial.print("\t"); // prints a tab
// use a float here for low frequencies
float mod_speed = (float)kMapModSpeed(LDR2_value)/1000;
kIntensityMod.setFreq(mod_speed);
Serial.println(); // finally, print a carraige return for the next line of debugging info
}
int updateAudio(){
long modulation = aSmoothIntensity.next(fm_intensity) * aModulator.next();
return aCarrier.phMod(modulation);
}
void loop(){
audioHook();
}
++++
==== Code pour communiquer avec PureData COMPORT (2 led branché en 9 et 10): ====
On controle ainsi deux pins avec tone depuis Pure Data...
**Patch PureData :** voir fichier 4 dans la page ressource [[http://reso-nance.org/wiki/logiciels/serial/accueil?s[]=puredata&s[]=serial]]
++++ Le code |
String inputString = ""; // chaine de caractères pour contenir les données
boolean stringComplete = false; // pour savoir si la chaine est complète
String fct ="";
String arg="";
int index;
#include
Tone freq1;
Tone freq2;
void setup() {
Serial.begin(9600); // port série
freq1.begin(9);
freq2.begin(10);
}
void loop() {
if (stringComplete) {
//Serial.println(inputString);
index = inputString.indexOf(' '); // on récupère la position du séparateur (l'espace " ")
fct = inputString.substring(0,index); // on coupe la chaine en deux : la fonction et l'argument
arg = inputString.substring(index,inputString.length());
if (fct == "LED10") {
freq2.play(arg.toInt(),300);
}
else if (fct == "LED9") {
freq1.play(arg.toInt(),300);
}
inputString = ""; // vide la chaine
stringComplete = false;
}
}
/*
SerialEvent est déclenché quand de nouvelles données sont reçues.
Cett routine tourne entre chaque loop(), donc utiliser un delay la fait aussi attendre
*/
void serialEvent() {
while (Serial.available()) {
char inChar = (char)Serial.read(); // Récupérer le prochain octet (byte ou char)
inputString += inChar; // concaténation des octets
if (inChar == '\n') { // caractère de fin pour notre chaine
stringComplete = true;
}
}
}
++++
==== Code sympa fluctuant Mozzi ====
2 pot volume et pitch
++++ Le code |
#include
#include // oscillator template
#include // sine table for oscillator
const char KNOB_PIN = 0; // set the input for the knob to analog pin 0
const char LDR_PIN = 1; // set the input for the LDR to analog pin 1
// use: Oscil oscilName (wavetable), look in .h file of table #included above
Oscil aSin(SIN2048_DATA);
byte volume;
void setup(){
startMozzi(); // :))
}
void updateControl(){
// read the potentiometer
int knob_value = mozziAnalogRead(KNOB_PIN); // value is 0-1023
// map it to an 8 bit volume range for efficient calculations in updateAudio
volume = knob_value >> 2; // 10 bits (0->1023) shifted right by 2 bits to give 8 bits (0->255)
// read the light dependent resistor
int light_level = mozziAnalogRead(LDR_PIN); // value is 0-1023
light_level = map(light_level,0,1023,0,12);
light_level = light_level*100 + 200;
// set the frequency
aSin.setFreq( light_level);
}
int updateAudio(){
// cast char output from aSin.next() to int to make room for multiplication
return ((int)aSin.next() * volume) >> 8; // shift back into range after multiplying by 8 bit value
}
void loop(){
audioHook(); // required here
delay(100);
}
++++
==== Theremin fluctuant Mozzi ====
2 pot (selecteur si pot ou ldr pour controler le pitch, pitch ) un ldr (pitch)....
++++ Le code |
/*
*/
#include
#include // oscillator template
#include // sine table for oscillator
#include
#include
#define INPUT_PIN 0 // analog control input
#define INPUT_PINA 2 // analog control input
#define MIX_PIN 3 // analog control input
unsigned int echo_cells_1 = 32;
unsigned int echo_cells_2 = 60;
unsigned int echo_cells_3 = 127;
int bumpy_input = 12;
#define CONTROL_RATE 64
ControlDelay <128, int> kDelay; // 2seconds
// oscils to compare bumpy to averaged control input
Oscil aSin0(SIN2048_DATA);
Oscil aSin1(SIN2048_DATA);
Oscil aSin2(SIN2048_DATA);
Oscil aSin3(SIN2048_DATA);
// use: RollingAverage myThing
RollingAverage kAverage; // how_many_to_average has to be power of 2
int averaged;
void setup(){
kDelay.set(echo_cells_1);
startMozzi();
}
void updateControl(){
int mix = mozziAnalogRead(MIX_PIN);
int pot = mozziAnalogRead(INPUT_PINA) ;
int ldr = mozziAnalogRead(INPUT_PIN) ;
if (mix > 500)
{
bumpy_input = ldr;
}
else
{
bumpy_input = pot;
}
averaged = kAverage.next(bumpy_input);
aSin0.setFreq(averaged);
aSin1.setFreq(kDelay.next(averaged));
aSin2.setFreq(kDelay.read(echo_cells_2));
aSin3.setFreq(kDelay.read(echo_cells_3));
}
int updateAudio(){
return 3*((int)aSin0.next()+aSin1.next()+(aSin2.next()>>1)
+(aSin3.next()>>2)) >>3;
}
void loop(){
audioHook();
}
++++
===== Matériaux et outils =====
Liste de matériel et outils nécessaires.
===== Photos =====
Code pour afficher les images du projet :
{{gallery>?&crop&lightbox}}