How to change the frequency of a sine wave using a pot? (mozzi)

Bought some 10k pots to have a mess about with arduino. What would the code be to use a pot to control the frequency of a sine wave. (im using mozzi)

Thanks in advance :slight_smile:

Please post the code you are using to generate the sine wave. Use code tags.

//#include <ADC.h>  // Teensy 3.1 uncomment this line and install http://github.com/pedvide/ADC
#pragma GCC optimize ("O2")
#pragma G++ optimize ("O2")
#include <MozziGuts.h>
#include <Oscil.h> // oscillator template
#include <tables/sin2048_int8.h> // sine table for oscillator

// use: Oscil <table_size, update_rate> oscilName (wavetable), look in .h file of table #included above
Oscil <SIN2048_NUM_CELLS, AUDIO_RATE> aSin(SIN2048_DATA);

// use #define for CONTROL_RATE, not a constant
//#define CONTROL_RATE 64 // powers of 2 please
byte gain = 255;
int gainPot = A0;
int freqPot = A1;

void setup(){
  startMozzi(); // set a control rate of 64 (powers of 2 please)
  aSin.setFreq(300); // set the frequency
}

  int getFrequency () {
    return mozziAnalogRead(freqPot)*8+20;
  }
  
void updateControl(){
  // put changing controls in here
  gain = mozziAnalogRead(gainPot) >> 2; //0 -> 225
  aSin.setFreq(getFrequency); //20 -> 8,204
}


int updateAudio(){
  return aSin.next()>>8; // return an int signal centred around 0
  
}


void loop(){
  audioHook(); // required here
}

I started with the mozzi example for the sine wave and added code for the frequency change that I found from doing some googling. Also the gain control doesnt seem to be working with pot 1 (A0) and the frequency pot does nothing (A1)

While you calculate a variable called gain, I don't see anywhere that you actually use it to change anything.
Never used mozzi, just observation from reading the code.

I thought gainPot would be used here to be able to change the gain of the sine wave?

void updateControl(){
  // put changing controls in here
  gain = mozziAnalogRead(gainPot) >> 2; //0 -> 225
  aSin.setFreq(getFrequency); //20 -> 8,204

Do not cross-post. Other thread removed.

Arktureus:
I thought gainPot would be used here to be able to change the gain of the sine wave?

No that just reads the gain pot and returns a value, I would have expected that value to be somehow used to feed back into the synth. As I said I have not run this software but that is what I expect.

can you delete this thread.

(using mozzi) I get a sound out of the audio jack but when using either of the pots they dont effect the sine wave like they should. Am I out putting the sine wave correctly and have I got the code right for using the pots to change the frequency and gain?

//#include <ADC.h>  // Teensy 3.1 uncomment this line and install http://github.com/pedvide/ADC
#pragma GCC optimize ("O2")
#pragma G++ optimize ("O2")
#include <MozziGuts.h>
#include <Oscil.h> // oscillator template
#include <tables/sin2048_int8.h> // sine table for oscillator

// use: Oscil <table_size, update_rate> oscilName (wavetable), look in .h file of table #included above
Oscil <SIN2048_NUM_CELLS, AUDIO_RATE> aSin(SIN2048_DATA);

// use #define for CONTROL_RATE, not a constant
//#define CONTROL_RATE 64 // powers of 2 please
byte gain = 255;
const int gainPot = A0;
int freqPot = A1;
int playState =LOW;
int gainValue;
const int notePlay = 8;
int previousState = LOW;

void setup(){
  startMozzi(); // set a control rate of 64 (powers of 2 please)
  aSin.setFreq(getFrequency); // set the frequency
}

  int getFrequency () {
    return mozziAnalogRead(freqPot)*8+20;
  }
  
void updateControl(){
  // put changing controls in here

int currentState = digitalRead(notePlay);

  if(currentState == HIGH && previousState == LOW) {
    if (playState == HIGH) {
      // current playing must stop
      playState = LOW;
    } else {
      playState = HIGH;
    }
  }
  previousState = currentState;  

  if (playState == HIGH){
    gainValue = mozziAnalogRead(freqPot)>>4;
  } else {
    gainValue = 0;

  }
  

  gain = mozziAnalogRead(gainPot) >> 2; //0 -> 225
  aSin.setFreq(getFrequency); //20 -> 8,204
}


int updateAudio(){
  return (aSin.next()* gainPot)>>8; // return an int signal centred around 0
  
}


void loop(){
  audioHook(); // required here
}
void setup(){
  startMozzi(); // set a control rate of 64 (powers of 2 please)
  aSin.setFreq(getFrequency); // set the frequency
}

  int getFrequency () {
    return mozziAnalogRead(freqPot)*8+20;
  }

When you say "aSin.setFreq(getFrequency);" you are setting the frequency to the ADDRESS of the 'getFrequency' function. You probably want to say "aSin.setFreq(getFrequency());" to call the getFrequency() function and set the frequency to the value it returns.

Note: By doing that in setup() instead of loop() the frequency is set once when the Arduino starts. After that the knob will do nothing. Move that line to loop() if you want to control the frequency dynamically.

Do the "updateControl()" or "updateAudio()" functions ever get called?

johnwasser:
Do the "updateControl()" or "updateAudio()" functions ever get called?

Im new to coding and by called im guessing you mean do they run/work? I hanvnt hooked a button up to the arduino yet but im fairly sure the if statements will work when I do. And the update audio works as I can change the gain of the sine wave, while its running on the arduino.

I kind of fixed the frequency pot issue but it only changes between 2 frequencies when turning the pot and hitting halfway.

freq = analogRead(freqPot) / 2;

Also I did some more googling and read about mapping. Where would I put the line of code for the mapping?

This is the code I did for the mapping. Would I need to put "freq = " before this?

map(mozziAnalogRead(gainFreq),0,1023,20,8000)

Im new to coding and by called im guessing you mean do they run/work?

No. It does not matter whether the functions do what they are supposed to, or not, if you never call them.

It's like wondering if the radio in your car works, when you never use the car.

Add Serial.print() statements to the function, so you KNOW that they get called, or that they don't.

This is the code I did for the mapping. Would I need to put "freq = " before this?

Would you need to put state = before a call to digitalRead()? You would if you really cared what the digitalRead() function returned. You need to add something in front of the map() call, if you care what it returns. If you don't, delete the call.

Stop cross-posting. Last warning.

PaulS:
.

Add Serial.print() statements to the function, so you KNOW that they get called, or that they don't.

I added a Serial.print for the frequency change map and it returned 1000's of numbers corresponding to where the pot dial is. The numbers change in a somewhat correct fashion. But the frequency change is not smooth, it is either a distorted kind of clipping frequency or when the pot is turned past the half way point a frequency that is produced fine.