Voltage to resistance (digital pot or PWM?)

I need to convert an old fashioned variable analog 0-10Vdc to variable resistance, with the an increase in voltage proportionally changing the resistance and vise versa.

I know that arduino has no difficulty interfacing with a digital pot via the serial connections, but how do I get the potentiometer to respond from a 0-10V input?

What I'm trying to do: I am using another stand-alone lighting controller, which is used to fade lighting on and off, but it only outputs 0-10V. The LED driver I have built utilizes a current set resistor to regulate the current to the LEDs. Therefore if I can change the set resistor, I can thereby have dimming control over the LEDs.

Alternatively, my LED driver readily accepts PWM from arduino. So how could I have the 0-10V input change the level of PWM using the standard Arduino 'fading' sample program?

Which is the easier option and do you have any recommendation on how to write the program for it? Obviously converting 0-10V to PWM is the ideal resolution, but I don't know to get Arduino to read the voltage and automatically adjust the PWM level. I'm looking for about 100-256 'steps' of PWM (or levels of dimming.)

Thanks guys!

I'm not going to give you the exact answer, but maybe this will provide some clues:

  1. Use an ADC input to read the voltage - you'll have to feed the 10V into AREF/VREF, BTW (NOTE - SEE DISCUSSION BELOW!!!). This will give you a number 0-1023 (analogRead).

  2. Use the map function to convert the 0-1023 to 0-255.

  3. Use that number to set the digital pot, or output (analogWrite) the PWM signal.

:)

Obviously converting 0-10V to PWM is the ideal resolution,

Put the arduino's PWM line through a transistor with the collector (through a resistor) to 10V.

you'll have to feed the 10V into VREF, BTW.

Think very carefully about if this will blow up your arduino.

Think very carefully about if this will blow up your arduino.

After I posted that, I checked the ATMega328 docs (was mainly checking that it was called VREF; found that it was called AREF on the ATMega docs - can't rememeber on the Arduino itself) - I couldn't see anywhere that it stated a max voltage...?

:-?

I couldn’t see anywhere that it stated a max voltage…

In the data sheet where it says no pin should be greater than 0.5v above the supply voltage.

In the data sheet where it says no pin should be greater than 0.5v above the supply voltage.

What section is that (I'll continue to look in the meantime)?

If this is true, then technosteve will need a voltage divider or something to bring the voltage down to 0-5V range, before connecting to AREF.

And why doesn't section 23.5.2 mention that?

Ok - I found it - section 28.1 - my bad.

:-/

And table 28-16 provides more info...

That sounds excellent. Put a voltage divider on the incoming 0-10V so that the Aref sees a max of 5V, and output comes from any of the PWM pins.

Since I'm just an electrical engineer and not too familiar with the code, could someone please help me out with a sample of what the code should look like. I've looked at the reference code on the website of each of the analogread(), analogwrite(), and map(), however I'm not sure how to get them to interact and then loop the voltage sensing and constant adjustment of PWM output. Any ideas?

Thanks!

Any ideas?

Just use huff and puff. Measure, if it's too high increment the value fed to the PWM if too low decrement it. Repeat constantly.

I'm definitely sure that I don't know what huff and puff is. Can you put together a bit of sample code that represents that function?

I don’t know what huff and puff is

Ive just told you in the sentence that followed. What is there not to understand?

value = analogRead(pin);
if(value < threshold) out++; else out–;
if(out > 255) out = 255;
if(out <0 ) out = 0;
analogWrite(pin,out);

I just wanted to clarify that i am a noob at writing code. If someone would be willing to do a little freelance work, I’ll paypal you a $20 bill.

Here is what I am looking for. A sample of a complete working code, that outlines what was discussed above including the below requirements:

-Have arduino loop (continuously sampling and outputting) program that can accept an analog variable 0-10Vdc, and output a proportional PWM signal.

-have the PWM correspond to 1V increments corresponding to percentages of PWM intensity (ex. 1V =10% PWM, 2V =20%, etc.)

-please specify then pins on the arduino being utilized

Please send me the completed code and your email address and I’ll send you money.

Thanks!
Steve

I think all that you are missing is an understanding of the map function. Once you have a handle on this - it'll all fall into place.

http://arduino.cc/en/Reference/Map

Daveg360 -
Thanks for that, it was quite helpful. Where do I tell it to accept VRef as an input, or is that assumed? Please see my sample below. It shows that - an input of VRef of 0 volts will output 0 PWM,

  • 2.5V on VRef (1/2 of a max of 5V) will output 128 (about 1/2 of 255) PWM
  • 5V on ARef will output 255 on PWM.

Do I have everything I need?

void setup()
{
  pinMode(ledPin, 9);   // sets the pin as output
}
void loop()
{
  int val = analogRead(0);
  val = map(val, 0, 1024, 0, 255);
  analogWrite(9, 0);

  int val = analogRead(512);
  val = map(val, 0, 1024, 0, 255);
  analogWrite(9, 128);

  int val = analogRead(1024);
  val = map(val, 0, 1024, 0, 255);
  analogWrite(9, 255);
}

Thanks again, I will stop pulling out my hair now!

It doesn't work, seriously, nobody wants $20?

I think you're just slightly misunderstanding the example in the docs. Try this (just replace the red text with the specific pins from your circuit. Remember that when you read an input it doesn't give you a voltage. It gives you a value between 0 - 1023. So you are taking a value between 0 - 1023 and translating it to a value between 0 - 255 (with map) and then writing this to a PWM pin.

void loop() { int val = analogRead(Input Pin); val = map(val, 0, 1023, 0, 255); analogWrite(Output Pin, val); }

Hellloooooo?! Sigh.

Thanks for the help. How do I direct it to read the Aref pin, or can I use an Analog input pin, such as 0-5?

How does this look?

void loop()
{
  int val = analogRead(Aref);
  val = map(val, 1, 1023, 1, 255);
  analogWrite(9, 0);

  int val = analogRead(Aref);
  val = map(val, 511, 1023, 128, 255);
  analogWrite(9, 128);

  int val = analogRead(Aref);
  val = map(val, 1023, 1023, 255, 255);
  analogWrite(9, 255);
}

Thanks,
Steve

The AREF PIN is used to specify the reference voltage for the analog inputs. It defaults to 5v - so for the time being, don’t worry about it. Connect the 0 - 5v input to analog pin 0 (A0). Connect the output to Digital I/O Pin 3.

void loop()
{
int val = analogRead(0);
val = map(val, 0, 1023, 0, 255);
analogWrite(3, val);
}