Analogue to digital conversion for volume control

Hi,

I am new to the Arduino scene,so please bare withe me if my questions seem obvious! :slight_smile: ...but was wondering if i could get any thoughts on the following please:

I have a bluetooth controller for my iphone which controls the volume with two separate switches, one for volume up and one for volume down. The range of the volume covers 15 switch activations. For my project I need to control the volume using a rotary motion, so for this I have a 10 turn potentiometer and a Arduino Uno.

I think I understand the basic principle of how this needs to work, for every 68 step increase (of the 1024 step resolution) of the potentiometer, the volume up switch needs to be activated. As well as this recognising a decrease in steps to activate the volume down switch. Does this sound right?

Could anyone please point me in the right direction how i should begin setting this up and coding it or be able to show me some example of code of maybe a similar project.

Any help and advice would be much appreciated and sorry if i am covering obvious ground!

Thank you!

Sebvettel:
Could anyone please point me in the right direction how i should begin setting this up and coding it or be able to show me some example of code of maybe a similar project.

Step one: Do the analogue input tutorial with your potentiometer and have it write to the serial port whenever you think a button press should have occurred so you can check with the serial monitor if your program does what it should.

Step two: Start a new project to send button presses to your volume control. Best take the basic button tutorial and add the code to press a button on the remote. You're going to need to figure out on your own how those button presses are going to happen.

Step three: Apply what you learned in step one and two to create the thing you want.

Korman

Thanks for getting back to me.

I have worked out how to control the volume switches by using a quad bilateral switch (74HC4016).

I have mapped the potentiometer and programmed it activate the volume up switch every 68th step.

How do I program it so when its turned the opposite way it activates the volume down switch with out activating the volume up switch? So if the wiper is decreased then it activates a different port to the port when its increased. Does that make sense?

Slowly coming to terms with this!

Thanks again for any help!

Post the code you have so far - don't forget to use the # button above to enclose it.

Here is the code so far.

const int sensorMin = 23; // sensor minimum, discovered through experiment
const int sensorMax = 1000; // sensor maximum, discovered through experiment
const int ledPin = 9; // VOL UP connected to digital pin 9 through 4016

void setup() {
// initialize serial communication:
Serial.begin(9600);
}

void loop() {
// read the sensor:
int sensorReading = analogRead(A0);
// map the sensor range to a range of 17 options:
int range = map(sensorReading, sensorMin, sensorMax, 0, 16);

// do something different depending on the
// range value:
switch (range) {
case 0: // Pot turned full anticlock wise
Serial.println("Minimum Volume Level 0");

digitalWrite(9, HIGH); // set the VOL UP on
digitalWrite(9, LOW); // set the VOL UP off

break;
case 1: // 0.6 approx of a turn
Serial.println("Volume Level 1");

digitalWrite(9, HIGH); // set the VOL UP on
digitalWrite(9, LOW); // set the VOL UP off

break;
case 2: // 1.2 approx turns
Serial.println("Volume Level 2");

digitalWrite(9, HIGH); // set the VOL UP on
digitalWrite(9, LOW); // set the VOL UP off

break;
case 3: // 1.8 approx turns
Serial.println("Volume Level 3");

digitalWrite(9, HIGH); // set the VOL UP on
digitalWrite(9, LOW); // set the VOL UP off

break;
case 4: // 2.4 approx turns

digitalWrite(9, HIGH); // set the VOL UP on
digitalWrite(9, LOW); // set the VOL UP off

Serial.println("Volume Level 4");

digitalWrite(9, HIGH); // set the VOL UP on
digitalWrite(9, LOW); // set the VOL UP off

break;
case 5: // 3 approx turns
Serial.println("Volume Level 5");

digitalWrite(9, HIGH); // set the VOL UP on
digitalWrite(9, LOW); // set the VOL UP off

break;
case 6: // 3.6 approx turns
Serial.println("Volume Level 6");

digitalWrite(9, HIGH); // set the VOL UP on
digitalWrite(9, LOW); // set the VOL UP off

break;
case 7: // 4.2 approx turns
Serial.println("Volume Level 7");

digitalWrite(9, HIGH); // set the VOL UP on
digitalWrite(9, LOW); // set the VOL UP off

break;
case 8: // 4.8 approx turns
Serial.println("Volume Level 8");

digitalWrite(9, HIGH); // set the VOL UP on
digitalWrite(9, LOW); // set the VOL UP off

break;
case 9: // 5.4 approx turns
Serial.println("Volume Level 9");

digitalWrite(9, HIGH); // set the VOL UP on
digitalWrite(9, LOW); // set the VOL UP off

break;
case 10: // 6 approx turns
Serial.println("Volume Level 10");

digitalWrite(9, HIGH); // set the VOL UP on
digitalWrite(9, LOW); // set the VOL UP off

break;
case 11: // 6.6 approx turns
Serial.println("Volume Level 11");

digitalWrite(9, HIGH); // set the VOL UP on
digitalWrite(9, LOW); // set the VOL UP off

break;
case 12: // 7.2 approx turns
Serial.println("Volume Level 12");

digitalWrite(9, HIGH); // set the VOL UP on
digitalWrite(9, LOW); // set the VOL UP off

break;
case 13: // 7.8 approx turns
Serial.println("Volume Level 13");

digitalWrite(9, HIGH); // set the VOL UP on
digitalWrite(9, LOW); // set the VOL UP off

break;
case 14: // 8.4 approx turns
Serial.println("Volume Level 14");

digitalWrite(9, HIGH); // set the VOL UP on
digitalWrite(9, LOW); // set the VOL UP off

break;
case 15: // 9 approx turns
Serial.println("Volume Level 15");

digitalWrite(9, HIGH); // set the VOL UP on
digitalWrite(9, LOW); // set the VOL UP off

break;
case 16: // 9.6 approx turns (fully turned clockwise)
Serial.println("Max Volume Level 16");

digitalWrite(9, HIGH); // set the VOL UP on
digitalWrite(9, LOW); // set the VOL UP off

break;
}

}

Not sure if i have gone about this in the right way but would appreciate any comments to getting this working!

I havent yet entered the code for the vol down switch and the code for vol up doesnt seem to work either.

Thanks

Comment #1: every one of your cases in your switch/case is the same.
Comment #2: digitalwrite takes about 3.5 microseconds (give or take) to switch the state of a pin - you need to give time for the switch to respond
Comment #3: you don't use ledPin anywhere
Comment #4: you don't keep track of the current volume
Comment #5: I think they meant the "insert code" button in the toolbar - you can also type in [ code ] and [ / code ] without spaces.

Take a look at this:

const int sensorMin = 23;      // sensor minimum, discovered through experiment
const int sensorMax = 1000;    // sensor maximum, discovered through experiment
const int VOL_UP = 9;          // VOL UP connected to digital pin 9 through 4016
const int VOL_DOWN = 10000;    // I assume your volume down is similar to your 
                               // volume up

int volume;

void volumeUp() {
  digitalWrite(VOL_UP, HIGH); // toggle the pin high
  delay(10); // wait for it to be recognized
  digitalWrite(VOL_UP, LOW); // turn it back off
  delay(10);
  volume++;
}

void volumeDown() {
  digitalWrite(VOL_DOWN, HIGH); // toggle the pin high
  delay(10); // wait for it to be recognized
  digitalWrite(VOL_DOWN, LOW); // turn it back off
  delay(10);
  volume--;
}

void setup() {
  // initialize serial communication:
  Serial.begin(9600); 
  
  // ensure that the volume is set to 0
  // by pressing the down button 15 times
  for (uint8_t i = 0; i < 15; i++) {
    volumeDown();
  }
  volume = 0;
}

void loop() {
  // read the sensor:
  int sensorReading = analogRead(A0);
  // map the sensor range to a range of 15 options:
  int range = map(sensorReading, sensorMin, sensorMax, 0, 14);
  
  // volume is higher than the one read, set it back down to what it should be.
  while (volume > range) {
    volumeDown();
  }
  
  // volume is lower than the one read, set it up until its equal
  while (volume < range) {
    volumeUp();
  }
  
  // volume should now be equal to the one set on the pot
  Serial.print("Volume: ");
  Serial.print(volume);
}

Please tell if the code makes sense to you.

Thanks for the code, greatly appreciate you setting that out for me.

What you have done makes sense to me but i cant seem to actually get it to work. The volume is constantly trying to reduce (can tell this as the bluetooth device beeps when you hit the lowest volume level, so its constantly beeping). The serial monitor reads the pot as the text changes when the pot rotates but after maybe 5 mins it crashes arduino! Otherwise nothing else seems to work and i am sure i have set everything up in the right way! Not really sure were to go next?

I dont suppose anyone uk based does freelance work! Would be willing to pay anyone to set this up and have it working if I mailed them the components?

Thanks

In my code, I never set the pinMode of the two output pins to OUTPUT - you should try that before doing anything else. =).

I hate to ask but how do i do that! sorry!

in setup:

pinMode(VOL_UP, OUTPUT);
pinMode(VOL_DOWN, OUTPUT);

It would be really nice if you Googled your questions before asking them - the first result for set the pinMode arduino is the pinMode command reference page, which clearly tells you how to do this.

Ah yeah sorry, got carried away in the thought this may work! :slight_smile:

Will try that out now.

The other part confusing me is why is VOL_DOWN = 10000?

const int VOL_UP = 9;          // VOL UP connected to digital pin 9 through 4016
const int VOL_DOWN = 10000;    // I assume your volume down is similar to your 
                               // volume up

Thanks

It won't compile without a pin number given, and 10000 is obviously wrong, and you didn't give one. You are supposed to replace that with the actual pin number.

Ok so we may have some progress!

I can turn the volume down but it will not turn it back up again.

So if I turn the volume myself to max and set the potentiometer up in the position for having the volume turned up full. The arduino will reduce the volume itself a few levels before i turn it. Then when i do turn it, the volume doesnt reduce till after at least 5 of the 10 possible turns. Once turned all the way down, it continually tries to reduce the volume further.

Any ideas what could be going wrong?

I have attached my arduino set up to see if you maybe able to notice anything wrong with my set up:

Again thanks for your help!

Pretty poor picture. But I would guess that you have the pot wired wrong. Usually the variable resistance is the middle terminal, not one of the end terminals.

Lefty

I'd been inclined to suggest a rotary encoder. Don't worry about absolute position. Just click the up button if spun clockwise, down if anticlockwise. Then perhaps add complexity so that a sustained rotation continually presses the button. Pots are a bit unpredictable