Selecting functions with a potentiometer

Started by Denio, August 13, 2016, 05:58:07 PM

Previous topic - Next topic

Denio

Hi all!
Here's the deal.I am building a tremolo pedal using an arduino as the LFO.It has 5 waveforms(sine,square,triangle,left saw,right saw),pretty typical style tremolo.What I want is to select the different waveforms via a potentiometer.What I would do is do an analogRead() of the pot and divide the 0-1023 range by 5.And so from 0 to 204.8 it will e running the sine wave function,from 204.8 to 409.6-square wave,I think you get the idea.I tried doing this using a ton of if statements:
if(reading < 205) sineWave();
  if(reading > 205 && reading < 410) squareWave();
  if(reading > 410 && reading < 615) leftSaw();
  if(reading > 615 && reading < 820) rightSaw();
  if(reading > 820 && reading < 1024) triangleWave();


And it kinda worked but really poorly.I also had a switch statement in mind but figured it would not be suitable because it only checks against against specific values and not ranges as in my case.
What would you suggest?

Thank you for your time!  :)

Dan Moos

sounds like a job for a rotary encoder, or since there aren't that many options, maybe just a simple rotary switch.

Sent from my E6715 using Tapatalk


Denio

#2
Yeah,the rotary encoder came to mind.It will probably make things a bit more tough but I am still going to keep it as a backup plan.
The thing that is kinda stopping me for using the rotary encoder is that it requires 2 interrupt pins and I need 1 (I will be using an arduino pro mini or a nano,which I believe both have 2 interrupts)interrupt for a possible bypass switch(or I could use some sort of relay bypass).

The rotary switch is another good option I think.What I would do is I would connect the different throws of the switch to different voltage dividers and do an analog read and then maybe use a switch statement.
Thanks!

Dan Moos

could you use rotary switch and a parallel in/serial out shift register? i guess i don't know how tight you are for i/o pins.


Denio

Hmm,possible,though finding the right rotary switch is a bit tricky here in Bulgaria(electronics stores in here suck  >:( ).The switches either have too many throws or too many poles,but I think I found some with 2 poles and 5 throws that might work.

As for a parallel in serial out shift register maybe another option(though not the most elegant but still possible)would be to use normal push buttons and make something similar to the switches on a fan-only one on at a time.

slacker

What problem are you having with it? That code should work except that if the pot is near the change from one wave to another it will probably jump between the two because the result from the pot won't be the same every time, for example if the pot is set to about 205 it might read slightly above or below that value and jump between sine and square, is that the issue?

Denio

Not really.The thing is that this whole block of code with all these if statements seems a bit bulky and I just thought there might be a much more elegant way to do it.

Rixen

use the arduino 'map' function and a case statement.

I've used this for a couple of projects where I want a single resistor to select a mode..

Rixen

..this one where I call a function to turn an output on for one of twelve selectable durations..


*************************************************************************************
analogRead(modeselect);                                 //dummy read to stabilise ADC for high impedence source
  int mode = map(analogRead(modeselect), 0, 1024, 0, 13);  //find the mode
  switch (mode)
  {

  case 0:    // 0V level, minimum time of 100ms
    {
       ssr_on(100);
    }
    break;
  case 1:    // .41 V level, minimum time of 120ms
    {
       ssr_on(120);
    }
    break;
  case 2:    // 0.83V level, minimum time of 140ms
    {
       ssr_on(140);
    }
    break;
  case 3:    // 1.2 V level, minimum time of 200ms
    {
       ssr_on(200);
    }
    break;
  case 4:    // 1.6V level, minimum time of 240ms
    {
       ssr_on(240);
    }
    break;
  case 5:    // 2V level, minimum time of 280ms
    {
       ssr_on(280);
    }
    break;
  case 6:    // 2.4V level, minimum time of 320ms
    {
       ssr_on(320);
    }
    break;
  case 7:    // 2.8V level, minimum time of 360ms
    {
       ssr_on(360);
    }
    break;
  case 8:    // 3.2V level, minimum time of 400ms
    {
       ssr_on(400);
    }
    break;
  case 9:    // 3.6V level, minimum time of 440ms
    {
       ssr_on(440);
    }
    break;
  case 10:    // 4.58V level, minimum time of 480s
    {
       ssr_on(480);
    }
    break;
  case 11:    // 5V level, minimum time of 520ms
    {
       ssr_on(520);
    }
    break;   
  } 

Denio

Wow,this is pretty clever Rixen.  :)
Thank you! :)
Currently I am using a rotary encoder and it is working fine but I will keep your idea in mind for sure.  :)

ElectricDruid

Quote from: slacker on August 14, 2016, 08:54:50 AM
What problem are you having with it? That code should work except that if the pot is near the change from one wave to another it will probably jump between the two because the result from the pot won't be the same every time, for example if the pot is set to about 205 it might read slightly above or below that value and jump between sine and square, is that the issue?

+1 agree with Slacker. Hysteresis is your friend for jobs like this. Love that "map" function, btw - very useful indeed.

One way I use to do this is to do the "map" part twice, once with the actual value, and once with the actual value + 4. Or more than four if you've got lots of jitter. If the two runs both map to the same value, it's safe to use. If they're different, ignore it.

HTH,
Tom

JMacA

FWIW, When I design effects processors, I like to use a line of potentiometers with optional detents:

http://www.bitechnologies.com/pdfs/p08x.pdf

That way I can decide on a build-by-build basis whether a control should be discrete (e.g. selecting waveforms) or continuous.  I've found that having a mechanical detent is far less frustrating than hoping that the knob is pointing to the right place, and that the processor won't decide to change your parameter in the middle of a performance.  It's a pity there are so few detented pots to choose from.

ElectricDruid

#12
Another point to make is that the original "if" statement can be tidied up considerably:

if(reading < 205) sineWave();
  if(reading > 205 && reading < 410) squareWave();
  if(reading > 410 && reading < 615) leftSaw();
  if(reading > 615 && reading < 820) rightSaw();
  if(reading > 820 && reading < 1024) triangleWave();



if(reading < 205) {
   sineWave();
} else if (reading < 410) {
   squareWave();
} else if (reading < 615) {
   leftSaw();
} else if (reading < 820) {
   rightSaw();
} else {
   // We default to this if nothing else is selected
   triangleWave();
}


There, doesn't that seem better already? It's much faster, since it only tests a single case each time, and it only tests until it finds a condition that is met. The original tests every single condition in every case.

HTH,
Tom

aron

When you use the detent pots, are the values reasonably close for each detent?

JMacA

Re using a detent pot, think of it as a regular pot with, typically, 10 to 12 evenly spaced detents where the wiper would prefer to rest.  So if the pot is sweeping the full scale of your micro's A/D converter, and the pot is reasonably linear (which it is), then I've found that I can accurately read the correct detent with no calibration.  The largest downside to this technique is the very limited selection of detented pots, something that I never understood.

Rob Strand

There's a lot of gear using pots like this. You should be able to get it to work.
You need to workout if the values are jittering or the values are not corresponding to the expected position.
Sometimes you can fix jittering values with a cap to ground on the pot wiper.
Some brands of pots do not perform as expected near the ends so you may have to tweak the end values then tune-up the other positions.  Set the pot to a few known positions then look at the values coming back.  (For production you need to work out if it cause by tolerances or how the pot is made.)
I have a feeling detent pots are no better than a normal linear pot.

[Forgot to mention for jitter you can average the values being read in.]
Send:     . .- .-. - .... / - --- / --. --- .-. -
According to the water analogy of electricity, transistor leakage is caused by holes.