Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 3 of 3

Thread: Changing Volume Levels based on pot wheel

  1. #1
    Junior Member
    Join Date
    Apr 2019
    Posts
    3

    Changing Volume Levels based on pot wheel

    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
    }

  2. #2
    Senior Member
    Join Date
    Apr 2013
    Posts
    1,899
    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/...ions/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.

  3. #3
    Senior Member+ Theremingenieur's Avatar
    Join Date
    Feb 2014
    Location
    Colmar, France
    Posts
    2,535
    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);

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •