skewed potentiometer

I am trying to affect the frequency of an LED with a potentiometer and then serial print the frequency in Hertz.

However, the results seemed to be skewed greatly. In the following code the printed frequency range from 5 to 100, but the number changes only from 5 to around 9.5 for the first half of turning the potentiometer, and then near the other end of the potentiometer the number changes by thirty fro a minuscule turn of the potentiometer.

Can anyone give me a solution to make the potentiometer have a constant effect (the number changes at a consistent per turn of the potentiometer) on the printed frequency?

here is my code

int dial=A0;
int readval;
float vol;
int LEDpin=13;
float freq;

void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
pinMode(LEDpin, 13);
}

void loop() {
  // put your main code here, to run repeatedly:
readval=analogRead(dial);
vol=(5./1023.)*readval;
freq=19*vol + 5;

Serial.println(1000 * (1 / (2 * freq)));

digitalWrite(LEDpin, HIGH);
delay(freq);
digitalWrite(LEDpin, LOW);
delay(freq);
}

You may have a taper pot instead of a linear pot.

Does the value of readval change as you would expect ?

Are you using a linear pot or a logarithmic pot ?

I found the solution. I needed to make the printed number linear instead.

so I used this

Serial.println(-1 * freq + 105);

Not a direct answer to the OP, but:

It can be useful to use an exponential function when using a pot like this. Let’s say when the analog read is 0, you’d like the frequencey to be once every 2 seconds, and when it is 1023, you’d like the frequency to be 50hz. In other words, the time between blinks should vary smoothly between 2000ms and 20ms.

#include <math.h>

const float interval_at_zero = 1000 / .5; // .5Hz
const float interval_at_1023 = 1000 / 50; // 50Hz

float ln_zero;
float ln_perincrement;

void setup() {
  // precalculate these values at startup
  // note that log() is a natural log. 
  ln_zero = log(interval_at_zero);
  // this will be negative, which is fine
  ln_perincrement = log(interval_at_1023/interval_at_zero)/1023;
}

// target timing interval, in ms

float getInterval() {
  int pot = analogRead(A0);

  return exp(ln_zero + pot*ln_perincrement);
}

Hi,

The 1/period is what is causing the "skew", the period is linear the frequency is NOT.
Try this edited code, untried but may help;

int dial = A0;
int readval;
float vol;
int LEDpin = 13;
float freq;


void setup()
{
  // put your setup code here, to run once:
  Serial.begin(115200);
  pinMode(LEDpin, 13);
}


void loop()
{
  // put your main code here, to run repeatedly:
  readval = analogRead(dial);
  vol = (5. / 1023.) * readval;
  freq = 19 * vol + 5;


  Serial.println(freq);


  digitalWrite(LEDpin, HIGH);
  delay(1000 / (2 * freq));
  digitalWrite(LEDpin, LOW);
  delay(1000 / (2 * freq));
}

Tom... :slight_smile: