Changing Volume Levels based on pot wheel

Status
Not open for further replies.

Lauthai

New member
So I am going to be putting a 10k pot wheel onto the audio board gnd,vol,3.3v pins and want to make it so that when the wheel is turned, it will increase or decrease the volume. I know to get the value of the wheel it should be int val = analogRead(A1); but then I'm not sure how to use that and the changes in that to change the volume up and down.

Here is my full code so far:

Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

AudioPlaySdWav           playSdWav1;
AudioOutputI2S           i2s1;
AudioConnection          patchCord1(playSdWav1, 0, i2s1, 0);
AudioConnection          patchCord2(playSdWav1, 1, i2s1, 1);
AudioControlSGTL5000     sgtl5000_1;

// Use these with the Teensy Audio Shield
#define SDCARD_CS_PIN    10
#define SDCARD_MOSI_PIN  7
#define SDCARD_SCK_PIN   14

// Use these with the Teensy 3.5 & 3.6 SD card
//#define SDCARD_CS_PIN    BUILTIN_SDCARD
//#define SDCARD_MOSI_PIN  11  // not actually used
//#define SDCARD_SCK_PIN   13  // not actually used

// Use these for the SD+Wiz820 or other adaptors
//#define SDCARD_CS_PIN    4
//#define SDCARD_MOSI_PIN  11
//#define SDCARD_SCK_PIN   13


void setup() {
  Serial.begin(9600);
  AudioMemory(8);
  sgtl5000_1.enable();
  sgtl5000_1.volume(0.5);
  SPI.setMOSI(SDCARD_MOSI_PIN);
  SPI.setSCK(SDCARD_SCK_PIN);
  if (!(SD.begin(SDCARD_CS_PIN))) {
    while (1) {
      Serial.println("Unable to access the SD card");
      delay(500);
    }
  }
  delay(500);
}

int val;

void loop() {
  if (playSdWav1.isPlaying() == false) {
    Serial.println("Start playing");
    playSdWav1.play("AoaPP.WAV");
    delay(10); // wait for library to parse WAV info
  }

  val = analogRead(A1);
  Serial.print("analog 0 is: ");
  Serial.println(val);

  //TODO: Change volume based on analog
}
 
The basic solution is to add an Amplfier block to your patch system, between the SD card and the i2S output
https://www.pjrc.com/teensy/gui/?info=AudioAmplifier

You will need to map the 0-1024 output of analog read to the 0-1-32767 range of the amp module.

The map function https://www.arduino.cc/reference/en/language/functions/math/map/ exists to do this sort of thing but works with integer math

so there are several different approches using existing functions or rolling your own, but a simple (and relatively slow one) is:
Code:
   float gainLevel=val; //basic way to ensure floating point math used
   gainLevel = gainLevel/1024;


This means that if the input is the max (1024) the output of the math will be 1, which causes no gain/loss in the amp. If it is set half way you get 512/1024=0.5, causing the amp to play at half volume.

If you want the volume control to go higher than the input wavefile you can change to gainLevel/512 or similar to get a max gain of 2, 1 for a halfway (512/512) and then decreasing from there. If you wind the gain up to mcuh various noises and artifacts will result, so do not go too wild.

If you find that the 'shape' of the pot is not right you can adjust the math to make the volume control do what you want - for example set things up so that the volume control range is from 2-0.5 if you do not want to allow it to be fully silenced by accident.

Finally you may find that doing nothing but reading the pot and adjusting the gain adds artifacts and noise because it is happening too fast. If the file is short it may be tidier to only adjust volume in the restart of play loop. Otherwise you need to do some delaying of the pot read (say every half second) and or do some averaging.
 
The maximum reading in 10bit mode is 1023... ;)

To get a (pseudo-) logarithmic curve for volume control, one can use the following approach:
uint16_t a = analogRead(15);
float v = (float)(a * (a + 2))/(float)(1 << 20);
 
Status
Not open for further replies.
Back
Top