Ci-dessous, les différences entre deux révisions de la page.
Les deux révisions précédentes Révision précédente Prochaine révision | Révision précédente | ||
projets:light-synth:accueil [2017/07/09 13:08] resonance [Notes techniques] |
projets:light-synth:accueil [2018/06/09 11:33] (Version actuelle) resonance [Boite a rythme a led] |
||
---|---|---|---|
Ligne 4: | Ligne 4: | ||
* Licence : [[http:// | * Licence : [[http:// | ||
* Description : synthé qui marche avec la lumiere | * Description : synthé qui marche avec la lumiere | ||
- | * Fichiers sources : //mettre un lien// | + | * Fichiers sources : voir plus bas pour les codes , design : {{ : |
* Lien : //mettre un lien// | * Lien : //mettre un lien// | ||
Ligne 11: | Ligne 11: | ||
===== Note d' | ===== Note d' | ||
Synthé qui marche avec la lumiere : | Synthé qui marche avec la lumiere : | ||
- | Plusieurs pistes sont possible, notamment en changeant les frequences | + | Plusieurs pistes sont possible, notamment en changeant les fréquences |
{{projets: | {{projets: | ||
- | ===== Notes techniques | + | ===== Codes ===== |
- | Guide pas à pas et conseil | + | Voici quelques codes pas mal... Certains utilisent les libraries Tone et Mozzi pour transformer l' |
+ | |||
+ | On capte le son emis en lumiere par des leds, via un panneau solaire. | ||
+ | Ca donne ceci : | ||
+ | |||
+ | {{youtube> | ||
+ | //Le troisieme synth de la video est l' | ||
+ | |||
+ | |||
+ | |||
+ | ==== 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 | ||
- | code simple pour library tone : | ||
<code c+> | <code c+> | ||
+ | // 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]; | ||
+ | |||
+ | void setup() { | ||
+ | pinMode(led1, | ||
+ | pinMode(led2, | ||
+ | pinMode(led3, | ||
+ | |||
+ | Serial.begin(9600); | ||
+ | } | ||
+ | void loop() { | ||
+ | |||
+ | int sensorValue = analogRead(A0); | ||
+ | sensorValue = map(sensorValue, | ||
+ | |||
+ | if(sensorValue > 1990) { | ||
+ | sensorValue == 10000; | ||
+ | } | ||
+ | int sensorValueB = analogRead(A1); | ||
+ | sensorValueB = map(sensorValueB, | ||
+ | |||
+ | if(sensorValueB > 800) { | ||
+ | | ||
+ | | ||
+ | | ||
+ | } | ||
+ | |||
+ | if(sensorValueB > 400 && sensorValueB < 800 ) { | ||
+ | | ||
+ | | ||
+ | | ||
+ | } | ||
+ | |||
+ | if(sensorValueB < 400) { | ||
+ | | ||
+ | | ||
+ | | ||
+ | } | ||
+ | |||
+ | Serial.print(" | ||
+ | Serial.println(sensorValue); | ||
+ | |||
+ | Serial.print(" | ||
+ | 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 | ||
+ | | ||
+ | }} | ||
+ | |||
+ | ///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, | ||
+ | delay (pwm/ | ||
+ | digitalWrite(led, | ||
+ | delay (pwm/ | ||
+ | digitalWrite(led, | ||
+ | } | ||
+ | } | ||
+ | |||
+ | ///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, | ||
+ | delay (pwm/ | ||
+ | digitalWrite(led, | ||
+ | delay (pwm/ | ||
+ | digitalWrite(led, | ||
+ | delay (pwm/ | ||
+ | digitalWrite(led, | ||
+ | delay (pwm/ | ||
+ | digitalWrite(led, | ||
+ | delay (pwm/ | ||
+ | digitalWrite(led, | ||
+ | delay (pwm/ | ||
+ | digitalWrite(led, | ||
+ | delay (pwm/ | ||
+ | digitalWrite(led, | ||
+ | delay (pwm/ | ||
+ | digitalWrite(led, | ||
+ | } | ||
+ | } | ||
+ | |||
+ | </ | ||
+ | ++++ | ||
+ | |||
+ | ==== 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 | ||
+ | |||
+ | |||
+ | |||
+ | <code c+> | ||
+ | /* | ||
+ | Use 5 Analogic inputs to control fm synth (A0 - ... - A4 ) | ||
+ | Output Pin 9 - led ... | ||
+ | */ | ||
+ | |||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | |||
+ | // 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' | ||
+ | const int MIN_INTENSITY = 700; | ||
+ | const int MAX_INTENSITY = 10; | ||
+ | |||
+ | // desired mod speed max and min, for AutoMap, note they' | ||
+ | const int MIN_MOD_SPEED = 10000; | ||
+ | const int MAX_MOD_SPEED = 1; | ||
+ | |||
+ | AutoMap kMapCarrierFreq(0, | ||
+ | AutoMap kMapIntensity(0, | ||
+ | AutoMap kMapModSpeed(0, | ||
+ | AutoMap mapThis(0, | ||
+ | AutoMap mapThisToo(0, | ||
+ | |||
+ | 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< | ||
+ | Oscil< | ||
+ | Oscil< | ||
+ | |||
+ | int mod_ratio = 5; // brightness (harmonics) | ||
+ | long fm_intensity; | ||
+ | |||
+ | // smoothing for intensity to remove clicks on transitions | ||
+ | float smoothness = 0.95f; | ||
+ | Smooth < | ||
+ | |||
+ | |||
+ | void setup(){ | ||
+ | Serial.begin(115200); | ||
+ | startMozzi(); | ||
+ | } | ||
+ | |||
+ | void updateControl(){ | ||
+ | | ||
+ | // freqVal = map(LDR3_PIN, | ||
+ | int freqVal = mozziAnalogRead(LDR3_PIN); | ||
+ | int FRQ = mapThis(freqVal); | ||
+ | int knob2 = mozziAnalogRead(LDR4_PIN); | ||
+ | int knob2Val = mapThis(knob2); | ||
+ | | ||
+ | // read the knob | ||
+ | int knob_value = mozziAnalogRead(KNOB_PIN); | ||
+ | |||
+ | // 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); | ||
+ | // 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))>> | ||
+ | |||
+ | | ||
+ | // read the light dependent resistor on the speed Analog input pin | ||
+ | int LDR2_value= mozziAnalogRead(LDR2_PIN); | ||
+ | |||
+ | | ||
+ | | ||
+ | Serial.print(knob_value); | ||
+ | Serial.print(" | ||
+ | | ||
+ | | ||
+ | Serial.print(LDR1_value); | ||
+ | Serial.print(" | ||
+ | | ||
+ | | ||
+ | Serial.print(LDR2_value); | ||
+ | Serial.print(" | ||
+ | |||
+ | |||
+ | Serial.print(" | ||
+ | Serial.print(freqVal); | ||
+ | Serial.print(" | ||
+ | |||
+ | Serial.print(" | ||
+ | Serial.print(knob2); | ||
+ | Serial.print(" | ||
+ | | ||
+ | |||
+ | // use a float here for low frequencies | ||
+ | float mod_speed = (float)kMapModSpeed(LDR2_value)/ | ||
+ | |||
+ | kIntensityMod.setFreq(mod_speed); | ||
+ | | ||
+ | Serial.println(); | ||
+ | } | ||
+ | |||
+ | 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:// | ||
+ | |||
+ | ++++ Le code | ||
+ | <code c+> | ||
+ | String inputString = ""; | ||
+ | boolean stringComplete = false; | ||
+ | String fct =""; | ||
+ | String arg=""; | ||
+ | int index; | ||
+ | |||
#include < | #include < | ||
Tone freq1; | Tone freq1; | ||
Tone freq2; | Tone freq2; | ||
- | void setup() | + | void setup() { |
- | { | + | Serial.begin(9600); |
freq1.begin(9); | freq1.begin(9); | ||
freq2.begin(10); | freq2.begin(10); | ||
} | } | ||
- | void loop() | + | void loop() { |
+ | if (stringComplete) { | ||
+ | // | ||
+ | index = inputString.indexOf(' | ||
+ | fct = inputString.substring(0, | ||
+ | arg = inputString.substring(index, | ||
+ | |||
+ | if (fct == " | ||
+ | freq2.play(arg.toInt(), | ||
+ | } | ||
+ | else if (fct == " | ||
+ | freq1.play(arg.toInt(), | ||
+ | } | ||
+ | |||
+ | inputString = ""; | ||
+ | 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(); | ||
+ | inputString += inChar; // concaténation des octets | ||
+ | if (inChar == ' | ||
+ | stringComplete = true; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | |||
+ | </ | ||
+ | ++++ | ||
+ | |||
+ | ==== Code sympa fluctuant Mozzi ==== | ||
+ | 2 pot volume et pitch | ||
+ | |||
+ | ++++ Le code | | ||
+ | <code c+> | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | |||
+ | 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 < | ||
+ | Oscil < | ||
+ | |||
+ | byte volume; | ||
+ | |||
+ | void setup(){ | ||
+ | startMozzi(); | ||
+ | } | ||
+ | |||
+ | |||
+ | void updateControl(){ | ||
+ | // read the potentiometer | ||
+ | int knob_value = mozziAnalogRead(KNOB_PIN); | ||
+ | |||
+ | // map it to an 8 bit volume range for efficient calculations in updateAudio | ||
+ | volume = knob_value >> 2; // 10 bits (0-> | ||
+ | |||
+ | // read the light dependent resistor | ||
+ | int light_level = mozziAnalogRead(LDR_PIN); | ||
+ | |||
+ | light_level = map(light_level, | ||
+ | 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(); | ||
+ | delay(100); | ||
+ | } | ||
+ | </ | ||
+ | ++++ | ||
+ | |||
+ | ==== Theremin fluctuant Mozzi ==== | ||
+ | 2 pot (selecteur si pot ou ldr pour controler le pitch, pitch ) un ldr (pitch).... | ||
+ | |||
+ | ++++ Le code | | ||
+ | <code c+> | ||
+ | /* | ||
+ | */ | ||
+ | |||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #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 < | ||
+ | Oscil < | ||
+ | Oscil < | ||
+ | Oscil < | ||
+ | |||
+ | // use: RollingAverage < | ||
+ | RollingAverage <int, 32> 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) | ||
{ | { | ||
- | freq1.play(10, | + | bumpy_input = ldr; |
- | freq2.play(100, | + | |
} | } | ||
+ | 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()>> | ||
+ | +(aSin3.next()>> | ||
+ | } | ||
+ | |||
+ | |||
+ | void loop(){ | ||
+ | audioHook(); | ||
+ | } | ||
+ | |||
</ | </ | ||
+ | ++++ | ||
+ | |||
===== Matériaux et outils ===== | ===== Matériaux et outils ===== | ||
Liste de matériel et outils nécessaires. | Liste de matériel et outils nécessaires. |