Volume control with analog sensor Arduino/ Processing


#1

Hi everyone,
I would like to control the volume of my audio file or my video with a classic analog sensor. So I founded these sketchs to link Arduino and Processing and I modified it to map my volume but I don’t understand why it doesn’t work. Anyone can help me ?

Sorry for my english, I’m French !`

Arduino:

void setup() {
  Serial.begin(9600);
}

void loop() {
  int sensorValue = analogRead(A0);
  Serial.println(sensorValue);
  if(sensorValue > 1000) {
    Serial.println("T"); 
    // send the letter T (for Trigger) once the sensor value is bigger than 1000  
  }
  delay(1);       
}

Processing:
import processing.serial.;
import ddf.minim.
;
import ddf.minim.effects.;
import ddf.minim.ugens.
;

Minim minim;
AudioOutput output;
FilePlayer groove;
LowPassFS lpf;

int lf = 10; // Linefeed in ASCII
String myString = null;
Serial myPort; // The serial port
int sensorValue = 0;

void setup() {
// Open the port you are using at the rate you want:
myPort = new Serial(this, Serial.list()[2], 9600);
myPort.clear();
// Throw out the first reading, in case we started reading
// in the middle of a string from the sender.
myString = myPort.readStringUntil(lf);
myString = null;
// we pass this to Minim so that it can load files from the data directory
minim = new Minim(this);
// loadFile will look in all the same places as loadImage does.
// this means you can find files that are in the data folder and the
// sketch folder. you can also pass an absolute path, or a URL.
// Change the name of the audio file here and add it by clicking on “Sketch —> Import File”
output = minim.getLineOut();
groove = new FilePlayer( minim.loadFileStream(“groove.mp3”) );
// make a low pass filter with a cutoff frequency of 100 Hz
// the second argument is the sample rate of the audio that will be filtered
// it is required to correctly compute values used by the filter
lpf = new LowPassFS(100, output.sampleRate());
groove.patch( lpf ).patch( output );
groove.loop();
}

void draw() {
// check if there is something new on the serial port
while (myPort.available() > 0) {
// store the data in myString
myString = myPort.readStringUntil(lf);
// check if we really have something
if (myString != null) {
myString = myString.trim(); // let’s remove whitespace characters
// if we have at least one character…
if(myString.length() > 0) {
println(myString); // print out the data we just received
// if we received a number (e.g. 123) store it in sensorValue, we sill use this to change the volume.
try {
sensorValue = Integer.parseInt(myString);
for ( int sensorValue = 0; sensorValue < output.bufferSize() - 1; i++ ){

       float x1 = map(sensorValue, 0, output.bufferSize(), 0, 10);
       float x2 = map(sensorValue+1, 0, output.bufferSize(), 0, 10);
   }
 } catch(Exception e){}
   if(myString.equals("T")){
      if(
      }
   }
}

}
}
}


#2

Peux-tu formater ton code avec le bouton </>

EDIT:
Regarde cette page qui donne une bonne idée de comment utiliser arduino avec Processing
http://playground.arduino.cc/Interfacing/Processing


#3

Merci de m’avoir répondu! Désolé, je connais encore mal le site.
Merci pour le conseil je vais suivre cela étape par étape. J’aimerai juste savoir comment est-ce que je map un fichier audio ou le son sur une vidéo. J’ai vu plusieurs manières:

float dB = map(mouseX, 0, width, -6, 6);
  gain.setValue(dB);

Ou

float amplitude = map(mouseY, 0, height, 0.4, 0.0);
  s.volume(amplitude);
}

Voici mon code mais je pense qu’il n’est pas bon du tout

import processing.serial.;
import ddf.minim.;
import ddf.minim.effects.;
import ddf.minim.ugens.;

Minim minim;
AudioOutput output;
FilePlayer groove;
LowPassFS lpf;

int lf = 10; // Linefeed in ASCII
String myString = null;
Serial myPort; // The serial port
int sensorValue = 0;

void setup() {
// Open the port you are using at the rate you want:
myPort = new Serial(this, Serial.list()[2], 9600);
myPort.clear();
// Throw out the first reading, in case we started reading
// in the middle of a string from the sender.
myString = myPort.readStringUntil(lf);
myString = null;
// we pass this to Minim so that it can load files from the data directory
minim = new Minim(this);
// loadFile will look in all the same places as loadImage does.
// this means you can find files that are in the data folder and the
// sketch folder. you can also pass an absolute path, or a URL.
// Change the name of the audio file here and add it by clicking on “Sketch —> Import File”
output = minim.getLineOut();
groove = new FilePlayer( minim.loadFileStream(“groove.mp3”) );
// make a low pass filter with a cutoff frequency of 100 Hz
// the second argument is the sample rate of the audio that will be filtered
// it is required to correctly compute values used by the filter
lpf = new LowPassFS(100, output.sampleRate());
groove.patch( lpf ).patch( output );
groove.loop();
}

void draw() {
// check if there is something new on the serial port
while (myPort.available() > 0) {
// store the data in myString
myString = myPort.readStringUntil(lf);
// check if we really have something
if (myString != null) {
myString = myString.trim(); // let’s remove whitespace characters
// if we have at least one character…
if(myString.length() > 0) {
println(myString); // print out the data we just received
// if we received a number (e.g. 123) store it in sensorValue, we sill use this to change the volume.
try {
sensorValue = Integer.parseInt(myString);
for ( int sensorValue = 0; sensorValue < output.bufferSize() - 1; i++ ){

       float x1 = map(sensorValue, 0, output.bufferSize(), 0, 10);
       float x2 = map(sensorValue+1, 0, output.bufferSize(), 0, 10);
   }
 } catch(Exception e){}
   if(myString.equals("T")){
      if(
      }
   }
}
}
}
}

#4

Est-ce que tu utilise un Arduino avec un Potentiomètre?
Selon ton code il me semble que non, je ne voie que l’utilisation du sérial port.
Voici en bref pour le volume si tu utilise un arduino et un potentiomètre branché a la pin A0.

volumePot=arduino.analogRead(A0);
volume=map(volumePot,0,1023,0.0,1.01);//range de volume entre min 0.0  et max 1.0

#5

Dans ton code je ne vois pas ou tu as de la vidéo.
Est-ce que tu veux synchroniser un son avec une vidéo?


#6

Je te conseille d’aller voir le repos de b2renger qui est très documenté et fourni en français, et bien expliqué, en matière d’Arduino et Processing pour les débutants. https://github.com/b2renger/Introduction_p5js

As-tu bien vérifié que tu te situes sur bon port quand tu le mentionnes dans Processing ? Et pour envoyer des datas d’Arduino vers Processing, je ne vois pas bien comment tu envoies tes données vers Processing, mais je ne connais que ce moyen là…) Je passe par un json dans Arduino :

  String json;

  json = json + "{\"tesdatas\": ";
  json = json + tesdatas;
  
  json = json + "}";
  Serial.println(json);

et je la récupère dans Processing (un peu barbare) :

//for get data from Arduino
void serialEvent (Serial myPort) {
  println("serialEvent");
  try {
    println("serialEvent");
    while (myPort.available() > 0) {
      String inBuffer = myPort.readStringUntil('\n');
      if (inBuffer != null) {
        if (inBuffer.substring(0, 1).equals("{")) {
          JSONObject json = parseJSONObject(inBuffer);
          if (json == null) {
            println("JSONObject could not be parsed");
          } else {
float mes_valeurs_dans_processing = json.getInt("tesdatas") ;
          }
        }
      } else {
      }
    }
  }

  catch (Exception e) {
  }
}

tu n’as pas vraiment besoin de comprendre ça, il suffit simplement de changer le nom de tes variables que tu veux utiliser dans processing, et donc les mots clés que tu nommes dans Arduino qui serviront à parser ton ficher


#7

Cela à fonctionné !

Alors j’ai tout repris:
-la connexion Arduino/Pocessing

  • map avec volume
    -le port
    -l’emplacement des fichiers
    (J’utilise bien un capteur analogique égal au potentiomètre)

Finalement, j’ai ajouté la librairy Sound j’ai essayé avec un simple float amplitude mais avec mon sensorValue:

float amplitude = (int)map(sensorValue, 0,1023, 0.2, 1);
             soundfile.amp(amplitude);

Et dans mon exception “T” j’y ai rejouté la condition du player:

catch(Exception e){}
       if(myString.equals("T")){
          if(player.isPlaying() == false){
              player.play();
          }
       }

Je pense que c’est parce que je n’avais pas compris le volume entre [-1.0;1.0] dans le map que cela n’a pas marché la première fois !

Merci 1000fois pour votre aide précieuse !